Files
XCEngine/tests/core/test_core.cpp
ssdfasd 34c75e7129 feat: 实现Containers、Memory、Threading核心模块及单元测试
- Containers: String, Array, HashMap 容器实现及测试
- Memory: Allocator, LinearAllocator, PoolAllocator, ProxyAllocator, MemoryManager 实现及测试
- Threading: Mutex, SpinLock, ReadWriteLock, Thread, Task, TaskSystem 实现及测试
- 修复Windows平台兼容性: _aligned_malloc, std::hash特化
- 修复构建错误和测试用例问题
2026-03-13 20:37:08 +08:00

227 lines
4.6 KiB
C++

#include <gtest/gtest.h>
#include <XCEngine/Core/RefCounted.h>
#include <XCEngine/Core/SmartPtr.h>
#include <XCEngine/Core/Event.h>
#include <XCEngine/Core/Types.h>
#include <string>
#include <thread>
#include <atomic>
using namespace XCEngine::Core;
namespace {
class TestRefCounted : public RefCounted {
public:
TestRefCounted() : value(42) {}
int value;
};
TEST(Core_RefCounted, DefaultConstructor) {
TestRefCounted* obj = new TestRefCounted();
EXPECT_EQ(obj->GetRefCount(), 1);
delete obj;
}
TEST(Core_RefCounted, AddRef) {
TestRefCounted* obj = new TestRefCounted();
EXPECT_EQ(obj->GetRefCount(), 1);
obj->AddRef();
EXPECT_EQ(obj->GetRefCount(), 2);
obj->Release();
EXPECT_EQ(obj->GetRefCount(), 1);
delete obj;
}
TEST(Core_RefCounted, Release) {
TestRefCounted* obj = new TestRefCounted();
EXPECT_EQ(obj->GetRefCount(), 1);
obj->AddRef();
EXPECT_EQ(obj->GetRefCount(), 2);
obj->Release();
EXPECT_EQ(obj->GetRefCount(), 1);
obj->Release();
}
TEST(Core_RefCounted, ChainedRefs) {
TestRefCounted* obj = new TestRefCounted();
EXPECT_EQ(obj->GetRefCount(), 1);
for (int i = 0; i < 5; i++) {
obj->AddRef();
}
EXPECT_EQ(obj->GetRefCount(), 6);
for (int i = 0; i < 5; i++) {
obj->Release();
}
EXPECT_EQ(obj->GetRefCount(), 1);
delete obj;
}
struct TestStruct {
int value = 100;
std::string name = "test";
};
TEST(Core_SmartPtr, MakeRef) {
auto ref = MakeRef<TestStruct>();
EXPECT_NE(ref, nullptr);
EXPECT_EQ(ref->value, 100);
EXPECT_EQ(ref->name, "test");
}
TEST(Core_SmartPtr, Ref_NullCheck) {
Ref<TestStruct> ref = nullptr;
EXPECT_EQ(ref, nullptr);
EXPECT_FALSE(ref);
}
TEST(Core_SmartPtr, Ref_Dereference) {
auto ref = MakeRef<TestStruct>();
ref->value = 200;
EXPECT_EQ(ref->value, 200);
EXPECT_EQ((*ref).value, 200);
}
TEST(Core_SmartPtr, Ref_Copy) {
auto ref1 = MakeRef<TestStruct>();
ref1->value = 300;
auto ref2 = ref1;
EXPECT_EQ(ref1.use_count(), 2);
EXPECT_EQ(ref2.use_count(), 2);
EXPECT_EQ(ref2->value, 300);
ref2->value = 400;
EXPECT_EQ(ref1->value, 400);
}
TEST(Core_SmartPtr, Ref_Move) {
auto ref1 = MakeRef<TestStruct>();
ref1->value = 500;
auto ref2 = std::move(ref1);
EXPECT_EQ(ref1, nullptr);
EXPECT_NE(ref2, nullptr);
EXPECT_EQ(ref2->value, 500);
}
TEST(Core_SmartPtr, MakeUnique) {
auto unique = MakeUnique<TestStruct>();
EXPECT_NE(unique, nullptr);
EXPECT_EQ(unique->value, 100);
}
TEST(Core_SmartPtr, UniqueRef_Ownership) {
auto unique1 = MakeUnique<TestStruct>();
unique1->value = 600;
auto unique2 = std::move(unique1);
EXPECT_EQ(unique1, nullptr);
EXPECT_NE(unique2, nullptr);
EXPECT_EQ(unique2->value, 600);
}
TEST(Core_Event, Subscribe) {
Event<> event;
bool called = false;
uint64_t id = event.Subscribe([&called]() {
called = true;
});
EXPECT_NE(id, 0u);
event.Invoke();
EXPECT_TRUE(called);
}
TEST(Core_Event, Invoke_NoArgs) {
Event<> event;
int count = 0;
event.Subscribe([&count]() { count++; });
event.Subscribe([&count]() { count++; });
event.Invoke();
EXPECT_EQ(count, 2);
}
TEST(Core_Event, Invoke_WithArgs) {
Event<int, std::string> event;
int result = 0;
std::string text;
event.Subscribe([&result, &text](int v, const std::string& s) {
result = v;
text = s;
});
event.Invoke(42, "hello");
EXPECT_EQ(result, 42);
EXPECT_EQ(text, "hello");
}
TEST(Core_Event, Unsubscribe) {
Event<> event;
int count = 0;
uint64_t id = event.Subscribe([&count]() { count++; });
event.Subscribe([&count]() { count++; });
event.Invoke();
EXPECT_EQ(count, 2);
event.Unsubscribe(id);
event.Invoke();
EXPECT_EQ(count, 3);
}
TEST(Core_Event, Clear) {
Event<> event;
int count = 0;
event.Subscribe([&count]() { count++; });
event.Subscribe([&count]() { count++; });
event.Clear();
event.Invoke();
EXPECT_EQ(count, 0);
}
TEST(Core_Event, MultipleListeners) {
Event<int> event;
std::vector<int> results;
for (int i = 0; i < 5; i++) {
event.Subscribe([&results](int v) {
results.push_back(v);
});
}
event.Invoke(10);
EXPECT_EQ(results.size(), 5);
for (int v : results) {
EXPECT_EQ(v, 10);
}
}
TEST(Core_Event, ReturnId) {
Event<> event;
uint64_t id1 = event.Subscribe([]() {});
uint64_t id2 = event.Subscribe([]() {});
EXPECT_NE(id1, id2);
}
} // namespace