Merge branch 'development' into cmake/SPEC-7179
This commit is contained in:
@@ -63,6 +63,9 @@ namespace AzToolsFramework
|
||||
//! Signal the Python handler to stop
|
||||
virtual bool StopPython(bool silenceWarnings = false) = 0;
|
||||
|
||||
//! Query to determine if the Python VM has been initialized indicating an active state
|
||||
virtual bool IsPythonActive() = 0;
|
||||
|
||||
//! Determines if the caller needs to wait for the Python VM to initialize (non-main thread only)
|
||||
virtual void WaitForInitialization() {}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <AzFramework/Input/Buses/Notifications/InputChannelNotificationBus.h>
|
||||
#include <AzFramework/Input/Buses/Requests/InputChannelRequestBus.h>
|
||||
#include <AzQtComponents/Utilities/QtWindowUtilities.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCursor>
|
||||
@@ -187,12 +188,6 @@ namespace AzToolsFramework
|
||||
|
||||
bool QtEventToAzInputMapper::HandlesInputEvent(const AzFramework::InputChannel& channel) const
|
||||
{
|
||||
const AzFramework::InputChannelId& channelId = channel.GetInputChannelId();
|
||||
if (channelId == AzFramework::InputDeviceMouse::Movement::X || channelId == AzFramework::InputDeviceMouse::Movement::Y)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// We map keyboard and mouse events from Qt, so flag all events coming from those devices
|
||||
// as handled by our synthetic event system.
|
||||
const AzFramework::InputDeviceId& deviceId = channel.GetInputDevice().GetInputDeviceId();
|
||||
@@ -210,6 +205,22 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
void QtEventToAzInputMapper::SetCursorCaptureEnabled(bool enabled)
|
||||
{
|
||||
if (m_capturingCursor != enabled)
|
||||
{
|
||||
m_capturingCursor = enabled;
|
||||
if (m_capturingCursor)
|
||||
{
|
||||
qApp->setOverrideCursor(Qt::BlankCursor);
|
||||
}
|
||||
else
|
||||
{
|
||||
qApp->restoreOverrideCursor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool QtEventToAzInputMapper::eventFilter(QObject* object, QEvent* event)
|
||||
{
|
||||
// Abort if processing isn't enabled.
|
||||
@@ -284,13 +295,25 @@ namespace AzToolsFramework
|
||||
{
|
||||
auto systemCursorChannel =
|
||||
GetInputChannel<AzFramework::InputChannelDeltaWithSharedPosition2D>(AzFramework::InputDeviceMouse::SystemCursorPosition);
|
||||
auto movementXChannel =
|
||||
GetInputChannel<AzFramework::InputChannelDeltaWithSharedPosition2D>(AzFramework::InputDeviceMouse::Movement::X);
|
||||
auto movementYChannel =
|
||||
GetInputChannel<AzFramework::InputChannelDeltaWithSharedPosition2D>(AzFramework::InputDeviceMouse::Movement::Y);
|
||||
auto mouseWheelChannel =
|
||||
GetInputChannel<AzFramework::InputChannelDeltaWithSharedPosition2D>(AzFramework::InputDeviceMouse::Movement::Z);
|
||||
|
||||
systemCursorChannel->ProcessRawInputEvent(m_cursorPosition->m_normalizedPositionDelta.GetLength());
|
||||
// Generate movement events based on the pixel delta divided by the DPI scaling factor, to calculate a rough approximation
|
||||
// of cursor movement velocity.
|
||||
movementXChannel->ProcessRawInputEvent(
|
||||
m_cursorPosition->m_normalizedPositionDelta.GetX() * aznumeric_cast<float>(m_sourceWidget->width()) / m_sourceWidget->devicePixelRatioF());
|
||||
movementYChannel->ProcessRawInputEvent(
|
||||
m_cursorPosition->m_normalizedPositionDelta.GetY() * aznumeric_cast<float>(m_sourceWidget->height()) / m_sourceWidget->devicePixelRatioF());
|
||||
mouseWheelChannel->ProcessRawInputEvent(0.f);
|
||||
|
||||
NotifyUpdateChannelIfNotIdle(systemCursorChannel, nullptr);
|
||||
NotifyUpdateChannelIfNotIdle(movementXChannel, nullptr);
|
||||
NotifyUpdateChannelIfNotIdle(movementYChannel, nullptr);
|
||||
NotifyUpdateChannelIfNotIdle(mouseWheelChannel, nullptr);
|
||||
}
|
||||
|
||||
@@ -318,16 +341,42 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
AZ::Vector2 QtEventToAzInputMapper::WidgetPositionToNormalizedPosition(QPoint position)
|
||||
{
|
||||
const float normalizedX = aznumeric_cast<float>(position.x()) / aznumeric_cast<float>(m_sourceWidget->width());
|
||||
const float normalizedY = aznumeric_cast<float>(position.y()) / aznumeric_cast<float>(m_sourceWidget->height());
|
||||
return AZ::Vector2{normalizedX, normalizedY};
|
||||
}
|
||||
|
||||
QPoint QtEventToAzInputMapper::NormalizedPositionToWidgetPosition(AZ::Vector2 normalizedPosition)
|
||||
{
|
||||
const int denormalizedX = aznumeric_cast<int>(normalizedPosition.GetX() * m_sourceWidget->width());
|
||||
const int denormalizedY = aznumeric_cast<int>(normalizedPosition.GetY() * m_sourceWidget->height());
|
||||
return QPoint{denormalizedX, denormalizedY};
|
||||
}
|
||||
|
||||
void QtEventToAzInputMapper::HandleMouseMoveEvent(QMouseEvent* mouseEvent)
|
||||
{
|
||||
AZ::Vector2 lastCursorPosition = m_cursorPosition->m_normalizedPosition;
|
||||
|
||||
const QPoint mousePos = mouseEvent->pos();
|
||||
const float normalizedX = aznumeric_cast<float>(mousePos.x()) / aznumeric_cast<float>(m_sourceWidget->width());
|
||||
const float normalizedY = aznumeric_cast<float>(mousePos.y()) / aznumeric_cast<float>(m_sourceWidget->height());
|
||||
const AZ::Vector2 normalizedPosition(normalizedX, normalizedY);
|
||||
const AZ::Vector2 normalizedPosition = WidgetPositionToNormalizedPosition(mousePos);
|
||||
m_cursorPosition->m_normalizedPositionDelta = normalizedPosition - m_cursorPosition->m_normalizedPosition;
|
||||
m_cursorPosition->m_normalizedPosition = normalizedPosition;
|
||||
ProcessPendingMouseEvents();
|
||||
m_mouseChannelsNeedUpdate = true;
|
||||
|
||||
if (m_capturingCursor)
|
||||
{
|
||||
// Reset our cursor position to the previous point.
|
||||
QPoint targetScreenPosition = m_sourceWidget->mapToGlobal(NormalizedPositionToWidgetPosition(lastCursorPosition));
|
||||
AzQtComponents::SetCursorPos(targetScreenPosition);
|
||||
|
||||
// Even though we just set the cursor position, there are edge cases such as remote desktop that will leave
|
||||
// the cursor position unchanged. For safety, we re-cache our last cursor position for delta generation.
|
||||
QPoint actualWidgetPosition = m_sourceWidget->mapFromGlobal(QCursor::pos());
|
||||
m_cursorPosition->m_normalizedPosition = WidgetPositionToNormalizedPosition(actualWidgetPosition);
|
||||
}
|
||||
}
|
||||
|
||||
void QtEventToAzInputMapper::HandleKeyEvent(QKeyEvent* keyEvent)
|
||||
|
||||
@@ -47,6 +47,12 @@ namespace AzToolsFramework
|
||||
//! Sets whether or not this input mapper should be updating its input channels from Qt events.
|
||||
void SetEnabled(bool enabled);
|
||||
|
||||
//! Sets whether or not the cursor should be constrained to the source widget and invisible.
|
||||
//! Internally, this will reset the cursor position after each move event to ensure movement
|
||||
//! events don't allow the cursor to escape. This can be used for typical camera controls
|
||||
//! like a dolly or rotation, where mouse movement is important but cursor location is not.
|
||||
void SetCursorCaptureEnabled(bool enabled);
|
||||
|
||||
// QObject overrides...
|
||||
bool eventFilter(QObject* object, QEvent* event) override;
|
||||
|
||||
@@ -106,6 +112,11 @@ namespace AzToolsFramework
|
||||
// Processes any pending mouse movement events, this allows mouse movement channels to close themselves.
|
||||
void ProcessPendingMouseEvents();
|
||||
|
||||
// Converts a point in logical source widget space [0..m_sourceWidget->size()] to normalized [0..1] space.
|
||||
AZ::Vector2 WidgetPositionToNormalizedPosition(QPoint position);
|
||||
// Converts a point in normalized [0..1] space to logical source widget space [0..m_sourceWidget->size()].
|
||||
QPoint NormalizedPositionToWidgetPosition(AZ::Vector2 normalizedPosition);
|
||||
|
||||
// Handle mouse click events.
|
||||
void HandleMouseButtonEvent(QMouseEvent* mouseEvent);
|
||||
// Handle mouse move events.
|
||||
@@ -144,6 +155,8 @@ namespace AzToolsFramework
|
||||
bool m_mouseChannelsNeedUpdate = false;
|
||||
// Flags whether or not Qt events should currently be processed.
|
||||
bool m_enabled = true;
|
||||
// Flags whether or not the cursor is being constrained to the source widget (for invisible mouse movement).
|
||||
bool m_capturingCursor = false;
|
||||
|
||||
// Our viewport-specific AZ devices. We control their internal input channel states.
|
||||
AZStd::unique_ptr<EditorQtMouseDevice> m_mouseDevice;
|
||||
|
||||
+11
-8
@@ -172,20 +172,23 @@ namespace AzToolsFramework
|
||||
PrefabDom& templateDomReference = m_prefabSystemComponentInterface->FindTemplateDom(templateId);
|
||||
|
||||
//apply patch to template
|
||||
AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::ApplyPatch(templateDomReference,
|
||||
templateDomReference.GetAllocator(), providedPatch, AZ::JsonMergeApproach::JsonPatch);
|
||||
AZ::JsonSerializationResult::ResultCode result =
|
||||
PrefabDomUtils::ApplyPatches(templateDomReference, templateDomReference.GetAllocator(), providedPatch);
|
||||
|
||||
//trigger propagation
|
||||
if (result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success)
|
||||
if (result.GetOutcome() != AZ::JsonSerializationResult::Outcomes::Success)
|
||||
{
|
||||
m_prefabSystemComponentInterface->SetTemplateDirtyFlag(templateId, true);
|
||||
m_prefabSystemComponentInterface->PropagateTemplateChanges(templateId, instanceToExclude);
|
||||
return true;
|
||||
AZ_Error("Prefab", false, "Patch was not successfully applied.");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("Prefab", false, "Patch was not successfully applied");
|
||||
return false;
|
||||
AZ_Error(
|
||||
"Prefab", result.GetOutcome() != AZ::JsonSerializationResult::Outcomes::PartialSkip,
|
||||
"Some of the patches are not successfully applied.");
|
||||
m_prefabSystemComponentInterface->SetTemplateDirtyFlag(templateId, true);
|
||||
m_prefabSystemComponentInterface->PropagateTemplateChanges(templateId, instanceToExclude);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -176,12 +176,17 @@ namespace AzToolsFramework
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ::JsonSerializationResult::ResultCode applyPatchResult = AZ::JsonSerialization::ApplyPatch(
|
||||
sourceTemplateDomCopy,
|
||||
targetTemplatePrefabDom.GetAllocator(),
|
||||
patchesReference->get(),
|
||||
AZ::JsonMergeApproach::JsonPatch);
|
||||
AZ::JsonSerializationResult::ResultCode applyPatchResult =
|
||||
PrefabDomUtils::ApplyPatches(sourceTemplateDomCopy, targetTemplatePrefabDom.GetAllocator(), patchesReference->get());
|
||||
linkedInstanceDom.CopyFrom(sourceTemplateDomCopy, targetTemplatePrefabDom.GetAllocator());
|
||||
|
||||
PrefabDomValueReference sourceTemplateName =
|
||||
PrefabDomUtils::FindPrefabDomValue(sourceTemplateDomCopy, PrefabDomUtils::SourceName);
|
||||
AZ_Assert(sourceTemplateName && sourceTemplateName->get().IsString(), "A valid source template name couldn't be found");
|
||||
PrefabDomValueReference targetTemplateName =
|
||||
PrefabDomUtils::FindPrefabDomValue(targetTemplatePrefabDom, PrefabDomUtils::SourceName);
|
||||
AZ_Assert(targetTemplateName && targetTemplateName->get().IsString(), "A valid target template name couldn't be found");
|
||||
|
||||
if (applyPatchResult.GetProcessing() != AZ::JsonSerializationResult::Processing::Completed)
|
||||
{
|
||||
AZ_Error(
|
||||
@@ -190,6 +195,14 @@ namespace AzToolsFramework
|
||||
m_sourceTemplateId, m_targetTemplateId);
|
||||
return false;
|
||||
}
|
||||
if (applyPatchResult.GetOutcome() == AZ::JsonSerializationResult::Outcomes::PartialSkip)
|
||||
{
|
||||
AZ_Error(
|
||||
"Prefab", false,
|
||||
"Link::UpdateTarget - Some of the patches couldn't be applied on the source template '%s' present under the "
|
||||
"target Template '%s'.",
|
||||
sourceTemplateName->get().GetString(), targetTemplateName->get().GetString());
|
||||
}
|
||||
}
|
||||
|
||||
// This is a guardrail to ensure the linked instance dom always has the LinkId value
|
||||
|
||||
@@ -236,6 +236,26 @@ namespace AzToolsFramework
|
||||
return findInstancesResult->get();
|
||||
}
|
||||
|
||||
AZ::JsonSerializationResult::ResultCode ApplyPatches(
|
||||
PrefabDomValue& prefabDomToApplyPatchesOn, PrefabDom::AllocatorType& allocator, const PrefabDomValue& patches)
|
||||
{
|
||||
auto issueReportingCallback = [](AZStd::string_view, AZ::JsonSerializationResult::ResultCode result,
|
||||
AZStd::string_view) -> AZ::JsonSerializationResult::ResultCode
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
if (result.GetProcessing() == Processing::Halted)
|
||||
{
|
||||
return ResultCode(result.GetTask(), Outcomes::PartialSkip);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
AZ::JsonApplyPatchSettings applyPatchSettings;
|
||||
applyPatchSettings.m_reporting = AZStd::move(issueReportingCallback);
|
||||
return AZ::JsonSerialization::ApplyPatch(
|
||||
prefabDomToApplyPatchesOn, allocator, patches, AZ::JsonMergeApproach::JsonPatch, applyPatchSettings);
|
||||
}
|
||||
|
||||
void PrintPrefabDomValue(
|
||||
[[maybe_unused]] const AZStd::string_view printMessage,
|
||||
[[maybe_unused]] const PrefabDomValue& prefabDomValue)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Serialization/Json/JsonSerializationResult.h>
|
||||
#include <AzCore/std/optional.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
@@ -122,6 +123,11 @@ namespace AzToolsFramework
|
||||
*/
|
||||
PrefabDomValueConstReference GetInstancesValue(const PrefabDomValue& prefabDom);
|
||||
|
||||
AZ::JsonSerializationResult::ResultCode ApplyPatches(
|
||||
PrefabDomValue& prefabDomToApplyPatchesOn,
|
||||
PrefabDom::AllocatorType& allocator,
|
||||
const PrefabDomValue& patches);
|
||||
|
||||
/**
|
||||
* Prints the contents of the given prefab DOM value to the debug output console in a readable format.
|
||||
* @param printMessage The message that will be printed before printing the PrefabDomValue
|
||||
|
||||
@@ -261,8 +261,13 @@ namespace AzToolsFramework
|
||||
instanceDom.CopyFrom(instanceDomRef->get(), instanceDom.GetAllocator());
|
||||
|
||||
//apply the patch to the template within the target
|
||||
AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::ApplyPatch(instanceDom,
|
||||
instanceDom.GetAllocator(), patch, AZ::JsonMergeApproach::JsonPatch);
|
||||
AZ::JsonSerializationResult::ResultCode result = PrefabDomUtils::ApplyPatches(instanceDom, instanceDom.GetAllocator(), patch);
|
||||
|
||||
AZ_Error(
|
||||
"Prefab",
|
||||
result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::PartialSkip ||
|
||||
result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success,
|
||||
"Some of the patches are not successfully applied.");
|
||||
|
||||
//remove the link id placed into the instance
|
||||
auto linkIdIter = instanceDom.FindMember(PrefabDomUtils::LinkIdName);
|
||||
|
||||
@@ -22,11 +22,11 @@ namespace AzToolsFramework
|
||||
/// @name Reverse URLs.
|
||||
/// Used to identify common actions and override them when necessary.
|
||||
//@{
|
||||
static const AZ::Crc32 s_backAction = AZ_CRC("com.amazon.action.common.back", 0xd772a2af);
|
||||
static const AZ::Crc32 s_deleteAction = AZ_CRC("com.amazon.action.common.delete", 0x5731f6cb);
|
||||
static const AZ::Crc32 s_duplicateAction = AZ_CRC("com.amazon.action.common.duplicate", 0x08ccf461);
|
||||
static const AZ::Crc32 s_nextComponentMode = AZ_CRC("com.amazon.action.common.nextComponentMode", 0xcc26094f);
|
||||
static const AZ::Crc32 s_previousComponentMode = AZ_CRC("com.amazon.action.common.previousComponentMode", 0x0d18ff39);
|
||||
static const AZ::Crc32 s_backAction = AZ_CRC("com.o3de.action.common.back", 0xd772a2af);
|
||||
static const AZ::Crc32 s_deleteAction = AZ_CRC("com.o3de.action.common.delete", 0x5731f6cb);
|
||||
static const AZ::Crc32 s_duplicateAction = AZ_CRC("com.o3de.action.common.duplicate", 0x08ccf461);
|
||||
static const AZ::Crc32 s_nextComponentMode = AZ_CRC("com.o3de.action.common.nextComponentMode", 0xcc26094f);
|
||||
static const AZ::Crc32 s_previousComponentMode = AZ_CRC("com.o3de.action.common.previousComponentMode", 0x0d18ff39);
|
||||
//@}
|
||||
|
||||
/// Specific Action properties to be sent to a type implementing
|
||||
|
||||
@@ -276,11 +276,6 @@ namespace AzToolsFramework
|
||||
virtual void EndCursorCapture() = 0;
|
||||
//! Gets the most recent recorded cursor position in the viewport in screen space coordinates.
|
||||
virtual AzFramework::ScreenPoint ViewportCursorScreenPosition() = 0;
|
||||
//! Gets the cursor position recorded prior to the most recent cursor position.
|
||||
//! Note: The cursor may be captured by the viewport, in which case this may not correspond to the last result
|
||||
//! from ViewportCursorScreenPosition. This method will always return the correct position to generate a mouse
|
||||
//! position delta.
|
||||
virtual AZStd::optional<AzFramework::ScreenPoint> PreviousViewportCursorScreenPosition() = 0;
|
||||
//! Is mouse over viewport.
|
||||
virtual bool IsMouseOver() const = 0;
|
||||
|
||||
|
||||
+1
-1
@@ -98,7 +98,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
}
|
||||
|
||||
AZ::Crc32 m_uri; //!< Unique identifier for the Action. (In the form 'com.amazon.action.---").
|
||||
AZ::Crc32 m_uri; //!< Unique identifier for the Action. (In the form 'com.o3de.action.---").
|
||||
AZStd::vector<AZStd::function<void()>> m_callbacks; //!< Callbacks associated with this Action (note: with multi-selections
|
||||
//!< there will be a callback per Entity/Component).
|
||||
AZStd::unique_ptr<QAction> m_action; //!< The QAction associated with the overrideWidget for all ComponentMode actions.
|
||||
|
||||
@@ -76,6 +76,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
|
||||
PRIVATE
|
||||
AZ::AzTestShared
|
||||
3rdParty::Qt::Test
|
||||
AZ::AzFrameworkTestShared
|
||||
AZ::AzToolsFramework
|
||||
AZ::AzToolsFrameworkTestCommon
|
||||
AZ::AzManipulatorTestFramework.Static
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <AzCore/Memory/Memory.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzCore/UserSettings/UserSettingsComponent.h>
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <Tests/AZTestShared/Utils/Utils.h>
|
||||
#include <AzToolsFramework/Archive/ArchiveAPI.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
@@ -23,6 +24,7 @@
|
||||
#include <QStandardPaths>
|
||||
#include <QTemporaryDir>
|
||||
#include <QTextStream>
|
||||
#include <Utils/Utils.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
@@ -72,7 +74,7 @@ namespace UnitTest
|
||||
|
||||
void CreateArchiveFolder( QString archiveFolderName, QStringList fileList )
|
||||
{
|
||||
QDir tempPath = QDir(m_tempDir.path()).filePath(archiveFolderName);
|
||||
QDir tempPath = QDir(m_tempDir.GetDirectory()).filePath(archiveFolderName);
|
||||
|
||||
for (const auto& thisFile : fileList)
|
||||
{
|
||||
@@ -88,12 +90,12 @@ namespace UnitTest
|
||||
|
||||
QString GetArchivePath()
|
||||
{
|
||||
return QDir(m_tempDir.path()).filePath("TestArchive.pak");
|
||||
return QDir(m_tempDir.GetDirectory()).filePath("TestArchive.pak");
|
||||
}
|
||||
|
||||
QString GetArchiveFolder()
|
||||
{
|
||||
return QDir(m_tempDir.path()).filePath(GetArchiveFolderName());
|
||||
return QDir(m_tempDir.GetDirectory()).filePath(GetArchiveFolderName());
|
||||
}
|
||||
|
||||
bool CreateArchive()
|
||||
@@ -111,6 +113,11 @@ namespace UnitTest
|
||||
// shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash
|
||||
// in the unit tests.
|
||||
AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize);
|
||||
|
||||
if (auto fileIoBase = AZ::IO::FileIOBase::GetInstance(); fileIoBase != nullptr)
|
||||
{
|
||||
fileIoBase->SetAlias("@assets@", m_tempDir.GetDirectory());
|
||||
}
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
@@ -120,7 +127,7 @@ namespace UnitTest
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<ToolsTestApplication> m_app;
|
||||
QTemporaryDir m_tempDir {QDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation)).filePath("ArchiveTests-")};
|
||||
UnitTest::ScopedTemporaryDirectory m_tempDir;
|
||||
};
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS
|
||||
@@ -129,7 +136,7 @@ namespace UnitTest
|
||||
TEST_F(ArchiveTest, CreateArchiveBlocking_FilesAtThreeDepths_ArchiveCreated)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS
|
||||
{
|
||||
EXPECT_TRUE(m_tempDir.isValid());
|
||||
EXPECT_TRUE(m_tempDir.IsValid());
|
||||
CreateArchiveFolder();
|
||||
|
||||
bool createResult = CreateArchive();
|
||||
@@ -143,7 +150,7 @@ namespace UnitTest
|
||||
TEST_F(ArchiveTest, ListFilesInArchiveBlocking_FilesAtThreeDepths_FilesFound)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS
|
||||
{
|
||||
EXPECT_TRUE(m_tempDir.isValid());
|
||||
EXPECT_TRUE(m_tempDir.IsValid());
|
||||
CreateArchiveFolder();
|
||||
|
||||
EXPECT_EQ(CreateArchive(), true);
|
||||
@@ -203,7 +210,9 @@ namespace UnitTest
|
||||
}
|
||||
|
||||
bool catalogCreated{ false };
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
AzToolsFramework::AssetBundleCommandsBus::BroadcastResult(catalogCreated, &AzToolsFramework::AssetBundleCommandsBus::Events::CreateDeltaCatalog, GetArchivePath().toStdString().c_str(), true);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // produces different counts in different platforms
|
||||
EXPECT_EQ(catalogCreated, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <AzToolsFramework/AssetCatalog/PlatformAddressedAssetCatalog.h>
|
||||
#include <AzToolsFramework/UnitTest/ToolsTestApplication.h>
|
||||
#include <AzCore/UserSettings/UserSettingsComponent.h>
|
||||
#include <Utils/Utils.h>
|
||||
|
||||
namespace // anonymous
|
||||
{
|
||||
@@ -54,9 +55,11 @@ namespace UnitTest
|
||||
m_localFileIO = aznew AZ::IO::LocalFileIO();
|
||||
|
||||
m_priorFileIO = AZ::IO::FileIOBase::GetInstance();
|
||||
AZ::IO::FileIOBase::SetInstance(nullptr);
|
||||
AZ::IO::FileIOBase::SetInstance(m_localFileIO);
|
||||
|
||||
AZ::IO::FileIOBase::GetInstance()->SetAlias("@assets@", GetTestFolderPath().c_str());
|
||||
AZ::IO::FileIOBase::GetInstance()->SetAlias("@assets@", m_tempDir.GetDirectory());
|
||||
|
||||
AZStd::string assetRoot = AzToolsFramework::PlatformAddressedAssetCatalog::GetAssetRootForPlatform(AzFramework::PlatformId::PC);
|
||||
|
||||
for (int idx = 0; idx < TotalAssets; idx++)
|
||||
@@ -68,9 +71,11 @@ namespace UnitTest
|
||||
assetRegistry.RegisterAsset(m_assets[idx], info);
|
||||
|
||||
AzFramework::StringFunc::Path::Join(assetRoot.c_str(), info.m_relativePath.c_str(), m_assetsPath[idx]);
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
if (m_fileStreams[idx].Open(m_assetsPath[idx].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath))
|
||||
{
|
||||
m_fileStreams[idx].Write(info.m_relativePath.size(), info.m_relativePath.data());
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -114,10 +119,12 @@ namespace UnitTest
|
||||
|
||||
// Modify contents of asset2
|
||||
int fileIndex = 2;
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
if (m_fileStreams[fileIndex].Open(m_assetsPath[fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath))
|
||||
{
|
||||
AZStd::string fileContent = AZStd::string::format("new Asset%d.txt", fileIndex);// changing file content
|
||||
m_fileStreams[fileIndex].Write(fileContent.size(), fileContent.c_str());
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -126,10 +133,12 @@ namespace UnitTest
|
||||
|
||||
// Modify contents of asset 4
|
||||
fileIndex = 4;
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
if (m_fileStreams[fileIndex].Open(m_assetsPath[fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath))
|
||||
{
|
||||
AZStd::string fileContent = AZStd::string::format("new Asset%d.txt", fileIndex);// changing file content
|
||||
m_fileStreams[fileIndex].Write(fileContent.size(), fileContent.c_str());
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -151,7 +160,9 @@ namespace UnitTest
|
||||
{
|
||||
if (fileIO->Exists(TempFiles[idx]))
|
||||
{
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
fileIO->Remove(TempFiles[idx]);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1); // deleting from asset cache folder
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,19 +173,24 @@ namespace UnitTest
|
||||
m_fileStreams[idx].Close();
|
||||
if (fileIO->Exists(m_assetsPath[idx].c_str()))
|
||||
{
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
fileIO->Remove(m_assetsPath[idx].c_str());
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1); // deleting from asset cache folder
|
||||
}
|
||||
}
|
||||
|
||||
auto pcCatalogFile = AzToolsFramework::PlatformAddressedAssetCatalog::GetCatalogRegistryPathForPlatform(AzFramework::PlatformId::PC);
|
||||
if (fileIO->Exists(pcCatalogFile.c_str()))
|
||||
{
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
fileIO->Remove(pcCatalogFile.c_str());
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1); // deleting from asset cache folder
|
||||
}
|
||||
|
||||
delete m_pcCatalog;
|
||||
delete m_localFileIO;
|
||||
m_localFileIO = nullptr;
|
||||
AZ::IO::FileIOBase::SetInstance(nullptr);
|
||||
AZ::IO::FileIOBase::SetInstance(m_priorFileIO);
|
||||
m_application->Stop();
|
||||
delete m_application;
|
||||
@@ -726,6 +742,7 @@ namespace UnitTest
|
||||
}
|
||||
|
||||
ToolsTestApplication* m_application;
|
||||
UnitTest::ScopedTemporaryDirectory m_tempDir;
|
||||
AzToolsFramework::PlatformAddressedAssetCatalog* m_pcCatalog;
|
||||
AZ::IO::FileIOBase* m_priorFileIO = nullptr;
|
||||
AZ::IO::FileIOBase* m_localFileIO = nullptr;
|
||||
|
||||
@@ -87,10 +87,12 @@ namespace UnitTest
|
||||
for (int idx = 0; idx < s_totalAssets; idx++)
|
||||
{
|
||||
AzFramework::StringFunc::Path::Join(assetRoot.c_str(), m_assetsPath[idx].c_str(), m_assetsPathFull[platformCount][idx]);
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
if (m_fileStreams[platformCount][idx].Open(m_assetsPathFull[platformCount][idx].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath))
|
||||
{
|
||||
m_fileStreams[platformCount][idx].Write(m_assetsPath[idx].size(), m_assetsPath[idx].data());
|
||||
m_fileStreams[platformCount][idx].Close();
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, only invalid for PC, not invalid in Jenkins
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -112,7 +114,9 @@ namespace UnitTest
|
||||
m_testDynamicSliceAssetId = testDynamicSliceAsset;
|
||||
m_assetRegistry->RegisterAsset(testDynamicSliceAsset, dynamicSliceAssetInfo);
|
||||
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
AZ::IO::FileIOStream dynamicSliceFileIOStream(TestDynamicSliceAssetPath, AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeText);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins
|
||||
|
||||
AZ::Data::AssetInfo sliceAssetInfo;
|
||||
sliceAssetInfo.m_relativePath = TestSliceAssetPath;
|
||||
@@ -124,7 +128,9 @@ namespace UnitTest
|
||||
secondSliceAssetInfo.m_assetId = secondTestSliceAsset;
|
||||
m_assetRegistry->RegisterAsset(secondTestSliceAsset, secondSliceAssetInfo);
|
||||
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
AZ::IO::FileIOStream sliceFileIOStream(TestSliceAssetPath, AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeText);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins
|
||||
|
||||
// asset0 -> asset1 -> asset2 -> asset4
|
||||
// --> asset3
|
||||
@@ -186,7 +192,6 @@ namespace UnitTest
|
||||
AZ::IO::Path assetRoot(AZ::Utils::GetProjectPath());
|
||||
assetRoot /= "Cache";
|
||||
AZ::IO::FileIOBase::GetInstance()->SetAlias("@root@", assetRoot.c_str());
|
||||
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
@@ -195,7 +200,9 @@ namespace UnitTest
|
||||
|
||||
if (fileIO->Exists(s_catalogFile))
|
||||
{
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
fileIO->Remove(s_catalogFile);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins
|
||||
}
|
||||
|
||||
for (size_t platformCount = 0; platformCount < s_totalTestPlatforms; ++platformCount)
|
||||
@@ -206,26 +213,34 @@ namespace UnitTest
|
||||
// we need to close the handle before we try to remove the file
|
||||
if (fileIO->Exists(m_assetsPathFull[platformCount][idx].c_str()))
|
||||
{
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
fileIO->Remove(m_assetsPathFull[platformCount][idx].c_str());
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fileIO->Exists(TestSliceAssetPath))
|
||||
{
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
fileIO->Remove(TestSliceAssetPath);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins
|
||||
}
|
||||
|
||||
if (fileIO->Exists(TestDynamicSliceAssetPath))
|
||||
{
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
fileIO->Remove(TestDynamicSliceAssetPath);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins
|
||||
}
|
||||
|
||||
auto pcCatalogFile = AzToolsFramework::PlatformAddressedAssetCatalog::GetCatalogRegistryPathForPlatform(AzFramework::PlatformId::PC);
|
||||
auto androidCatalogFile = AzToolsFramework::PlatformAddressedAssetCatalog::GetCatalogRegistryPathForPlatform(AzFramework::PlatformId::ANDROID_ID);
|
||||
if (fileIO->Exists(pcCatalogFile.c_str()))
|
||||
{
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
fileIO->Remove(pcCatalogFile.c_str());
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins
|
||||
}
|
||||
|
||||
if (fileIO->Exists(androidCatalogFile.c_str()))
|
||||
@@ -266,7 +281,9 @@ namespace UnitTest
|
||||
AZ::IO::SystemFile::SetWritable(filePath.c_str(), false);
|
||||
|
||||
// Attempt to save to the same file. Should not be allowed.
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
EXPECT_FALSE(m_assetSeedManager->Save(filePath));
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins
|
||||
|
||||
// Clean up the test environment
|
||||
AZ::IO::SystemFile::SetWritable(filePath.c_str(), true);
|
||||
@@ -290,7 +307,9 @@ namespace UnitTest
|
||||
AZ::IO::SystemFile::SetWritable(filePath.c_str(), false);
|
||||
|
||||
// Attempt to save to the same file. Should not be allowed.
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
EXPECT_FALSE(m_assetSeedManager->SaveAssetFileInfo(filePath, AzFramework::PlatformFlags::Platform_PC, {}));
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins
|
||||
|
||||
// Clean up the test environment
|
||||
AZ::IO::SystemFile::SetWritable(filePath.c_str(), true);
|
||||
@@ -357,7 +376,9 @@ namespace UnitTest
|
||||
m_assetSeedManager->AddSeedAsset(assets[2], AzFramework::PlatformFlags::Platform_PC);
|
||||
|
||||
// Step we are testing
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
m_assetSeedManager->AddPlatformToAllSeeds(AzFramework::PlatformId::ANDROID_ID);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins
|
||||
|
||||
// Verification
|
||||
AzFramework::PlatformFlags expectedPlatformFlags = AzFramework::PlatformFlags::Platform_PC | AzFramework::PlatformFlags::Platform_ANDROID;
|
||||
@@ -623,11 +644,13 @@ namespace UnitTest
|
||||
|
||||
EXPECT_EQ(assetList1.m_fileInfoList.size(), 1);
|
||||
EXPECT_TRUE(Search(assetList1, assets[fileIndex]));
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
if (m_fileStreams[0][fileIndex].Open(m_assetsPathFull[0][fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath))
|
||||
{
|
||||
AZStd::string fileContent = AZStd::string::format("asset%d.txt", fileIndex);
|
||||
m_fileStreams[0][fileIndex].Write(fileContent.size(), fileContent.c_str());
|
||||
m_fileStreams[0][fileIndex].Close();
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins
|
||||
}
|
||||
|
||||
AzToolsFramework::AssetFileInfoList assetList2 = m_assetSeedManager->GetDependencyList(AzFramework::PlatformId::PC);
|
||||
@@ -654,11 +677,13 @@ namespace UnitTest
|
||||
|
||||
EXPECT_EQ(assetList1.m_fileInfoList.size(), 1);
|
||||
EXPECT_TRUE(Search(assetList1, assets[fileIndex]));
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
if (m_fileStreams[0][fileIndex].Open(m_assetsPathFull[0][fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath))
|
||||
{
|
||||
AZStd::string fileContent = AZStd::string::format("asset%d.txt", fileIndex + 1);// changing file content
|
||||
m_fileStreams[0][fileIndex].Write(fileContent.size(), fileContent.c_str());
|
||||
m_fileStreams[0][fileIndex].Close();
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins
|
||||
}
|
||||
|
||||
AzToolsFramework::AssetFileInfoList assetList2 = m_assetSeedManager->GetDependencyList(AzFramework::PlatformId::PC);
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzTest/AzTest.h>
|
||||
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzFramework/Components/ComponentAdapter.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorComponentAdapter.h>
|
||||
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
static bool s_activateCalled = false;
|
||||
static bool s_deactivateCalled = false;
|
||||
|
||||
struct TestConfig
|
||||
: public AZ::ComponentConfig
|
||||
{
|
||||
AZ_RTTI(TestConfig, "{835CF711-77DB-4DF2-A364-936227A7AF5F}", AZ::ComponentConfig);
|
||||
uint32_t m_testValue = 0;
|
||||
};
|
||||
|
||||
class TestController
|
||||
{
|
||||
public:
|
||||
|
||||
AZ_TYPE_INFO(TestController, "{89C1FED9-C306-4B00-9EA4-577862D9277D}");
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
AZ_UNUSED(context);
|
||||
}
|
||||
|
||||
TestController() = default;
|
||||
TestController(const TestConfig& config):
|
||||
m_config(config)
|
||||
{
|
||||
}
|
||||
void Activate(AZ::EntityId entityId)
|
||||
{
|
||||
AZ_UNUSED(entityId);
|
||||
s_activateCalled = true;
|
||||
}
|
||||
void Deactivate()
|
||||
{
|
||||
s_deactivateCalled = true;
|
||||
}
|
||||
void SetConfiguration(const TestConfig& config)
|
||||
{
|
||||
m_config = config;
|
||||
}
|
||||
const TestConfig& GetConfiguration() const
|
||||
{
|
||||
return m_config;
|
||||
}
|
||||
TestConfig m_config;
|
||||
};
|
||||
|
||||
class TestRuntimeComponent
|
||||
: public AzFramework::Components::ComponentAdapter<TestController, TestConfig>
|
||||
{
|
||||
public:
|
||||
using BaseClass = AzFramework::Components::ComponentAdapter<TestController, TestConfig>;
|
||||
AZ_COMPONENT(TestRuntimeComponent, "{136104E4-36A6-4778-AE65-065D33F87E76}", BaseClass);
|
||||
TestRuntimeComponent() = default;
|
||||
TestRuntimeComponent(const TestConfig& config)
|
||||
: BaseClass(config)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class TestEditorComponent
|
||||
: public AzToolsFramework::Components::EditorComponentAdapter<TestController, TestRuntimeComponent, TestConfig>
|
||||
{
|
||||
public:
|
||||
using BaseClass = AzToolsFramework::Components::EditorComponentAdapter<TestController, TestRuntimeComponent, TestConfig>;
|
||||
AZ_EDITOR_COMPONENT(TestEditorComponent, "{5FA2B1D6-E2DA-47FB-8419-B6425C37AC80}", BaseClass);
|
||||
TestEditorComponent() = default;
|
||||
TestEditorComponent(const TestConfig& config)
|
||||
: BaseClass(config)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class WrappedComponentTest
|
||||
: public AllocatorsFixture
|
||||
{
|
||||
|
||||
AZStd::unique_ptr<AZ::SerializeContext> m_serializeContext;
|
||||
AZStd::unique_ptr<AZ::ComponentDescriptor> m_testRuntimeComponentDescriptor;
|
||||
AZStd::unique_ptr<AZ::ComponentDescriptor> m_testEditorComponentDescriptor;
|
||||
|
||||
public:
|
||||
void SetUp() override
|
||||
{
|
||||
AllocatorsFixture::SetUp();
|
||||
|
||||
s_activateCalled = false;
|
||||
s_deactivateCalled = false;
|
||||
|
||||
m_serializeContext = AZStd::make_unique<AZ::SerializeContext>();
|
||||
|
||||
m_testRuntimeComponentDescriptor.reset(TestRuntimeComponent::CreateDescriptor());
|
||||
m_testRuntimeComponentDescriptor->Reflect(&(*m_serializeContext));
|
||||
|
||||
m_testEditorComponentDescriptor.reset(TestEditorComponent::CreateDescriptor());
|
||||
m_testEditorComponentDescriptor->Reflect(&(*m_serializeContext));
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
m_testEditorComponentDescriptor.reset();
|
||||
m_testRuntimeComponentDescriptor.reset();
|
||||
m_serializeContext.reset();
|
||||
|
||||
AllocatorsFixture::TearDown();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(WrappedComponentTest, RuntimeWrappersWrapCommon)
|
||||
{
|
||||
AZ::Entity entity;
|
||||
TestRuntimeComponent* runtimeComponent = entity.CreateComponent<TestRuntimeComponent>();
|
||||
|
||||
entity.Init();
|
||||
entity.Activate();
|
||||
EXPECT_TRUE(s_activateCalled);
|
||||
entity.Deactivate();
|
||||
EXPECT_TRUE(s_deactivateCalled);
|
||||
|
||||
TestConfig config;
|
||||
config.m_testValue = 100;
|
||||
|
||||
EXPECT_TRUE(runtimeComponent->SetConfiguration(config));
|
||||
|
||||
TestConfig outConfig;
|
||||
EXPECT_TRUE(runtimeComponent->GetConfiguration(outConfig));
|
||||
|
||||
EXPECT_EQ(config.m_testValue, outConfig.m_testValue);
|
||||
}
|
||||
|
||||
TEST_F(WrappedComponentTest, EditorWrappersWrapCommon)
|
||||
{
|
||||
AZ::Entity entity;
|
||||
TestEditorComponent* editorComponent = entity.CreateComponent<TestEditorComponent>();
|
||||
|
||||
entity.Init();
|
||||
entity.Activate();
|
||||
EXPECT_TRUE(s_activateCalled);
|
||||
entity.Deactivate();
|
||||
EXPECT_TRUE(s_deactivateCalled);
|
||||
|
||||
TestConfig config;
|
||||
config.m_testValue = 100;
|
||||
|
||||
EXPECT_TRUE(editorComponent->SetConfiguration(config));
|
||||
|
||||
TestConfig outConfig;
|
||||
EXPECT_TRUE(editorComponent->GetConfiguration(outConfig));
|
||||
|
||||
EXPECT_EQ(config.m_testValue, outConfig.m_testValue);
|
||||
|
||||
AZ::Entity gameEntity;
|
||||
editorComponent->BuildGameEntity(&gameEntity);
|
||||
TestRuntimeComponent* testRuntimeComponent = gameEntity.FindComponent<TestRuntimeComponent>();
|
||||
|
||||
EXPECT_NE(testRuntimeComponent, nullptr);
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -196,7 +196,7 @@ namespace AzToolsFramework
|
||||
|
||||
AZStd::vector<AzToolsFramework::ActionOverride> PlaceHolderComponentMode::PopulateActionsImpl()
|
||||
{
|
||||
const AZ::Crc32 placeHolderComponentModeAction = AZ_CRC_CE("com.amazon.action.placeholder.test");
|
||||
const AZ::Crc32 placeHolderComponentModeAction = AZ_CRC_CE("com.o3de.action.placeholder.test");
|
||||
|
||||
return AZStd::vector<AzToolsFramework::ActionOverride>
|
||||
{
|
||||
|
||||
@@ -493,7 +493,10 @@ namespace UnitTest
|
||||
// Add placeholder component which implements component mode.
|
||||
entity->CreateComponent<PlaceHolderComponent>();
|
||||
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
entity->Activate();
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -348,7 +348,6 @@ namespace UnitTest
|
||||
EXPECT_FALSE(AzToolsFramework::ComponentPaletteUtil::ContainsEditableComponents(context, &Filter_IsTestComponent2, AZ::ComponentDescriptor::DependencyArrayType()));
|
||||
|
||||
// Reflect Test Component 2 for subsequent tests
|
||||
Inspector_TestComponent2::Reflect(context);
|
||||
m_application->RegisterComponentDescriptor(Inspector_TestComponent2Descriptor);
|
||||
|
||||
// Verify that there is now a component that satisfies the AppearsInGameComponentMenu filter without service dependency conditions
|
||||
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "EntityOwnershipServiceTestFixture.h"
|
||||
#include <AzCore/UserSettings/UserSettingsComponent.h>
|
||||
#include <AzFramework/Components/AzFrameworkConfigurationSystemComponent.h>
|
||||
|
||||
#include <AzToolsFramework/Prefab/PrefabSystemComponent.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
void EntityOwnershipServiceTestFixture::SetUpEntityOwnershipServiceTest()
|
||||
{
|
||||
AllocatorsTestFixture::SetUp();
|
||||
AZ::ComponentApplication::Descriptor componentApplicationDescriptor;
|
||||
componentApplicationDescriptor.m_useExistingAllocator = true;
|
||||
componentApplicationDescriptor.m_enableDrilling = false; // we already created a memory driller for the test(AllocatorsTestFixture)
|
||||
m_app = AZStd::make_unique<EntityOwnershipServiceApplication>();
|
||||
m_app->Start(componentApplicationDescriptor);
|
||||
|
||||
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
|
||||
// shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash
|
||||
// in the unit tests.
|
||||
AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize);
|
||||
}
|
||||
|
||||
void EntityOwnershipServiceTestFixture::TearDownEntityOwnershipServiceTest()
|
||||
{
|
||||
m_app.reset();
|
||||
AllocatorsTestFixture::TearDown();
|
||||
}
|
||||
|
||||
AZ::ComponentTypeList EntityOwnershipServiceTestFixture::EntityOwnershipServiceApplication::GetRequiredSystemComponents() const
|
||||
{
|
||||
AZ::ComponentTypeList defaultRequiredComponents = AzFramework::Application::GetRequiredSystemComponents();
|
||||
|
||||
defaultRequiredComponents.emplace_back(azrtti_typeid<AzToolsFramework::Prefab::PrefabSystemComponent>());
|
||||
|
||||
auto findComponentIterator = AZStd::find(defaultRequiredComponents.begin(), defaultRequiredComponents.end(),
|
||||
azrtti_typeid<AzFramework::GameEntityContextComponent>());
|
||||
if (findComponentIterator != defaultRequiredComponents.end())
|
||||
{
|
||||
defaultRequiredComponents.erase(findComponentIterator);
|
||||
}
|
||||
findComponentIterator = AZStd::find(defaultRequiredComponents.begin(), defaultRequiredComponents.end(),
|
||||
azrtti_typeid<AzFramework::AzFrameworkConfigurationSystemComponent>());
|
||||
if (findComponentIterator != defaultRequiredComponents.end())
|
||||
{
|
||||
defaultRequiredComponents.erase(findComponentIterator);
|
||||
}
|
||||
return defaultRequiredComponents;
|
||||
}
|
||||
|
||||
AzFramework::RootSliceAsset EntityOwnershipServiceTestFixture::GetRootSliceAsset()
|
||||
{
|
||||
AzFramework::RootSliceAsset rootSliceAsset;
|
||||
AzFramework::SliceEntityOwnershipServiceRequestBus::BroadcastResult(rootSliceAsset,
|
||||
&AzFramework::SliceEntityOwnershipServiceRequestBus::Events::GetRootAsset);
|
||||
return rootSliceAsset;
|
||||
}
|
||||
|
||||
void EntityOwnershipServiceTestFixture::HandleEntitiesAdded(const AzFramework::EntityList& entityList)
|
||||
{
|
||||
m_entitiesAddedCallbackTriggered = true;
|
||||
|
||||
for (AZ::Entity* entity : entityList)
|
||||
{
|
||||
// If the entities are not initialized, they won't be removed from ComponentApplication during Entity destruction.
|
||||
if (entity->GetState() != AZ::Entity::State::Init)
|
||||
{
|
||||
entity->Init();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EntityOwnershipServiceTestFixture::HandleEntitiesRemoved(const AzFramework::EntityIdList&)
|
||||
{
|
||||
m_entityRemovedCallbackTriggered = true;
|
||||
}
|
||||
|
||||
bool EntityOwnershipServiceTestFixture::ValidateEntities(const AzFramework::EntityList&)
|
||||
{
|
||||
m_validateEntitiesCallbackTriggered = true;
|
||||
return m_areEntitiesValidForContext;
|
||||
}
|
||||
|
||||
AzFramework::SliceInstantiationTicket EntityOwnershipServiceTestFixture::AddSlice(const EntityList& entityList,
|
||||
const bool isAsynchronous)
|
||||
{
|
||||
AZ::Data::Asset<AZ::SliceAsset> sliceAsset;
|
||||
sliceAsset.Create(AZ::Data::AssetId(AZ::Uuid::CreateRandom()), false);
|
||||
|
||||
return AddSlice(entityList, isAsynchronous, sliceAsset);
|
||||
}
|
||||
|
||||
AzFramework::SliceInstantiationTicket EntityOwnershipServiceTestFixture::AddSlice(const EntityList& entityList,
|
||||
const bool isAsynchronous, AZ::Data::Asset<AZ::SliceAsset>& sliceAsset)
|
||||
{
|
||||
AddSliceComponentToAsset(sliceAsset, entityList);
|
||||
|
||||
AzFramework::SliceInstantiationTicket sliceInstantiationTicket;
|
||||
AzFramework::SliceEntityOwnershipServiceRequestBus::BroadcastResult(sliceInstantiationTicket,
|
||||
&AzFramework::SliceEntityOwnershipServiceRequestBus::Events::InstantiateSlice, sliceAsset, nullptr, nullptr);
|
||||
if (!isAsynchronous)
|
||||
{
|
||||
AZ::TickBus::ExecuteQueuedEvents();
|
||||
}
|
||||
return sliceInstantiationTicket;
|
||||
}
|
||||
|
||||
void EntityOwnershipServiceTestFixture::AddEditorSlice(
|
||||
AZ::Data::Asset<AZ::SliceAsset>& sliceAsset, const AZ::Transform& worldTransform, const EntityList& entityList)
|
||||
{
|
||||
AddSliceComponentToAsset(sliceAsset, entityList);
|
||||
AzToolsFramework::SliceEditorEntityOwnershipServiceRequestBus::Broadcast(
|
||||
&AzToolsFramework::SliceEditorEntityOwnershipServiceRequests::InstantiateEditorSlice, sliceAsset, worldTransform);
|
||||
AZ::TickBus::ExecuteQueuedEvents();
|
||||
}
|
||||
|
||||
void EntityOwnershipServiceTestFixture::AddSliceComponentToAsset(AZ::Data::Asset<AZ::SliceAsset>& sliceAsset,
|
||||
const EntityList& entityList)
|
||||
{
|
||||
AZ::Entity* sliceEntity = aznew AZ::Entity();
|
||||
AZ::SliceComponent* sliceComponent = sliceEntity->CreateComponent<AZ::SliceComponent>();
|
||||
sliceComponent->SetSerializeContext(m_app->GetSerializeContext());
|
||||
|
||||
for (AZ::Entity* entity : entityList)
|
||||
{
|
||||
sliceComponent->AddEntity(entity);
|
||||
}
|
||||
|
||||
sliceAsset->SetData(sliceEntity, sliceComponent);
|
||||
}
|
||||
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Component/ComponentApplication.h>
|
||||
#include <AzCore/Memory/PoolAllocator.h>
|
||||
#include <AzCore/Slice/SliceAssetHandler.h>
|
||||
#include <AzCore/Slice/SliceComponent.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AzFramework/Application/Application.h>
|
||||
#include <AzFramework/Entity/GameEntityContextComponent.h>
|
||||
#include <AzFramework/Entity/SliceEntityOwnershipService.h>
|
||||
#include <AzToolsFramework/Application/ToolsApplication.h>
|
||||
#include <AzToolsFramework/Entity/SliceEditorEntityOwnershipService.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
using EntityList = AZStd::vector<AZ::Entity*>;
|
||||
|
||||
class EntityOwnershipServiceTestFixture
|
||||
: public AllocatorsTestFixture
|
||||
{
|
||||
protected:
|
||||
AzFramework::RootSliceAsset GetRootSliceAsset();
|
||||
void SetUpEntityOwnershipServiceTest();
|
||||
void TearDownEntityOwnershipServiceTest();
|
||||
AzFramework::SliceInstantiationTicket AddSlice(const EntityList& entityList, const bool isAsynchronous = false);
|
||||
void AddEditorSlice(
|
||||
AZ::Data::Asset<AZ::SliceAsset>& sliceAsset, const AZ::Transform& worldTransform, const EntityList& entityList);
|
||||
AzFramework::SliceInstantiationTicket AddSlice(const EntityList& entityList, const bool isAsynchronous,
|
||||
AZ::Data::Asset<AZ::SliceAsset>& sliceAsset);
|
||||
void HandleEntitiesAdded(const AzFramework::EntityList& entityList);
|
||||
void HandleEntitiesRemoved(const AzFramework::EntityIdList& entityIds);
|
||||
bool ValidateEntities(const AzFramework::EntityList&);
|
||||
|
||||
void AddSliceComponentToAsset(AZ::Data::Asset<AZ::SliceAsset>& sliceAsset, const EntityList& entityList);
|
||||
|
||||
AZStd::unique_ptr<AzFramework::Application> m_app;
|
||||
bool m_entitiesAddedCallbackTriggered = false;
|
||||
bool m_entityRemovedCallbackTriggered = false;
|
||||
bool m_validateEntitiesCallbackTriggered = false;
|
||||
bool m_areEntitiesValidForContext = true;
|
||||
|
||||
class EntityOwnershipServiceApplication : public AzToolsFramework::ToolsApplication
|
||||
{
|
||||
public:
|
||||
AZ::ComponentTypeList GetRequiredSystemComponents() const override;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+266
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzToolsFramework/Entity/SliceEditorEntityOwnershipService.h>
|
||||
#include "EntityOwnershipServiceTestFixture.h"
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
class SliceEditorEntityOwnershipTests
|
||||
: public EntityOwnershipServiceTestFixture
|
||||
{
|
||||
public:
|
||||
void SetUp() override
|
||||
{
|
||||
SetUpEntityOwnershipServiceTest();
|
||||
m_sliceEditorEntityOwnershipService = AZStd::make_unique<AzToolsFramework::SliceEditorEntityOwnershipService>(
|
||||
AZ::Uuid::CreateNull(), m_app->GetSerializeContext());
|
||||
|
||||
m_sliceEditorEntityOwnershipService->SetEntitiesAddedCallback([this](const AzFramework::EntityList& entityList)
|
||||
{
|
||||
this->HandleEntitiesAdded(entityList);
|
||||
});
|
||||
|
||||
m_sliceEditorEntityOwnershipService->SetEntitiesRemovedCallback([this](const AzFramework::EntityIdList& entityIds)
|
||||
{
|
||||
this->HandleEntitiesRemoved(entityIds);
|
||||
});
|
||||
|
||||
m_sliceEditorEntityOwnershipService->SetValidateEntitiesCallback([this](const AzFramework::EntityList& entityList)
|
||||
{
|
||||
return this->ValidateEntities(entityList);
|
||||
});
|
||||
|
||||
m_sliceEditorEntityOwnershipService->Initialize();
|
||||
}
|
||||
void TearDown() override
|
||||
{
|
||||
m_sliceEditorEntityOwnershipService->Destroy();
|
||||
m_sliceEditorEntityOwnershipService.reset();
|
||||
TearDownEntityOwnershipServiceTest();
|
||||
}
|
||||
protected:
|
||||
|
||||
AZStd::unique_ptr<AzToolsFramework::SliceEditorEntityOwnershipService> m_sliceEditorEntityOwnershipService;
|
||||
};
|
||||
|
||||
TEST_F(SliceEditorEntityOwnershipTests, Initialize_ResetOwnershipService_CreateRootSlice)
|
||||
{
|
||||
m_sliceEditorEntityOwnershipService->Reset();
|
||||
EXPECT_TRUE(GetRootSliceAsset()->GetComponent() != nullptr);
|
||||
}
|
||||
|
||||
TEST_F(SliceEditorEntityOwnershipTests, OnAssetReloaded_RootAssetReloaded_ReloadEntities)
|
||||
{
|
||||
// Clone the root slice asset
|
||||
AZ::Data::Asset<AZ::SliceAsset> rootSliceAssetClone(GetRootSliceAsset().Get()->Clone(), AZ::Data::AssetLoadBehavior::Default);
|
||||
|
||||
AZ::Entity* sliceRootEntity = new AZ::Entity();
|
||||
AZ::SliceComponent* sliceComponent = sliceRootEntity->CreateComponent<AZ::SliceComponent>();
|
||||
sliceComponent->SetSerializeContext(m_app->GetSerializeContext());
|
||||
sliceComponent->AddEntity(aznew AZ::Entity("testEntity"));
|
||||
rootSliceAssetClone->SetData(sliceRootEntity, sliceComponent);
|
||||
|
||||
m_sliceEditorEntityOwnershipService->OnAssetReloaded(rootSliceAssetClone);
|
||||
|
||||
// Validate that entities-added callback is triggerted.
|
||||
EXPECT_TRUE(m_entitiesAddedCallbackTriggered);
|
||||
|
||||
const AzFramework::EntityList& entitiesUnderRootSlice = GetRootSliceAsset()->GetComponent()->GetNewEntities();
|
||||
|
||||
// Validate that there is only one entity under root slice.
|
||||
EXPECT_EQ(entitiesUnderRootSlice.size(), 1);
|
||||
|
||||
EXPECT_EQ(entitiesUnderRootSlice.at(0)->GetName(), "testEntity");
|
||||
}
|
||||
|
||||
TEST_F(SliceEditorEntityOwnershipTests, LoadFromStream_RemapIdsFalse_IdsNotRemapped)
|
||||
{
|
||||
AZ::Entity* rootEntity = aznew AZ::Entity();
|
||||
AZ::SliceComponent* rootSliceComponent = rootEntity->CreateComponent<AZ::SliceComponent>();
|
||||
AZ::Entity* testEntity = aznew AZ::Entity();
|
||||
rootSliceComponent->AddEntity(testEntity);
|
||||
|
||||
AZStd::vector<char> charBuffer;
|
||||
AZ::IO::ByteContainerStream<AZStd::vector<char>> stream(&charBuffer);
|
||||
AZ::Utils::SaveObjectToStream<AZ::Entity>(stream, AZ::ObjectStream::ST_XML, rootEntity, m_app->GetSerializeContext());
|
||||
stream.Seek(0, AZ::IO::GenericStream::ST_SEEK_BEGIN);
|
||||
|
||||
EXPECT_TRUE(m_sliceEditorEntityOwnershipService->LoadFromStream(stream, false));
|
||||
|
||||
AZ::SliceComponent::EntityIdToEntityIdMap previousToNewIdMap;
|
||||
AzFramework::SliceEntityOwnershipServiceRequestBus::BroadcastResult(previousToNewIdMap,
|
||||
&AzFramework::SliceEntityOwnershipServiceRequestBus::Events::GetLoadedEntityIdMap);
|
||||
|
||||
// Verify that remapping of entityIds is not done by comparing the entityIds in previousToNewIdMap
|
||||
EXPECT_TRUE(previousToNewIdMap.begin()->first == previousToNewIdMap.begin()->second);
|
||||
|
||||
delete rootEntity;
|
||||
}
|
||||
|
||||
TEST_F(SliceEditorEntityOwnershipTests, InstantiateEditorSlice_ValidAssetProvided_SliceCreated)
|
||||
{
|
||||
AZ::Data::Asset<AZ::SliceAsset> sliceAsset;
|
||||
sliceAsset.Create(AZ::Data::AssetId(AZ::Uuid::CreateRandom()), false);
|
||||
|
||||
AddEditorSlice(sliceAsset, AZ::Transform::CreateIdentity(), EntityList{});
|
||||
|
||||
AZ::SliceComponent::SliceList& slicesUnderRootSlice = GetRootSliceAsset()->GetComponent()->GetSlices();
|
||||
ASSERT_EQ(slicesUnderRootSlice.size(), 1);
|
||||
|
||||
// Verify that the created slice has the same asset as the one it's provided to be created with.
|
||||
EXPECT_EQ(sliceAsset, slicesUnderRootSlice.front().GetSliceAsset());
|
||||
}
|
||||
|
||||
TEST_F(SliceEditorEntityOwnershipTests, PromoteEditorEntitiesIntoSlice_ValidEntitiesProvided_SliceCreated)
|
||||
{
|
||||
AZ::Entity* looseEntity = aznew AZ::Entity("testEntity");
|
||||
m_sliceEditorEntityOwnershipService->AddEntity(looseEntity);
|
||||
|
||||
AZ::Entity* entityInSlice = aznew AZ::Entity("testEntity");
|
||||
AZ::Data::Asset<AZ::SliceAsset> sliceAsset;
|
||||
sliceAsset.Create(AZ::Data::AssetId(AZ::Uuid::CreateRandom()), false);
|
||||
AddSliceComponentToAsset(sliceAsset, EntityList{ entityInSlice });
|
||||
|
||||
AZ::SliceComponent::EntityIdToEntityIdMap looseEntityIdToSliceAssetEntityIdMap;
|
||||
looseEntityIdToSliceAssetEntityIdMap.emplace(looseEntity->GetId(), entityInSlice->GetId());
|
||||
|
||||
// Verify that no slices exist.
|
||||
AZ::SliceComponent::SliceList& slicesUnderRootSlice = GetRootSliceAsset()->GetComponent()->GetSlices();
|
||||
ASSERT_EQ(slicesUnderRootSlice.size(), 0);
|
||||
|
||||
AzToolsFramework::SliceEditorEntityOwnershipServiceRequestBus::Broadcast(
|
||||
&AzToolsFramework::SliceEditorEntityOwnershipServiceRequestBus::Events::PromoteEditorEntitiesIntoSlice,
|
||||
sliceAsset, looseEntityIdToSliceAssetEntityIdMap);
|
||||
// Verify that one slice is created.
|
||||
slicesUnderRootSlice = GetRootSliceAsset()->GetComponent()->GetSlices();
|
||||
ASSERT_EQ(slicesUnderRootSlice.size(), 1);
|
||||
|
||||
AZ::SliceComponent::SliceReference& sliceReference = slicesUnderRootSlice.front();
|
||||
|
||||
// Verify that there exists one slice instance with one entity and the correct slice asset.
|
||||
ASSERT_EQ(sliceAsset, sliceReference.GetSliceAsset());
|
||||
ASSERT_EQ(sliceReference.GetInstances().size(), 1);
|
||||
AzFramework::EntityList entitiesOfSlice = sliceReference.GetInstances().begin()->GetInstantiated()->m_entities;
|
||||
ASSERT_EQ(entitiesOfSlice.size(), 1);
|
||||
|
||||
// Verify that the entity in the created slice has the same id of the provided test entity.
|
||||
EXPECT_EQ(entitiesOfSlice[0]->GetId(), looseEntity->GetId());
|
||||
}
|
||||
|
||||
TEST_F(SliceEditorEntityOwnershipTests, DetachSliceEntities_ValidEntitiesProvided_EntitiesDetached)
|
||||
{
|
||||
AZ::Data::Asset<AZ::SliceAsset> sliceAsset;
|
||||
sliceAsset.Create(AZ::Data::AssetId(AZ::Uuid::CreateRandom()), false);
|
||||
AZ::Entity* entityInSlice = aznew AZ::Entity("testEntity");
|
||||
AddEditorSlice(sliceAsset, AZ::Transform::CreateIdentity(), EntityList{ entityInSlice });
|
||||
|
||||
// Verify that one slice is created and it has one editor entity
|
||||
AZ::SliceComponent::SliceList& slicesUnderRootSlice = GetRootSliceAsset()->GetComponent()->GetSlices();
|
||||
ASSERT_EQ(slicesUnderRootSlice.size(), 1);
|
||||
AZ::SliceComponent::SliceReference& sliceReference = slicesUnderRootSlice.front();
|
||||
AzFramework::EntityList entitiesOfSlice = sliceReference.GetInstances().begin()->GetInstantiated()->m_entities;
|
||||
ASSERT_EQ(entitiesOfSlice.size(), 1);
|
||||
|
||||
// Verify that owning slice for the editor entity exists.
|
||||
AZ::SliceComponent::SliceInstanceAddress sliceInstanceAddressBeforeDetach;
|
||||
AzFramework::SliceEntityRequestBus::EventResult(sliceInstanceAddressBeforeDetach, entitiesOfSlice[0]->GetId(),
|
||||
&AzFramework::SliceEntityRequestBus::Events::GetOwningSlice);
|
||||
EXPECT_TRUE(sliceInstanceAddressBeforeDetach.IsValid());
|
||||
|
||||
AzToolsFramework::SliceEditorEntityOwnershipServiceRequestBus::Broadcast(
|
||||
&AzToolsFramework::SliceEditorEntityOwnershipServiceRequestBus::Events::DetachSliceEntities,
|
||||
AzToolsFramework::EntityIdList{ entitiesOfSlice[0]->GetId() });
|
||||
|
||||
// Verify that owning slice for the editor entity doesn't exist.
|
||||
AZ::SliceComponent::SliceInstanceAddress sliceInstanceAddressAfterDetach;
|
||||
AzFramework::SliceEntityRequestBus::EventResult(sliceInstanceAddressAfterDetach, entitiesOfSlice[0]->GetId(),
|
||||
&AzFramework::SliceEntityRequestBus::Events::GetOwningSlice);
|
||||
EXPECT_FALSE(sliceInstanceAddressAfterDetach.IsValid());
|
||||
}
|
||||
|
||||
TEST_F(SliceEditorEntityOwnershipTests, DetachSliceInstances_ValidInstanceProvided_InstanceDetached)
|
||||
{
|
||||
AZ::Data::Asset<AZ::SliceAsset> sliceAsset;
|
||||
sliceAsset.Create(AZ::Data::AssetId(AZ::Uuid::CreateRandom()), false);
|
||||
AZ::Entity* testEntity = aznew AZ::Entity("testEntity");
|
||||
AddEditorSlice(sliceAsset, AZ::Transform::CreateIdentity(), EntityList{ testEntity });
|
||||
|
||||
// Verify that one slice exists before detaching it.
|
||||
AZ::SliceComponent::SliceList& slicesUnderRootSlice = GetRootSliceAsset()->GetComponent()->GetSlices();
|
||||
ASSERT_EQ(slicesUnderRootSlice.front().GetInstances().size(), 1);
|
||||
|
||||
// Verify that there are no loose entities in the editor.
|
||||
EntityList looseEntitiesBeforeDetach;
|
||||
m_sliceEditorEntityOwnershipService->GetNonPrefabEntities(looseEntitiesBeforeDetach);
|
||||
EXPECT_TRUE(looseEntitiesBeforeDetach.size() == 0);
|
||||
|
||||
AZ::SliceComponent::SliceReference& sliceReference = slicesUnderRootSlice.front();
|
||||
auto sliceInstanceIterator = sliceReference.GetInstances().begin();
|
||||
AZ::SliceComponent::SliceInstanceAddress sliceInstanceAddress(&sliceReference, &(*sliceInstanceIterator));
|
||||
|
||||
// Verify that there is one entity in the slice that is about to be detached.
|
||||
EntityList entitiesInsliceBeforeDetach = sliceInstanceIterator->GetInstantiated()->m_entities;
|
||||
EXPECT_TRUE(entitiesInsliceBeforeDetach.size() == 1);
|
||||
|
||||
AzToolsFramework::SliceEditorEntityOwnershipServiceRequestBus::Broadcast(
|
||||
&AzToolsFramework::SliceEditorEntityOwnershipServiceRequestBus::Events::DetachSliceInstances,
|
||||
AZ::SliceComponent::SliceInstanceAddressSet{ sliceInstanceAddress });
|
||||
|
||||
// Verify that the only slice that existed is not there anymore after detaching it.
|
||||
slicesUnderRootSlice = GetRootSliceAsset()->GetComponent()->GetSlices();
|
||||
EXPECT_EQ(slicesUnderRootSlice.front().GetInstances().size(), 0);
|
||||
|
||||
// Verify that that the detached slice entity is now a loose entity in the editor.
|
||||
EntityList looseEntitiesAfterDetach;
|
||||
m_sliceEditorEntityOwnershipService->GetNonPrefabEntities(looseEntitiesAfterDetach);
|
||||
EXPECT_TRUE(looseEntitiesAfterDetach.size() == 1);
|
||||
EXPECT_EQ(entitiesInsliceBeforeDetach[0]->GetId(), looseEntitiesAfterDetach[0]->GetId());
|
||||
}
|
||||
|
||||
TEST_F(SliceEditorEntityOwnershipTests, RestoreSliceEntity_SliceEntityDeleted_SliceEntityRestored)
|
||||
{
|
||||
AZ::Data::Asset<AZ::SliceAsset> sliceAsset;
|
||||
sliceAsset.Create(AZ::Data::AssetId(AZ::Uuid::CreateRandom()), false);
|
||||
AZ::Entity* testEntity = aznew AZ::Entity("testEntity");
|
||||
AddEditorSlice(sliceAsset, AZ::Transform::CreateIdentity(), EntityList{ testEntity });
|
||||
|
||||
// Verify that one slice exists
|
||||
AZ::SliceComponent::SliceList& slicesUnderRootSlice = GetRootSliceAsset()->GetComponent()->GetSlices();
|
||||
ASSERT_EQ(slicesUnderRootSlice.front().GetInstances().size(), 1);
|
||||
|
||||
AZ::SliceComponent::SliceReference& sliceReference = slicesUnderRootSlice.front();
|
||||
|
||||
// Verify that one entity exists in the slice
|
||||
EntityList entitiesOfSlice = sliceReference.GetInstances().begin()->GetInstantiated()->m_entities;
|
||||
ASSERT_EQ(entitiesOfSlice.size(), 1);
|
||||
|
||||
// Get the slice entity ancestor and slice instance id before destroying the entity of the slice
|
||||
AZ::SliceComponent::EntityAncestorList entityAncestorList;
|
||||
sliceReference.GetInstanceEntityAncestry(entitiesOfSlice.front()->GetId(), entityAncestorList);
|
||||
AZ::SliceComponent::SliceInstanceId sliceInstanceId = sliceReference.GetInstances().begin()->GetId();
|
||||
|
||||
m_sliceEditorEntityOwnershipService->DestroyEntityById(entitiesOfSlice.front()->GetId());
|
||||
|
||||
// Verify that no slices exists after slice entity is destroyed.
|
||||
ASSERT_EQ(slicesUnderRootSlice.size(), 0);
|
||||
|
||||
// Restore the slice entity
|
||||
AZ::SliceComponent::EntityRestoreInfo entityRestoreInfo = AZ::SliceComponent::EntityRestoreInfo(sliceAsset,
|
||||
sliceInstanceId, entityAncestorList.front().m_entity->GetId(), AZ::DataPatch::FlagsMap{});
|
||||
AzToolsFramework::SliceEditorEntityOwnershipServiceRequestBus::Broadcast(
|
||||
&AzToolsFramework::SliceEditorEntityOwnershipServiceRequestBus::Events::RestoreSliceEntity, entitiesOfSlice.front(),
|
||||
entityRestoreInfo, AzToolsFramework::SliceEntityRestoreType::Deleted);
|
||||
AZ::TickBus::ExecuteQueuedEvents();
|
||||
|
||||
// Verify that slice is restored with the same entity it had before.
|
||||
ASSERT_EQ(slicesUnderRootSlice.size(), 1);
|
||||
EntityList entitiesOfSliceAfterRestore = sliceReference.GetInstances().begin()->GetInstantiated()->m_entities;
|
||||
ASSERT_EQ(entitiesOfSliceAfterRestore.size(), 1);
|
||||
EXPECT_EQ(entitiesOfSliceAfterRestore.front()->GetId(), entitiesOfSlice.front()->GetId());
|
||||
}
|
||||
}
|
||||
+406
@@ -0,0 +1,406 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzFramework/Entity/SliceEntityOwnershipService.h>
|
||||
#include "EntityOwnershipServiceTestFixture.h"
|
||||
#include <AzToolsFramework/Slice/SliceMetadataEntityContextBus.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
class SliceEntityOwnershipTests
|
||||
: public EntityOwnershipServiceTestFixture
|
||||
{
|
||||
public:
|
||||
void SetUp() override
|
||||
{
|
||||
SetUpEntityOwnershipServiceTest();
|
||||
m_sliceEntityOwnershipService = AZStd::make_unique<AzFramework::SliceEntityOwnershipService>(AZ::Uuid::CreateNull(),
|
||||
m_app->GetSerializeContext());
|
||||
m_sliceEntityOwnershipService->Initialize();
|
||||
m_sliceEntityOwnershipService->SetEntitiesAddedCallback([this](const AzFramework::EntityList& entityList)
|
||||
{
|
||||
this->HandleEntitiesAdded(entityList);
|
||||
});
|
||||
|
||||
m_sliceEntityOwnershipService->SetEntitiesRemovedCallback([this](const AzFramework::EntityIdList& entityIds)
|
||||
{
|
||||
this->HandleEntitiesRemoved(entityIds);
|
||||
});
|
||||
|
||||
m_sliceEntityOwnershipService->SetValidateEntitiesCallback([this](const AzFramework::EntityList& entityList)
|
||||
{
|
||||
return this->ValidateEntities(entityList);
|
||||
});
|
||||
}
|
||||
void TearDown() override
|
||||
{
|
||||
m_sliceEntityOwnershipService->SetEntitiesAddedCallback(nullptr);
|
||||
|
||||
// In order for the death tests to work, we have to destroy the EOS early. So, don't try to destroy again.
|
||||
if (m_sliceEntityOwnershipService->IsInitialized())
|
||||
{
|
||||
m_sliceEntityOwnershipService->Destroy();
|
||||
}
|
||||
|
||||
m_sliceEntityOwnershipService.reset();
|
||||
|
||||
TearDownEntityOwnershipServiceTest();
|
||||
}
|
||||
protected:
|
||||
AZStd::unique_ptr<AzFramework::SliceEntityOwnershipService> m_sliceEntityOwnershipService;
|
||||
};
|
||||
|
||||
using SliceEntityOwnershipDeathTests = SliceEntityOwnershipTests;
|
||||
|
||||
TEST_F(SliceEntityOwnershipTests, AddEntity_InitalizedCorrectly_EntityCreated)
|
||||
{
|
||||
AZ::Entity* testEntity = aznew AZ::Entity("testEntity");
|
||||
m_sliceEntityOwnershipService->AddEntity(testEntity);
|
||||
|
||||
// Validate that entities-added callback is triggerted.
|
||||
EXPECT_TRUE(m_entitiesAddedCallbackTriggered);
|
||||
|
||||
const AzFramework::EntityList& entitiesUnderRootSlice = GetRootSliceAsset()->GetComponent()->GetNewEntities();
|
||||
|
||||
// Validate that there is only one entity under root slice.
|
||||
EXPECT_EQ(entitiesUnderRootSlice.size(), 1);
|
||||
|
||||
EXPECT_EQ(entitiesUnderRootSlice.at(0)->GetName(), "testEntity");
|
||||
}
|
||||
|
||||
TEST_F(SliceEntityOwnershipTests, DestroyEntityById_EntityAdded_EntityDestroyed)
|
||||
{
|
||||
AZ::Entity* testEntity = aznew AZ::Entity("testEntity");
|
||||
m_sliceEntityOwnershipService->AddEntity(testEntity);
|
||||
|
||||
AzFramework::EntityList entitiesUnderRootSlice = GetRootSliceAsset()->GetComponent()->GetNewEntities();
|
||||
|
||||
// Verify that entity is added
|
||||
EXPECT_EQ(entitiesUnderRootSlice.size(), 1);
|
||||
|
||||
EXPECT_TRUE(m_sliceEntityOwnershipService->DestroyEntityById(testEntity->GetId()));
|
||||
|
||||
entitiesUnderRootSlice = GetRootSliceAsset()->GetComponent()->GetNewEntities();
|
||||
|
||||
// Verify that entity is destroyed
|
||||
EXPECT_EQ(entitiesUnderRootSlice.size(), 0);
|
||||
}
|
||||
|
||||
TEST_F(SliceEntityOwnershipTests, GetRootSlice_RootAssetAbsent_ReturnNull)
|
||||
{
|
||||
m_sliceEntityOwnershipService->Destroy();
|
||||
AZ::SliceComponent* rootSlice = nullptr;
|
||||
AzFramework::SliceEntityOwnershipServiceRequestBus::BroadcastResult(rootSlice,
|
||||
&AzFramework::SliceEntityOwnershipServiceRequestBus::Events::GetRootSlice);
|
||||
EXPECT_EQ(rootSlice, nullptr);
|
||||
}
|
||||
|
||||
TEST_F(SliceEntityOwnershipTests, GetRootSlice_RootAssetPresent_ReturnRootSlice)
|
||||
{
|
||||
AZ::SliceComponent* rootSlice = nullptr;
|
||||
AzFramework::SliceEntityOwnershipServiceRequestBus::BroadcastResult(rootSlice,
|
||||
&AzFramework::SliceEntityOwnershipServiceRequestBus::Events::GetRootSlice);
|
||||
EXPECT_NE(rootSlice, nullptr);
|
||||
}
|
||||
|
||||
TEST_F(SliceEntityOwnershipTests, Reset_SliceAdded_DestroySliceEntities)
|
||||
{
|
||||
AzFramework::EntityList entitiesToAdd = AzFramework::EntityList{ aznew AZ::Entity() };
|
||||
AddSlice(entitiesToAdd);
|
||||
|
||||
size_t slicesCountBeforeReset = GetRootSliceAsset()->GetComponent()->GetSlices().size();
|
||||
|
||||
// Verify that slice exists
|
||||
EXPECT_EQ(slicesCountBeforeReset, 1);
|
||||
|
||||
m_sliceEntityOwnershipService->Reset();
|
||||
|
||||
size_t slicesCountAfterReset = GetRootSliceAsset()->GetComponent()->GetSlices().size();
|
||||
|
||||
// Verify that slices under rootSlice were removed after reset of EntityOwnershipService.
|
||||
EXPECT_EQ(slicesCountAfterReset, 0);
|
||||
|
||||
// Verify that call to destroy entities in the added slice occured.
|
||||
EXPECT_TRUE(m_entityRemovedCallbackTriggered);
|
||||
}
|
||||
|
||||
TEST_F(SliceEntityOwnershipTests, Reset_SliceInstantiationStarted_StopSliceInstantiation)
|
||||
{
|
||||
AddSlice(AzFramework::EntityList{}, true);
|
||||
m_sliceEntityOwnershipService->Reset();
|
||||
AZ::TickBus::ExecuteQueuedEvents();
|
||||
|
||||
size_t slicesCountUnderRootSlice = GetRootSliceAsset()->GetComponent()->GetSlices().size();
|
||||
EXPECT_EQ(slicesCountUnderRootSlice, 0);
|
||||
}
|
||||
|
||||
TEST_F(SliceEntityOwnershipTests, Reset_EntityAdded_EntityDestroyedAfterReset)
|
||||
{
|
||||
AZ::Entity* testEntity = aznew AZ::Entity("testEntity");
|
||||
m_sliceEntityOwnershipService->AddEntity(testEntity);
|
||||
|
||||
m_sliceEntityOwnershipService->Reset();
|
||||
|
||||
const AzFramework::EntityList& entitiesUnderRootSlice = GetRootSliceAsset()->GetComponent()->GetNewEntities();
|
||||
|
||||
EXPECT_EQ(entitiesUnderRootSlice.size(), 0);
|
||||
EXPECT_TRUE(m_entityRemovedCallbackTriggered);
|
||||
}
|
||||
|
||||
TEST_F(SliceEntityOwnershipTests, HandleRootEntityReloadedFromStream_NoRootEntity_FailToLoadEntity)
|
||||
{
|
||||
bool rootEntityLoadSuccessful = false;
|
||||
AzFramework::SliceEntityOwnershipServiceRequestBus::BroadcastResult(rootEntityLoadSuccessful,
|
||||
&AzFramework::SliceEntityOwnershipServiceRequestBus::Events::HandleRootEntityReloadedFromStream, nullptr, false, nullptr);
|
||||
EXPECT_FALSE(rootEntityLoadSuccessful);
|
||||
}
|
||||
|
||||
TEST_F(SliceEntityOwnershipTests, HandleRootEntityReloadedFromStream_NoSliceComponent_FailToLoadEntity)
|
||||
{
|
||||
AZ::Entity* testEntity = aznew AZ::Entity();
|
||||
|
||||
// Suppress the AZ_Error thrown for not creating the root slice.
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
bool rootEntityLoadSuccessful = false;
|
||||
AzFramework::SliceEntityOwnershipServiceRequestBus::BroadcastResult(rootEntityLoadSuccessful,
|
||||
&AzFramework::SliceEntityOwnershipServiceRequestBus::Events::HandleRootEntityReloadedFromStream, testEntity, false, nullptr);
|
||||
EXPECT_FALSE(rootEntityLoadSuccessful);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
delete testEntity;
|
||||
}
|
||||
|
||||
TEST_F(SliceEntityOwnershipTests, HandleRootEntityReloadedFromStream_RemapIdsTrue_IdsRemapped)
|
||||
{
|
||||
AZ::Entity* rootEntity = aznew AZ::Entity();
|
||||
AZ::SliceComponent* rootSliceComponent = rootEntity->CreateComponent<AZ::SliceComponent>();
|
||||
AZ::Entity* testEntity = aznew AZ::Entity();
|
||||
rootSliceComponent->AddEntity(testEntity);
|
||||
|
||||
AZ::SliceComponent::EntityIdToEntityIdMap previousToNewIdMap;
|
||||
previousToNewIdMap.emplace(testEntity->GetId(), testEntity->GetId());
|
||||
|
||||
bool rootEntityLoadSuccessful = false;
|
||||
AzFramework::SliceEntityOwnershipServiceRequestBus::BroadcastResult(rootEntityLoadSuccessful,
|
||||
&AzFramework::SliceEntityOwnershipServiceRequestBus::Events::HandleRootEntityReloadedFromStream,
|
||||
rootEntity, true, &previousToNewIdMap);
|
||||
|
||||
EXPECT_TRUE(rootEntityLoadSuccessful);
|
||||
|
||||
// Verify that remapping of entityIds is done by comparing the entityIds in previousToNewIdMap
|
||||
EXPECT_TRUE(previousToNewIdMap.begin()->first != previousToNewIdMap.begin()->second);
|
||||
}
|
||||
|
||||
TEST_F(SliceEntityOwnershipTests, FindLoadedEntityIdMapping_IdsNotRemapped_EntityIdPresent)
|
||||
{
|
||||
AZ::Entity* rootEntity = aznew AZ::Entity();
|
||||
AZ::SliceComponent* rootSliceComponent = rootEntity->CreateComponent<AZ::SliceComponent>();
|
||||
AZ::Entity* testEntity = aznew AZ::Entity();
|
||||
rootSliceComponent->AddEntity(testEntity);
|
||||
|
||||
bool rootEntityLoadSuccessful = false;
|
||||
AzFramework::SliceEntityOwnershipServiceRequestBus::BroadcastResult(rootEntityLoadSuccessful,
|
||||
&AzFramework::SliceEntityOwnershipServiceRequestBus::Events::HandleRootEntityReloadedFromStream, rootEntity, false, nullptr);
|
||||
EXPECT_TRUE(rootEntityLoadSuccessful);
|
||||
|
||||
AZ::EntityId loadedEntityId;
|
||||
AzFramework::SliceEntityOwnershipServiceRequestBus::BroadcastResult(loadedEntityId,
|
||||
&AzFramework::SliceEntityOwnershipServiceRequestBus::Events::FindLoadedEntityIdMapping, testEntity->GetId());
|
||||
|
||||
// Verify that the entityId in the loadedEntityIdMap is same as the provided entityId, which happens when remapping is not done.
|
||||
EXPECT_TRUE(loadedEntityId == testEntity->GetId());
|
||||
}
|
||||
|
||||
TEST_F(SliceEntityOwnershipTests, FindLoadedEntityIdMapping_IdsRemapped_EntityIdAbsent)
|
||||
{
|
||||
AZ::Entity* rootEntity = aznew AZ::Entity();
|
||||
AZ::SliceComponent* rootSliceComponent = rootEntity->CreateComponent<AZ::SliceComponent>();
|
||||
AZ::Entity* testEntity = aznew AZ::Entity();
|
||||
rootSliceComponent->AddEntity(testEntity);
|
||||
|
||||
AZ::SliceComponent::EntityIdToEntityIdMap previousToNewIdMap;
|
||||
previousToNewIdMap.emplace(testEntity->GetId(), testEntity->GetId());
|
||||
bool rootEntityLoadSuccessful = false;
|
||||
AzFramework::SliceEntityOwnershipServiceRequestBus::BroadcastResult(rootEntityLoadSuccessful,
|
||||
&AzFramework::SliceEntityOwnershipServiceRequestBus::Events::HandleRootEntityReloadedFromStream,
|
||||
rootEntity, true, &previousToNewIdMap);
|
||||
EXPECT_TRUE(rootEntityLoadSuccessful);
|
||||
|
||||
AZ::EntityId loadedEntityId;
|
||||
AzFramework::SliceEntityOwnershipServiceRequestBus::BroadcastResult(loadedEntityId,
|
||||
&AzFramework::SliceEntityOwnershipServiceRequestBus::Events::FindLoadedEntityIdMapping, testEntity->GetId());
|
||||
|
||||
// Verify that entityId is not present in the loadedEntityIdMap when remapping is done.
|
||||
EXPECT_FALSE(loadedEntityId.IsValid());
|
||||
}
|
||||
|
||||
TEST_F(SliceEntityOwnershipTests, OnAssetReady_RootSliceAssetReady_DoNotInstantiate)
|
||||
{
|
||||
m_sliceEntityOwnershipService->OnAssetReady(GetRootSliceAsset());
|
||||
|
||||
// Verify that validate entities callback is not triggered,
|
||||
// which will only happen when an attempt to instantiate slice didn't occur.
|
||||
EXPECT_FALSE(m_validateEntitiesCallbackTriggered);
|
||||
}
|
||||
|
||||
TEST_F(SliceEntityOwnershipTests, OnAssetError_RootSliceAssetError_DoNotClearOtherSliceInstantiations)
|
||||
{
|
||||
AddSlice(AzFramework::EntityList{}, true);
|
||||
m_sliceEntityOwnershipService->OnAssetError(GetRootSliceAsset());
|
||||
|
||||
// Try to finish any queued slice instantiations
|
||||
AZ::TickBus::ExecuteQueuedEvents();
|
||||
|
||||
// Verify that slice instantiation was successful.
|
||||
size_t slicesCountUnderRootSlice = GetRootSliceAsset()->GetComponent()->GetSlices().size();
|
||||
EXPECT_EQ(slicesCountUnderRootSlice, 1);
|
||||
}
|
||||
|
||||
TEST_F(SliceEntityOwnershipTests, OnAssetError_InstantiatingAssetError_StopSliceInstantiation)
|
||||
{
|
||||
AZ::Data::Asset<AZ::SliceAsset> sliceAsset1;
|
||||
AZ::Data::AssetId sliceAsset1Id = AZ::Data::AssetId(AZ::Uuid::CreateRandom());
|
||||
sliceAsset1.Create(sliceAsset1Id, false);
|
||||
AddSlice(AzFramework::EntityList{}, true, sliceAsset1);
|
||||
|
||||
AZ::Data::Asset<AZ::SliceAsset> sliceAsset2;
|
||||
sliceAsset2.Create(AZ::Data::AssetId(AZ::Uuid::CreateRandom()), false);
|
||||
AddSlice(AzFramework::EntityList{}, true, sliceAsset2);
|
||||
|
||||
m_sliceEntityOwnershipService->OnAssetError(sliceAsset2);
|
||||
|
||||
// Try to finish any queued slice instantiations
|
||||
AZ::TickBus::ExecuteQueuedEvents();
|
||||
|
||||
AZ::SliceComponent::SliceList& slicesUnderRootSlice = GetRootSliceAsset()->GetComponent()->GetSlices();
|
||||
|
||||
// Verify that there is only one slice under root slice
|
||||
EXPECT_EQ(slicesUnderRootSlice.size(), 1);
|
||||
|
||||
// Verify that the slice without the asset error was instantiated
|
||||
EXPECT_EQ(slicesUnderRootSlice.front().GetSliceAsset().GetId(), sliceAsset1Id);
|
||||
}
|
||||
|
||||
TEST_F(SliceEntityOwnershipTests, InstantiateSlice_InvalidAssetId_ReturnBlankInstantiationTicket)
|
||||
{
|
||||
AZ::Entity* sliceEntity = aznew AZ::Entity();
|
||||
AZ::SliceComponent* sliceComponent = sliceEntity->CreateComponent<AZ::SliceComponent>();
|
||||
sliceComponent->SetSerializeContext(m_app->GetSerializeContext());
|
||||
sliceComponent->AddEntity(aznew AZ::Entity());
|
||||
|
||||
// Set the asset id to null to invalidate it.
|
||||
AZ::Data::Asset<AZ::SliceAsset> sliceAssetHolder = AZ::Data::AssetManager::Instance().
|
||||
CreateAsset<AZ::SliceAsset>(AZ::Data::AssetId(AZ::Uuid::CreateNull()));
|
||||
sliceAssetHolder.Get()->SetData(sliceEntity, sliceComponent);
|
||||
|
||||
AzFramework::SliceInstantiationTicket sliceInstantiationTicket;
|
||||
AzFramework::SliceEntityOwnershipServiceRequestBus::BroadcastResult(sliceInstantiationTicket,
|
||||
&AzFramework::SliceEntityOwnershipServiceRequestBus::Events::InstantiateSlice, sliceAssetHolder, nullptr, nullptr);
|
||||
AZ::TickBus::ExecuteQueuedEvents();
|
||||
|
||||
// Verify that there is no request id or context id associated with the sliceInstantiationTicket
|
||||
EXPECT_EQ(sliceInstantiationTicket.GetContextId(), AZ::Uuid::CreateNull());
|
||||
EXPECT_EQ(sliceInstantiationTicket.GetRequestId(), 0);
|
||||
}
|
||||
|
||||
TEST_F(SliceEntityOwnershipTests, InstantiateSlice_InstantiateTwoSlices_SlicesInstantiated)
|
||||
{
|
||||
// Add 2 slices asynchronously
|
||||
AddSlice(AzFramework::EntityList{}, true);
|
||||
AddSlice(AzFramework::EntityList{}, true);
|
||||
AZ::TickBus::ExecuteQueuedEvents();
|
||||
size_t slicesCountUnderRootSlice = GetRootSliceAsset()->GetComponent()->GetSlices().size();
|
||||
EXPECT_EQ(slicesCountUnderRootSlice, 2);
|
||||
}
|
||||
|
||||
TEST_F(SliceEntityOwnershipTests, CloneSliceInstance_InstantiateSlice_SliceCloned)
|
||||
{
|
||||
AZ::Entity* testEntity = aznew AZ::Entity("testEntity");
|
||||
AddSlice(AzFramework::EntityList{ testEntity });
|
||||
|
||||
AZ::SliceComponent::EntityIdSet entityIdsInSlice;
|
||||
GetRootSliceAsset()->GetComponent()->GetEntityIds(entityIdsInSlice);
|
||||
|
||||
AZ::SliceComponent* rootSlice = nullptr;
|
||||
AzFramework::SliceEntityOwnershipServiceRequestBus::BroadcastResult(rootSlice,
|
||||
&AzFramework::SliceEntityOwnershipServiceRequestBus::Events::GetRootSlice);
|
||||
AZ::SliceComponent::SliceInstanceAddress sourceSliceInstanceAddress = rootSlice->FindSlice(*entityIdsInSlice.begin());
|
||||
AZ::SliceComponent::EntityIdToEntityIdMap entityIdToEntityIdMap;
|
||||
AZ::SliceComponent::SliceInstanceAddress clonedSliceInstanceAddress;
|
||||
AzFramework::SliceEntityOwnershipServiceRequestBus::BroadcastResult(clonedSliceInstanceAddress,
|
||||
&AzFramework::SliceEntityOwnershipServiceRequests::CloneSliceInstance, sourceSliceInstanceAddress, entityIdToEntityIdMap);
|
||||
|
||||
// Verify that the entity was cloned successfully with the slice
|
||||
EXPECT_EQ(clonedSliceInstanceAddress.GetInstance()->GetInstantiated()->m_entities.front()->GetName(), "testEntity");
|
||||
|
||||
// Verify that the source slice and the cloned slice have the same reference.
|
||||
EXPECT_EQ(sourceSliceInstanceAddress.GetReference(), clonedSliceInstanceAddress.GetReference());
|
||||
}
|
||||
|
||||
TEST_F(SliceEntityOwnershipTests, InstantiateSlice_EntitiesInvalid_SliceInstantiationFailed)
|
||||
{
|
||||
m_areEntitiesValidForContext = false;
|
||||
AddSlice(AzFramework::EntityList{});
|
||||
|
||||
size_t slicesCountUnderRootSlice = GetRootSliceAsset()->GetComponent()->GetSlices().size();
|
||||
|
||||
// If entities are invalid, then slice instantiation would fail
|
||||
EXPECT_EQ(slicesCountUnderRootSlice, 0);
|
||||
}
|
||||
|
||||
TEST_F(SliceEntityOwnershipTests, CancelSliceInstantiation_SetupCorrect_SliceInstantiationCanceled)
|
||||
{
|
||||
AzFramework::SliceInstantiationTicket sliceInstantiationTicket = AddSlice(AzFramework::EntityList{}, true);
|
||||
|
||||
AzFramework::SliceEntityOwnershipServiceRequestBus::Broadcast(
|
||||
&AzFramework::SliceEntityOwnershipServiceRequestBus::Events::CancelSliceInstantiation, sliceInstantiationTicket);
|
||||
|
||||
// This will try to finish any queued slice instantiations.
|
||||
AZ::TickBus::ExecuteQueuedEvents();
|
||||
|
||||
size_t slicesCountUnderRootSlice = GetRootSliceAsset()->GetComponent()->GetSlices().size();
|
||||
EXPECT_EQ(slicesCountUnderRootSlice, 0);
|
||||
}
|
||||
|
||||
TEST_F(SliceEntityOwnershipTests, GetOwningSlice_SliceAdded_OwningSliceFetchedCorrectly)
|
||||
{
|
||||
AZ::SliceComponent::SliceList& slicesUnderRootSlice = GetRootSliceAsset()->GetComponent()->GetSlices();
|
||||
AddSlice(AzFramework::EntityList{ aznew AZ::Entity() });
|
||||
ASSERT_EQ(slicesUnderRootSlice.size(), 1);
|
||||
AZ::SliceComponent::SliceReference& sliceReference = slicesUnderRootSlice.front();
|
||||
ASSERT_EQ(sliceReference.GetInstances().size(), 1);
|
||||
AzFramework::EntityList entitiesOfSlice = sliceReference.GetInstances().begin()->GetInstantiated()->m_entities;
|
||||
ASSERT_EQ(entitiesOfSlice.size(), 1);
|
||||
AZ::SliceComponent::SliceInstanceAddress sliceInstanceAddress;
|
||||
AzFramework::SliceEntityRequestBus::EventResult(sliceInstanceAddress, entitiesOfSlice.front()->GetId(),
|
||||
&AzFramework::SliceEntityRequestBus::Events::GetOwningSlice);
|
||||
|
||||
// Verify that the source slice and the cloned slice have the same slice asset.
|
||||
EXPECT_EQ(sliceInstanceAddress.GetReference()->GetSliceAsset(), sliceReference.GetSliceAsset());
|
||||
}
|
||||
|
||||
TEST_F(SliceEntityOwnershipTests, GetOwningSlice_LooseEntityAdded_EntityHasNoOwningSlice)
|
||||
{
|
||||
AZ::Entity* testEntity = aznew AZ::Entity();
|
||||
m_sliceEntityOwnershipService->AddEntity(testEntity);
|
||||
AZ::SliceComponent::SliceInstanceAddress sliceInstanceAddress;
|
||||
AzFramework::SliceEntityRequestBus::EventResult(sliceInstanceAddress, testEntity->GetId(),
|
||||
&AzFramework::SliceEntityRequestBus::Events::GetOwningSlice);
|
||||
|
||||
// Verify that the loose entity doesn't belong to a slice instance
|
||||
EXPECT_FALSE(sliceInstanceAddress.IsValid());
|
||||
}
|
||||
|
||||
TEST_F(SliceEntityOwnershipDeathTests, AddEntity_RootSliceAssetAbsent_EntityNotCreated)
|
||||
{
|
||||
m_sliceEntityOwnershipService->Destroy();
|
||||
AZ::Entity testEntity = AZ::Entity("testEntity");
|
||||
EXPECT_DEATH(
|
||||
{
|
||||
m_sliceEntityOwnershipService->AddEntity(&testEntity);
|
||||
}, ".*");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Memory/AllocationRecords.h>
|
||||
#include <AzCore/Memory/MemoryComponent.h>
|
||||
#include <AzCore/IO/Streamer/StreamerComponent.h>
|
||||
#include <AzCore/Asset/AssetManagerComponent.h>
|
||||
#include <AzCore/Serialization/Utils.h>
|
||||
#include <AzCore/Component/EntityUtils.h>
|
||||
#include <AzCore/PlatformIncl.h>
|
||||
#include <AzFramework/Entity/EntityContextBus.h>
|
||||
#include <AzFramework/Entity/EntityContext.h>
|
||||
#include <AzFramework/IO/LocalFileIO.h>
|
||||
#include <AzFramework/Application/Application.h>
|
||||
#include <AzFramework/Asset/AssetCatalogComponent.h>
|
||||
#include <AzFramework/Asset/AssetCatalogBus.h>
|
||||
//#include <AzToolsFramework/UI/Outliner/OutlinerWidget.hxx>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/PropertyManagerComponent.h>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx>
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Entity/SliceEditorEntityOwnershipServiceBus.h>
|
||||
#include <AzToolsFramework/Application/ToolsApplication.h>
|
||||
#include <QtWidgets/QMainWindow>
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QtWidgets/QVBoxLayout>
|
||||
#include <QtWidgets/QPushButton>
|
||||
#include <QtWidgets/QFileDialog>
|
||||
#include <QtCore/QTimer>
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
using namespace AZ;
|
||||
|
||||
class EntityTestbed
|
||||
: public AllocatorsFixture
|
||||
, public QObject
|
||||
{
|
||||
public:
|
||||
|
||||
class TestbedApplication
|
||||
: public AzToolsFramework::ToolsApplication
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(TestbedApplication, AZ::SystemAllocator, 0);
|
||||
|
||||
TestbedApplication(EntityTestbed& testbed)
|
||||
: m_testbed(testbed) {}
|
||||
|
||||
EntityTestbed& m_testbed;
|
||||
};
|
||||
|
||||
QTimer* m_tickBusTimer = nullptr;
|
||||
TestbedApplication* m_componentApplication = nullptr;
|
||||
AZ::Entity* m_systemEntity = nullptr;
|
||||
QApplication* m_qtApplication = nullptr;
|
||||
QWidget* m_window = nullptr;
|
||||
//AzToolsFramework::OutlinerWidget* m_outliner = nullptr;
|
||||
AzToolsFramework::EntityPropertyEditor* m_propertyEditor = nullptr;
|
||||
AZ::u32 m_entityCounter = 0;
|
||||
AZ::IO::LocalFileIO m_localFileIO;
|
||||
|
||||
EntityTestbed()
|
||||
: AllocatorsFixture()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~EntityTestbed()
|
||||
{
|
||||
if (m_tickBusTimer)
|
||||
{
|
||||
m_tickBusTimer->stop();
|
||||
delete m_tickBusTimer;
|
||||
m_tickBusTimer = nullptr;
|
||||
}
|
||||
|
||||
Destroy();
|
||||
}
|
||||
|
||||
virtual void OnSetup() {}
|
||||
virtual void OnAddButtons(QHBoxLayout& layout) { (void)layout; }
|
||||
virtual void OnEntityAdded(AZ::Entity& entity) { (void)entity; }
|
||||
virtual void OnEntityRemoved(AZ::Entity& entity) { (void)entity; }
|
||||
virtual void OnReflect(AZ::SerializeContext& context, AZ::Entity& systemEntity) { (void)context; (void)systemEntity; }
|
||||
virtual void OnDestroy() {}
|
||||
|
||||
void Run(int argc = 0, char** argv = nullptr)
|
||||
{
|
||||
SetupComponentApplication();
|
||||
|
||||
m_qtApplication = new QApplication(argc, argv);
|
||||
|
||||
m_tickBusTimer = new QTimer(this);
|
||||
m_qtApplication->connect(m_tickBusTimer, &QTimer::timeout,
|
||||
[]()
|
||||
{
|
||||
AZ::TickBus::ExecuteQueuedEvents();
|
||||
EBUS_EVENT(AZ::TickBus, OnTick, 0.3f, AZ::ScriptTimePoint());
|
||||
}
|
||||
);
|
||||
|
||||
m_tickBusTimer->start();
|
||||
|
||||
SetupUI();
|
||||
|
||||
OnSetup();
|
||||
|
||||
m_window->show();
|
||||
m_qtApplication->exec();
|
||||
}
|
||||
|
||||
void SetupUI()
|
||||
{
|
||||
m_window = new QWidget();
|
||||
//m_outliner = aznew AzToolsFramework::OutlinerWidget(nullptr);
|
||||
m_propertyEditor = aznew AzToolsFramework::EntityPropertyEditor(nullptr);
|
||||
|
||||
AZ::SerializeContext* serializeContext = nullptr;
|
||||
EBUS_EVENT_RESULT(serializeContext, AZ::ComponentApplicationBus, GetSerializeContext);
|
||||
|
||||
m_window->setMinimumHeight(600);
|
||||
m_propertyEditor->setMinimumWidth(600);
|
||||
//m_outliner->setMinimumWidth(100);
|
||||
|
||||
QVBoxLayout* leftLayout = new QVBoxLayout();
|
||||
QHBoxLayout* outlinerLayout = new QHBoxLayout();
|
||||
QHBoxLayout* outlinerButtonLayout = new QHBoxLayout();
|
||||
//outlinerLayout->addWidget(m_outliner);
|
||||
leftLayout->addLayout(outlinerLayout);
|
||||
leftLayout->addLayout(outlinerButtonLayout);
|
||||
|
||||
QVBoxLayout* rightLayout = new QVBoxLayout();
|
||||
QHBoxLayout* propertyLayout = new QHBoxLayout();
|
||||
QHBoxLayout* propertyButtonLayout = new QHBoxLayout();
|
||||
propertyLayout->addWidget(m_propertyEditor);
|
||||
rightLayout->addLayout(propertyLayout);
|
||||
rightLayout->addLayout(propertyButtonLayout);
|
||||
|
||||
QHBoxLayout* mainLayout = new QHBoxLayout();
|
||||
m_window->setLayout(mainLayout);
|
||||
|
||||
mainLayout->addLayout(leftLayout, 1);
|
||||
mainLayout->addLayout(rightLayout, 3);
|
||||
|
||||
// Add default buttons.
|
||||
QPushButton* addEntity = new QPushButton(QString("Create"));
|
||||
QPushButton* deleteEntities = new QPushButton(QString("Delete"));
|
||||
outlinerButtonLayout->addWidget(addEntity);
|
||||
outlinerButtonLayout->addWidget(deleteEntities);
|
||||
m_qtApplication->connect(addEntity, &QPushButton::pressed, [ this ]() { this->AddEntity(); });
|
||||
m_qtApplication->connect(deleteEntities, &QPushButton::pressed, [ this ]() { this->DeleteSelected(); });
|
||||
|
||||
// Test-specific buttons.
|
||||
OnAddButtons(*outlinerButtonLayout);
|
||||
}
|
||||
|
||||
void SetupComponentApplication()
|
||||
{
|
||||
AZ::ComponentApplication::Descriptor desc;
|
||||
desc.m_enableDrilling = true;
|
||||
desc.m_allocationRecords = true;
|
||||
desc.m_recordingMode = AZ::Debug::AllocationRecords::RECORD_FULL;
|
||||
desc.m_stackRecordLevels = 10;
|
||||
desc.m_useExistingAllocator = true;
|
||||
m_componentApplication = aznew TestbedApplication(*this);
|
||||
|
||||
AZ::IO::FileIOBase::SetInstance(&m_localFileIO);
|
||||
|
||||
m_componentApplication->Start(desc);
|
||||
|
||||
AZ::SerializeContext* serializeContext = m_componentApplication->GetSerializeContext();
|
||||
serializeContext->CreateEditContext();
|
||||
|
||||
AzToolsFramework::Components::PropertyManagerComponent::CreateDescriptor();
|
||||
|
||||
const char* dir = m_componentApplication->GetExecutableFolder();
|
||||
|
||||
m_localFileIO.SetAlias("@assets@", dir);
|
||||
m_localFileIO.SetAlias("@devassets@", dir);
|
||||
}
|
||||
|
||||
void Destroy()
|
||||
{
|
||||
OnDestroy();
|
||||
|
||||
//delete m_outliner;
|
||||
delete m_propertyEditor;
|
||||
delete m_window;
|
||||
delete m_qtApplication;
|
||||
delete m_componentApplication;
|
||||
|
||||
//m_outliner = nullptr;
|
||||
m_propertyEditor = nullptr;
|
||||
m_window = nullptr;
|
||||
m_qtApplication = nullptr;
|
||||
m_componentApplication = nullptr;
|
||||
|
||||
if (AZ::Data::AssetManager::IsReady())
|
||||
{
|
||||
AZ::Data::AssetManager::Destroy();
|
||||
}
|
||||
|
||||
AZ::IO::FileIOBase::SetInstance(nullptr);
|
||||
}
|
||||
|
||||
void AddEntity()
|
||||
{
|
||||
AZStd::string entityName = AZStd::string::format("Entity%u", m_entityCounter);
|
||||
AZ::EntityId entityId;
|
||||
AzToolsFramework::EditorEntityContextRequestBus::BroadcastResult(entityId, &AzToolsFramework::EditorEntityContextRequests::CreateNewEditorEntity, entityName.c_str());
|
||||
++m_entityCounter;
|
||||
|
||||
AZ::Entity* entity = nullptr;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationRequests::FindEntity, entityId);
|
||||
|
||||
entity->Deactivate();
|
||||
OnEntityAdded(*entity);
|
||||
entity->Activate();
|
||||
}
|
||||
|
||||
void DeleteSelected()
|
||||
{
|
||||
EBUS_EVENT(AzToolsFramework::ToolsApplicationRequests::Bus, DeleteSelected);
|
||||
}
|
||||
|
||||
void SaveRoot()
|
||||
{
|
||||
const QString saveAs = QFileDialog::getSaveFileName(nullptr,
|
||||
QString("Save As..."), QString("."), QString("Xml Files (*.xml)"));
|
||||
if (!saveAs.isEmpty())
|
||||
{
|
||||
AZ::SliceComponent* rootSlice;
|
||||
AzToolsFramework::SliceEditorEntityOwnershipServiceRequestBus::BroadcastResult(
|
||||
rootSlice, &AzToolsFramework::SliceEditorEntityOwnershipServiceRequestBus::Events::GetEditorRootSlice);
|
||||
AZ::Utils::SaveObjectToFile(saveAs.toUtf8().constData(), AZ::DataStream::ST_XML, rootSlice->GetEntity());
|
||||
}
|
||||
}
|
||||
|
||||
void ResetRoot()
|
||||
{
|
||||
EBUS_EVENT(AzToolsFramework::EditorEntityContextRequestBus, ResetEditorContext);
|
||||
}
|
||||
};
|
||||
} // namespace UnitTest;
|
||||
@@ -0,0 +1,479 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <FrameworkApplicationFixture.h>
|
||||
#include <Utils/Utils.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/Outcome/Outcome.h>
|
||||
#include <AzCore/Serialization/Json/JsonSerialization.h>
|
||||
#include <AzCore/Serialization/Json/JsonSystemComponent.h>
|
||||
#include <AzCore/Serialization/Json/RegistrationContext.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzFramework/FileFunc/FileFunc.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
#include <AzFramework/IO/LocalFileIO.h>
|
||||
#include <AzTest/AzTest.h>
|
||||
|
||||
#include <QTemporaryDir>
|
||||
#include <QTextStream>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
namespace FileFunc
|
||||
{
|
||||
namespace Internal
|
||||
{
|
||||
AZ::Outcome<void,AZStd::string> UpdateCfgContents(AZStd::string& cfgContents, const AZStd::list<AZStd::string>& updateRules);
|
||||
AZ::Outcome<void,AZStd::string> UpdateCfgContents(AZStd::string& cfgContents, const AZStd::string& header, const AZStd::string& key, const AZStd::string& value);
|
||||
AZ::Outcome<void, AZStd::string> WriteJsonToStream(const rapidjson::Document& document, AZ::IO::GenericStream& stream,
|
||||
WriteJsonSettings settings = WriteJsonSettings{});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
class FileFuncTest : public ScopedAllocatorSetupFixture
|
||||
{
|
||||
public:
|
||||
void SetUp()
|
||||
{
|
||||
m_prevFileIO = AZ::IO::FileIOBase::GetInstance();
|
||||
AZ::IO::FileIOBase::SetInstance(nullptr);
|
||||
AZ::IO::FileIOBase::SetInstance(&m_fileIO);
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
AZ::IO::FileIOBase::SetInstance(nullptr);
|
||||
AZ::IO::FileIOBase::SetInstance(m_prevFileIO);
|
||||
}
|
||||
|
||||
AZ::IO::LocalFileIO m_fileIO;
|
||||
AZ::IO::FileIOBase* m_prevFileIO;
|
||||
};
|
||||
|
||||
TEST_F(FileFuncTest, UpdateCfgContents_InValidInput_Fail)
|
||||
{
|
||||
AZStd::string cfgContents = "[Foo]\n";
|
||||
AZStd::list<AZStd::string> updateRules;
|
||||
|
||||
updateRules.push_back(AZStd::string("Foo/one*1"));
|
||||
auto result = AzFramework::FileFunc::Internal::UpdateCfgContents(cfgContents, updateRules);
|
||||
ASSERT_FALSE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(FileFuncTest, UpdateCfgContents_ValidInput_Success)
|
||||
{
|
||||
AZStd::string cfgContents =
|
||||
"[Foo]\n"
|
||||
"one =2 \n"
|
||||
"two= 3\n"
|
||||
"three = 4\n"
|
||||
"\n"
|
||||
"[Bar]\n"
|
||||
"four=3\n"
|
||||
"five=3\n"
|
||||
"six=3\n"
|
||||
"eight=3\n";
|
||||
|
||||
AZStd::list<AZStd::string> updateRules;
|
||||
|
||||
updateRules.push_back(AZStd::string("Foo/one=1"));
|
||||
updateRules.push_back(AZStd::string("Foo/two=2"));
|
||||
updateRules.push_back(AZStd::string("three=3"));
|
||||
auto result = AzFramework::FileFunc::Internal::UpdateCfgContents(cfgContents, updateRules);
|
||||
EXPECT_TRUE(result.IsSuccess());
|
||||
|
||||
AZStd::string compareCfgContents =
|
||||
"[Foo]\n"
|
||||
"one =1\n"
|
||||
"two= 2\n"
|
||||
"three = 3\n"
|
||||
"\n"
|
||||
"[Bar]\n"
|
||||
"four=3\n"
|
||||
"five=3\n"
|
||||
"six=3\n"
|
||||
"eight=3\n";
|
||||
|
||||
bool equals = cfgContents.compare(compareCfgContents) == 0;
|
||||
ASSERT_TRUE(equals);
|
||||
}
|
||||
|
||||
TEST_F(FileFuncTest, UpdateCfgContents_ValidInputNewEntrySameHeader_Success)
|
||||
{
|
||||
AZStd::string cfgContents =
|
||||
"[Foo]\n"
|
||||
"one =2 \n"
|
||||
"two= 3\n"
|
||||
"three = 4\n";
|
||||
|
||||
AZStd::string header("[Foo]");
|
||||
AZStd::string key("four");
|
||||
AZStd::string value("4");
|
||||
auto result = AzFramework::FileFunc::Internal::UpdateCfgContents(cfgContents, header, key, value);
|
||||
EXPECT_TRUE(result.IsSuccess());
|
||||
|
||||
AZStd::string compareCfgContents =
|
||||
"[Foo]\n"
|
||||
"four=4\n"
|
||||
"one =2 \n"
|
||||
"two= 3\n"
|
||||
"three = 4\n";
|
||||
|
||||
bool equals = cfgContents.compare(compareCfgContents) == 0;
|
||||
ASSERT_TRUE(equals);
|
||||
}
|
||||
|
||||
TEST_F(FileFuncTest, UpdateCfgContents_ValidInputNewEntryDifferentHeader_Success)
|
||||
{
|
||||
AZStd::string cfgContents =
|
||||
";Sample Data\n"
|
||||
"[Foo]\n"
|
||||
"one =2 \n"
|
||||
"two= 3\n"
|
||||
"three = 4\n";
|
||||
|
||||
AZStd::list<AZStd::string> updateRules;
|
||||
|
||||
AZStd::string header("[Bar]");
|
||||
AZStd::string key("four");
|
||||
AZStd::string value("4");
|
||||
auto result = AzFramework::FileFunc::Internal::UpdateCfgContents(cfgContents, header, key, value);
|
||||
EXPECT_TRUE(result.IsSuccess());
|
||||
|
||||
AZStd::string compareCfgContents =
|
||||
";Sample Data\n"
|
||||
"[Foo]\n"
|
||||
"one =2 \n"
|
||||
"two= 3\n"
|
||||
"three = 4\n"
|
||||
"\n"
|
||||
"[Bar]\n"
|
||||
"four=4\n";
|
||||
|
||||
bool equals = cfgContents.compare(compareCfgContents) == 0;
|
||||
ASSERT_TRUE(equals);
|
||||
}
|
||||
|
||||
static bool CreateDummyFile(const QString& fullPathToFile, const QString& tempStr = {})
|
||||
{
|
||||
QFileInfo fi(fullPathToFile);
|
||||
QDir fp(fi.path());
|
||||
fp.mkpath(".");
|
||||
QFile writer(fullPathToFile);
|
||||
if (!writer.open(QFile::ReadWrite))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
{
|
||||
QTextStream stream(&writer);
|
||||
stream << tempStr << Qt::endl;
|
||||
}
|
||||
writer.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST_F(FileFuncTest, FindFilesTest_EmptyFolder_Failure)
|
||||
{
|
||||
QTemporaryDir tempDir;
|
||||
|
||||
QDir tempPath(tempDir.path());
|
||||
|
||||
const char dependenciesPattern[] = "*_dependencies.xml";
|
||||
bool recurse = true;
|
||||
AZStd::string folderPath = tempPath.absolutePath().toStdString().c_str();
|
||||
AZ::Outcome<AZStd::list<AZStd::string>, AZStd::string> result = AzFramework::FileFunc::FindFileList(folderPath.c_str(),
|
||||
dependenciesPattern, recurse);
|
||||
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
ASSERT_EQ(result.GetValue().size(), 0);
|
||||
}
|
||||
|
||||
TEST_F(FileFuncTest, FindFilesTest_DependenciesWildcards_Success)
|
||||
{
|
||||
QTemporaryDir tempDir;
|
||||
|
||||
QDir tempPath(tempDir.path());
|
||||
|
||||
const char* expectedFileNames[] = { "a_dependencies.xml","b_dependencies.xml" };
|
||||
ASSERT_TRUE(CreateDummyFile(tempPath.absoluteFilePath(expectedFileNames[0]), QString("tempdata\n")));
|
||||
ASSERT_TRUE(CreateDummyFile(tempPath.absoluteFilePath(expectedFileNames[1]), QString("tempdata\n")));
|
||||
ASSERT_TRUE(CreateDummyFile(tempPath.absoluteFilePath("dependencies.xml"), QString("tempdata\n")));
|
||||
|
||||
const char dependenciesPattern[] = "*_dependencies.xml";
|
||||
bool recurse = true;
|
||||
AZStd::string folderPath = tempPath.absolutePath().toStdString().c_str();
|
||||
AZ::Outcome<AZStd::list<AZStd::string>, AZStd::string> result = AzFramework::FileFunc::FindFileList(folderPath.c_str(),
|
||||
dependenciesPattern, recurse);
|
||||
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
ASSERT_EQ(result.GetValue().size(), 2);
|
||||
|
||||
for (size_t i = 0; i < AZ_ARRAY_SIZE(expectedFileNames); ++i)
|
||||
{
|
||||
auto findElement = AZStd::find_if(result.GetValue().begin(), result.GetValue().end(), [&expectedFileNames, i](const AZStd::string& thisString)
|
||||
{
|
||||
AZStd::string thisFileName;
|
||||
AzFramework::StringFunc::Path::GetFullFileName(thisString.c_str(), thisFileName);
|
||||
return thisFileName == expectedFileNames[i];
|
||||
});
|
||||
ASSERT_NE(findElement, result.GetValue().end());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(FileFuncTest, FindFilesTest_DependenciesWildcardsSubfolders_Success)
|
||||
{
|
||||
QTemporaryDir tempDir;
|
||||
|
||||
QDir tempPath(tempDir.path());
|
||||
|
||||
ASSERT_TRUE(CreateDummyFile(tempPath.absoluteFilePath("a_dependencies.xml"), QString("tempdata\n")));
|
||||
ASSERT_TRUE(CreateDummyFile(tempPath.absoluteFilePath("b_dependencies.xml"), QString("tempdata\n")));
|
||||
ASSERT_TRUE(CreateDummyFile(tempPath.absoluteFilePath("dependencies.xml"), QString("tempdata\n")));
|
||||
|
||||
const char dependenciesPattern[] = "*_dependencies.xml";
|
||||
bool recurse = true;
|
||||
AZStd::string folderPath = tempPath.absolutePath().toStdString().c_str();
|
||||
|
||||
ASSERT_TRUE(CreateDummyFile(tempPath.absoluteFilePath("subfolder1/c_dependencies.xml"), QString("tempdata\n")));
|
||||
ASSERT_TRUE(CreateDummyFile(tempPath.absoluteFilePath("subfolder1/d_dependencies.xml"), QString("tempdata\n")));
|
||||
ASSERT_TRUE(CreateDummyFile(tempPath.absoluteFilePath("subfolder1/dependencies.xml"), QString("tempdata\n")));
|
||||
|
||||
AZ::Outcome<AZStd::list<AZStd::string>, AZStd::string> result = AzFramework::FileFunc::FindFileList(folderPath.c_str(),
|
||||
dependenciesPattern, recurse);
|
||||
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
ASSERT_EQ(result.GetValue().size(), 4);
|
||||
|
||||
const char* expectedFileNames[] = { "a_dependencies.xml","b_dependencies.xml", "c_dependencies.xml", "d_dependencies.xml" };
|
||||
for (size_t i = 0; i < AZ_ARRAY_SIZE(expectedFileNames); ++i)
|
||||
{
|
||||
auto findElement = AZStd::find_if(result.GetValue().begin(), result.GetValue().end(), [&expectedFileNames, i](const AZStd::string& thisString)
|
||||
{
|
||||
AZStd::string thisFileName;
|
||||
AzFramework::StringFunc::Path::GetFullFileName(thisString.c_str(), thisFileName);
|
||||
return thisFileName == expectedFileNames[i];
|
||||
});
|
||||
ASSERT_NE(findElement, result.GetValue().end());
|
||||
}
|
||||
}
|
||||
|
||||
class JsonFileFuncTest
|
||||
: public FrameworkApplicationFixture
|
||||
{
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
FrameworkApplicationFixture::SetUp();
|
||||
|
||||
AZ::SettingsRegistryInterface* registry = AZ::SettingsRegistry::Get();
|
||||
auto projectPathKey =
|
||||
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) + "/project_path";
|
||||
registry->Set(projectPathKey, "AutomatedTesting");
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*registry);
|
||||
|
||||
m_serializeContext = AZStd::make_unique<AZ::SerializeContext>();
|
||||
m_jsonRegistrationContext = AZStd::make_unique<AZ::JsonRegistrationContext>();
|
||||
m_jsonSystemComponent = AZStd::make_unique<AZ::JsonSystemComponent>();
|
||||
|
||||
m_serializationSettings.m_serializeContext = m_serializeContext.get();
|
||||
m_serializationSettings.m_registrationContext = m_jsonRegistrationContext.get();
|
||||
|
||||
m_deserializationSettings.m_serializeContext = m_serializeContext.get();
|
||||
m_deserializationSettings.m_registrationContext = m_jsonRegistrationContext.get();
|
||||
|
||||
m_jsonSystemComponent->Reflect(m_jsonRegistrationContext.get());
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
m_jsonRegistrationContext->EnableRemoveReflection();
|
||||
m_jsonSystemComponent->Reflect(m_jsonRegistrationContext.get());
|
||||
m_jsonRegistrationContext->DisableRemoveReflection();
|
||||
|
||||
m_jsonRegistrationContext.reset();
|
||||
m_serializeContext.reset();
|
||||
m_jsonSystemComponent.reset();
|
||||
|
||||
FrameworkApplicationFixture::TearDown();
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<AZ::SerializeContext> m_serializeContext;
|
||||
AZStd::unique_ptr<AZ::JsonRegistrationContext> m_jsonRegistrationContext;
|
||||
AZStd::unique_ptr<AZ::JsonSystemComponent> m_jsonSystemComponent;
|
||||
|
||||
AZ::JsonSerializerSettings m_serializationSettings;
|
||||
AZ::JsonDeserializerSettings m_deserializationSettings;
|
||||
};
|
||||
|
||||
TEST_F(JsonFileFuncTest, WriteJsonString_ValidJson_ExpectSuccess)
|
||||
{
|
||||
rapidjson::Document document;
|
||||
document.SetObject();
|
||||
document.AddMember("a", 1, document.GetAllocator());
|
||||
document.AddMember("b", 2, document.GetAllocator());
|
||||
document.AddMember("c", 3, document.GetAllocator());
|
||||
|
||||
AZStd::string expectedJsonText =
|
||||
R"({
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3
|
||||
})";
|
||||
expectedJsonText.erase(AZStd::remove_if(expectedJsonText.begin(), expectedJsonText.end(), ::isspace), expectedJsonText.end());
|
||||
|
||||
AZStd::string outString;
|
||||
AZ::Outcome<void, AZStd::string> result = AzFramework::FileFunc::WriteJsonToString(document, outString);
|
||||
EXPECT_TRUE(result.IsSuccess());
|
||||
|
||||
outString.erase(AZStd::remove_if(outString.begin(), outString.end(), ::isspace), outString.end());
|
||||
EXPECT_EQ(expectedJsonText, outString) << "expected:\n" << expectedJsonText.c_str() << "\nactual:\n" << outString.c_str();
|
||||
}
|
||||
|
||||
TEST_F(JsonFileFuncTest, WriteJsonStream_ValidJson_ExpectSuccess)
|
||||
{
|
||||
rapidjson::Document document;
|
||||
document.SetObject();
|
||||
document.AddMember("a", 1, document.GetAllocator());
|
||||
document.AddMember("b", 2, document.GetAllocator());
|
||||
document.AddMember("c", 3, document.GetAllocator());
|
||||
|
||||
AZStd::string expectedJsonText =
|
||||
R"({
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3
|
||||
})";
|
||||
expectedJsonText.erase(AZStd::remove_if(expectedJsonText.begin(), expectedJsonText.end(), ::isspace), expectedJsonText.end());
|
||||
|
||||
AZStd::vector<char> outBuffer;
|
||||
AZ::IO::ByteContainerStream<AZStd::vector<char>> outStream{ &outBuffer };
|
||||
AZ::Outcome<void, AZStd::string> result = AzFramework::FileFunc::Internal::WriteJsonToStream(document, outStream);
|
||||
EXPECT_TRUE(result.IsSuccess());
|
||||
|
||||
outBuffer.push_back(0);
|
||||
AZStd::string outString = outBuffer.data();
|
||||
outString.erase(AZStd::remove_if(outString.begin(), outString.end(), ::isspace), outString.end());
|
||||
EXPECT_EQ(expectedJsonText, outString) << "expected:\n" << expectedJsonText.c_str() << "\nactual:\n" << outString.c_str();
|
||||
}
|
||||
|
||||
TEST_F(JsonFileFuncTest, WriteJsonFile_ValidJson_ExpectSuccess)
|
||||
{
|
||||
AZ::Test::ScopedAutoTempDirectory tempDir;
|
||||
|
||||
rapidjson::Document document;
|
||||
document.SetObject();
|
||||
document.AddMember("a", 1, document.GetAllocator());
|
||||
document.AddMember("b", 2, document.GetAllocator());
|
||||
document.AddMember("c", 3, document.GetAllocator());
|
||||
|
||||
AZStd::string expectedJsonText =
|
||||
R"({
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3
|
||||
})";
|
||||
expectedJsonText.erase(AZStd::remove_if(expectedJsonText.begin(), expectedJsonText.end(), ::isspace), expectedJsonText.end());
|
||||
|
||||
AZStd::string pathStr;
|
||||
AzFramework::StringFunc::Path::ConstructFull(tempDir.GetDirectory(), "test.json", pathStr, true);
|
||||
|
||||
// Write the JSON to a file
|
||||
AZ::IO::Path path(pathStr);
|
||||
AZ::Outcome<void, AZStd::string> saveResult = AzFramework::FileFunc::WriteJsonFile(document, path);
|
||||
EXPECT_TRUE(saveResult.IsSuccess());
|
||||
|
||||
// Verify that the contents of the file is what we expect
|
||||
AZ::Outcome<AZStd::string, AZStd::string> readResult = AZ::Utils::ReadFile(pathStr);
|
||||
EXPECT_TRUE(readResult.IsSuccess());
|
||||
AZStd::string outString(readResult.TakeValue());
|
||||
outString.erase(AZStd::remove_if(outString.begin(), outString.end(), ::isspace), outString.end());
|
||||
EXPECT_EQ(outString, expectedJsonText);
|
||||
|
||||
// Clean up
|
||||
AZ::IO::FileIOBase::GetInstance()->Remove(path.c_str());
|
||||
}
|
||||
|
||||
TEST_F(JsonFileFuncTest, ReadJsonString_ValidJson_ExpectSuccess)
|
||||
{
|
||||
const char* jsonText =
|
||||
R"(
|
||||
{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3
|
||||
})";
|
||||
|
||||
AZ::Outcome<rapidjson::Document, AZStd::string> result = AzFramework::FileFunc::ReadJsonFromString(jsonText);
|
||||
|
||||
EXPECT_TRUE(result.IsSuccess());
|
||||
EXPECT_TRUE(result.GetValue().IsObject());
|
||||
EXPECT_TRUE(result.GetValue().HasMember("a"));
|
||||
EXPECT_TRUE(result.GetValue().HasMember("b"));
|
||||
EXPECT_TRUE(result.GetValue().HasMember("c"));
|
||||
EXPECT_EQ(result.GetValue()["a"].GetInt(), 1);
|
||||
EXPECT_EQ(result.GetValue()["b"].GetInt(), 2);
|
||||
EXPECT_EQ(result.GetValue()["c"].GetInt(), 3);
|
||||
}
|
||||
|
||||
TEST_F(JsonFileFuncTest, ReadJsonString_InvalidJson_ErrorReportsLineNumber)
|
||||
{
|
||||
const char* jsonText =
|
||||
R"(
|
||||
{
|
||||
"a": "This line is missing a comma"
|
||||
"b": 2,
|
||||
"c": 3
|
||||
}
|
||||
)";
|
||||
|
||||
AZ::Outcome<rapidjson::Document, AZStd::string> result = AzFramework::FileFunc::ReadJsonFromString(jsonText);
|
||||
|
||||
EXPECT_FALSE(result.IsSuccess());
|
||||
EXPECT_TRUE(result.GetError().find("JSON parse error at line 4:") == 0);
|
||||
}
|
||||
|
||||
TEST_F(JsonFileFuncTest, ReadJsonFile_ValidJson_ExpectSuccess)
|
||||
{
|
||||
AZ::Test::ScopedAutoTempDirectory tempDir;
|
||||
|
||||
const char* inputJsonText =
|
||||
R"({
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3
|
||||
})";
|
||||
|
||||
rapidjson::Document expectedDocument;
|
||||
expectedDocument.SetObject();
|
||||
expectedDocument.AddMember("a", 1, expectedDocument.GetAllocator());
|
||||
expectedDocument.AddMember("b", 2, expectedDocument.GetAllocator());
|
||||
expectedDocument.AddMember("c", 3, expectedDocument.GetAllocator());
|
||||
|
||||
// Create test file
|
||||
AZStd::string path;
|
||||
AzFramework::StringFunc::Path::ConstructFull(tempDir.GetDirectory(), "test.json", path, true);
|
||||
AZ::Outcome<void, AZStd::string> writeResult = AZ::Utils::WriteFile(inputJsonText, path);
|
||||
EXPECT_TRUE(writeResult.IsSuccess());
|
||||
|
||||
|
||||
// Read the JSON from the test file
|
||||
AZ::Outcome<rapidjson::Document, AZStd::string> readResult = AzFramework::FileFunc::ReadJsonFile(path);
|
||||
EXPECT_TRUE(readResult.IsSuccess());
|
||||
|
||||
EXPECT_EQ(expectedDocument, readResult.GetValue());
|
||||
|
||||
// Clean up
|
||||
AZ::IO::FileIOBase::GetInstance()->Remove(path.c_str());
|
||||
}
|
||||
} // namespace UnitTest
|
||||
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#include <AzTest/AzTest.h>
|
||||
#include <AzCore/Slice/SliceComponent.h>
|
||||
#include <AzCore/Serialization/Utils.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/UserSettings/UserSettingsComponent.h>
|
||||
#include <AzToolsFramework/ToolsComponents/GenericComponentWrapper.h>
|
||||
#include <AzToolsFramework/Application/ToolsApplication.h>
|
||||
#include <AzToolsFramework/API/EntityCompositionRequestBus.h>
|
||||
|
||||
// Test that editor-components wrapped within a GenericComponentWrapper
|
||||
// are moved out of the wrapper when a slice is loaded.
|
||||
const char kWrappedEditorComponent[] =
|
||||
R"DELIMITER(<ObjectStream version="1">
|
||||
<Class name="SliceComponent" field="element" version="1" type="{AFD304E4-1773-47C8-855A-8B622398934F}">
|
||||
<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
|
||||
<Class name="AZ::u64" field="Id" value="7737200995084371546" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::vector" field="Entities" type="{2BADE35A-6F1B-4698-B2BC-3373D010020C}">
|
||||
<Class name="AZ::Entity" field="element" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
|
||||
<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
|
||||
<Class name="AZ::u64" field="id" value="16119032733109672753" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::string" field="Name" value="RigidPhysicsMesh" type="{EF8FF807-DDEE-4EB0-B678-4CA3A2C490A4}"/>
|
||||
<Class name="bool" field="IsDependencyReady" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="AZStd::vector" field="Components" type="{2BADE35A-6F1B-4698-B2BC-3373D010020C}">
|
||||
<Class name="GenericComponentWrapper" field="element" type="{68D358CA-89B9-4730-8BA6-E181DEA28FDE}">
|
||||
<Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
|
||||
<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
|
||||
<Class name="AZ::u64" field="Id" value="11874523501682509824" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="SelectionComponent" field="m_template" type="{73B724FC-43D1-4C75-ACF5-79AA8A3BF89D}">
|
||||
<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
|
||||
<Class name="AZ::u64" field="Id" value="0" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZStd::list" field="Prefabs" type="{B845AD64-B5A0-4CCD-A86B-3477A36779BE}"/>
|
||||
<Class name="bool" field="IsDynamic" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
</Class>
|
||||
</ObjectStream>)DELIMITER";
|
||||
|
||||
class WrappedEditorComponentTest
|
||||
: public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
AZ::SettingsRegistryInterface* registry = AZ::SettingsRegistry::Get();
|
||||
auto projectPathKey =
|
||||
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) + "/project_path";
|
||||
registry->Set(projectPathKey, "AutomatedTesting");
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*registry);
|
||||
|
||||
m_app.Start(AZ::ComponentApplication::Descriptor());
|
||||
|
||||
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
|
||||
// shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash
|
||||
// in the unit tests.
|
||||
AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize);
|
||||
|
||||
m_slice.reset(AZ::Utils::LoadObjectFromBuffer<AZ::SliceComponent>(kWrappedEditorComponent, strlen(kWrappedEditorComponent) + 1));
|
||||
if (m_slice)
|
||||
{
|
||||
if (m_slice->GetNewEntities().size() > 0)
|
||||
{
|
||||
m_entityFromSlice = m_slice->GetNewEntities()[0];
|
||||
if (m_entityFromSlice)
|
||||
{
|
||||
if (m_entityFromSlice->GetComponents().size() > 0)
|
||||
{
|
||||
m_componentFromSlice = m_entityFromSlice->GetComponents()[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
m_slice.reset();
|
||||
|
||||
m_app.Stop();
|
||||
}
|
||||
|
||||
AzToolsFramework::ToolsApplication m_app;
|
||||
AZStd::unique_ptr<AZ::SliceComponent> m_slice;
|
||||
AZ::Entity* m_entityFromSlice = nullptr;
|
||||
AZ::Component* m_componentFromSlice = nullptr;
|
||||
};
|
||||
|
||||
TEST_F(WrappedEditorComponentTest, Slice_Loaded)
|
||||
{
|
||||
EXPECT_NE(m_slice.get(), nullptr);
|
||||
}
|
||||
|
||||
TEST_F(WrappedEditorComponentTest, EntityFromSlice_Exists)
|
||||
{
|
||||
EXPECT_NE(m_entityFromSlice, nullptr);
|
||||
}
|
||||
|
||||
TEST_F(WrappedEditorComponentTest, ComponentFromSlice_Exists)
|
||||
{
|
||||
EXPECT_NE(m_componentFromSlice, nullptr);
|
||||
}
|
||||
|
||||
TEST_F(WrappedEditorComponentTest, Component_IsNotGenericComponentWrapper)
|
||||
{
|
||||
EXPECT_EQ(azrtti_cast<AzToolsFramework::Components::GenericComponentWrapper*>(m_componentFromSlice), nullptr);
|
||||
}
|
||||
|
||||
// The swapped component should have adopted the GenericComponentWrapper's ComponentId.
|
||||
TEST_F(WrappedEditorComponentTest, ComponentId_MatchesWrapperId)
|
||||
{
|
||||
EXPECT_EQ(m_componentFromSlice->GetId(), 11874523501682509824u);
|
||||
}
|
||||
|
||||
const AZ::Uuid InGameOnlyComponentTypeId = "{1D538623-2052-464F-B0DA-D000E1520333}";
|
||||
class InGameOnlyComponent
|
||||
: public AZ::Component
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(InGameOnlyComponent, InGameOnlyComponentTypeId);
|
||||
|
||||
void Activate() override {}
|
||||
void Deactivate() override {}
|
||||
|
||||
static void Reflect(AZ::ReflectContext* reflection)
|
||||
{
|
||||
if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection))
|
||||
{
|
||||
serializeContext->Class<InGameOnlyComponent, AZ::Component>();
|
||||
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
|
||||
{
|
||||
editContext->Class<InGameOnlyComponent>("InGame Only", "")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game"));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const AZ::Uuid NoneEditorComponentTypeId = "{AE3454BA-D785-4EE2-A55B-A089F2B2916A}";
|
||||
class NoneEditorComponent
|
||||
: public AZ::Component
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(NoneEditorComponent, NoneEditorComponentTypeId);
|
||||
|
||||
void Activate() override {}
|
||||
void Deactivate() override {}
|
||||
|
||||
static void Reflect(AZ::ReflectContext* reflection)
|
||||
{
|
||||
if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection))
|
||||
{
|
||||
serializeContext->Class<NoneEditorComponent, AZ::Component>();
|
||||
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
|
||||
{
|
||||
editContext->Class<NoneEditorComponent>("None Editor", "")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game"));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class FindWrappedComponentsTest
|
||||
: public ::testing::Test
|
||||
{
|
||||
public:
|
||||
void SetUp() override
|
||||
{
|
||||
AZ::SettingsRegistryInterface* registry = AZ::SettingsRegistry::Get();
|
||||
auto projectPathKey =
|
||||
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) + "/project_path";
|
||||
registry->Set(projectPathKey, "AutomatedTesting");
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*registry);
|
||||
|
||||
m_app.Start(AzFramework::Application::Descriptor());
|
||||
|
||||
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
|
||||
// shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash
|
||||
// in the unit tests.
|
||||
AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize);
|
||||
|
||||
m_app.RegisterComponentDescriptor(InGameOnlyComponent::CreateDescriptor());
|
||||
m_app.RegisterComponentDescriptor(NoneEditorComponent::CreateDescriptor());
|
||||
|
||||
m_entity = new AZ::Entity("Entity1");
|
||||
|
||||
AZ::Component* inGameOnlyComponent = nullptr;
|
||||
AZ::ComponentDescriptorBus::EventResult(inGameOnlyComponent, InGameOnlyComponentTypeId, &AZ::ComponentDescriptorBus::Events::CreateComponent);
|
||||
AZ::Component* genericComponent0 = aznew AzToolsFramework::Components::GenericComponentWrapper(inGameOnlyComponent);
|
||||
m_entity->AddComponent(genericComponent0);
|
||||
|
||||
AZ::Component* noneEditorComponent = nullptr;
|
||||
AZ::ComponentDescriptorBus::EventResult(noneEditorComponent, NoneEditorComponentTypeId, &AZ::ComponentDescriptorBus::Events::CreateComponent);
|
||||
AZ::Component* genericComponent1 = aznew AzToolsFramework::Components::GenericComponentWrapper(noneEditorComponent);
|
||||
m_entity->AddComponent(genericComponent1);
|
||||
|
||||
m_entity->Init();
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
m_app.Stop();
|
||||
}
|
||||
|
||||
AzToolsFramework::ToolsApplication m_app;
|
||||
|
||||
AZ::Entity* m_entity = nullptr;
|
||||
};
|
||||
|
||||
TEST_F(FindWrappedComponentsTest, found)
|
||||
{
|
||||
InGameOnlyComponent* ingameOnlyComponent = AzToolsFramework::FindWrappedComponentForEntity<InGameOnlyComponent>(m_entity);
|
||||
EXPECT_NE(ingameOnlyComponent, nullptr);
|
||||
|
||||
NoneEditorComponent* noneEditorComponent = AzToolsFramework::FindWrappedComponentForEntity<NoneEditorComponent>(m_entity);
|
||||
EXPECT_NE(noneEditorComponent, nullptr);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -46,7 +46,7 @@ AZTEST_EXPORT int AZ_UNIT_TEST_HOOK_NAME(int argc, char** argv)
|
||||
}
|
||||
styleManager->initialize(&app, engineRootPath);
|
||||
AZ::Test::printUnusedParametersWarning(argc, argv);
|
||||
AZ::Test::addTestEnvironments({ new ToolsFrameworkHook });
|
||||
AZ::Test::addTestEnvironments({ DEFAULT_UNIT_TEST_ENV, new ToolsFrameworkHook });
|
||||
int result = RUN_ALL_TESTS();
|
||||
styleManager.release();
|
||||
return result;
|
||||
|
||||
@@ -23,8 +23,7 @@ namespace UnitTest
|
||||
};
|
||||
|
||||
struct PerforceComponentFixture
|
||||
: ::testing::Test
|
||||
, TraceBusRedirector
|
||||
: ScopedAllocatorSetupFixture
|
||||
, SourceControlTest
|
||||
|
||||
{
|
||||
@@ -40,7 +39,6 @@ namespace UnitTest
|
||||
m_jobContext = aznew AZ::JobContext(*m_jobManager);
|
||||
AZ::JobContext::SetGlobalContext(m_jobContext);
|
||||
|
||||
AZ::Debug::TraceMessageBus::Handler::BusConnect();
|
||||
AZ::TickBus::AllowFunctionQueuing(true);
|
||||
|
||||
m_perforceComponent = AZStd::make_unique<MockPerforceComponent>();
|
||||
@@ -52,8 +50,6 @@ namespace UnitTest
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
AZ::Debug::TraceMessageBus::Handler::BusDisconnect();
|
||||
|
||||
AZ::TickBus::AllowFunctionQueuing(false);
|
||||
AZ::TickBus::ClearQueuedEvents();
|
||||
|
||||
|
||||
@@ -83,9 +83,11 @@ namespace UnitTest
|
||||
info.m_assetId = m_assets[platformNum][idx];
|
||||
assetRegistry->RegisterAsset(m_assets[platformNum][idx], info);
|
||||
m_assetsPath[platformNum][idx] = info.m_relativePath;
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
if (m_fileStreams[platformNum][idx].Open(m_assetsPath[platformNum][idx].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath))
|
||||
{
|
||||
m_fileStreams[platformNum][idx].Write(info.m_relativePath.size(), info.m_relativePath.data());
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -131,7 +133,9 @@ namespace UnitTest
|
||||
m_fileStreams[platformNum][idx].Close();
|
||||
if (fileIO->Exists(m_assetsPath[platformNum][idx].c_str()))
|
||||
{
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
fileIO->Remove(m_assetsPath[platformNum][idx].c_str());
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1); // removing from asset cache folder
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -246,7 +250,9 @@ namespace UnitTest
|
||||
AzFramework::AssetSystem::NetworkAssetUpdateInterface* notificationInterface = AZ::Interface<AzFramework::AssetSystem::NetworkAssetUpdateInterface>::Get();
|
||||
EXPECT_NE(notificationInterface, nullptr);
|
||||
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
auto* mockCatalog = new ::testing::NiceMock<PlatformAddressedAssetCatalogMessageTest>(AzFramework::PlatformId::ANDROID_ID);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
AZStd::unique_ptr< ::testing::NiceMock<PlatformAddressedAssetCatalogMessageTest>> catalogHolder;
|
||||
catalogHolder.reset(mockCatalog);
|
||||
|
||||
|
||||
@@ -13,7 +13,9 @@ namespace UnitTest
|
||||
|
||||
TEST_F(PrefabInstantiateTest, PrefabInstantiate_InstantiateInvalidTemplate_InstantiateFails)
|
||||
{
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
EXPECT_FALSE(m_prefabSystemComponent->InstantiatePrefab(AzToolsFramework::Prefab::InvalidTemplateId));
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
}
|
||||
|
||||
TEST_F(PrefabInstantiateTest, PrefabInstantiate_NoNestingTemplate_InstantiateSucceeds)
|
||||
|
||||
@@ -68,8 +68,10 @@ namespace UnitTest
|
||||
|
||||
MockPrefabFileIOActionValidator mockIOActionValidator;
|
||||
mockIOActionValidator.ReadPrefabDom(templateData.m_filePath, templatePrefabDom);
|
||||
|
||||
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
templateData.m_id = m_prefabLoaderInterface->LoadTemplateFromFile(templateData.m_filePath);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(3);
|
||||
templateData.m_isLoadedWithErrors = true;
|
||||
|
||||
PrefabTestDataUtils::ValidateTemplateLoad(templateData);
|
||||
@@ -115,7 +117,9 @@ namespace UnitTest
|
||||
targetTemplateData.m_filePath, targetTemplatePrefabDom);
|
||||
|
||||
// Load target and source Templates and get their Ids.
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
targetTemplateData.m_id = m_prefabLoaderInterface->LoadTemplateFromFile(targetTemplateData.m_filePath);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(4);
|
||||
sourceTemplateData.m_id = m_prefabSystemComponent->GetTemplateIdFromFilePath(sourceTemplateData.m_filePath);
|
||||
|
||||
// Because of cyclical dependency, the two Templates should be loaded with errors.
|
||||
@@ -144,7 +148,9 @@ namespace UnitTest
|
||||
MockPrefabFileIOActionValidator mockIOActionValidator;
|
||||
mockIOActionValidator.ReadPrefabDom(templateData.m_filePath, templatePrefabDom);
|
||||
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
templateData.m_id = m_prefabLoaderInterface->LoadTemplateFromFile(templateData.m_filePath);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(2);
|
||||
|
||||
PrefabTestDataUtils::ValidateTemplateLoad(templateData);
|
||||
}
|
||||
@@ -161,7 +167,9 @@ namespace UnitTest
|
||||
MockPrefabFileIOActionValidator mockIOActionValidator;
|
||||
mockIOActionValidator.ReadPrefabDom(templateData.m_filePath, templatePrefabDom);
|
||||
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
templateData.m_id = m_prefabLoaderInterface->LoadTemplateFromFile(templateData.m_filePath);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(2);
|
||||
|
||||
PrefabTestDataUtils::ValidateTemplateLoad(templateData);
|
||||
}
|
||||
@@ -183,7 +191,9 @@ namespace UnitTest
|
||||
templateInstanceData.m_source, PrefabTestDomUtils::CreatePrefabDom(),
|
||||
AZ::IO::ResultCode::Success, AZ::IO::ResultCode::Error);
|
||||
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
templateData.m_id = m_prefabLoaderInterface->LoadTemplateFromFile(templateData.m_filePath);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(3);
|
||||
|
||||
PrefabTestDataUtils::ValidateTemplateLoad(templateData);
|
||||
}
|
||||
@@ -279,8 +289,10 @@ namespace UnitTest
|
||||
|
||||
MockPrefabFileIOActionValidator mockIOActionValidator;
|
||||
mockIOActionValidator.ReadPrefabDom(pathToCorruptedPrefab, corruptedPrefabContent);
|
||||
|
||||
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
TemplateId templateId = m_prefabLoaderInterface->LoadTemplateFromFile(pathToCorruptedPrefab);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
|
||||
EXPECT_EQ(templateId, AzToolsFramework::Prefab::InvalidTemplateId);
|
||||
}
|
||||
@@ -289,8 +301,10 @@ namespace UnitTest
|
||||
{
|
||||
PrefabDom emptyPrefabDom = PrefabTestDomUtils::CreatePrefabDom();
|
||||
AZStd::string emptyPrefabDomStr = PrefabTestDomUtils::DomToString(emptyPrefabDom);
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
EXPECT_EQ(m_prefabLoaderInterface->LoadTemplateFromString(emptyPrefabDomStr, "|?<>"), AzToolsFramework::Prefab::InvalidTemplateId);
|
||||
EXPECT_EQ(m_prefabLoaderInterface->LoadTemplateFromString(emptyPrefabDomStr, "notAFile/"), AzToolsFramework::Prefab::InvalidTemplateId);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(2);
|
||||
}
|
||||
|
||||
TEST_F(PrefabLoadTemplateTest, LoadTemplate_LoadFromString_LoadsEmptyPrefab)
|
||||
@@ -318,9 +332,11 @@ namespace UnitTest
|
||||
);
|
||||
|
||||
AZStd::string selfDependentPrefabStr = PrefabTestDomUtils::DomToString(selfDependentPrefab);
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
templateData.m_id = m_prefabLoaderInterface->LoadTemplateFromString(
|
||||
selfDependentPrefabStr,
|
||||
templateData.m_filePath);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // produces different counts in Jenkins vs local
|
||||
|
||||
templateData.m_isLoadedWithErrors = true;
|
||||
|
||||
@@ -330,7 +346,9 @@ namespace UnitTest
|
||||
TEST_F(PrefabLoadTemplateTest, LoadTemplate_LoadFromString_CorruptedReturnsInvalidTemplateId)
|
||||
{
|
||||
AZStd::string corruptPrefab = "{ Corrupted PrefabDom";
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
TemplateId templateId = m_prefabLoaderInterface->LoadTemplateFromString(corruptPrefab);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
EXPECT_EQ(templateId, AzToolsFramework::Prefab::InvalidTemplateId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,13 +166,25 @@ namespace UnitTest
|
||||
if (expectedNestedInstanceDomInstances.has_value())
|
||||
{
|
||||
ASSERT_TRUE(actualNestedInstanceDomInstances.has_value());
|
||||
for (auto instanceIterator = expectedNestedInstanceDomInstances->get().MemberBegin();
|
||||
instanceIterator != expectedNestedInstanceDomInstances->get().MemberEnd(); ++instanceIterator)
|
||||
if (expectedNestedInstanceDomInstances->get().IsArray())
|
||||
{
|
||||
ComparePrefabDoms(
|
||||
instanceIterator->value,
|
||||
PrefabDomUtils::FindPrefabDomValue(actualNestedInstanceDomInstances->get(), instanceIterator->name.GetString()),
|
||||
shouldCompareLinkIds, shouldCompareContainerEntities);
|
||||
ASSERT_TRUE(actualNestedInstanceDomInstances->get().IsArray());
|
||||
const size_t expectedArraySize = expectedNestedInstanceDomInstances->get().GetArray().Size();
|
||||
EXPECT_EQ(0, expectedArraySize);
|
||||
const size_t actualArraySize = actualNestedInstanceDomInstances->get().GetArray().Size();
|
||||
EXPECT_EQ(0, actualArraySize);
|
||||
}
|
||||
if (expectedNestedInstanceDomInstances->get().IsObject())
|
||||
{
|
||||
ASSERT_TRUE(actualNestedInstanceDomInstances->get().IsObject());
|
||||
for (auto instanceIterator = expectedNestedInstanceDomInstances->get().MemberBegin();
|
||||
instanceIterator != expectedNestedInstanceDomInstances->get().MemberEnd(); ++instanceIterator)
|
||||
{
|
||||
ComparePrefabDoms(
|
||||
instanceIterator->value,
|
||||
PrefabDomUtils::FindPrefabDomValue(actualNestedInstanceDomInstances->get(), instanceIterator->name.GetString()),
|
||||
shouldCompareLinkIds, shouldCompareContainerEntities);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,8 +37,7 @@ namespace UnitTest
|
||||
};
|
||||
|
||||
class PrefabTestFixture
|
||||
: public ToolsApplicationFixture,
|
||||
public UnitTest::TraceBusRedirector
|
||||
: public ToolsApplicationFixture
|
||||
{
|
||||
protected:
|
||||
|
||||
|
||||
@@ -96,8 +96,8 @@ namespace UnitTest
|
||||
|
||||
//apply the patch
|
||||
PrefabDom& templateDomReference = m_prefabSystemComponent->FindTemplateDom(nestedTemplateId);
|
||||
AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::ApplyPatch(templateDomReference,
|
||||
templateDomReference.GetAllocator(), patch, AZ::JsonMergeApproach::JsonPatch);
|
||||
AZ::JsonSerializationResult::ResultCode result =
|
||||
PrefabDomUtils::ApplyPatches(templateDomReference, templateDomReference.GetAllocator(), patch);
|
||||
|
||||
AZ_Error("Prefab", result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success,
|
||||
"Patch was not successfully applied");
|
||||
|
||||
@@ -426,7 +426,9 @@ namespace UnitTest
|
||||
AZStd::any keyString = AZStd::make_any<AZStd::string_view>("0");
|
||||
|
||||
EXPECT_FALSE(propertyTree.GetContainerItem("My New Int", key).IsSuccess());
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
EXPECT_FALSE(propertyTree.GetContainerItem("My New List", keyString).IsSuccess());
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
|
||||
PropertyTreeEditor::PropertyAccessOutcome outcome = propertyTree.GetContainerItem("My New List", key);
|
||||
EXPECT_TRUE(outcome.IsSuccess());
|
||||
@@ -446,7 +448,9 @@ namespace UnitTest
|
||||
AZStd::any value = AZStd::make_any<PropertyTreeEditorTester::PropertyTreeEditorNestedTester>(testUpdate);
|
||||
|
||||
EXPECT_FALSE(propertyTree.UpdateContainerItem("My New Int", key, value).IsSuccess());
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
EXPECT_FALSE(propertyTree.UpdateContainerItem("My New List", keyString, value).IsSuccess());
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
EXPECT_TRUE(propertyTree.UpdateContainerItem("My New List", key, value).IsSuccess());
|
||||
|
||||
PropertyTreeEditor::PropertyAccessOutcome outcome = propertyTree.GetContainerItem("My New List", key);
|
||||
@@ -464,7 +468,9 @@ namespace UnitTest
|
||||
AZStd::any keyString = AZStd::make_any<AZStd::string_view>("0");
|
||||
|
||||
EXPECT_FALSE(propertyTree.RemoveContainerItem("My New Int", key).IsSuccess());
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
EXPECT_FALSE(propertyTree.RemoveContainerItem("My New List", keyString).IsSuccess());
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
|
||||
PropertyTreeEditor::PropertyAccessOutcome outcomeAdd1 = propertyTree.RemoveContainerItem("My New List", key);
|
||||
EXPECT_TRUE(outcomeAdd1.IsSuccess());
|
||||
@@ -755,7 +761,9 @@ namespace UnitTest
|
||||
EXPECT_TRUE(propertyTree.SetProperty("My Int", anEmpty).IsSuccess());
|
||||
EXPECT_TRUE(propertyTree.SetProperty("My Negative Short", anEmpty).IsSuccess());
|
||||
EXPECT_TRUE(propertyTree.SetProperty("My New List", anEmpty).IsSuccess());
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
EXPECT_TRUE(propertyTree.SetProperty("My Asset Data", anEmpty).IsSuccess());
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
EXPECT_TRUE(propertyTree.SetProperty("My Test Simple Asset", anEmpty).IsSuccess());
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Math/Uuid.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
|
||||
#include <AzToolsFramework/SQLite/SQLiteConnection.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
using namespace AzToolsFramework;
|
||||
|
||||
static int s_numTablesToCreate = 100;
|
||||
// we'll do about as much as we can get away with for about a second with most modern CPU
|
||||
static int s_numTrialsToPerform = 10500;
|
||||
|
||||
class SQLiteTest
|
||||
: public AllocatorsFixture
|
||||
{
|
||||
public:
|
||||
SQLiteTest()
|
||||
: AllocatorsFixture()
|
||||
{
|
||||
}
|
||||
|
||||
~SQLiteTest() = default;
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
AllocatorsFixture::SetUp();
|
||||
m_database.reset(aznew SQLite::Connection());
|
||||
m_randomDatabaseFileName = AZStd::string::format("%s_temp.sqlite", AZ::Uuid::CreateRandom().ToString<AZStd::string>().c_str());
|
||||
m_database->Open(m_randomDatabaseFileName.c_str(), false);
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
m_database->Close();
|
||||
m_database.reset();
|
||||
AZ::IO::SystemFile::Delete(m_randomDatabaseFileName.c_str());
|
||||
m_randomDatabaseFileName.set_capacity(0);
|
||||
AllocatorsFixture::TearDown();
|
||||
}
|
||||
|
||||
AZStd::string m_randomDatabaseFileName;
|
||||
AZStd::unique_ptr<SQLite::Connection> m_database;
|
||||
};
|
||||
|
||||
|
||||
TEST_F(SQLiteTest, DoesTableExist_BadInputs_ShouldAssert)
|
||||
{
|
||||
ASSERT_TRUE(m_database->IsOpen());
|
||||
|
||||
// basic tests, bad input:
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
EXPECT_FALSE(m_database->DoesTableExist(""));
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
EXPECT_FALSE(m_database->DoesTableExist(nullptr));
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
}
|
||||
|
||||
// DoesTableExist had an off-by-one error in its string. It would not always crash.
|
||||
// This just stress tests that function (which also tests statement creation and destruction) to ensure
|
||||
// that if there is a problem with failing creation of functions, we don't crash.
|
||||
TEST_F(SQLiteTest, DoesTableExist_BasicFuzzTest_BadTableNames_ShouldNotAssert_ShouldReturnFalse)
|
||||
{
|
||||
ASSERT_TRUE(m_database->IsOpen());
|
||||
|
||||
// now make up some random table names and try them out - none should exist.
|
||||
AZStd::string randomJunkTableName;
|
||||
randomJunkTableName.resize(16, '\0');
|
||||
for (int trialNumber = 0; trialNumber < s_numTrialsToPerform; ++trialNumber)
|
||||
{
|
||||
for (int randomChar = 0; randomChar < 16; ++randomChar)
|
||||
{
|
||||
// note that this also puts characters AFTER the null, if a null appears in the mddle.
|
||||
// so that if there are off by one errors they could include cruft afterwards.
|
||||
randomJunkTableName[randomChar] = (char)(rand() % 256); // this will trigger invalid UTF8 decoding too
|
||||
}
|
||||
randomJunkTableName[0] = 'a'; // just to make sure we don't retry the null case.
|
||||
EXPECT_FALSE(m_database->DoesTableExist(randomJunkTableName.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
// this makes sure that repeated calls to DoesTableExist does not cause some crazy assertion or failure
|
||||
// if code is incorrect, it might, because DoesTableExists tends to create and destroy temporary statments.
|
||||
// as a coincidence, this also serves as somewhat of a stress test for all the other parts of the database
|
||||
// since this tests both creation of statements, execution of them, and retiring / cleaning the memory / freeing them
|
||||
TEST_F(SQLiteTest, DoesTableExist_BasicStressTest_GoodTableNames_ShouldNotAssert_ShouldReturnTrue)
|
||||
{
|
||||
// --- SETUP PHASE ----
|
||||
ASSERT_TRUE(m_database->IsOpen());
|
||||
|
||||
// outside scope to improve reuse memory performance.
|
||||
AZStd::string randomValidTableName;
|
||||
AZStd::string createDatabaseTableStatement;
|
||||
|
||||
for (int tableToCreate = 0; tableToCreate < s_numTablesToCreate; ++tableToCreate)
|
||||
{
|
||||
randomValidTableName = AZStd::string::format("testtable_%i", tableToCreate);
|
||||
createDatabaseTableStatement = AZStd::string::format(
|
||||
"CREATE TABLE IF NOT EXISTS %s( "
|
||||
" rowID INTEGER PRIMARY KEY, "
|
||||
" version INTEGER NOT NULL);", randomValidTableName.c_str());
|
||||
|
||||
m_database->AddStatement(randomValidTableName, createDatabaseTableStatement);
|
||||
EXPECT_TRUE(m_database->ExecuteOneOffStatement(randomValidTableName.c_str()));
|
||||
m_database->RemoveStatement(randomValidTableName.c_str());
|
||||
}
|
||||
|
||||
// --- TEST PHASE ----
|
||||
for (int trialNumber = 0; trialNumber < s_numTrialsToPerform; ++trialNumber)
|
||||
{
|
||||
randomValidTableName = AZStd::string::format("testtable_%i", rand() % s_numTablesToCreate);
|
||||
EXPECT_TRUE(m_database->DoesTableExist(randomValidTableName.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Asset/AssetManagerComponent.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Script/ScriptAsset.h>
|
||||
#include <AzCore/Script/ScriptSystemComponent.h>
|
||||
#include <AzCore/Script/ScriptContext.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AzToolsFramework/ToolsComponents/ScriptEditorComponent.h>
|
||||
|
||||
#include "EntityTestbed.h"
|
||||
|
||||
extern "C" {
|
||||
# include <Lua/lualib.h>
|
||||
# include <Lua/lauxlib.h>
|
||||
}
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
using namespace AZ;
|
||||
using namespace AzFramework;
|
||||
|
||||
// Global Properties used for Testing
|
||||
int mySubValue = 0;
|
||||
int myReloadValue = 0;
|
||||
|
||||
class ScriptComponentTest
|
||||
: public testing::Test
|
||||
{
|
||||
public:
|
||||
AZ_TYPE_INFO(ScriptComponentTest, "{85CDBD49-70FF-416A-8154-B5525EDD30D4}");
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
ComponentApplication::Descriptor appDesc;
|
||||
appDesc.m_memoryBlocksByteSize = 100 * 1024 * 1024;
|
||||
//appDesc.m_recordsMode = AllocationRecords::RECORD_FULL;
|
||||
//appDesc.m_stackRecordLevels = 20;
|
||||
Entity* systemEntity = m_app.Create(appDesc);
|
||||
|
||||
systemEntity->CreateComponent<MemoryComponent>();
|
||||
systemEntity->CreateComponent("{CAE3A025-FAC9-4537-B39E-0A800A2326DF}"); // JobManager component
|
||||
systemEntity->CreateComponent<StreamerComponent>();
|
||||
systemEntity->CreateComponent<AssetManagerComponent>();
|
||||
systemEntity->CreateComponent("{A316662A-6C3E-43E6-BC61-4B375D0D83B4}"); // Usersettings component
|
||||
systemEntity->CreateComponent<ScriptSystemComponent>();
|
||||
|
||||
systemEntity->Init();
|
||||
systemEntity->Activate();
|
||||
|
||||
EBUS_EVENT_RESULT(m_scriptContext, ScriptSystemRequestBus, GetContext, DefaultScriptContextId);
|
||||
EBUS_EVENT_RESULT(m_behaviorContext, AZ::ComponentApplicationBus, GetBehaviorContext);
|
||||
EBUS_EVENT_RESULT(m_serializeContext, AZ::ComponentApplicationBus, GetSerializeContext);
|
||||
|
||||
AzToolsFramework::Components::ScriptEditorComponent::CreateDescriptor(); // descriptor is deleted by app
|
||||
AzToolsFramework::Components::ScriptEditorComponent::Reflect(m_serializeContext);
|
||||
|
||||
ScriptComponent::CreateDescriptor(); // descriptor is deleted by app
|
||||
ScriptComponent::Reflect(m_serializeContext);
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
m_app.Destroy();
|
||||
}
|
||||
|
||||
Data::Asset<ScriptAsset> CreateAndLoadScriptAsset(const AZStd::string& script)
|
||||
{
|
||||
Data::Asset<ScriptAsset> scriptAsset = Data::AssetManager::Instance().CreateAsset<ScriptAsset>(Uuid::CreateRandom());
|
||||
scriptAsset.Get()->m_scriptBuffer.insert(scriptAsset.Get()->m_scriptBuffer.begin(), script.begin(), script.end());
|
||||
EBUS_EVENT(Data::AssetManagerBus, OnAssetReady, scriptAsset);
|
||||
|
||||
m_app.Tick();
|
||||
m_app.TickSystem(); // flush assets etc.
|
||||
|
||||
return scriptAsset;
|
||||
}
|
||||
|
||||
static ScriptComponent* BuildGameEntity(const Data::Asset<ScriptAsset>& scriptAsset, Entity& gameEntity)
|
||||
{
|
||||
// We first setup the ScriptEditorComponent.
|
||||
// After a script asset is loaded the ScriptEditorComponent builds the properties table.
|
||||
// BuildGameEntity() hands off the properties table to the game runtime ScriptComponent.
|
||||
Entity editorEntity;
|
||||
auto* scriptEditorComponent = editorEntity.CreateComponent<AzToolsFramework::Components::ScriptEditorComponent>();
|
||||
scriptEditorComponent->SetScript(scriptAsset);
|
||||
editorEntity.Init();
|
||||
editorEntity.Activate();
|
||||
|
||||
scriptEditorComponent->BuildGameEntity(&gameEntity);
|
||||
|
||||
auto* scriptComponent = gameEntity.FindComponent<ScriptComponent>();
|
||||
return scriptComponent;
|
||||
}
|
||||
|
||||
static void OverwriteScriptBuffer(Data::Asset<ScriptAsset> scriptAsset, AZStd::string newScript)
|
||||
{
|
||||
scriptAsset.Get()->m_scriptBuffer.insert(scriptAsset.Get()->m_scriptBuffer.begin(), newScript.begin(), newScript.end());
|
||||
}
|
||||
|
||||
ComponentApplication m_app;
|
||||
ScriptContext* m_scriptContext = nullptr;
|
||||
BehaviorContext* m_behaviorContext = nullptr;
|
||||
SerializeContext* m_serializeContext = nullptr;
|
||||
};
|
||||
|
||||
|
||||
TEST_F(ScriptComponentTest, ScriptInstancesCanReadButDontModifySourceTable)
|
||||
{
|
||||
// make sure script instances don't can read only share data, but don't modify the source table
|
||||
const AZStd::string script = "test = {\
|
||||
--[[test with no properties table as this should work too!]]\
|
||||
state = {\
|
||||
mysubstate = {\
|
||||
mysubvalue = 2,\
|
||||
},\
|
||||
myvalue = 0,\
|
||||
},\
|
||||
}\
|
||||
function test:OnActivate()\
|
||||
self.state.mysubstate.mysubvalue = 5\
|
||||
end\
|
||||
return test;";
|
||||
|
||||
Data::Asset<ScriptAsset> scriptAsset = CreateAndLoadScriptAsset(script);
|
||||
|
||||
auto* entity1 = aznew Entity();
|
||||
entity1->CreateComponent<ScriptComponent>()->SetScript(scriptAsset);
|
||||
|
||||
entity1->Init();
|
||||
entity1->Activate();
|
||||
|
||||
auto* entity2 = aznew Entity();
|
||||
entity2->CreateComponent<ScriptComponent>()->SetScript(scriptAsset);
|
||||
|
||||
entity2->Init();
|
||||
entity2->Activate();
|
||||
|
||||
m_behaviorContext->Property("globalMySubValue", BehaviorValueProperty(&mySubValue));
|
||||
m_scriptContext->Execute("globalMySubValue = test.state.mysubstate.mysubvalue", "Read my subvalue");
|
||||
AZ_TEST_ASSERT(mySubValue == 2); // we should not have changed test. table but the instance table of each component.
|
||||
|
||||
delete entity1;
|
||||
delete entity2;
|
||||
}
|
||||
|
||||
|
||||
TEST_F(ScriptComponentTest, ScriptReloads)
|
||||
{
|
||||
// Test script reload
|
||||
m_behaviorContext->Property("myReloadValue", BehaviorValueProperty(&myReloadValue));
|
||||
const AZStd::string script1 ="local testReload = {}\
|
||||
function testReload:OnActivate()\
|
||||
myReloadValue = 1\
|
||||
end\
|
||||
function testReload:OnDeactivate()\
|
||||
myReloadValue = 0\
|
||||
end\
|
||||
return testReload;";
|
||||
Data::Asset<ScriptAsset> scriptAsset1 = CreateAndLoadScriptAsset(script1);
|
||||
|
||||
auto* entity = aznew Entity();
|
||||
entity->CreateComponent<ScriptComponent>()->SetScript(scriptAsset1);
|
||||
|
||||
entity->Init();
|
||||
entity->Activate();
|
||||
|
||||
// test value, it should set during activation of the first script
|
||||
AZ_TEST_ASSERT(myReloadValue == 1);
|
||||
|
||||
const AZStd::string script2 ="local testReload = {}\
|
||||
function testReload:OnActivate()\
|
||||
myReloadValue = 5\
|
||||
end\
|
||||
return testReload";
|
||||
|
||||
// modify the asset
|
||||
Data::Asset<ScriptAsset> scriptAsset2(aznew ScriptAsset(scriptAsset1.GetId()), AZ::Data::AssetLoadBehavior::Default);
|
||||
OverwriteScriptBuffer(scriptAsset2, script2);
|
||||
|
||||
// When reloading script assets from files, ScriptSystemComponent would clear old script caches automatically in the
|
||||
// function `ScriptSystemComponent::LoadAssetData()`. But here we are changing script directly in memory, therefore we
|
||||
// need to clear old cache manually.
|
||||
AZ::ScriptSystemRequestBus::Broadcast(&AZ::ScriptSystemRequestBus::Events::ClearAssetReferences, scriptAsset1.GetId());
|
||||
|
||||
// trigger reload
|
||||
Data::AssetManager::Instance().ReloadAssetFromData(scriptAsset2);
|
||||
|
||||
// ReloadAssetFromData is (now) a queued event
|
||||
// Need to tick subsystems here to receive reload event.
|
||||
m_app.Tick();
|
||||
m_app.TickSystem();
|
||||
|
||||
// test value with the reloaded value
|
||||
EXPECT_EQ(5, myReloadValue);
|
||||
|
||||
delete entity;
|
||||
}
|
||||
|
||||
TEST_F(ScriptComponentTest, LuaPropertiesAreDiscovered)
|
||||
{
|
||||
const AZStd::string script = "local test = {\
|
||||
Properties = {\
|
||||
myNum = { default = 2 },\
|
||||
},\
|
||||
}\
|
||||
function test:OnActivate()\
|
||||
self.Properties.myNum = 5\
|
||||
end\
|
||||
return test";
|
||||
|
||||
const Data::Asset<ScriptAsset> scriptAsset = CreateAndLoadScriptAsset(script);
|
||||
Entity editorEntity, gameEntity;
|
||||
auto* scriptComponent = BuildGameEntity(scriptAsset, gameEntity);
|
||||
|
||||
EXPECT_NE(scriptComponent->GetScriptProperty("myNum"), nullptr);
|
||||
}
|
||||
} // namespace UnitTest
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Asset/AssetManagerComponent.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Script/ScriptAsset.h>
|
||||
#include <AzCore/Script/ScriptSystemComponent.h>
|
||||
#include <AzCore/Script/ScriptContext.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AzToolsFramework/ToolsComponents/ScriptEditorComponent.h>
|
||||
|
||||
#include "EntityTestbed.h"
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
using namespace AZ;
|
||||
using namespace AzFramework;
|
||||
|
||||
class EntityScriptTest
|
||||
: public EntityTestbed
|
||||
{
|
||||
public:
|
||||
|
||||
ScriptContext* m_scriptContext;
|
||||
|
||||
~EntityScriptTest()
|
||||
{
|
||||
}
|
||||
|
||||
void OnDestroy() override
|
||||
{
|
||||
delete m_scriptContext;
|
||||
m_scriptContext = nullptr;
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
int argc = 0;
|
||||
char* argv = nullptr;
|
||||
Run(argc, &argv);
|
||||
}
|
||||
|
||||
void OnReflect(AZ::SerializeContext& context, AZ::Entity& systemEntity) override
|
||||
{
|
||||
(void)context;
|
||||
(void)systemEntity;
|
||||
}
|
||||
|
||||
void OnSetup() override
|
||||
{
|
||||
m_scriptContext = aznew AZ::ScriptContext();
|
||||
|
||||
auto* catalogBus = AZ::Data::AssetCatalogRequestBus::FindFirstHandler();
|
||||
if (catalogBus)
|
||||
{
|
||||
// Register asset types the asset DB should query our catalog for.
|
||||
catalogBus->AddAssetType(AZ::AzTypeInfo<AZ::ScriptAsset>::Uuid());
|
||||
|
||||
// Build the catalog (scan).
|
||||
catalogBus->AddExtension(".lua");
|
||||
}
|
||||
}
|
||||
|
||||
void OnEntityAdded(AZ::Entity& entity) override
|
||||
{
|
||||
// Add your components.
|
||||
entity.CreateComponent<AzToolsFramework::Components::ScriptEditorComponent>();
|
||||
entity.Activate();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(EntityScriptTest, DISABLED_Test)
|
||||
{
|
||||
run();
|
||||
}
|
||||
} // namespace UnitTest
|
||||
@@ -275,6 +275,7 @@ namespace UnitTest
|
||||
TEST_F(SliceUpgradeTest, IntermmediateDataTypeChange)
|
||||
{
|
||||
TestDataA::Reflect(m_serializeContext.get());
|
||||
AzToolsFramework::Components::EditorComponentBase::Reflect(m_serializeContext.get());
|
||||
TestComponentA_V0::Reflect(m_serializeContext.get());
|
||||
AZ::Entity* entityA = aznew AZ::Entity();
|
||||
TestComponentA_V0* component = entityA->CreateComponent<TestComponentA_V0>();
|
||||
@@ -320,6 +321,7 @@ namespace UnitTest
|
||||
TEST_F(SliceUpgradeTest, TypeChangeInUnorderedMap)
|
||||
{
|
||||
TestDataB_V0::Reflect(m_serializeContext.get());
|
||||
AzToolsFramework::Components::EditorComponentBase::Reflect(m_serializeContext.get());
|
||||
TestComponentB_V0::Reflect(m_serializeContext.get());
|
||||
AZ::Entity* entityA = aznew AZ::Entity();
|
||||
TestComponentB_V0* componentB = entityA->CreateComponent<TestComponentB_V0>();
|
||||
@@ -395,6 +397,7 @@ namespace UnitTest
|
||||
TEST_F(SliceUpgradeTest, TypeChangeInVector)
|
||||
{
|
||||
TestDataB_V0::Reflect(m_serializeContext.get());
|
||||
AzToolsFramework::Components::EditorComponentBase::Reflect(m_serializeContext.get());
|
||||
TestComponentC_V0::Reflect(m_serializeContext.get());
|
||||
AZ::Entity* entityA = aznew AZ::Entity();
|
||||
TestComponentC_V0* componentC = entityA->CreateComponent<TestComponentC_V0>();
|
||||
@@ -452,6 +455,7 @@ namespace UnitTest
|
||||
TEST_F(SliceUpgradeTest, UpgradeSkipVersion_TypeChange_FloatToDouble)
|
||||
{
|
||||
// 1. Create an entity with a TestComponentE_V4 with the default value for m_data
|
||||
AzToolsFramework::Components::EditorComponentBase::Reflect(m_serializeContext.get());
|
||||
TestComponentE_V4::Reflect(m_serializeContext.get());
|
||||
AZ::Entity* testEntity = aznew AZ::Entity();
|
||||
TestComponentE_V4* componentEV4 = testEntity->CreateComponent<TestComponentE_V4>();
|
||||
@@ -563,6 +567,7 @@ namespace UnitTest
|
||||
SliceUpgradeTestAsset::Reflect(m_serializeContext.get());
|
||||
AzFramework::SimpleAssetReference<SliceUpgradeTestAsset>::Register(*m_serializeContext.get());
|
||||
|
||||
AzToolsFramework::Components::EditorComponentBase::Reflect(m_serializeContext.get());
|
||||
TestComponentD_V1::Reflect(m_serializeContext.get());
|
||||
AZ::Entity* entity = aznew AZ::Entity();
|
||||
entity->CreateComponent<TestComponentD_V1>();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,6 @@ namespace UnitTest
|
||||
|
||||
class ThumbnailerTests
|
||||
: public ::testing::Test
|
||||
, public TraceBusRedirector
|
||||
{
|
||||
protected:
|
||||
void SetUp() override
|
||||
@@ -31,8 +30,6 @@ namespace UnitTest
|
||||
// was running, because the environment wasn't setup for it to save these settings.
|
||||
AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize);
|
||||
|
||||
TraceBusRedirector::BusConnect();
|
||||
|
||||
AZStd::string entityName("test");
|
||||
AZ::EntityId testEntityId;
|
||||
AzToolsFramework::EditorEntityContextRequestBus::BroadcastResult(
|
||||
@@ -61,8 +58,6 @@ namespace UnitTest
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
TraceBusRedirector::BusDisconnect();
|
||||
|
||||
AzToolsFramework::EditorEntityContextRequestBus::Broadcast(
|
||||
&AzToolsFramework::EditorEntityContextRequestBus::Events::DestroyEditorEntity,
|
||||
m_testEntity->GetId());
|
||||
|
||||
@@ -248,8 +248,6 @@ namespace AzToolsFramework
|
||||
|
||||
m_app.Stop();
|
||||
AZ::Debug::TraceMessageBus::Handler::BusDisconnect();
|
||||
|
||||
|
||||
}
|
||||
|
||||
// A few tests save a layer and want to check the state after saving.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -127,7 +127,6 @@ namespace UnitTest
|
||||
void SetUpEditorFixtureImpl() override
|
||||
{
|
||||
m_editor = new EntityPropertyEditor();
|
||||
m_editorActions.Connect();
|
||||
|
||||
m_entity1 = CreateDefaultEditorEntity("Entity1");
|
||||
m_entity2 = CreateDefaultEditorEntity("Entity2");
|
||||
@@ -137,13 +136,11 @@ namespace UnitTest
|
||||
|
||||
void TearDownEditorFixtureImpl() override
|
||||
{
|
||||
m_editorActions.Disconnect();
|
||||
delete m_editor;
|
||||
}
|
||||
|
||||
public:
|
||||
EntityPropertyEditor* m_editor;
|
||||
TestEditorActions m_editorActions;
|
||||
EntityIdList m_entityIds;
|
||||
AZ::EntityId m_entity1;
|
||||
AZ::EntityId m_entity2;
|
||||
@@ -234,8 +231,6 @@ namespace UnitTest
|
||||
entities.insert(m_levelEntity);
|
||||
m_levelEditor->SetOverrideEntityIds(entities);
|
||||
|
||||
m_editorActions.Connect();
|
||||
|
||||
// Connect to the EditorRequestBus so that we can intercept calls checking whether or not a level is currently open.
|
||||
AzToolsFramework::EditorRequestBus::Handler::BusConnect();
|
||||
}
|
||||
@@ -244,7 +239,6 @@ namespace UnitTest
|
||||
{
|
||||
AzToolsFramework::EditorRequestBus::Handler::BusDisconnect();
|
||||
|
||||
m_editorActions.Disconnect();
|
||||
delete m_levelEditor;
|
||||
}
|
||||
|
||||
@@ -258,7 +252,6 @@ namespace UnitTest
|
||||
|
||||
public:
|
||||
EntityPropertyEditor* m_levelEditor;
|
||||
TestEditorActions m_editorActions;
|
||||
AZ::EntityId m_levelEntity;
|
||||
bool m_levelOpen = false;
|
||||
};
|
||||
|
||||
@@ -85,19 +85,8 @@ namespace UnitTest
|
||||
}
|
||||
|
||||
class ViewportUiWidgetAssertFixture
|
||||
: public ::testing::Test
|
||||
, UnitTest::TraceBusRedirector
|
||||
{
|
||||
public:
|
||||
void SetUp() override
|
||||
{
|
||||
AZ::Debug::TraceMessageBus::Handler::BusConnect();
|
||||
}
|
||||
void TearDown() override
|
||||
{
|
||||
AZ::Debug::TraceMessageBus::Handler::BusDisconnect();
|
||||
}
|
||||
};
|
||||
: public ScopedAllocatorSetupFixture
|
||||
{};
|
||||
|
||||
TEST_F(ViewportUiWidgetAssertFixture, RegisterUpdateCallbackDoesNotRegisterFunctionForNotAddedObject)
|
||||
{
|
||||
|
||||
@@ -11,35 +11,37 @@ set(FILES
|
||||
AssetFileInfoListComparison.cpp
|
||||
AssetSeedManager.cpp
|
||||
AssetSystemMocks.h
|
||||
ComponentModeTests.cpp
|
||||
ComponentModeTestDoubles.h
|
||||
ComponentAdapterTests.cpp
|
||||
ComponentAddRemove.cpp
|
||||
ComponentModeTestDoubles.cpp
|
||||
ComponentModeTestFixture.h
|
||||
ComponentModeTestDoubles.h
|
||||
ComponentModeTestFixture.cpp
|
||||
ComponentModeTestFixture.h
|
||||
ComponentModeTests.cpp
|
||||
EditorTransformComponentSelectionTests.cpp
|
||||
EditorVertexSelectionTests.cpp
|
||||
Entity/EditorEntityContextComponentTests.cpp
|
||||
Entity/EditorEntityHelpersTests.cpp
|
||||
Entity/EditorEntitySearchComponentTests.cpp
|
||||
Entity/EditorEntitySelectionTests.cpp
|
||||
EntityIdQLabelTests.cpp
|
||||
EntityInspectorTests.cpp
|
||||
EntityOwnershipService/EntityOwnershipServiceTestFixture.cpp
|
||||
EntityOwnershipService/EntityOwnershipServiceTestFixture.h
|
||||
EntityOwnershipService/SliceEditorEntityOwnershipTests.cpp
|
||||
EntityOwnershipService/SliceEntityOwnershipTests.cpp
|
||||
EntityTestbed.h
|
||||
FileFunc.cpp
|
||||
FingerprintingTests.cpp
|
||||
GenericComponentWrapperTest.cpp
|
||||
InstanceDataHierarchy.cpp
|
||||
IntegerPrimtitiveTestConfig.h
|
||||
LogLines.cpp
|
||||
ManipulatorBoundsTests.cpp
|
||||
ManipulatorCoreTests.cpp
|
||||
ManipulatorViewTests.cpp
|
||||
PlatformAddressedAssetCatalogTests.cpp
|
||||
PropertyIntCtrlCommonTests.h
|
||||
IntegerPrimtitiveTestConfig.h
|
||||
QtWidgetLimitsTests.cpp
|
||||
PropertyIntSliderCtrlTests.cpp
|
||||
PropertyIntSpinCtrlTests.cpp
|
||||
PropertyTreeEditorTests.cpp
|
||||
PythonBindingTests.cpp
|
||||
Slice.cpp
|
||||
SliceUpgradeTestsData.h
|
||||
SliceUpgradeTests.cpp
|
||||
SpinBoxTests.cpp
|
||||
ThumbnailerTests.cpp
|
||||
UndoStack.cpp
|
||||
PerforceComponentTests.cpp
|
||||
PlatformAddressedAssetCatalogTests.cpp
|
||||
Prefab/Benchmark/PrefabBenchmarkFixture.cpp
|
||||
Prefab/Benchmark/PrefabBenchmarkFixture.h
|
||||
Prefab/Benchmark/PrefabCreateBenchmarks.cpp
|
||||
@@ -47,13 +49,13 @@ set(FILES
|
||||
Prefab/Benchmark/PrefabLoadBenchmarks.cpp
|
||||
Prefab/Benchmark/PrefabUpdateInstancesBenchmarks.cpp
|
||||
Prefab/Benchmark/SpawnableCreateBenchmarks.cpp
|
||||
Prefab/Spawnable/SpawnableMetaDataTests.cpp
|
||||
Prefab/MockPrefabFileIOActionValidator.cpp
|
||||
Prefab/MockPrefabFileIOActionValidator.h
|
||||
Prefab/PrefabDuplicateTests.cpp
|
||||
Prefab/PrefabEntityAliasTests.cpp
|
||||
Prefab/PrefabInstanceToTemplatePropagatorTests.cpp
|
||||
Prefab/PrefabInstantiateTests.cpp
|
||||
Prefab/PrefabInstantiateTests.cpp
|
||||
Prefab/PrefabLoadTemplateTests.cpp
|
||||
Prefab/PrefabTestComponent.cpp
|
||||
Prefab/PrefabTestComponent.h
|
||||
@@ -67,37 +69,50 @@ set(FILES
|
||||
Prefab/PrefabTestFixture.h
|
||||
Prefab/PrefabTestUndoFixture.cpp
|
||||
Prefab/PrefabTestUndoFixture.h
|
||||
Prefab/PrefabTestUtils.h
|
||||
Prefab/PrefabUndoLinkTests.cpp
|
||||
Prefab/PrefabUndoTests.cpp
|
||||
Prefab/PrefabTestUtils.h
|
||||
Prefab/PrefabUpdateInstancesTests.cpp
|
||||
Prefab/PrefabUpdateTemplateTests.cpp
|
||||
Prefab/PrefabUpdateWithPatchesTests.cpp
|
||||
Prefab/PrefabInstantiateTests.cpp
|
||||
Prefab/Spawnable/SpawnableMetaDataTests.cpp
|
||||
Prefab/SpawnableCreateTests.cpp
|
||||
Prefab/SpawnableRemoveEditorInfoTests.cpp
|
||||
Prefab/SpawnableRemoveEditorInfoTestFixture.cpp
|
||||
Prefab/SpawnableRemoveEditorInfoTestFixture.h
|
||||
Prefab/SpawnableSortEntitiesTests.cpp
|
||||
Prefab/SpawnableRemoveEditorInfoTests.cpp
|
||||
Prefab/SpawnableSortEntitiesTestFixture.cpp
|
||||
Prefab/SpawnableSortEntitiesTestFixture.h
|
||||
Entity/EditorEntityContextComponentTests.cpp
|
||||
Entity/EditorEntityHelpersTests.cpp
|
||||
Entity/EditorEntitySearchComponentTests.cpp
|
||||
Entity/EditorEntitySelectionTests.cpp
|
||||
SliceStabilityTests/SliceStabilityTestFramework.h
|
||||
SliceStabilityTests/SliceStabilityTestFramework.cpp
|
||||
Prefab/SpawnableSortEntitiesTests.cpp
|
||||
PropertyIntCtrlCommonTests.h
|
||||
PropertyIntSliderCtrlTests.cpp
|
||||
PropertyIntSpinCtrlTests.cpp
|
||||
PropertyTreeEditorTests.cpp
|
||||
PythonBindingTests.cpp
|
||||
QtWidgetLimitsTests.cpp
|
||||
Script/ScriptComponentTests.cpp
|
||||
Script/ScriptEntityTests.cpp
|
||||
Slice.cpp
|
||||
Slices.cpp
|
||||
SliceStabilityTests/SliceStabilityCreateTests.cpp
|
||||
SliceStabilityTests/SliceStabilityPushTests.cpp
|
||||
SliceStabilityTests/SliceStabilityReParentTests.cpp
|
||||
SliceStabilityTests/SliceStabilityTestFramework.cpp
|
||||
SliceStabilityTests/SliceStabilityTestFramework.h
|
||||
SliceUpgradeTests.cpp
|
||||
SliceUpgradeTestsData.h
|
||||
SpinBoxTests.cpp
|
||||
SQLiteConnectionTests.cpp
|
||||
ThumbnailerTests.cpp
|
||||
ToolsComponents/EditorLayerComponentTests.cpp
|
||||
ToolsComponents/EditorTransformComponentTests.cpp
|
||||
TransformComponent.cpp
|
||||
UI/EntityPropertyEditorTests.cpp
|
||||
UndoStack.cpp
|
||||
Viewport/ClusterTests.cpp
|
||||
Viewport/ViewportScreenTests.cpp
|
||||
Viewport/ViewportUiClusterTests.cpp
|
||||
Viewport/ViewportUiDisplayTests.cpp
|
||||
Viewport/ViewportUiManagerTests.cpp
|
||||
Viewport/ClusterTests.cpp
|
||||
Viewport/ViewportUiWidgetManagerTests.cpp
|
||||
Visibility/EditorVisibilityTests.cpp
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user