Fix PODs not initializing in Json Serialization
When pointers are used new instances are created for pod types, which will have random values at that point. The Json Serialization did not set a value for these if they were explicitly set to defaults. This change adds initialization for explicit defaults in the bool, integer and double serializer plus unit tests to verify.
This commit is contained in:
@@ -63,6 +63,18 @@ namespace JsonSerializationTests
|
||||
: public BaseJsonSerializerFixture
|
||||
{
|
||||
public:
|
||||
struct BoolPointerWrapper
|
||||
{
|
||||
AZ_TYPE_INFO(BoolPointerWrapper, "{2E67C069-BB0F-4F00-A704-E964F5FE5ED2}");
|
||||
|
||||
bool* m_value{ nullptr };
|
||||
|
||||
~BoolPointerWrapper()
|
||||
{
|
||||
azfree(m_value);
|
||||
}
|
||||
};
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
BaseJsonSerializerFixture::SetUp();
|
||||
@@ -75,6 +87,12 @@ namespace JsonSerializationTests
|
||||
BaseJsonSerializerFixture::TearDown();
|
||||
}
|
||||
|
||||
void RegisterAdditional(AZStd::unique_ptr<AZ::SerializeContext>& serializeContext) override
|
||||
{
|
||||
serializeContext->Class<BoolPointerWrapper>()
|
||||
->Field("Value", &BoolPointerWrapper::m_value);
|
||||
}
|
||||
|
||||
void Load(rapidjson::Value& testVal, bool expectedBool, AZ::JsonSerializationResult::Outcomes expectedOutcome)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
@@ -242,4 +260,24 @@ namespace JsonSerializationTests
|
||||
Load(m_jsonValue.SetDouble(-1.0f), true, AZ::JsonSerializationResult::Outcomes::Success);
|
||||
Load(m_jsonValue.SetDouble(2.0), true, AZ::JsonSerializationResult::Outcomes::Success);
|
||||
}
|
||||
|
||||
TEST_F(JsonBoolSerializerTests, Load_LoadDefaultToPointer_ValueIsIsInitialized)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
BoolPointerWrapper instance;
|
||||
|
||||
this->m_jsonDocument->Parse(R"({ "Value": {}})");
|
||||
ASSERT_FALSE(this->m_jsonDocument->HasParseError());
|
||||
|
||||
AZ::JsonDeserializerSettings settings;
|
||||
settings.m_serializeContext = this->m_jsonDeserializationContext->GetSerializeContext();
|
||||
settings.m_registrationContext = this->m_jsonDeserializationContext->GetRegistrationContext();
|
||||
ResultCode result = AZ::JsonSerialization::Load(instance, *this->m_jsonDocument, settings);
|
||||
|
||||
EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome());
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
ASSERT_NE(nullptr, instance.m_value);
|
||||
EXPECT_FALSE(*instance.m_value);
|
||||
}
|
||||
} // namespace JsonSerializationTests
|
||||
|
||||
@@ -71,6 +71,20 @@ namespace JsonSerializationTests
|
||||
: public BaseJsonSerializerFixture
|
||||
{
|
||||
public:
|
||||
struct DoublePointerWrapper
|
||||
{
|
||||
AZ_TYPE_INFO(DoublePointerWrapper, "{C2FD9E0B-2641-4D24-A3D9-A29FD1A21A81}");
|
||||
|
||||
double* m_double{ nullptr };
|
||||
float* m_float{ nullptr };
|
||||
|
||||
~DoublePointerWrapper()
|
||||
{
|
||||
azfree(m_float);
|
||||
azfree(m_double);
|
||||
}
|
||||
};
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
BaseJsonSerializerFixture::SetUp();
|
||||
@@ -85,6 +99,13 @@ namespace JsonSerializationTests
|
||||
BaseJsonSerializerFixture::TearDown();
|
||||
}
|
||||
|
||||
void RegisterAdditional(AZStd::unique_ptr<AZ::SerializeContext>& serializeContext) override
|
||||
{
|
||||
serializeContext->Class<DoublePointerWrapper>()
|
||||
->Field("Double", &DoublePointerWrapper::m_double)
|
||||
->Field("Float", &DoublePointerWrapper::m_float);
|
||||
}
|
||||
|
||||
void TestSerializers(rapidjson::Value& testVal, double expectedValue, AZ::JsonSerializationResult::Outcomes expectedOutcome)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
@@ -275,4 +296,32 @@ namespace JsonSerializationTests
|
||||
EXPECT_EQ(Outcomes::Unsupported, result.GetOutcome());
|
||||
EXPECT_EQ(42.0f, value);
|
||||
}
|
||||
|
||||
// Pointers
|
||||
|
||||
TEST_F(JsonDoubleSerializerTests, Load_LoadDefaultToPointer_ValuesArIsInitialized)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
DoublePointerWrapper instance;
|
||||
|
||||
this->m_jsonDocument->Parse(R"(
|
||||
{
|
||||
"Double": {},
|
||||
"Float": {}
|
||||
})");
|
||||
ASSERT_FALSE(this->m_jsonDocument->HasParseError());
|
||||
|
||||
AZ::JsonDeserializerSettings settings;
|
||||
settings.m_serializeContext = this->m_jsonDeserializationContext->GetSerializeContext();
|
||||
settings.m_registrationContext = this->m_jsonDeserializationContext->GetRegistrationContext();
|
||||
ResultCode result = AZ::JsonSerialization::Load(instance, *this->m_jsonDocument, settings);
|
||||
|
||||
EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome());
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
ASSERT_NE(nullptr, instance.m_double);
|
||||
ASSERT_NE(nullptr, instance.m_float);
|
||||
EXPECT_DOUBLE_EQ(0.0, *instance.m_double);
|
||||
EXPECT_FLOAT_EQ(0.0f, *instance.m_float);
|
||||
}
|
||||
} // namespace JsonSerializationTests
|
||||
|
||||
@@ -147,6 +147,18 @@ namespace JsonSerializationTests
|
||||
: public BaseJsonSerializerFixture
|
||||
{
|
||||
public:
|
||||
struct IntegerPointerWrapper
|
||||
{
|
||||
AZ_TYPE_INFO(IntegerPointerWrapper, "{F6B3BEF1-59A4-4E45-BF02-DDA868C38A28}");
|
||||
|
||||
typename SerializerInfo<SerializerType>::DataType* m_value{ nullptr };
|
||||
|
||||
~IntegerPointerWrapper()
|
||||
{
|
||||
azfree(m_value);
|
||||
}
|
||||
};
|
||||
|
||||
AZStd::unique_ptr<SerializerType> m_serializer;
|
||||
|
||||
void SetUp() override
|
||||
@@ -161,6 +173,12 @@ namespace JsonSerializationTests
|
||||
BaseJsonSerializerFixture::TearDown();
|
||||
}
|
||||
|
||||
void RegisterAdditional(AZStd::unique_ptr<AZ::SerializeContext>& serializeContext) override
|
||||
{
|
||||
serializeContext->Class<IntegerPointerWrapper>()
|
||||
->Field("Value", &IntegerPointerWrapper::m_value);
|
||||
}
|
||||
|
||||
template<typename T, typename AZStd::enable_if_t<AZStd::is_floating_point<T>::value, int> = 0>
|
||||
void SetValue(rapidjson::Value& out, T in)
|
||||
{
|
||||
@@ -487,6 +505,26 @@ namespace JsonSerializationTests
|
||||
EXPECT_EQ(typename SerializerInfo<TypeParam>::DataType(), convertedValue);
|
||||
}
|
||||
|
||||
TYPED_TEST(TypedJsonIntSerializerTests, Load_LoadDefaultToPointer_ValueIsIsInitialized)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
IntegerPointerWrapper instance;
|
||||
|
||||
this->m_jsonDocument->Parse(R"({ "Value": {}})");
|
||||
ASSERT_FALSE(this->m_jsonDocument->HasParseError());
|
||||
|
||||
AZ::JsonDeserializerSettings settings;
|
||||
settings.m_serializeContext = this->m_jsonDeserializationContext->GetSerializeContext();
|
||||
settings.m_registrationContext = this->m_jsonDeserializationContext->GetRegistrationContext();
|
||||
ResultCode result = AZ::JsonSerialization::Load(instance, *this->m_jsonDocument, settings);
|
||||
|
||||
EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome());
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
ASSERT_NE(nullptr, instance.m_value);
|
||||
EXPECT_EQ(0, *instance.m_value);
|
||||
}
|
||||
|
||||
TYPED_TEST(TypedJsonIntSerializerTests, Load_MaxInt8Value_ConvertIfFitsOrUnsupported) { this->template TestMaxValue<int8_t>(); }
|
||||
TYPED_TEST(TypedJsonIntSerializerTests, Load_MaxShortValue_ConvertIfFitsOrUnsupported) { this->template TestMaxValue<short>(); }
|
||||
TYPED_TEST(TypedJsonIntSerializerTests, Load_MaxIntValue_ConvertIfFitsOrUnsupported) { this->template TestMaxValue<int>(); }
|
||||
|
||||
Reference in New Issue
Block a user