#include #include #include #include #include #include #include #include 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(); EXPECT_NE(ref, nullptr); EXPECT_EQ(ref->value, 100); EXPECT_EQ(ref->name, "test"); } TEST(Core_SmartPtr, Ref_NullCheck) { Ref ref = nullptr; EXPECT_EQ(ref, nullptr); EXPECT_FALSE(ref); } TEST(Core_SmartPtr, Ref_Dereference) { auto ref = MakeRef(); ref->value = 200; EXPECT_EQ(ref->value, 200); EXPECT_EQ((*ref).value, 200); } TEST(Core_SmartPtr, Ref_Copy) { auto ref1 = MakeRef(); 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(); 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(); EXPECT_NE(unique, nullptr); EXPECT_EQ(unique->value, 100); } TEST(Core_SmartPtr, UniqueRef_Ownership) { auto unique1 = MakeUnique(); 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 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 event; std::vector 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