#include "precompiled_unittests_gameplay.h" #include "gameplay/ClientNotifier/ClientNotifier.h" namespace ITF { // gtest & gmock use namespace testing using namespace testing; class MockClientNotifier; class MockClientClass { public: MockClientClass() : m_notifier(NULL), m_notifiesCount(0) {} ClientNotifier* m_notifier; u32 m_notifiesCount; }; class MockClientNotifier : public ClientNotifier { public: MockClientNotifier() : ClientNotifier(), m_clientsAreAttached(bfalse) {} virtual bbool addClient(MockClientClass * _newClient) override { if (ClientNotifier::addClient(_newClient)) { _newClient->m_notifier = this; return btrue; } return bfalse; } virtual bbool removeClient(MockClientClass * _client) override { if (ClientNotifier::removeClient(_client)) { _client->m_notifier = NULL; _client->m_notifiesCount = 0; return btrue; } return bfalse; } bbool areClientsAttached() const {return m_clientsAreAttached;} protected: virtual void onFirstClientAttached() override { m_clientsAreAttached = btrue; } virtual void onLastClientDetached() override { m_clientsAreAttached = bfalse; } virtual void notifyClient(MockClientClass *_client) override { _client->m_notifier = this; _client->m_notifiesCount++; } bbool m_clientsAreAttached; }; class ClientNotifierContext : public Test { public: ClientNotifierContext() : Test(), m_notifier(NULL) {} void Configure(u32 _nbClients) { m_notifier = newAlloc(mId_Gameplay, MockClientNotifier()); for (u32 i = 0; i < _nbClients; ++i) { m_mockClients.push_back(newAlloc(mId_Gameplay, MockClientClass())); } } virtual void TearDown() override { for (u32 i = 0; i < m_mockClients.size(); ++i) { SF_DEL(m_mockClients[i]); } m_mockClients.clear(); SF_DEL(m_notifier); } protected: ITF_VECTOR m_mockClients; MockClientNotifier* m_notifier; }; TEST_F(ClientNotifierContext, test_FirstAndLastClient) { Configure(3); //add a client m_notifier->addClient(m_mockClients[0]); EXPECT_EQ(btrue, m_notifier->areClientsAttached()); // remove the same client m_notifier->removeClient(m_mockClients[0]); EXPECT_EQ(bfalse, m_notifier->areClientsAttached()); // remove a client that is not added m_notifier->addClient(m_mockClients[0]); m_notifier->removeClient(m_mockClients[1]); EXPECT_EQ(btrue, m_notifier->areClientsAttached()); //add a second client & remove the first one m_notifier->addClient(m_mockClients[1]); m_notifier->removeClient(m_mockClients[0]); EXPECT_EQ(btrue, m_notifier->areClientsAttached()); //add the first & third client m_notifier->addClient(m_mockClients[2]); m_notifier->addClient(m_mockClients[0]); EXPECT_EQ(btrue, m_notifier->areClientsAttached()); //remove the second one m_notifier->removeClient(m_mockClients[1]); EXPECT_EQ(btrue, m_notifier->areClientsAttached()); //remove again the second one m_notifier->removeClient(m_mockClients[1]); EXPECT_EQ(btrue, m_notifier->areClientsAttached()); //remove the second one m_notifier->removeClient(m_mockClients[0]); m_notifier->removeClient(m_mockClients[2]); EXPECT_EQ(bfalse, m_notifier->areClientsAttached()); } TEST_F(ClientNotifierContext, test_ClientNotifications) { Configure(2); //client 0 added m_notifier->addClient(m_mockClients[0]); //Should be attached but Shouldn't be notified before first update EXPECT_EQ(m_notifier, m_mockClients[0]->m_notifier); EXPECT_EQ(0U, m_mockClients[0]->m_notifiesCount); m_notifier->update(1.0f); EXPECT_EQ(m_notifier, m_mockClients[0]->m_notifier); EXPECT_EQ(1U, m_mockClients[0]->m_notifiesCount); //same client added, should not be notified twice m_notifier->addClient(m_mockClients[0]); m_notifier->update(1.0f); EXPECT_EQ(m_notifier, m_mockClients[0]->m_notifier); EXPECT_EQ(1U, m_mockClients[0]->m_notifiesCount); //client 1 added, should notify only this one m_notifier->addClient(m_mockClients[1]); m_notifier->update(1.0f); EXPECT_EQ(m_notifier, m_mockClients[0]->m_notifier); EXPECT_EQ(1U, m_mockClients[0]->m_notifiesCount); EXPECT_EQ(m_notifier,m_mockClients[1]->m_notifier); EXPECT_EQ(1U, m_mockClients[1]->m_notifiesCount); // client 0 removed m_notifier->removeClient(m_mockClients[0]); //should be cleared EXPECT_TRUE(m_mockClients[0]->m_notifier == NULL); EXPECT_EQ(0U, m_mockClients[0]->m_notifiesCount); m_notifier->update(1.0f); EXPECT_TRUE(m_mockClients[0]->m_notifier == NULL); EXPECT_EQ(0U, m_mockClients[0]->m_notifiesCount); EXPECT_EQ(m_notifier,m_mockClients[1]->m_notifier); EXPECT_EQ(1U, m_mockClients[1]->m_notifiesCount); // client 0 added, should be notified again m_notifier->addClient(m_mockClients[0]); m_notifier->update(1.0f); EXPECT_EQ(m_notifier, m_mockClients[0]->m_notifier); EXPECT_EQ(1U, m_mockClients[0]->m_notifiesCount); EXPECT_EQ(m_notifier,m_mockClients[1]->m_notifier); EXPECT_EQ(1U, m_mockClients[1]->m_notifiesCount); m_notifier->removeClient(m_mockClients[0]); m_notifier->removeClient(m_mockClients[1]); //should be changed before the update EXPECT_TRUE(m_mockClients[0]->m_notifier == NULL); EXPECT_EQ(0U, m_mockClients[0]->m_notifiesCount); EXPECT_TRUE(m_mockClients[1]->m_notifier == NULL); EXPECT_EQ(0U, m_mockClients[1]->m_notifiesCount); m_notifier->update(1.0f); //should not change after the update EXPECT_TRUE(m_mockClients[0]->m_notifier == NULL); EXPECT_EQ(0U, m_mockClients[0]->m_notifiesCount); EXPECT_TRUE(m_mockClients[1]->m_notifier == NULL); EXPECT_EQ(0U, m_mockClients[1]->m_notifiesCount); } TEST_F(ClientNotifierContext, test_ClientsCount) { Configure(5); //Add client 0 m_notifier->addClient(m_mockClients[0]); //Should already be count 1 before update EXPECT_EQ(1U, m_notifier->getClientsCount()); m_notifier->update(1.0f); //Should still be count 1 after update EXPECT_EQ(1U, m_notifier->getClientsCount()); m_notifier->addClient(m_mockClients[1]); m_notifier->addClient(m_mockClients[2]); EXPECT_EQ(3U, m_notifier->getClientsCount()); m_notifier->update(1.0f); EXPECT_EQ(3U, m_notifier->getClientsCount()); m_notifier->addClient(m_mockClients[3]); m_notifier->addClient(m_mockClients[4]); EXPECT_EQ(5U, m_notifier->getClientsCount()); m_notifier->update(1.0f); EXPECT_EQ(5U, m_notifier->getClientsCount()); m_notifier->removeClient(m_mockClients[3]); //should be updated before update EXPECT_EQ(4U, m_notifier->getClientsCount()); m_notifier->update(1.0f); EXPECT_EQ(4U, m_notifier->getClientsCount()); //removing an already removed client and another one m_notifier->removeClient(m_mockClients[3]); m_notifier->removeClient(m_mockClients[1]); EXPECT_EQ(3U, m_notifier->getClientsCount()); //adding cl3 again and remove cl0 & cl2, cl1 already removed, count should be 2 (cl3 & cl4) m_notifier->addClient(m_mockClients[3]); m_notifier->removeClient(m_mockClients[0]); m_notifier->removeClient(m_mockClients[1]); m_notifier->removeClient(m_mockClients[2]); EXPECT_EQ(2U, m_notifier->getClientsCount()); //remove cl3 & cl4, cl0 already removed, count should be 0 m_notifier->removeClient(m_mockClients[0]); m_notifier->removeClient(m_mockClients[3]); m_notifier->removeClient(m_mockClients[4]); EXPECT_EQ(0U, m_notifier->getClientsCount()); EXPECT_EQ(bfalse, m_notifier->areClientsAttached()); } }