3
0

SliceStabilityCreateTests.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  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 <Tests/SliceStabilityTests/SliceStabilityTestFramework.h>
  9. #include <AzToolsFramework/ToolsComponents/TransformComponent.h>
  10. namespace UnitTest
  11. {
  12. TEST_F(SliceStabilityTest, CreateSlice_ValidSingleParentEntityWithValidChildEntity_EntityStateRemainsTheSame_FT)
  13. {
  14. AUTO_RESULT_IF_SETTING_TRUE(UnitTest::prefabSystemSetting, true)
  15. // Generate Parent entity
  16. AzToolsFramework::EntityIdList liveEntityIds;
  17. AZ::EntityId parent = CreateEditorEntity("Parent", liveEntityIds);
  18. ASSERT_TRUE(parent.IsValid());
  19. // Generate Child entity and set its parent to Parent entity
  20. ASSERT_TRUE(CreateEditorEntity("Child", liveEntityIds, parent).IsValid());
  21. // Capture initial hierarchy state
  22. EXPECT_TRUE(m_validator.Capture(liveEntityIds));
  23. // Create slice from hierarchy
  24. AZ::SliceComponent::SliceInstanceAddress sliceInstanceAddress;
  25. ASSERT_TRUE(CreateSlice("NewSlice", liveEntityIds, sliceInstanceAddress).IsValid());
  26. // Compare generated slice instance to initial capture state
  27. EXPECT_TRUE(m_validator.Compare(sliceInstanceAddress));
  28. }
  29. TEST_F(SliceStabilityTest, CreateSlice_ValidGrandparentParentChildHierarchy_EntityStateRemainsTheSame_FT)
  30. {
  31. AUTO_RESULT_IF_SETTING_TRUE(UnitTest::prefabSystemSetting, true)
  32. // Build Grandparent->Parent->Child and link parent entities between them
  33. AzToolsFramework::EntityIdList liveEntityIds;
  34. AZ::EntityId grandparent = CreateEditorEntity("Grandparent", liveEntityIds);
  35. ASSERT_TRUE(grandparent.IsValid());
  36. AZ::EntityId parent = CreateEditorEntity("Parent", liveEntityIds, grandparent);
  37. ASSERT_TRUE(parent.IsValid());
  38. ASSERT_TRUE(CreateEditorEntity("Child", liveEntityIds, parent).IsValid());
  39. // Capture initial hierarchy state
  40. EXPECT_TRUE(m_validator.Capture(liveEntityIds));
  41. // Create slice from hierarchy
  42. AZ::SliceComponent::SliceInstanceAddress sliceInstanceAddress;
  43. ASSERT_TRUE(CreateSlice("NewSlice", liveEntityIds, sliceInstanceAddress).IsValid());
  44. // Compare generated slice instance to initial capture state
  45. EXPECT_TRUE(m_validator.Compare(sliceInstanceAddress));
  46. }
  47. TEST_F(SliceStabilityTest, CreateSlice_10DeepParentChildHierarchy_EntityStateRemainsTheSame_FT)
  48. {
  49. AUTO_RESULT_IF_SETTING_TRUE(UnitTest::prefabSystemSetting, true)
  50. AzToolsFramework::EntityIdList liveEntityIds;
  51. // Build a 10 entity deep hierarchy
  52. AZ::EntityId parent;
  53. for (size_t entityCounter = 0; entityCounter < 10; ++entityCounter)
  54. {
  55. // For each iteration capture the entity made to be used as the parent for the next
  56. parent = CreateEditorEntity(AZStd::string::format("Entity Level %zu", entityCounter).c_str(), liveEntityIds, parent);
  57. ASSERT_TRUE(parent.IsValid());
  58. }
  59. // Capture the hierarchy state
  60. EXPECT_TRUE(m_validator.Capture(liveEntityIds));
  61. // Create slice from hierarchy
  62. AZ::SliceComponent::SliceInstanceAddress sliceInstanceAddress;
  63. ASSERT_TRUE(CreateSlice("NewSlice", liveEntityIds, sliceInstanceAddress).IsValid());
  64. // Compare generated slice instance to initial capture state
  65. EXPECT_TRUE(m_validator.Compare(sliceInstanceAddress));
  66. }
  67. TEST_F(SliceStabilityTest, CreateSlice_ValidParentWith10ValidChildren_EntityStateRemainsTheSame_FT)
  68. {
  69. AUTO_RESULT_IF_SETTING_TRUE(UnitTest::prefabSystemSetting, true)
  70. AzToolsFramework::EntityIdList liveEntityIds;
  71. // Create the parent entity and hold on to its id
  72. AZ::EntityId parent = CreateEditorEntity("Parent", liveEntityIds);
  73. ASSERT_TRUE(parent.IsValid());
  74. // Build 10 children and set all of their parent ids to the same parent entity
  75. for (size_t childEntityCounter = 0; childEntityCounter < 10; ++childEntityCounter)
  76. {
  77. ASSERT_TRUE(CreateEditorEntity(AZStd::string::format("Child #%zu", childEntityCounter + 1).c_str(), liveEntityIds, parent).IsValid());
  78. }
  79. // Capture the hierarchy state
  80. EXPECT_TRUE(m_validator.Capture(liveEntityIds));
  81. // Create slice from hierarchy
  82. AZ::SliceComponent::SliceInstanceAddress sliceInstanceAddress;
  83. ASSERT_TRUE(CreateSlice("NewSlice", liveEntityIds, sliceInstanceAddress).IsValid());
  84. // Compare generated slice instance to initial capture state
  85. EXPECT_TRUE(m_validator.Compare(sliceInstanceAddress));
  86. }
  87. TEST_F(SliceStabilityTest, CreateSlice_ValidParentEntityWithValidChildEntity_OnlyChildEntityAddedToSlice_EntityStateRemainsTheSame_FT)
  88. {
  89. AUTO_RESULT_IF_SETTING_TRUE(UnitTest::prefabSystemSetting, true)
  90. AzToolsFramework::EntityIdList liveEntityIds;
  91. // Build parent and child entities and connect child to parent
  92. AZ::EntityId parent = CreateEditorEntity("Parent", liveEntityIds);
  93. ASSERT_TRUE(parent.IsValid());
  94. AZ::EntityId child = CreateEditorEntity("Child", liveEntityIds, parent);
  95. ASSERT_TRUE(child.IsValid());
  96. // Capture just the child to compare to
  97. EXPECT_TRUE(m_validator.Capture({ child }));
  98. // Build a slice from only the child entity
  99. AZ::SliceComponent::SliceInstanceAddress sliceInstanceAddress;
  100. ASSERT_TRUE(CreateSlice("NewSlice", { child }, sliceInstanceAddress).IsValid());
  101. // Validate that the slice instance only contains the child entity
  102. EXPECT_TRUE(m_validator.Compare(sliceInstanceAddress));
  103. }
  104. TEST_F(SliceStabilityTest, CreateSlice_EntityWithExternalReference_ExternalReferenceEntityAutoAddedToSlice_EntityStateRemainsTheSame_FT)
  105. {
  106. AUTO_RESULT_IF_SETTING_TRUE(UnitTest::prefabSystemSetting, true)
  107. // Generate a root entity that will be referenced externally by the entities used to create the slice
  108. AzToolsFramework::EntityIdList liveEntityIds;
  109. AZ::EntityId externalRootId = CreateEditorEntity("ExternalRoot", liveEntityIds);
  110. ASSERT_TRUE(externalRootId.IsValid());
  111. // Generate the entity that will contain the external entity reference to ExternalRoot and set its parent to ExternalRoot
  112. AZ::EntityId entityWithExternalReferenceId = CreateEditorEntity("EntityWithExternalReference", liveEntityIds, externalRootId);
  113. ASSERT_TRUE(entityWithExternalReferenceId.IsValid());
  114. // Acquire the Entity* of EntityWithExternalReference and validate that we successfully acquired it
  115. AZ::Entity* entityWithExternalReference = FindEntityInEditor(entityWithExternalReferenceId);
  116. ASSERT_TRUE(entityWithExternalReference);
  117. // Deactivate the entity so that we can give it a new component
  118. entityWithExternalReference->Deactivate();
  119. // Add an EntityReferenceComponent to EntityWithExternalReference and validate that the component was successfully created
  120. EntityReferenceComponent* externalEntityReferenceComponent = entityWithExternalReference->CreateComponent<EntityReferenceComponent>();
  121. ASSERT_TRUE(externalEntityReferenceComponent);
  122. // Activate the entity
  123. entityWithExternalReference->Activate();
  124. // Set its external entity reference field to the ExternalRoot
  125. externalEntityReferenceComponent->m_entityReference = externalRootId;
  126. // Capture the hierarchy state
  127. EXPECT_TRUE(m_validator.Capture(liveEntityIds));
  128. // Create a slice just from the entity containing the external reference
  129. // Create slice should detect the external reference and auto add ExternalRoot to the slice
  130. AZ::SliceComponent::SliceInstanceAddress sliceInstanceAddress;
  131. ASSERT_TRUE(CreateSlice("Slice1", { entityWithExternalReferenceId }, sliceInstanceAddress).IsValid());
  132. // Validate that the slice instance contains both entities
  133. // Confirming that the externally referenced entity was auto added
  134. EXPECT_TRUE(m_validator.Compare(sliceInstanceAddress));
  135. }
  136. TEST_F(SliceStabilityTest, CreateSlice_2ValidWithSharedParent_ParentNotIncludedInSliceCreate_ParentIsGenerated_EntityStateRemainsTheSame_FT)
  137. {
  138. AUTO_RESULT_IF_SETTING_TRUE(UnitTest::prefabSystemSetting, true)
  139. // Create a shared parent that won't be included in the CreateSlice call
  140. // Including a shared parent will validate that the generated parent becomes a child of the original parent
  141. // A generated parent is made because CreateSlice will not have a parent entity to work with and one is required
  142. AzToolsFramework::EntityIdList rootParentEntityId;
  143. AZ::EntityId rootParentEntity = CreateEditorEntity("RootParentEntity", rootParentEntityId);
  144. ASSERT_TRUE(rootParentEntity.IsValid());
  145. // Create two entities and set their parent to rootParentEntity
  146. AzToolsFramework::EntityIdList liveEntityIds;
  147. AZ::EntityId entity1Id = CreateEditorEntity("Entity1", liveEntityIds, rootParentEntity);
  148. ASSERT_TRUE(entity1Id.IsValid());
  149. AZ::EntityId entity2Id = CreateEditorEntity("Entity2", liveEntityIds, rootParentEntity);
  150. ASSERT_TRUE(entity2Id.IsValid());
  151. // Gather the transform data of entity 1 and entity 2
  152. // Also set the transform data of entity 1 to be different from entity 2
  153. // Since we're calling multiple TransformBus events on entity 1
  154. // We can batch them in an Event lambda
  155. AZ::Transform entity1WorldTransform;
  156. AZ::TransformBus::Event(entity1Id, [&entity1WorldTransform]
  157. (AZ::TransformInterface* transformInterface)
  158. {
  159. AZ::Vector3 entity1LocalTranslate = transformInterface->GetLocalTranslation();
  160. AZ::Vector3 entity1LocalRotation = transformInterface->GetLocalRotation();
  161. transformInterface->SetLocalTranslation(entity1LocalTranslate * 2);
  162. transformInterface->SetLocalRotation(entity1LocalRotation * 2);
  163. entity1WorldTransform = transformInterface->GetWorldTM();
  164. });
  165. AZ::Transform entity2WorldTransform;
  166. AZ::TransformBus::EventResult(entity2WorldTransform, entity2Id, &AZ::TransformBus::Events::GetWorldTM);
  167. // Validate that both transforms are different from the identity
  168. // Validate that both transforms are different from each other
  169. EXPECT_FALSE(entity1WorldTransform.IsClose(AZ::Transform::Identity()));
  170. EXPECT_FALSE(entity2WorldTransform.IsClose(AZ::Transform::Identity()));
  171. EXPECT_FALSE(entity1WorldTransform.IsClose(entity2WorldTransform));
  172. // Create a slice from these two entities
  173. // Create slice should detect that the provided entity list does not contain a shared parent and will generate one
  174. AZ::SliceComponent::SliceInstanceAddress sliceInstanceAddress;
  175. ASSERT_TRUE(CreateSlice("NewSlice", liveEntityIds, sliceInstanceAddress).IsValid());
  176. // Grab the instantiated entities within the generated slice instance
  177. const AZ::SliceComponent::InstantiatedContainer* sliceInstanceEntities = sliceInstanceAddress.GetInstance()->GetInstantiated();
  178. ASSERT_TRUE(sliceInstanceEntities);
  179. // Confirm that it contains 3 entities (Entity1, Entity2, GeneratedRoot)
  180. EXPECT_EQ(sliceInstanceEntities->m_entities.size(), 3);
  181. // Validate that the entities are not null
  182. ASSERT_TRUE(sliceInstanceEntities->m_entities[0]);
  183. ASSERT_TRUE(sliceInstanceEntities->m_entities[1]);
  184. ASSERT_TRUE(sliceInstanceEntities->m_entities[2]);
  185. // Validate that the first two entities have the same ids as Entity1 and Entity2
  186. EXPECT_EQ(sliceInstanceEntities->m_entities[0]->GetId(), entity1Id);
  187. EXPECT_EQ(sliceInstanceEntities->m_entities[1]->GetId(), entity2Id);
  188. // Get Entity1's parent id
  189. AZ::EntityId entity1Parent;
  190. AZ::TransformBus::EventResult(entity1Parent, entity1Id, &AZ::TransformBus::Events::GetParentId);
  191. // Get Entity2's parent id
  192. AZ::EntityId entity2Parent;
  193. AZ::TransformBus::EventResult(entity2Parent, entity2Id, &AZ::TransformBus::Events::GetParentId);
  194. // Confirm the parent id is valid and the same between Entity1 and Entity2
  195. EXPECT_TRUE(entity1Parent.IsValid());
  196. EXPECT_EQ(entity1Parent, entity2Parent);
  197. // Confirm that the parentId is not the original parent but instead a new parent
  198. EXPECT_NE(entity1Parent, rootParentEntity);
  199. // Get the parent of entity 1 and 2's parent
  200. // This should be the original rootParentEntity
  201. AZ::EntityId grandparent;
  202. AZ::TransformBus::EventResult(grandparent, entity1Parent, &AZ::TransformBus::Events::GetParentId);
  203. // Confirm that the new parent is a child of the original parent
  204. EXPECT_EQ(grandparent, rootParentEntity);
  205. // Gather the transform information of entity 1 and entity 2 after the create slice operation
  206. AZ::Transform entity1SliceWorldTransform;
  207. AZ::TransformBus::EventResult(entity1SliceWorldTransform, entity1Id, &AZ::TransformBus::Events::GetWorldTM);
  208. AZ::Transform entity2SliceWorldTransform;
  209. AZ::TransformBus::EventResult(entity2SliceWorldTransform, entity2Id, &AZ::TransformBus::Events::GetWorldTM);
  210. // Validate that the create slice operation did not impact the transform data
  211. EXPECT_TRUE(entity1WorldTransform.IsClose(entity1SliceWorldTransform));
  212. EXPECT_TRUE(entity2WorldTransform.IsClose(entity2SliceWorldTransform));
  213. }
  214. TEST_F(SliceStabilityTest, CreateSlice_TestSubsliceOfSameType_EntityStateRemainsTheSame_FT)
  215. {
  216. AUTO_RESULT_IF_SETTING_TRUE(UnitTest::prefabSystemSetting, true)
  217. // Create a Root entity
  218. AzToolsFramework::EntityIdList liveEntityIds;
  219. AZ::EntityId rootEntity = CreateEditorEntity("Root", liveEntityIds);
  220. ASSERT_TRUE(rootEntity.IsValid());
  221. // Capture entity state
  222. EXPECT_TRUE(m_validator.Capture(liveEntityIds));
  223. // Create slice from root entity
  224. AZ::SliceComponent::SliceInstanceAddress parentSliceInstance;
  225. AZ::Data::AssetId parentSliceId = CreateSlice("InheritedSlice", liveEntityIds, parentSliceInstance);
  226. ASSERT_TRUE(parentSliceId.IsValid());
  227. // Compare generated slice instance to initial capture state
  228. EXPECT_TRUE(m_validator.Compare(parentSliceInstance));
  229. m_validator.Reset();
  230. // Create a second instance of the slice and make it a child of the Root entity
  231. AZ::SliceComponent::SliceInstanceAddress childSliceInstance = InstantiateEditorSlice(parentSliceId, liveEntityIds, rootEntity);
  232. ASSERT_TRUE(childSliceInstance.IsValid());
  233. // Capture this new hierarchy state
  234. EXPECT_TRUE(m_validator.Capture(liveEntityIds));
  235. // Create a slice from this new hierarchy
  236. AZ::SliceComponent::SliceInstanceAddress finalSliceInstance;
  237. AZ::Data::AssetId finalSliceId = CreateSlice("FinalSlice", liveEntityIds, finalSliceInstance);
  238. ASSERT_TRUE(finalSliceId.IsValid());
  239. // Compare genarated slice instance to capture state
  240. EXPECT_TRUE(m_validator.Compare(finalSliceInstance));
  241. }
  242. TEST_F(SliceStabilityTest, CreateSlice_TestSubsliceOfDifferentType_EntityStateRemainsTheSame_FT)
  243. {
  244. AUTO_RESULT_IF_SETTING_TRUE(UnitTest::prefabSystemSetting, true)
  245. // Create a root entity to be used in Slice1
  246. AzToolsFramework::EntityIdList slice1Entities;
  247. AZ::EntityId slice1Root = CreateEditorEntity("Slice1Root", slice1Entities);
  248. ASSERT_TRUE(slice1Root.IsValid());
  249. // Capture the entity state of Slice1Root
  250. EXPECT_TRUE(m_validator.Capture(slice1Entities));
  251. // Create a slice from Slice1Root
  252. AZ::SliceComponent::SliceInstanceAddress slice1Instance;
  253. ASSERT_TRUE(CreateSlice("Slice1", slice1Entities, slice1Instance).IsValid());
  254. // Compare generated slice1Instance to Slice1Root
  255. EXPECT_TRUE(m_validator.Compare(slice1Instance));
  256. m_validator.Reset();
  257. // Create a root entity to be used in Slice2
  258. AzToolsFramework::EntityIdList slice2Entities;
  259. AZ::EntityId slice2Root = CreateEditorEntity("Slice2Root", slice2Entities);
  260. ASSERT_TRUE(slice2Root.IsValid());
  261. // Capture the entity state of Slice2Root
  262. EXPECT_TRUE(m_validator.Capture(slice2Entities));
  263. // Create a slice from Slice2Root
  264. AZ::SliceComponent::SliceInstanceAddress slice2Instance;
  265. ASSERT_TRUE(CreateSlice("Slice2", slice2Entities, slice2Instance).IsValid());
  266. // Compare generated slice2Instance to Slice2Root
  267. EXPECT_TRUE(m_validator.Compare(slice2Instance));
  268. m_validator.Reset();
  269. // Make Slice1Root the parent of Slice2Root
  270. AZ::TransformBus::Event(slice2Root, &AZ::TransformBus::Events::SetParent, slice1Root);
  271. // Validate that the parent of Slice2Root was correctly set
  272. AZ::EntityId slice2RootParent;
  273. AZ::TransformBus::EventResult(slice2RootParent, slice2Root, &AZ::TransformBus::Events::GetParentId);
  274. EXPECT_EQ(slice2RootParent, slice1Root);
  275. // Combine entity lists
  276. AzToolsFramework::EntityIdList slice3Entities = slice1Entities;
  277. slice3Entities.insert(slice3Entities.end(), slice2Entities.begin(), slice2Entities.end());
  278. // Capture final hierarchy state
  279. EXPECT_TRUE(m_validator.Capture(slice3Entities));
  280. // Create a slice from final hiararchy
  281. AZ::SliceComponent::SliceInstanceAddress slice3Instance;
  282. ASSERT_TRUE(CreateSlice("Slice3", slice3Entities, slice3Instance).IsValid());
  283. // Compare generated slice instance to capture state
  284. EXPECT_TRUE(m_validator.Compare(slice3Instance));
  285. }
  286. TEST_F(SliceStabilityTest, CreateSlice_Test10DeepSliceAncestry_EntityStateRemainsTheSame_InstanceAncestryIntact_FT)
  287. {
  288. AUTO_RESULT_IF_SETTING_TRUE(UnitTest::prefabSystemSetting, true)
  289. AZ::u32 totalAncestors = 10;
  290. // Generate a Root entity
  291. AzToolsFramework::EntityIdList liveEntityIds;
  292. AZ::EntityId rootEntity = CreateEditorEntity("Root", liveEntityIds);
  293. ASSERT_TRUE(rootEntity.IsValid());
  294. // Capture the entity state of Root
  295. EXPECT_TRUE(m_validator.Capture(liveEntityIds));
  296. AZ::SliceComponent::SliceInstanceAddress sliceInstanceAddress;
  297. for (AZ::u32 ancestorCount = 0; ancestorCount < totalAncestors; ++ancestorCount)
  298. {
  299. // Continue to make a slice off of Root entity where each iteration Root entity is owned by an instance of the previously made slice
  300. // For each iteration validate the state of each instance matches the state of the initally captured Root entity state
  301. ASSERT_TRUE(CreateSlice(AZStd::string::format("Slice Level: %i", ancestorCount + 1).c_str(), liveEntityIds, sliceInstanceAddress).IsValid());
  302. EXPECT_TRUE(m_validator.Compare(sliceInstanceAddress));
  303. }
  304. // Acquire the ancestor hierarchy of Root entity
  305. // We pass in totalAncestors + 1 for maxLevels to ensure we rule out the ancestry is greater than expected fail state
  306. AZ::SliceComponent::EntityAncestorList ancestors;
  307. sliceInstanceAddress.GetReference()->GetInstanceEntityAncestry(rootEntity, ancestors, totalAncestors + 1);
  308. // Confirm that the ancestor hierarchy size is the same as the number of slices we iteratively built off of Root entity
  309. EXPECT_EQ(ancestors.size(), totalAncestors);
  310. }
  311. TEST_F(SliceStabilityTest, CreateSlice_Test5DeepSliceAncestryWithSubslices_EntityStateRemainsTheSame_FT)
  312. {
  313. AUTO_RESULT_IF_SETTING_TRUE(UnitTest::prefabSystemSetting, true)
  314. // Generate a Root entity
  315. AzToolsFramework::EntityIdList liveEntityIds;
  316. AZ::EntityId rootEntity = CreateEditorEntity("Root", liveEntityIds);
  317. ASSERT_TRUE(rootEntity.IsValid());
  318. // This loop moves each iteration's hierarchy into a slice instance
  319. // It then instantiates a second instance and places the second instance under the original hierachy
  320. // This results in the number of entities growing at a power of 2
  321. AZ::SliceComponent::SliceInstanceAddress sliceInstanceAddress;
  322. for (size_t ancestorCount = 0; ancestorCount < 5; ++ancestorCount)
  323. {
  324. // Each iteration capture the entity hierarchy state
  325. EXPECT_TRUE(m_validator.Capture(liveEntityIds));
  326. // Create a slice from the current hierarchy
  327. AZ::Data::AssetId newSlice = CreateSlice(AZStd::string::format("Slice Level: %zu", ancestorCount + 1).c_str(), liveEntityIds, sliceInstanceAddress);
  328. ASSERT_TRUE(newSlice.IsValid());
  329. // Compare the generated slice instance against the capture state and reset the capture for the next iteration
  330. EXPECT_TRUE(m_validator.Compare(sliceInstanceAddress));
  331. m_validator.Reset();
  332. // Instantiate a second copy of this iteration's slice and set Root entity as its parent
  333. // liveEntityIds is updated by this call to include the new instances entities
  334. ASSERT_TRUE(InstantiateEditorSlice(newSlice, liveEntityIds, rootEntity).IsValid());
  335. }
  336. }
  337. TEST_F(SliceStabilityTest, CreateSlice_TestOverride_OverrideAppliesSuccesfully_FT)
  338. {
  339. AUTO_RESULT_IF_SETTING_TRUE(UnitTest::prefabSystemSetting, true)
  340. // Generate a Root entity
  341. AzToolsFramework::EntityIdList liveEntityIds;
  342. ASSERT_TRUE(CreateEditorEntity("Root", liveEntityIds).IsValid());
  343. // Capture the Root entity state
  344. EXPECT_TRUE(m_validator.Capture(liveEntityIds));
  345. // Create a slice from Root entity
  346. AZ::SliceComponent::SliceInstanceAddress sliceInstanceAddress;
  347. ASSERT_TRUE(CreateSlice("Slice1", liveEntityIds, sliceInstanceAddress).IsValid());
  348. // Compare the generated slice instance to the capture state and then reset capture state
  349. EXPECT_TRUE(m_validator.Compare(sliceInstanceAddress));
  350. m_validator.Reset();
  351. // Validator passing guarantees instance and its instantiated container are not nullptr and instantiated is size 1
  352. const AZ::SliceComponent::InstantiatedContainer* instantiatedEntities = sliceInstanceAddress.GetInstance()->GetInstantiated();
  353. // Confirm that the first entity entry is not nullptr
  354. EXPECT_TRUE(instantiatedEntities->m_entities[0]);
  355. // Rename the Root entity
  356. constexpr const char* newRootName = "Renamed Root";
  357. instantiatedEntities->m_entities[0]->SetName(newRootName);
  358. // Capture the new entity state which includes the rename
  359. EXPECT_TRUE(m_validator.Capture(liveEntityIds));
  360. // Create a slice from the renamed Root
  361. // This should create a slice with an override on Slice1 that performs the entity rename
  362. AZ::SliceComponent::SliceInstanceAddress slice2InstanceAddress;
  363. AZ::Data::AssetId slice2Asset = CreateSlice("Slice2", liveEntityIds, slice2InstanceAddress);
  364. ASSERT_TRUE(slice2Asset.IsValid());
  365. // Compare the generated slice instance to the captured entity state
  366. EXPECT_TRUE(m_validator.Compare(slice2InstanceAddress));
  367. // Instantiate a second instance of this slice
  368. // We want to validate that further instantiations after the slice create persist the override
  369. AzToolsFramework::EntityIdList slice2NewInstanceEntities;
  370. AZ::SliceComponent::SliceInstanceAddress slice2NewInstanceAddress = InstantiateEditorSlice(slice2Asset, slice2NewInstanceEntities);
  371. // Confirm the instance is valid
  372. ASSERT_TRUE(slice2NewInstanceAddress.IsValid());
  373. // Acquire the instantiated container from the instance and confirm the container is valid
  374. const AZ::SliceComponent::SliceInstance* slice2NewInstance = slice2NewInstanceAddress.GetInstance();
  375. const AZ::SliceComponent::InstantiatedContainer* newSlice2InstantiatedEntities = slice2NewInstance->GetInstantiated();
  376. ASSERT_TRUE(newSlice2InstantiatedEntities);
  377. // Confirm that the slice instance contains only 1 entity and that its name matches the renamed entity
  378. ASSERT_EQ(newSlice2InstantiatedEntities->m_entities.size(), 1);
  379. ASSERT_TRUE(newSlice2InstantiatedEntities->m_entities[0]);
  380. EXPECT_EQ(newSlice2InstantiatedEntities->m_entities[0]->GetName(), newRootName);
  381. }
  382. }