104 lines
3.3 KiB
C++
104 lines
3.3 KiB
C++
|
#include "RootedObject.h"
|
||
|
|
||
|
|
||
|
#if WITH_DEV_AUTOMATION_TESTS
|
||
|
|
||
|
template<typename AssigneeType, typename ValueType>
|
||
|
struct TIsAssignableFrom
|
||
|
{
|
||
|
struct TrueType {};
|
||
|
|
||
|
template<typename T>
|
||
|
static T DeclVal(); // intentionally not implemented
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
Value = TIsSame<decltype(DeclVal<AssigneeType>() = DeclVal<ValueType>(), DeclVal<TrueType>()), TrueType>::Value
|
||
|
};
|
||
|
};
|
||
|
|
||
|
static_assert(TIsConstructible<TRootedObject<UObject>>::Value, "TRootedObject should be default constructible");
|
||
|
|
||
|
static_assert(TIsConstructible<TRootedObject<UObject>, TRootedObject<UObject>&&>::Value, "TRootedObject should be move constructible");
|
||
|
static_assert(TIsAssignableFrom<TRootedObject<UObject>, TRootedObject<UObject>&&>::Value, "TRootedObject should be move assignable");
|
||
|
|
||
|
static_assert(TIsAssignableFrom<UObject*&, TRootedObject<UObject>>::Value, "TRootedObject should implicitly castable to its inner type");
|
||
|
|
||
|
BEGIN_DEFINE_SPEC(TRootedObjectSpec, "Workshop.RootedObject", EAutomationTestFlags::ProductFilter | EAutomationTestFlags::ApplicationContextMask)
|
||
|
UObject* TheInnerObject;
|
||
|
END_DEFINE_SPEC(TRootedObjectSpec)
|
||
|
|
||
|
void TRootedObjectSpec::Define()
|
||
|
{
|
||
|
BeforeEach([this]()
|
||
|
{
|
||
|
TheInnerObject = NewObject<USceneComponent>();
|
||
|
});
|
||
|
|
||
|
Describe("Construct", [this]()
|
||
|
{
|
||
|
It("Should add the rooted object to the root", [this]()
|
||
|
{
|
||
|
TRootedObject<UObject> RootedObject(TheInnerObject);
|
||
|
TestTrue("TheInnerObject->IsRooted()", TheInnerObject->IsRooted());
|
||
|
});
|
||
|
|
||
|
It("Should move correctly", [this]()
|
||
|
{
|
||
|
TRootedObject<UObject> RootedObject(TheInnerObject);
|
||
|
TRootedObject<UObject> OtherRootedObject;
|
||
|
|
||
|
OtherRootedObject = MoveTemp(RootedObject);
|
||
|
|
||
|
TestTrue("TheInnerObject->IsRooted()", TheInnerObject->IsRooted());
|
||
|
TestFalse("RootedObject.IsValid()", RootedObject.IsValid());
|
||
|
TestTrue("OtherRootedObject.IsValid()", OtherRootedObject.IsValid());
|
||
|
});
|
||
|
});
|
||
|
|
||
|
Describe("Destruct", [this]()
|
||
|
{
|
||
|
It("Should remove the rooted object from the root", [this]()
|
||
|
{
|
||
|
{
|
||
|
TRootedObject<UObject> RootedObject(TheInnerObject);
|
||
|
TestTrue("TheInnerObject->IsRooted()", TheInnerObject->IsRooted());
|
||
|
}
|
||
|
TestFalse("TheInnerObject->IsRooted()", TheInnerObject->IsRooted());
|
||
|
});
|
||
|
});
|
||
|
|
||
|
Describe("RetrieveObject", [this]()
|
||
|
{
|
||
|
It("Should invalidate the rooted object", [this]()
|
||
|
{
|
||
|
TRootedObject<UObject> RootedObject(TheInnerObject);
|
||
|
RootedObject.RetrieveObject();
|
||
|
TestFalse("RootedObject.IsValid()", RootedObject.IsValid());
|
||
|
});
|
||
|
|
||
|
It("Should return the inner object", [this]()
|
||
|
{
|
||
|
TRootedObject<UObject> RootedObject(TheInnerObject);
|
||
|
UObject* RetrievedObject = RootedObject.RetrieveObject();
|
||
|
TestEqual("RootedObject.IsValid()", TheInnerObject, RetrievedObject);
|
||
|
});
|
||
|
|
||
|
It("Should remove the inner object from root", [this]()
|
||
|
{
|
||
|
TRootedObject<UObject> RootedObject(TheInnerObject);
|
||
|
UObject* RetrievedObject = RootedObject.RetrieveObject();
|
||
|
TestFalse("RetrievedObject->IsRooted()", RetrievedObject->IsRooted());
|
||
|
});
|
||
|
|
||
|
It("Implicit Retrieve is same as explicit retrieve", [this]()
|
||
|
{
|
||
|
TRootedObject<UObject> RootedObject(TheInnerObject);
|
||
|
UObject* RetrievedObject = RootedObject;
|
||
|
TestEqual("RootedObject.IsValid()", TheInnerObject, RetrievedObject);
|
||
|
TestFalse("RetrievedObject->IsRooted()", RetrievedObject->IsRooted());
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
|
||
|
#endif
|