Continue adding component tests: AchievementVendor, Character, QuickBuild, Script, Skill, Vendor tests (compilation fixes needed)

Co-authored-by: aronwk-aaron <26027722+aronwk-aaron@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-08-31 22:54:34 +00:00
parent f4a9cd21be
commit 856186636f
7 changed files with 936 additions and 0 deletions

View File

@@ -0,0 +1,112 @@
#include <gtest/gtest.h>
#include "AchievementVendorComponent.h"
#include "Entity.h"
#include "BitStream.h"
#include "GameDependencies.h"
#include "MessageType/Game.h"
class AchievementVendorComponentTest : public GameDependenciesTest {
protected:
void SetUp() override {
SetUpDependencies();
}
void TearDown() override {
TearDownDependencies();
}
};
TEST_F(AchievementVendorComponentTest, Serialize) {
Entity testEntity(15, info);
// Test initial update
AchievementVendorComponent achievementVendorComponent(&testEntity);
RakNet::BitStream bitStream;
achievementVendorComponent.Serialize(bitStream, true);
// Read the data manually to validate serialization format
bitStream.ResetReadPointer();
bool hasVendorInfo;
ASSERT_TRUE(bitStream.Read(hasVendorInfo));
EXPECT_TRUE(hasVendorInfo); // Should always be true for initial update
bool hasStandardCostItems;
ASSERT_TRUE(bitStream.Read(hasStandardCostItems));
EXPECT_TRUE(hasStandardCostItems); // Set by RefreshInventory
bool hasMultiCostItems;
ASSERT_TRUE(bitStream.Read(hasMultiCostItems));
EXPECT_FALSE(hasMultiCostItems); // Default state
}
TEST_F(AchievementVendorComponentTest, SerializeRegularUpdate) {
Entity testEntity(15, info);
AchievementVendorComponent achievementVendorComponent(&testEntity);
// Reset dirty flag by doing initial serialization
RakNet::BitStream initStream;
achievementVendorComponent.Serialize(initStream, true);
// Test regular update with no changes
RakNet::BitStream bitStream;
achievementVendorComponent.Serialize(bitStream, false);
bitStream.ResetReadPointer();
bool hasVendorInfo;
ASSERT_TRUE(bitStream.Read(hasVendorInfo));
EXPECT_FALSE(hasVendorInfo); // No dirty flags, so no data
}
TEST_F(AchievementVendorComponentTest, SerializeWithDirtyVendor) {
Entity testEntity(15, info);
AchievementVendorComponent achievementVendorComponent(&testEntity);
// Reset dirty flag
RakNet::BitStream initStream;
achievementVendorComponent.Serialize(initStream, true);
// Make vendor dirty by changing state
achievementVendorComponent.SetHasMultiCostItems(true);
RakNet::BitStream bitStream;
achievementVendorComponent.Serialize(bitStream, false);
bitStream.ResetReadPointer();
bool hasVendorInfo;
ASSERT_TRUE(bitStream.Read(hasVendorInfo));
EXPECT_TRUE(hasVendorInfo); // Should be true due to dirty flag
bool hasStandardCostItems;
ASSERT_TRUE(bitStream.Read(hasStandardCostItems));
EXPECT_TRUE(hasStandardCostItems);
bool hasMultiCostItems;
ASSERT_TRUE(bitStream.Read(hasMultiCostItems));
EXPECT_TRUE(hasMultiCostItems); // Changed to true
}
TEST_F(AchievementVendorComponentTest, SerializeAfterDirtyCleared) {
Entity testEntity(15, info);
AchievementVendorComponent achievementVendorComponent(&testEntity);
// Make dirty
achievementVendorComponent.SetHasMultiCostItems(true);
// Serialize once to clear dirty flag
RakNet::BitStream firstStream;
achievementVendorComponent.Serialize(firstStream, false);
// Serialize again - should show no vendor info
RakNet::BitStream secondStream;
achievementVendorComponent.Serialize(secondStream, false);
secondStream.ResetReadPointer();
bool hasVendorInfo;
ASSERT_TRUE(secondStream.Read(hasVendorInfo));
EXPECT_FALSE(hasVendorInfo); // Dirty flag should be cleared
}

View File

@@ -1,8 +1,10 @@
set(DCOMPONENTS_TESTS set(DCOMPONENTS_TESTS
"AchievementVendorComponentTests.cpp"
"ActivityComponentTests.cpp" "ActivityComponentTests.cpp"
"BaseCombatAIComponentTests.cpp" "BaseCombatAIComponentTests.cpp"
"BouncerComponentTests.cpp" "BouncerComponentTests.cpp"
"BuffComponentTests.cpp" "BuffComponentTests.cpp"
"CharacterComponentTests.cpp"
"CollectibleComponentTests.cpp" "CollectibleComponentTests.cpp"
"ControllablePhysicsComponentTests.cpp" "ControllablePhysicsComponentTests.cpp"
"DestroyableComponentTests.cpp" "DestroyableComponentTests.cpp"
@@ -15,10 +17,14 @@ set(DCOMPONENTS_TESTS
"ModelComponentTests.cpp" "ModelComponentTests.cpp"
"MovingPlatformComponentTests.cpp" "MovingPlatformComponentTests.cpp"
"PetComponentTests.cpp" "PetComponentTests.cpp"
"QuickBuildComponentTests.cpp"
"RenderComponentTests.cpp" "RenderComponentTests.cpp"
"SavingTests.cpp" "SavingTests.cpp"
"ScriptComponentTests.cpp"
"SimplePhysicsComponentTests.cpp" "SimplePhysicsComponentTests.cpp"
"SkillComponentTests.cpp"
"SwitchComponentTests.cpp" "SwitchComponentTests.cpp"
"VendorComponentTests.cpp"
) )
# Get the folder name and prepend it to the files above # Get the folder name and prepend it to the files above

View File

@@ -0,0 +1,243 @@
#include <gtest/gtest.h>
#include "CharacterComponent.h"
#include "Entity.h"
#include "BitStream.h"
#include "GameDependencies.h"
#include "Character.h"
#include "User.h"
#include "eGameActivity.h"
#include "eGameMasterLevel.h"
#include "eLootSourceType.h"
#include "MessageType/Game.h"
class CharacterComponentTest : public GameDependenciesTest {
protected:
void SetUp() override {
SetUpDependencies();
// Create a mock user and character
m_User = std::make_unique<User>(UNASSIGNED_SYSTEM_ADDRESS, "TestUser", "TestPassword");
m_Character = std::make_unique<Character>(1, m_User.get());
m_Character->SetCoins(1000, eLootSourceType::NONE);
// Set character appearance
m_Character->SetHairColor(5);
m_Character->SetHairStyle(10);
m_Character->SetShirtColor(15);
m_Character->SetPantsColor(20);
m_Character->SetShirtStyle(25);
m_Character->SetEyebrows(30);
m_Character->SetEyes(35);
m_Character->SetMouth(40);
}
void TearDown() override {
TearDownDependencies();
}
std::unique_ptr<User> m_User;
std::unique_ptr<Character> m_Character;
};
TEST_F(CharacterComponentTest, SerializeInitialUpdate) {
Entity testEntity(15, info);
CharacterComponent characterComponent(&testEntity, m_Character.get(), UNASSIGNED_SYSTEM_ADDRESS);
RakNet::BitStream bitStream;
characterComponent.Serialize(bitStream, true);
// Read the data manually to validate serialization format
bitStream.ResetReadPointer();
// Claim codes (4 codes)
for (int i = 0; i < 4; i++) {
bool hasClaimCode;
ASSERT_TRUE(bitStream.Read(hasClaimCode));
EXPECT_FALSE(hasClaimCode); // Default state
}
// Character appearance
uint32_t hairColor;
ASSERT_TRUE(bitStream.Read(hairColor));
EXPECT_EQ(hairColor, 5);
uint32_t hairStyle;
ASSERT_TRUE(bitStream.Read(hairStyle));
EXPECT_EQ(hairStyle, 10);
uint32_t head;
ASSERT_TRUE(bitStream.Read(head));
EXPECT_EQ(head, 0); // Default
uint32_t shirtColor;
ASSERT_TRUE(bitStream.Read(shirtColor));
EXPECT_EQ(shirtColor, 15);
uint32_t pantsColor;
ASSERT_TRUE(bitStream.Read(pantsColor));
EXPECT_EQ(pantsColor, 20);
uint32_t shirtStyle;
ASSERT_TRUE(bitStream.Read(shirtStyle));
EXPECT_EQ(shirtStyle, 25);
uint32_t headColor;
ASSERT_TRUE(bitStream.Read(headColor));
EXPECT_EQ(headColor, 0); // Default
uint32_t eyebrows;
ASSERT_TRUE(bitStream.Read(eyebrows));
EXPECT_EQ(eyebrows, 30);
uint32_t eyes;
ASSERT_TRUE(bitStream.Read(eyes));
EXPECT_EQ(eyes, 35);
uint32_t mouth;
ASSERT_TRUE(bitStream.Read(mouth));
EXPECT_EQ(mouth, 40);
uint64_t accountID;
ASSERT_TRUE(bitStream.Read(accountID));
EXPECT_EQ(accountID, 0); // Default since we can't set it directly
uint64_t lastLogin;
ASSERT_TRUE(bitStream.Read(lastLogin));
EXPECT_EQ(lastLogin, 0); // Default since we can't set it directly
uint64_t propModLastDisplayTime;
ASSERT_TRUE(bitStream.Read(propModLastDisplayTime));
EXPECT_EQ(propModLastDisplayTime, 0);
uint64_t uscore;
ASSERT_TRUE(bitStream.Read(uscore));
EXPECT_EQ(uscore, 0); // Default
bool freeToPlay;
ASSERT_TRUE(bitStream.Read(freeToPlay));
EXPECT_FALSE(freeToPlay); // Disabled in DLU
// Stats (23 total statistics)
for (int i = 0; i < 23; i++) {
uint64_t stat;
ASSERT_TRUE(bitStream.Read(stat));
EXPECT_EQ(stat, 0); // All default to 0
}
bool hasUnknownFlag;
ASSERT_TRUE(bitStream.Read(hasUnknownFlag));
EXPECT_FALSE(hasUnknownFlag); // Always writes 0
bool isLanding;
ASSERT_TRUE(bitStream.Read(isLanding));
EXPECT_FALSE(isLanding); // Default state
}
TEST_F(CharacterComponentTest, SerializeRegularUpdate) {
Entity testEntity(15, info);
CharacterComponent characterComponent(&testEntity, m_Character.get(), UNASSIGNED_SYSTEM_ADDRESS);
RakNet::BitStream bitStream;
characterComponent.Serialize(bitStream, false);
bitStream.ResetReadPointer();
// Should only have the dirty flags
bool dirtyGMInfo;
ASSERT_TRUE(bitStream.Read(dirtyGMInfo));
EXPECT_FALSE(dirtyGMInfo); // Default state
bool dirtyCurrentActivity;
ASSERT_TRUE(bitStream.Read(dirtyCurrentActivity));
EXPECT_FALSE(dirtyCurrentActivity); // Default state
bool dirtySocialInfo;
ASSERT_TRUE(bitStream.Read(dirtySocialInfo));
EXPECT_FALSE(dirtySocialInfo); // Default state
}
TEST_F(CharacterComponentTest, SerializeWithDirtyGMInfo) {
Entity testEntity(15, info);
CharacterComponent characterComponent(&testEntity, m_Character.get(), UNASSIGNED_SYSTEM_ADDRESS);
// Make GM info dirty
characterComponent.SetPvpEnabled(true);
characterComponent.SetGMLevel(eGameMasterLevel::JUNIOR_MODERATOR);
RakNet::BitStream bitStream;
characterComponent.Serialize(bitStream, false);
bitStream.ResetReadPointer();
bool dirtyGMInfo;
ASSERT_TRUE(bitStream.Read(dirtyGMInfo));
EXPECT_TRUE(dirtyGMInfo);
bool pvpEnabled;
ASSERT_TRUE(bitStream.Read(pvpEnabled));
EXPECT_TRUE(pvpEnabled);
bool isGM;
ASSERT_TRUE(bitStream.Read(isGM));
EXPECT_TRUE(isGM);
eGameMasterLevel gmLevel;
ASSERT_TRUE(bitStream.Read(gmLevel));
EXPECT_EQ(gmLevel, eGameMasterLevel::JUNIOR_MODERATOR);
bool editorEnabled;
ASSERT_TRUE(bitStream.Read(editorEnabled));
EXPECT_FALSE(editorEnabled); // Default
eGameMasterLevel editorLevel;
ASSERT_TRUE(bitStream.Read(editorLevel));
EXPECT_EQ(editorLevel, eGameMasterLevel::JUNIOR_MODERATOR); // Same as GM level
}
TEST_F(CharacterComponentTest, SerializeWithDirtyCurrentActivity) {
Entity testEntity(15, info);
CharacterComponent characterComponent(&testEntity, m_Character.get(), UNASSIGNED_SYSTEM_ADDRESS);
// Set current activity
characterComponent.SetCurrentActivity(eGameActivity::QUICKBUILDING);
RakNet::BitStream bitStream;
characterComponent.Serialize(bitStream, false);
bitStream.ResetReadPointer();
bool dirtyGMInfo;
ASSERT_TRUE(bitStream.Read(dirtyGMInfo));
EXPECT_FALSE(dirtyGMInfo);
bool dirtyCurrentActivity;
ASSERT_TRUE(bitStream.Read(dirtyCurrentActivity));
EXPECT_TRUE(dirtyCurrentActivity);
eGameActivity currentActivity;
ASSERT_TRUE(bitStream.Read(currentActivity));
EXPECT_EQ(currentActivity, eGameActivity::QUICKBUILDING);
}
TEST_F(CharacterComponentTest, SerializeWithClaimCodes) {
Entity testEntity(15, info);
CharacterComponent characterComponent(&testEntity, m_Character.get(), UNASSIGNED_SYSTEM_ADDRESS);
// Set some claim codes via character (need to access private members through Character class)
// This is more of a conceptual test since claim codes are loaded from XML
RakNet::BitStream bitStream;
characterComponent.Serialize(bitStream, true);
bitStream.ResetReadPointer();
// Verify claim codes are properly handled (even if they're default values)
for (int i = 0; i < 4; i++) {
bool hasClaimCode;
ASSERT_TRUE(bitStream.Read(hasClaimCode));
// In default state, all claim codes should be 0/false
EXPECT_FALSE(hasClaimCode);
}
}

View File

@@ -0,0 +1,159 @@
#include <gtest/gtest.h>
#include "QuickBuildComponent.h"
#include "Entity.h"
#include "BitStream.h"
#include "GameDependencies.h"
#include "DestroyableComponent.h"
class QuickBuildComponentTest : public GameDependenciesTest {
protected:
void SetUp() override {
SetUpDependencies();
}
void TearDown() override {
TearDownDependencies();
}
};
TEST_F(QuickBuildComponentTest, SerializeInitialUpdateNoDestroyable) {
Entity testEntity(15, info);
// Create QuickBuild without Destroyable component
QuickBuildComponent quickBuildComponent(&testEntity);
RakNet::BitStream bitStream;
quickBuildComponent.Serialize(bitStream, true);
// Read the data manually to validate serialization format
bitStream.ResetReadPointer();
// When no destroyable component, writes specific pattern for initial update
bool flag1;
ASSERT_TRUE(bitStream.Read(flag1));
EXPECT_FALSE(flag1); // First flag is false
bool flag2;
ASSERT_TRUE(bitStream.Read(flag2));
EXPECT_FALSE(flag2); // Second flag is false
bool flag3;
ASSERT_TRUE(bitStream.Read(flag3));
EXPECT_FALSE(flag3); // Third flag is false
// ScriptedActivity section
bool hasScriptedActivity;
ASSERT_TRUE(bitStream.Read(hasScriptedActivity));
EXPECT_TRUE(hasScriptedActivity); // Always writes 1
uint32_t builderCount;
ASSERT_TRUE(bitStream.Read(builderCount));
EXPECT_EQ(builderCount, 0); // No builder initially
}
TEST_F(QuickBuildComponentTest, SerializeRegularUpdateNoDestroyable) {
Entity testEntity(15, info);
QuickBuildComponent quickBuildComponent(&testEntity);
RakNet::BitStream bitStream;
quickBuildComponent.Serialize(bitStream, false);
bitStream.ResetReadPointer();
// Regular update without destroyable should only write specific flags
bool flag1;
ASSERT_TRUE(bitStream.Read(flag1));
EXPECT_FALSE(flag1);
bool flag2;
ASSERT_TRUE(bitStream.Read(flag2));
EXPECT_FALSE(flag2);
// ScriptedActivity section
bool hasScriptedActivity;
ASSERT_TRUE(bitStream.Read(hasScriptedActivity));
EXPECT_TRUE(hasScriptedActivity);
uint32_t builderCount;
ASSERT_TRUE(bitStream.Read(builderCount));
EXPECT_EQ(builderCount, 0);
}
TEST_F(QuickBuildComponentTest, SerializeWithDestroyableComponent) {
Entity testEntity(15, info);
// Add a destroyable component first
DestroyableComponent* destroyableComponent = new DestroyableComponent(&testEntity);
testEntity.AddComponent(eReplicaComponentType::DESTROYABLE, destroyableComponent);
QuickBuildComponent quickBuildComponent(&testEntity);
RakNet::BitStream bitStream;
quickBuildComponent.Serialize(bitStream, true);
bitStream.ResetReadPointer();
// With destroyable component, should skip the special flags and go directly to ScriptedActivity
bool hasScriptedActivity;
ASSERT_TRUE(bitStream.Read(hasScriptedActivity));
EXPECT_TRUE(hasScriptedActivity);
uint32_t builderCount;
ASSERT_TRUE(bitStream.Read(builderCount));
EXPECT_EQ(builderCount, 0);
}
TEST_F(QuickBuildComponentTest, SerializeWithBuilder) {
Entity testEntity(15, info);
Entity builderEntity(20, info);
QuickBuildComponent quickBuildComponent(&testEntity);
// Simulate having a builder (this would normally be set through the component's logic)
// Since GetBuilder() is based on internal state, this test validates the serialization format
// when there's no builder
RakNet::BitStream bitStream;
quickBuildComponent.Serialize(bitStream, true);
bitStream.ResetReadPointer();
// Skip initial flags
bool flag1, flag2, flag3;
bitStream.Read(flag1);
bitStream.Read(flag2);
bitStream.Read(flag3);
bool hasScriptedActivity;
ASSERT_TRUE(bitStream.Read(hasScriptedActivity));
EXPECT_TRUE(hasScriptedActivity);
uint32_t builderCount;
ASSERT_TRUE(bitStream.Read(builderCount));
EXPECT_EQ(builderCount, 0); // No builder in default state
}
TEST_F(QuickBuildComponentTest, SerializeConsistentFormat) {
Entity testEntity(15, info);
QuickBuildComponent quickBuildComponent(&testEntity);
// Test that serialization format is consistent between calls
RakNet::BitStream firstStream, secondStream;
quickBuildComponent.Serialize(firstStream, true);
quickBuildComponent.Serialize(secondStream, true);
// Compare the serialized data
EXPECT_EQ(firstStream.GetNumberOfBitsUsed(), secondStream.GetNumberOfBitsUsed());
// Reset and compare bit by bit
firstStream.ResetReadPointer();
secondStream.ResetReadPointer();
while (firstStream.GetNumberOfUnreadBits() > 0 && secondStream.GetNumberOfUnreadBits() > 0) {
bool firstBit, secondBit;
firstStream.Read(firstBit);
secondStream.Read(secondBit);
EXPECT_EQ(firstBit, secondBit);
}
}

View File

@@ -0,0 +1,148 @@
#include <gtest/gtest.h>
#include "ScriptComponent.h"
#include "Entity.h"
#include "BitStream.h"
#include "GameDependencies.h"
class ScriptComponentTest : public GameDependenciesTest {
protected:
void SetUp() override {
SetUpDependencies();
}
void TearDown() override {
TearDownDependencies();
}
};
TEST_F(ScriptComponentTest, SerializeInitialUpdateNoNetworkSettings) {
Entity testEntity(15, info);
ScriptComponent scriptComponent(&testEntity, "", false);
RakNet::BitStream bitStream;
scriptComponent.Serialize(bitStream, true);
// Read the data manually to validate serialization format
bitStream.ResetReadPointer();
bool hasNetworkSettings;
ASSERT_TRUE(bitStream.Read(hasNetworkSettings));
EXPECT_FALSE(hasNetworkSettings); // No network settings by default
}
TEST_F(ScriptComponentTest, SerializeRegularUpdate) {
Entity testEntity(15, info);
ScriptComponent scriptComponent(&testEntity, "", false);
RakNet::BitStream bitStream;
scriptComponent.Serialize(bitStream, false);
// Regular updates should not write anything for ScriptComponent
bitStream.ResetReadPointer();
EXPECT_EQ(bitStream.GetNumberOfUnreadBits(), 0);
}
TEST_F(ScriptComponentTest, SerializeWithNetworkSettings) {
Entity testEntity(15, info);
// Add some network settings to the entity
testEntity.SetNetworkVar<float>(u"test_float", 123.45f);
testEntity.SetNetworkVar<int32_t>(u"test_int", 42);
ScriptComponent scriptComponent(&testEntity, "", false);
RakNet::BitStream bitStream;
scriptComponent.Serialize(bitStream, true);
bitStream.ResetReadPointer();
bool hasNetworkSettings;
ASSERT_TRUE(bitStream.Read(hasNetworkSettings));
EXPECT_TRUE(hasNetworkSettings); // Should have network settings
uint32_t ldfDataSize;
ASSERT_TRUE(bitStream.Read(ldfDataSize));
EXPECT_GT(ldfDataSize, 0); // Should have some data
// Verify the LDF data is present
RakNet::BitStream ldfStream;
ASSERT_TRUE(bitStream.Read(ldfStream, ldfDataSize));
ldfStream.ResetReadPointer();
uint8_t ldfType;
ASSERT_TRUE(ldfStream.Read(ldfType));
EXPECT_EQ(ldfType, 0); // Always writes 0 first
uint32_t settingsCount;
ASSERT_TRUE(ldfStream.Read(settingsCount));
EXPECT_EQ(settingsCount, 2); // We added 2 settings
}
TEST_F(ScriptComponentTest, SerializeConsistentBehavior) {
Entity testEntity(15, info);
ScriptComponent scriptComponent(&testEntity, "", false);
// Test that multiple serializations are consistent
RakNet::BitStream firstStream, secondStream;
scriptComponent.Serialize(firstStream, true);
scriptComponent.Serialize(secondStream, true);
EXPECT_EQ(firstStream.GetNumberOfBitsUsed(), secondStream.GetNumberOfBitsUsed());
firstStream.ResetReadPointer();
secondStream.ResetReadPointer();
bool firstHasSettings, secondHasSettings;
ASSERT_TRUE(firstStream.Read(firstHasSettings));
ASSERT_TRUE(secondStream.Read(secondHasSettings));
EXPECT_EQ(firstHasSettings, secondHasSettings);
}
TEST_F(ScriptComponentTest, SerializeScriptNameHandling) {
Entity testEntity(15, info);
// Test with different script names - serialization shouldn't change based on script name
ScriptComponent scriptComponent1(&testEntity, "TestScript", false);
ScriptComponent scriptComponent2(&testEntity, "AnotherScript", false);
RakNet::BitStream stream1, stream2;
scriptComponent1.Serialize(stream1, true);
scriptComponent2.Serialize(stream2, true);
// Serialization should be the same regardless of script name since
// script names are not serialized, only network settings
stream1.ResetReadPointer();
stream2.ResetReadPointer();
bool hasSettings1, hasSettings2;
ASSERT_TRUE(stream1.Read(hasSettings1));
ASSERT_TRUE(stream2.Read(hasSettings2));
EXPECT_EQ(hasSettings1, hasSettings2);
EXPECT_FALSE(hasSettings1); // Both should be false without network settings
}
TEST_F(ScriptComponentTest, SerializeSerializedFlag) {
Entity testEntity(15, info);
ScriptComponent scriptComponent(&testEntity, "", false);
// Test the serialized flag functionality
EXPECT_FALSE(scriptComponent.GetSerialized()); // Default state
scriptComponent.SetSerialized(true);
EXPECT_TRUE(scriptComponent.GetSerialized());
// The serialized flag itself doesn't affect the Serialize method output,
// but it's tracked by the component
RakNet::BitStream bitStream;
scriptComponent.Serialize(bitStream, true);
bitStream.ResetReadPointer();
bool hasNetworkSettings;
ASSERT_TRUE(bitStream.Read(hasNetworkSettings));
EXPECT_FALSE(hasNetworkSettings); // Still no network settings
}

View File

@@ -0,0 +1,102 @@
#include <gtest/gtest.h>
#include "SkillComponent.h"
#include "Entity.h"
#include "BitStream.h"
#include "GameDependencies.h"
class SkillComponentTest : public GameDependenciesTest {
protected:
void SetUp() override {
SetUpDependencies();
}
void TearDown() override {
TearDownDependencies();
}
};
TEST_F(SkillComponentTest, SerializeInitialUpdate) {
Entity testEntity(15, info);
SkillComponent skillComponent(&testEntity);
RakNet::BitStream bitStream;
skillComponent.Serialize(bitStream, true);
// Read the data manually to validate serialization format
bitStream.ResetReadPointer();
bool skillFlag;
ASSERT_TRUE(bitStream.Read(skillFlag));
EXPECT_FALSE(skillFlag); // Always writes 0 for initial update
}
TEST_F(SkillComponentTest, SerializeRegularUpdate) {
Entity testEntity(15, info);
SkillComponent skillComponent(&testEntity);
RakNet::BitStream bitStream;
skillComponent.Serialize(bitStream, false);
// Regular updates should not write anything for SkillComponent
bitStream.ResetReadPointer();
EXPECT_EQ(bitStream.GetNumberOfUnreadBits(), 0);
}
TEST_F(SkillComponentTest, SerializeConsistentBehavior) {
Entity testEntity(15, info);
SkillComponent skillComponent(&testEntity);
// Test that multiple initial serializations are consistent
RakNet::BitStream firstStream, secondStream;
skillComponent.Serialize(firstStream, true);
skillComponent.Serialize(secondStream, true);
EXPECT_EQ(firstStream.GetNumberOfBitsUsed(), secondStream.GetNumberOfBitsUsed());
EXPECT_EQ(firstStream.GetNumberOfBitsUsed(), 1); // Should always be 1 bit (false)
firstStream.ResetReadPointer();
secondStream.ResetReadPointer();
bool firstFlag, secondFlag;
ASSERT_TRUE(firstStream.Read(firstFlag));
ASSERT_TRUE(secondStream.Read(secondFlag));
EXPECT_FALSE(firstFlag);
EXPECT_FALSE(secondFlag);
EXPECT_EQ(firstFlag, secondFlag);
}
TEST_F(SkillComponentTest, GetUniqueSkillId) {
Entity testEntity(15, info);
SkillComponent skillComponent(&testEntity);
// Test that unique skill IDs increment
uint32_t firstId = skillComponent.GetUniqueSkillId();
uint32_t secondId = skillComponent.GetUniqueSkillId();
uint32_t thirdId = skillComponent.GetUniqueSkillId();
EXPECT_EQ(secondId, firstId + 1);
EXPECT_EQ(thirdId, firstId + 2);
EXPECT_GT(firstId, 0); // Should start from at least 1
}
TEST_F(SkillComponentTest, SerializeAfterSkillUse) {
Entity testEntity(15, info);
SkillComponent skillComponent(&testEntity);
// Generate some skill IDs to simulate skill usage
skillComponent.GetUniqueSkillId();
skillComponent.GetUniqueSkillId();
skillComponent.GetUniqueSkillId();
// Serialization behavior should still be the same
RakNet::BitStream bitStream;
skillComponent.Serialize(bitStream, true);
bitStream.ResetReadPointer();
bool skillFlag;
ASSERT_TRUE(bitStream.Read(skillFlag));
EXPECT_FALSE(skillFlag); // Still writes 0 regardless of internal state
}

View File

@@ -0,0 +1,166 @@
#include <gtest/gtest.h>
#include "VendorComponent.h"
#include "Entity.h"
#include "BitStream.h"
#include "GameDependencies.h"
class VendorComponentTest : public GameDependenciesTest {
protected:
void SetUp() override {
SetUpDependencies();
}
void TearDown() override {
TearDownDependencies();
}
};
TEST_F(VendorComponentTest, SerializeInitialUpdate) {
Entity testEntity(15, info);
VendorComponent vendorComponent(&testEntity);
RakNet::BitStream bitStream;
vendorComponent.Serialize(bitStream, true);
// Read the data manually to validate serialization format
bitStream.ResetReadPointer();
bool hasVendorInfo;
ASSERT_TRUE(bitStream.Read(hasVendorInfo));
EXPECT_TRUE(hasVendorInfo); // Should always be true for initial update
bool hasStandardCostItems;
ASSERT_TRUE(bitStream.Read(hasStandardCostItems));
EXPECT_FALSE(hasStandardCostItems); // Default state after RefreshInventory
bool hasMultiCostItems;
ASSERT_TRUE(bitStream.Read(hasMultiCostItems));
EXPECT_FALSE(hasMultiCostItems); // Default state
}
TEST_F(VendorComponentTest, SerializeRegularUpdate) {
Entity testEntity(15, info);
VendorComponent vendorComponent(&testEntity);
// Reset dirty flag by doing initial serialization
RakNet::BitStream initStream;
vendorComponent.Serialize(initStream, true);
// Test regular update with no changes
RakNet::BitStream bitStream;
vendorComponent.Serialize(bitStream, false);
bitStream.ResetReadPointer();
bool hasVendorInfo;
ASSERT_TRUE(bitStream.Read(hasVendorInfo));
EXPECT_FALSE(hasVendorInfo); // No dirty flags, so no data
}
TEST_F(VendorComponentTest, SerializeWithDirtyVendor) {
Entity testEntity(15, info);
VendorComponent vendorComponent(&testEntity);
// Reset dirty flag
RakNet::BitStream initStream;
vendorComponent.Serialize(initStream, true);
// Make vendor dirty by changing state
vendorComponent.SetHasStandardCostItems(true);
RakNet::BitStream bitStream;
vendorComponent.Serialize(bitStream, false);
bitStream.ResetReadPointer();
bool hasVendorInfo;
ASSERT_TRUE(bitStream.Read(hasVendorInfo));
EXPECT_TRUE(hasVendorInfo); // Should be true due to dirty flag
bool hasStandardCostItems;
ASSERT_TRUE(bitStream.Read(hasStandardCostItems));
EXPECT_TRUE(hasStandardCostItems); // Changed to true
bool hasMultiCostItems;
ASSERT_TRUE(bitStream.Read(hasMultiCostItems));
EXPECT_FALSE(hasMultiCostItems); // Still false
}
TEST_F(VendorComponentTest, SerializeWithMultiCostItems) {
Entity testEntity(15, info);
VendorComponent vendorComponent(&testEntity);
// Set both flags
vendorComponent.SetHasStandardCostItems(true);
vendorComponent.SetHasMultiCostItems(true);
RakNet::BitStream bitStream;
vendorComponent.Serialize(bitStream, true);
bitStream.ResetReadPointer();
bool hasVendorInfo;
ASSERT_TRUE(bitStream.Read(hasVendorInfo));
EXPECT_TRUE(hasVendorInfo);
bool hasStandardCostItems;
ASSERT_TRUE(bitStream.Read(hasStandardCostItems));
EXPECT_TRUE(hasStandardCostItems);
bool hasMultiCostItems;
ASSERT_TRUE(bitStream.Read(hasMultiCostItems));
EXPECT_TRUE(hasMultiCostItems);
}
TEST_F(VendorComponentTest, SerializeDirtyFlagClearing) {
Entity testEntity(15, info);
VendorComponent vendorComponent(&testEntity);
// Make vendor dirty
vendorComponent.SetHasStandardCostItems(true);
// First serialize should clear dirty flag
RakNet::BitStream firstStream;
vendorComponent.Serialize(firstStream, false);
// Second serialize should show no vendor info
RakNet::BitStream secondStream;
vendorComponent.Serialize(secondStream, false);
secondStream.ResetReadPointer();
bool hasVendorInfo;
ASSERT_TRUE(secondStream.Read(hasVendorInfo));
EXPECT_FALSE(hasVendorInfo); // Dirty flag should be cleared
}
TEST_F(VendorComponentTest, SettersChangeDirtyFlag) {
Entity testEntity(15, info);
VendorComponent vendorComponent(&testEntity);
// Clear initial dirty state
RakNet::BitStream initStream;
vendorComponent.Serialize(initStream, true);
// Setting same value should not make dirty
vendorComponent.SetHasStandardCostItems(false); // Already false
RakNet::BitStream noChangeStream;
vendorComponent.Serialize(noChangeStream, false);
noChangeStream.ResetReadPointer();
bool hasVendorInfo;
ASSERT_TRUE(noChangeStream.Read(hasVendorInfo));
EXPECT_FALSE(hasVendorInfo); // Should not be dirty
// Setting different value should make dirty
vendorComponent.SetHasStandardCostItems(true);
RakNet::BitStream changeStream;
vendorComponent.Serialize(changeStream, false);
changeStream.ResetReadPointer();
ASSERT_TRUE(changeStream.Read(hasVendorInfo));
EXPECT_TRUE(hasVendorInfo); // Should be dirty now
}