Integrating latest 47acbe8
This commit is contained in:
@@ -128,7 +128,11 @@ namespace UnitTest
|
||||
QTemporaryDir m_tempDir {QDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation)).filePath("ArchiveTests-")};
|
||||
};
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS
|
||||
TEST_F(ArchiveTest, DISABLED_CreateArchiveBlocking_FilesAtThreeDepths_ArchiveCreated)
|
||||
#else
|
||||
TEST_F(ArchiveTest, CreateArchiveBlocking_FilesAtThreeDepths_ArchiveCreated)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS
|
||||
{
|
||||
EXPECT_TRUE(m_tempDir.isValid());
|
||||
CreateArchiveFolder();
|
||||
@@ -138,7 +142,11 @@ namespace UnitTest
|
||||
EXPECT_EQ(createResult, true);
|
||||
}
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS
|
||||
TEST_F(ArchiveTest, DISABLED_ListFilesInArchiveBlocking_FilesAtThreeDepths_FilesFound)
|
||||
#else
|
||||
TEST_F(ArchiveTest, ListFilesInArchiveBlocking_FilesAtThreeDepths_FilesFound)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS
|
||||
{
|
||||
EXPECT_TRUE(m_tempDir.isValid());
|
||||
CreateArchiveFolder();
|
||||
@@ -152,7 +160,11 @@ namespace UnitTest
|
||||
EXPECT_EQ(fileList.size(), 6);
|
||||
}
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS
|
||||
TEST_F(ArchiveTest, DISABLED_CreateDeltaCatalog_AssetsNotRegistered_Failure)
|
||||
#else
|
||||
TEST_F(ArchiveTest, CreateDeltaCatalog_AssetsNotRegistered_Failure)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS
|
||||
{
|
||||
QStringList fileList = CreateArchiveFileList();
|
||||
|
||||
@@ -169,7 +181,11 @@ namespace UnitTest
|
||||
EXPECT_EQ(catalogCreated, false);
|
||||
}
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS
|
||||
TEST_F(ArchiveTest, DISABLED_CreateDeltaCatalog_ArchiveWithoutCatalogAssetsRegistered_Success)
|
||||
#else
|
||||
TEST_F(ArchiveTest, CreateDeltaCatalog_ArchiveWithoutCatalogAssetsRegistered_Success)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS
|
||||
{
|
||||
QStringList fileList = CreateArchiveFileList();
|
||||
|
||||
|
||||
@@ -69,9 +69,6 @@ namespace //anonymous
|
||||
"executable_name": "DummyProjectLauncher",
|
||||
"modules" : [],
|
||||
"project_id": "{91FB81A1-072C-4A80-8FCC-7E2C4C767B4D}",
|
||||
|
||||
"xenia_settings" : {
|
||||
},
|
||||
|
||||
"android_settings" : {
|
||||
"package_name" : "com.lumberyard.yourgame",
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution(the "License").All use of this software is governed by the License,
|
||||
* or , if provided, by the license below or the license accompanying this file.Do not
|
||||
*remove or modify any license notices.This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#if defined(HAVE_BENCHMARK)
|
||||
|
||||
#include <Prefab/Benchmark/PrefabBenchmarkFixture.h>
|
||||
|
||||
#include <AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h>
|
||||
|
||||
namespace Benchmark
|
||||
{
|
||||
using BM_SpawnableCreate = BM_Prefab;
|
||||
using namespace AzToolsFramework::Prefab;
|
||||
|
||||
BENCHMARK_DEFINE_F(BM_SpawnableCreate, CreateSpawnable_SingleEntityInstance)(::benchmark::State& state)
|
||||
{
|
||||
const unsigned int numSpawnables = state.range();
|
||||
|
||||
AZStd::unique_ptr<Instance> instance(m_prefabSystemComponent->CreatePrefab(
|
||||
{ CreateEntity("Entity1") },
|
||||
{},
|
||||
m_pathString));
|
||||
|
||||
auto& prefabDom = m_prefabSystemComponent->FindTemplateDom(instance->GetTemplateId());
|
||||
for (auto _ : state)
|
||||
{
|
||||
state.PauseTiming();
|
||||
|
||||
auto spawnable = ::AzToolsFramework::Prefab::SpawnableUtils::CreateSpawnable(prefabDom);
|
||||
|
||||
state.ResumeTiming();
|
||||
}
|
||||
|
||||
state.SetComplexityN(numSpawnables);
|
||||
}
|
||||
BENCHMARK_REGISTER_F(BM_SpawnableCreate, CreateSpawnable_SingleEntityInstance)
|
||||
->RangeMultiplier(10)
|
||||
->Range(100, 10000)
|
||||
->Unit(benchmark::kMillisecond)
|
||||
->Complexity();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Prefab/PrefabTestDomUtils.h>
|
||||
#include <Prefab/PrefabTestComponent.h>
|
||||
#include <Prefab/PrefabTestFixture.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
using PrefabEntityAliasTests = PrefabTestFixture;
|
||||
|
||||
TEST_F(PrefabEntityAliasTests, PrefabEntityAlias_ReferenceEntityWithinSameInstance_ReferencePersists)
|
||||
{
|
||||
// Make a new entity with a test component
|
||||
AZ::Entity* newEntity = CreateEntity("New Entity", false);
|
||||
PrefabTestComponent* newComponent = newEntity->CreateComponent<PrefabTestComponent>();
|
||||
ASSERT_TRUE(newComponent);
|
||||
|
||||
// Generate a second entity that will be referenced by the first
|
||||
AZ::Entity* referencedEntity = CreateEntity("Referenced Entity");
|
||||
newComponent->m_entityIdProperty = referencedEntity->GetId();
|
||||
|
||||
// Place both entities in the same prefab
|
||||
AZStd::unique_ptr<Instance> newInstance =
|
||||
m_prefabSystemComponent->CreatePrefab({ newEntity, referencedEntity }, {}, "test/path");
|
||||
|
||||
ASSERT_TRUE(newInstance);
|
||||
|
||||
// Grab the alias of both entities so they can be found in a new instantiation
|
||||
EntityAliasOptionalReference newEntityAliasRef = newInstance->GetEntityAlias(newEntity->GetId());
|
||||
ASSERT_TRUE(newEntityAliasRef);
|
||||
|
||||
EntityAliasOptionalReference referencedEntityAliasRef = newInstance->GetEntityAlias(referencedEntity->GetId());
|
||||
ASSERT_TRUE(referencedEntityAliasRef);
|
||||
|
||||
EntityAlias newEntityAlias = newEntityAliasRef.value();
|
||||
EntityAlias referencedEntityAlias = referencedEntityAliasRef.value();
|
||||
|
||||
// A new instance should maintain the entity reference while also having unique entity ids
|
||||
AZStd::unique_ptr<Instance> secondInstance =
|
||||
m_prefabSystemComponent->InstantiatePrefab(newInstance->GetTemplateId());
|
||||
|
||||
// Activate the entities so that we can find them via the component application bus
|
||||
secondInstance->InitializeEntities();
|
||||
secondInstance->ActivateEntities();
|
||||
|
||||
AZ::Entity* secondNewEntity = nullptr;
|
||||
|
||||
AZ::ComponentApplicationBus::BroadcastResult(secondNewEntity,
|
||||
&AZ::ComponentApplicationBus::Events::FindEntity, secondInstance->GetEntityId(newEntityAlias));
|
||||
|
||||
ASSERT_TRUE(secondNewEntity);
|
||||
|
||||
PrefabTestComponent* secondComponent = secondNewEntity->FindComponent<PrefabTestComponent>();
|
||||
ASSERT_TRUE(secondComponent);
|
||||
|
||||
// Validate that the entity reference is preserved in the second instance
|
||||
ASSERT_TRUE(secondComponent->m_entityIdProperty.IsValid());
|
||||
ASSERT_EQ(secondComponent->m_entityIdProperty, secondInstance->GetEntityId(referencedEntityAlias));
|
||||
}
|
||||
|
||||
TEST_F(PrefabEntityAliasTests, PrefabEntityAlias_ReferenceNotInSameHierarchy_ReferenceGoesToNull)
|
||||
{
|
||||
// Make a new entity with a test component
|
||||
AZ::Entity* newEntity = CreateEntity("New Entity", false);
|
||||
PrefabTestComponent* newComponent = newEntity->CreateComponent<PrefabTestComponent>();
|
||||
ASSERT_TRUE(newComponent);
|
||||
|
||||
// Generate a second entity that will be referenced by the first
|
||||
// however we won't add both to the same prefab hierarchy
|
||||
AZ::Entity* referencedEntity = CreateEntity("Referenced Entity");
|
||||
newComponent->m_entityIdProperty = referencedEntity->GetId();
|
||||
|
||||
AZStd::unique_ptr<Instance> unrelatedInstance =
|
||||
m_prefabSystemComponent->CreatePrefab({ referencedEntity }, {}, "test/path/0");
|
||||
|
||||
AZStd::unique_ptr<Instance> firstInstance =
|
||||
m_prefabSystemComponent->CreatePrefab({ newEntity }, {}, "test/path/1");
|
||||
|
||||
ASSERT_TRUE(firstInstance);
|
||||
|
||||
// Grab the alias of newEntity so it can be found in a new instantiation
|
||||
EntityAliasOptionalReference newEntityAliasRef = firstInstance->GetEntityAlias(newEntity->GetId());
|
||||
ASSERT_TRUE(newEntityAliasRef);
|
||||
|
||||
EntityAlias newEntityAlias = newEntityAliasRef.value();
|
||||
|
||||
// On instantiation the referenced entity should be invalid
|
||||
AZStd::unique_ptr<Instance> secondInstance =
|
||||
m_prefabSystemComponent->InstantiatePrefab(firstInstance->GetTemplateId());
|
||||
|
||||
// Activate the entities so that we can find them via the component application bus
|
||||
secondInstance->InitializeEntities();
|
||||
secondInstance->ActivateEntities();
|
||||
|
||||
AZ::Entity* secondNewEntity = nullptr;
|
||||
|
||||
AZ::ComponentApplicationBus::BroadcastResult(secondNewEntity,
|
||||
&AZ::ComponentApplicationBus::Events::FindEntity, secondInstance->GetEntityId(newEntityAlias));
|
||||
|
||||
ASSERT_TRUE(secondNewEntity);
|
||||
|
||||
PrefabTestComponent* secondComponent = secondNewEntity->FindComponent<PrefabTestComponent>();
|
||||
ASSERT_TRUE(secondComponent);
|
||||
|
||||
ASSERT_FALSE(secondComponent->m_entityIdProperty.IsValid());
|
||||
}
|
||||
|
||||
TEST_F(PrefabEntityAliasTests, PrefabEntityAlias_ReferenceEntityFoundInNestedInstance_ReferencePersists)
|
||||
{
|
||||
// Make a new entity with a test component
|
||||
AZ::Entity* newEntity = CreateEntity("New Entity", false);
|
||||
PrefabTestComponent* newComponent = newEntity->CreateComponent<PrefabTestComponent>();
|
||||
ASSERT_TRUE(newComponent);
|
||||
|
||||
// Generate a second entity that will be referenced by the first
|
||||
AZ::Entity* referencedEntity = CreateEntity("Referenced Entity");
|
||||
|
||||
newComponent->m_entityIdProperty = referencedEntity->GetId();
|
||||
|
||||
// Build out a prefab holding the referenced entity
|
||||
AZStd::unique_ptr<Instance> nestedInstance =
|
||||
m_prefabSystemComponent->CreatePrefab({ referencedEntity }, {}, "Test/Path/0");
|
||||
|
||||
// Grab the alias of the nested instance
|
||||
EntityAliasOptionalReference referencedEntityAliasRef =
|
||||
nestedInstance->GetEntityAlias(referencedEntity->GetId());
|
||||
ASSERT_TRUE(referencedEntityAliasRef);
|
||||
|
||||
EntityAlias referencedEntityAlias = referencedEntityAliasRef.value();
|
||||
|
||||
TemplateId nestedTemplateId = nestedInstance->GetTemplateId();
|
||||
|
||||
// Create our root instance and nest our first instance under it
|
||||
AZStd::unique_ptr<Instance> rootInstance =
|
||||
m_prefabSystemComponent->CreatePrefab({ newEntity },
|
||||
PrefabTestUtils::MakeInstanceList(AZStd::move(nestedInstance)), "Test/Path/1");
|
||||
|
||||
// Acquire the alias name of our entity so we can look it up in future instances
|
||||
EntityAliasOptionalReference newEntityAliasRef =
|
||||
rootInstance->GetEntityAlias(newEntity->GetId());
|
||||
ASSERT_TRUE(newEntityAliasRef);
|
||||
|
||||
EntityAlias newEntityAlias = newEntityAliasRef.value();
|
||||
|
||||
// Acquire the nested instance alias so we can look it up in future instances
|
||||
AZStd::vector<InstanceAlias> nestedInstanceAliases = rootInstance->GetNestedInstanceAliases(nestedTemplateId);
|
||||
ASSERT_EQ(nestedInstanceAliases.size(), 1);
|
||||
|
||||
InstanceAlias nestedAlias = nestedInstanceAliases[0];
|
||||
|
||||
// Make a new instance of root
|
||||
// Entity references should be preserved among its unique entities
|
||||
AZStd::unique_ptr<Instance> secondRootInstance =
|
||||
m_prefabSystemComponent->InstantiatePrefab(rootInstance->GetTemplateId());
|
||||
|
||||
ASSERT_TRUE(secondRootInstance);
|
||||
|
||||
// Activate the entities so that we can find them via the component application bus
|
||||
secondRootInstance->InitializeNestedEntities();
|
||||
secondRootInstance->ActivateNestedEntities();
|
||||
|
||||
// Find the new instances versions of the new and referenced entities using the aliases we saved
|
||||
AZ::EntityId secondNewEntityId = secondRootInstance->GetEntityId(newEntityAlias);
|
||||
|
||||
InstanceOptionalReference secondNestedInstance = secondRootInstance->FindNestedInstance(nestedAlias);
|
||||
ASSERT_TRUE(secondNestedInstance);
|
||||
|
||||
AZ::EntityId secondReferencedEntityId = secondNestedInstance->get().GetEntityId(referencedEntityAlias);
|
||||
|
||||
AZ::Entity* secondNewEntity = nullptr;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(secondNewEntity,
|
||||
&AZ::ComponentApplicationBus::Events::FindEntity, secondNewEntityId);
|
||||
|
||||
ASSERT_TRUE(secondNewEntity);
|
||||
|
||||
PrefabTestComponent* secondComponent = secondNewEntity->FindComponent<PrefabTestComponent>();
|
||||
ASSERT_TRUE(secondComponent);
|
||||
|
||||
EXPECT_TRUE(secondComponent->m_entityIdProperty.IsValid());
|
||||
EXPECT_EQ(secondComponent->m_entityIdProperty, secondReferencedEntityId);
|
||||
}
|
||||
|
||||
TEST_F(PrefabEntityAliasTests, PrefabEntityAlias_ReferenceEntityFoundInParentInstance_ReferencePersists)
|
||||
{
|
||||
// Make a new entity with a test component
|
||||
AZ::Entity* newEntity = CreateEntity("New Entity", false);
|
||||
PrefabTestComponent* newComponent = newEntity->CreateComponent<PrefabTestComponent>();
|
||||
ASSERT_TRUE(newComponent);
|
||||
|
||||
// Generate a second entity that will be referenced by the first
|
||||
AZ::Entity* referencedEntity = CreateEntity("Referenced Entity");
|
||||
|
||||
// Make our first instance to be nested under the prefab containing the entity we reference
|
||||
AZStd::unique_ptr<Instance> nestedInstance =
|
||||
m_prefabSystemComponent->CreatePrefab({ newEntity }, {}, "Test/Path/0");
|
||||
|
||||
// Save off the entity alias so we can find it in future instances
|
||||
EntityAliasOptionalReference newEntityAliasRef = nestedInstance->GetEntityAlias(newEntity->GetId());
|
||||
ASSERT_TRUE(newEntityAliasRef);
|
||||
|
||||
EntityAlias entityAlias = newEntityAliasRef.value();
|
||||
|
||||
TemplateId nestedTemplateId = nestedInstance->GetTemplateId();
|
||||
|
||||
// Make our root instance which contains the entity being referenced
|
||||
AZStd::unique_ptr<Instance> rootInstance =
|
||||
m_prefabSystemComponent->CreatePrefab({ referencedEntity },
|
||||
PrefabTestUtils::MakeInstanceList(AZStd::move(nestedInstance)), "Test/Path/1");
|
||||
|
||||
// Acquire the nested instance alias so we can look it up in future instances
|
||||
AZStd::vector<InstanceAlias> nestedInstanceAliases = rootInstance->GetNestedInstanceAliases(nestedTemplateId);
|
||||
ASSERT_EQ(nestedInstanceAliases.size(), 1);
|
||||
|
||||
InstanceAlias nestedAlias = nestedInstanceAliases[0];
|
||||
|
||||
// Save off the referenced entity alias
|
||||
EntityAliasOptionalReference referencedEntityAliasRef =
|
||||
rootInstance->GetEntityAlias(referencedEntity->GetId());
|
||||
|
||||
ASSERT_TRUE(referencedEntityAliasRef);
|
||||
|
||||
EntityAlias referencedEntityAlias = referencedEntityAliasRef.value();
|
||||
|
||||
// Capture the before and after for setting the reference property
|
||||
PrefabDom entityDomBeforeUpdate;
|
||||
m_instanceToTemplateInterface->GenerateDomForEntity(entityDomBeforeUpdate, *newEntity);
|
||||
|
||||
newComponent->m_entityIdProperty = referencedEntity->GetId();
|
||||
|
||||
PrefabDom entityDomAfterUpdate;
|
||||
m_instanceToTemplateInterface->GenerateDomForEntity(entityDomAfterUpdate, *newEntity);
|
||||
|
||||
PrefabDom patch;
|
||||
m_instanceToTemplateInterface->GeneratePatch(patch, entityDomBeforeUpdate, entityDomAfterUpdate);
|
||||
|
||||
// Patch the nested prefab to reference an entity in its parent
|
||||
m_instanceToTemplateInterface->PatchEntityInTemplate(patch, newEntity->GetId());
|
||||
|
||||
// Using the aliases we saved grab the updated entities so we can verify the entity reference is still preserved
|
||||
InstanceOptionalReference updatedNestedInstance = rootInstance->FindNestedInstance(nestedAlias);
|
||||
ASSERT_TRUE(updatedNestedInstance);
|
||||
|
||||
AZ::EntityId updatedNewEntityId = updatedNestedInstance->get().GetEntityId(entityAlias);
|
||||
AZ::Entity* updatedNewEntity = nullptr;
|
||||
|
||||
// Activate the entities so that we can find them via the component application bus
|
||||
rootInstance->InitializeNestedEntities();
|
||||
rootInstance->ActivateNestedEntities();
|
||||
|
||||
AZ::ComponentApplicationBus::BroadcastResult(updatedNewEntity,
|
||||
&AZ::ComponentApplicationBus::Events::FindEntity, updatedNewEntityId);
|
||||
|
||||
ASSERT_TRUE(updatedNewEntity);
|
||||
|
||||
PrefabTestComponent* updatedComponent = updatedNewEntity->FindComponent<PrefabTestComponent>();
|
||||
ASSERT_TRUE(updatedComponent);
|
||||
|
||||
AZ::EntityId updatedReferencedEntityId = rootInstance->GetEntityId(referencedEntityAlias);
|
||||
|
||||
EXPECT_TRUE(updatedComponent->m_entityIdProperty.IsValid());
|
||||
EXPECT_EQ(updatedComponent->m_entityIdProperty, updatedReferencedEntityId);
|
||||
}
|
||||
}
|
||||
+18
-19
@@ -38,6 +38,11 @@ namespace UnitTest
|
||||
AZStd::unique_ptr<Instance> firstInstance = m_prefabSystemComponent->CreatePrefab({ newEntity }, {}, "test/path");
|
||||
ASSERT_TRUE(firstInstance);
|
||||
|
||||
EntityAliasOptionalReference newEntityAliasReference = firstInstance->GetEntityAlias(entityId);
|
||||
ASSERT_TRUE(newEntityAliasReference);
|
||||
|
||||
EntityAlias newEntityAlias = newEntityAliasReference.value();
|
||||
|
||||
//get template id
|
||||
TemplateId templateId = firstInstance->GetTemplateId();
|
||||
|
||||
@@ -69,22 +74,14 @@ namespace UnitTest
|
||||
secondInstance->ActivateNestedEntities();
|
||||
|
||||
//get the entity id
|
||||
AZStd::vector<AZ::EntityId> entityIdVector;
|
||||
|
||||
secondInstance->GetEntityIds([&entityIdVector](const AZ::EntityId& entityId)
|
||||
{
|
||||
entityIdVector.push_back(entityId);
|
||||
return true;
|
||||
});
|
||||
|
||||
EXPECT_EQ(entityIdVector.size(), 1);
|
||||
AZStd::optional<AZ::EntityId> secondEntityId = entityIdVector[0];
|
||||
AZ::EntityId secondEntityId = secondInstance->GetEntityId(newEntityAlias);
|
||||
ASSERT_TRUE(secondEntityId.IsValid());
|
||||
|
||||
//verify template updated correctly
|
||||
//get the values from the transform on the entity
|
||||
float confirmXValue = 0.0f;
|
||||
AZ::TransformBus::EventResult(confirmXValue, entityId, &AZ::TransformInterface::GetWorldX);
|
||||
AZ::TransformBus::EventResult(confirmXValue, secondEntityId.value(), &AZ::TransformInterface::GetWorldX);
|
||||
AZ::TransformBus::EventResult(confirmXValue, secondEntityId, &AZ::TransformInterface::GetWorldX);
|
||||
|
||||
ASSERT_TRUE(confirmXValue == updatedXValue);
|
||||
}
|
||||
@@ -128,20 +125,21 @@ namespace UnitTest
|
||||
//get the entity id
|
||||
AZStd::vector<AZ::EntityId> entityIdVector;
|
||||
|
||||
secondInstance->GetEntityIds([&entityIdVector](const AZ::EntityId& entityId)
|
||||
secondInstance->GetEntityIds([&entityIdVector](AZ::EntityId entityId)
|
||||
{
|
||||
entityIdVector.push_back(entityId);
|
||||
return true;
|
||||
});
|
||||
|
||||
EXPECT_EQ(entityIdVector.size(), 1);
|
||||
// There should be 2 entities in the instance, the container entity and the one we added
|
||||
EXPECT_EQ(entityIdVector.size(), 2);
|
||||
}
|
||||
|
||||
TEST_F(PrefabInstanceToTemplateTests, PrefabUpdateTemplate_RemoveEntityFromInstance)
|
||||
{
|
||||
//create template with single entity
|
||||
const char* newEntityName = "New Entity";
|
||||
AZ::Entity* newEntity = CreateEntity(newEntityName, false);
|
||||
|
||||
AZ::Entity* newEntity = CreateEntity("New Entity", false);
|
||||
ASSERT_TRUE(newEntity);
|
||||
AZ::EntityId entityId = newEntity->GetId();
|
||||
|
||||
@@ -177,13 +175,14 @@ namespace UnitTest
|
||||
//get the entity id
|
||||
AZStd::vector<AZ::EntityId> entityIdVector;
|
||||
|
||||
secondInstance->GetEntityIds([&entityIdVector](const AZ::EntityId& entityId)
|
||||
secondInstance->GetEntityIds([&entityIdVector](AZ::EntityId entityId)
|
||||
{
|
||||
entityIdVector.push_back(entityId);
|
||||
return true;
|
||||
});
|
||||
|
||||
EXPECT_EQ(entityIdVector.size(), 0);
|
||||
// There should be 1 entity, the container and no others since we removed the other
|
||||
EXPECT_EQ(entityIdVector.size(), 1);
|
||||
}
|
||||
|
||||
TEST_F(PrefabInstanceToTemplateTests, PrefabUpdateTemplate_AddInstanceToInstance)
|
||||
@@ -207,8 +206,8 @@ namespace UnitTest
|
||||
AZStd::unique_ptr<Instance> addedInstance = m_prefabSystemComponent->CreatePrefab({}, {}, "test/pathtest");
|
||||
|
||||
//add instance to instance
|
||||
InstanceOptionalConstReference addedInstanceRef { firstInstance->AddInstance(AZStd::move(addedInstance)) };
|
||||
const AzToolsFramework::Prefab::InstanceAlias addedAlias = addedInstanceRef->get().GetInstanceAlias();
|
||||
Instance& addedInstanceRef = firstInstance->AddInstance(AZStd::move(addedInstance));
|
||||
const AzToolsFramework::Prefab::InstanceAlias addedAlias = addedInstanceRef.GetInstanceAlias();
|
||||
|
||||
//create document with after change snapshot
|
||||
PrefabDom instanceDomAfterUpdate;
|
||||
|
||||
@@ -21,7 +21,8 @@ namespace UnitTest
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<PrefabTestComponent, AzToolsFramework::Components::EditorComponentBase>()->
|
||||
Field("BoolProperty", &PrefabTestComponent::m_boolProperty);
|
||||
Field("BoolProperty", &PrefabTestComponent::m_boolProperty)->
|
||||
Field("EntityReferenceProperty", &PrefabTestComponent::m_entityIdProperty);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,5 +28,6 @@ namespace UnitTest
|
||||
static void Reflect(AZ::ReflectContext* reflection);
|
||||
|
||||
bool m_boolProperty = false;
|
||||
AZ::EntityId m_entityIdProperty;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -32,7 +32,8 @@ namespace UnitTest
|
||||
using namespace PrefabTestUtils;
|
||||
|
||||
class PrefabTestFixture
|
||||
: public ToolsApplicationFixture
|
||||
: public ToolsApplicationFixture,
|
||||
public UnitTest::TraceBusRedirector
|
||||
{
|
||||
protected:
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Prefab/PrefabTestUndoFixture.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
void PrefabTestUndoFixture::SetupInstances(
|
||||
AZStd::unique_ptr<Instance>& firstInstance,
|
||||
AZStd::unique_ptr<Instance>& secondInstance,
|
||||
TemplateId& ownerId,
|
||||
TemplateId& referenceId)
|
||||
{
|
||||
//create two prefabs for test
|
||||
//create prefab 1
|
||||
firstInstance = AZStd::move(m_prefabSystemComponent->CreatePrefab({ }, {}, "test/path0"));
|
||||
ASSERT_TRUE(firstInstance);
|
||||
|
||||
//get template id
|
||||
ownerId = firstInstance->GetTemplateId();
|
||||
|
||||
//create prefab 2
|
||||
secondInstance = AZStd::move(m_prefabSystemComponent->CreatePrefab({ }, {}, "test/path1"));
|
||||
ASSERT_TRUE(secondInstance);
|
||||
|
||||
//get template id
|
||||
referenceId = secondInstance->GetTemplateId();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <Prefab/PrefabTestFixture.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
class PrefabTestUndoFixture
|
||||
: public PrefabTestFixture
|
||||
{
|
||||
protected:
|
||||
void SetupInstances(
|
||||
AZStd::unique_ptr<Instance>& firstInstance,
|
||||
AZStd::unique_ptr<Instance>& secondInstance,
|
||||
TemplateId& ownerId,
|
||||
TemplateId& referenceId);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Prefab/PrefabTestDomUtils.h>
|
||||
#include <Prefab/PrefabTestUndoFixture.h>
|
||||
|
||||
#include <Prefab/PrefabUndo.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
using PrefabUndoLinkTests = PrefabTestUndoFixture;
|
||||
|
||||
TEST_F(PrefabUndoLinkTests, PrefabUndoLinkAdd)
|
||||
{
|
||||
AZStd::unique_ptr<Instance> firstInstance = nullptr;
|
||||
AZStd::unique_ptr<Instance> secondInstance = nullptr;
|
||||
TemplateId firstTemplateId = InvalidTemplateId;
|
||||
TemplateId secondTemplateId = InvalidTemplateId;
|
||||
|
||||
SetupInstances(firstInstance, secondInstance, firstTemplateId, secondTemplateId);
|
||||
|
||||
firstInstance->AddInstance(AZStd::move(secondInstance));
|
||||
AZStd::vector<InstanceAlias> aliases = firstInstance->GetNestedInstanceAliases(secondTemplateId);
|
||||
|
||||
//parent prefab2 to prefab 1 by creating a link
|
||||
//capture the link addition in undo node
|
||||
PrefabUndoInstanceLink undoLink("Undo Link Add Node");
|
||||
undoLink.Capture(firstTemplateId, secondTemplateId, aliases[0]);
|
||||
undoLink.Redo();
|
||||
|
||||
AZStd::unique_ptr<Instance> newInstance = m_prefabSystemComponent->InstantiatePrefab(firstTemplateId);
|
||||
AZStd::vector<InstanceAlias> instances = newInstance->GetNestedInstanceAliases(secondTemplateId);
|
||||
|
||||
ASSERT_TRUE(instances.size() > 0);
|
||||
instances.clear();
|
||||
|
||||
//undo the parenting
|
||||
undoLink.Undo();
|
||||
|
||||
newInstance = m_prefabSystemComponent->InstantiatePrefab(firstTemplateId);
|
||||
instances = newInstance->GetNestedInstanceAliases(secondTemplateId);
|
||||
|
||||
ASSERT_TRUE(instances.size() == 0);
|
||||
|
||||
//undo the parenting
|
||||
undoLink.Redo();
|
||||
|
||||
newInstance = m_prefabSystemComponent->InstantiatePrefab(firstTemplateId);
|
||||
instances = newInstance->GetNestedInstanceAliases(secondTemplateId);
|
||||
|
||||
ASSERT_TRUE(instances.size() == 1);
|
||||
}
|
||||
} // namespace UnitTest
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Prefab/PrefabTestDomUtils.h>
|
||||
#include <Prefab/PrefabTestFixture.h>
|
||||
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
|
||||
#include <AzFramework/Components/TransformComponent.h>
|
||||
|
||||
#include <Prefab/PrefabUndo.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
using PrefabUndoTests = PrefabTestFixture;
|
||||
|
||||
TEST_F(PrefabUndoTests, PrefabUndoEntityUpdate)
|
||||
{
|
||||
//create template with single entity
|
||||
AZ::Entity* newEntity = CreateEntity("New Entity", false);
|
||||
ASSERT_TRUE(newEntity);
|
||||
AZ::EntityId entityId = newEntity->GetId();
|
||||
|
||||
//add a transform component for testing purposes
|
||||
newEntity->CreateComponent(AZ::EditorTransformComponentTypeId);
|
||||
newEntity->Init();
|
||||
newEntity->Activate();
|
||||
|
||||
AZStd::unique_ptr<Instance> testInstance = m_prefabSystemComponent->CreatePrefab({ newEntity }, {}, "test/path");
|
||||
ASSERT_TRUE(testInstance);
|
||||
|
||||
//get template id
|
||||
TemplateId templateId = testInstance->GetTemplateId();
|
||||
|
||||
//create document with before change snapshot
|
||||
PrefabDom entityDomBeforeUpdate;
|
||||
m_instanceToTemplateInterface->GenerateDomForEntity(entityDomBeforeUpdate, *newEntity);
|
||||
|
||||
float checkXValue = 0.0f;
|
||||
AZ::TransformBus::EventResult(checkXValue, entityId, &AZ::TransformInterface::GetWorldX);
|
||||
ASSERT_TRUE(0.0f == checkXValue);
|
||||
|
||||
//update values on entity
|
||||
const float updatedXValue = 5.0f;
|
||||
AZ::TransformBus::Event(entityId, &AZ::TransformInterface::SetWorldX, updatedXValue);
|
||||
|
||||
AZ::TransformBus::EventResult(checkXValue, entityId, &AZ::TransformInterface::GetWorldX);
|
||||
ASSERT_TRUE(updatedXValue == checkXValue);
|
||||
|
||||
//create document with after change snapshot
|
||||
PrefabDom entityDomAfterUpdate;
|
||||
m_instanceToTemplateInterface->GenerateDomForEntity(entityDomAfterUpdate, *newEntity);
|
||||
|
||||
//generate patch
|
||||
PrefabDom patch;
|
||||
m_instanceToTemplateInterface->GeneratePatch(patch, entityDomBeforeUpdate, entityDomAfterUpdate);
|
||||
|
||||
//create undo node
|
||||
PrefabUndoEntityUpdate instanceEntityUndo("Entity Update Undo Node");
|
||||
instanceEntityUndo.Capture(entityDomBeforeUpdate, entityDomAfterUpdate, entityId);
|
||||
|
||||
EntityAliasOptionalReference entityAliasRef = testInstance->GetEntityAlias(entityId);
|
||||
ASSERT_TRUE(entityAliasRef);
|
||||
|
||||
EntityAlias entityAlias = entityAliasRef.value();
|
||||
|
||||
//update template
|
||||
m_instanceToTemplateInterface->PatchEntityInTemplate(patch, entityAlias, templateId);
|
||||
|
||||
//undo change
|
||||
instanceEntityUndo.Undo();
|
||||
|
||||
// verify template updated correctly
|
||||
//instantiate second instance for checking if propogation works
|
||||
AZStd::unique_ptr<Instance> secondInstance = m_prefabSystemComponent->InstantiatePrefab(templateId);
|
||||
ASSERT_TRUE(secondInstance);
|
||||
|
||||
secondInstance->InitializeNestedEntities();
|
||||
secondInstance->ActivateNestedEntities();
|
||||
|
||||
//get the values from the transform on the entity
|
||||
AZ::EntityId secondNewEntity = secondInstance->GetEntityId(entityAlias);
|
||||
|
||||
const float confirmXValue = 0.0f;
|
||||
float value = 10.0f;
|
||||
AZ::TransformBus::EventResult(value, secondNewEntity, &AZ::TransformInterface::GetWorldX);
|
||||
|
||||
ASSERT_TRUE(confirmXValue == value);
|
||||
}
|
||||
|
||||
TEST_F(PrefabUndoTests, PrefabUndoInstanceUpdate_AddEntity)
|
||||
{
|
||||
//create single entity
|
||||
AZ::Entity* newEntity = CreateEntity("New Entity", false);
|
||||
ASSERT_TRUE(newEntity);
|
||||
AZ::EntityId entityId = newEntity->GetId();
|
||||
|
||||
//create a first instance where the entity will be added
|
||||
AZStd::unique_ptr<Instance> testInstance = m_prefabSystemComponent->CreatePrefab({}, {}, "test/path");
|
||||
ASSERT_TRUE(testInstance);
|
||||
|
||||
//get template id
|
||||
TemplateId templateId = testInstance->GetTemplateId();
|
||||
|
||||
//create document with before change snapshot
|
||||
PrefabDom instanceDomBeforeUpdate;
|
||||
m_instanceToTemplateInterface->GenerateDomForInstance(instanceDomBeforeUpdate, *testInstance);
|
||||
|
||||
//add entity to instance
|
||||
testInstance->AddEntity(*newEntity);
|
||||
|
||||
//create document with after change snapshot
|
||||
PrefabDom instanceDomAfterUpdate;
|
||||
m_instanceToTemplateInterface->GenerateDomForInstance(instanceDomAfterUpdate, *testInstance);
|
||||
|
||||
//generate patch
|
||||
PrefabDom patch;
|
||||
m_instanceToTemplateInterface->GeneratePatch(patch, instanceDomBeforeUpdate, instanceDomAfterUpdate);
|
||||
|
||||
//create undo node
|
||||
PrefabUndoInstance instanceEntityAddUndo("Entity Update Undo Node");
|
||||
instanceEntityAddUndo.Capture(instanceDomBeforeUpdate, instanceDomAfterUpdate, templateId);
|
||||
|
||||
//update template
|
||||
m_instanceToTemplateInterface->PatchTemplate(patch, templateId);
|
||||
|
||||
//undo change
|
||||
instanceEntityAddUndo.Undo();
|
||||
|
||||
//get the entity id
|
||||
AZStd::vector<AZ::EntityId> entityIdVector;
|
||||
|
||||
testInstance->GetEntityIds([&entityIdVector](const AZ::EntityId& entityId)
|
||||
{
|
||||
entityIdVector.push_back(entityId);
|
||||
return true;
|
||||
});
|
||||
|
||||
// Entity count minimum is 1 due to container entity
|
||||
EXPECT_EQ(entityIdVector.size(), 1);
|
||||
}
|
||||
|
||||
TEST_F(PrefabUndoTests, PrefabUndoInstanceUpdate_RemoveEntity)
|
||||
{
|
||||
//create single entity
|
||||
AZ::Entity* newEntity = CreateEntity("New Entity", false);
|
||||
ASSERT_TRUE(newEntity);
|
||||
AZ::EntityId entityId = newEntity->GetId();
|
||||
|
||||
//create a first instance where the entity will be added
|
||||
AZStd::unique_ptr<Instance> testInstance = m_prefabSystemComponent->CreatePrefab({newEntity}, {}, "test/path");
|
||||
ASSERT_TRUE(testInstance);
|
||||
|
||||
//get template id
|
||||
TemplateId templateId = testInstance->GetTemplateId();
|
||||
|
||||
//create document with before change snapshot
|
||||
PrefabDom instanceDomBeforeUpdate;
|
||||
m_instanceToTemplateInterface->GenerateDomForInstance(instanceDomBeforeUpdate, *testInstance);
|
||||
|
||||
//detach entity from instance
|
||||
testInstance->DetachEntity(entityId);
|
||||
|
||||
//create document with after change snapshot
|
||||
PrefabDom instanceDomAfterUpdate;
|
||||
m_instanceToTemplateInterface->GenerateDomForInstance(instanceDomAfterUpdate, *testInstance);
|
||||
|
||||
//generate patch
|
||||
PrefabDom patch;
|
||||
m_instanceToTemplateInterface->GeneratePatch(patch, instanceDomBeforeUpdate, instanceDomAfterUpdate);
|
||||
|
||||
//create undo node
|
||||
PrefabUndoInstance instanceEntityRemoveUndo("Entity Update Undo Node");
|
||||
instanceEntityRemoveUndo.Capture(instanceDomBeforeUpdate, instanceDomAfterUpdate, templateId);
|
||||
|
||||
//update template
|
||||
m_instanceToTemplateInterface->PatchTemplate(patch, templateId);
|
||||
|
||||
//undo change
|
||||
instanceEntityRemoveUndo.Undo();
|
||||
|
||||
//get the entity id
|
||||
AZStd::vector<AZ::EntityId> entityIdVector;
|
||||
|
||||
testInstance->GetEntityIds([&entityIdVector](const AZ::EntityId& entityId)
|
||||
{
|
||||
entityIdVector.push_back(entityId);
|
||||
return true;
|
||||
});
|
||||
|
||||
// Entity count is container entity + our entity restored via the undo
|
||||
EXPECT_EQ(entityIdVector.size(), 2);
|
||||
}
|
||||
}
|
||||
@@ -46,9 +46,9 @@ namespace UnitTest
|
||||
ASSERT_EQ(wheelTemplateEntityAliases.size(), 1);
|
||||
|
||||
// Validate that the wheel entity has 1 component under it.
|
||||
AZStd::string entityAlias = wheelTemplateEntityAliases.front();
|
||||
EntityAlias wheelEntityAlias = wheelTemplateEntityAliases.front();
|
||||
PrefabDomValue* wheelEntityComponents =
|
||||
PrefabTestDomUtils::GetPrefabDomComponentsPath(entityAlias).Get(wheelTemplateDom);
|
||||
PrefabTestDomUtils::GetPrefabDomComponentsPath(wheelEntityAlias).Get(wheelTemplateDom);
|
||||
ASSERT_TRUE(wheelEntityComponents != nullptr && wheelEntityComponents->IsArray());
|
||||
EXPECT_EQ(wheelEntityComponents->GetArray().Size(), 1);
|
||||
|
||||
@@ -66,6 +66,7 @@ namespace UnitTest
|
||||
const TemplateId axleTemplateId = axleInstance->GetTemplateId();
|
||||
PrefabDom& axleTemplateDom = m_prefabSystemComponent->FindTemplateDom(axleTemplateId);
|
||||
const AZStd::vector<InstanceAlias> wheelInstanceAliasesUnderAxle = axleInstance->GetNestedInstanceAliases(wheelTemplateId);
|
||||
ASSERT_EQ(wheelInstanceAliasesUnderAxle.size(), 1);
|
||||
|
||||
|
||||
// Create a car with 0 entities and 1 axle instance.
|
||||
@@ -80,16 +81,19 @@ namespace UnitTest
|
||||
axleInstance->InitializeNestedEntities();
|
||||
axleInstance->ActivateNestedEntities();
|
||||
|
||||
InstanceOptionalReference nestedWheelInstanceRef = axleInstance->FindNestedInstance(wheelInstanceAliasesUnderAxle[0]);
|
||||
ASSERT_TRUE(nestedWheelInstanceRef);
|
||||
|
||||
//get the entity id
|
||||
AZStd::vector<AZ::EntityId> entityIdVector;
|
||||
axleInstance->GetNestedEntityIds([&entityIdVector](const AZ::EntityId& entityId)
|
||||
axleInstance->GetNestedEntityIds([&entityIdVector](AZ::EntityId entityId)
|
||||
{
|
||||
entityIdVector.push_back(entityId);
|
||||
return true;
|
||||
});
|
||||
|
||||
EXPECT_EQ(entityIdVector.size(), 1);
|
||||
AZ::EntityId wheelEntityIdUnderAxle = entityIdVector.front();
|
||||
ASSERT_EQ(entityIdVector.size(), 3);
|
||||
AZ::EntityId wheelEntityIdUnderAxle = nestedWheelInstanceRef->get().GetEntityId(wheelEntityAlias);
|
||||
|
||||
// Retrieve the entity pointer from the component application bus.
|
||||
AZ::Entity* wheelEntityUnderAxle = nullptr;
|
||||
@@ -118,7 +122,7 @@ namespace UnitTest
|
||||
// Even though we changed the property to false, it won't be serialized out because it's a default value.
|
||||
PrefabDomValue* wheelInstanceDomUnderAxle =
|
||||
PrefabTestDomUtils::GetPrefabDomInstancePath(wheelInstanceAliasesUnderAxle.front()).Get(axleTemplateDom);
|
||||
wheelEntityComponents = PrefabTestDomUtils::GetPrefabDomComponentsPath(entityAlias).Get(*wheelInstanceDomUnderAxle);
|
||||
wheelEntityComponents = PrefabTestDomUtils::GetPrefabDomComponentsPath(wheelEntityAlias).Get(*wheelInstanceDomUnderAxle);
|
||||
ASSERT_TRUE(wheelEntityComponents != nullptr);
|
||||
PrefabDomValueReference wheelEntityComponentBoolPropertyValue =
|
||||
PrefabDomUtils::FindPrefabDomValue(*wheelEntityComponents->Begin(), PrefabTestDomUtils::BoolPropertyName);
|
||||
|
||||
@@ -0,0 +1,436 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AzToolsFramework/Prefab/Spawnable/SpawnableMetaDataBuilder.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
class SpawnableMetaDataTests
|
||||
: public AllocatorsFixture
|
||||
{
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class TypedSpawnableMetaDataTests
|
||||
: public SpawnableMetaDataTests
|
||||
{
|
||||
public:
|
||||
using SetType = T;
|
||||
using GetType = AZStd::conditional_t<AZStd::is_same_v<T, AZStd::string>, AZStd::string_view, T>;
|
||||
|
||||
SetType GetValue()
|
||||
{
|
||||
if constexpr (AZStd::is_same_v<SetType, bool>)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if constexpr(AZStd::is_same_v<SetType, uint64_t>)
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
else if constexpr(AZStd::is_same_v<SetType, int64_t>)
|
||||
{
|
||||
return -42;
|
||||
}
|
||||
else if constexpr(AZStd::is_same_v<SetType, double>)
|
||||
{
|
||||
return 42.0;
|
||||
}
|
||||
else if constexpr(AZStd::is_same_v<SetType, AZStd::string>)
|
||||
{
|
||||
return AZStd::string("The number 42");
|
||||
}
|
||||
}
|
||||
|
||||
AzFramework::SpawnableMetaData::ValueType GetValueType()
|
||||
{
|
||||
if constexpr (AZStd::is_same_v<SetType, bool>)
|
||||
{
|
||||
return AzFramework::SpawnableMetaData::ValueType::Boolean;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<SetType, uint64_t>)
|
||||
{
|
||||
return AzFramework::SpawnableMetaData::ValueType::UnsignedInteger;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<SetType, int64_t>)
|
||||
{
|
||||
return AzFramework::SpawnableMetaData::ValueType::SignedInteger;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<SetType, double>)
|
||||
{
|
||||
return AzFramework::SpawnableMetaData::ValueType::FloatingPoint;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<SetType, AZStd::string>)
|
||||
{
|
||||
return AzFramework::SpawnableMetaData::ValueType::String;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename LT, typename RT>
|
||||
void ExpectEq(const LT& lhs, const RT& rhs)
|
||||
{
|
||||
if constexpr (AZStd::is_same_v<LT, AZStd::string> || AZStd::is_same_v<RT, AZStd::string>)
|
||||
{
|
||||
EXPECT_STREQ(lhs.data(), rhs.data());
|
||||
}
|
||||
else
|
||||
{
|
||||
EXPECT_EQ(lhs, rhs);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TYPED_TEST_CASE_P(TypedSpawnableMetaDataTests);
|
||||
|
||||
TYPED_TEST_P(TypedSpawnableMetaDataTests, Add_AddValueToMetaData_NoCrash)
|
||||
{
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::SpawnableMetaDataBuilder builder;
|
||||
builder.Add("RandomKey", this->GetValue());
|
||||
}
|
||||
|
||||
TYPED_TEST_P(TypedSpawnableMetaDataTests, Add_ChainAdds_NoCrash)
|
||||
{
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::SpawnableMetaDataBuilder builder;
|
||||
builder.Add("RandomKey1", this->GetValue()).Add("RandomKey2", this->GetValue());
|
||||
}
|
||||
|
||||
TYPED_TEST_P(TypedSpawnableMetaDataTests, Add_AddThenRetrieveValue_StoredIsSameAsRetrieved)
|
||||
{
|
||||
using GetType = typename TypedSpawnableMetaDataTests<TypeParam>::GetType;
|
||||
|
||||
auto value = this->GetValue();
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::SpawnableMetaDataBuilder builder;
|
||||
builder.Add("RandomKey", value);
|
||||
|
||||
AzFramework::SpawnableMetaData metaData(builder.BuildMetaData());
|
||||
GetType stored{};
|
||||
EXPECT_TRUE(metaData.Get("RandomKey", stored));
|
||||
|
||||
this->ExpectEq(stored, value);
|
||||
}
|
||||
|
||||
TYPED_TEST_P(TypedSpawnableMetaDataTests, Add_OverwritingValue_OriginalReplacedWithNewValue)
|
||||
{
|
||||
using GetType = typename TypedSpawnableMetaDataTests<TypeParam>::GetType;
|
||||
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::SpawnableMetaDataBuilder builder;
|
||||
if constexpr (AZStd::is_same_v<GetType, bool>)
|
||||
{
|
||||
builder.Add("RandomKey", 42.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.Add("RandomKey", true);
|
||||
}
|
||||
|
||||
builder.Add("RandomKey", this->GetValue());
|
||||
|
||||
AzFramework::SpawnableMetaData metaData(builder.BuildMetaData());
|
||||
GetType stored{};
|
||||
EXPECT_EQ(this->GetValueType(), metaData.GetType("RandomKey"));
|
||||
}
|
||||
|
||||
TYPED_TEST_P(TypedSpawnableMetaDataTests, Add_OverwritingArray_ArrayElementsAreRemoved)
|
||||
{
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::SpawnableMetaDataBuilder builder;
|
||||
builder.AppendArray("RandomKey", true);
|
||||
builder.AppendArray("RandomKey", uint64_t{ 42 });
|
||||
builder.AppendArray("RandomKey", int64_t{ -42 });
|
||||
builder.AppendArray("RandomKey", 42.0);
|
||||
builder.AppendArray("RandomKey", "Hello");
|
||||
ASSERT_EQ(6, builder.GetEntryCount()); // 5 entries plus the entry that holds the array size.
|
||||
|
||||
auto value = this->GetValue();
|
||||
builder.Add("RandomKey", value);
|
||||
|
||||
EXPECT_EQ(1, builder.GetEntryCount());
|
||||
}
|
||||
|
||||
TYPED_TEST_P(TypedSpawnableMetaDataTests, GetType_RetrieveTypeOfValue_ValueTypeMatches)
|
||||
{
|
||||
auto value = this->GetValue();
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::SpawnableMetaDataBuilder builder;
|
||||
builder.Add("RandomKey", value);
|
||||
|
||||
AzFramework::SpawnableMetaData metaData(builder.BuildMetaData());
|
||||
|
||||
AzFramework::SpawnableMetaData::ValueType type = metaData.GetType("RandomKey");
|
||||
EXPECT_EQ(this->GetValueType(), type);
|
||||
}
|
||||
|
||||
TYPED_TEST_P(TypedSpawnableMetaDataTests, GetType_RetrieveTypeOfArrayEntry_ValueTypeMatches)
|
||||
{
|
||||
auto value = this->GetValue();
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::SpawnableMetaDataBuilder builder;
|
||||
builder.AppendArray("RandomKey", value);
|
||||
|
||||
AzFramework::SpawnableMetaData metaData(builder.BuildMetaData());
|
||||
|
||||
AzFramework::SpawnableMetaData::ValueType type = metaData.GetType("RandomKey", 0);
|
||||
EXPECT_EQ(this->GetValueType(), type);
|
||||
}
|
||||
|
||||
TYPED_TEST_P(TypedSpawnableMetaDataTests, AppendArray_AddValueToMetaDataArray_NoCrash)
|
||||
{
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::SpawnableMetaDataBuilder builder;
|
||||
builder.AppendArray("RandomKey", this->GetValue());
|
||||
}
|
||||
|
||||
TYPED_TEST_P(TypedSpawnableMetaDataTests, AppendArray_AppendThenRetrieveValue_StoredIsSameAsRetrieved)
|
||||
{
|
||||
using GetType = typename TypedSpawnableMetaDataTests<TypeParam>::GetType;
|
||||
|
||||
auto value = this->GetValue();
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::SpawnableMetaDataBuilder builder;
|
||||
builder.AppendArray("RandomKey", value);
|
||||
|
||||
AzFramework::SpawnableMetaData metaData(builder.BuildMetaData());
|
||||
GetType stored{};
|
||||
EXPECT_TRUE(metaData.Get("RandomKey", 0, stored));
|
||||
|
||||
this->ExpectEq(stored, value);
|
||||
}
|
||||
|
||||
TYPED_TEST_P(TypedSpawnableMetaDataTests, AppendArray_ReplaceExistingValue_ArraySizeReplacesOriginalEntry)
|
||||
{
|
||||
auto value = this->GetValue();
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::SpawnableMetaDataBuilder builder;
|
||||
builder.Add("RandomKey", value);
|
||||
builder.AppendArray("RandomKey", value);
|
||||
|
||||
AzFramework::SpawnableMetaData metaData(builder.BuildMetaData());
|
||||
EXPECT_EQ(AzFramework::SpawnableMetaData::ValueType::ArraySize, metaData.GetType("RandomKey"));
|
||||
}
|
||||
|
||||
TYPED_TEST_P(TypedSpawnableMetaDataTests, Get_WrongType_ReturnsFalse)
|
||||
{
|
||||
using GetType = typename TypedSpawnableMetaDataTests<TypeParam>::GetType;
|
||||
|
||||
auto value = this->GetValue();
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::SpawnableMetaDataBuilder builder;
|
||||
builder.AppendArray("RandomKey", value);
|
||||
|
||||
AzFramework::SpawnableMetaData metaData(builder.BuildMetaData());
|
||||
if constexpr (AZStd::is_same_v<GetType, bool>)
|
||||
{
|
||||
double stored{};
|
||||
EXPECT_FALSE(metaData.Get("RandomKey", stored));
|
||||
}
|
||||
else
|
||||
{
|
||||
bool stored{};
|
||||
EXPECT_FALSE(metaData.Get("RandomKey", stored));
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_TYPED_TEST_CASE_P(TypedSpawnableMetaDataTests,
|
||||
Add_AddValueToMetaData_NoCrash,
|
||||
Add_ChainAdds_NoCrash,
|
||||
Add_AddThenRetrieveValue_StoredIsSameAsRetrieved,
|
||||
Add_OverwritingValue_OriginalReplacedWithNewValue,
|
||||
Add_OverwritingArray_ArrayElementsAreRemoved,
|
||||
GetType_RetrieveTypeOfValue_ValueTypeMatches,
|
||||
GetType_RetrieveTypeOfArrayEntry_ValueTypeMatches,
|
||||
AppendArray_AddValueToMetaDataArray_NoCrash,
|
||||
AppendArray_AppendThenRetrieveValue_StoredIsSameAsRetrieved,
|
||||
AppendArray_ReplaceExistingValue_ArraySizeReplacesOriginalEntry,
|
||||
Get_WrongType_ReturnsFalse);
|
||||
|
||||
using SpawnableMetaDataTestTypes = ::testing::Types<bool, uint64_t, int64_t, double, AZStd::string>;
|
||||
INSTANTIATE_TYPED_TEST_CASE_P(SpawnableMetaDataTests, TypedSpawnableMetaDataTests, SpawnableMetaDataTestTypes);
|
||||
|
||||
|
||||
TEST_F(SpawnableMetaDataTests, Get_UnknownKey_ReturnsFalse)
|
||||
{
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::SpawnableMetaDataBuilder builder;
|
||||
builder.Add("RandomKey", uint64_t{ 42 });
|
||||
|
||||
AzFramework::SpawnableMetaData metaData(builder.BuildMetaData());
|
||||
|
||||
uint64_t stored{};
|
||||
EXPECT_FALSE(metaData.Get("UnknownKey", stored));
|
||||
}
|
||||
|
||||
TEST_F(SpawnableMetaDataTests, Get_ArraySize_ReturnsNumberOfEntries)
|
||||
{
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::SpawnableMetaDataBuilder builder;
|
||||
builder.AppendArray("RandomKey", true);
|
||||
builder.AppendArray("RandomKey", uint64_t{ 42 });
|
||||
builder.AppendArray("RandomKey", int64_t{ -42 });
|
||||
builder.AppendArray("RandomKey", 42.0);
|
||||
builder.AppendArray("RandomKey", "Hello");
|
||||
|
||||
AzFramework::SpawnableMetaData metaData(builder.BuildMetaData());
|
||||
AzFramework::SpawnableMetaDataArraySize stored{};
|
||||
EXPECT_TRUE(metaData.Get("RandomKey", stored));
|
||||
|
||||
EXPECT_EQ(AzFramework::SpawnableMetaDataArraySize{ 5 }, stored);
|
||||
}
|
||||
|
||||
TEST_F(SpawnableMetaDataTests, Get_ArrayElementsAtVariousIndices_ReturnsValues)
|
||||
{
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::SpawnableMetaDataBuilder builder;
|
||||
for (uint64_t i = 42; i < 88; ++i)
|
||||
{
|
||||
builder.AppendArray("RandomKey", i);
|
||||
}
|
||||
|
||||
AzFramework::SpawnableMetaData metaData(builder.BuildMetaData());
|
||||
|
||||
for (size_t i = 0; i < 88 - 42; ++i)
|
||||
{
|
||||
uint64_t stored;
|
||||
EXPECT_TRUE(metaData.Get("RandomKey", i, stored));
|
||||
EXPECT_EQ(42 + i, stored);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(SpawnableMetaDataTests, Get_ArrayIndexOutOfBounds_ReturnsFalse)
|
||||
{
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::SpawnableMetaDataBuilder builder;
|
||||
builder.AppendArray("RandomKey", true);
|
||||
builder.AppendArray("RandomKey", uint64_t{ 42 });
|
||||
builder.AppendArray("RandomKey", int64_t{ -42 });
|
||||
builder.AppendArray("RandomKey", 42.0);
|
||||
builder.AppendArray("RandomKey", "Hello");
|
||||
|
||||
AzFramework::SpawnableMetaData metaData(builder.BuildMetaData());
|
||||
|
||||
uint64_t stored{};
|
||||
EXPECT_FALSE(metaData.Get("RandomKey", 5, stored));
|
||||
}
|
||||
|
||||
TEST_F(SpawnableMetaDataTests, Get_RetrieveArrayType_ReturnArrayType)
|
||||
{
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::SpawnableMetaDataBuilder builder;
|
||||
builder.AppendArray("RandomKey", true);
|
||||
builder.AppendArray("RandomKey", uint64_t{ 42 });
|
||||
builder.AppendArray("RandomKey", int64_t{ -42 });
|
||||
builder.AppendArray("RandomKey", 42.0);
|
||||
builder.AppendArray("RandomKey", "Hello");
|
||||
|
||||
AzFramework::SpawnableMetaData metaData(builder.BuildMetaData());
|
||||
|
||||
EXPECT_EQ(AzFramework::SpawnableMetaData::ValueType::ArraySize, metaData.GetType("RandomKey"));
|
||||
}
|
||||
|
||||
TEST_F(SpawnableMetaDataTests, Get_RetrieveNonExistingValue_ReturnUnavailable)
|
||||
{
|
||||
AzFramework::SpawnableMetaData metaData;
|
||||
EXPECT_EQ(AzFramework::SpawnableMetaData::ValueType::Unavailable, metaData.GetType("RandomKey"));
|
||||
}
|
||||
|
||||
TEST_F(SpawnableMetaDataTests, Get_RetrieveNonExistingArrayIndex_ReturnUnavailable)
|
||||
{
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::SpawnableMetaDataBuilder builder;
|
||||
builder.AppendArray("RandomKey", true);
|
||||
builder.AppendArray("RandomKey", uint64_t{ 42 });
|
||||
builder.AppendArray("RandomKey", int64_t{ -42 });
|
||||
builder.AppendArray("RandomKey", 42.0);
|
||||
builder.AppendArray("RandomKey", "Hello");
|
||||
|
||||
AzFramework::SpawnableMetaData metaData(builder.BuildMetaData());
|
||||
|
||||
EXPECT_EQ(AzFramework::SpawnableMetaData::ValueType::Unavailable, metaData.GetType("RandomKey", 42));
|
||||
}
|
||||
|
||||
TEST_F(SpawnableMetaDataTests, Remove_RemoveExistingEntry_EntryNotFound)
|
||||
{
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::SpawnableMetaDataBuilder builder;
|
||||
builder.Add("RandomKey", uint64_t{ 42 });
|
||||
|
||||
ASSERT_TRUE(builder.Remove("RandomKey"));
|
||||
|
||||
AzFramework::SpawnableMetaData metaData(builder.BuildMetaData());
|
||||
|
||||
uint64_t stored{};
|
||||
EXPECT_FALSE(metaData.Get("RandomKey", stored));
|
||||
}
|
||||
|
||||
TEST_F(SpawnableMetaDataTests, Remove_RemoveNonExistingEntry_ReturnsFalse)
|
||||
{
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::SpawnableMetaDataBuilder builder;
|
||||
EXPECT_FALSE(builder.Remove("UnknownKey"));
|
||||
}
|
||||
|
||||
TEST_F(SpawnableMetaDataTests, Remove_RemoveArray_AllArrayEntriesAreRemovedAsWell)
|
||||
{
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::SpawnableMetaDataBuilder builder;
|
||||
builder.AppendArray("RandomKey", uint64_t{ 10 });
|
||||
builder.AppendArray("RandomKey", uint64_t{ 11 });
|
||||
builder.AppendArray("RandomKey", uint64_t{ 12 });
|
||||
builder.AppendArray("RandomKey", uint64_t{ 13 });
|
||||
builder.AppendArray("RandomKey", uint64_t{ 14 });
|
||||
builder.AppendArray("RandomKey", uint64_t{ 15 });
|
||||
|
||||
EXPECT_TRUE(builder.Remove("RandomKey"));
|
||||
|
||||
EXPECT_EQ(0, builder.GetEntryCount());
|
||||
}
|
||||
|
||||
TEST_F(SpawnableMetaDataTests, RemoveArrayEntry_RemoveExistingEntry_EntryNotFound)
|
||||
{
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::SpawnableMetaDataBuilder builder;
|
||||
builder.AppendArray("RandomKey", uint64_t{ 10 });
|
||||
builder.AppendArray("RandomKey", uint64_t{ 11 });
|
||||
builder.AppendArray("RandomKey", uint64_t{ 12 });
|
||||
builder.AppendArray("RandomKey", uint64_t{ 13 });
|
||||
builder.AppendArray("RandomKey", uint64_t{ 14 });
|
||||
builder.AppendArray("RandomKey", uint64_t{ 15 });
|
||||
|
||||
ASSERT_TRUE(builder.RemoveArrayEntry("RandomKey", 3));
|
||||
|
||||
AzFramework::SpawnableMetaData metaData(builder.BuildMetaData());
|
||||
|
||||
AzFramework::SpawnableMetaDataArraySize stored{};
|
||||
EXPECT_TRUE(metaData.Get("RandomKey", stored));
|
||||
EXPECT_EQ(stored, AzFramework::SpawnableMetaDataArraySize{ 5 });
|
||||
|
||||
uint64_t storedValue;
|
||||
EXPECT_TRUE(metaData.Get("RandomKey", 0, storedValue));
|
||||
EXPECT_EQ(10, storedValue);
|
||||
|
||||
EXPECT_TRUE(metaData.Get("RandomKey", 1, storedValue));
|
||||
EXPECT_EQ(11, storedValue);
|
||||
|
||||
EXPECT_TRUE(metaData.Get("RandomKey", 2, storedValue));
|
||||
EXPECT_EQ(12, storedValue);
|
||||
|
||||
EXPECT_TRUE(metaData.Get("RandomKey", 3, storedValue));
|
||||
EXPECT_EQ(14, storedValue);
|
||||
|
||||
EXPECT_TRUE(metaData.Get("RandomKey", 4, storedValue));
|
||||
EXPECT_EQ(15, storedValue);
|
||||
|
||||
EXPECT_FALSE(metaData.Get("RandomKey", 5, storedValue));
|
||||
}
|
||||
|
||||
TEST_F(SpawnableMetaDataTests, RemoveArrayEntry_RemoveNonExistingKey_ReturnFalse)
|
||||
{
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::SpawnableMetaDataBuilder builder;
|
||||
ASSERT_FALSE(builder.RemoveArrayEntry("RandomKey", 0));
|
||||
}
|
||||
|
||||
TEST_F(SpawnableMetaDataTests, RemoveArrayEntry_RemoveNonExistingEntry_ReturnFalse)
|
||||
{
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::SpawnableMetaDataBuilder builder;
|
||||
builder.AppendArray("RandomKey", uint64_t{ 0 });
|
||||
builder.AppendArray("RandomKey", uint64_t{ 1 });
|
||||
builder.AppendArray("RandomKey", uint64_t{ 2 });
|
||||
builder.AppendArray("RandomKey", uint64_t{ 3 });
|
||||
builder.AppendArray("RandomKey", uint64_t{ 4 });
|
||||
builder.AppendArray("RandomKey", uint64_t{ 5 });
|
||||
|
||||
ASSERT_FALSE(builder.RemoveArrayEntry("RandomKey", 42));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Prefab/PrefabTestFixture.h>
|
||||
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
#include <AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
using SpawnableCreateTest = PrefabTestFixture;
|
||||
|
||||
TEST_F(SpawnableCreateTest, SpawnableCreate_NoNestingPrefabDom_CreateSucceeds)
|
||||
{
|
||||
AZStd::vector<AZ::Entity*> entitiesCreated;
|
||||
AZStd::unordered_set<AZStd::string> expectedEntityNameSet;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
entitiesCreated.push_back(CreateEntity(AZStd::string::format("Entity_%i", i).c_str()));
|
||||
expectedEntityNameSet.insert(entitiesCreated.back()->GetName());
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<AzToolsFramework::Prefab::Instance> instance(
|
||||
m_prefabSystemComponent->CreatePrefab(entitiesCreated, {}, "test/path"));
|
||||
ASSERT_TRUE(instance);
|
||||
|
||||
//Create Spawnable
|
||||
auto& prefabDom = m_prefabSystemComponent->FindTemplateDom(instance->GetTemplateId());
|
||||
auto spawnable = ::AzToolsFramework::Prefab::SpawnableUtils::CreateSpawnable(prefabDom);
|
||||
|
||||
EXPECT_EQ(spawnable.GetEntities().size(), 3);
|
||||
const auto& spawnableEntities = spawnable.GetEntities();
|
||||
AZStd::unordered_set<AZStd::string> actualEntityNameSet;
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
actualEntityNameSet.insert(spawnableEntities[i]->GetName());
|
||||
}
|
||||
|
||||
EXPECT_EQ(expectedEntityNameSet, actualEntityNameSet);
|
||||
}
|
||||
|
||||
TEST_F(SpawnableCreateTest, SpawnableCreate_TripleNestingPrefabDom_CreateSucceeds)
|
||||
{
|
||||
AZStd::vector<AZ::Entity*> entitiesCreated;
|
||||
AZStd::unordered_set<AZStd::string> expectedEntityNameSet;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
entitiesCreated.push_back(CreateEntity(AZStd::string::format("Entity_%i", i).c_str()));
|
||||
expectedEntityNameSet.insert(entitiesCreated.back()->GetName());
|
||||
}
|
||||
|
||||
// Build a 3 level deep nested Template
|
||||
AZStd::unique_ptr<AzToolsFramework::Prefab::Instance> firstInstance(
|
||||
m_prefabSystemComponent->CreatePrefab({ entitiesCreated[0] }, {}, "test/path1"));
|
||||
ASSERT_TRUE(firstInstance);
|
||||
|
||||
AZStd::unique_ptr<AzToolsFramework::Prefab::Instance> secondInstance(
|
||||
m_prefabSystemComponent->CreatePrefab({ entitiesCreated[1] }, MakeInstanceList(AZStd::move(firstInstance)), "test/path2"));
|
||||
ASSERT_TRUE(secondInstance);
|
||||
|
||||
AZStd::unique_ptr<AzToolsFramework::Prefab::Instance> thirdInstance(
|
||||
m_prefabSystemComponent->CreatePrefab({ entitiesCreated[2] }, MakeInstanceList(AZStd::move(secondInstance)), "test/path3"));
|
||||
ASSERT_TRUE(thirdInstance);
|
||||
|
||||
//Create Spawnable
|
||||
auto& prefabDom = m_prefabSystemComponent->FindTemplateDom(thirdInstance->GetTemplateId());
|
||||
auto spawnable = ::AzToolsFramework::Prefab::SpawnableUtils::CreateSpawnable(prefabDom);
|
||||
|
||||
EXPECT_EQ(spawnable.GetEntities().size(), 3);
|
||||
const auto& spawnableEntities = spawnable.GetEntities();
|
||||
AZStd::unordered_set<AZStd::string> actualEntityNameSet;
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
actualEntityNameSet.insert(spawnableEntities[i]->GetName());
|
||||
}
|
||||
|
||||
EXPECT_EQ(expectedEntityNameSet, actualEntityNameSet);
|
||||
}
|
||||
}
|
||||
+223
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Prefab/SpawnableRemoveEditorInfoTestFixture.h>
|
||||
|
||||
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorOnlyEntityComponent.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorOnlyEntityComponentBus.h>
|
||||
#include <AzToolsFramework/ToolsComponents/TransformComponent.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
TestExportRuntimeComponentWithCallback::TestExportRuntimeComponentWithCallback(bool returnPointerToSelf, bool exportHandled)
|
||||
: m_returnPointerToSelf(returnPointerToSelf)
|
||||
, m_exportHandled(exportHandled)
|
||||
{}
|
||||
|
||||
void TestExportRuntimeComponentWithCallback::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<TestExportRuntimeComponentWithCallback, AZ::Component>()->Version(1)
|
||||
->Field("ExportHandled", &TestExportRuntimeComponentWithCallback::m_exportHandled)
|
||||
->Field("ReturnPointerToSelf", &TestExportRuntimeComponentWithCallback::m_returnPointerToSelf);
|
||||
|
||||
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
|
||||
{
|
||||
editContext->Class<TestExportRuntimeComponentWithCallback>(
|
||||
"Test Export Runtime Component", "Validate different options for exporting runtime components")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::RuntimeExportCallback, &TestExportRuntimeComponentWithCallback::ExportComponent)
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AZ::ExportedComponent TestExportRuntimeComponentWithCallback::ExportComponent(AZ::Component* thisComponent, const AZ::PlatformTagSet& /*platformTags*/)
|
||||
{
|
||||
return AZ::ExportedComponent(m_returnPointerToSelf? thisComponent : nullptr, false, m_exportHandled);
|
||||
}
|
||||
|
||||
void TestExportRuntimeComponentWithoutCallback::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
auto* serialize = azrtti_cast<AZ::SerializeContext*>(context);
|
||||
if (serialize)
|
||||
{
|
||||
serialize->Class<TestExportRuntimeComponentWithoutCallback, AZ::Component>()
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
TestExportEditorComponent::TestExportEditorComponent(
|
||||
TestExportEditorComponent::ExportComponentType exportType, bool exportHandled)
|
||||
: m_exportType(exportType)
|
||||
, m_exportHandled(exportHandled)
|
||||
{}
|
||||
|
||||
void TestExportEditorComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<TestExportEditorComponent, AzToolsFramework::Components::EditorComponentBase>()
|
||||
->Version(1)
|
||||
->Field("ExportHandled", &TestExportEditorComponent::m_exportHandled)
|
||||
->Field("ExportType", &TestExportEditorComponent::m_exportType)
|
||||
;
|
||||
|
||||
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
|
||||
{
|
||||
editContext->Class<TestExportEditorComponent>(
|
||||
"Test Export Editor Component", "Validate different options for exporting editor components")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::RuntimeExportCallback, &TestExportEditorComponent::ExportComponent)
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AZ::ExportedComponent TestExportEditorComponent::ExportComponent(
|
||||
AZ::Component* thisComponent, const AZ::PlatformTagSet& /*platformTags*/)
|
||||
{
|
||||
switch (m_exportType)
|
||||
{
|
||||
case ExportComponentType::ExportEditorComponent:
|
||||
return AZ::ExportedComponent(thisComponent, false, m_exportHandled);
|
||||
case ExportComponentType::ExportRuntimeComponentWithCallBack:
|
||||
return AZ::ExportedComponent(aznew TestExportRuntimeComponentWithCallback(true, true), true, m_exportHandled);
|
||||
case ExportComponentType::ExportRuntimeComponentWithoutCallBack:
|
||||
return AZ::ExportedComponent(aznew TestExportRuntimeComponentWithoutCallback, true, m_exportHandled);
|
||||
case ExportComponentType::ExportNullComponent:
|
||||
return AZ::ExportedComponent(nullptr, false, m_exportHandled);
|
||||
default:
|
||||
return AZ::ExportedComponent();
|
||||
}
|
||||
}
|
||||
|
||||
void TestExportEditorComponent::BuildGameEntity(AZ::Entity* gameEntity)
|
||||
{
|
||||
gameEntity->CreateComponent<TestExportRuntimeComponentWithCallback>(true, true);
|
||||
}
|
||||
|
||||
void SpawnableRemoveEditorInfoTestFixture::SetUpEditorFixtureImpl()
|
||||
{
|
||||
auto* app = GetApplication();
|
||||
|
||||
// Acquire the system entity
|
||||
AZ::Entity* systemEntity = app->FindEntity(AZ::SystemEntityId);
|
||||
EXPECT_TRUE(systemEntity);
|
||||
|
||||
// Acquire the prefab system component to gain access to its APIs for testing
|
||||
m_prefabSystemComponent = systemEntity->FindComponent<AzToolsFramework::Prefab::PrefabSystemComponent>();
|
||||
EXPECT_TRUE(m_prefabSystemComponent);
|
||||
|
||||
m_serializeContext = app->GetSerializeContext();
|
||||
EXPECT_TRUE(m_serializeContext);
|
||||
|
||||
app->RegisterComponentDescriptor(TestExportRuntimeComponentWithCallback::CreateDescriptor());
|
||||
app->RegisterComponentDescriptor(TestExportRuntimeComponentWithoutCallback::CreateDescriptor());
|
||||
app->RegisterComponentDescriptor(TestExportEditorComponent::CreateDescriptor());
|
||||
}
|
||||
|
||||
void SpawnableRemoveEditorInfoTestFixture::TearDownEditorFixtureImpl()
|
||||
{
|
||||
for (AZ::Entity* entity : m_runtimeEntities)
|
||||
{
|
||||
delete entity;
|
||||
}
|
||||
|
||||
m_sourceEntities.clear();
|
||||
m_runtimeEntities.clear();
|
||||
}
|
||||
|
||||
void SpawnableRemoveEditorInfoTestFixture::CreateSourceEntity(const char* name, bool editorOnly)
|
||||
{
|
||||
AZ::Entity* entity = aznew AZ::Entity(name);
|
||||
entity->CreateComponent<AzToolsFramework::Components::TransformComponent>();
|
||||
entity->CreateComponent<AzToolsFramework::Components::EditorOnlyEntityComponent>();
|
||||
m_sourceEntities.push_back(entity);
|
||||
|
||||
entity->Init();
|
||||
EXPECT_EQ(AZ::Entity::State::Init, entity->GetState());
|
||||
entity->Activate();
|
||||
EXPECT_EQ(AZ::Entity::State::Active, entity->GetState());
|
||||
|
||||
AzToolsFramework::EditorOnlyEntityComponentRequestBus::Event(
|
||||
entity->GetId(),
|
||||
&AzToolsFramework::EditorOnlyEntityComponentRequests::SetIsEditorOnlyEntity,
|
||||
editorOnly);
|
||||
}
|
||||
|
||||
void SpawnableRemoveEditorInfoTestFixture::CreateSourceTestExportRuntimeEntity(
|
||||
const char* name, bool returnPointerToSelf, bool exportHandled)
|
||||
{
|
||||
AZ::Entity* entity = aznew AZ::Entity(name);
|
||||
entity->CreateComponent<AzToolsFramework::Components::TransformComponent>();
|
||||
entity->CreateComponent<TestExportRuntimeComponentWithCallback>(returnPointerToSelf, exportHandled);
|
||||
m_sourceEntities.push_back(entity);
|
||||
}
|
||||
|
||||
void SpawnableRemoveEditorInfoTestFixture::CreateSourceTestExportEditorEntity(
|
||||
const char* name,
|
||||
TestExportEditorComponent::ExportComponentType exportType,
|
||||
bool exportHandled)
|
||||
{
|
||||
AZ::Entity* entity = aznew AZ::Entity(name);
|
||||
entity->CreateComponent<AzToolsFramework::Components::TransformComponent>();
|
||||
entity->CreateComponent<TestExportEditorComponent>(exportType, exportHandled);
|
||||
m_sourceEntities.push_back(entity);
|
||||
}
|
||||
|
||||
AZ::Entity* SpawnableRemoveEditorInfoTestFixture::GetRuntimeEntity(const char* entityName)
|
||||
{
|
||||
for (AZ::Entity* entity : m_runtimeEntities)
|
||||
{
|
||||
const AZStd::string& name = entity->GetName();
|
||||
if (name == entityName)
|
||||
{
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SpawnableRemoveEditorInfoTestFixture::ConvertSourceEntitiesToPrefab()
|
||||
{
|
||||
AZStd::unique_ptr<AzToolsFramework::Prefab::Instance> sourceInstance(
|
||||
m_prefabSystemComponent->CreatePrefab(m_sourceEntities, {}, "test/path"));
|
||||
ASSERT_TRUE(sourceInstance);
|
||||
|
||||
auto& prefabTemplateDom = m_prefabSystemComponent->FindTemplateDom(sourceInstance->GetTemplateId());
|
||||
m_prefabDom.CopyFrom(prefabTemplateDom, m_prefabDom.GetAllocator());
|
||||
}
|
||||
|
||||
void SpawnableRemoveEditorInfoTestFixture::ConvertRuntimePrefab(bool expectedResult)
|
||||
{
|
||||
ConvertSourceEntitiesToPrefab();
|
||||
|
||||
const bool actualResult =
|
||||
m_editorInfoRemover.RemoveEditorInfo(m_prefabDom, m_serializeContext, m_prefabProcessorContext).IsSuccess();
|
||||
|
||||
EXPECT_EQ(expectedResult, actualResult);
|
||||
|
||||
AZStd::unique_ptr<Instance> convertedInstance(aznew Instance());
|
||||
ASSERT_TRUE(AzToolsFramework::Prefab::PrefabDomUtils::LoadInstanceFromPrefabDom(*convertedInstance, m_prefabDom, false));
|
||||
|
||||
convertedInstance->DetachNestedEntities(
|
||||
[this](AZStd::unique_ptr<AZ::Entity> entity)
|
||||
{
|
||||
m_runtimeEntities.emplace_back(entity.release());
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorComponentBase.h>
|
||||
#include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
|
||||
#include <Prefab/Spawnable/EditorInfoRemover.h>
|
||||
#include <Prefab/Spawnable/PrefabProcessorContext.h>
|
||||
#include <Prefab/PrefabSystemComponent.h>
|
||||
#include <Prefab/PrefabDomTypes.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
using namespace AzToolsFramework::Prefab;
|
||||
|
||||
class TestExportRuntimeComponentWithCallback
|
||||
: public AZ::Component
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(TestExportRuntimeComponentWithCallback, "{BD30EBBB-74DA-473C-9C68-7077AAE8C0B1}", AZ::Component);
|
||||
|
||||
TestExportRuntimeComponentWithCallback() = default;
|
||||
TestExportRuntimeComponentWithCallback(bool returnPointerToSelf, bool exportHandled);
|
||||
|
||||
void Activate() override {}
|
||||
void Deactivate() override {}
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
AZ::ExportedComponent ExportComponent(AZ::Component* thisComponent, const AZ::PlatformTagSet& /*platformTags*/);
|
||||
|
||||
const bool m_exportHandled{ false };
|
||||
const bool m_returnPointerToSelf{ false };
|
||||
};
|
||||
|
||||
class TestExportRuntimeComponentWithoutCallback
|
||||
: public AZ::Component
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(TestExportRuntimeComponentWithoutCallback, "{44216269-2BAB-48E4-864F-F8D4CCFF60BB}", AZ::Component);
|
||||
|
||||
void Activate() override {}
|
||||
void Deactivate() override {}
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
};
|
||||
|
||||
class TestExportEditorComponent
|
||||
: public AzToolsFramework::Components::EditorComponentBase
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(TestExportEditorComponent, "{60EE7F0E-1C89-433A-AA7C-20F64BA1F470}", AzToolsFramework::Components::EditorComponentBase);
|
||||
|
||||
enum class ExportComponentType
|
||||
{
|
||||
ExportEditorComponent,
|
||||
ExportRuntimeComponentWithCallBack,
|
||||
ExportRuntimeComponentWithoutCallBack,
|
||||
ExportNullComponent,
|
||||
};
|
||||
|
||||
TestExportEditorComponent() = default;
|
||||
TestExportEditorComponent(ExportComponentType exportType, bool exportHandled);
|
||||
|
||||
void Activate() override {}
|
||||
void Deactivate() override {}
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
AZ::ExportedComponent ExportComponent(AZ::Component* thisComponent, const AZ::PlatformTagSet& /*platformTags*/);
|
||||
|
||||
void BuildGameEntity(AZ::Entity* gameEntity) override;
|
||||
|
||||
ExportComponentType m_exportType{ ExportComponentType::ExportNullComponent };
|
||||
bool m_exportHandled{ false };
|
||||
};
|
||||
|
||||
class SpawnableRemoveEditorInfoTestFixture
|
||||
: public ToolsApplicationFixture
|
||||
{
|
||||
protected:
|
||||
void SetUpEditorFixtureImpl() override;
|
||||
void TearDownEditorFixtureImpl() override;
|
||||
|
||||
// create entity containing the EditorOnly component to be processed
|
||||
void CreateSourceEntity(const char* name, bool editorOnly);
|
||||
|
||||
// create entity containing the non editor-only component to be processed
|
||||
void CreateSourceTestExportRuntimeEntity(const char* name, bool returnPointerToSelf, bool exportHandled);
|
||||
|
||||
// create entity containing the editor-only component to be processed
|
||||
void CreateSourceTestExportEditorEntity(
|
||||
const char* name,
|
||||
TestExportEditorComponent::ExportComponentType exportType,
|
||||
bool exportHandled);
|
||||
|
||||
// Locate and return an entity from the exported entities
|
||||
AZ::Entity* GetRuntimeEntity(const char* entityName);
|
||||
|
||||
void ConvertSourceEntitiesToPrefab();
|
||||
|
||||
void ConvertRuntimePrefab(bool expectedResult = true);
|
||||
|
||||
AZStd::vector<AZ::Entity*> m_sourceEntities;
|
||||
AZStd::vector<AZ::Entity*> m_runtimeEntities;
|
||||
AZ::SerializeContext* m_serializeContext{ nullptr };
|
||||
PrefabSystemComponent* m_prefabSystemComponent{ nullptr };
|
||||
PrefabConversionUtils::EditorInfoRemover m_editorInfoRemover;
|
||||
PrefabConversionUtils::PrefabProcessorContext m_prefabProcessorContext;
|
||||
PrefabDom m_prefabDom;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Prefab/SpawnableRemoveEditorInfoTestFixture.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
using SpawnableRemoveEditorInfoTests = SpawnableRemoveEditorInfoTestFixture;
|
||||
|
||||
TEST_F(SpawnableRemoveEditorInfoTests, SpawnableRemoveEditorInfo_OnlyRuntimeEntityExported)
|
||||
{
|
||||
// Create one entity that's flagged as Editor-Only, and one that's enabled for runtime.
|
||||
CreateSourceEntity("EditorOnly", true);
|
||||
CreateSourceEntity("EditorAndRuntime", false);
|
||||
|
||||
ConvertRuntimePrefab();
|
||||
|
||||
// Only the runtime entity exists in the converted Prefab DOM.
|
||||
EXPECT_FALSE(GetRuntimeEntity("EditorOnly"));
|
||||
EXPECT_TRUE(GetRuntimeEntity("EditorAndRuntime"));
|
||||
}
|
||||
|
||||
TEST_F(SpawnableRemoveEditorInfoTests, SpawnableRemoveEditorInfo_RuntimeComponentExportedSuccessfully)
|
||||
{
|
||||
// Create a component with RuntimeExportCallback and successfully exports itself.
|
||||
CreateSourceTestExportRuntimeEntity("EntityWithRuntimeComponent", true, true);
|
||||
|
||||
ConvertRuntimePrefab();
|
||||
|
||||
// Expected result: processed entity contains the component.
|
||||
AZ::Entity* entity = GetRuntimeEntity("EntityWithRuntimeComponent");
|
||||
EXPECT_TRUE(entity);
|
||||
EXPECT_TRUE(entity->FindComponent<TestExportRuntimeComponentWithCallback>());
|
||||
}
|
||||
|
||||
TEST_F(SpawnableRemoveEditorInfoTests, RuntimeExportCallback_RuntimeComponentExportRemoved)
|
||||
{
|
||||
// Create a component with RuntimeExportCallback and successfully removes itself from exporting.
|
||||
CreateSourceTestExportRuntimeEntity("EntityWithRuntimeComponent", false, true);
|
||||
|
||||
ConvertRuntimePrefab();
|
||||
|
||||
// Expected result: processed entity does NOT contain the component.
|
||||
AZ::Entity* entity = GetRuntimeEntity("EntityWithRuntimeComponent");
|
||||
EXPECT_TRUE(entity);
|
||||
EXPECT_FALSE(entity->FindComponent<TestExportRuntimeComponentWithCallback>());
|
||||
}
|
||||
|
||||
TEST_F(SpawnableRemoveEditorInfoTests, RuntimeExportCallback_RuntimeComponentExportUnhandled)
|
||||
{
|
||||
// Create a component with RuntimeExportCallback, returns a pointer to itself, but says it wasn't handled.
|
||||
CreateSourceTestExportRuntimeEntity("EntityWithRuntimeComponent", true, false);
|
||||
|
||||
ConvertRuntimePrefab();
|
||||
|
||||
// Expected result: processed entity contains the component, because the default behavior is "clone/add" for
|
||||
// runtime components.
|
||||
AZ::Entity* entity = GetRuntimeEntity("EntityWithRuntimeComponent");
|
||||
EXPECT_TRUE(entity);
|
||||
EXPECT_TRUE(entity->FindComponent<TestExportRuntimeComponentWithCallback>());
|
||||
}
|
||||
|
||||
TEST_F(SpawnableRemoveEditorInfoTests, RuntimeExportCallback_RuntimeComponentExportRemovedAndUnhandled)
|
||||
{
|
||||
// Create a component with RuntimeExportCallback and removes itself from exporting, but says it wasn't handled.
|
||||
CreateSourceTestExportRuntimeEntity("EntityWithRuntimeComponent", false, false);
|
||||
|
||||
ConvertRuntimePrefab();
|
||||
|
||||
// Expected result: processed entity contains the component, because by saying it wasn't handled, it
|
||||
// should fall back on the default behavior of "clone/add" for runtime components.
|
||||
AZ::Entity* entity = GetRuntimeEntity("EntityWithRuntimeComponent");
|
||||
EXPECT_TRUE(entity);
|
||||
EXPECT_TRUE(entity->FindComponent<TestExportRuntimeComponentWithCallback>());
|
||||
}
|
||||
|
||||
TEST_F(SpawnableRemoveEditorInfoTests, RuntimeExportCallback_EditorComponentExportedSuccessfully)
|
||||
{
|
||||
// Create an editor component that has a RuntimeExportCallback and successfully exports itself.
|
||||
CreateSourceTestExportEditorEntity(
|
||||
"EntityWithEditorComponent",
|
||||
TestExportEditorComponent::ExportComponentType::ExportRuntimeComponentWithoutCallBack,
|
||||
true);
|
||||
|
||||
ConvertRuntimePrefab();
|
||||
|
||||
// Expected result: processed entity contains the runtime component, exported from RuntimeExportCallback.
|
||||
AZ::Entity* entity = GetRuntimeEntity("EntityWithEditorComponent");
|
||||
EXPECT_TRUE(entity);
|
||||
EXPECT_FALSE(entity->FindComponent<TestExportEditorComponent>());
|
||||
EXPECT_FALSE(entity->FindComponent<TestExportRuntimeComponentWithCallback>());
|
||||
EXPECT_TRUE(entity->FindComponent<TestExportRuntimeComponentWithoutCallback>());
|
||||
}
|
||||
|
||||
TEST_F(SpawnableRemoveEditorInfoTests, RuntimeExportCallback_EditorComponentExportRemoved)
|
||||
{
|
||||
// Create an editor component that has a RuntimeExportCallback and successfully removes itself from exporting.
|
||||
CreateSourceTestExportEditorEntity(
|
||||
"EntityWithEditorComponent",
|
||||
TestExportEditorComponent::ExportComponentType::ExportNullComponent,
|
||||
true);
|
||||
|
||||
ConvertRuntimePrefab();
|
||||
|
||||
// Expected result: processed entity does NOT contain either component.
|
||||
AZ::Entity* entity = GetRuntimeEntity("EntityWithEditorComponent");
|
||||
EXPECT_TRUE(entity);
|
||||
EXPECT_FALSE(entity->FindComponent<TestExportEditorComponent>());
|
||||
EXPECT_FALSE(entity->FindComponent<TestExportRuntimeComponentWithCallback>());
|
||||
EXPECT_FALSE(entity->FindComponent<TestExportRuntimeComponentWithoutCallback>());
|
||||
}
|
||||
|
||||
TEST_F(SpawnableRemoveEditorInfoTests, RuntimeExportCallback_EditorComponentExportUnhandledFallBackToBuildGameEntity)
|
||||
{
|
||||
// Create an editor component that has a RuntimeExportCallback, returns a pointer to itself, but says it wasn't handled.
|
||||
CreateSourceTestExportEditorEntity(
|
||||
"EntityWithEditorComponent",
|
||||
TestExportEditorComponent::ExportComponentType::ExportEditorComponent,
|
||||
false);
|
||||
|
||||
ConvertRuntimePrefab();
|
||||
|
||||
// Expected result: processed entity contains the runtime component, because the fallback to BuildGameEntity()
|
||||
// produced a runtime component.
|
||||
AZ::Entity* entity = GetRuntimeEntity("EntityWithEditorComponent");
|
||||
EXPECT_TRUE(entity);
|
||||
EXPECT_FALSE(entity->FindComponent<TestExportEditorComponent>());
|
||||
EXPECT_TRUE(entity->FindComponent<TestExportRuntimeComponentWithCallback>());
|
||||
EXPECT_FALSE(entity->FindComponent<TestExportRuntimeComponentWithoutCallback>());
|
||||
}
|
||||
|
||||
TEST_F(SpawnableRemoveEditorInfoTests, RuntimeExportCallback_EditorComponentExportRemovedAndUnhandledFallBackToBuildGameEntity)
|
||||
{
|
||||
// Create an editor component that has a RuntimeExportCallback and removes itself from exporting, but says it wasn't handled.
|
||||
CreateSourceTestExportEditorEntity(
|
||||
"EntityWithEditorComponent",
|
||||
TestExportEditorComponent::ExportComponentType::ExportNullComponent,
|
||||
false);
|
||||
|
||||
ConvertRuntimePrefab();
|
||||
|
||||
// Expected result: processed entity contains the runtime component, because the fallback to BuildGameEntity()
|
||||
// produced a runtime component.
|
||||
AZ::Entity* entity = GetRuntimeEntity("EntityWithEditorComponent");
|
||||
EXPECT_TRUE(entity);
|
||||
EXPECT_FALSE(entity->FindComponent<TestExportEditorComponent>());
|
||||
EXPECT_TRUE(entity->FindComponent<TestExportRuntimeComponentWithCallback>());
|
||||
EXPECT_FALSE(entity->FindComponent<TestExportRuntimeComponentWithoutCallback>());
|
||||
}
|
||||
|
||||
TEST_F(SpawnableRemoveEditorInfoTests, RuntimeExportCallback_EditorComponentFailsToExportItself)
|
||||
{
|
||||
// Create an editor component that has a RuntimeExportCallback and removes itself from exporting, but says it wasn't handled.
|
||||
CreateSourceTestExportEditorEntity(
|
||||
"EntityWithEditorComponent",
|
||||
TestExportEditorComponent::ExportComponentType::ExportEditorComponent,
|
||||
true);
|
||||
|
||||
// We expect the exporting to fail, since an editor component is being exported as a game component.
|
||||
ConvertRuntimePrefab(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Prefab/SpawnableSortEntitiesTestFixture.h>
|
||||
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzToolsFramework/ToolsComponents/TransformComponent.h>
|
||||
#include <Prefab/Spawnable/SpawnableUtils.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
void SpawnableSortEntitiesTestFixture::TearDownEditorFixtureImpl()
|
||||
{
|
||||
for (AZ::Entity* entity : m_sorted)
|
||||
{
|
||||
delete entity;
|
||||
}
|
||||
|
||||
m_unsorted.clear();
|
||||
m_sorted.clear();
|
||||
m_expectedEntities.clear();
|
||||
m_actualEntities.clear();
|
||||
}
|
||||
|
||||
void SpawnableSortEntitiesTestFixture::AddEntity(AZ::EntityId id, AZ::EntityId parentId, bool expectedInSorted)
|
||||
{
|
||||
auto* newEntity = aznew AZ::Entity(id);
|
||||
newEntity->CreateComponent<AzFramework::TransformComponent>()->SetParent(parentId);
|
||||
|
||||
m_unsorted.push_back(newEntity);
|
||||
if (expectedInSorted)
|
||||
{
|
||||
m_expectedEntities.insert(newEntity);
|
||||
}
|
||||
}
|
||||
|
||||
void SpawnableSortEntitiesTestFixture::AddEntity(AZ::Entity* entity, bool expectedInSorted)
|
||||
{
|
||||
m_unsorted.push_back(entity);
|
||||
if (expectedInSorted)
|
||||
{
|
||||
m_expectedEntities.insert(entity);
|
||||
}
|
||||
}
|
||||
|
||||
void SpawnableSortEntitiesTestFixture::ConvertEntitiesToSpawnable(const AZStd::vector<AZ::Entity*>& rawEntities)
|
||||
{
|
||||
auto& entities = m_spawnable.GetEntities();
|
||||
entities.clear();
|
||||
entities.reserve(rawEntities.size());
|
||||
|
||||
AZStd::for_each(rawEntities.begin(), rawEntities.end(),
|
||||
[&entities](auto& rawEntity)
|
||||
{
|
||||
entities.emplace_back(AZStd::unique_ptr<AZ::Entity>(rawEntity));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void SpawnableSortEntitiesTestFixture::ConvertoSpawnableToEntities(AZStd::vector<AZ::Entity*>& rawEntities)
|
||||
{
|
||||
auto& entities = m_spawnable.GetEntities();
|
||||
rawEntities.clear();
|
||||
rawEntities.reserve(entities.size());
|
||||
|
||||
AZStd::for_each(entities.begin(), entities.end(),
|
||||
[this, &rawEntities](auto& entity)
|
||||
{
|
||||
auto* rawEntity = entity.release();
|
||||
m_actualEntities.insert(rawEntity);
|
||||
rawEntities.emplace_back(rawEntity);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void SpawnableSortEntitiesTestFixture::SortAndSanityCheck()
|
||||
{
|
||||
ConvertEntitiesToSpawnable(m_unsorted);
|
||||
AzToolsFramework::Prefab::SpawnableUtils::SortEntitiesByTransformHierarchy(m_spawnable);
|
||||
ConvertoSpawnableToEntities(m_sorted);
|
||||
|
||||
// sanity check that all entries are still there
|
||||
EXPECT_EQ(m_expectedEntities, m_actualEntities);
|
||||
}
|
||||
|
||||
bool SpawnableSortEntitiesTestFixture::IsChildAfterParent(AZ::EntityId childId, AZ::EntityId parentId)
|
||||
{
|
||||
int parentIndex = -1;
|
||||
int childIndex = -1;
|
||||
for (int i = 0; i < m_sorted.size(); ++i)
|
||||
{
|
||||
if (m_sorted[i] && (m_sorted[i]->GetId() == parentId) && (parentIndex == -1))
|
||||
{
|
||||
parentIndex = i;
|
||||
}
|
||||
if (m_sorted[i] && (m_sorted[i]->GetId() == childId) && (childIndex == -1))
|
||||
{
|
||||
childIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_NE(childIndex, -1);
|
||||
EXPECT_NE(parentIndex, -1);
|
||||
return childIndex > parentIndex;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/std/containers/set.h>
|
||||
#include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
|
||||
#include <AzFramework/Spawnable/Spawnable.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
class SpawnableSortEntitiesTestFixture
|
||||
: public ToolsApplicationFixture
|
||||
{
|
||||
protected:
|
||||
AZStd::vector<AZ::Entity*> m_unsorted;
|
||||
AZStd::vector<AZ::Entity*> m_sorted;
|
||||
AZStd::multiset<AZ::Entity*> m_expectedEntities;
|
||||
AZStd::multiset<AZ::Entity*> m_actualEntities;
|
||||
AzFramework::Spawnable m_spawnable;
|
||||
|
||||
// Entity IDs to use in tests
|
||||
AZ::EntityId E1 = AZ::EntityId(1);
|
||||
AZ::EntityId E2 = AZ::EntityId(2);
|
||||
AZ::EntityId E3 = AZ::EntityId(3);
|
||||
AZ::EntityId E4 = AZ::EntityId(4);
|
||||
AZ::EntityId E5 = AZ::EntityId(5);
|
||||
AZ::EntityId E6 = AZ::EntityId(6);
|
||||
AZ::EntityId MissingNo = AZ::EntityId(999);
|
||||
|
||||
void TearDownEditorFixtureImpl() override;
|
||||
|
||||
// add entity to m_unsorted
|
||||
void AddEntity(AZ::EntityId id, AZ::EntityId parentId = AZ::EntityId(), bool expectedInSorted = true);
|
||||
void AddEntity(AZ::Entity* entity, bool expectedInSorted = true);
|
||||
|
||||
void ConvertEntitiesToSpawnable(const AZStd::vector<AZ::Entity*>& rawEntities);
|
||||
void ConvertoSpawnableToEntities(AZStd::vector<AZ::Entity*>& rawEntities);
|
||||
|
||||
void SortAndSanityCheck();
|
||||
|
||||
bool IsChildAfterParent(AZ::EntityId childId, AZ::EntityId parentId);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Prefab/SpawnableSortEntitiesTestFixture.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
using SpawnableSortEntitiesTests = SpawnableSortEntitiesTestFixture;
|
||||
|
||||
|
||||
TEST_F(SpawnableSortEntitiesTests, SpawnableSortEntities_0Entities_IsOk)
|
||||
{
|
||||
SortAndSanityCheck();
|
||||
}
|
||||
|
||||
TEST_F(SpawnableSortEntitiesTests, SpawnableSortEntities_1Entity_IsOk)
|
||||
{
|
||||
AddEntity(E1);
|
||||
|
||||
SortAndSanityCheck();
|
||||
}
|
||||
|
||||
TEST_F(SpawnableSortEntitiesTests, SpawnableSortEntities_ParentAndChild_SortsCorrectly)
|
||||
{
|
||||
AddEntity(E2, E1);
|
||||
AddEntity(E1);
|
||||
|
||||
SortAndSanityCheck();
|
||||
|
||||
EXPECT_TRUE(IsChildAfterParent(E2, E1));
|
||||
}
|
||||
|
||||
TEST_F(SpawnableSortEntitiesTests, SpawnableSortEntities_6EntitiesWith2Roots_SortsCorrectly)
|
||||
{
|
||||
// Hierarchy looks like:
|
||||
// 1
|
||||
// + 2
|
||||
// + 3
|
||||
// 4
|
||||
// + 5
|
||||
// + 6
|
||||
// The entities are added in "random-ish" order on purpose
|
||||
AddEntity(E3, E2);
|
||||
AddEntity(E1);
|
||||
AddEntity(E6, E4);
|
||||
AddEntity(E5, E4);
|
||||
AddEntity(E2, E1);
|
||||
AddEntity(E4);
|
||||
|
||||
SortAndSanityCheck();
|
||||
|
||||
EXPECT_TRUE(IsChildAfterParent(E2, E1));
|
||||
EXPECT_TRUE(IsChildAfterParent(E3, E2));
|
||||
EXPECT_TRUE(IsChildAfterParent(E5, E4));
|
||||
EXPECT_TRUE(IsChildAfterParent(E6, E4));
|
||||
}
|
||||
|
||||
TEST_F(SpawnableSortEntitiesTests, SpawnableSortEntities_ParentNotFound_ChildTreatedAsRoot)
|
||||
{
|
||||
AddEntity(E1);
|
||||
AddEntity(E2, E1);
|
||||
AddEntity(E3, MissingNo); // E3's parent not found
|
||||
AddEntity(E4, E3);
|
||||
|
||||
SortAndSanityCheck();
|
||||
|
||||
EXPECT_TRUE(IsChildAfterParent(E2, E1));
|
||||
EXPECT_TRUE(IsChildAfterParent(E4, E2));
|
||||
}
|
||||
|
||||
TEST_F(SpawnableSortEntitiesTests, SpawnableSortEntities_NullptrEntry_RemovedFromSorted)
|
||||
{
|
||||
AddEntity(E2, E1);
|
||||
AddEntity(nullptr, false);
|
||||
AddEntity(E1);
|
||||
|
||||
SortAndSanityCheck();
|
||||
|
||||
EXPECT_TRUE(IsChildAfterParent(E2, E1));
|
||||
}
|
||||
|
||||
TEST_F(SpawnableSortEntitiesTests, SpawnableSortEntities_DuplicateEntityId_RemovedFromSorted)
|
||||
{
|
||||
AddEntity(E2, E1);
|
||||
AddEntity(E1);
|
||||
AddEntity(E1, AZ::EntityId(), false); // duplicate EntityId
|
||||
|
||||
SortAndSanityCheck();
|
||||
|
||||
EXPECT_TRUE(IsChildAfterParent(E2, E1));
|
||||
}
|
||||
|
||||
TEST_F(SpawnableSortEntitiesTests, SpawnableSortEntities_LoopingHierarchy_PicksAnyParentAsRoot)
|
||||
{
|
||||
// loop: E1 -> E2 -> E3 -> E1 -> ...
|
||||
AddEntity(E2, E1);
|
||||
AddEntity(E3, E2);
|
||||
AddEntity(E1, E3);
|
||||
|
||||
SortAndSanityCheck();
|
||||
|
||||
AZ::EntityId first = m_sorted.front()->GetId();
|
||||
|
||||
if (first == E1)
|
||||
{
|
||||
EXPECT_TRUE(IsChildAfterParent(E2, E1));
|
||||
EXPECT_TRUE(IsChildAfterParent(E3, E2));
|
||||
}
|
||||
else if (first == E2)
|
||||
{
|
||||
EXPECT_TRUE(IsChildAfterParent(E3, E2));
|
||||
EXPECT_TRUE(IsChildAfterParent(E1, E3));
|
||||
}
|
||||
else // if (first == E3)
|
||||
{
|
||||
EXPECT_TRUE(IsChildAfterParent(E1, E3));
|
||||
EXPECT_TRUE(IsChildAfterParent(E2, E1));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(SpawnableSortEntitiesTests, SpawnableSortEntities_EntityLackingTransformComponent_IsTreatedLikeItHasNoParent)
|
||||
{
|
||||
AddEntity(E2, E1);
|
||||
AddEntity(aznew AZ::Entity(E1));
|
||||
|
||||
SortAndSanityCheck();
|
||||
|
||||
EXPECT_TRUE(IsChildAfterParent(E2, E1));
|
||||
}
|
||||
|
||||
TEST_F(SpawnableSortEntitiesTests, SpawnableSortEntities_EntityParentedToSelf_IsTreatedLikeItHasNoParent)
|
||||
{
|
||||
AddEntity(E2, E1);
|
||||
AddEntity(E1, E1); // parented to self
|
||||
|
||||
SortAndSanityCheck();
|
||||
|
||||
EXPECT_TRUE(IsChildAfterParent(E2, E1));
|
||||
}
|
||||
|
||||
TEST_F(SpawnableSortEntitiesTests, SpawnableSortEntities_EntityWithInvalidId_RemovedFromSorted)
|
||||
{
|
||||
AddEntity(E2, E1);
|
||||
AddEntity(E1);
|
||||
AddEntity(AZ::EntityId(), AZ::EntityId(), false); // entity using invalid ID as its own ID
|
||||
|
||||
SortAndSanityCheck();
|
||||
|
||||
EXPECT_TRUE(IsChildAfterParent(E2, E1));
|
||||
}
|
||||
}
|
||||
@@ -50,8 +50,11 @@ set(FILES
|
||||
Prefab/Benchmark/PrefabInstantiateBenchmarks.cpp
|
||||
Prefab/Benchmark/PrefabLoadBenchmarks.cpp
|
||||
Prefab/Benchmark/PrefabUpdateInstancesBenchmarks.cpp
|
||||
Prefab/Benchmark/SpawnableCreateBenchmarks.cpp
|
||||
Prefab/Spawnable/SpawnableMetaDataTests.cpp
|
||||
Prefab/MockPrefabFileIOActionValidator.cpp
|
||||
Prefab/MockPrefabFileIOActionValidator.h
|
||||
Prefab/PrefabEntityAliasTests.cpp
|
||||
Prefab/PrefabInstanceToTemplatePropagatorTests.cpp
|
||||
Prefab/PrefabInstantiateTests.cpp
|
||||
Prefab/PrefabLoadTemplateTests.cpp
|
||||
@@ -65,11 +68,22 @@ set(FILES
|
||||
Prefab/PrefabTestDomUtils.h
|
||||
Prefab/PrefabTestFixture.cpp
|
||||
Prefab/PrefabTestFixture.h
|
||||
Prefab/PrefabTestUndoFixture.cpp
|
||||
Prefab/PrefabTestUndoFixture.h
|
||||
Prefab/PrefabUndoLinkTests.cpp
|
||||
Prefab/PrefabUndoTests.cpp
|
||||
Prefab/PrefabTestUtils.h
|
||||
Prefab/PrefabUpdateInstancesTests.cpp
|
||||
Prefab/PrefabUpdateTemplateTests.cpp
|
||||
Prefab/PrefabUpdateWithPatchesTests.cpp
|
||||
Prefab/PrefabInstantiateTests.cpp
|
||||
Prefab/SpawnableCreateTests.cpp
|
||||
Prefab/SpawnableRemoveEditorInfoTests.cpp
|
||||
Prefab/SpawnableRemoveEditorInfoTestFixture.cpp
|
||||
Prefab/SpawnableRemoveEditorInfoTestFixture.h
|
||||
Prefab/SpawnableSortEntitiesTests.cpp
|
||||
Prefab/SpawnableSortEntitiesTestFixture.cpp
|
||||
Prefab/SpawnableSortEntitiesTestFixture.h
|
||||
Entity/EditorEntityContextComponentTests.cpp
|
||||
Entity/EditorEntitySearchComponentTests.cpp
|
||||
SliceStabilityTests/SliceStabilityTestFramework.h
|
||||
|
||||
Reference in New Issue
Block a user