From 2b0791130fc5cba2fdbd98a1a4abc8af35f3bb6d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 31 Aug 2025 06:53:34 +0000 Subject: [PATCH] Improve CharacterComponent tests to follow proper variable testing pattern and address feedback on testing each component variable Co-authored-by: aronwk-aaron <26027722+aronwk-aaron@users.noreply.github.com> --- .../CharacterComponentTests.cpp | 341 ++++++++++-------- 1 file changed, 199 insertions(+), 142 deletions(-) diff --git a/tests/dGameTests/dComponentsTests/CharacterComponentTests.cpp b/tests/dGameTests/dComponentsTests/CharacterComponentTests.cpp index e0750dab..5aaa6ce7 100644 --- a/tests/dGameTests/dComponentsTests/CharacterComponentTests.cpp +++ b/tests/dGameTests/dComponentsTests/CharacterComponentTests.cpp @@ -7,22 +7,22 @@ #include "Character.h" #include "User.h" #include "eReplicaComponentType.h" -#include "eStateChangeType.h" +#include "eGameActivity.h" class CharacterComponentTest : public GameDependenciesTest { protected: - std::unique_ptr baseEntity; + Entity* baseEntity; CharacterComponent* characterComponent; std::unique_ptr character; std::unique_ptr user; - CBITSTREAM; + CBITSTREAM + uint32_t flags = 0; void SetUp() override { SetUpDependencies(); // Create a mock user and character user = std::make_unique(UNASSIGNED_SYSTEM_ADDRESS, "", "TestUser"); - // Note: User account ID is set internally character = std::make_unique(1, user.get()); character->SetHairColor(5); @@ -33,161 +33,218 @@ protected: character->SetEyebrows(3); character->SetEyes(7); character->SetMouth(9); - // Note: Last login is set internally - baseEntity = std::make_unique(15, GameDependenciesTest::info); + baseEntity = new Entity(15, GameDependenciesTest::info); characterComponent = baseEntity->AddComponent(character.get(), UNASSIGNED_SYSTEM_ADDRESS); - // Note: Statistics are set internally through game actions, not directly settable + // Set some test values using available setter methods + characterComponent->SetUScore(12345); + characterComponent->SetCurrentActivity(eGameActivity::QUICKBUILDING); + characterComponent->SetReputation(6789); + characterComponent->SetPvpEnabled(true); + characterComponent->SetLastRocketConfig(u"test,rocket,config"); + + // Update some statistics using the UpdatePlayerStatistic method + characterComponent->UpdatePlayerStatistic(StatisticID::CurrencyCollected, 100); + characterComponent->UpdatePlayerStatistic(StatisticID::BricksCollected, 200); + characterComponent->UpdatePlayerStatistic(StatisticID::SmashablesSmashed, 50); + characterComponent->UpdatePlayerStatistic(StatisticID::QuickBuildsCompleted, 25); + characterComponent->UpdatePlayerStatistic(StatisticID::EnemiesSmashed, 75); } void TearDown() override { + delete baseEntity; TearDownDependencies(); } }; +/** + * Test Construction of a CharacterComponent + */ TEST_F(CharacterComponentTest, CharacterComponentSerializeConstructionTest) { characterComponent->Serialize(bitStream, true); - // Read back the serialized data to verify structure - bool hasClaimCode0; - bitStream.Read(hasClaimCode0); - ASSERT_FALSE(hasClaimCode0); // Default is 0 - - bool hasClaimCode1; - bitStream.Read(hasClaimCode1); - ASSERT_FALSE(hasClaimCode1); // Default is 0 - - bool hasClaimCode2; - bitStream.Read(hasClaimCode2); - ASSERT_FALSE(hasClaimCode2); // Default is 0 - - bool hasClaimCode3; - bitStream.Read(hasClaimCode3); - ASSERT_FALSE(hasClaimCode3); // Default is 0 - - // Character appearance data - uint32_t hairColor, hairStyle, head, shirtColor, pantsColor, shirtStyle, headColor; - uint32_t eyebrows, eyes, mouth; - uint64_t accountId, lastLogin, propModLastDisplayTime, uScore; - bool freeToPlay; - - bitStream.Read(hairColor); - bitStream.Read(hairStyle); - bitStream.Read(head); - bitStream.Read(shirtColor); - bitStream.Read(pantsColor); - bitStream.Read(shirtStyle); - bitStream.Read(headColor); - bitStream.Read(eyebrows); - bitStream.Read(eyes); - bitStream.Read(mouth); - bitStream.Read(accountId); - bitStream.Read(lastLogin); - bitStream.Read(propModLastDisplayTime); - bitStream.Read(uScore); - bitStream.Read(freeToPlay); - - ASSERT_EQ(hairColor, 5); - ASSERT_EQ(hairStyle, 10); - ASSERT_EQ(head, 0); - ASSERT_EQ(shirtColor, 15); - ASSERT_EQ(pantsColor, 20); - ASSERT_EQ(shirtStyle, 25); - ASSERT_EQ(headColor, 0); - ASSERT_EQ(eyebrows, 3); - ASSERT_EQ(eyes, 7); - ASSERT_EQ(mouth, 9); - // Account ID and other values are set internally - ASSERT_GE(accountId, 0); // Just verify it's a valid number - ASSERT_GE(lastLogin, 0); - ASSERT_EQ(propModLastDisplayTime, 0); - ASSERT_GE(uScore, 0); // U-score starts at 0 - ASSERT_FALSE(freeToPlay); - - // Statistics verification - uint64_t currencyCollected, bricksCollected, smashablesSmashed, quickBuildsCompleted; - uint64_t enemiesSmashed, rocketsUsed, missionsCompleted, petsTamed; - uint64_t imaginationPowerUps, lifePowerUps, armorPowerUps, metersTraveled; - uint64_t timesSmashed, totalDamageTaken, totalDamageHealed, totalArmorRepaired; - uint64_t totalImaginationRestored, totalImaginationUsed, distanceDriven, timeAirborneInCar; - uint64_t racingImaginationPowerUps, racingImaginationCrates, racingCarBoosts; - uint64_t racingTimesWrecked, racingSmashablesSmashed, racesFinished, firstPlaceRaces; - - bitStream.Read(currencyCollected); - bitStream.Read(bricksCollected); - bitStream.Read(smashablesSmashed); - bitStream.Read(quickBuildsCompleted); - bitStream.Read(enemiesSmashed); - bitStream.Read(rocketsUsed); - bitStream.Read(missionsCompleted); - bitStream.Read(petsTamed); - bitStream.Read(imaginationPowerUps); - bitStream.Read(lifePowerUps); - bitStream.Read(armorPowerUps); - bitStream.Read(metersTraveled); - bitStream.Read(timesSmashed); - bitStream.Read(totalDamageTaken); - bitStream.Read(totalDamageHealed); - bitStream.Read(totalArmorRepaired); - bitStream.Read(totalImaginationRestored); - bitStream.Read(totalImaginationUsed); - bitStream.Read(distanceDriven); - bitStream.Read(timeAirborneInCar); - bitStream.Read(racingImaginationPowerUps); - bitStream.Read(racingImaginationCrates); - bitStream.Read(racingCarBoosts); - bitStream.Read(racingTimesWrecked); - bitStream.Read(racingSmashablesSmashed); - bitStream.Read(racesFinished); - bitStream.Read(firstPlaceRaces); - - ASSERT_GE(currencyCollected, 0); // Default statistics should be >= 0 - ASSERT_GE(bricksCollected, 0); - ASSERT_GE(smashablesSmashed, 0); - ASSERT_GE(quickBuildsCompleted, 0); - ASSERT_GE(enemiesSmashed, 0); - ASSERT_GE(rocketsUsed, 0); - ASSERT_GE(missionsCompleted, 0); - ASSERT_GE(petsTamed, 0); - ASSERT_EQ(imaginationPowerUps, 0); // Default values - ASSERT_EQ(lifePowerUps, 0); - ASSERT_EQ(armorPowerUps, 0); + { + // Read back the serialized data to verify structure + bool hasClaimCode0, hasClaimCode1, hasClaimCode2, hasClaimCode3; + bitStream.Read(hasClaimCode0); + bitStream.Read(hasClaimCode1); + bitStream.Read(hasClaimCode2); + bitStream.Read(hasClaimCode3); + + EXPECT_FALSE(hasClaimCode0); // Default is 0 + EXPECT_FALSE(hasClaimCode1); // Default is 0 + EXPECT_FALSE(hasClaimCode2); // Default is 0 + EXPECT_FALSE(hasClaimCode3); // Default is 0 + + // Character appearance data + uint32_t hairColor, hairStyle, head, shirtColor, pantsColor, shirtStyle, headColor; + uint32_t eyebrows, eyes, mouth; + uint64_t accountId, lastLogin, propModLastDisplayTime, uScore; + bool freeToPlay; + + bitStream.Read(hairColor); + bitStream.Read(hairStyle); + bitStream.Read(head); + bitStream.Read(shirtColor); + bitStream.Read(pantsColor); + bitStream.Read(shirtStyle); + bitStream.Read(headColor); + bitStream.Read(eyebrows); + bitStream.Read(eyes); + bitStream.Read(mouth); + bitStream.Read(accountId); + bitStream.Read(lastLogin); + bitStream.Read(propModLastDisplayTime); + bitStream.Read(uScore); + bitStream.Read(freeToPlay); + + // Verify character appearance values + EXPECT_EQ(hairColor, 5); + EXPECT_EQ(hairStyle, 10); + EXPECT_EQ(head, 0); // Default value + EXPECT_EQ(shirtColor, 15); + EXPECT_EQ(pantsColor, 20); + EXPECT_EQ(shirtStyle, 25); + EXPECT_EQ(headColor, 0); // Default value + EXPECT_EQ(eyebrows, 3); + EXPECT_EQ(eyes, 7); + EXPECT_EQ(mouth, 9); + + // Account and score values + EXPECT_GE(accountId, 0); // Valid account ID + EXPECT_GE(lastLogin, 0); // Valid last login + EXPECT_EQ(propModLastDisplayTime, 0); // Default value + EXPECT_EQ(uScore, 12345); // Value we set + EXPECT_FALSE(freeToPlay); // Default value + + // Statistics verification - read all statistics values + uint64_t currencyCollected, bricksCollected, smashablesSmashed, quickBuildsCompleted; + uint64_t enemiesSmashed, rocketsUsed, missionsCompleted, petsTamed; + uint64_t imaginationPowerUps, lifePowerUps, armorPowerUps, metersTraveled; + uint64_t timesSmashed, totalDamageTaken, totalDamageHealed, totalArmorRepaired; + uint64_t totalImaginationRestored, totalImaginationUsed, distanceDriven, timeAirborneInCar; + uint64_t racingImaginationPowerUps, racingImaginationCrates, racingCarBoosts; + uint64_t racingTimesWrecked, racingSmashablesSmashed, racesFinished, firstPlaceRaces; + + bitStream.Read(currencyCollected); + bitStream.Read(bricksCollected); + bitStream.Read(smashablesSmashed); + bitStream.Read(quickBuildsCompleted); + bitStream.Read(enemiesSmashed); + bitStream.Read(rocketsUsed); + bitStream.Read(missionsCompleted); + bitStream.Read(petsTamed); + bitStream.Read(imaginationPowerUps); + bitStream.Read(lifePowerUps); + bitStream.Read(armorPowerUps); + bitStream.Read(metersTraveled); + bitStream.Read(timesSmashed); + bitStream.Read(totalDamageTaken); + bitStream.Read(totalDamageHealed); + bitStream.Read(totalArmorRepaired); + bitStream.Read(totalImaginationRestored); + bitStream.Read(totalImaginationUsed); + bitStream.Read(distanceDriven); + bitStream.Read(timeAirborneInCar); + bitStream.Read(racingImaginationPowerUps); + bitStream.Read(racingImaginationCrates); + bitStream.Read(racingCarBoosts); + bitStream.Read(racingTimesWrecked); + bitStream.Read(racingSmashablesSmashed); + bitStream.Read(racesFinished); + bitStream.Read(firstPlaceRaces); + + // Verify the statistics we set + EXPECT_EQ(currencyCollected, 100); // Value we set + EXPECT_EQ(bricksCollected, 200); // Value we set + EXPECT_EQ(smashablesSmashed, 50); // Value we set + EXPECT_EQ(quickBuildsCompleted, 25); // Value we set + EXPECT_EQ(enemiesSmashed, 75); // Value we set + + // Default values for statistics we didn't set + EXPECT_EQ(rocketsUsed, 0); + EXPECT_EQ(missionsCompleted, 0); + EXPECT_EQ(petsTamed, 0); + EXPECT_EQ(imaginationPowerUps, 0); + EXPECT_EQ(lifePowerUps, 0); + EXPECT_EQ(armorPowerUps, 0); + + // Read trailing construction data + bool unknown1; + bool isLanding; + bitStream.Read(unknown1); + bitStream.Read(isLanding); + + EXPECT_FALSE(unknown1); // Default value + EXPECT_TRUE(isLanding); // Should be true when we have rocket config + + if (isLanding) { + uint16_t rocketConfigSize; + bitStream.Read(rocketConfigSize); + EXPECT_GT(rocketConfigSize, 0); // Should have some config data + + // Skip over rocket config data + for (uint16_t i = 0; i < rocketConfigSize; i++) { + uint16_t configChar; + bitStream.Read(configChar); + } + } + } + bitStream.Reset(); } +/** + * Test serialization of a CharacterComponent update + */ TEST_F(CharacterComponentTest, CharacterComponentSerializeUpdateTest) { // Test non-initial update serialization characterComponent->Serialize(bitStream, false); - // Should serialize flags for different update types - bool hasLevel, hasSpeedBoost, hasClaimCodes, hasActivity; - bitStream.Read(hasLevel); - bitStream.Read(hasSpeedBoost); - bitStream.Read(hasClaimCodes); - bitStream.Read(hasActivity); - - // Default state should have no updates - ASSERT_FALSE(hasLevel); - ASSERT_FALSE(hasSpeedBoost); - ASSERT_FALSE(hasClaimCodes); - ASSERT_FALSE(hasActivity); -} - -TEST_F(CharacterComponentTest, CharacterComponentClaimCodeSerializationTest) { - // Test that default claim codes serialize correctly (all should be 0) - characterComponent->Serialize(bitStream, true); - - bool hasClaimCode0, hasClaimCode1, hasClaimCode2, hasClaimCode3; - - bitStream.Read(hasClaimCode0); - ASSERT_FALSE(hasClaimCode0); // 0 should result in false - - bitStream.Read(hasClaimCode1); - ASSERT_FALSE(hasClaimCode1); // 0 should result in false - - bitStream.Read(hasClaimCode2); - ASSERT_FALSE(hasClaimCode2); // 0 should result in false - - bitStream.Read(hasClaimCode3); - ASSERT_FALSE(hasClaimCode3); // 0 should result in false + { + // Should serialize flags for different update types + bool hasGMInfo, hasCurrentActivity, hasSocialInfo; + bitStream.Read(hasGMInfo); + bitStream.Read(hasCurrentActivity); + bitStream.Read(hasSocialInfo); + + // We set current activity, so that should be true + EXPECT_TRUE(hasGMInfo); // PVP was enabled + EXPECT_TRUE(hasCurrentActivity); // We set current activity + EXPECT_FALSE(hasSocialInfo); // Default state + + // Read GM info if present + if (hasGMInfo) { + bool pvpEnabled, isGM; + uint8_t gmLevel; + bool editorEnabled; + uint8_t editorLevel; + + bitStream.Read(pvpEnabled); + bitStream.Read(isGM); + bitStream.Read(gmLevel); + bitStream.Read(editorEnabled); + bitStream.Read(editorLevel); + + EXPECT_TRUE(pvpEnabled); // Value we set + EXPECT_FALSE(isGM); // Default value + EXPECT_EQ(gmLevel, 0); // Default GM level + EXPECT_FALSE(editorEnabled); // Default value + EXPECT_EQ(editorLevel, 0); // Default editor level + } + + // Read current activity if present + if (hasCurrentActivity) { + uint32_t currentActivity; + bitStream.Read(currentActivity); + EXPECT_EQ(currentActivity, static_cast(eGameActivity::QUICKBUILDING)); // Value we set + } + + // Social info should not be present in this test case + if (hasSocialInfo) { + // Skip social info reading as it's not expected to be present + FAIL() << "Social info should not be dirty in this test"; + } + } + bitStream.Reset(); } \ No newline at end of file