PrefabProcessorRemoveComponentPerPlatformTests.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzCore/UnitTest/TestTypes.h>
  9. #include <AzFramework/Components/TransformComponent.h>
  10. #include <AzFramework/Spawnable/Spawnable.h>
  11. #include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
  12. #include <AzToolsFramework/Prefab/Spawnable/AssetPlatformComponentRemover.h>
  13. #include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
  14. #include <Prefab/PrefabDomTypes.h>
  15. #include <Prefab/Spawnable/PrefabProcessorContext.h>
  16. namespace UnitTest
  17. {
  18. constexpr AZ::Uuid Uuid_RemoveThisComponent("{6E29CD1C-D2CF-4763-80E1-F45FFA439A6A}");
  19. constexpr AZ::Uuid Uuid_KeepThisComponent("{9218A873-1525-4278-AC07-17AD6A6B8374}");
  20. constexpr AZ::Uuid Uuid_DependentComponent("{95421870-F6FD-44D2-AA5F-AF85FD977F75}");
  21. const AZStd::set<AZ::Uuid> ExcludedComponents = { Uuid_RemoveThisComponent };
  22. const char* PlatformTag = "platform_1";
  23. const char* EntityName = "entity_1";
  24. const AZ::Crc32 ComponentService = AZ_CRC_CE("good_service");
  25. class KeepThisComponent : public AZ::Component
  26. {
  27. public:
  28. AZ_COMPONENT(KeepThisComponent, Uuid_KeepThisComponent);
  29. static void Reflect(AZ::ReflectContext* context)
  30. {
  31. if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  32. {
  33. serializeContext->Class<KeepThisComponent, AZ::Component>()->Version(1);
  34. }
  35. }
  36. KeepThisComponent() = default;
  37. void Activate() override {}
  38. void Deactivate() override {}
  39. };
  40. class RemoveThisComponent : public AZ::Component
  41. {
  42. public:
  43. AZ_COMPONENT(RemoveThisComponent, Uuid_RemoveThisComponent);
  44. static void Reflect(AZ::ReflectContext* context)
  45. {
  46. if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  47. {
  48. serializeContext->Class<RemoveThisComponent, AZ::Component>()->Version(1);
  49. }
  50. }
  51. RemoveThisComponent() = default;
  52. void Activate() override {}
  53. void Deactivate() override {}
  54. static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
  55. {
  56. provided.push_back(ComponentService);
  57. }
  58. };
  59. class DependentComponent : public AZ::Component
  60. {
  61. public:
  62. AZ_COMPONENT(DependentComponent, Uuid_DependentComponent);
  63. static void Reflect(AZ::ReflectContext* context)
  64. {
  65. if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  66. {
  67. serializeContext->Class<DependentComponent, AZ::Component>()->Version(1);
  68. }
  69. }
  70. DependentComponent() = default;
  71. void Activate() override {}
  72. void Deactivate() override {}
  73. static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
  74. {
  75. required.push_back(ComponentService);
  76. }
  77. };
  78. class PrefabProcessingTestFixture
  79. : public LeakDetectionFixture
  80. {
  81. public:
  82. void SetUp() override
  83. {
  84. m_application.reset(aznew AzToolsFramework::ToolsApplication());
  85. m_application.get()->Start(AzFramework::Application::Descriptor());
  86. m_application.get()->RegisterComponentDescriptor(KeepThisComponent::CreateDescriptor());
  87. m_application.get()->RegisterComponentDescriptor(RemoveThisComponent::CreateDescriptor());
  88. m_application.get()->RegisterComponentDescriptor(DependentComponent::CreateDescriptor());
  89. AZStd::map<AZStd::string, AZStd::set<AZ::Uuid>> platformExcludedComponents;
  90. platformExcludedComponents.emplace(PlatformTag, ExcludedComponents);
  91. m_processor.m_platformExcludedComponents = platformExcludedComponents;
  92. }
  93. void TearDown() override
  94. {
  95. AZ::Interface<AzToolsFramework::Prefab::PrefabSystemComponentInterface>::Get()->RemoveAllTemplates();
  96. m_application.get()->Stop();
  97. m_application.reset();
  98. }
  99. static void ConvertEntitiesToPrefab(const AZStd::vector<AZ::Entity*>& entities, AzToolsFramework::Prefab::PrefabDom& prefabDom)
  100. {
  101. auto* prefabSystem = AZ::Interface<AzToolsFramework::Prefab::PrefabSystemComponentInterface>::Get();
  102. AZStd::unique_ptr<AzToolsFramework::Prefab::Instance> sourceInstance(prefabSystem->CreatePrefab(entities, {}, "test/my_prefab"));
  103. ASSERT_TRUE(sourceInstance);
  104. auto& prefabTemplateDom = prefabSystem->FindTemplateDom(sourceInstance->GetTemplateId());
  105. prefabDom.CopyFrom(prefabTemplateDom, prefabDom.GetAllocator());
  106. }
  107. static AZ::Entity* CreateSourceEntity(const char* name, AZStd::vector<AZ::Uuid> components, AZ::Entity* parent = nullptr)
  108. {
  109. AZ::Entity* entity = aznew AZ::Entity(name);
  110. auto* transformComponent = entity->CreateComponent<AzFramework::TransformComponent>();
  111. if (parent)
  112. {
  113. transformComponent->SetParent(parent->GetId());
  114. }
  115. for (auto componentUUID : components)
  116. {
  117. entity->CreateComponent(componentUUID);
  118. }
  119. entity->Init();
  120. entity->Activate();
  121. return entity;
  122. }
  123. AZStd::unique_ptr<AzToolsFramework::ToolsApplication> m_application = {};
  124. AzToolsFramework::Prefab::PrefabConversionUtils::AssetPlatformComponentRemover m_processor;
  125. };
  126. TEST_F(PrefabProcessingTestFixture, PrefabProcessorRemoveComponentPerPlatform_RemoveSingleComponent)
  127. {
  128. using namespace AzToolsFramework::Prefab::PrefabConversionUtils;
  129. // Add the prefab into the Prefab Processor Context
  130. PrefabProcessorContext prefabProcessorContext{ AZ::Uuid::CreateRandom() };
  131. prefabProcessorContext.SetPlatformTags({ AZ::Crc32(PlatformTag) });
  132. // Create a prefab
  133. PrefabDocument document("testPrefab");
  134. AzToolsFramework::Prefab::PrefabDom prefabDom;
  135. AZStd::vector<AZ::Entity*> entities;
  136. entities.emplace_back(CreateSourceEntity(EntityName, { Uuid_RemoveThisComponent, Uuid_KeepThisComponent }));
  137. ConvertEntitiesToPrefab(entities, prefabDom);
  138. ASSERT_TRUE(document.SetPrefabDom(AZStd::move(prefabDom)));
  139. prefabProcessorContext.AddPrefab(AZStd::move(document));
  140. // Validate the component exists before processing and removed afterward
  141. prefabProcessorContext.ListPrefabs(
  142. [](PrefabDocument& prefab) -> void
  143. {
  144. prefab.GetInstance().GetAllEntitiesInHierarchy(
  145. [](AZStd::unique_ptr<AZ::Entity>& entity) -> bool
  146. {
  147. if (entity->GetName() == EntityName)
  148. {
  149. EXPECT_NE(entity->FindComponent(Uuid_RemoveThisComponent), nullptr);
  150. EXPECT_NE(entity->FindComponent(Uuid_KeepThisComponent), nullptr);
  151. }
  152. return true;
  153. }
  154. );
  155. }
  156. );
  157. // Process Prefab
  158. m_processor.Process(prefabProcessorContext);
  159. ASSERT_TRUE(prefabProcessorContext.HasPrefabs());
  160. ASSERT_TRUE(prefabProcessorContext.HasCompletedSuccessfully());
  161. // Validate 1 component is removed
  162. prefabProcessorContext.ListPrefabs(
  163. [](PrefabDocument& prefab) -> void
  164. {
  165. prefab.GetInstance().GetAllEntitiesInHierarchy(
  166. [](AZStd::unique_ptr<AZ::Entity>& entity) -> bool
  167. {
  168. if (entity->GetName() == EntityName)
  169. {
  170. EXPECT_EQ(entity->FindComponent(Uuid_RemoveThisComponent), nullptr);
  171. EXPECT_NE(entity->FindComponent(Uuid_KeepThisComponent), nullptr);
  172. }
  173. return true;
  174. }
  175. );
  176. }
  177. );
  178. }
  179. TEST_F(PrefabProcessingTestFixture, PrefabProcessorRemoveComponentPerPlatform_ComponentDependencyError)
  180. {
  181. using namespace AzToolsFramework::Prefab::PrefabConversionUtils;
  182. // Add the prefab into the Prefab Processor Context
  183. PrefabProcessorContext prefabProcessorContext{ AZ::Uuid::CreateRandom() };
  184. prefabProcessorContext.SetPlatformTags({ AZ::Crc32(PlatformTag) });
  185. // Create a prefab
  186. PrefabDocument document("testPrefab");
  187. AzToolsFramework::Prefab::PrefabDom prefabDom;
  188. AZStd::vector<AZ::Entity*> entities;
  189. entities.emplace_back(CreateSourceEntity(EntityName, { Uuid_RemoveThisComponent, Uuid_KeepThisComponent, Uuid_DependentComponent }));
  190. ConvertEntitiesToPrefab(entities, prefabDom);
  191. ASSERT_TRUE(document.SetPrefabDom(AZStd::move(prefabDom)));
  192. prefabProcessorContext.AddPrefab(AZStd::move(document));
  193. // Process Prefab
  194. AZ_TEST_START_TRACE_SUPPRESSION;
  195. m_processor.Process(prefabProcessorContext);
  196. AZ_TEST_STOP_TRACE_SUPPRESSION(1); //< Expect 1 error due to missing a component dependency
  197. ASSERT_FALSE(prefabProcessorContext.HasCompletedSuccessfully());
  198. }
  199. } // namespace UnitTest