PrefabComponentAliasTests.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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 <Prefab/PrefabTestFixture.h>
  9. #include <Prefab/PrefabTestComponent.h>
  10. #include <AzToolsFramework/API/EntityCompositionRequestBus.h>
  11. #include <AzToolsFramework/Prefab/PrefabDomUtils.h>
  12. namespace UnitTest
  13. {
  14. using PrefabComponentAliasTest = PrefabTestFixture;
  15. static void CreateAndValidateComponentAlias(const AZ::Entity::ComponentArrayType& componentsToAdd, AZStd::string entityAlias, AZ::Dom::Path pathToComponent)
  16. {
  17. Instance prefab;
  18. AZStd::unique_ptr<AZ::Entity> entityInPrefab = AZStd::make_unique<AZ::Entity>();
  19. for (AZ::Component* component: componentsToAdd)
  20. {
  21. entityInPrefab->AddComponent(component);
  22. }
  23. prefab.AddEntity(AZStd::move(entityInPrefab), AZStd::move(entityAlias));
  24. PrefabDom prefabDom;
  25. PrefabDomUtils::StoreInstanceInPrefabDom(prefab, prefabDom);
  26. PrefabDomPath domPathToComponents(pathToComponent.ToString().c_str());
  27. const PrefabDomValue* componentsDom = domPathToComponents.Get(prefabDom);
  28. EXPECT_EQ(componentsDom->IsNull(), false);
  29. }
  30. TEST_F(PrefabComponentAliasTest, TypeNameBasedAliasIsCreatedWhenAliasAbsent)
  31. {
  32. AZStd::string entityAlias = "EntityAlias";
  33. AZ::Dom::Path pathToComponent = AZ::Dom::Path(PrefabDomUtils::EntitiesName) / entityAlias.c_str() / PrefabDomUtils::ComponentsName /
  34. PrefabTestComponent::RTTI_TypeName();
  35. // Validate that the typename is set as component alias.
  36. CreateAndValidateComponentAlias(
  37. AZ::Entity::ComponentArrayType{ aznew PrefabTestComponent() }, AZStd::move(entityAlias), pathToComponent);
  38. }
  39. TEST_F(PrefabComponentAliasTest, NumberedAliasesCreatedForMultipleComponentsWithSameType)
  40. {
  41. AZStd::string entityAlias = "EntityAlias";
  42. AZStd::string secondComponentAlias = AZStd::string::format("%s_%u", PrefabTestComponent::RTTI_TypeName(), 2);
  43. AZ::Dom::Path pathToSecondComponent = AZ::Dom::Path(PrefabDomUtils::EntitiesName) / entityAlias.c_str() /
  44. PrefabDomUtils::ComponentsName / secondComponentAlias.c_str();
  45. // Validate that the second component got a number next to the typename as alias.
  46. CreateAndValidateComponentAlias(
  47. AZ::Entity::ComponentArrayType{ aznew PrefabTestComponent(), aznew PrefabTestComponent() },
  48. AZStd::move(entityAlias),
  49. pathToSecondComponent);
  50. }
  51. TEST_F(PrefabComponentAliasTest, AliasNotCreatedWhenAliasAlreadyPresent)
  52. {
  53. PrefabTestComponent* prefabTestComponent = aznew PrefabTestComponent();
  54. AZStd::string customComponentAlias = "CustomSerializedIdentifier";
  55. AZStd::string entityAlias = "EntityAlias";
  56. // This is analogous to reading a component from prefab file since we set component aliases when a prefab is loaded from JSON.
  57. prefabTestComponent->SetSerializedIdentifier(customComponentAlias);
  58. AZ::Dom::Path pathToComponent = AZ::Dom::Path(PrefabDomUtils::EntitiesName) / entityAlias.c_str() / PrefabDomUtils::ComponentsName /
  59. customComponentAlias.c_str();
  60. // Validate that serializing the component again won't make it lose its custom alias. This proves that aliases in existing prefabs
  61. // will not get changed when the same prefab is saved again.
  62. CreateAndValidateComponentAlias(AZ::Entity::ComponentArrayType{ prefabTestComponent }, AZStd::move(entityAlias), pathToComponent);
  63. }
  64. TEST_F(PrefabComponentAliasTest, UnderlyingTypeNameAliasCreatedForGenericComponentWrapper)
  65. {
  66. AZ::EntityId entityId = CreateEditorEntityUnderRoot("entity");
  67. AZ::Entity* entityInPrefab = nullptr;
  68. AZ::ComponentApplicationBus::BroadcastResult(entityInPrefab, &AZ::ComponentApplicationBus::Events::FindEntity, entityId);
  69. ASSERT_TRUE(entityInPrefab);
  70. entityInPrefab->Deactivate();
  71. // In order to make make a GenericComponentWrapper wrap against a non-editor component( doesn't derive from EditorComponentBase),
  72. // we need to add component this way. This is what happens when users try to add a non-editor component in the inspector too
  73. AzToolsFramework::EntityCompositionRequests::AddComponentsOutcome addComponentsOutcome;
  74. AzToolsFramework::EntityCompositionRequestBus::BroadcastResult(
  75. addComponentsOutcome,
  76. &AzToolsFramework::EntityCompositionRequests::AddComponentsToEntities,
  77. AzToolsFramework::EntityIdList{ entityId },
  78. AZ::ComponentTypeList{ PrefabNonEditorComponent::RTTI_Type() });
  79. InstanceOptionalReference prefab = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
  80. EXPECT_TRUE(prefab.has_value());
  81. PrefabDom prefabDom;
  82. PrefabDomUtils::StoreInstanceInPrefabDom(prefab->get(), prefabDom);
  83. AZ::Dom::Path pathToComponent = AZ::Dom::Path(PrefabDomUtils::EntitiesName) / prefab->get().GetEntityAliases().front().c_str() /
  84. PrefabDomUtils::ComponentsName / PrefabNonEditorComponent::RTTI_TypeName();
  85. PrefabDomPath domPathToComponents(pathToComponent.ToString().c_str());
  86. const PrefabDomValue* componentsDom = domPathToComponents.Get(prefabDom);
  87. ASSERT_EQ(componentsDom->IsNull(), false);
  88. }
  89. } // namespace UnitTest