You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
301 lines
11 KiB
C++
301 lines
11 KiB
C++
/*
|
|
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
|
* its licensors.
|
|
*
|
|
* For complete copyright and license terms please see the LICENSE at the root of thistoolsApp
|
|
* distribution (the "License"). All use of this software is governed by the License,
|
|
* or, if provided, by the license below or the license accompanying this file. Do not
|
|
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
*
|
|
*/
|
|
|
|
#include <AzCore/UnitTest/TestTypes.h>
|
|
#include <AzToolsFramework/Fingerprinting/TypeFingerprinter.h>
|
|
|
|
using namespace AzToolsFramework;
|
|
using namespace AzToolsFramework::Fingerprinting;
|
|
|
|
namespace UnitTest
|
|
{
|
|
class ReflectedTestClass
|
|
{
|
|
public:
|
|
AZ_TYPE_INFO(ReflectedTestClass, "{AE55A3D4-845B-457F-94BA-A708BBDD6307}");
|
|
AZ_CLASS_ALLOCATOR(ReflectedTestClass, AZ::SystemAllocator, 0);
|
|
|
|
~ReflectedTestClass()
|
|
{
|
|
delete m_property1AsPointer;
|
|
}
|
|
|
|
int m_property1;
|
|
|
|
bool m_property1AsBool;
|
|
int *m_property1AsPointer = nullptr;
|
|
|
|
int m_property2;
|
|
|
|
static void ReflectDefault(AZ::SerializeContext& context)
|
|
{
|
|
context.Class<ReflectedTestClass>()
|
|
->Field("Property1", &ReflectedTestClass::m_property1);
|
|
}
|
|
|
|
static void ReflectHigherVersion(AZ::SerializeContext& context)
|
|
{
|
|
context.Class<ReflectedTestClass>()
|
|
->Version(2)
|
|
->Field("Property1", &ReflectedTestClass::m_property1);
|
|
}
|
|
|
|
static void ReflectRenamedProperty(AZ::SerializeContext& context)
|
|
{
|
|
context.Class<ReflectedTestClass>()
|
|
->Field("Property1Renamed", &ReflectedTestClass::m_property1);
|
|
}
|
|
|
|
static void ReflectPropertyWithDifferentType(AZ::SerializeContext& context)
|
|
{
|
|
context.Class<ReflectedTestClass>()
|
|
->Field("Property", &ReflectedTestClass::m_property1AsBool);
|
|
}
|
|
|
|
static void ReflectPropertyAsPointer(AZ::SerializeContext& context)
|
|
{
|
|
context.Class<ReflectedTestClass>()
|
|
->Field("Property1", &ReflectedTestClass::m_property1AsPointer);
|
|
}
|
|
|
|
static void ReflectTwoProperties(AZ::SerializeContext& context)
|
|
{
|
|
context.Class<ReflectedTestClass>()
|
|
->Field("Property1", &ReflectedTestClass::m_property1)
|
|
->Field("Property2", &ReflectedTestClass::m_property2);
|
|
}
|
|
};
|
|
|
|
class ReflectedBaseClass
|
|
{
|
|
public:
|
|
AZ_TYPE_INFO(ReflectedBaseClass, "{B53DC61E-6E8A-4F0A-82E4-864FA50326E5}");
|
|
virtual ~ReflectedBaseClass() = default;
|
|
|
|
static void ReflectDefault(AZ::SerializeContext& context)
|
|
{
|
|
context.Class<ReflectedBaseClass>();
|
|
}
|
|
};
|
|
|
|
class ReflectedSubClass : public ReflectedBaseClass
|
|
{
|
|
public:
|
|
AZ_TYPE_INFO(ReflectedSubClass, "{B95E143C-D97E-44F3-8F38-BAB6F317A03C}");
|
|
|
|
static void ReflectWithInheritance(AZ::SerializeContext& context)
|
|
{
|
|
context.Class<ReflectedSubClass, ReflectedBaseClass>();
|
|
}
|
|
|
|
static void ReflectWithoutInheritance(AZ::SerializeContext& context)
|
|
{
|
|
context.Class<ReflectedSubClass>();
|
|
}
|
|
};
|
|
|
|
class ReflectedClassWithPointer
|
|
{
|
|
public:
|
|
AZ_TYPE_INFO(ReflectedClassWithPointer, "{03DE24B9-288B-41B5-952D-4749F8F400D2}");
|
|
|
|
~ReflectedClassWithPointer()
|
|
{
|
|
delete m_pointer;
|
|
}
|
|
|
|
ReflectedTestClass* m_pointer = nullptr;
|
|
|
|
static void Reflect(AZ::SerializeContext& context)
|
|
{
|
|
context.Class<ReflectedClassWithPointer>()
|
|
->Field("Pointer", &ReflectedClassWithPointer::m_pointer);
|
|
}
|
|
};
|
|
|
|
TEST(FingerprintTests, IntFingerprint_IsValid)
|
|
{
|
|
AZ::SerializeContext serializeContext;
|
|
TypeFingerprinter fingerprinter{ serializeContext };
|
|
EXPECT_NE(InvalidTypeFingerprint, fingerprinter.GetFingerprint<int>());
|
|
}
|
|
|
|
TEST(FingerprintTests, ClassFingerprint_IsValid)
|
|
{
|
|
AZ::SerializeContext serializeContext;
|
|
ReflectedTestClass::ReflectDefault(serializeContext);
|
|
|
|
TypeFingerprinter fingerprinter{ serializeContext };
|
|
EXPECT_NE(InvalidTypeFingerprint, fingerprinter.GetFingerprint<ReflectedTestClass>());
|
|
}
|
|
|
|
TEST(FingerprintTests, ClassWithNewVersionNumber_ChangesFingerprint)
|
|
{
|
|
AZ::SerializeContext serializeContext1;
|
|
ReflectedTestClass::ReflectDefault(serializeContext1);
|
|
TypeFingerprinter fingerprinter1{ serializeContext1 };
|
|
|
|
AZ::SerializeContext serializeContext2;
|
|
ReflectedTestClass::ReflectHigherVersion(serializeContext2);
|
|
TypeFingerprinter fingerprinter2{ serializeContext2 };
|
|
|
|
EXPECT_NE(fingerprinter1.GetFingerprint<ReflectedTestClass>(), fingerprinter2.GetFingerprint<ReflectedTestClass>());
|
|
}
|
|
|
|
TEST(FingerprintTests, ClassWithRenamedProperty_ChangesFingerprint)
|
|
{
|
|
AZ::SerializeContext serializeContext1;
|
|
ReflectedTestClass::ReflectDefault(serializeContext1);
|
|
TypeFingerprinter fingerprinter1{ serializeContext1 };
|
|
|
|
AZ::SerializeContext serializeContext2;
|
|
ReflectedTestClass::ReflectRenamedProperty(serializeContext2);
|
|
TypeFingerprinter fingerprinter2{ serializeContext2 };
|
|
|
|
EXPECT_NE(fingerprinter1.GetFingerprint<ReflectedTestClass>(), fingerprinter2.GetFingerprint<ReflectedTestClass>());
|
|
}
|
|
|
|
TEST(FingerprintTests, ClassWithPropertyThatChangesType_ChangesFingerprint)
|
|
{
|
|
AZ::SerializeContext serializeContext1;
|
|
ReflectedTestClass::ReflectDefault(serializeContext1);
|
|
TypeFingerprinter fingerprinter1{ serializeContext1 };
|
|
|
|
AZ::SerializeContext serializeContext2;
|
|
ReflectedTestClass::ReflectPropertyWithDifferentType(serializeContext2);
|
|
TypeFingerprinter fingerprinter2{ serializeContext2 };
|
|
|
|
EXPECT_NE(fingerprinter1.GetFingerprint<ReflectedTestClass>(), fingerprinter2.GetFingerprint<ReflectedTestClass>());
|
|
}
|
|
|
|
TEST(FingerprintTests, ClassWithPropertyThatChangesToPointer_ChangesFingerprint)
|
|
{
|
|
AZ::SerializeContext serializeContext1;
|
|
ReflectedTestClass::ReflectDefault(serializeContext1);
|
|
TypeFingerprinter fingerprinter1{ serializeContext1 };
|
|
|
|
AZ::SerializeContext serializeContext2;
|
|
ReflectedTestClass::ReflectPropertyAsPointer(serializeContext2);
|
|
TypeFingerprinter fingerprinter2{ serializeContext2 };
|
|
|
|
EXPECT_NE(fingerprinter1.GetFingerprint<ReflectedTestClass>(), fingerprinter2.GetFingerprint<ReflectedTestClass>());
|
|
}
|
|
|
|
TEST(FingerprintTests, ClassWithNewProperty_ChangesFingerprint)
|
|
{
|
|
AZ::SerializeContext serializeContext1;
|
|
ReflectedTestClass::ReflectDefault(serializeContext1);
|
|
TypeFingerprinter fingerprinter1{ serializeContext1 };
|
|
|
|
AZ::SerializeContext serializeContext2;
|
|
ReflectedTestClass::ReflectTwoProperties(serializeContext2);
|
|
TypeFingerprinter fingerprinter2{ serializeContext2 };
|
|
|
|
EXPECT_NE(fingerprinter1.GetFingerprint<ReflectedTestClass>(), fingerprinter2.GetFingerprint<ReflectedTestClass>());
|
|
}
|
|
|
|
TEST(FingerprintTests, ClassGainingBaseClass_ChangesFingerprint)
|
|
{
|
|
AZ::SerializeContext serializeContext1;
|
|
ReflectedBaseClass::ReflectDefault(serializeContext1);
|
|
ReflectedSubClass::ReflectWithoutInheritance(serializeContext1);
|
|
TypeFingerprinter fingerprinter1{ serializeContext1 };
|
|
|
|
AZ::SerializeContext serializeContext2;
|
|
ReflectedBaseClass::ReflectDefault(serializeContext2);
|
|
ReflectedSubClass::ReflectWithInheritance(serializeContext2);
|
|
TypeFingerprinter fingerprinter2{ serializeContext2 };
|
|
|
|
EXPECT_NE(fingerprinter1.GetFingerprint<ReflectedSubClass>(), fingerprinter2.GetFingerprint<ReflectedSubClass>());
|
|
}
|
|
|
|
TEST(FingerprintTests, GatherAllTypesInObject_FindsCorrectTypes)
|
|
{
|
|
AZ::SerializeContext serializeContext;
|
|
ReflectedTestClass::ReflectDefault(serializeContext);
|
|
TypeFingerprinter fingerprinter{ serializeContext };
|
|
|
|
ReflectedTestClass object;
|
|
TypeCollection typesInObject;
|
|
fingerprinter.GatherAllTypesInObject(&object, typesInObject);
|
|
|
|
EXPECT_EQ(2, typesInObject.size());
|
|
EXPECT_EQ(1, typesInObject.count(AZ::SerializeTypeInfo<int>::GetUuid()));
|
|
EXPECT_EQ(1, typesInObject.count(AZ::SerializeTypeInfo<ReflectedTestClass>::GetUuid()));
|
|
}
|
|
|
|
TEST(FingerprintTests, GatherAllTypesInObjectWithBaseClass_FindsCorrectTypes)
|
|
{
|
|
AZ::SerializeContext serializeContext;
|
|
ReflectedBaseClass::ReflectDefault(serializeContext);
|
|
ReflectedSubClass::ReflectWithInheritance(serializeContext);
|
|
TypeFingerprinter fingerprinter{ serializeContext };
|
|
|
|
ReflectedSubClass object;
|
|
TypeCollection typesInObject;
|
|
fingerprinter.GatherAllTypesInObject(&object, typesInObject);
|
|
|
|
EXPECT_EQ(2, typesInObject.size());
|
|
EXPECT_EQ(1, typesInObject.count(AZ::SerializeTypeInfo<ReflectedSubClass>::GetUuid()));
|
|
EXPECT_EQ(1, typesInObject.count(AZ::SerializeTypeInfo<ReflectedBaseClass>::GetUuid()));
|
|
}
|
|
|
|
TEST(FingerprintTests, GatherTypesInObjectWithNullPointer_FindsCorrectTypes)
|
|
{
|
|
AZ::SerializeContext serializeContext;
|
|
ReflectedClassWithPointer::Reflect(serializeContext);
|
|
ReflectedTestClass::ReflectDefault(serializeContext);
|
|
TypeFingerprinter fingerprinter{ serializeContext };
|
|
|
|
ReflectedClassWithPointer classWithPointer;
|
|
classWithPointer.m_pointer = nullptr;
|
|
|
|
TypeCollection typesInObject;
|
|
fingerprinter.GatherAllTypesInObject(&classWithPointer, typesInObject);
|
|
|
|
// shouldn't gather types from ReflectedTestClass, since m_pointer is null
|
|
EXPECT_EQ(1, typesInObject.size());
|
|
EXPECT_EQ(1, typesInObject.count(AZ::SerializeTypeInfo<ReflectedClassWithPointer>::GetUuid()));
|
|
}
|
|
|
|
TEST(FingerprintTests, GatherTypesInObjectWithValidPointer_FindsCorrectTypes)
|
|
{
|
|
AZ::SerializeContext serializeContext;
|
|
ReflectedClassWithPointer::Reflect(serializeContext);
|
|
ReflectedTestClass::ReflectDefault(serializeContext);
|
|
TypeFingerprinter fingerprinter{ serializeContext };
|
|
|
|
ReflectedClassWithPointer classWithPointer;
|
|
classWithPointer.m_pointer = aznew ReflectedTestClass();
|
|
|
|
TypeCollection typesInObject;
|
|
fingerprinter.GatherAllTypesInObject(&classWithPointer, typesInObject);
|
|
|
|
// should have followed m_pointer and gathered types from ReflectedTestClass
|
|
EXPECT_EQ(3, typesInObject.size());
|
|
EXPECT_EQ(1, typesInObject.count(AZ::SerializeTypeInfo<ReflectedClassWithPointer>::GetUuid()));
|
|
EXPECT_EQ(1, typesInObject.count(AZ::SerializeTypeInfo<ReflectedTestClass>::GetUuid()));
|
|
EXPECT_EQ(1, typesInObject.count(AZ::SerializeTypeInfo<int>::GetUuid()));
|
|
}
|
|
|
|
TEST(FingerprintTests, GenerateFingerprintForAllTypesInObject_Works)
|
|
{
|
|
AZ::SerializeContext serializeContext;
|
|
ReflectedTestClass::ReflectDefault(serializeContext);
|
|
TypeFingerprinter fingerprinter{ serializeContext };
|
|
|
|
ReflectedTestClass object;
|
|
|
|
EXPECT_NE(InvalidTypeFingerprint, fingerprinter.GenerateFingerprintForAllTypesInObject(&object));
|
|
}
|
|
} // namespace UnitTest
|