merge from main
This commit is contained in:
@@ -186,7 +186,8 @@ namespace UnitTest
|
||||
int GetWeakUseCount() { return m_weakUseCount.load(); }
|
||||
};
|
||||
|
||||
TEST_F(WeakAssetTest, WeakAsset_ConstructionAndDestruction_UpdatesAssetDataWeakRefCount)
|
||||
// Asset cancellation is temporarily disabled, re-enable this test when cancellation is more stable
|
||||
TEST_F(WeakAssetTest, DISABLED_WeakAsset_ConstructionAndDestruction_UpdatesAssetDataWeakRefCount)
|
||||
{
|
||||
TestAssetData testData;
|
||||
EXPECT_EQ(testData.GetWeakUseCount(), 0);
|
||||
@@ -202,7 +203,8 @@ namespace UnitTest
|
||||
EXPECT_EQ(testData.GetWeakUseCount(), 0);
|
||||
}
|
||||
|
||||
TEST_F(WeakAssetTest, WeakAsset_MoveOperatorWithDifferentData_UpdatesOldAssetDataWeakRefCount)
|
||||
// Asset cancellation is temporarily disabled, re-enable this test when cancellation is more stable
|
||||
TEST_F(WeakAssetTest, DISABLED_WeakAsset_MoveOperatorWithDifferentData_UpdatesOldAssetDataWeakRefCount)
|
||||
{
|
||||
TestAssetData testData;
|
||||
EXPECT_EQ(testData.GetWeakUseCount(), 0);
|
||||
@@ -217,7 +219,8 @@ namespace UnitTest
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
}
|
||||
|
||||
TEST_F(WeakAssetTest, WeakAsset_MoveOperatorWithSameData_PreservesAssetDataWeakRefCount)
|
||||
// Asset cancellation is temporarily disabled, re-enable this test when cancellation is more stable
|
||||
TEST_F(WeakAssetTest, DISABLED_WeakAsset_MoveOperatorWithSameData_PreservesAssetDataWeakRefCount)
|
||||
{
|
||||
TestAssetData testData;
|
||||
EXPECT_EQ(testData.GetWeakUseCount(), 0);
|
||||
@@ -234,7 +237,8 @@ namespace UnitTest
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
}
|
||||
|
||||
TEST_F(WeakAssetTest, WeakAsset_AssignmentOperator_CopiesDataAndIncrementsWeakRefCount)
|
||||
// Asset cancellation is temporarily disabled, re-enable this test when cancellation is more stable
|
||||
TEST_F(WeakAssetTest, DISABLED_WeakAsset_AssignmentOperator_CopiesDataAndIncrementsWeakRefCount)
|
||||
{
|
||||
TestAssetData testData;
|
||||
EXPECT_EQ(testData.GetWeakUseCount(), 0);
|
||||
|
||||
@@ -575,6 +575,91 @@ namespace UnitTest
|
||||
EXPECT_EQ(baseStatus, expected_base_status);
|
||||
}
|
||||
|
||||
struct DebugListener : AZ::Interface<IDebugAssetEvent>::Registrar
|
||||
{
|
||||
void AssetStatusUpdate(AZ::Data::AssetId id, AZ::Data::AssetData::AssetStatus status) override
|
||||
{
|
||||
AZ::Debug::Trace::Output(
|
||||
"", AZStd::string::format("Status %s - %d\n", id.ToString<AZStd::string>().c_str(), static_cast<int>(status)).c_str());
|
||||
}
|
||||
void ReleaseAsset(AZ::Data::AssetId id) override
|
||||
{
|
||||
AZ::Debug::Trace::Output(
|
||||
"", AZStd::string::format("Release %s\n", id.ToString<AZStd::string>().c_str()).c_str());
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(AssetJobsFloodTest, RapidAcquireAndRelease)
|
||||
{
|
||||
DebugListener listener;
|
||||
auto assetUuids = {
|
||||
MyAsset1Id,
|
||||
MyAsset2Id,
|
||||
MyAsset3Id,
|
||||
};
|
||||
|
||||
AZStd::vector<AZStd::thread> threads;
|
||||
AZStd::mutex mutex;
|
||||
AZStd::atomic<int> threadCount(static_cast<int>(assetUuids.size()));
|
||||
AZStd::condition_variable cv;
|
||||
AZStd::atomic_bool keepDispatching(true);
|
||||
|
||||
auto dispatch = [&keepDispatching]() {
|
||||
while (keepDispatching)
|
||||
{
|
||||
AssetManager::Instance().DispatchEvents();
|
||||
}
|
||||
};
|
||||
|
||||
AZStd::thread dispatchThread(dispatch);
|
||||
|
||||
for (const auto& assetUuid : assetUuids)
|
||||
{
|
||||
threads.emplace_back([this, &threadCount, &cv, assetUuid]() {
|
||||
bool checkLoaded = true;
|
||||
|
||||
for (int i = 0; i < 5000; i++)
|
||||
{
|
||||
Asset<AssetWithAssetReference> asset1 =
|
||||
m_testAssetManager->GetAsset(assetUuid, azrtti_typeid<AssetWithAssetReference>(), AZ::Data::AssetLoadBehavior::PreLoad);
|
||||
|
||||
if (checkLoaded)
|
||||
{
|
||||
asset1.BlockUntilLoadComplete();
|
||||
|
||||
EXPECT_TRUE(asset1.IsReady()) << "Iteration " << i << " failed. Asset status: " << static_cast<int>(asset1.GetStatus());
|
||||
}
|
||||
|
||||
checkLoaded = !checkLoaded;
|
||||
}
|
||||
|
||||
--threadCount;
|
||||
cv.notify_one();
|
||||
});
|
||||
}
|
||||
|
||||
bool timedOut = false;
|
||||
|
||||
// Used to detect a deadlock. If we wait for more than 5 seconds, it's likely a deadlock has occurred
|
||||
while (threadCount > 0 && !timedOut)
|
||||
{
|
||||
AZStd::unique_lock<AZStd::mutex> lock(mutex);
|
||||
timedOut = (AZStd::cv_status::timeout == cv.wait_until(lock, AZStd::chrono::system_clock::now() + DefaultTimeoutSeconds * 20000));
|
||||
}
|
||||
|
||||
ASSERT_EQ(threadCount, 0) << "Thread count is non-zero, a thread has likely deadlocked. Test will not shut down cleanly.";
|
||||
|
||||
for (auto& thread : threads)
|
||||
{
|
||||
thread.join();
|
||||
}
|
||||
|
||||
keepDispatching = false;
|
||||
dispatchThread.join();
|
||||
|
||||
AssetManager::Destroy();
|
||||
}
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
|
||||
TEST_F(AssetJobsFloodTest, DISABLED_AssetLoadBehaviorIsPreserved)
|
||||
#else
|
||||
@@ -957,11 +1042,7 @@ namespace UnitTest
|
||||
|
||||
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
|
||||
TEST_F(AssetJobsFloodTest, DISABLED_ContainerCoreTest_BasicDependencyManagement_Success)
|
||||
#else
|
||||
TEST_F(AssetJobsFloodTest, ContainerCoreTest_BasicDependencyManagement_Success)
|
||||
#endif // !AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
|
||||
{
|
||||
m_assetHandlerAndCatalog->AssetCatalogRequestBus::Handler::BusConnect();
|
||||
// Setup has already created/destroyed assets
|
||||
@@ -2592,7 +2673,8 @@ namespace UnitTest
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
|
||||
TEST_F(AssetManagerCancelTests, DISABLED_CancelLoad_NoReferences_LoadCancels)
|
||||
#else
|
||||
TEST_F(AssetManagerCancelTests, CancelLoad_NoReferences_LoadCancels)
|
||||
// Asset cancellation is temporarily disabled, re-enable this test when cancellation is more stable. LYN-3263
|
||||
TEST_F(AssetManagerCancelTests, DISABLED_CancelLoad_NoReferences_LoadCancels)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
|
||||
{
|
||||
m_assetHandlerAndCatalog->SetArtificialDelayMilliseconds(0, 100);
|
||||
@@ -2632,7 +2714,8 @@ namespace UnitTest
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
|
||||
TEST_F(AssetManagerCancelTests, DISABLED_CanceledLoad_CanBeLoadedAgainLater)
|
||||
#else
|
||||
TEST_F(AssetManagerCancelTests, CanceledLoad_CanBeLoadedAgainLater)
|
||||
// Asset cancellation is temporarily disabled, re-enable this test when cancellation is more stable. LYN-3263
|
||||
TEST_F(AssetManagerCancelTests, DISABLED_CanceledLoad_CanBeLoadedAgainLater)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
|
||||
{
|
||||
m_assetHandlerAndCatalog->SetArtificialDelayMilliseconds(0, 50);
|
||||
@@ -2681,7 +2764,8 @@ namespace UnitTest
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
|
||||
TEST_F(AssetManagerCancelTests, DISABLED_CancelLoad_InProgressLoad_Continues)
|
||||
#else
|
||||
TEST_F(AssetManagerCancelTests, CancelLoad_InProgressLoad_Continues)
|
||||
// Asset cancellation is temporarily disabled, re-enable this test when cancellation is more stable. LYN-3263
|
||||
TEST_F(AssetManagerCancelTests, DISABLED_CancelLoad_InProgressLoad_Continues)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
|
||||
{
|
||||
m_assetHandlerAndCatalog->SetArtificialDelayMilliseconds(0, 100);
|
||||
@@ -2903,8 +2987,9 @@ namespace UnitTest
|
||||
TEST_F(AssetManagerClearAssetReferenceTests,
|
||||
DISABLED_ContainerLoadTest_AssetLosesAndGainsReferencesDuringLoadAndSuspendedRelease_AssetSuccessfullyFinishesLoading)
|
||||
#else
|
||||
// Asset cancellation is temporarily disabled, re-enable this test when cancellation is more stable. LYN-3263
|
||||
TEST_F(AssetManagerClearAssetReferenceTests,
|
||||
ContainerLoadTest_AssetLosesAndGainsReferencesDuringLoadAndSuspendedRelease_AssetSuccessfullyFinishesLoading)
|
||||
DISABLED_ContainerLoadTest_AssetLosesAndGainsReferencesDuringLoadAndSuspendedRelease_AssetSuccessfullyFinishesLoading)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
|
||||
{
|
||||
// Start the load and wait for the dependent asset to hit the loading state.
|
||||
@@ -2961,7 +3046,8 @@ namespace UnitTest
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
|
||||
TEST_F(AssetManagerClearAssetReferenceTests, DISABLED_ContainerLoadTest_RootAssetDestroyedWhileContainerLoading_ContainerFinishesLoad)
|
||||
#else
|
||||
TEST_F(AssetManagerClearAssetReferenceTests, ContainerLoadTest_RootAssetDestroyedWhileContainerLoading_ContainerFinishesLoad)
|
||||
// Asset cancellation is temporarily disabled, re-enable this test when cancellation is more stable. LYN-3263
|
||||
TEST_F(AssetManagerClearAssetReferenceTests, DISABLED_ContainerLoadTest_RootAssetDestroyedWhileContainerLoading_ContainerFinishesLoad)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
|
||||
{
|
||||
OnAssetReadyListener assetStatus1(DependentPreloadAssetId, azrtti_typeid<AssetWithAssetReference>());
|
||||
|
||||
@@ -330,4 +330,208 @@ namespace UnitTest
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// The AssetManagerStreamerImmediateCompletionTests class adjusts the asset loading to force it to complete immediately,
|
||||
// while still within the callstack for GetAsset(). This can be used to test various conditions in which the load thread
|
||||
// completes more rapidly than expected, and can expose subtle race conditions.
|
||||
// There are a few key things that this class does to make this work:
|
||||
// - The file I/O streamer is mocked
|
||||
// - The asset stream data is mocked to a 0-byte length for the asset so that the stream load will bypass the I/O streamer and
|
||||
// just immediately return completion.
|
||||
// - The number of JobManager threads is set to 0, forcing jobs to execute synchronously inline when they are started.
|
||||
// With these changes, GetAssetInternal() will queue the stream, which will immediately call the callback that creates LoadAssetJob,
|
||||
// which immediately executes in-place to process the asset due to the synchronous JobManager.
|
||||
// Note that if we just created the asset in a Ready state, most of the asset loading code is completely bypassed, and so we
|
||||
// wouldn't be able to test for race conditions in the AssetContainer.
|
||||
//
|
||||
// This class also unregisters the catalog and asset handler before shutting down the asset manager. This is done to catch
|
||||
// any outstanding asset references that exist due to loads not completing and cleaning up successfully.
|
||||
struct AssetManagerStreamerImmediateCompletionTests : public BaseAssetManagerTest,
|
||||
public AZ::Data::AssetCatalogRequestBus::Handler,
|
||||
public AZ::Data::AssetHandler,
|
||||
public AZ::Data::AssetCatalog
|
||||
{
|
||||
static inline const AZ::Uuid TestAssetId{"{E970B177-5F45-44EB-A2C4-9F29D9A0B2A2}"};
|
||||
static inline const AZ::Uuid MissingAssetId{"{11111111-1111-1111-1111-111111111111}"};
|
||||
static inline constexpr AZStd::string_view TestAssetPath = "test";
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
BaseAssetManagerTest::SetUp();
|
||||
AssetManager::Descriptor desc;
|
||||
AssetManager::Create(desc);
|
||||
|
||||
// Register the handler and catalog after creation, because we intend to destroy them before AssetManager destruction.
|
||||
// The specific asset we load is irrelevant, so register EmptyAsset.
|
||||
AZ::Data::AssetManager::Instance().RegisterHandler(this, AZ::AzTypeInfo<EmptyAsset>::Uuid());
|
||||
AZ::Data::AssetManager::Instance().RegisterCatalog(this, AZ::AzTypeInfo<EmptyAsset>::Uuid());
|
||||
|
||||
// Intercept messages for finding assets by name so that we can mock out the asset we're loading.
|
||||
AZ::Data::AssetCatalogRequestBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
// Unregister before destroying AssetManager.
|
||||
// This will catch any assets that got stuck in a loading state without getting cleaned up.
|
||||
AZ::Data::AssetManager::Instance().UnregisterCatalog(this);
|
||||
AZ::Data::AssetManager::Instance().UnregisterHandler(this);
|
||||
|
||||
AZ::Data::AssetCatalogRequestBus::Handler::BusDisconnect();
|
||||
|
||||
AssetManager::Destroy();
|
||||
BaseAssetManagerTest::TearDown();
|
||||
}
|
||||
|
||||
size_t GetNumJobManagerThreads() const override
|
||||
{
|
||||
// Return 0 threads so that the Job Manager executes jobs synchronously inline. This lets us finish a load while still
|
||||
// in the callstack that initiates the load.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Create a mock streamer instead of a real one, since we don't really want to load an asset.
|
||||
IO::IStreamer* CreateStreamer() override
|
||||
{
|
||||
m_mockStreamer = AZStd::make_unique<StreamerWrapper>();
|
||||
return &(m_mockStreamer->m_mockStreamer);
|
||||
}
|
||||
|
||||
void DestroyStreamer([[maybe_unused]] IO::IStreamer* streamer) override
|
||||
{
|
||||
m_mockStreamer = nullptr;
|
||||
}
|
||||
|
||||
// AssetHandler implementation
|
||||
|
||||
// Minimalist mock to create a new EmptyAsset with the desired asset ID.
|
||||
AZ::Data::AssetPtr CreateAsset(const AZ::Data::AssetId& id, [[maybe_unused]] const AZ::Data::AssetType& type) override
|
||||
{
|
||||
return new EmptyAsset(id);
|
||||
}
|
||||
|
||||
void DestroyAsset(AZ::Data::AssetPtr ptr) override
|
||||
{
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
// The mocked-out Asset Catalog handles EmptyAsset types.
|
||||
void GetHandledAssetTypes(AZStd::vector<AZ::Data::AssetType>& assetTypes) override
|
||||
{
|
||||
assetTypes.push_back(AZ::AzTypeInfo<EmptyAsset>::Uuid());
|
||||
}
|
||||
|
||||
// This is a mocked-out load, so just immediately return completion without doing anything.
|
||||
AZ::Data::AssetHandler::LoadResult LoadAssetData(
|
||||
[[maybe_unused]] const AZ::Data::Asset<AZ::Data::AssetData>& asset,
|
||||
[[maybe_unused]] AZStd::shared_ptr<AZ::Data::AssetDataStream> stream,
|
||||
[[maybe_unused]] const AZ::Data::AssetFilterCB& assetLoadFilterCB)
|
||||
{
|
||||
return AZ::Data::AssetHandler::LoadResult::LoadComplete;
|
||||
}
|
||||
|
||||
// AssetCatalogRequestBus implementation
|
||||
|
||||
// Minimalist mocks to provide our desired asset path or asset id
|
||||
AZStd::string GetAssetPathById(const AZ::Data::AssetId& id) override
|
||||
{
|
||||
if (id == TestAssetId)
|
||||
{
|
||||
return TestAssetPath;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
AZ::Data::AssetId GetAssetIdByPath(
|
||||
const char* path, [[maybe_unused]] const AZ::Data::AssetType& typeToRegister,
|
||||
[[maybe_unused]] bool autoRegisterIfNotFound) override
|
||||
{
|
||||
if (path == TestAssetPath)
|
||||
{
|
||||
return TestAssetId;
|
||||
}
|
||||
|
||||
return AZ::Data::AssetId();
|
||||
}
|
||||
|
||||
// Return the mocked-out information for our test asset
|
||||
AZ::Data::AssetInfo GetAssetInfoById(const AZ::Data::AssetId& id) override
|
||||
{
|
||||
AZ::Data::AssetInfo assetInfo;
|
||||
|
||||
if (id == TestAssetId)
|
||||
{
|
||||
assetInfo.m_assetId = TestAssetId;
|
||||
assetInfo.m_assetType = AZ::AzTypeInfo<EmptyAsset>::Uuid();
|
||||
assetInfo.m_relativePath = TestAssetPath;
|
||||
}
|
||||
|
||||
return assetInfo;
|
||||
}
|
||||
|
||||
// AssetCatalog implementation
|
||||
|
||||
// Set the mocked-out asset load to have a 0-byte length so that the load skips I/O and immediately returns success
|
||||
AZ::Data::AssetStreamInfo GetStreamInfoForLoad(
|
||||
const AZ::Data::AssetId& id, const AZ::Data::AssetType& type) override
|
||||
{
|
||||
EXPECT_TRUE(type == AZ::AzTypeInfo<EmptyAsset>::Uuid());
|
||||
AZ::Data::AssetStreamInfo info;
|
||||
|
||||
info.m_dataOffset = 0;
|
||||
info.m_dataLen = 0;
|
||||
info.m_streamFlags = AZ::IO::OpenMode::ModeRead;
|
||||
|
||||
if (id == TestAssetId)
|
||||
{
|
||||
info.m_streamName = TestAssetPath;
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<StreamerWrapper> m_mockStreamer;
|
||||
};
|
||||
|
||||
// This test will verify that even if the asset loading stream/job returns immediately, all of the loading
|
||||
// code works successfully. The test here is fairly simple - it just loads the asset and verifies that it
|
||||
// loaded successfully. The bulk of the test is really in the setup class above, where the load is forced
|
||||
// to complete immediately. Also, the true failure condition is caught in the setup class too, which is
|
||||
// the presence of any assets at the point that the asset handler is unregistered. If they're present, then
|
||||
// the immediate load wasn't truly successful, as it left around extra references to the asset that haven't
|
||||
// been cleaned up.
|
||||
TEST_F(AssetManagerStreamerImmediateCompletionTests, LoadAssetWithImmediateJobCompletion_WorksSuccessfully)
|
||||
{
|
||||
AZ::Data::AssetLoadParameters loadParams;
|
||||
|
||||
auto testAsset =
|
||||
AssetManager::Instance().GetAsset<EmptyAsset>(TestAssetId, AZ::Data::AssetLoadBehavior::Default, loadParams);
|
||||
|
||||
AZ::Data::AssetManager::Instance().DispatchEvents();
|
||||
EXPECT_TRUE(testAsset.IsReady());
|
||||
}
|
||||
|
||||
// This test verifies that even if the asset loading returns immediately with an error, all of the loading code works
|
||||
// successfully. The test itself loads a missing asset twice - the first time is a non-immediate error, where the error
|
||||
// isn't reported until the DispatchEvents() call. The second time is an immediate error, because now the asset is already
|
||||
// registered in an Error state. If the test fails, it will likely get caught in the shutdown of the test class, if any
|
||||
// assets still exist at the point that the asset handler is unregistered. If they're present, then handling of the immediate
|
||||
// error didn't work, as it left around extra references to the asset that haven't been cleaned up.
|
||||
TEST_F(AssetManagerStreamerImmediateCompletionTests, ImmediateAssetError_WorksSuccessfully)
|
||||
{
|
||||
AZ::Data::AssetLoadParameters loadParams;
|
||||
|
||||
// Attempt to load a missing asset the first time. It will get an error, but not until the DispatchEvents() call happens.
|
||||
auto testAsset1 = AssetManager::Instance().GetAsset<EmptyAsset>(MissingAssetId, AZ::Data::AssetLoadBehavior::Default, loadParams);
|
||||
AZ::Data::AssetManager::Instance().DispatchEvents();
|
||||
EXPECT_TRUE(testAsset1.IsError());
|
||||
|
||||
// While the reference to the missing asset still exists, try to get it again. This will cause a more immediate error in
|
||||
// the AssetContainer code, which should still get handled correctly. In the failure condition, it will instead leave the
|
||||
// AssetContainer in a state where it never sends the final OnAssetContainerReady/Canceled message.
|
||||
auto testAsset2 = AssetManager::Instance().GetAsset<EmptyAsset>(MissingAssetId, AZ::Data::AssetLoadBehavior::Default, loadParams);
|
||||
AZ::Data::AssetManager::Instance().DispatchEvents();
|
||||
EXPECT_TRUE(testAsset2.IsError());
|
||||
}
|
||||
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -24,6 +24,13 @@ namespace UnitTest
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(EmptyAsset, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(EmptyAsset, "{098E3F7F-13AC-414B-9B4E-49B5AD1BD7FE}", AZ::Data::AssetData);
|
||||
|
||||
EmptyAsset(
|
||||
const AZ::Data::AssetId& assetId = AZ::Data::AssetId(),
|
||||
AZ::Data::AssetData::AssetStatus status = AZ::Data::AssetData::AssetStatus::NotLoaded)
|
||||
: AZ::Data::AssetData(assetId, status)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// EmptyAssetWithNoHandler: no data contained within, and no AssetHandler registered for this type
|
||||
|
||||
@@ -104,6 +104,11 @@ namespace JsonSerializationTests
|
||||
AZ::AllocatorInstance<AZ::PoolAllocator>::Destroy();
|
||||
}
|
||||
|
||||
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context) override
|
||||
{
|
||||
context->RegisterGenericType<Asset>();
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<AZ::BaseJsonSerializer> CreateSerializer() override
|
||||
{
|
||||
return AZStd::make_shared<AZ::Data::AssetJsonSerializer>();
|
||||
@@ -130,6 +135,7 @@ namespace JsonSerializationTests
|
||||
auto instance = AZStd::make_shared<Asset>();
|
||||
instance->Create(id, false);
|
||||
instance->SetHint("TestFile");
|
||||
instance->SetAutoLoadBehavior(AZ::Data::AssetLoadBehavior::PreLoad);
|
||||
return instance;
|
||||
}
|
||||
|
||||
@@ -153,6 +159,7 @@ namespace JsonSerializationTests
|
||||
"guid": "{BBEAC89F-8BAD-4A9D-BF6E-D0DF84A8DFD6}",
|
||||
"subId": 1
|
||||
},
|
||||
"loadBehavior": "PreLoad",
|
||||
"assetHint": "TestFile"
|
||||
})";
|
||||
}
|
||||
|
||||
@@ -49,9 +49,13 @@ namespace UnitTest
|
||||
// ComponentApplicationBus
|
||||
AZ::ComponentApplication* GetApplication() override { return nullptr; }
|
||||
void RegisterComponentDescriptor(const AZ::ComponentDescriptor*) override {}
|
||||
void UnregisterComponentDescriptor(const AZ::ComponentDescriptor*) override {}
|
||||
void RegisterEntityAddedEventHandler(AZ::EntityAddedEvent::Handler&) override {}
|
||||
void RegisterEntityRemovedEventHandler(AZ::EntityRemovedEvent::Handler&) override {}
|
||||
void UnregisterComponentDescriptor(const AZ::ComponentDescriptor*) override {}
|
||||
void RegisterEntityActivatedEventHandler(AZ::EntityActivatedEvent::Handler&) override {}
|
||||
void RegisterEntityDeactivatedEventHandler(AZ::EntityDeactivatedEvent::Handler&) override {}
|
||||
void SignalEntityActivated(AZ::Entity*) override {}
|
||||
void SignalEntityDeactivated(AZ::Entity*) override {}
|
||||
bool AddEntity(AZ::Entity*) override { return true; }
|
||||
bool RemoveEntity(AZ::Entity*) override { return true; }
|
||||
bool DeleteEntity(const AZ::EntityId&) override { return true; }
|
||||
|
||||
@@ -13,24 +13,25 @@
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Console/Console.h>
|
||||
|
||||
#include <AzCore/Settings/SettingsRegistryImpl.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
using namespace UnitTest;
|
||||
|
||||
AZ_CVAR(bool, testBool, false, nullptr, ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(char, testChar, 0, nullptr, ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(int8_t, testInt8, 0, nullptr, ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(int16_t, testInt16, 0, nullptr, ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(int32_t, testInt32, 0, nullptr, ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(int64_t, testInt64, 0, nullptr, ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(uint8_t, testUInt8, 0, nullptr, ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(bool, testBool, false, nullptr, ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(char, testChar, 0, nullptr, ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(int8_t, testInt8, 0, nullptr, ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(int16_t, testInt16, 0, nullptr, ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(int32_t, testInt32, 0, nullptr, ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(int64_t, testInt64, 0, nullptr, ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(uint8_t, testUInt8, 0, nullptr, ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(uint16_t, testUInt16, 0, nullptr, ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(uint32_t, testUInt32, 0, nullptr, ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(uint64_t, testUInt64, 0, nullptr, ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, testFloat, 0, nullptr, ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(double, testDouble, 0, nullptr, ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, testFloat, 0, nullptr, ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(double, testDouble, 0, nullptr, ConsoleFunctorFlags::Null, "");
|
||||
|
||||
AZ_CVAR(AZ::CVarFixedString, testString, "default", nullptr, ConsoleFunctorFlags::Null, "");
|
||||
|
||||
@@ -189,7 +190,7 @@ namespace AZ
|
||||
|
||||
TEST_F(ConsoleTests, CVar_GetSetTest_Vector2)
|
||||
{
|
||||
testVec2 = AZ::Vector2{ 0.0f, 0.0f};
|
||||
testVec2 = AZ::Vector2{ 0.0f, 0.0f };
|
||||
TestCVarHelper(testVec2, "testVec2", "testVec2 1 1", "testVec2 asdf", AZ::Vector2(100, 100), AZ::Vector2(0, 0), AZ::Vector2(1, 1));
|
||||
}
|
||||
|
||||
@@ -350,3 +351,245 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace ConsoleSettingsRegistryTests
|
||||
{
|
||||
//! ConfigFile MergeUtils Test
|
||||
struct ConfigFileParams
|
||||
{
|
||||
AZStd::string_view m_testConfigFileName;
|
||||
AZStd::string_view m_testConfigContents;
|
||||
};
|
||||
class ConsoleSettingsRegistryFixture
|
||||
: public UnitTest::ScopedAllocatorSetupFixture
|
||||
, public ::testing::WithParamInterface<ConfigFileParams>
|
||||
{
|
||||
public:
|
||||
void SetUp() override
|
||||
{
|
||||
m_registry = AZStd::make_unique<AZ::SettingsRegistryImpl>();
|
||||
// Store off the old global settings registry to restore after each test
|
||||
m_oldSettingsRegistry = AZ::SettingsRegistry::Get();
|
||||
if (m_oldSettingsRegistry != nullptr)
|
||||
{
|
||||
AZ::SettingsRegistry::Unregister(m_oldSettingsRegistry);
|
||||
}
|
||||
AZ::SettingsRegistry::Register(m_registry.get());
|
||||
|
||||
// Create a TestFile in the Test Directory
|
||||
m_testFolder = AZ::IO::FixedMaxPath(AZ::Utils::GetExecutableDirectory()) / "ConsoleTestFolder";
|
||||
auto configFileParams = GetParam();
|
||||
CreateTestFile(m_testFolder / configFileParams.m_testConfigFileName, configFileParams.m_testConfigContents);
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
// Remove the Test Directory
|
||||
DeleteFolderRecursive(m_testFolder);
|
||||
|
||||
// Restore the old global settings registry
|
||||
AZ::SettingsRegistry::Unregister(m_registry.get());
|
||||
if (m_oldSettingsRegistry != nullptr)
|
||||
{
|
||||
AZ::SettingsRegistry::Register(m_oldSettingsRegistry);
|
||||
m_oldSettingsRegistry = {};
|
||||
}
|
||||
m_registry.reset();
|
||||
}
|
||||
|
||||
void TestClassFunc(const AZ::ConsoleCommandContainer& someStrings)
|
||||
{
|
||||
m_stringArgCount = someStrings.size();
|
||||
}
|
||||
|
||||
AZ_CONSOLEFUNC(ConsoleSettingsRegistryFixture, TestClassFunc, AZ::ConsoleFunctorFlags::Null, "");
|
||||
|
||||
static void DeleteFolderRecursive(const AZ::IO::PathView& path)
|
||||
{
|
||||
auto callback = [&path](AZStd::string_view filename, bool isFile) -> bool
|
||||
{
|
||||
if (isFile)
|
||||
{
|
||||
auto filePath = AZ::IO::FixedMaxPath(path) / filename;
|
||||
AZ::IO::SystemFile::Delete(filePath.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (filename != "." && filename != "..")
|
||||
{
|
||||
auto folderPath = AZ::IO::FixedMaxPath(path) / filename;
|
||||
DeleteFolderRecursive(folderPath);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
auto searchPath = AZ::IO::FixedMaxPath(path) / "*";
|
||||
AZ::IO::SystemFile::FindFiles(searchPath.c_str(), callback);
|
||||
AZ::IO::SystemFile::DeleteDir(AZ::IO::FixedMaxPathString(path.Native()).c_str());
|
||||
}
|
||||
|
||||
static bool CreateTestFile(const AZ::IO::FixedMaxPath& testPath, AZStd::string_view content)
|
||||
{
|
||||
AZ::IO::SystemFile file;
|
||||
if (!file.Open(testPath.c_str(), AZ::IO::SystemFile::OpenMode::SF_OPEN_CREATE
|
||||
| AZ::IO::SystemFile::SF_OPEN_CREATE_PATH | AZ::IO::SystemFile::SF_OPEN_WRITE_ONLY))
|
||||
{
|
||||
AZ_Assert(false, "Unable to open test file for writing: %s", testPath.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (file.Write(content.data(), content.size()) != content.size())
|
||||
{
|
||||
AZ_Assert(false, "Unable to write content to test file: %s", testPath.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
size_t m_stringArgCount{};
|
||||
AZStd::unique_ptr<AZ::SettingsRegistryInterface> m_registry;
|
||||
AZ::IO::FixedMaxPath m_testFolder;
|
||||
|
||||
private:
|
||||
AZ::SettingsRegistryInterface* m_oldSettingsRegistry{};
|
||||
};
|
||||
|
||||
static bool s_consoleFreeFunctionInvoked = false;
|
||||
static void TestSettingsRegistryFreeFunc(const AZ::ConsoleCommandContainer& someStrings)
|
||||
{
|
||||
EXPECT_TRUE(someStrings.empty());
|
||||
s_consoleFreeFunctionInvoked = true;
|
||||
}
|
||||
|
||||
AZ_CONSOLEFREEFUNC(TestSettingsRegistryFreeFunc, AZ::ConsoleFunctorFlags::Null, "");
|
||||
|
||||
TEST_P(ConsoleSettingsRegistryFixture, Console_AbleToLoadSettingsFile_Successfully)
|
||||
{
|
||||
AZ::Console testConsole(*m_registry);
|
||||
testConsole.LinkDeferredFunctors(AZ::ConsoleFunctorBase::GetDeferredHead());
|
||||
AZ::Interface<AZ::IConsole>::Register(&testConsole);
|
||||
AZ_CVAR_SCOPED(int32_t, testInit, 0, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
s_consoleFreeFunctionInvoked = false;
|
||||
testInit = {};
|
||||
AZ::testChar = {};
|
||||
AZ::testBool = {};
|
||||
AZ::testInt8 = {};
|
||||
AZ::testInt16 = {};
|
||||
AZ::testInt32 = {};
|
||||
AZ::testInt64 = {};
|
||||
AZ::testUInt8 = {};
|
||||
AZ::testUInt16 = {};
|
||||
AZ::testUInt32 = {};
|
||||
AZ::testUInt64 = {};
|
||||
AZ::testFloat= {};
|
||||
AZ::testDouble = {};
|
||||
AZ::testString = {};
|
||||
|
||||
auto configFileParams = GetParam();
|
||||
auto testFilePath = m_testFolder / configFileParams.m_testConfigFileName;
|
||||
EXPECT_TRUE(AZ::IO::SystemFile::Exists(testFilePath.c_str()));
|
||||
testConsole.ExecuteConfigFile(testFilePath.Native());
|
||||
EXPECT_TRUE(s_consoleFreeFunctionInvoked);
|
||||
EXPECT_EQ(3, testInit);
|
||||
EXPECT_TRUE(static_cast<bool>(AZ::testBool));
|
||||
EXPECT_EQ('Q', AZ::testChar);
|
||||
EXPECT_EQ(24, AZ::testInt8);
|
||||
EXPECT_EQ(-32, AZ::testInt16);
|
||||
EXPECT_EQ(41, AZ::testInt32);
|
||||
EXPECT_EQ(-51, AZ::testInt64);
|
||||
EXPECT_EQ(3, AZ::testUInt8);
|
||||
EXPECT_EQ(5, AZ::testUInt16);
|
||||
EXPECT_EQ(6, AZ::testUInt32);
|
||||
EXPECT_EQ(0xFFFF'FFFF'FFFF'FFFF, AZ::testUInt64);
|
||||
EXPECT_FLOAT_EQ(1.0f, AZ::testFloat);
|
||||
EXPECT_DOUBLE_EQ(2, AZ::testDouble);
|
||||
EXPECT_STREQ("Stable", static_cast<AZ::CVarFixedString>(AZ::testString).c_str());
|
||||
EXPECT_EQ(3, m_stringArgCount);
|
||||
AZ::Interface<AZ::IConsole>::Unregister(&testConsole);
|
||||
}
|
||||
|
||||
|
||||
static constexpr AZStd::string_view UserINIStyleContent =
|
||||
R"(
|
||||
testInit = 3
|
||||
testBool true
|
||||
testChar Q
|
||||
testInt8 24
|
||||
testInt16 -32
|
||||
testInt32 41
|
||||
testInt64 -51
|
||||
testUInt8 3
|
||||
testUInt16 5
|
||||
testUInt32 6
|
||||
testUInt64 18446744073709551615
|
||||
testFloat 1.0
|
||||
testDouble 2
|
||||
testString Stable
|
||||
ConsoleSettingsRegistryFixture.testClassFunc Foo Bar Baz
|
||||
TestSettingsRegistryFreeFunc
|
||||
)";
|
||||
|
||||
static constexpr AZStd::string_view UserJsonMergePatchContent =
|
||||
R"(
|
||||
{
|
||||
"Amazon": {
|
||||
"AzCore": {
|
||||
"Runtime": {
|
||||
"ConsoleCommands": {
|
||||
"testInit": 3,
|
||||
"testBool": true,
|
||||
"testChar": "Q",
|
||||
"testInt8": 24,
|
||||
"testInt16": -32,
|
||||
"testInt32": 41,
|
||||
"testInt64": -51,
|
||||
"testUInt8": 3,
|
||||
"testUInt16": 5,
|
||||
"testUInt32": 6,
|
||||
"testUInt64": 18446744073709551615,
|
||||
"testFloat": 1.0,
|
||||
"testDouble": 2,
|
||||
"testString": "Stable",
|
||||
"ConsoleSettingsRegistryFixture.testClassFunc": "Foo Bar Baz",
|
||||
"TestSettingsRegistryFreeFunc": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)";
|
||||
static constexpr AZStd::string_view UserJsonPatchContent =
|
||||
R"(
|
||||
[
|
||||
{ "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testInit", "value": 3 },
|
||||
{ "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testBool", "value": true },
|
||||
{ "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testChar", "value": "Q" },
|
||||
{ "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testInt8", "value": 24 },
|
||||
{ "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testInt16", "value": -32 },
|
||||
{ "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testInt32", "value": 41 },
|
||||
{ "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testInt64", "value": -51 },
|
||||
{ "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testUInt8", "value": 3 },
|
||||
{ "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testUInt16", "value": 5 },
|
||||
{ "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testUInt32", "value": 6 },
|
||||
{ "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testUInt64", "value": 18446744073709551615 },
|
||||
{ "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testFloat", "value": 1.0 },
|
||||
{ "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testDouble", "value": 2 },
|
||||
{ "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testString", "value": "Stable" },
|
||||
{ "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/ConsoleSettingsRegistryFixture.testClassFunc", "value": "Foo Bar Baz" },
|
||||
{ "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/TestSettingsRegistryFreeFunc", "value": "" }
|
||||
]
|
||||
)";
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
ExecuteCommandFromSettingsFile,
|
||||
ConsoleSettingsRegistryFixture,
|
||||
::testing::Values(
|
||||
ConfigFileParams{"user.cfg", UserINIStyleContent},
|
||||
ConfigFileParams{"user.setreg", UserJsonMergePatchContent},
|
||||
ConfigFileParams{"user.setregpatch", UserJsonPatchContent}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -139,4 +139,4 @@ TEST_F(EntityIdTests, Constructor_Default_IsInvalidEntityId)
|
||||
AZ::EntityId entityId;
|
||||
AZ::EntityId invalidId(AZ::EntityId::InvalidEntityId);
|
||||
EXPECT_EQ((AZ::u64)entityId, (AZ::u64)invalidId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,4 +172,4 @@ namespace UnitTest
|
||||
|
||||
testSystem1.Deactivate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <AzCore/Math/Transform.h>
|
||||
#include <AzCore/Math/Quaternion.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AZTestShared/Math/MathTestHelpers.h>
|
||||
|
||||
using namespace AZ;
|
||||
|
||||
@@ -251,19 +252,19 @@ namespace UnitTest
|
||||
m2.SetRow(2, 13.0f, 14.0f, 15.0f);
|
||||
|
||||
Matrix3x3 m3 = m1 * m2;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(66.0f, 72.0f, 78.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(156.0f, 171.0f, 186.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(246.0f, 270.0f, 294.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(66.0f, 72.0f, 78.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(156.0f, 171.0f, 186.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(246.0f, 270.0f, 294.0f)));
|
||||
|
||||
Matrix3x3 m4 = m1;
|
||||
m4 *= m2;
|
||||
AZ_TEST_ASSERT(m4.GetRow(0).IsClose(Vector3(66.0f, 72.0f, 78.0f)));
|
||||
AZ_TEST_ASSERT(m4.GetRow(1).IsClose(Vector3(156.0f, 171.0f, 186.0f)));
|
||||
AZ_TEST_ASSERT(m4.GetRow(2).IsClose(Vector3(246.0f, 270.0f, 294.0f)));
|
||||
EXPECT_THAT(m4.GetRow(0), IsClose(Vector3(66.0f, 72.0f, 78.0f)));
|
||||
EXPECT_THAT(m4.GetRow(1), IsClose(Vector3(156.0f, 171.0f, 186.0f)));
|
||||
EXPECT_THAT(m4.GetRow(2), IsClose(Vector3(246.0f, 270.0f, 294.0f)));
|
||||
m3 = m1.TransposedMultiply(m2);
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(138.0f, 150.0f, 162.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(168.0f, 183.0f, 198.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(198.0f, 216.0f, 234.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(138.0f, 150.0f, 162.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(168.0f, 183.0f, 198.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(198.0f, 216.0f, 234.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x3, TestVectorMultiplication)
|
||||
@@ -277,11 +278,11 @@ namespace UnitTest
|
||||
m2.SetRow(1, 10.0f, 11.0f, 12.0f);
|
||||
m2.SetRow(2, 13.0f, 14.0f, 15.0f);
|
||||
|
||||
AZ_TEST_ASSERT((m1 * Vector3(1.0f, 2.0f, 3.0f)).IsClose(Vector3(14.0f, 32.0f, 50.0f)));
|
||||
EXPECT_THAT((m1 * Vector3(1.0f, 2.0f, 3.0f)), IsClose(Vector3(14.0f, 32.0f, 50.0f)));
|
||||
Vector3 v1(1.0f, 2.0f, 3.0f);
|
||||
AZ_TEST_ASSERT((v1 * m1).IsClose(Vector3(30.0f, 36.0f, 42.0f)));
|
||||
EXPECT_THAT((v1 * m1), IsClose(Vector3(30.0f, 36.0f, 42.0f)));
|
||||
v1 *= m1;
|
||||
AZ_TEST_ASSERT(v1.IsClose(Vector3(30.0f, 36.0f, 42.0f)));
|
||||
EXPECT_THAT(v1, IsClose(Vector3(30.0f, 36.0f, 42.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x3, TestSum)
|
||||
@@ -296,15 +297,15 @@ namespace UnitTest
|
||||
m2.SetRow(2, 13.0f, 14.0f, 15.0f);
|
||||
|
||||
Matrix3x3 m3 = m1 + m2;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(20.0f, 22.0f, 24.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(20.0f, 22.0f, 24.0f)));
|
||||
|
||||
m3 = m1;
|
||||
m3 += m2;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(20.0f, 22.0f, 24.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(20.0f, 22.0f, 24.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x3, TestDifference)
|
||||
@@ -319,14 +320,14 @@ namespace UnitTest
|
||||
m2.SetRow(2, 13.0f, 14.0f, 15.0f);
|
||||
|
||||
Matrix3x3 m3 = m1 - m2;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
m3 = m1;
|
||||
m3 -= m2;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x3, TestScalarMultiplication)
|
||||
@@ -341,18 +342,18 @@ namespace UnitTest
|
||||
m2.SetRow(2, 13.0f, 14.0f, 15.0f);
|
||||
|
||||
Matrix3x3 m3 = m1 * 2.0f;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(2.0f, 4.0f, 6.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(2.0f, 4.0f, 6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
m3 = m1;
|
||||
m3 *= 2.0f;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(2.0f, 4.0f, 6.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(2.0f, 4.0f, 6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
m3 = 2.0f * m1;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(2.0f, 4.0f, 6.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(2.0f, 4.0f, 6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x3, TestScalarDivision)
|
||||
@@ -367,18 +368,32 @@ namespace UnitTest
|
||||
m2.SetRow(2, 13.0f, 14.0f, 15.0f);
|
||||
|
||||
Matrix3x3 m3 = m1 / 0.5f;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(2.0f, 4.0f, 6.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(2.0f, 4.0f, 6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
m3 = m1;
|
||||
m3 /= 0.5f;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(2.0f, 4.0f, 6.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
m3 = -m1;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(-1.0f, -2.0f, -3.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(-4.0f, -5.0f, -6.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(-7.0f, -8.0f, -9.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(2.0f, 4.0f, 6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x3, TestNegation)
|
||||
{
|
||||
Matrix3x3 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f);
|
||||
m1.SetRow(1, 4.0f, 5.0f, 6.0f);
|
||||
m1.SetRow(2, 7.0f, 8.0f, 9.0f);
|
||||
EXPECT_THAT(-(-m1), IsClose(m1));
|
||||
EXPECT_THAT(-Matrix3x3::CreateZero(), IsClose(Matrix3x3::CreateZero()));
|
||||
|
||||
Matrix3x3 m2 = -m1;
|
||||
EXPECT_THAT(m2.GetRow(0), IsClose(Vector3(-1.0f, -2.0f, -3.0f)));
|
||||
EXPECT_THAT(m2.GetRow(1), IsClose(Vector3(-4.0f, -5.0f, -6.0f)));
|
||||
EXPECT_THAT(m2.GetRow(2), IsClose(Vector3(-7.0f, -8.0f, -9.0f)));
|
||||
|
||||
Matrix3x3 m3 = m1 + (-m1);
|
||||
EXPECT_THAT(m3, IsClose(Matrix3x3::CreateZero()));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x3, TestTranspose)
|
||||
@@ -425,11 +440,33 @@ namespace UnitTest
|
||||
TEST(MATH_Matrix3x3, TestScaleAccess)
|
||||
{
|
||||
Matrix3x3 m1 = Matrix3x3::CreateRotationX(DegToRad(40.0f)) * Matrix3x3::CreateScale(Vector3(2.0f, 3.0f, 4.0f));
|
||||
AZ_TEST_ASSERT(m1.RetrieveScale().IsClose(Vector3(2.0f, 3.0f, 4.0f)));
|
||||
AZ_TEST_ASSERT(m1.ExtractScale().IsClose(Vector3(2.0f, 3.0f, 4.0f)));
|
||||
AZ_TEST_ASSERT(m1.RetrieveScale().IsClose(Vector3::CreateOne()));
|
||||
EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3(2.0f, 3.0f, 4.0f)));
|
||||
EXPECT_THAT(m1.ExtractScale(), IsClose(Vector3(2.0f, 3.0f, 4.0f)));
|
||||
EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3::CreateOne()));
|
||||
m1.MultiplyByScale(Vector3(3.0f, 4.0f, 5.0f));
|
||||
AZ_TEST_ASSERT(m1.RetrieveScale().IsClose(Vector3(3.0f, 4.0f, 5.0f)));
|
||||
EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3(3.0f, 4.0f, 5.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x3, TestScaleSqAccess)
|
||||
{
|
||||
Matrix3x3 m1 = Matrix3x3::CreateRotationX(DegToRad(40.0f)) * Matrix3x3::CreateScale(Vector3(2.0f, 3.0f, 4.0f));
|
||||
EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3(4.0f, 9.0f, 16.0f)));
|
||||
m1.ExtractScale();
|
||||
EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3::CreateOne()));
|
||||
m1.MultiplyByScale(Vector3(3.0f, 4.0f, 5.0f));
|
||||
EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3(9.0f, 16.0f, 25.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x3, TestReciprocalScaled)
|
||||
{
|
||||
Matrix3x3 orthogonalMatrix = Matrix3x3::CreateRotationX(DegToRad(40.0f));
|
||||
EXPECT_THAT(orthogonalMatrix.GetReciprocalScaled(), IsClose(orthogonalMatrix));
|
||||
const AZ::Vector3 scale(2.8f, 0.7f, 1.3f);
|
||||
AZ::Matrix3x3 scaledMatrix = orthogonalMatrix;
|
||||
scaledMatrix.MultiplyByScale(scale);
|
||||
AZ::Matrix3x3 reciprocalScaledMatrix = orthogonalMatrix;
|
||||
reciprocalScaledMatrix.MultiplyByScale(scale.GetReciprocal());
|
||||
EXPECT_THAT(scaledMatrix.GetReciprocalScaled(), IsClose(reciprocalScaledMatrix));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x3, TestPolarDecomposition)
|
||||
|
||||
@@ -467,21 +467,136 @@ namespace UnitTest
|
||||
EXPECT_THAT(matrix.Multiply3x3(axisDirection), IsClose(forwardDirection));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x4, MultiplyByMatrix3x4)
|
||||
TEST(MATH_Matrix3x4, TestMatrixMultiplication)
|
||||
{
|
||||
const AZ::Matrix3x4 matrix1 = AZ::Matrix3x4::CreateFromValue(1.2f);
|
||||
const AZ::Matrix3x4 matrix2 = AZ::Matrix3x4::CreateDiagonal(AZ::Vector3(1.3f, 1.5f, 0.4f));
|
||||
const AZ::Matrix3x4 matrix3 = AZ::Matrix3x4::CreateFromQuaternionAndTranslation(
|
||||
AZ::Quaternion(0.42f, 0.46f, -0.66f, 0.42f), AZ::Vector3(2.8f, -3.7f, 1.6f));
|
||||
const AZ::Matrix3x4 matrix4 = AZ::Matrix3x4::CreateRotationX(-0.7f) * AZ::Matrix3x4::CreateScale(AZ::Vector3(0.6f, 1.3f, 0.7f));
|
||||
AZ::Matrix3x4 matrix5 = matrix1;
|
||||
matrix5 *= matrix4;
|
||||
const AZ::Vector3 vector(1.9f, 2.3f, 0.2f);
|
||||
EXPECT_TRUE((matrix1 * (matrix2 * matrix3)).IsClose((matrix1 * matrix2) * matrix3));
|
||||
EXPECT_THAT((matrix3 * matrix4) * vector, IsClose(matrix3 * (matrix4 * vector)));
|
||||
EXPECT_TRUE((matrix2 * AZ::Matrix3x4::Identity()).IsClose(matrix2));
|
||||
EXPECT_TRUE((matrix3 * AZ::Matrix3x4::Identity()).IsClose(AZ::Matrix3x4::Identity() * matrix3));
|
||||
EXPECT_TRUE(matrix5.IsClose(matrix1 * matrix4));
|
||||
AZ::Matrix3x4 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
AZ::Matrix3x4 m2;
|
||||
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
|
||||
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
|
||||
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
|
||||
AZ::Matrix3x4 m3 = m1 * m2;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(74.0f, 80.0f, 86.0f, 96.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(206.0f, 224.0f, 242.0f, 268.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(338.0f, 368.0f, 398.0f, 440.0f)));
|
||||
AZ::Matrix3x4 m4 = m1;
|
||||
m4 *= m2;
|
||||
EXPECT_THAT(m4.GetRow(0), IsClose(AZ::Vector4(74.0f, 80.0f, 86.0f, 96.0f)));
|
||||
EXPECT_THAT(m4.GetRow(1), IsClose(AZ::Vector4(206.0f, 224.0f, 242.0f, 268.0f)));
|
||||
EXPECT_THAT(m4.GetRow(2), IsClose(AZ::Vector4(338.0f, 368.0f, 398.0f, 440.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x4, TestSum)
|
||||
{
|
||||
AZ::Matrix3x4 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
AZ::Matrix3x4 m2;
|
||||
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
|
||||
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
|
||||
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
|
||||
|
||||
AZ::Matrix3x4 m3 = m1 + m2;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(8.0f, 10.0f, 12.0f, 14.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(16.0f, 18.0f, 20.0f, 22.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(24.0f, 26.0f, 28.0f, 30.0f)));
|
||||
|
||||
m3 = m1;
|
||||
m3 += m2;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(8.0f, 10.0f, 12.0f, 14.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(16.0f, 18.0f, 20.0f, 22.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(24.0f, 26.0f, 28.0f, 30.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x4, TestDifference)
|
||||
{
|
||||
AZ::Matrix3x4 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
AZ::Matrix3x4 m2;
|
||||
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
|
||||
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
|
||||
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
|
||||
|
||||
AZ::Matrix3x4 m3 = m1 - m2;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
m3 = m1;
|
||||
m3 -= m2;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x4, TestScalarMultiplication)
|
||||
{
|
||||
AZ::Matrix3x4 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
AZ::Matrix3x4 m2;
|
||||
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
|
||||
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
|
||||
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
|
||||
|
||||
AZ::Matrix3x4 m3 = m1 * 2.0f;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
|
||||
m3 = m1;
|
||||
m3 *= 2.0f;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
|
||||
m3 = 2.0f * m1;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x4, TestScalarDivision)
|
||||
{
|
||||
AZ::Matrix3x4 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
AZ::Matrix3x4 m2;
|
||||
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
|
||||
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
|
||||
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
|
||||
|
||||
AZ::Matrix3x4 m3 = m1 / 0.5f;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
|
||||
m3 = m1;
|
||||
m3 /= 0.5f;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x4, TestNegation)
|
||||
{
|
||||
AZ::Matrix3x4 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
EXPECT_THAT(-(-m1), IsClose(m1));
|
||||
EXPECT_THAT(-AZ::Matrix3x4::CreateZero(), IsClose(AZ::Matrix3x4::CreateZero()));
|
||||
|
||||
AZ::Matrix3x4 m2 = -m1;
|
||||
EXPECT_THAT(m2.GetRow(0), IsClose(AZ::Vector4(-1.0f, -2.0f, -3.0f, -4.0f)));
|
||||
EXPECT_THAT(m2.GetRow(1), IsClose(AZ::Vector4(-5.0f, -6.0f, -7.0f, -8.0f)));
|
||||
EXPECT_THAT(m2.GetRow(2), IsClose(AZ::Vector4(-9.0f, -10.0f, -11.0f, -12.0f)));
|
||||
|
||||
AZ::Matrix3x4 m3 = m1 + (-m1);
|
||||
EXPECT_THAT(m3, IsClose(AZ::Matrix3x4::CreateZero()));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x4, MultiplyByVector3)
|
||||
@@ -652,6 +767,34 @@ namespace UnitTest
|
||||
EXPECT_THAT(scaledMatrix.RetrieveScale(), IsClose(AZ::Vector3::CreateOne()));
|
||||
}
|
||||
|
||||
TEST_P(Matrix3x4ScaleFixture, ScaleSq)
|
||||
{
|
||||
const AZ::Matrix3x4 orthogonalMatrix = GetParam();
|
||||
EXPECT_THAT(orthogonalMatrix.RetrieveScaleSq(), IsClose(AZ::Vector3::CreateOne()));
|
||||
AZ::Matrix3x4 unscaledMatrix = orthogonalMatrix;
|
||||
unscaledMatrix.ExtractScale();
|
||||
EXPECT_THAT(unscaledMatrix.RetrieveScaleSq(), IsClose(AZ::Vector3::CreateOne()));
|
||||
const AZ::Vector3 scale(2.8f, 0.7f, 1.3f);
|
||||
AZ::Matrix3x4 scaledMatrix = orthogonalMatrix;
|
||||
scaledMatrix.MultiplyByScale(scale);
|
||||
EXPECT_THAT(scaledMatrix.RetrieveScaleSq(), IsClose(scale * scale));
|
||||
EXPECT_THAT(scaledMatrix.RetrieveScaleSq(), IsClose(scaledMatrix.RetrieveScale() * scaledMatrix.RetrieveScale()));
|
||||
scaledMatrix.ExtractScale();
|
||||
EXPECT_THAT(scaledMatrix.RetrieveScaleSq(), IsClose(AZ::Vector3::CreateOne()));
|
||||
}
|
||||
|
||||
TEST_P(Matrix3x4ScaleFixture, GetReciprocalScaled)
|
||||
{
|
||||
const AZ::Matrix3x4 orthogonalMatrix = GetParam();
|
||||
EXPECT_THAT(orthogonalMatrix.GetReciprocalScaled(), IsClose(orthogonalMatrix));
|
||||
const AZ::Vector3 scale(2.8f, 0.7f, 1.3f);
|
||||
AZ::Matrix3x4 scaledMatrix = orthogonalMatrix;
|
||||
scaledMatrix.MultiplyByScale(scale);
|
||||
AZ::Matrix3x4 reciprocalScaledMatrix = orthogonalMatrix;
|
||||
reciprocalScaledMatrix.MultiplyByScale(scale.GetReciprocal());
|
||||
EXPECT_THAT(scaledMatrix.GetReciprocalScaled(), IsClose(reciprocalScaledMatrix));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(MATH_Matrix3x4, Matrix3x4ScaleFixture, ::testing::ValuesIn(MathTestData::OrthogonalMatrix3x4s));
|
||||
|
||||
TEST(MATH_Matrix3x4, IsOrthogonal)
|
||||
|
||||
@@ -246,16 +246,16 @@ namespace UnitTest
|
||||
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
|
||||
m2.SetRow(3, 19.0f, 20.0f, 21.0f, 22.0f);
|
||||
Matrix4x4 m3 = m1 * m2;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector4(150.0f, 160.0f, 170.0f, 180.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector4(358.0f, 384.0f, 410.0f, 436.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector4(566.0f, 608.0f, 650.0f, 692.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(3).IsClose(Vector4(774.0f, 832.0f, 890.0f, 948.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(150.0f, 160.0f, 170.0f, 180.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(358.0f, 384.0f, 410.0f, 436.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(566.0f, 608.0f, 650.0f, 692.0f)));
|
||||
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(774.0f, 832.0f, 890.0f, 948.0f)));
|
||||
Matrix4x4 m4 = m1;
|
||||
m4 *= m2;
|
||||
AZ_TEST_ASSERT(m4.GetRow(0).IsClose(Vector4(150.0f, 160.0f, 170.0f, 180.0f)));
|
||||
AZ_TEST_ASSERT(m4.GetRow(1).IsClose(Vector4(358.0f, 384.0f, 410.0f, 436.0f)));
|
||||
AZ_TEST_ASSERT(m4.GetRow(2).IsClose(Vector4(566.0f, 608.0f, 650.0f, 692.0f)));
|
||||
AZ_TEST_ASSERT(m4.GetRow(3).IsClose(Vector4(774.0f, 832.0f, 890.0f, 948.0f)));
|
||||
EXPECT_THAT(m4.GetRow(0), IsClose(Vector4(150.0f, 160.0f, 170.0f, 180.0f)));
|
||||
EXPECT_THAT(m4.GetRow(1), IsClose(Vector4(358.0f, 384.0f, 410.0f, 436.0f)));
|
||||
EXPECT_THAT(m4.GetRow(2), IsClose(Vector4(566.0f, 608.0f, 650.0f, 692.0f)));
|
||||
EXPECT_THAT(m4.GetRow(3), IsClose(Vector4(774.0f, 832.0f, 890.0f, 948.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix4x4, TestVectorMultiplication)
|
||||
@@ -265,18 +265,148 @@ namespace UnitTest
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f);
|
||||
AZ_TEST_ASSERT((m1 * Vector3(1.0f, 2.0f, 3.0f)).IsClose(Vector3(18.0f, 46.0f, 74.0f)));
|
||||
AZ_TEST_ASSERT((m1 * Vector4(1.0f, 2.0f, 3.0f, 4.0f)).IsClose(Vector4(30.0f, 70.0f, 110.0f, 150.0f)));
|
||||
AZ_TEST_ASSERT(m1.TransposedMultiply3x3(Vector3(1.0f, 2.0f, 3.0f)).IsClose(Vector3(38.0f, 44.0f, 50.0f)));
|
||||
AZ_TEST_ASSERT(m1.Multiply3x3(Vector3(1.0f, 2.0f, 3.0f)).IsClose(Vector3(14.0f, 38.0f, 62.0f)));
|
||||
EXPECT_THAT((m1 * Vector3(1.0f, 2.0f, 3.0f)), IsClose(Vector3(18.0f, 46.0f, 74.0f)));
|
||||
EXPECT_THAT((m1 * Vector4(1.0f, 2.0f, 3.0f, 4.0f)), IsClose(Vector4(30.0f, 70.0f, 110.0f, 150.0f)));
|
||||
EXPECT_THAT(m1.TransposedMultiply3x3(Vector3(1.0f, 2.0f, 3.0f)), IsClose(Vector3(38.0f, 44.0f, 50.0f)));
|
||||
EXPECT_THAT(m1.Multiply3x3(Vector3(1.0f, 2.0f, 3.0f)), IsClose(Vector3(14.0f, 38.0f, 62.0f)));
|
||||
Vector3 v1(1.0f, 2.0f, 3.0f);
|
||||
AZ_TEST_ASSERT((v1 * m1).IsClose(Vector3(51.0f, 58.0f, 65.0f)));
|
||||
EXPECT_THAT((v1 * m1), IsClose(Vector3(51.0f, 58.0f, 65.0f)));
|
||||
v1 *= m1;
|
||||
AZ_TEST_ASSERT(v1.IsClose(Vector3(51.0f, 58.0f, 65.0f)));
|
||||
EXPECT_THAT(v1, IsClose(Vector3(51.0f, 58.0f, 65.0f)));
|
||||
Vector4 v2(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
AZ_TEST_ASSERT((v2 * m1).IsClose(Vector4(90.0f, 100.0f, 110.0f, 120.0f)));
|
||||
EXPECT_THAT((v2 * m1), IsClose(Vector4(90.0f, 100.0f, 110.0f, 120.0f)));
|
||||
v2 *= m1;
|
||||
AZ_TEST_ASSERT(v2.IsClose(Vector4(90.0f, 100.0f, 110.0f, 120.0f)));
|
||||
EXPECT_THAT(v2, IsClose(Vector4(90.0f, 100.0f, 110.0f, 120.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix4x4, TestSum)
|
||||
{
|
||||
Matrix4x4 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f);
|
||||
Matrix4x4 m2;
|
||||
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
|
||||
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
|
||||
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
|
||||
m2.SetRow(3, 19.0f, 20.0f, 21.0f, 22.0f);
|
||||
|
||||
Matrix4x4 m3 = m1 + m2;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(8.0f, 10.0f, 12.0f, 14.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(16.0f, 18.0f, 20.0f, 22.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(24.0f, 26.0f, 28.0f, 30.0f)));
|
||||
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(32.0f, 34.0f, 36.0f, 38.0f)));
|
||||
|
||||
m3 = m1;
|
||||
m3 += m2;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(8.0f, 10.0f, 12.0f, 14.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(16.0f, 18.0f, 20.0f, 22.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(24.0f, 26.0f, 28.0f, 30.0f)));
|
||||
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(32.0f, 34.0f, 36.0f, 38.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix4x4, TestDifference)
|
||||
{
|
||||
Matrix4x4 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f);
|
||||
Matrix4x4 m2;
|
||||
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
|
||||
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
|
||||
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
|
||||
m2.SetRow(3, 19.0f, 20.0f, 21.0f, 22.0f);
|
||||
|
||||
Matrix4x4 m3 = m1 - m2;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
m3 = m1;
|
||||
m3 -= m2;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix4x4, TestScalarMultiplication)
|
||||
{
|
||||
Matrix4x4 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f);
|
||||
Matrix4x4 m2;
|
||||
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
|
||||
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
|
||||
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
|
||||
m2.SetRow(3, 19.0f, 20.0f, 21.0f, 22.0f);
|
||||
|
||||
Matrix4x4 m3 = m1 * 2.0f;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
|
||||
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(26.0f, 28.0f, 30.0f, 32.0f)));
|
||||
m3 = m1;
|
||||
m3 *= 2.0f;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
|
||||
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(26.0f, 28.0f, 30.0f, 32.0f)));
|
||||
m3 = 2.0f * m1;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
|
||||
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(26.0f, 28.0f, 30.0f, 32.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix4x4, TestScalarDivision)
|
||||
{
|
||||
Matrix4x4 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f);
|
||||
Matrix4x4 m2;
|
||||
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
|
||||
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
|
||||
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
|
||||
m2.SetRow(3, 19.0f, 20.0f, 21.0f, 22.0f);
|
||||
|
||||
Matrix4x4 m3 = m1 / 0.5f;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
|
||||
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(26.0f, 28.0f, 30.0f, 32.0f)));
|
||||
m3 = m1;
|
||||
m3 /= 0.5f;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
|
||||
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(26.0f, 28.0f, 30.0f, 32.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix4x4, TestNegation)
|
||||
{
|
||||
Matrix4x4 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f);
|
||||
EXPECT_THAT(-(-m1), IsClose(m1));
|
||||
EXPECT_THAT(-Matrix4x4::CreateZero(), IsClose(Matrix4x4::CreateZero()));
|
||||
|
||||
Matrix4x4 m2 = -m1;
|
||||
EXPECT_THAT(m2.GetRow(0), IsClose(Vector4(-1.0f, -2.0f, -3.0f, -4.0f)));
|
||||
EXPECT_THAT(m2.GetRow(1), IsClose(Vector4(-5.0f, -6.0f, -7.0f, -8.0f)));
|
||||
EXPECT_THAT(m2.GetRow(2), IsClose(Vector4(-9.0f, -10.0f, -11.0f, -12.0f)));
|
||||
EXPECT_THAT(m2.GetRow(3), IsClose(Vector4(-13.0f, -14.0f, -15.0f, -16.0f)));
|
||||
|
||||
Matrix4x4 m3 = m1 + (-m1);
|
||||
EXPECT_THAT(m3, IsClose(Matrix4x4::CreateZero()));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix4x4, TestTranspose)
|
||||
@@ -368,4 +498,36 @@ namespace UnitTest
|
||||
m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f);
|
||||
AZ_TEST_ASSERT(m1.GetDiagonal() == Vector4(1.0f, 6.0f, 11.0f, 16.0f));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix4x4, TestScaleAccess)
|
||||
{
|
||||
Matrix4x4 m1 = Matrix4x4::CreateRotationX(DegToRad(40.0f)) * Matrix4x4::CreateScale(Vector3(2.0f, 3.0f, 4.0f));
|
||||
EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3(2.0f, 3.0f, 4.0f)));
|
||||
EXPECT_THAT(m1.ExtractScale(), IsClose(Vector3(2.0f, 3.0f, 4.0f)));
|
||||
EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3::CreateOne()));
|
||||
m1.MultiplyByScale(Vector3(3.0f, 4.0f, 5.0f));
|
||||
EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3(3.0f, 4.0f, 5.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix4x4, TestScaleSqAccess)
|
||||
{
|
||||
Matrix4x4 m1 = Matrix4x4::CreateRotationX(DegToRad(40.0f)) * Matrix4x4::CreateScale(Vector3(2.0f, 3.0f, 4.0f));
|
||||
EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3(4.0f, 9.0f, 16.0f)));
|
||||
m1.ExtractScale();
|
||||
EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3::CreateOne()));
|
||||
m1.MultiplyByScale(Vector3(3.0f, 4.0f, 5.0f));
|
||||
EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3(9.0f, 16.0f, 25.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix4x4, TestReciprocalScaled)
|
||||
{
|
||||
Matrix4x4 orthogonalMatrix = Matrix4x4::CreateRotationX(DegToRad(40.0f));
|
||||
EXPECT_THAT(orthogonalMatrix.GetReciprocalScaled(), IsClose(orthogonalMatrix));
|
||||
const AZ::Vector3 scale(2.8f, 0.7f, 1.3f);
|
||||
AZ::Matrix4x4 scaledMatrix = orthogonalMatrix;
|
||||
scaledMatrix.MultiplyByScale(scale);
|
||||
AZ::Matrix4x4 reciprocalScaledMatrix = orthogonalMatrix;
|
||||
reciprocalScaledMatrix.MultiplyByScale(scale.GetReciprocal());
|
||||
EXPECT_THAT(scaledMatrix.GetReciprocalScaled(), IsClose(reciprocalScaledMatrix));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,4 @@ public:
|
||||
virtual const char* GetModuleName() = 0;
|
||||
};
|
||||
|
||||
using ModuleTestRequestBus = AZ::EBus<ModuleTestRequests>;
|
||||
using ModuleTestRequestBus = AZ::EBus<ModuleTestRequests>;
|
||||
|
||||
@@ -386,4 +386,4 @@ namespace UnitTest
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // #if !defined(AZCORE_EXCLUDE_LUA)
|
||||
#endif // #if !defined(AZCORE_EXCLUDE_LUA)
|
||||
|
||||
@@ -1232,6 +1232,10 @@ namespace UnitTest
|
||||
void UnregisterComponentDescriptor(const ComponentDescriptor*) override { }
|
||||
void RegisterEntityAddedEventHandler(EntityAddedEvent::Handler&) override { }
|
||||
void RegisterEntityRemovedEventHandler(EntityRemovedEvent::Handler&) override { }
|
||||
void RegisterEntityActivatedEventHandler(EntityActivatedEvent::Handler&) override { }
|
||||
void RegisterEntityDeactivatedEventHandler(EntityDeactivatedEvent::Handler&) override { }
|
||||
void SignalEntityActivated(Entity*) override { }
|
||||
void SignalEntityDeactivated(Entity*) override { }
|
||||
bool AddEntity(Entity*) override { return false; }
|
||||
bool RemoveEntity(Entity*) override { return false; }
|
||||
bool DeleteEntity(const EntityId&) override { return false; }
|
||||
@@ -1252,6 +1256,7 @@ namespace UnitTest
|
||||
m_serializeContext.reset(aznew AZ::SerializeContext());
|
||||
|
||||
ComponentApplicationBus::Handler::BusConnect();
|
||||
AZ::Interface<AZ::ComponentApplicationRequests>::Register(this);
|
||||
|
||||
AZ::AllocatorInstance<AZ::PoolAllocator>::Create();
|
||||
AZ::AllocatorInstance<AZ::ThreadPoolAllocator>::Create();
|
||||
@@ -1270,6 +1275,7 @@ namespace UnitTest
|
||||
AZ::AllocatorInstance<AZ::ThreadPoolAllocator>::Destroy();
|
||||
AZ::AllocatorInstance<AZ::PoolAllocator>::Destroy();
|
||||
|
||||
AZ::Interface<AZ::ComponentApplicationRequests>::Unregister(this);
|
||||
ComponentApplicationBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ namespace JsonSerializationTests
|
||||
EXPECT_EQ(42, value);
|
||||
}
|
||||
|
||||
TEST_F(BaseJsonSerializerTests, ContinueLoading_PointerInstance_ValueLoadedCorrectly)
|
||||
TEST_F(BaseJsonSerializerTests, ContinueLoading_ToPointerInstance_ValueLoadedCorrectly)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
@@ -119,13 +119,62 @@ namespace JsonSerializationTests
|
||||
int value = 0;
|
||||
int* ptrValue = &value;
|
||||
|
||||
ResultCode result = ContinueLoading(&ptrValue, azrtti_typeid<int>(), json, *m_jsonDeserializationContext, Flags::ResolvePointer);
|
||||
ResultCode result =
|
||||
ContinueLoading(&ptrValue, azrtti_typeid<int>(), json, *m_jsonDeserializationContext, ContinuationFlags::ResolvePointer);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
ASSERT_NE(nullptr, ptrValue);
|
||||
EXPECT_EQ(42, value);
|
||||
}
|
||||
|
||||
TEST_F(BaseJsonSerializerTests, ContinueLoading_ToNullPointer_ValueLoadedCorrectly)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
rapidjson::Value json;
|
||||
json.Set(42);
|
||||
int* ptrValue = nullptr;
|
||||
|
||||
ResultCode result =
|
||||
ContinueLoading(&ptrValue, azrtti_typeid<int>(), json, *m_jsonDeserializationContext, ContinuationFlags::ResolvePointer);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
ASSERT_NE(nullptr, ptrValue);
|
||||
EXPECT_EQ(42, *ptrValue);
|
||||
|
||||
azfree(ptrValue, AZ::SystemAllocator, sizeof(int), alignof(int));
|
||||
}
|
||||
|
||||
TEST_F(BaseJsonSerializerTests, ContinueLoading_DefaultToNullPointer_ValueLoadedCorrectly)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
rapidjson::Value json(rapidjson::kObjectType);
|
||||
int* ptrValue = nullptr;
|
||||
|
||||
ResultCode result =
|
||||
ContinueLoading(&ptrValue, azrtti_typeid<int>(), json, *m_jsonDeserializationContext, ContinuationFlags::ResolvePointer);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
ASSERT_NE(nullptr, ptrValue);
|
||||
|
||||
azfree(ptrValue, AZ::SystemAllocator, sizeof(int), alignof(int));
|
||||
}
|
||||
|
||||
TEST_F(BaseJsonSerializerTests, ContinueLoading_NullDeletesObject_ValueLoadedCorrectly)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
rapidjson::Value json(rapidjson::kNullType);
|
||||
int* ptrValue = reinterpret_cast<int*>(azmalloc(sizeof(int), alignof(int), AZ::SystemAllocator));
|
||||
|
||||
ResultCode result =
|
||||
ContinueLoading(&ptrValue, azrtti_typeid<int>(), json, *m_jsonDeserializationContext, ContinuationFlags::ResolvePointer);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
ASSERT_EQ(nullptr, ptrValue);
|
||||
}
|
||||
|
||||
//
|
||||
// ContinueStoring
|
||||
//
|
||||
@@ -149,21 +198,82 @@ namespace JsonSerializationTests
|
||||
int value = 42;
|
||||
int* ptrValue = &value;
|
||||
|
||||
ResultCode result = ContinueStoring(*m_jsonDocument, &ptrValue, nullptr, azrtti_typeid<int>(), *m_jsonSerializationContext,
|
||||
Flags::ResolvePointer);
|
||||
ResultCode result = ContinueStoring(
|
||||
*m_jsonDocument, &ptrValue, nullptr, azrtti_typeid<int>(), *m_jsonSerializationContext, ContinuationFlags::ResolvePointer);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
Expect_DocStrEq("42");
|
||||
}
|
||||
|
||||
TEST_F(BaseJsonSerializerTests, ContinueStoring_StorePointerToFullDefaultedInstance_ValueStoredCorrectly)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
int value = 42;
|
||||
int* ptrValue = &value;
|
||||
int value2 = 42;
|
||||
int* defaultPtrValue = &value2;
|
||||
|
||||
ResultCode result = ContinueStoring(
|
||||
*m_jsonDocument, &ptrValue, &defaultPtrValue, azrtti_typeid<int>(), *m_jsonSerializationContext,
|
||||
ContinuationFlags::ResolvePointer);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
Expect_DocStrEq("{}");
|
||||
}
|
||||
|
||||
TEST_F(BaseJsonSerializerTests, ContinueStoring_StorePointerToNullptr_ValueStoredCorrectly)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
int* ptrValue = nullptr;
|
||||
|
||||
ResultCode result = ContinueStoring(
|
||||
*m_jsonDocument, &ptrValue, nullptr, azrtti_typeid<int>(), *m_jsonSerializationContext, ContinuationFlags::ResolvePointer);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
Expect_DocStrEq("null");
|
||||
}
|
||||
|
||||
TEST_F(BaseJsonSerializerTests, ContinueStoring_StorePointerToNullptrWithValueDefault_ValueStoredCorrectly)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
int* ptrValue = nullptr;
|
||||
int value2 = 42;
|
||||
int* defaultPtrValue = &value2;
|
||||
|
||||
ResultCode result = ContinueStoring(
|
||||
*m_jsonDocument, &ptrValue, &defaultPtrValue, azrtti_typeid<int>(), *m_jsonSerializationContext,
|
||||
ContinuationFlags::ResolvePointer);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
Expect_DocStrEq("null");
|
||||
}
|
||||
|
||||
TEST_F(BaseJsonSerializerTests, ContinueStoring_StorePointerToNullptrWithNullPtrDefault_NullPtrIsStored)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
int* ptrValue = nullptr;
|
||||
int* defaultPtrValue = nullptr;
|
||||
|
||||
ResultCode result = ContinueStoring(
|
||||
*m_jsonDocument, &ptrValue, &defaultPtrValue, azrtti_typeid<int>(), *m_jsonSerializationContext,
|
||||
ContinuationFlags::ResolvePointer);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
Expect_DocStrEq("null");
|
||||
}
|
||||
|
||||
TEST_F(BaseJsonSerializerTests, ContinueStoring_ReplaceDefault_ValueStoredCorrectly)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
int value = 42;
|
||||
|
||||
ResultCode result = ContinueStoring(*m_jsonDocument, &value, nullptr, azrtti_typeid<int>(), *m_jsonSerializationContext,
|
||||
Flags::ReplaceDefault);
|
||||
ResultCode result = ContinueStoring(
|
||||
*m_jsonDocument, &value, nullptr, azrtti_typeid<int>(), *m_jsonSerializationContext, ContinuationFlags::ReplaceDefault);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
Expect_DocStrEq("42");
|
||||
@@ -177,7 +287,7 @@ namespace JsonSerializationTests
|
||||
int* ptrValue = &value;
|
||||
|
||||
ResultCode result = ContinueStoring(*m_jsonDocument, &ptrValue, nullptr, azrtti_typeid<int>(), *m_jsonSerializationContext,
|
||||
Flags::ResolvePointer | Flags::ReplaceDefault);
|
||||
ContinuationFlags::ResolvePointer | ContinuationFlags::ReplaceDefault);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
Expect_DocStrEq("42");
|
||||
@@ -190,8 +300,8 @@ namespace JsonSerializationTests
|
||||
int value = 42;
|
||||
AZ::Uuid unknownType("{09AE3CEC-EBFC-41EC-A7F6-949721521716}");
|
||||
|
||||
ResultCode result = ContinueStoring(*m_jsonDocument, &value, nullptr, unknownType, *m_jsonSerializationContext,
|
||||
Flags::ReplaceDefault);
|
||||
ResultCode result =
|
||||
ContinueStoring(*m_jsonDocument, &value, nullptr, unknownType, *m_jsonSerializationContext, ContinuationFlags::ReplaceDefault);
|
||||
|
||||
EXPECT_EQ(Processing::Halted, result.GetProcessing());
|
||||
}
|
||||
|
||||
@@ -449,6 +449,46 @@ namespace JsonSerializationTests
|
||||
|
||||
}
|
||||
|
||||
TEST_F(JsonSerializationTests, Load_PrimitiveForInheritedClass_LoadsCorrectClass)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
using namespace ::testing;
|
||||
|
||||
AZStd::string json = AZStd::string::format(R"(
|
||||
{
|
||||
"%s": "SimpleInheritence",
|
||||
"base_var": -88.0,
|
||||
"var1": 88,
|
||||
"var2": 42
|
||||
})",
|
||||
AZ::JsonSerialization::TypeIdFieldIdentifier);
|
||||
m_jsonDocument->Parse(json.c_str());
|
||||
|
||||
SimpleInheritence::Reflect(m_serializeContext, true);
|
||||
m_serializeContext->RegisterGenericType<AZStd::unique_ptr<BaseClass>>();
|
||||
m_jsonRegistrationContext->Serializer<JsonSerializerMock>()->HandlesType<SimpleInheritence>();
|
||||
JsonSerializerMock* mock =
|
||||
reinterpret_cast<JsonSerializerMock*>(m_jsonRegistrationContext->GetSerializerForType(azrtti_typeid<SimpleInheritence>()));
|
||||
EXPECT_CALL(*mock, Load(_, _, _, _))
|
||||
.Times(Exactly(1))
|
||||
.WillRepeatedly(Return(Result(m_deserializationSettings->m_reporting, "Test", Tasks::ReadField, Outcomes::Success, "")));
|
||||
|
||||
AZStd::unique_ptr<BaseClass> instance;
|
||||
ResultCode result = AZ::JsonSerialization::Load(instance, *m_jsonDocument, *m_deserializationSettings);
|
||||
EXPECT_NE(Processing::Halted, result.GetProcessing());
|
||||
|
||||
EXPECT_EQ(azrtti_typeid<SimpleInheritence>(), azrtti_typeid(*instance));
|
||||
|
||||
m_serializeContext->EnableRemoveReflection();
|
||||
SimpleInheritence::Reflect(m_serializeContext, true);
|
||||
m_serializeContext->DisableRemoveReflection();
|
||||
|
||||
m_jsonRegistrationContext->EnableRemoveReflection();
|
||||
m_serializeContext->RegisterGenericType<AZStd::unique_ptr<BaseClass>>();
|
||||
m_jsonRegistrationContext->Serializer<JsonSerializerMock>()->HandlesType<SimpleInheritence>();
|
||||
m_jsonRegistrationContext->DisableRemoveReflection();
|
||||
}
|
||||
|
||||
TEST_F(JsonSerializationTests, Store_TemplatedClassWithRegisteredHandler_StoreOnHandlerCalled)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
@@ -474,6 +514,52 @@ namespace JsonSerializationTests
|
||||
m_jsonRegistrationContext->DisableRemoveReflection();
|
||||
}
|
||||
|
||||
TEST_F(JsonSerializationTests, Store_PrimitiveForInheritedClass_StoreSucceedsAndTypeIdIsAdded)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
using namespace ::testing;
|
||||
|
||||
SimpleInheritence::Reflect(m_serializeContext, true);
|
||||
m_serializeContext->RegisterGenericType<AZStd::unique_ptr<BaseClass>>();
|
||||
m_jsonRegistrationContext->Serializer<JsonSerializerMock>()->HandlesType<SimpleInheritence>();
|
||||
JsonSerializerMock* mock =
|
||||
reinterpret_cast<JsonSerializerMock*>(m_jsonRegistrationContext->GetSerializerForType(azrtti_typeid<SimpleInheritence>()));
|
||||
EXPECT_CALL(*mock, Store(_, _, _, _, _))
|
||||
.Times(Exactly(1))
|
||||
.WillRepeatedly(Invoke([](rapidjson::Value& output, const void*, const void*, const AZ::Uuid&, AZ::JsonSerializerContext& context)
|
||||
{
|
||||
// Insert some values to allow verification later on.
|
||||
output.SetObject();
|
||||
output.AddMember("base_var", -88.0, context.GetJsonAllocator());
|
||||
output.AddMember("var1", 88, context.GetJsonAllocator());
|
||||
output.AddMember("var2", 42, context.GetJsonAllocator());
|
||||
return context.Report(Tasks::WriteValue, Outcomes::Success, "");
|
||||
}));
|
||||
|
||||
AZStd::unique_ptr<BaseClass> instance{ aznew SimpleInheritence() };
|
||||
ResultCode result = AZ::JsonSerialization::Store(*m_jsonDocument, m_jsonDocument->GetAllocator(), instance, *m_serializationSettings);
|
||||
EXPECT_NE(Processing::Halted, result.GetProcessing());
|
||||
|
||||
AZStd::string compare = AZStd::string::format(R"(
|
||||
{
|
||||
"%s": "SimpleInheritence",
|
||||
"base_var": -88.0,
|
||||
"var1": 88,
|
||||
"var2": 42
|
||||
})",
|
||||
AZ::JsonSerialization::TypeIdFieldIdentifier);
|
||||
Expect_DocStrEq(compare.c_str());
|
||||
|
||||
m_serializeContext->EnableRemoveReflection();
|
||||
m_serializeContext->RegisterGenericType<AZStd::unique_ptr<BaseClass>>();
|
||||
SimpleInheritence::Reflect(m_serializeContext, true);
|
||||
m_serializeContext->DisableRemoveReflection();
|
||||
|
||||
m_jsonRegistrationContext->EnableRemoveReflection();
|
||||
m_jsonRegistrationContext->Serializer<JsonSerializerMock>()->HandlesType<SimpleInheritence>();
|
||||
m_jsonRegistrationContext->DisableRemoveReflection();
|
||||
}
|
||||
|
||||
TEST_F(JsonSerializationTests, Store_StoreWithNullPtr_ReturnsCatastrophic)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
@@ -90,9 +90,14 @@ namespace JsonSerializationTests
|
||||
virtual ~JsonSerializerConformityTestDescriptor() = default;
|
||||
|
||||
virtual AZStd::shared_ptr<AZ::BaseJsonSerializer> CreateSerializer() = 0;
|
||||
|
||||
|
||||
//! Create an instance of the target type with all values set to default.
|
||||
virtual AZStd::shared_ptr<T> CreateDefaultInstance() = 0;
|
||||
//! Create an instance of the target type that constructed with default constructor.
|
||||
//! This will be the same instance that Json Serialization creates for dynamic types. Typically it's the same
|
||||
//! as from CreateDefaultInstance(), except of types, such as pointers, that need to do minimal (de)serialization
|
||||
//! to initialize an object.
|
||||
virtual AZStd::shared_ptr<T> CreateDefaultConstructedInstance() { return CreateDefaultInstance(); }
|
||||
//! Create an instance of the target type with some values set and some kept on defaults.
|
||||
//! If the target type doesn't support partial specialization this can be ignored and
|
||||
//! tests for partial support will be skipped.
|
||||
@@ -316,10 +321,10 @@ namespace JsonSerializationTests
|
||||
ASSERT_FALSE(this->m_jsonDocument->HasParseError());
|
||||
|
||||
auto serializer = this->m_description.CreateSerializer();
|
||||
auto instance = this->m_description.CreateDefaultInstance();
|
||||
auto instance = this->m_description.CreateDefaultConstructedInstance();
|
||||
auto original = this->m_description.CreateDefaultInstance();
|
||||
|
||||
ResultCode result = serializer->Load(instance.get(), azrtti_typeid(*original),
|
||||
ResultCode result = serializer->Load(instance.get(), azrtti_typeid(*instance),
|
||||
*this->m_jsonDocument, *this->m_jsonDeserializationContext);
|
||||
|
||||
if (this->m_features.m_mandatoryFields.empty())
|
||||
@@ -339,6 +344,42 @@ namespace JsonSerializationTests
|
||||
}
|
||||
}
|
||||
|
||||
TYPED_TEST_P(JsonSerializerConformityTests, Load_DeserializeEmptyObjectThroughMainLoad_SucceedsAndObjectMatchesDefaults)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
if (this->m_features.SupportsJsonType(rapidjson::kObjectType))
|
||||
{
|
||||
this->m_jsonDocument->Parse("{}");
|
||||
ASSERT_FALSE(this->m_jsonDocument->HasParseError());
|
||||
|
||||
auto serializer = this->m_description.CreateSerializer();
|
||||
auto instance = this->m_description.CreateDefaultConstructedInstance();
|
||||
auto original = this->m_description.CreateDefaultInstance();
|
||||
|
||||
AZ::JsonDeserializerSettings settings;
|
||||
settings.m_serializeContext = this->m_jsonDeserializationContext->GetSerializeContext();
|
||||
settings.m_registrationContext = this->m_jsonDeserializationContext->GetRegistrationContext();
|
||||
ResultCode result = AZ::JsonSerialization::Load(
|
||||
instance.get(), azrtti_typeid(*instance), *this->m_jsonDocument, settings);
|
||||
|
||||
if (this->m_features.m_mandatoryFields.empty())
|
||||
{
|
||||
EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome());
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
}
|
||||
else
|
||||
{
|
||||
EXPECT_EQ(Outcomes::Unsupported, result.GetOutcome());
|
||||
bool validProcessing =
|
||||
result.GetProcessing() == Processing::Altered ||
|
||||
result.GetProcessing() == Processing::PartialAlter;
|
||||
EXPECT_TRUE(validProcessing);
|
||||
}
|
||||
EXPECT_TRUE(this->m_description.AreEqual(*original, *instance));
|
||||
}
|
||||
}
|
||||
|
||||
TYPED_TEST_P(JsonSerializerConformityTests, Load_DeserializeEmptyArray_SucceedsAndObjectMatchesDefaults)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
@@ -349,7 +390,7 @@ namespace JsonSerializationTests
|
||||
ASSERT_FALSE(this->m_jsonDocument->HasParseError());
|
||||
|
||||
auto serializer = this->m_description.CreateSerializer();
|
||||
auto instance = this->m_description.CreateDefaultInstance();
|
||||
auto instance = this->m_description.CreateDefaultConstructedInstance();
|
||||
auto original = this->m_description.CreateDefaultInstance();
|
||||
|
||||
this->m_deserializationSettings->m_clearContainers = false;
|
||||
@@ -384,7 +425,7 @@ namespace JsonSerializationTests
|
||||
ASSERT_FALSE(this->m_jsonDocument->HasParseError());
|
||||
|
||||
auto serializer = this->m_description.CreateSerializer();
|
||||
auto instance = this->m_description.CreateDefaultInstance();
|
||||
auto instance = this->m_description.CreateDefaultConstructedInstance();
|
||||
auto original = this->m_description.CreateDefaultInstance();
|
||||
|
||||
this->m_deserializationSettings->m_clearContainers = true;
|
||||
@@ -488,7 +529,7 @@ namespace JsonSerializationTests
|
||||
ASSERT_FALSE(this->m_jsonDocument->HasParseError());
|
||||
|
||||
auto serializer = this->m_description.CreateSerializer();
|
||||
auto instance = this->m_description.CreateDefaultInstance();
|
||||
auto instance = this->m_description.CreateDefaultConstructedInstance();
|
||||
auto compare = this->m_description.CreateFullySetInstance();
|
||||
|
||||
ResultCode result = serializer->Load(instance.get(), azrtti_typeid(*instance),
|
||||
@@ -499,6 +540,28 @@ namespace JsonSerializationTests
|
||||
EXPECT_TRUE(this->m_description.AreEqual(*instance, *compare));
|
||||
}
|
||||
|
||||
TYPED_TEST_P(JsonSerializerConformityTests, Load_DeserializeFullySetInstanceThroughMainLoad_SucceedsAndObjectMatchesFullySetInstance)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
AZStd::string_view json = this->m_description.GetJsonFor_Load_DeserializeFullySetInstance();
|
||||
this->m_jsonDocument->Parse(json.data());
|
||||
ASSERT_FALSE(this->m_jsonDocument->HasParseError());
|
||||
|
||||
auto serializer = this->m_description.CreateSerializer();
|
||||
auto instance = this->m_description.CreateDefaultConstructedInstance();
|
||||
auto compare = this->m_description.CreateFullySetInstance();
|
||||
|
||||
AZ::JsonDeserializerSettings settings;
|
||||
settings.m_serializeContext = this->m_jsonDeserializationContext->GetSerializeContext();
|
||||
settings.m_registrationContext = this->m_jsonDeserializationContext->GetRegistrationContext();
|
||||
ResultCode result = AZ::JsonSerialization::Load(instance.get(), azrtti_typeid(*instance), *this->m_jsonDocument, settings);
|
||||
|
||||
EXPECT_EQ(Outcomes::Success, result.GetOutcome());
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
EXPECT_TRUE(this->m_description.AreEqual(*instance, *compare));
|
||||
}
|
||||
|
||||
TYPED_TEST_P(JsonSerializerConformityTests, Load_DeserializeWithMissingMandatoryField_LoadFailedAndUnsupportedReported)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
@@ -518,7 +581,7 @@ namespace JsonSerializationTests
|
||||
ASSERT_NE(this->m_jsonDocument->MemberEnd(), memberToErase);
|
||||
this->m_jsonDocument->RemoveMember(memberToErase);
|
||||
|
||||
auto instance = this->m_description.CreateDefaultInstance();
|
||||
auto instance = this->m_description.CreateDefaultConstructedInstance();
|
||||
|
||||
ResultCode result = serializer->Load(instance.get(), azrtti_typeid(*instance),
|
||||
*this->m_jsonDocument, *this->m_jsonDeserializationContext);
|
||||
@@ -546,7 +609,7 @@ namespace JsonSerializationTests
|
||||
ASSERT_FALSE(this->m_jsonDocument->HasParseError());
|
||||
|
||||
auto serializer = this->m_description.CreateSerializer();
|
||||
auto instance = this->m_description.CreateDefaultInstance();
|
||||
auto instance = this->m_description.CreateDefaultConstructedInstance();
|
||||
auto compare = this->m_description.CreatePartialDefaultInstance();
|
||||
ASSERT_NE(nullptr, compare);
|
||||
|
||||
@@ -567,7 +630,7 @@ namespace JsonSerializationTests
|
||||
ASSERT_FALSE(this->m_jsonDocument->HasParseError());
|
||||
|
||||
auto serializer = this->m_description.CreateSerializer();
|
||||
auto instance = this->m_description.CreateDefaultInstance();
|
||||
auto instance = this->m_description.CreateDefaultConstructedInstance();
|
||||
|
||||
AZ::ScopedContextReporter reporter(*this->m_jsonDeserializationContext,
|
||||
[](AZStd::string_view message, ResultCode result, AZStd::string_view path) -> ResultCode
|
||||
@@ -604,7 +667,7 @@ namespace JsonSerializationTests
|
||||
}
|
||||
|
||||
auto serializer = this->m_description.CreateSerializer();
|
||||
auto instance = this->m_description.CreateDefaultInstance();
|
||||
auto instance = this->m_description.CreateDefaultConstructedInstance();
|
||||
auto compare = this->m_description.CreateFullySetInstance();
|
||||
|
||||
ResultCode result = serializer->Load(instance.get(), azrtti_typeid(*instance),
|
||||
@@ -635,7 +698,7 @@ namespace JsonSerializationTests
|
||||
}
|
||||
|
||||
auto serializer = this->m_description.CreateSerializer();
|
||||
auto instance = this->m_description.CreateDefaultInstance();
|
||||
auto instance = this->m_description.CreateDefaultConstructedInstance();
|
||||
|
||||
ResultCode result = serializer->Load(instance.get(), azrtti_typeid(*instance),
|
||||
*this->m_jsonDocument, *this->m_jsonDeserializationContext);
|
||||
@@ -693,6 +756,36 @@ namespace JsonSerializationTests
|
||||
}
|
||||
}
|
||||
|
||||
TYPED_TEST_P(JsonSerializerConformityTests, Store_SerializeDefaultInstanceThroughMainStore_EmptyJsonReturned)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
auto serializer = this->m_description.CreateSerializer();
|
||||
auto instance = this->m_description.CreateDefaultInstance();
|
||||
rapidjson::Value convertedValue = this->CreateExplicitDefault();
|
||||
|
||||
AZ::JsonSerializerSettings settings;
|
||||
settings.m_serializeContext = this->m_jsonDeserializationContext->GetSerializeContext();
|
||||
settings.m_registrationContext = this->m_jsonDeserializationContext->GetRegistrationContext();
|
||||
ResultCode result = AZ::JsonSerialization::Store(
|
||||
convertedValue, this->m_jsonDocument->GetAllocator(), instance.get(), instance.get(), azrtti_typeid(*instance), settings);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
if (convertedValue.IsObject() && !this->m_features.m_mandatoryFields.empty())
|
||||
{
|
||||
ASSERT_EQ(convertedValue.MemberCount(), this->m_features.m_mandatoryFields.size());
|
||||
for (const AZStd::string& mandatoryField : this->m_features.m_mandatoryFields)
|
||||
{
|
||||
EXPECT_NE(convertedValue.MemberEnd(), convertedValue.FindMember(mandatoryField.c_str()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome());
|
||||
this->Expect_ExplicitDefault(convertedValue);
|
||||
}
|
||||
}
|
||||
|
||||
TYPED_TEST_P(JsonSerializerConformityTests, Store_SerializeWithDefaultsKept_FullyWrittenJson)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
@@ -924,6 +1017,20 @@ namespace JsonSerializationTests
|
||||
}
|
||||
}
|
||||
|
||||
TYPED_TEST_P(JsonSerializerConformityTests, GetOperationsFlags_ManualDefaultSetIfNeeded_ManualDefaultOperationSetIfMandatoryFieldsAreDeclared)
|
||||
{
|
||||
if (this->m_features.SupportsJsonType(rapidjson::kObjectType))
|
||||
{
|
||||
if (!this->m_features.m_mandatoryFields.empty())
|
||||
{
|
||||
auto serializer = this->m_description.CreateSerializer();
|
||||
bool manuallyHandlesDefaults = (serializer->GetOperationsFlags() & AZ::BaseJsonSerializer::OperationFlags::ManualDefault) ==
|
||||
AZ::BaseJsonSerializer::OperationFlags::ManualDefault;
|
||||
EXPECT_TRUE(manuallyHandlesDefaults);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_TYPED_TEST_CASE_P(JsonSerializerConformityTests,
|
||||
Registration_SerializerIsRegisteredWithContext_SerializerFound,
|
||||
|
||||
@@ -934,14 +1041,16 @@ namespace JsonSerializationTests
|
||||
Load_InvalidTypeOfArrayType_ReturnsUnsupported,
|
||||
Load_InvalidTypeOfStringType_ReturnsUnsupported,
|
||||
Load_InvalidTypeOfNumberType_ReturnsUnsupported,
|
||||
|
||||
|
||||
Load_DeserializeUnreflectedType_ReturnsUnsupported,
|
||||
Load_DeserializeEmptyObject_SucceedsAndObjectMatchesDefaults,
|
||||
Load_DeserializeEmptyObjectThroughMainLoad_SucceedsAndObjectMatchesDefaults,
|
||||
Load_DeserializeEmptyArray_SucceedsAndObjectMatchesDefaults,
|
||||
Load_DeserializeEmptyArrayWithClearEnabled_SucceedsAndObjectMatchesDefaults,
|
||||
Load_DeserializeEmptyArrayWithClearedTarget_SucceedsAndObjectMatchesDefaults,
|
||||
Load_InterruptClearingTarget_ContainerIsNotCleared,
|
||||
Load_DeserializeFullySetInstance_SucceedsAndObjectMatchesFullySetInstance,
|
||||
Load_DeserializeFullySetInstanceThroughMainLoad_SucceedsAndObjectMatchesFullySetInstance,
|
||||
Load_DeserializePartialInstance_SucceedsAndObjectMatchesParialInstance,
|
||||
Load_DeserializeWithMissingMandatoryField_LoadFailedAndUnsupportedReported,
|
||||
Load_InsertAdditionalData_SucceedsAndObjectMatchesFullySetInstance,
|
||||
@@ -950,6 +1059,7 @@ namespace JsonSerializationTests
|
||||
|
||||
Store_SerializeUnreflectedType_ReturnsUnsupported,
|
||||
Store_SerializeDefaultInstance_EmptyJsonReturned,
|
||||
Store_SerializeDefaultInstanceThroughMainStore_EmptyJsonReturned,
|
||||
Store_SerializeWithDefaultsKept_FullyWrittenJson,
|
||||
Store_SerializeFullySetInstance_StoredSuccessfullyAndJsonMatches,
|
||||
Store_SerializeWithoutDefault_StoredSuccessfullyAndJsonMatches,
|
||||
@@ -957,10 +1067,12 @@ namespace JsonSerializationTests
|
||||
Store_SerializePartialInstance_StoredSuccessfullyAndJsonMatches,
|
||||
Store_SerializeEmptyArray_StoredSuccessfullyAndJsonMatches,
|
||||
Store_HaltedThroughCallback_StoreFailsAndHaltReported,
|
||||
|
||||
|
||||
StoreLoad_RoundTripWithPartialDefault_IdenticalInstances,
|
||||
StoreLoad_RoundTripWithFullSet_IdenticalInstances,
|
||||
StoreLoad_RoundTripWithDefaultsKept_IdenticalInstances);
|
||||
StoreLoad_RoundTripWithDefaultsKept_IdenticalInstances,
|
||||
|
||||
GetOperationsFlags_ManualDefaultSetIfNeeded_ManualDefaultOperationSetIfMandatoryFieldsAreDeclared);
|
||||
} // namespace JsonSerializationTests
|
||||
|
||||
namespace AZ
|
||||
|
||||
@@ -0,0 +1,562 @@
|
||||
/*
|
||||
* 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 this
|
||||
* 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/Casting/numeric_cast.h>
|
||||
#include <AzCore/Math/MathMatrixSerializer.h>
|
||||
#include <AzCore/Math/Matrix3x3.h>
|
||||
#include <AzCore/Math/Matrix3x4.h>
|
||||
#include <AzCore/Math/Matrix4x4.h>
|
||||
#include <AzCore/Math/Random.h>
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
#include <AzCore/Serialization/Json/DoubleSerializer.h>
|
||||
#include <AzCore/Serialization/Json/RegistrationContext.h>
|
||||
#include <Tests/Serialization/Json/BaseJsonSerializerFixture.h>
|
||||
#include <Tests/Serialization/Json/JsonSerializerConformityTests.h>
|
||||
|
||||
namespace JsonSerializationTests
|
||||
{
|
||||
namespace DataHelper
|
||||
{
|
||||
// Build Matrix
|
||||
|
||||
template <typename MatrixType>
|
||||
MatrixType BuildMatrixRotationWithSale(const AZ::Vector3& angles, float scale)
|
||||
{
|
||||
// start a matrix with angle degrees
|
||||
const AZ::Vector3 eulerRadians = AZ::Vector3DegToRad(angles);
|
||||
const auto rotX = MatrixType::CreateRotationX(eulerRadians.GetX());
|
||||
const auto rotY = MatrixType::CreateRotationY(eulerRadians.GetY());
|
||||
const auto rotZ = MatrixType::CreateRotationZ(eulerRadians.GetZ());
|
||||
auto matrix = rotX * rotY * rotZ;
|
||||
|
||||
// apply a scale
|
||||
matrix.MultiplyByScale(AZ::Vector3{ scale });
|
||||
return matrix;
|
||||
}
|
||||
|
||||
template <typename MatrixType>
|
||||
MatrixType BuildMatrix(const AZ::Vector3& angles, float scale, const AZ::Vector3& translation)
|
||||
{
|
||||
auto matrix = BuildMatrixRotationWithSale<MatrixType>(angles, scale);
|
||||
matrix.SetTranslation(translation);
|
||||
return matrix;
|
||||
}
|
||||
|
||||
template <>
|
||||
AZ::Matrix3x3 BuildMatrix(const AZ::Vector3& angles, float scale, const AZ::Vector3&)
|
||||
{
|
||||
return BuildMatrixRotationWithSale<AZ::Matrix3x3>(angles, scale);
|
||||
}
|
||||
|
||||
// Arbitrary Matrix
|
||||
|
||||
template <typename MatrixType>
|
||||
MatrixType CreateArbitraryMatrixRotationAndSale(AZ::SimpleLcgRandom& random)
|
||||
{
|
||||
// start a matrix with arbitrary degrees
|
||||
float roll = random.GetRandomFloat() * 360.0f;
|
||||
float pitch = random.GetRandomFloat() * 360.0f;
|
||||
float yaw = random.GetRandomFloat() * 360.0f;
|
||||
const AZ::Vector3 eulerRadians = AZ::Vector3DegToRad(AZ::Vector3{ roll, pitch, yaw });
|
||||
const auto rotX = MatrixType::CreateRotationX(eulerRadians.GetX());
|
||||
const auto rotY = MatrixType::CreateRotationY(eulerRadians.GetY());
|
||||
const auto rotZ = MatrixType::CreateRotationZ(eulerRadians.GetZ());
|
||||
auto matrix = rotX * rotY * rotZ;
|
||||
|
||||
// apply a scale
|
||||
matrix.MultiplyByScale(AZ::Vector3{ random.GetRandomFloat() });
|
||||
return matrix;
|
||||
}
|
||||
|
||||
template <typename MatrixType>
|
||||
void AssignArbitrarySetTranslation(MatrixType& matrix, AZ::SimpleLcgRandom& random)
|
||||
{
|
||||
float x = random.GetRandomFloat() * 10000.0f;
|
||||
float y = random.GetRandomFloat() * 10000.0f;
|
||||
float z = random.GetRandomFloat() * 10000.0f;
|
||||
matrix.SetTranslation(AZ::Vector3{ x, y, z });
|
||||
}
|
||||
|
||||
template <typename MatrixType>
|
||||
MatrixType CreateArbitraryMatrix(size_t seed);
|
||||
|
||||
template <>
|
||||
AZ::Matrix3x3 CreateArbitraryMatrix(size_t seed)
|
||||
{
|
||||
AZ::SimpleLcgRandom random(seed);
|
||||
return CreateArbitraryMatrixRotationAndSale<AZ::Matrix3x3>(random);
|
||||
}
|
||||
|
||||
template <>
|
||||
AZ::Matrix3x4 CreateArbitraryMatrix(size_t seed)
|
||||
{
|
||||
AZ::SimpleLcgRandom random(seed);
|
||||
auto matrix = CreateArbitraryMatrixRotationAndSale<AZ::Matrix3x4>(random);
|
||||
AssignArbitrarySetTranslation<AZ::Matrix3x4>(matrix, random);
|
||||
return matrix;
|
||||
}
|
||||
|
||||
template <>
|
||||
AZ::Matrix4x4 CreateArbitraryMatrix(size_t seed)
|
||||
{
|
||||
AZ::SimpleLcgRandom random(seed);
|
||||
auto matrix = CreateArbitraryMatrixRotationAndSale<AZ::Matrix4x4>(random);
|
||||
AssignArbitrarySetTranslation<AZ::Matrix4x4>(matrix, random);
|
||||
return matrix;
|
||||
}
|
||||
|
||||
// CreateQuaternion
|
||||
|
||||
template<typename MatrixType>
|
||||
AZ::Quaternion CreateQuaternion(const MatrixType& matrix);
|
||||
|
||||
template<>
|
||||
AZ::Quaternion CreateQuaternion<AZ::Matrix3x3>(const AZ::Matrix3x3& matrix)
|
||||
{
|
||||
return AZ::Quaternion::CreateFromMatrix3x3(matrix);
|
||||
}
|
||||
|
||||
template<>
|
||||
AZ::Quaternion CreateQuaternion<AZ::Matrix3x4>(const AZ::Matrix3x4& matrix)
|
||||
{
|
||||
return AZ::Quaternion::CreateFromMatrix3x4(matrix);
|
||||
}
|
||||
|
||||
template<>
|
||||
AZ::Quaternion CreateQuaternion<AZ::Matrix4x4>(const AZ::Matrix4x4& matrix)
|
||||
{
|
||||
return AZ::Quaternion::CreateFromMatrix4x4(matrix);
|
||||
}
|
||||
|
||||
template<typename MatrixType>
|
||||
void AddRotation(rapidjson::Value& value, const MatrixType& matrix, rapidjson::Document::AllocatorType& allocator)
|
||||
{
|
||||
AZ::Quaternion rotation = CreateQuaternion<MatrixType>(matrix);
|
||||
const auto degrees = rotation.GetEulerDegrees();
|
||||
value.AddMember("yaw", degrees.GetX(), allocator);
|
||||
value.AddMember("pitch", degrees.GetY(), allocator);
|
||||
value.AddMember("roll", degrees.GetZ(), allocator);
|
||||
}
|
||||
|
||||
void AddScale(rapidjson::Value& value, float scale, rapidjson::Document::AllocatorType& allocator)
|
||||
{
|
||||
value.AddMember("scale", scale, allocator);
|
||||
}
|
||||
|
||||
void AddTranslation(rapidjson::Value& value, const AZ::Vector3& translation, rapidjson::Document::AllocatorType& allocator)
|
||||
{
|
||||
value.AddMember("x", translation.GetX(), allocator);
|
||||
value.AddMember("y", translation.GetY(), allocator);
|
||||
value.AddMember("z", translation.GetZ(), allocator);
|
||||
}
|
||||
|
||||
template <typename MatrixType>
|
||||
void AddData(rapidjson::Value& value, const MatrixType& matrix, rapidjson::Document::AllocatorType& allocator);
|
||||
|
||||
template <>
|
||||
void AddData(rapidjson::Value& value, const AZ::Matrix3x3& matrix, rapidjson::Document::AllocatorType& allocator)
|
||||
{
|
||||
AddScale(value, matrix.RetrieveScale().GetX(), allocator);
|
||||
AddRotation(value, matrix, allocator);
|
||||
}
|
||||
|
||||
template <>
|
||||
void AddData(rapidjson::Value& value, const AZ::Matrix3x4& matrix, rapidjson::Document::AllocatorType& allocator)
|
||||
{
|
||||
AddScale(value, matrix.RetrieveScale().GetX(), allocator);
|
||||
AddTranslation(value, matrix.GetTranslation(), allocator);
|
||||
AddRotation(value, matrix, allocator);
|
||||
}
|
||||
|
||||
template <>
|
||||
void AddData(rapidjson::Value& value, const AZ::Matrix4x4& matrix, rapidjson::Document::AllocatorType& allocator)
|
||||
{
|
||||
AddScale(value, matrix.RetrieveScale().GetX(), allocator);
|
||||
AddTranslation(value, matrix.GetTranslation(), allocator);
|
||||
AddRotation(value, matrix, allocator);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename MatrixType, size_t RowCount, size_t ColumnCount, typename Serializer>
|
||||
class MathMatrixSerializerTestDescription :
|
||||
public JsonSerializerConformityTestDescriptor<MatrixType>
|
||||
{
|
||||
public:
|
||||
AZStd::shared_ptr<AZ::BaseJsonSerializer> CreateSerializer() override
|
||||
{
|
||||
return AZStd::make_shared<Serializer>();
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<MatrixType> CreateDefaultInstance() override
|
||||
{
|
||||
return AZStd::make_shared<MatrixType>(MatrixType::CreateIdentity());
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<MatrixType> CreateFullySetInstance() override
|
||||
{
|
||||
auto angles = AZ::Vector3 { 0.0f, 0.0f, 0.0f };
|
||||
auto scale = 10.0f;
|
||||
auto translation = AZ::Vector3{ 10.0f, 20.0f, 30.0f };
|
||||
auto matrix = DataHelper::BuildMatrix<MatrixType>(angles, scale, translation);
|
||||
return AZStd::make_shared<MatrixType>(matrix);
|
||||
}
|
||||
|
||||
AZStd::string_view GetJsonForFullySetInstance() override
|
||||
{
|
||||
if constexpr (RowCount * ColumnCount == 9)
|
||||
{
|
||||
return "{\"roll\":0.0,\"pitch\":0.0,\"yaw\":0.0,\"scale\":10.0}";
|
||||
}
|
||||
else if constexpr (RowCount * ColumnCount == 12)
|
||||
{
|
||||
return "{\"roll\":0.0,\"pitch\":0.0,\"yaw\":0.0,\"scale\":10.0,\"x\":10.0,\"y\":20.0,\"z\":30.0}";
|
||||
}
|
||||
else if constexpr (RowCount * ColumnCount == 16)
|
||||
{
|
||||
return "{\"roll\":0.0,\"pitch\":0.0,\"yaw\":0.0,\"scale\":10.0,\"x\":10.0,\"y\":20.0,\"z\":30.0}";
|
||||
}
|
||||
else
|
||||
{
|
||||
static_assert((RowCount >= 3 && RowCount <= 4) && (ColumnCount >= 3 && ColumnCount <= 4),
|
||||
"Only matrix 3x3, 3x4 or 4x4 are supported by this test.");
|
||||
}
|
||||
return "{}";
|
||||
}
|
||||
|
||||
void ConfigureFeatures(JsonSerializerConformityTestDescriptorFeatures& features) override
|
||||
{
|
||||
features.EnableJsonType(rapidjson::kArrayType);
|
||||
features.EnableJsonType(rapidjson::kObjectType);
|
||||
features.m_fixedSizeArray = true;
|
||||
features.m_supportsPartialInitialization = false;
|
||||
features.m_supportsInjection = false;
|
||||
}
|
||||
|
||||
bool AreEqual(const MatrixType& lhs, const MatrixType& rhs) override
|
||||
{
|
||||
for (int r = 0; r < RowCount; ++r)
|
||||
{
|
||||
for (int c = 0; c < ColumnCount; ++c)
|
||||
{
|
||||
if (!AZ::IsClose(lhs.GetElement(r, c), rhs.GetElement(r, c), AZ::Constants::Tolerance))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
using MathMatrixSerializerConformityTestTypes = ::testing::Types<
|
||||
MathMatrixSerializerTestDescription<AZ::Matrix3x3, 3, 3, AZ::JsonMatrix3x3Serializer>,
|
||||
MathMatrixSerializerTestDescription<AZ::Matrix3x4, 3, 4, AZ::JsonMatrix3x4Serializer>,
|
||||
MathMatrixSerializerTestDescription<AZ::Matrix4x4, 4, 4, AZ::JsonMatrix4x4Serializer>
|
||||
>;
|
||||
INSTANTIATE_TYPED_TEST_CASE_P(JsonMathMatrixSerializer, JsonSerializerConformityTests, MathMatrixSerializerConformityTestTypes);
|
||||
|
||||
template<typename T>
|
||||
class JsonMathMatrixSerializerTests
|
||||
: public BaseJsonSerializerFixture
|
||||
{
|
||||
public:
|
||||
using Descriptor = T;
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
BaseJsonSerializerFixture::SetUp();
|
||||
m_serializer = AZStd::make_unique<typename T::Serializer>();
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
m_serializer.reset();
|
||||
BaseJsonSerializerFixture::TearDown();
|
||||
}
|
||||
|
||||
protected:
|
||||
AZStd::unique_ptr<typename T::Serializer> m_serializer;
|
||||
};
|
||||
|
||||
struct Matrix3x3Descriptor
|
||||
{
|
||||
using MatrixType = AZ::Matrix3x3;
|
||||
using Serializer = AZ::JsonMatrix3x3Serializer;
|
||||
constexpr static size_t RowCount = 3;
|
||||
constexpr static size_t ColumnCount = 3;
|
||||
constexpr static size_t ElementCount = RowCount * ColumnCount;
|
||||
constexpr static bool HasTranslation = false;
|
||||
};
|
||||
|
||||
struct Matrix3x4Descriptor
|
||||
{
|
||||
using MatrixType = AZ::Matrix3x4;
|
||||
using Serializer = AZ::JsonMatrix3x4Serializer;
|
||||
constexpr static size_t RowCount = 3;
|
||||
constexpr static size_t ColumnCount = 4;
|
||||
constexpr static size_t ElementCount = RowCount * ColumnCount;
|
||||
constexpr static bool HasTranslation = true;
|
||||
};
|
||||
|
||||
struct Matrix4x4Descriptor
|
||||
{
|
||||
using MatrixType = AZ::Matrix4x4;
|
||||
using Serializer = AZ::JsonMatrix4x4Serializer;
|
||||
constexpr static size_t RowCount = 4;
|
||||
constexpr static size_t ColumnCount = 4;
|
||||
constexpr static size_t ElementCount = RowCount * ColumnCount;
|
||||
constexpr static bool HasTranslation = true;
|
||||
};
|
||||
|
||||
using JsonMathMatrixSerializerTypes = ::testing::Types <
|
||||
Matrix3x3Descriptor, Matrix3x4Descriptor, Matrix4x4Descriptor>;
|
||||
TYPED_TEST_CASE(JsonMathMatrixSerializerTests, JsonMathMatrixSerializerTypes);
|
||||
|
||||
// Load array tests
|
||||
|
||||
TYPED_TEST(JsonMathMatrixSerializerTests, Load_Array_ReturnsConvertAndLoadsMatrix)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
rapidjson::Value& arrayValue = this->m_jsonDocument->SetArray();
|
||||
for (size_t i = 0; i < JsonMathMatrixSerializerTests<TypeParam>::Descriptor::ElementCount; ++i)
|
||||
{
|
||||
arrayValue.PushBack(static_cast<float>(i + 1), this->m_jsonDocument->GetAllocator());
|
||||
}
|
||||
|
||||
auto output = JsonMathMatrixSerializerTests<TypeParam>::Descriptor::MatrixType::CreateZero();
|
||||
ResultCode result = this->m_serializer->Load(
|
||||
&output,
|
||||
azrtti_typeid<typename JsonMathMatrixSerializerTests<TypeParam>::Descriptor::MatrixType>(),
|
||||
*this->m_jsonDocument,
|
||||
*this->m_jsonDeserializationContext);
|
||||
ASSERT_EQ(Outcomes::Success, result.GetOutcome());
|
||||
|
||||
for (int r = 0; r < JsonMathMatrixSerializerTests<TypeParam>::Descriptor::RowCount; ++r)
|
||||
{
|
||||
for (int c = 0; c < JsonMathMatrixSerializerTests<TypeParam>::Descriptor::ColumnCount; ++c)
|
||||
{
|
||||
auto testValue = static_cast<float>((r * JsonMathMatrixSerializerTests<TypeParam>::Descriptor::ColumnCount) + c + 1);
|
||||
EXPECT_FLOAT_EQ(testValue, output.GetElement(r, c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TYPED_TEST(JsonMathMatrixSerializerTests, Load_InvalidEntries_ReturnsUnsupportedAndLeavesMatrixUntouched)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
rapidjson::Value& arrayValue = this->m_jsonDocument->SetArray();
|
||||
for (size_t i = 0; i < JsonMathMatrixSerializerTests<TypeParam>::Descriptor::ElementCount; ++i)
|
||||
{
|
||||
if (i == 1)
|
||||
{
|
||||
arrayValue.PushBack(rapidjson::StringRef("Invalid"), this->m_jsonDocument->GetAllocator());
|
||||
}
|
||||
else
|
||||
{
|
||||
arrayValue.PushBack(static_cast<float>(i + 1), this->m_jsonDocument->GetAllocator());
|
||||
}
|
||||
}
|
||||
|
||||
auto output = JsonMathMatrixSerializerTests<TypeParam>::Descriptor::MatrixType::CreateZero();
|
||||
ResultCode result = this->m_serializer->Load(
|
||||
&output,
|
||||
azrtti_typeid<typename JsonMathMatrixSerializerTests<TypeParam>::Descriptor::MatrixType>(),
|
||||
*this->m_jsonDocument,
|
||||
*this->m_jsonDeserializationContext);
|
||||
EXPECT_EQ(Outcomes::Unsupported, result.GetOutcome());
|
||||
|
||||
for (int r = 0; r < JsonMathMatrixSerializerTests<TypeParam>::Descriptor::RowCount; ++r)
|
||||
{
|
||||
for (int c = 0; c < JsonMathMatrixSerializerTests<TypeParam>::Descriptor::ColumnCount; ++c)
|
||||
{
|
||||
EXPECT_FLOAT_EQ(0.0f, output.GetElement(r, c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TYPED_TEST(JsonMathMatrixSerializerTests, Load_FloatSerializerMissingForArray_ReturnsCatastrophic)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
this->m_jsonRegistrationContext->EnableRemoveReflection();
|
||||
this->m_jsonRegistrationContext->template Serializer<AZ::JsonFloatSerializer>()->template HandlesType<float>();
|
||||
this->m_jsonRegistrationContext->DisableRemoveReflection();
|
||||
|
||||
rapidjson::Value& arrayValue = this->m_jsonDocument->SetArray();
|
||||
for (size_t i = 0; i < JsonMathMatrixSerializerTests<TypeParam>::Descriptor::ElementCount + 1; ++i)
|
||||
{
|
||||
arrayValue.PushBack(static_cast<float>(i + 1), this->m_jsonDocument->GetAllocator());
|
||||
}
|
||||
|
||||
typename JsonMathMatrixSerializerTests<TypeParam>::Descriptor::MatrixType output;
|
||||
ResultCode result = this->m_serializer->Load(
|
||||
&output,
|
||||
azrtti_typeid<typename JsonMathMatrixSerializerTests<TypeParam>::Descriptor::MatrixType>(),
|
||||
*this->m_jsonDocument,
|
||||
*this->m_jsonDeserializationContext);
|
||||
EXPECT_EQ(Outcomes::Catastrophic, result.GetOutcome());
|
||||
|
||||
this->m_jsonRegistrationContext->template Serializer<AZ::JsonFloatSerializer>()->template HandlesType<float>();
|
||||
}
|
||||
|
||||
// Load object tests
|
||||
TYPED_TEST(JsonMathMatrixSerializerTests, Load_ValidObjectLowerCase_ReturnsSuccessAndLoadsMatrix)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
rapidjson::Value& objectValue = this->m_jsonDocument->SetObject();
|
||||
auto input = JsonMathMatrixSerializerTests<TypeParam>::Descriptor::MatrixType::CreateIdentity();
|
||||
DataHelper::AddData(objectValue, input, this->m_jsonDocument->GetAllocator());
|
||||
|
||||
auto output = JsonMathMatrixSerializerTests<TypeParam>::Descriptor::MatrixType::CreateZero();
|
||||
ResultCode result = this->m_serializer->Load(
|
||||
&output,
|
||||
azrtti_typeid<typename JsonMathMatrixSerializerTests<TypeParam>::Descriptor::MatrixType>(),
|
||||
*this->m_jsonDocument,
|
||||
*this->m_jsonDeserializationContext);
|
||||
ASSERT_EQ(Outcomes::DefaultsUsed, result.GetOutcome());
|
||||
EXPECT_TRUE(input == output);
|
||||
}
|
||||
|
||||
TYPED_TEST(JsonMathMatrixSerializerTests, Load_ValidObjectWithExtraFields_ReturnsPartialConvertAndLoadsMatrix)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
rapidjson::Value& objectValue = this->m_jsonDocument->SetObject();
|
||||
auto input = JsonMathMatrixSerializerTests<TypeParam>::Descriptor::MatrixType::CreateIdentity();
|
||||
DataHelper::AddScale(objectValue, input.RetrieveScale().GetX(), this->m_jsonDocument->GetAllocator());
|
||||
DataHelper::AddRotation(objectValue, input, this->m_jsonDocument->GetAllocator());
|
||||
objectValue.AddMember(rapidjson::StringRef("extra"), "no value", this->m_jsonDocument->GetAllocator());
|
||||
|
||||
auto output = JsonMathMatrixSerializerTests<TypeParam>::Descriptor::MatrixType::CreateZero();
|
||||
ResultCode result = this->m_serializer->Load(
|
||||
&output,
|
||||
azrtti_typeid<typename JsonMathMatrixSerializerTests<TypeParam>::Descriptor::MatrixType>(),
|
||||
*this->m_jsonDocument,
|
||||
*this->m_jsonDeserializationContext);
|
||||
ASSERT_EQ(Outcomes::DefaultsUsed, result.GetOutcome());
|
||||
EXPECT_TRUE(input == output);
|
||||
}
|
||||
|
||||
TYPED_TEST(JsonMathMatrixSerializerTests, SaveLoad_Identity_LoadsDefaultMatrixWithIdentity)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
auto defaultValue = JsonMathMatrixSerializerTests<TypeParam>::Descriptor::MatrixType::CreateIdentity();
|
||||
|
||||
rapidjson::Value& objectInput = this->m_jsonDocument->SetObject();
|
||||
this->m_serializer->Store(
|
||||
objectInput,
|
||||
&defaultValue,
|
||||
&defaultValue,
|
||||
azrtti_typeid<typename JsonMathMatrixSerializerTests<TypeParam>::Descriptor::MatrixType>(),
|
||||
*this->m_jsonSerializationContext);
|
||||
|
||||
rapidjson::StringBuffer buffer;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
|
||||
objectInput.Accept(writer);
|
||||
|
||||
auto output = defaultValue;
|
||||
ResultCode result = this->m_serializer->Load(
|
||||
&output,
|
||||
azrtti_typeid<typename JsonMathMatrixSerializerTests<TypeParam>::Descriptor::MatrixType>(),
|
||||
*this->m_jsonDocument,
|
||||
*this->m_jsonDeserializationContext);
|
||||
|
||||
EXPECT_TRUE(defaultValue == output);
|
||||
}
|
||||
|
||||
TYPED_TEST(JsonMathMatrixSerializerTests, LoadSave_Zero_SavesAndLoadsIdentityMatrix)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
auto defaultValue = JsonMathMatrixSerializerTests<TypeParam>::Descriptor::MatrixType::CreateIdentity();
|
||||
auto input = JsonMathMatrixSerializerTests<TypeParam>::Descriptor::MatrixType::CreateZero();
|
||||
|
||||
rapidjson::Value& objectInput = this->m_jsonDocument->SetObject();
|
||||
this->m_serializer->Store(
|
||||
objectInput,
|
||||
&input,
|
||||
&defaultValue,
|
||||
azrtti_typeid<typename JsonMathMatrixSerializerTests<TypeParam>::Descriptor::MatrixType>(),
|
||||
*this->m_jsonSerializationContext);
|
||||
|
||||
auto output = defaultValue;
|
||||
ResultCode result = this->m_serializer->Load(
|
||||
&output,
|
||||
azrtti_typeid<typename JsonMathMatrixSerializerTests<TypeParam>::Descriptor::MatrixType>(),
|
||||
*this->m_jsonDocument,
|
||||
*this->m_jsonDeserializationContext);
|
||||
|
||||
ASSERT_EQ(Outcomes::Unsupported, result.GetOutcome());
|
||||
EXPECT_TRUE(defaultValue == output);
|
||||
}
|
||||
|
||||
TYPED_TEST(JsonMathMatrixSerializerTests, Load_InvalidFields_ReturnsUnsupportedAndLeavesMatrixUntouched)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
using Descriptor = typename JsonMathMatrixSerializerTests<TypeParam>::Descriptor;
|
||||
|
||||
const auto defaultValue = Descriptor::MatrixType::CreateIdentity();
|
||||
rapidjson::Value& objectValue = this->m_jsonDocument->SetObject();
|
||||
auto input = Descriptor::MatrixType::CreateIdentity();
|
||||
DataHelper::AddData(objectValue, input, this->m_jsonDocument->GetAllocator());
|
||||
objectValue["yaw"] = "Invalid";
|
||||
|
||||
auto output = Descriptor::MatrixType::CreateZero();
|
||||
ResultCode result = this->m_serializer->Load(
|
||||
&output,
|
||||
azrtti_typeid<typename Descriptor::MatrixType>(),
|
||||
*this->m_jsonDocument,
|
||||
*this->m_jsonDeserializationContext);
|
||||
ASSERT_EQ(Outcomes::Unsupported, result.GetOutcome());
|
||||
EXPECT_TRUE(input == output);
|
||||
}
|
||||
|
||||
TYPED_TEST(JsonMathMatrixSerializerTests, LoadSave_Arbitrary_SavesAndLoadsArbitraryMatrix)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
using Descriptor = typename JsonMathMatrixSerializerTests<TypeParam>::Descriptor;
|
||||
|
||||
auto defaultValue = Descriptor::MatrixType::CreateIdentity();
|
||||
size_t elementCount = Descriptor::RowCount * Descriptor::ColumnCount;
|
||||
auto input = DataHelper::CreateArbitraryMatrix<typename Descriptor::MatrixType>(elementCount);
|
||||
|
||||
rapidjson::Value& objectInput = this->m_jsonDocument->SetObject();
|
||||
this->m_serializer->Store(
|
||||
objectInput,
|
||||
&input,
|
||||
&defaultValue,
|
||||
azrtti_typeid<typename Descriptor::MatrixType>(),
|
||||
*this->m_jsonSerializationContext);
|
||||
|
||||
auto output = defaultValue;
|
||||
ResultCode result = this->m_serializer->Load(
|
||||
&output,
|
||||
azrtti_typeid<typename Descriptor::MatrixType>(),
|
||||
*this->m_jsonDocument,
|
||||
*this->m_jsonDeserializationContext);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
|
||||
for (int r = 0; r < Descriptor::RowCount; ++r)
|
||||
{
|
||||
for (int c = 0; c < Descriptor::ColumnCount; ++c)
|
||||
{
|
||||
EXPECT_NEAR(input.GetElement(r, c), output.GetElement(r, c), AZ::Constants::Tolerance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace JsonSerializationTests
|
||||
@@ -32,7 +32,7 @@ namespace JsonSerializationTests
|
||||
return AZStd::make_shared<AZ::JsonSmartPointerSerializer>();
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> CreateDefaultInstance() override
|
||||
AZStd::shared_ptr<SmartPointer> CreateDefaultConstructedInstance() override
|
||||
{
|
||||
return AZStd::make_shared<SmartPointer>();
|
||||
}
|
||||
@@ -51,6 +51,13 @@ namespace JsonSerializationTests
|
||||
using SmartPointer = T<SimpleClass>;
|
||||
using Base = SmartPointerBaseTestDescription<SmartPointer>;
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> CreateDefaultInstance() override
|
||||
{
|
||||
auto result = AZStd::make_shared<SmartPointer>();
|
||||
*result = SmartPointer(aznew SimpleClass());
|
||||
return result;
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> CreateFullySetInstance() override
|
||||
{
|
||||
auto result = AZStd::make_shared<SmartPointer>();
|
||||
@@ -106,21 +113,6 @@ namespace JsonSerializationTests
|
||||
}
|
||||
};
|
||||
|
||||
template<template<typename...> class T>
|
||||
class SmartPointerSimpleClassWithInstanceTestDescription :
|
||||
public SmartPointerSimpleClassTestDescription<T>
|
||||
{
|
||||
public:
|
||||
using SmartPointer = typename SmartPointerSimpleClassTestDescription<T>::SmartPointer;
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> CreateDefaultInstance() override
|
||||
{
|
||||
auto result = AZStd::make_shared<SmartPointer>();
|
||||
*result = SmartPointer(aznew SimpleClass());
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template<template<typename...> class T>
|
||||
class SmartPointerSimpleDerivedClassTestDescription :
|
||||
public SmartPointerBaseTestDescription<T<BaseClass>>
|
||||
@@ -129,6 +121,13 @@ namespace JsonSerializationTests
|
||||
using SmartPointer = T<BaseClass>;
|
||||
using Base = SmartPointerBaseTestDescription<SmartPointer>;
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> CreateDefaultInstance() override
|
||||
{
|
||||
auto result = AZStd::make_shared<SmartPointer>();
|
||||
*result = SmartPointer(aznew BaseClass());
|
||||
return result;
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> CreateFullySetInstance() override
|
||||
{
|
||||
auto* instance = aznew SimpleInheritence();
|
||||
@@ -234,13 +233,19 @@ namespace JsonSerializationTests
|
||||
public:
|
||||
using SmartPointer = typename SmartPointerSimpleDerivedClassTestDescription<T>::SmartPointer;
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> CreateDefaultInstance() override
|
||||
// This test is specific for derived classes being used as a default value.
|
||||
AZStd::shared_ptr<SmartPointer> CreateDefaultConstructedInstance() override
|
||||
{
|
||||
auto result = AZStd::make_shared<SmartPointer>();
|
||||
*result = SmartPointer(aznew SimpleInheritence());
|
||||
return result;
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> CreateDefaultInstance() override
|
||||
{
|
||||
return CreateDefaultConstructedInstance();
|
||||
}
|
||||
|
||||
AZStd::string_view GetJsonForPartialDefaultInstance() override
|
||||
{
|
||||
return R"(
|
||||
@@ -272,6 +277,13 @@ namespace JsonSerializationTests
|
||||
using SmartPointer = T<BaseClass2>;
|
||||
using Base = SmartPointerBaseTestDescription<SmartPointer>;
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> CreateDefaultInstance() override
|
||||
{
|
||||
auto result = AZStd::make_shared<SmartPointer>();
|
||||
*result = SmartPointer(aznew BaseClass2());
|
||||
return result;
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> CreateFullySetInstance() override
|
||||
{
|
||||
auto* instance = aznew MultipleInheritence();
|
||||
@@ -385,13 +397,19 @@ namespace JsonSerializationTests
|
||||
public:
|
||||
using SmartPointer = typename SmartPointerComplexDerivedClassTestDescription<T>::SmartPointer;
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> CreateDefaultInstance() override
|
||||
// This test is specific for derived classes being used as a default value.
|
||||
AZStd::shared_ptr<SmartPointer> CreateDefaultConstructedInstance() override
|
||||
{
|
||||
auto result = AZStd::make_shared<SmartPointer>();
|
||||
*result = SmartPointer(aznew MultipleInheritence());
|
||||
return result;
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> CreateDefaultInstance() override
|
||||
{
|
||||
return CreateDefaultConstructedInstance();
|
||||
}
|
||||
|
||||
AZStd::string_view GetJsonForPartialDefaultInstance() override
|
||||
{
|
||||
return R"(
|
||||
@@ -424,9 +442,6 @@ namespace JsonSerializationTests
|
||||
SmartPointerSimpleClassTestDescription<AZStd::unique_ptr>,
|
||||
SmartPointerSimpleClassTestDescription<AZStd::shared_ptr>,
|
||||
SmartPointerSimpleClassTestDescription<AZStd::intrusive_ptr>,
|
||||
SmartPointerSimpleClassWithInstanceTestDescription<AZStd::unique_ptr>,
|
||||
SmartPointerSimpleClassWithInstanceTestDescription<AZStd::shared_ptr>,
|
||||
SmartPointerSimpleClassWithInstanceTestDescription<AZStd::intrusive_ptr>,
|
||||
// Simple derived class, include single inheritance.
|
||||
SmartPointerSimpleDerivedClassTestDescription<AZStd::unique_ptr>,
|
||||
SmartPointerSimpleDerivedClassTestDescription<AZStd::shared_ptr>,
|
||||
@@ -551,6 +566,37 @@ namespace JsonSerializationTests
|
||||
EXPECT_EQ(nullptr, *instance);
|
||||
}
|
||||
|
||||
TEST_F(JsonSmartPointerSerializerTests, Load_DefaultInstanceToNullptr_ReturnsSuccess)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
SmartPointer instance;
|
||||
AZStd::shared_ptr<SmartPointer> compare = m_description.CreateDefaultInstance();
|
||||
m_jsonDocument->SetObject();
|
||||
|
||||
JSR::ResultCode result =
|
||||
m_serializer.Load(&instance, azrtti_typeid<SmartPointer>(), *m_jsonDocument, *m_jsonDeserializationContext);
|
||||
|
||||
EXPECT_EQ(JSR::Processing::Completed, result.GetProcessing());
|
||||
EXPECT_NE(nullptr, instance);
|
||||
EXPECT_TRUE(m_description.AreEqual(instance, *compare));
|
||||
}
|
||||
|
||||
TEST_F(JsonSmartPointerSerializerTests, Load_DefaultObjectDoesNotUpdateInstance_ReturnsSuccess)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> instance = m_description.CreateFullySetInstance();
|
||||
AZStd::shared_ptr<SmartPointer> compare = m_description.CreateFullySetInstance();
|
||||
m_jsonDocument->SetObject();
|
||||
|
||||
JSR::ResultCode result =
|
||||
m_serializer.Load(instance.get(), azrtti_typeid<SmartPointer>(), *m_jsonDocument, *m_jsonDeserializationContext);
|
||||
|
||||
EXPECT_EQ(JSR::Processing::Completed, result.GetProcessing());
|
||||
EXPECT_TRUE(m_description.AreEqual(*instance, *compare));
|
||||
}
|
||||
|
||||
TEST_F(JsonSmartPointerSerializerTests, Load_InstanceBeingReplacedWithDifferentType_ReturnsSuccess)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
@@ -720,13 +766,66 @@ namespace JsonSerializationTests
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> instance = m_description.CreateFullySetInstance();
|
||||
SmartPointer nullPtr;
|
||||
JSR::ResultCode result = m_serializer.Store(*m_jsonDocument, instance.get(), &nullPtr,
|
||||
SmartPointer defaultInstance;
|
||||
JSR::ResultCode result = m_serializer.Store(
|
||||
*m_jsonDocument, instance.get(), &defaultInstance,
|
||||
azrtti_typeid<SmartPointer>(), *m_jsonSerializationContext);
|
||||
|
||||
EXPECT_EQ(JSR::Outcomes::Success, result.GetOutcome());
|
||||
}
|
||||
|
||||
TEST_F(JsonSmartPointerSerializerTests, Store_ValuePointerIsNullPtr_ReturnsSuccessAndStoresNull)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
SmartPointer instance;
|
||||
AZStd::shared_ptr<SmartPointer> defaultInstance = m_description.CreateFullySetInstance();
|
||||
JSR::ResultCode result = m_serializer.Store(
|
||||
*m_jsonDocument, &instance, defaultInstance.get(), azrtti_typeid<SmartPointer>(), *m_jsonSerializationContext);
|
||||
|
||||
EXPECT_EQ(JSR::Outcomes::Success, result.GetOutcome());
|
||||
EXPECT_TRUE(m_jsonDocument->IsNull());
|
||||
}
|
||||
|
||||
TEST_F(JsonSmartPointerSerializerTests, Store_ValueAndDefaultPointersAreNullPtr_ReturnsSuccessAndStoresNull)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
SmartPointer instance;
|
||||
SmartPointer defaultInstance;
|
||||
JSR::ResultCode result =
|
||||
m_serializer.Store(*m_jsonDocument, &instance, &defaultInstance, azrtti_typeid<SmartPointer>(), *m_jsonSerializationContext);
|
||||
|
||||
EXPECT_EQ(JSR::Outcomes::DefaultsUsed, result.GetOutcome());
|
||||
EXPECT_TRUE(m_jsonDocument->IsNull());
|
||||
}
|
||||
|
||||
TEST_F(JsonSmartPointerSerializerTests, Store_ValueAndDefaultPointersAreBothDefault_ReturnsSuccess)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> instance = m_description.CreateDefaultInstance();
|
||||
AZStd::shared_ptr<SmartPointer> defaultInstance = m_description.CreateDefaultInstance();
|
||||
JSR::ResultCode result =
|
||||
m_serializer.Store(*m_jsonDocument, instance.get(), defaultInstance.get(), azrtti_typeid<SmartPointer>(), *m_jsonSerializationContext);
|
||||
|
||||
EXPECT_EQ(JSR::Outcomes::DefaultsUsed, result.GetOutcome());
|
||||
Expect_ExplicitDefault(*m_jsonDocument);
|
||||
}
|
||||
|
||||
TEST_F(JsonSmartPointerSerializerTests, Store_ValueHasDefaultValuesAndDefaultHasNullPointer_ReturnsSuccess)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> instance = m_description.CreateDefaultInstance();
|
||||
SmartPointer defaultInstance;
|
||||
JSR::ResultCode result = m_serializer.Store(
|
||||
*m_jsonDocument, instance.get(), &defaultInstance, azrtti_typeid<SmartPointer>(), *m_jsonSerializationContext);
|
||||
|
||||
EXPECT_EQ(JSR::Outcomes::DefaultsUsed, result.GetOutcome());
|
||||
Expect_ExplicitDefault(*m_jsonDocument);
|
||||
}
|
||||
|
||||
TEST_F(JsonSmartPointerSerializerTests, Store_DefaultPointerIsOtherClass_CompletesButDoesNotReturnDefaults)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
@@ -749,7 +848,7 @@ namespace JsonSerializationTests
|
||||
EXPECT_EQ(JSR::Processing::Completed, result.GetProcessing());
|
||||
}
|
||||
|
||||
TEST_F(JsonSmartPointerSerializerTests, Store_SaveAnClassThatIsNotReflected_ReturnsUnknown)
|
||||
TEST_F(JsonSmartPointerSerializerTests, Store_ClassThatIsNotReflected_ReturnsUnknown)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace SettingsRegistryConsoleUtilsTests
|
||||
{
|
||||
constexpr const char* settingsKey = "/TestKey";
|
||||
constexpr const char* expectedValue = "TestValue";
|
||||
AZ::Console testConsole;
|
||||
AZ::Console testConsole(*m_registry);
|
||||
AZ::SettingsRegistryConsoleUtils::ConsoleFunctorHandle handle{
|
||||
AZ::SettingsRegistryConsoleUtils::RegisterAzConsoleCommands(*m_registry, testConsole) };
|
||||
EXPECT_TRUE(testConsole.PerformCommand(AZ::SettingsRegistryConsoleUtils::SettingsRegistrySet, { settingsKey, expectedValue }));
|
||||
@@ -69,7 +69,7 @@ namespace SettingsRegistryConsoleUtilsTests
|
||||
{
|
||||
constexpr const char* settingsKey = "/TestKey";
|
||||
constexpr const char* expectedValue = "TestValue";
|
||||
AZ::Console testConsole;
|
||||
AZ::Console testConsole(*m_registry);
|
||||
|
||||
// Scopes the console functor handle so that it destructs and unregisters the console functors
|
||||
{
|
||||
@@ -89,7 +89,7 @@ namespace SettingsRegistryConsoleUtilsTests
|
||||
constexpr const char* settingsKey2 = "/TestKey2";
|
||||
constexpr const char* expectedValue = R"(TestValue)";
|
||||
constexpr const char* expectedValue2 = R"(Hello World)";
|
||||
AZ::Console testConsole;
|
||||
AZ::Console testConsole(*m_registry);
|
||||
AZ::SettingsRegistryConsoleUtils::ConsoleFunctorHandle handle{
|
||||
AZ::SettingsRegistryConsoleUtils::RegisterAzConsoleCommands(*m_registry, testConsole) };
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace SettingsRegistryConsoleUtilsTests
|
||||
constexpr const char* settingsKey2 = "/TestKey2";
|
||||
constexpr const char* expectedValue = R"(TestValue)";
|
||||
constexpr const char* expectedValue2 = R"(Hello World)";
|
||||
AZ::Console testConsole;
|
||||
AZ::Console testConsole(*m_registry);
|
||||
|
||||
// Add settings to settings registry
|
||||
EXPECT_TRUE(m_registry->Set(settingsKey, expectedValue));
|
||||
@@ -137,7 +137,7 @@ namespace SettingsRegistryConsoleUtilsTests
|
||||
constexpr const char* settingsKey2 = "/TestKey2";
|
||||
constexpr const char* expectedValue = R"(TestValue)";
|
||||
constexpr const char* expectedValue2 = R"(Hello World)";
|
||||
AZ::Console testConsole;
|
||||
AZ::Console testConsole(*m_registry);
|
||||
|
||||
AZ::SettingsRegistryConsoleUtils::ConsoleFunctorHandle handle{
|
||||
AZ::SettingsRegistryConsoleUtils::RegisterAzConsoleCommands(*m_registry, testConsole) };
|
||||
@@ -195,7 +195,7 @@ namespace SettingsRegistryConsoleUtilsTests
|
||||
constexpr const char* SettingsKey2 = "TestKey2";
|
||||
constexpr const char* ExpectedValue = R"(TestValue)";
|
||||
constexpr const char* ExpectedValue2 = R"(Hello World)";
|
||||
AZ::Console testConsole;
|
||||
AZ::Console testConsole(*m_registry);
|
||||
|
||||
AZ::SettingsRegistryConsoleUtils::ConsoleFunctorHandle handle{
|
||||
AZ::SettingsRegistryConsoleUtils::RegisterAzConsoleCommands(*m_registry, testConsole) };
|
||||
|
||||
@@ -1228,27 +1228,33 @@ namespace SettingsRegistryTests
|
||||
|
||||
TEST_F(SettingsRegistryTest, MergeCommandLineArgument_KeyIsTooLong_ReturnsFalse)
|
||||
{
|
||||
AZStd::string argument = AZStd::string::format("Te%*cst=Value", aznumeric_cast<int>(AZ::SettingsRegistryImpl::MaxJsonPathLength), ' ');
|
||||
constexpr int LongKeySize = 1024;
|
||||
AZStd::string argument = AZStd::string::format("Te%*cst=Value", LongKeySize, ' ');
|
||||
EXPECT_FALSE(m_registry->MergeCommandLineArgument(argument, {}, {}));
|
||||
}
|
||||
|
||||
TEST_F(SettingsRegistryTest, MergeCommandLineArgument_KeyIsTooLongWithDivider_ReturnsFalse)
|
||||
{
|
||||
AZStd::string argument = AZStd::string::format("/Te%*cst=Value", aznumeric_cast<int>(AZ::SettingsRegistryImpl::MaxJsonPathLength), ' ');
|
||||
constexpr int LongKeySize = 1024;
|
||||
AZStd::string argument = AZStd::string::format("/Te%*cst=Value", LongKeySize, ' ');
|
||||
EXPECT_FALSE(m_registry->MergeCommandLineArgument(argument, "/Path", {}));
|
||||
}
|
||||
|
||||
TEST_F(SettingsRegistryTest, MergeCommandLineArgument_ValueIsTooLong_ReturnsFalse)
|
||||
{
|
||||
AZStd::string argument = AZStd::string::format("Test=Val%*cue", aznumeric_cast<int>(AZ::SettingsRegistryImpl::MaxCommandLineArgumentLength), ' ');
|
||||
constexpr int LongValueSize = 1024;
|
||||
AZStd::string argument = AZStd::string::format("Test=Val%*cue", LongValueSize, ' ');
|
||||
EXPECT_FALSE(m_registry->MergeCommandLineArgument(argument, {}, {}));
|
||||
EXPECT_EQ(AZ::SettingsRegistryInterface::Type::NoType, m_registry->GetType("/Test"));
|
||||
}
|
||||
|
||||
TEST_F(SettingsRegistryTest, MergeCommandLineArgument_MissingValue_ReturnsFalse)
|
||||
TEST_F(SettingsRegistryTest, MergeCommandLineArgument_MissingValue_ReturnsEmptyString)
|
||||
{
|
||||
EXPECT_FALSE(m_registry->MergeCommandLineArgument("Test=", {}, {}));
|
||||
EXPECT_EQ(AZ::SettingsRegistryInterface::Type::NoType, m_registry->GetType("/Test"));
|
||||
EXPECT_TRUE(m_registry->MergeCommandLineArgument("Test=", {}, {}));
|
||||
EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType("/Test"));
|
||||
AZ::SettingsRegistryInterface::FixedValueString value;
|
||||
EXPECT_TRUE(m_registry->Get(value, "/Test"));
|
||||
EXPECT_TRUE(value.empty());
|
||||
}
|
||||
|
||||
TEST_F(SettingsRegistryTest, MergeCommandLineArgument_MissingKey_ReturnsFalse)
|
||||
@@ -1271,9 +1277,13 @@ namespace SettingsRegistryTests
|
||||
EXPECT_FALSE(m_registry->MergeCommandLineArgument(" =Value", {}, {}));
|
||||
}
|
||||
|
||||
TEST_F(SettingsRegistryTest, MergeCommandLineArgument_ValueIsSpaces_ReturnsFalse)
|
||||
TEST_F(SettingsRegistryTest, MergeCommandLineArgument_ValueIsSpaces_ReturnsEmptyString)
|
||||
{
|
||||
EXPECT_FALSE(m_registry->MergeCommandLineArgument("Key= ", {}, {}));
|
||||
EXPECT_TRUE(m_registry->MergeCommandLineArgument("Key= ", {}, {}));
|
||||
EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType("/Key"));
|
||||
AZ::SettingsRegistryInterface::FixedValueString value;
|
||||
EXPECT_TRUE(m_registry->Get(value, "/Key"));
|
||||
EXPECT_TRUE(value.empty());
|
||||
}
|
||||
|
||||
TEST_F(SettingsRegistryTest, MergeCommandLineArgument_KeyAndValueAreSpaces_ReturnsFalse)
|
||||
@@ -1367,9 +1377,8 @@ namespace SettingsRegistryTests
|
||||
|
||||
TEST_F(SettingsRegistryTest, MergeSettingsFile_PathAsSubStringThatsTooLong_ReturnsFalse)
|
||||
{
|
||||
char path[AZ::SettingsRegistryImpl::MaxFilePathLength + 1];
|
||||
memset(path, '1', sizeof(path));
|
||||
AZStd::string_view subPath(path, AZ::SettingsRegistryImpl::MaxFilePathLength);
|
||||
constexpr AZStd::fixed_string<AZ::IO::MaxPathLength + 1> path(AZ::IO::MaxPathLength + 1, '1');
|
||||
const AZStd::string_view subPath(path);
|
||||
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
bool result = m_registry->MergeSettingsFile(subPath, AZ::SettingsRegistryInterface::Format::JsonMergePatch, {}, nullptr);
|
||||
@@ -1719,8 +1728,7 @@ namespace SettingsRegistryTests
|
||||
|
||||
TEST_F(SettingsRegistryTest, MergeSettingsFolder_PathTooLong_ReportsErrorAndReturnsFalse)
|
||||
{
|
||||
char path[AZ::SettingsRegistryImpl::MaxFilePathLength + 1]{};
|
||||
memset(path, 'a', AZ_ARRAY_SIZE(path));
|
||||
constexpr AZStd::fixed_string<AZ::IO::MaxPathLength + 1> path(AZ::IO::MaxPathLength + 1, 'a');
|
||||
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
bool result = m_registry->MergeSettingsFolder(path, { "editor", "test" }, {}, nullptr);
|
||||
@@ -1741,7 +1749,7 @@ namespace SettingsRegistryTests
|
||||
m_testFolder->push_back(AZ_CORRECT_DATABASE_SEPARATOR);
|
||||
*m_testFolder += AZ::SettingsRegistryInterface::RegistryFolder;
|
||||
bool result = m_registry->MergeSettingsFolder(*m_testFolder, { "editor", "test" }, {}, nullptr);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(2);
|
||||
EXPECT_GT(::UnitTest::TestRunner::Instance().StopAssertTests(), 0);
|
||||
EXPECT_FALSE(result);
|
||||
|
||||
EXPECT_EQ(AZ::SettingsRegistryInterface::Type::Object, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/0")); // Folder and specialization settings.
|
||||
@@ -1751,11 +1759,5 @@ namespace SettingsRegistryTests
|
||||
EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/1/Path"));
|
||||
EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/1/File1"));
|
||||
EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/1/File2"));
|
||||
|
||||
EXPECT_EQ(AZ::SettingsRegistryInterface::Type::Object, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/2"));
|
||||
EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/2/Error"));
|
||||
EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/2/Path"));
|
||||
EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/2/File1"));
|
||||
EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/2/File2"));
|
||||
}
|
||||
} // namespace SettingsRegistryTests
|
||||
|
||||
@@ -111,6 +111,7 @@ set(FILES
|
||||
Serialization/Json/JsonSerializerMock.h
|
||||
Serialization/Json/MapSerializerTests.cpp
|
||||
Serialization/Json/MathVectorSerializerTests.cpp
|
||||
Serialization/Json/MathMatrixSerializerTests.cpp
|
||||
Serialization/Json/SmartPointerSerializerTests.cpp
|
||||
Serialization/Json/StringSerializerTests.cpp
|
||||
Serialization/Json/TestCases.h
|
||||
|
||||
Reference in New Issue
Block a user