feat: Add some save data tests (#1623)

* saving from a test works

* testing works

* Update SavingTests.cpp

* test dServer stuff

* tests

* use dummy database and add missing pure fns

* add more tests

* add more tests

* add rocket tests

* Update BuffComponent.h

* Update test_xml_data.xml

* Update SavingTests.cpp

* update
This commit is contained in:
David Markowitz 2024-11-17 16:27:33 -08:00 committed by GitHub
parent 008e2d4dce
commit adc9cd2876
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 570 additions and 6 deletions

View File

@ -8,9 +8,15 @@ foreach(file ${DDATABSE_DATABSES_MYSQL_SOURCES})
set(DDATABASE_GAMEDATABASE_SOURCES ${DDATABASE_GAMEDATABASE_SOURCES} "MySQL/${file}") set(DDATABASE_GAMEDATABASE_SOURCES ${DDATABASE_GAMEDATABASE_SOURCES} "MySQL/${file}")
endforeach() endforeach()
add_subdirectory(TestSQL)
foreach(file ${DDATABSE_DATABSES_TEST_SQL_SOURCES})
set(DDATABASE_GAMEDATABASE_SOURCES ${DDATABASE_GAMEDATABASE_SOURCES} "TestSQL/${file}")
endforeach()
add_library(dDatabaseGame STATIC ${DDATABASE_GAMEDATABASE_SOURCES}) add_library(dDatabaseGame STATIC ${DDATABASE_GAMEDATABASE_SOURCES})
target_include_directories(dDatabaseGame PUBLIC "." target_include_directories(dDatabaseGame PUBLIC "."
"ITables" PRIVATE "MySQL" "ITables" PRIVATE "MySQL" "TestSQL"
"${PROJECT_SOURCE_DIR}/dCommon" "${PROJECT_SOURCE_DIR}/dCommon"
"${PROJECT_SOURCE_DIR}/dCommon/dEnums" "${PROJECT_SOURCE_DIR}/dCommon/dEnums"
) )

View File

@ -38,3 +38,8 @@ void Database::Destroy(std::string source) {
LOG("Trying to destroy database when it's not connected!"); LOG("Trying to destroy database when it's not connected!");
} }
} }
void Database::_setDatabase(GameDatabase* const db) {
if (database) delete database;
database = db;
}

View File

@ -9,4 +9,8 @@ namespace Database {
void Connect(); void Connect();
GameDatabase* Get(); GameDatabase* Get();
void Destroy(std::string source = ""); void Destroy(std::string source = "");
// Used for assigning a test database as the handler for database logic.
// Do not use in production code.
void _setDatabase(GameDatabase* const db);
}; };

View File

@ -0,0 +1,4 @@
SET(DDATABSE_DATABSES_TEST_SQL_SOURCES
"TestSQLDatabase.cpp"
PARENT_SCOPE
)

View File

@ -0,0 +1,306 @@
#include "TestSQLDatabase.h"
void TestSQLDatabase::Connect() {
}
void TestSQLDatabase::Destroy(std::string source) {
}
sql::PreparedStatement* TestSQLDatabase::CreatePreppedStmt(const std::string& query) {
return nullptr;
}
void TestSQLDatabase::Commit() {
}
bool TestSQLDatabase::GetAutoCommit() {
return {};
}
void TestSQLDatabase::SetAutoCommit(bool value) {
}
void TestSQLDatabase::ExecuteCustomQuery(const std::string_view query) {
}
std::optional<IServers::MasterInfo> TestSQLDatabase::GetMasterInfo() {
return {};
}
std::vector<std::string> TestSQLDatabase::GetApprovedCharacterNames() {
return {};
}
std::vector<FriendData> TestSQLDatabase::GetFriendsList(uint32_t charID) {
return {};
}
std::optional<IFriends::BestFriendStatus> TestSQLDatabase::GetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId) {
return {};
}
void TestSQLDatabase::SetBestFriendStatus(const uint32_t playerAccountId, const uint32_t friendAccountId, const uint32_t bestFriendStatus) {
}
void TestSQLDatabase::AddFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) {
}
void TestSQLDatabase::RemoveFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) {
}
void TestSQLDatabase::UpdateActivityLog(const uint32_t characterId, const eActivityType activityType, const LWOMAPID mapId) {
}
void TestSQLDatabase::DeleteUgcModelData(const LWOOBJID& modelId) {
}
void TestSQLDatabase::UpdateUgcModelData(const LWOOBJID& modelId, std::istringstream& lxfml) {
}
std::vector<IUgc::Model> TestSQLDatabase::GetAllUgcModels() {
return {};
}
void TestSQLDatabase::CreateMigrationHistoryTable() {
}
bool TestSQLDatabase::IsMigrationRun(const std::string_view str) {
return {};
}
void TestSQLDatabase::InsertMigration(const std::string_view str) {
}
std::optional<ICharInfo::Info> TestSQLDatabase::GetCharacterInfo(const uint32_t charId) {
return {};
}
std::optional<ICharInfo::Info> TestSQLDatabase::GetCharacterInfo(const std::string_view charId) {
return {};
}
std::string TestSQLDatabase::GetCharacterXml(const uint32_t accountId) {
return {};
}
void TestSQLDatabase::UpdateCharacterXml(const uint32_t characterId, const std::string_view lxfml) {
}
std::optional<IAccounts::Info> TestSQLDatabase::GetAccountInfo(const std::string_view username) {
return {};
}
void TestSQLDatabase::InsertNewCharacter(const ICharInfo::Info info) {
}
void TestSQLDatabase::InsertCharacterXml(const uint32_t accountId, const std::string_view lxfml) {
}
std::vector<uint32_t> TestSQLDatabase::GetAccountCharacterIds(uint32_t accountId) {
return {};
}
void TestSQLDatabase::DeleteCharacter(const uint32_t characterId) {
}
void TestSQLDatabase::SetCharacterName(const uint32_t characterId, const std::string_view name) {
}
void TestSQLDatabase::SetPendingCharacterName(const uint32_t characterId, const std::string_view name) {
}
void TestSQLDatabase::UpdateLastLoggedInCharacter(const uint32_t characterId) {
}
void TestSQLDatabase::SetPetNameModerationStatus(const LWOOBJID& petId, const IPetNames::Info& info) {
}
std::optional<IPetNames::Info> TestSQLDatabase::GetPetNameInfo(const LWOOBJID& petId) {
return {};
}
std::optional<IProperty::Info> TestSQLDatabase::GetPropertyInfo(const LWOMAPID mapId, const LWOCLONEID cloneId) {
return {};
}
void TestSQLDatabase::UpdatePropertyModerationInfo(const IProperty::Info& info) {
}
void TestSQLDatabase::UpdatePropertyDetails(const IProperty::Info& info) {
}
void TestSQLDatabase::InsertNewProperty(const IProperty::Info& info, const uint32_t templateId, const LWOZONEID& zoneId) {
}
std::vector<IPropertyContents::Model> TestSQLDatabase::GetPropertyModels(const LWOOBJID& propertyId) {
return {};
}
void TestSQLDatabase::RemoveUnreferencedUgcModels() {
}
void TestSQLDatabase::InsertNewPropertyModel(const LWOOBJID& propertyId, const IPropertyContents::Model& model, const std::string_view name) {
}
void TestSQLDatabase::UpdateModel(const LWOOBJID& propertyId, const NiPoint3& position, const NiQuaternion& rotation, const std::array<std::pair<int32_t, std::string>, 5>& behaviors) {
}
void TestSQLDatabase::RemoveModel(const LWOOBJID& modelId) {
}
void TestSQLDatabase::UpdatePerformanceCost(const LWOZONEID& zoneId, const float performanceCost) {
}
void TestSQLDatabase::InsertNewBugReport(const IBugReports::Info& info) {
}
void TestSQLDatabase::InsertCheatDetection(const IPlayerCheatDetections::Info& info) {
}
void TestSQLDatabase::InsertNewMail(const IMail::MailInfo& mail) {
}
void TestSQLDatabase::InsertNewUgcModel(std::istringstream& sd0Data, const uint32_t blueprintId, const uint32_t accountId, const uint32_t characterId) {
}
std::vector<IMail::MailInfo> TestSQLDatabase::GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) {
return {};
}
std::optional<IMail::MailInfo> TestSQLDatabase::GetMail(const uint64_t mailId) {
return {};
}
uint32_t TestSQLDatabase::GetUnreadMailCount(const uint32_t characterId) {
return {};
}
void TestSQLDatabase::MarkMailRead(const uint64_t mailId) {
}
void TestSQLDatabase::DeleteMail(const uint64_t mailId) {
}
void TestSQLDatabase::ClaimMailItem(const uint64_t mailId) {
}
void TestSQLDatabase::InsertSlashCommandUsage(const uint32_t characterId, const std::string_view command) {
}
void TestSQLDatabase::UpdateAccountUnmuteTime(const uint32_t accountId, const uint64_t timeToUnmute) {
}
void TestSQLDatabase::UpdateAccountBan(const uint32_t accountId, const bool banned) {
}
void TestSQLDatabase::UpdateAccountPassword(const uint32_t accountId, const std::string_view bcryptpassword) {
}
void TestSQLDatabase::InsertNewAccount(const std::string_view username, const std::string_view bcryptpassword) {
}
void TestSQLDatabase::SetMasterIp(const std::string_view ip, const uint32_t port) {
}
std::optional<uint32_t> TestSQLDatabase::GetCurrentPersistentId() {
return {};
}
void TestSQLDatabase::InsertDefaultPersistentId() {
}
void TestSQLDatabase::UpdatePersistentId(const uint32_t id) {
}
std::optional<uint32_t> TestSQLDatabase::GetDonationTotal(const uint32_t activityId) {
return {};
}
std::optional<bool> TestSQLDatabase::IsPlaykeyActive(const int32_t playkeyId) {
return {};
}
std::vector<IUgc::Model> TestSQLDatabase::GetUgcModels(const LWOOBJID& propertyId) {
return {};
}
void TestSQLDatabase::AddIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) {
}
void TestSQLDatabase::RemoveIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) {
}
std::vector<IIgnoreList::Info> TestSQLDatabase::GetIgnoreList(const uint32_t playerId) {
return {};
}
void TestSQLDatabase::InsertRewardCode(const uint32_t account_id, const uint32_t reward_code) {
}
std::vector<uint32_t> TestSQLDatabase::GetRewardCodesByAccountID(const uint32_t account_id) {
return {};
}
void TestSQLDatabase::AddBehavior(const IBehaviors::Info& info) {
}
std::string TestSQLDatabase::GetBehavior(const int32_t behaviorId) {
return {};
}
void TestSQLDatabase::RemoveBehavior(const int32_t behaviorId) {
}
void TestSQLDatabase::UpdateAccountGmLevel(const uint32_t accountId, const eGameMasterLevel gmLevel) {
}

View File

@ -0,0 +1,95 @@
#ifndef TESTSQLDATABASE_H
#define TESTSQLDATABASE_H
#include "GameDatabase.h"
class TestSQLDatabase : public GameDatabase {
void Connect() override;
void Destroy(std::string source = "") override;
sql::PreparedStatement* CreatePreppedStmt(const std::string& query) override;
void Commit() override;
bool GetAutoCommit() override;
void SetAutoCommit(bool value) override;
void ExecuteCustomQuery(const std::string_view query) override;
// Overloaded queries
std::optional<IServers::MasterInfo> GetMasterInfo() override;
std::vector<std::string> GetApprovedCharacterNames() override;
std::vector<FriendData> GetFriendsList(uint32_t charID) override;
std::optional<IFriends::BestFriendStatus> GetBestFriendStatus(const uint32_t playerCharacterId, const uint32_t friendCharacterId) override;
void SetBestFriendStatus(const uint32_t playerAccountId, const uint32_t friendAccountId, const uint32_t bestFriendStatus) override;
void AddFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) override;
void RemoveFriend(const uint32_t playerAccountId, const uint32_t friendAccountId) override;
void UpdateActivityLog(const uint32_t characterId, const eActivityType activityType, const LWOMAPID mapId) override;
void DeleteUgcModelData(const LWOOBJID& modelId) override;
void UpdateUgcModelData(const LWOOBJID& modelId, std::istringstream& lxfml) override;
std::vector<IUgc::Model> GetAllUgcModels() override;
void CreateMigrationHistoryTable() override;
bool IsMigrationRun(const std::string_view str) override;
void InsertMigration(const std::string_view str) override;
std::optional<ICharInfo::Info> GetCharacterInfo(const uint32_t charId) override;
std::optional<ICharInfo::Info> GetCharacterInfo(const std::string_view charId) override;
std::string GetCharacterXml(const uint32_t accountId) override;
void UpdateCharacterXml(const uint32_t characterId, const std::string_view lxfml) override;
std::optional<IAccounts::Info> GetAccountInfo(const std::string_view username) override;
void InsertNewCharacter(const ICharInfo::Info info) override;
void InsertCharacterXml(const uint32_t accountId, const std::string_view lxfml) override;
std::vector<uint32_t> GetAccountCharacterIds(uint32_t accountId) override;
void DeleteCharacter(const uint32_t characterId) override;
void SetCharacterName(const uint32_t characterId, const std::string_view name) override;
void SetPendingCharacterName(const uint32_t characterId, const std::string_view name) override;
void UpdateLastLoggedInCharacter(const uint32_t characterId) override;
void SetPetNameModerationStatus(const LWOOBJID& petId, const IPetNames::Info& info) override;
std::optional<IPetNames::Info> GetPetNameInfo(const LWOOBJID& petId) override;
std::optional<IProperty::Info> GetPropertyInfo(const LWOMAPID mapId, const LWOCLONEID cloneId) override;
void UpdatePropertyModerationInfo(const IProperty::Info& info) override;
void UpdatePropertyDetails(const IProperty::Info& info) override;
void InsertNewProperty(const IProperty::Info& info, const uint32_t templateId, const LWOZONEID& zoneId) override;
std::vector<IPropertyContents::Model> GetPropertyModels(const LWOOBJID& propertyId) override;
void RemoveUnreferencedUgcModels() override;
void InsertNewPropertyModel(const LWOOBJID& propertyId, const IPropertyContents::Model& model, const std::string_view name) override;
void UpdateModel(const LWOOBJID& propertyId, const NiPoint3& position, const NiQuaternion& rotation, const std::array<std::pair<int32_t, std::string>, 5>& behaviors) override;
void RemoveModel(const LWOOBJID& modelId) override;
void UpdatePerformanceCost(const LWOZONEID& zoneId, const float performanceCost) override;
void InsertNewBugReport(const IBugReports::Info& info) override;
void InsertCheatDetection(const IPlayerCheatDetections::Info& info) override;
void InsertNewMail(const IMail::MailInfo& mail) override;
void InsertNewUgcModel(
std::istringstream& sd0Data,
const uint32_t blueprintId,
const uint32_t accountId,
const uint32_t characterId) override;
std::vector<IMail::MailInfo> GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) override;
std::optional<IMail::MailInfo> GetMail(const uint64_t mailId) override;
uint32_t GetUnreadMailCount(const uint32_t characterId) override;
void MarkMailRead(const uint64_t mailId) override;
void DeleteMail(const uint64_t mailId) override;
void ClaimMailItem(const uint64_t mailId) override;
void InsertSlashCommandUsage(const uint32_t characterId, const std::string_view command) override;
void UpdateAccountUnmuteTime(const uint32_t accountId, const uint64_t timeToUnmute) override;
void UpdateAccountBan(const uint32_t accountId, const bool banned) override;
void UpdateAccountPassword(const uint32_t accountId, const std::string_view bcryptpassword) override;
void InsertNewAccount(const std::string_view username, const std::string_view bcryptpassword) override;
void SetMasterIp(const std::string_view ip, const uint32_t port) override;
std::optional<uint32_t> GetCurrentPersistentId() override;
void InsertDefaultPersistentId() override;
void UpdatePersistentId(const uint32_t id) override;
std::optional<uint32_t> GetDonationTotal(const uint32_t activityId) override;
std::optional<bool> IsPlaykeyActive(const int32_t playkeyId) override;
std::vector<IUgc::Model> GetUgcModels(const LWOOBJID& propertyId) override;
void AddIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) override;
void RemoveIgnore(const uint32_t playerId, const uint32_t ignoredPlayerId) override;
std::vector<IIgnoreList::Info> GetIgnoreList(const uint32_t playerId) override;
void InsertRewardCode(const uint32_t account_id, const uint32_t reward_code) override;
std::vector<uint32_t> GetRewardCodesByAccountID(const uint32_t account_id) override;
void AddBehavior(const IBehaviors::Info& info) override;
std::string GetBehavior(const int32_t behaviorId) override;
void RemoveBehavior(const int32_t behaviorId) override;
void UpdateAccountGmLevel(const uint32_t accountId, const eGameMasterLevel gmLevel) override;
};
#endif //!TESTSQLDATABASE_H

View File

@ -40,8 +40,8 @@ void Character::UpdateInfoFromDatabase() {
auto charInfo = Database::Get()->GetCharacterInfo(m_ID); auto charInfo = Database::Get()->GetCharacterInfo(m_ID);
if (charInfo) { if (charInfo) {
m_Name = charInfo->name; m_Name = charInfo->name;
m_UnapprovedName = charInfo->pendingName; m_UnapprovedName = charInfo->pendingName;
m_NameRejected = charInfo->needsRename; m_NameRejected = charInfo->needsRename;
m_PropertyCloneID = charInfo->cloneId; m_PropertyCloneID = charInfo->cloneId;
m_PermissionMap = charInfo->permissionMap; m_PermissionMap = charInfo->permissionMap;

View File

@ -38,6 +38,7 @@ public:
const std::string& GetXMLData() const { return m_XMLData; } const std::string& GetXMLData() const { return m_XMLData; }
const tinyxml2::XMLDocument& GetXMLDoc() const { return m_Doc; } const tinyxml2::XMLDocument& GetXMLDoc() const { return m_Doc; }
void _setXmlDoc(tinyxml2::XMLDocument& doc) { doc.DeepCopy(&m_Doc); }
/** /**
* Out of abundance of safety and clarity of what this saves, this is its own function. * Out of abundance of safety and clarity of what this saves, this is its own function.
@ -459,6 +460,10 @@ public:
User* GetParentUser() const { return m_ParentUser; } User* GetParentUser() const { return m_ParentUser; }
void _doQuickXMLDataParse() { DoQuickXMLDataParse(); }
void _setXmlData(const std::string& xmlData) { m_XMLData = xmlData; }
private: private:
void UpdateInfoFromDatabase(); void UpdateInfoFromDatabase();
/** /**

View File

@ -25,6 +25,8 @@ struct ZoneStatistics {
uint64_t m_CoinsCollected; uint64_t m_CoinsCollected;
uint64_t m_EnemiesSmashed; uint64_t m_EnemiesSmashed;
uint64_t m_QuickBuildsCompleted; uint64_t m_QuickBuildsCompleted;
bool operator==(const ZoneStatistics& rhs) const = default;
}; };
/** /**
@ -279,9 +281,9 @@ public:
*/ */
void UpdateClientMinimap(bool showFaction, std::string ventureVisionType) const; void UpdateClientMinimap(bool showFaction, std::string ventureVisionType) const;
void SetCurrentInteracting(LWOOBJID objectID) {m_CurrentInteracting = objectID;}; void SetCurrentInteracting(LWOOBJID objectID) { m_CurrentInteracting = objectID; };
LWOOBJID GetCurrentInteracting() {return m_CurrentInteracting;}; LWOOBJID GetCurrentInteracting() { return m_CurrentInteracting; };
/** /**
* Sends a player to another zone with an optional clone ID * Sends a player to another zone with an optional clone ID
@ -307,6 +309,14 @@ public:
void SetDroppedCoins(const uint64_t value) { m_DroppedCoins = value; }; void SetDroppedCoins(const uint64_t value) { m_DroppedCoins = value; };
const std::array<uint64_t, 4>& GetClaimCodes() const { return m_ClaimCodes; };
const std::map<LWOMAPID, ZoneStatistics>& GetZoneStatistics() const { return m_ZoneStatistics; };
const std::u16string& GetLastRocketConfig() const { return m_LastRocketConfig; };
uint64_t GetTotalTimePlayed() const { return m_TotalTimePlayed; };
/** /**
* Character info regarding this character, including clothing styles, etc. * Character info regarding this character, including clothing styles, etc.
*/ */

View File

@ -86,7 +86,7 @@ private:
void SetupForMasterConnection(); void SetupForMasterConnection();
bool ConnectToMaster(); bool ConnectToMaster();
private: protected:
Logger* mLogger = nullptr; Logger* mLogger = nullptr;
dConfig* mConfig = nullptr; dConfig* mConfig = nullptr;
RakPeerInterface* mPeer = nullptr; RakPeerInterface* mPeer = nullptr;

View File

@ -9,6 +9,7 @@ add_subdirectory(dGameMessagesTests)
list(APPEND DGAMETEST_SOURCES ${DGAMEMESSAGES_TESTS}) list(APPEND DGAMETEST_SOURCES ${DGAMEMESSAGES_TESTS})
file(COPY ${GAMEMESSAGE_TESTBITSTREAMS} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) file(COPY ${GAMEMESSAGE_TESTBITSTREAMS} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
file(COPY ${COMPONENT_TEST_DATA} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
# Add the executable. Remember to add all tests above this! # Add the executable. Remember to add all tests above this!
add_executable(dGameTests ${DGAMETEST_SOURCES}) add_executable(dGameTests ${DGAMETEST_SOURCES})

View File

@ -8,6 +8,9 @@
#include "EntityInfo.h" #include "EntityInfo.h"
#include "EntityManager.h" #include "EntityManager.h"
#include "dConfig.h" #include "dConfig.h"
#include "dZoneManager.h"
#include "GameDatabase/TestSQL/TestSQLDatabase.h"
#include "Database.h"
#include <gtest/gtest.h> #include <gtest/gtest.h>
class dZoneManager; class dZoneManager;
@ -20,6 +23,7 @@ public:
~dServerMock() {}; ~dServerMock() {};
RakNet::BitStream* GetMostRecentBitStream() { return sentBitStream; }; RakNet::BitStream* GetMostRecentBitStream() { return sentBitStream; };
void Send(RakNet::BitStream& bitStream, const SystemAddress& sysAddr, bool broadcast) override { sentBitStream = &bitStream; }; void Send(RakNet::BitStream& bitStream, const SystemAddress& sysAddr, bool broadcast) override { sentBitStream = &bitStream; };
void SetZoneId(unsigned int zoneId) { mZoneID = zoneId; }
}; };
class GameDependenciesTest : public ::testing::Test { class GameDependenciesTest : public ::testing::Test {
@ -34,6 +38,9 @@ protected:
Game::server = new dServerMock(); Game::server = new dServerMock();
Game::config = new dConfig("worldconfig.ini"); Game::config = new dConfig("worldconfig.ini");
Game::entityManager = new EntityManager(); Game::entityManager = new EntityManager();
Game::zoneManager = new dZoneManager();
Game::zoneManager->LoadZone(LWOZONEID(1, 0, 0));
Database::_setDatabase(new TestSQLDatabase()); // this new is managed by the Database
// Create a CDClientManager instance and load from defaults // Create a CDClientManager instance and load from defaults
CDClientManager::LoadValuesFromDefaults(); CDClientManager::LoadValuesFromDefaults();
@ -42,6 +49,7 @@ protected:
void TearDownDependencies() { void TearDownDependencies() {
if (Game::server) delete Game::server; if (Game::server) delete Game::server;
if (Game::entityManager) delete Game::entityManager; if (Game::entityManager) delete Game::entityManager;
if (Game::zoneManager) delete Game::zoneManager;
if (Game::logger) { if (Game::logger) {
Game::logger->Flush(); Game::logger->Flush();
delete Game::logger; delete Game::logger;

View File

@ -2,6 +2,7 @@ set(DCOMPONENTS_TESTS
"DestroyableComponentTests.cpp" "DestroyableComponentTests.cpp"
"PetComponentTests.cpp" "PetComponentTests.cpp"
"SimplePhysicsComponentTests.cpp" "SimplePhysicsComponentTests.cpp"
"SavingTests.cpp"
) )
# Get the folder name and prepend it to the files above # Get the folder name and prepend it to the files above
@ -10,3 +11,8 @@ list(TRANSFORM DCOMPONENTS_TESTS PREPEND "${thisFolderName}/")
# Export to parent scope # Export to parent scope
set(DCOMPONENTS_TESTS ${DCOMPONENTS_TESTS} PARENT_SCOPE) set(DCOMPONENTS_TESTS ${DCOMPONENTS_TESTS} PARENT_SCOPE)
# Copy test files to testing directory
add_subdirectory(TestData)
list(TRANSFORM COMPONENT_TEST_DATA PREPEND "${thisFolderName}/")
set(COMPONENT_TEST_DATA ${COMPONENT_TEST_DATA} PARENT_SCOPE)

View File

@ -0,0 +1,103 @@
#include "GameDependencies.h"
#include "Character.h"
#include "Entity.h"
#include "tinyxml2.h"
#include "BuffComponent.h"
#include "CharacterComponent.h"
class SavingTest : public GameDependenciesTest {
protected:
std::unique_ptr<Entity> entity;
std::unique_ptr<Character> character;
tinyxml2::XMLDocument doc;
tinyxml2::XMLPrinter printer{ 0, true, 0 };
void SetUp() override {
SetUpDependencies();
Game::zoneManager->LoadZone(LWOZONEID(1800, 2, 0));
static_cast<dServerMock*>(Game::server)->SetZoneId(1800);
entity = std::make_unique<Entity>(1, GameDependenciesTest::info);
character = std::make_unique<Character>(1, nullptr);
doc.LoadFile("./test_xml_data.xml");
entity->SetCharacter(character.get());
character->SetEntity(entity.get());
doc.Print(&printer);
character->_setXmlData(printer.CStr());
printer.ClearBuffer();
character->_doQuickXMLDataParse();
character->LoadXmlRespawnCheckpoints();
entity->AddComponent<CharacterComponent>(character.get(), UNASSIGNED_SYSTEM_ADDRESS)->LoadFromXml(entity->GetCharacter()->GetXMLDoc());
}
void TearDown() override {
entity->SetCharacter(nullptr);
entity.reset();
character.reset();
TearDownDependencies();
}
};
TEST_F(SavingTest, CharacterComponentTest) {
// Print the original XML data
// character->GetXMLDoc().Print(&printer);
// std::string xmlDataOriginal(printer.CStr());
// printer.ClearBuffer();
// std::ofstream oldXml("./test_xml_data_original.xml");
// oldXml << xmlDataOriginal;
auto* characterComponent = entity->GetComponent<CharacterComponent>();
// Update the xml document so its been run through the saver
character->SaveXMLToDatabase();
// Reload the component and character from the now updated xml data
const auto prevTotalTime = characterComponent->GetTotalTimePlayed();
character->_doQuickXMLDataParse();
entity->AddComponent<CharacterComponent>(character.get(), UNASSIGNED_SYSTEM_ADDRESS);
characterComponent->LoadFromXml(entity->GetCharacter()->GetXMLDoc());
// Check that the buff component is the same as before which means resaving data and loading it back in didn't change anything
ASSERT_EQ("32114;69;343;13;163;2;181;2;388;252;146;24451;25;9022;41898;42186;42524;4404;0;0;0;0;0;0;0;0;0;", characterComponent->StatisticsToString());
// need a variable because the macros do not support {}
constexpr std::array<uint64_t, 4> correctCodes = { 1073741968, 0, 0, 0 };
ASSERT_EQ(correctCodes, characterComponent->GetClaimCodes());
ASSERT_EQ(1, characterComponent->m_Character->GetEyebrows());
ASSERT_EQ(2, characterComponent->m_Character->GetEyes());
ASSERT_EQ(9, characterComponent->m_Character->GetHairColor());
ASSERT_EQ(8, characterComponent->m_Character->GetHairStyle());
ASSERT_EQ(3, characterComponent->m_Character->GetPantsColor());
ASSERT_EQ(27634704, characterComponent->m_Character->GetLeftHand());
ASSERT_EQ(3, characterComponent->m_Character->GetMouth());
ASSERT_EQ(27187396, characterComponent->m_Character->GetRightHand());
ASSERT_EQ(13, characterComponent->m_Character->GetShirtColor());
ASSERT_EQ(7510, characterComponent->GetUScore());
ASSERT_EQ(300, characterComponent->GetReputation());
ASSERT_EQ(u"0:1:4719+1:4720+1:4721", characterComponent->GetLastRocketConfig());
ASSERT_EQ(prevTotalTime, characterComponent->GetTotalTimePlayed());
const std::map<LWOMAPID, ZoneStatistics> correctZoneStats =
{
{ 1000, { .m_AchievementsCollected = 0, .m_BricksCollected = 0, .m_CoinsCollected = 4, .m_EnemiesSmashed = 0, .m_QuickBuildsCompleted = 0 } },
{ 1100, { .m_AchievementsCollected = 1, .m_BricksCollected = 54, .m_CoinsCollected = 584, .m_EnemiesSmashed = 34, .m_QuickBuildsCompleted = 0 } },
{ 1101, { .m_AchievementsCollected = 7, .m_BricksCollected = 0, .m_CoinsCollected = 750, .m_EnemiesSmashed = 100, .m_QuickBuildsCompleted = 7 } },
{ 1200, { .m_AchievementsCollected = 51, .m_BricksCollected = 9, .m_CoinsCollected = 26724, .m_EnemiesSmashed = 0, .m_QuickBuildsCompleted = 3 } },
{ 1250, { .m_AchievementsCollected = 1, .m_BricksCollected = 1, .m_CoinsCollected = 158, .m_EnemiesSmashed = 15, .m_QuickBuildsCompleted = 1 } },
{ 1800, { .m_AchievementsCollected = 4, .m_BricksCollected = 5, .m_CoinsCollected = 3894, .m_EnemiesSmashed = 14, .m_QuickBuildsCompleted = 2 } },
};
ASSERT_EQ(correctZoneStats, characterComponent->GetZoneStatistics());
// Fails currently due to not reading style from xml
// Should the value be fixed, this test will fail and will match the above
// only then will this comment be removed.
ASSERT_NE(27, characterComponent->m_Character->GetShirtStyle());
}

View File

@ -0,0 +1,10 @@
set(COMPONENT_TEST_DATA
"test_xml_data.xml"
)
# Get the folder name and prepend it to the files above
get_filename_component(thisFolderName ${CMAKE_CURRENT_SOURCE_DIR} NAME)
list(TRANSFORM COMPONENT_TEST_DATA PREPEND "${thisFolderName}/")
# Export our list of files
set(COMPONENT_TEST_DATA ${COMPONENT_TEST_DATA} PARENT_SCOPE)

File diff suppressed because one or more lines are too long