/** * @file test_asset_cache.cpp * @brief AssetCache 单元测试 * * 测试资源缓存的添加、获取、淘汰等功能。 */ #include "test_framework.h" #include #include using namespace extra2d; using namespace extra2d::test; // --------------------------------------------------------------------------- // 测试辅助类 // --------------------------------------------------------------------------- /** * @brief 测试用资源类 */ class TestAsset : public Asset { public: AssetType type() const override { return AssetType::Data; } bool loaded() const override { return state_.load(std::memory_order_acquire) == AssetState::Loaded; } size_t memSize() const override { return dataSize_; } void setData(size_t size) { dataSize_ = size; setState(AssetState::Loaded); } static Ref create(const std::string& path, size_t size = 100) { auto asset = std::make_shared(); asset->setId(AssetID(path)); asset->setPath(path); asset->setData(size); return asset; } private: size_t dataSize_ = 0; }; // --------------------------------------------------------------------------- // 基本功能测试 // --------------------------------------------------------------------------- TEST(AssetCache, Create) { AssetCache cache; TEST_ASSERT_EQ(0u, cache.count()); TEST_ASSERT_EQ(0u, cache.bytes()); TEST_ASSERT_EQ(0u, cache.limit()); } TEST(AssetCache, CreateWithLimit) { AssetCache cache(1024 * 1024); TEST_ASSERT_EQ(1024 * 1024, cache.limit()); } TEST(AssetCache, AddAsset) { AssetCache cache; auto asset = TestAsset::create("test.asset", 100); auto handle = cache.add(asset); TEST_ASSERT_TRUE(handle.valid()); TEST_ASSERT_EQ(1u, cache.count()); TEST_ASSERT_EQ(100u, cache.bytes()); } TEST(AssetCache, AddNullAsset) { AssetCache cache; Ref nullAsset; auto handle = cache.add(nullAsset); TEST_ASSERT_FALSE(handle.valid()); TEST_ASSERT_EQ(0u, cache.count()); } TEST(AssetCache, GetAsset) { AssetCache cache; auto asset = TestAsset::create("test.asset", 200); cache.add(asset); auto handle = cache.get(AssetID("test.asset")); TEST_ASSERT_TRUE(handle.valid()); TEST_ASSERT_TRUE(handle.get() != nullptr); TEST_ASSERT_EQ(asset.get(), handle.get().get()); } TEST(AssetCache, GetNonExistent) { AssetCache cache; auto handle = cache.get(AssetID("nonexistent.asset")); TEST_ASSERT_FALSE(handle.valid()); } TEST(AssetCache, HasAsset) { AssetCache cache; auto asset = TestAsset::create("test.asset", 100); cache.add(asset); TEST_ASSERT_TRUE(cache.has(AssetID("test.asset"))); TEST_ASSERT_FALSE(cache.has(AssetID("other.asset"))); } TEST(AssetCache, RemoveAsset) { AssetCache cache; auto asset = TestAsset::create("test.asset", 100); cache.add(asset); TEST_ASSERT_TRUE(cache.remove(AssetID("test.asset"))); TEST_ASSERT_EQ(0u, cache.count()); TEST_ASSERT_FALSE(cache.has(AssetID("test.asset"))); } TEST(AssetCache, RemoveNonExistent) { AssetCache cache; TEST_ASSERT_FALSE(cache.remove(AssetID("nonexistent.asset"))); } // --------------------------------------------------------------------------- // 缓存统计测试 // --------------------------------------------------------------------------- TEST(AssetCache, Stats_Initial) { AssetCache cache; auto stats = cache.stats(); TEST_ASSERT_EQ(0u, stats.hits); TEST_ASSERT_EQ(0u, stats.misses); TEST_ASSERT_EQ(0u, stats.count); } TEST(AssetCache, Stats_HitMiss) { AssetCache cache; auto asset = TestAsset::create("test.asset", 100); cache.add(asset); cache.get(AssetID("test.asset")); cache.get(AssetID("nonexistent.asset")); auto stats = cache.stats(); TEST_ASSERT_EQ(1u, stats.hits); TEST_ASSERT_EQ(1u, stats.misses); } TEST(AssetCache, Stats_Reset) { AssetCache cache; auto asset = TestAsset::create("test.asset", 100); cache.add(asset); cache.get(AssetID("test.asset")); cache.get(AssetID("nonexistent.asset")); cache.resetStats(); auto stats = cache.stats(); TEST_ASSERT_EQ(0u, stats.hits); TEST_ASSERT_EQ(0u, stats.misses); } // --------------------------------------------------------------------------- // 内存限制测试 // --------------------------------------------------------------------------- TEST(AssetCache, SetLimit) { AssetCache cache; cache.setLimit(500); TEST_ASSERT_EQ(500u, cache.limit()); } TEST(AssetCache, MemoryTracking) { AssetCache cache; auto asset1 = TestAsset::create("asset1", 100); auto asset2 = TestAsset::create("asset2", 200); cache.add(asset1); cache.add(asset2); TEST_ASSERT_EQ(300u, cache.bytes()); } TEST(AssetCache, Clear) { AssetCache cache; auto asset1 = TestAsset::create("asset1", 100); auto asset2 = TestAsset::create("asset2", 200); cache.add(asset1); cache.add(asset2); cache.clear(); TEST_ASSERT_EQ(0u, cache.count()); TEST_ASSERT_EQ(0u, cache.bytes()); } // --------------------------------------------------------------------------- // LRU 测试 // --------------------------------------------------------------------------- TEST(AssetCache, LRU_AccessOrder) { AssetCache cache; auto asset1 = TestAsset::create("asset1", 100); auto asset2 = TestAsset::create("asset2", 100); auto asset3 = TestAsset::create("asset3", 100); cache.add(asset1); cache.add(asset2); cache.add(asset3); cache.get(AssetID("asset1")); TEST_ASSERT_TRUE(cache.has(AssetID("asset1"))); TEST_ASSERT_TRUE(cache.has(AssetID("asset2"))); TEST_ASSERT_TRUE(cache.has(AssetID("asset3"))); } // --------------------------------------------------------------------------- // Purge 测试 // --------------------------------------------------------------------------- TEST(AssetCache, Purge_NoReferences) { AssetCache cache; { auto asset = TestAsset::create("test.asset", 100); cache.add(asset); } size_t purged = cache.purge(); TEST_ASSERT_EQ(1u, purged); TEST_ASSERT_EQ(0u, cache.count()); } TEST(AssetCache, Purge_WithReferences) { AssetCache cache; auto asset = TestAsset::create("test.asset", 100); auto handle = cache.add(asset); size_t purged = cache.purge(); TEST_ASSERT_EQ(0u, purged); TEST_ASSERT_EQ(1u, cache.count()); } // --------------------------------------------------------------------------- // 多资源测试 // --------------------------------------------------------------------------- TEST(AssetCache, MultipleAssets) { AssetCache cache; for (int i = 0; i < 10; ++i) { auto asset = TestAsset::create("asset" + std::to_string(i), 100); cache.add(asset); } TEST_ASSERT_EQ(10u, cache.count()); TEST_ASSERT_EQ(1000u, cache.bytes()); for (int i = 0; i < 10; ++i) { TEST_ASSERT_TRUE(cache.has(AssetID("asset" + std::to_string(i)))); } } TEST(AssetCache, RemoveMultiple) { AssetCache cache; for (int i = 0; i < 5; ++i) { auto asset = TestAsset::create("asset" + std::to_string(i), 100); cache.add(asset); } for (int i = 0; i < 3; ++i) { cache.remove(AssetID("asset" + std::to_string(i))); } TEST_ASSERT_EQ(2u, cache.count()); TEST_ASSERT_EQ(200u, cache.bytes()); }