From 66bd95d4711c4ef75ef34aa959e652bb7ccfcdd3 Mon Sep 17 00:00:00 2001 From: codereader Date: Sun, 17 Oct 2021 07:11:28 +0200 Subject: [PATCH] #5613: Tests covering the EntityKeyValue observer behaviour on regular change and removal. --- test/Entity.cpp | 139 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) diff --git a/test/Entity.cpp b/test/Entity.cpp index e8880e32ce..71fc7c0458 100644 --- a/test/Entity.cpp +++ b/test/Entity.cpp @@ -5,6 +5,7 @@ #include "irendersystemfactory.h" #include "iselectable.h" #include "iselection.h" +#include "iundo.h" #include "ishaders.h" #include "icolourscheme.h" #include "ieclasscolours.h" @@ -15,6 +16,7 @@ #include "registry/registry.h" #include "eclass.h" #include "string/join.h" +#include "scenelib.h" namespace test { @@ -984,6 +986,46 @@ inline bool stackHasKeyValuePair(const std::vectorforEachEntityKeyValue([&](const std::string& key, EntityKeyValue& value) + { + if (!keyValue && key == keyToFind) + { + keyValue = &value; + } + }); + + return keyValue; +} + } TEST_F(EntityTest, EntityObserverAttachDetach) @@ -1149,4 +1191,101 @@ TEST_F(EntityTest, EntityObserverKeyChange) "Erase stack unexpectedly contained the kv " << NameKey << " = " << EvenNewerName; } +TEST_F(EntityTest, KeyObserverAttachDetach) +{ + auto guardNode = createByClassName("atdm:ai_builder_guard"); + auto guard = Node_getEntity(guardNode); + + constexpr const char* NewKeyName = "New_Unique_Key"; + constexpr const char* NewKeyValue = "New_Unique_Value"; + guard->setKeyValue(NewKeyName, NewKeyValue); + + TestKeyObserver observer; + + EntityKeyValue* keyValue = findKeyValue(guard, NewKeyName); + EXPECT_TRUE(keyValue != nullptr) << "Could not locate the key value"; + + // On attachment, the observer gets notified about the existing value + keyValue->attach(observer); + + EXPECT_TRUE(observer.hasBeenInvoked) << "Observer didn't get notified on attach"; + EXPECT_EQ(observer.receivedValue, NewKeyValue) << "Observer didn't get the correct value"; + + observer.reset(); + observer.receivedValue = "dummyvalue_that_should_be_overwritten"; + + // On detaching the observer receives another call with an empty value + keyValue->detach(observer); + + EXPECT_TRUE(observer.hasBeenInvoked) << "Observer didn't get notified on attach"; + EXPECT_EQ(observer.receivedValue, "") << "Observer didn't get the expected empty value"; +} + +TEST_F(EntityTest, KeyObserverValueChange) +{ + auto guardNode = createByClassName("atdm:ai_builder_guard"); + auto guard = Node_getEntity(guardNode); + + constexpr const char* NewKeyName = "New_Unique_Key"; + constexpr const char* NewKeyValue = "New_Unique_Value"; + guard->setKeyValue(NewKeyName, NewKeyValue); + + TestKeyObserver observer; + + EntityKeyValue* keyValue = findKeyValue(guard, NewKeyName); + EXPECT_TRUE(keyValue != nullptr) << "Could not locate the key value"; + + keyValue->attach(observer); + observer.reset(); + + constexpr const char* SomeOtherValue = "SomeOtherValue"; + guard->setKeyValue(NewKeyName, SomeOtherValue); + + EXPECT_TRUE(observer.hasBeenInvoked) << "Observer didn't get notified on change"; + EXPECT_EQ(observer.receivedValue, SomeOtherValue) << "Observer didn't get the correct value"; + + // One more round, this time we use the assign() method + observer.reset(); + constexpr const char* DistinguishableValue = "DistinguishableValue"; + keyValue->assign(DistinguishableValue); + + EXPECT_TRUE(observer.hasBeenInvoked) << "Observer didn't get notified on assign"; + EXPECT_EQ(observer.receivedValue, DistinguishableValue) << "Observer didn't get the correct value"; + observer.reset(); + + keyValue->detach(observer); + + EXPECT_TRUE(observer.hasBeenInvoked) << "Observer didn't get notified on attach"; + EXPECT_EQ(observer.receivedValue, "") << "Observer didn't get the expected empty value"; +} + +// KeyObserver doesn't get called when a key is removed entirely from the SpawnArgs +TEST_F(EntityTest, KeyObserverKeyRemoval) +{ + auto guardNode = createByClassName("atdm:ai_builder_guard"); + scene::addNodeToContainer(guardNode, GlobalMapModule().getRoot()); + auto guard = Node_getEntity(guardNode); + + constexpr const char* NewKeyName = "New_Unique_Key"; + constexpr const char* NewKeyValue = "New_Unique_Value"; + guard->setKeyValue(NewKeyName, NewKeyValue); + + UndoableCommand cmd("removeKey"); // prevent the key value from going out of scope + TestKeyObserver observer; + + EntityKeyValue* keyValue = findKeyValue(guard, NewKeyName); + EXPECT_TRUE(keyValue != nullptr) << "Could not locate the key value"; + + keyValue->attach(observer); + observer.reset(); + + // Remove the key + guard->setKeyValue(NewKeyName, ""); + + // The observer shouldn't have been notified + EXPECT_FALSE(observer.hasBeenInvoked) << "Observer has been notified on key remove"; + + keyValue->detach(observer); +} + } \ No newline at end of file