#include "c_PtrBag.h" #include "c_Test.h" TEST_CASE(test_ptr_bag_basic_and_optimization) { c_PtrBag_t bag; // 初始化一个初始容量为 3 的指针袋 ASSERT_INT_EQ(C_ERR_OK, c_PtrBag_Init(&bag, 3, NULL)); // 模拟三个异构结构体的实体对象(可以是完全不同的类型) int dummy_entity_a = 100; float dummy_entity_b = 200.0f; char* dummy_entity_c = "EntityC"; int dummy_entity_d = 400; // 用于触发自动扩容 // 1. 添加指针测试 ASSERT_INT_EQ(C_ERR_OK, c_PtrBag_Add(&bag, &dummy_entity_a)); ASSERT_INT_EQ(C_ERR_OK, c_PtrBag_Add(&bag, &dummy_entity_b)); ASSERT_INT_EQ(C_ERR_OK, c_PtrBag_Add(&bag, &dummy_entity_c)); ASSERT_INT_EQ(3, c_PtrBag_Size(&bag)); // 2. 自动扩容验证 ASSERT_INT_EQ(C_ERR_OK, c_PtrBag_Add(&bag, &dummy_entity_d)); // 触发 3 -> 6 扩容 ASSERT_INT_EQ(6, bag.capacity); // 3. 包含性检查 (Contains) ASSERT_TRUE(c_PtrBag_Contains(&bag, &dummy_entity_b)); ASSERT_TRUE(!c_PtrBag_Contains(&bag, NULL)); // 4. CRITICAL:验证 Swap-and-Remove 的 $O(1)$ 正确性 // 当前顺序:[0]:&a, [1]:&b, [2]:&c, [3]:&d // 我们强制移除索引 1 处的 &b void* popped_ptr = NULL; ASSERT_INT_EQ(C_ERR_OK, c_PtrBag_RemoveAt(&bag, 1, &popped_ptr)); // 验证拷出的指针确实是 b ASSERT_TRUE(popped_ptr == &dummy_entity_b); ASSERT_INT_EQ(3, c_PtrBag_Size(&bag)); // 严苛验证无序替换:原来的最后一个元素 &d 应该被移到了索引 1 处 ASSERT_TRUE(c_PtrBag_Get(&bag, 0) == &dummy_entity_a); ASSERT_TRUE(c_PtrBag_Get(&bag, 1) == &dummy_entity_d); // &d 顶替了 &b 的坑位! ASSERT_TRUE(c_PtrBag_Get(&bag, 2) == &dummy_entity_c); // 5. 直接按指针实例移除测试 ASSERT_INT_EQ(C_ERR_OK, c_PtrBag_Remove(&bag, &dummy_entity_a)); ASSERT_TRUE(!c_PtrBag_Contains(&bag, &dummy_entity_a)); ASSERT_INT_EQ(2, c_PtrBag_Size(&bag)); // 6. 清空与复用测试 c_PtrBag_Clear(&bag); ASSERT_INT_EQ(0, c_PtrBag_Size(&bag)); ASSERT_INT_EQ(6, bag.capacity); // 缓冲区未被释放 c_PtrBag_Destroy(&bag); } int main(void) { TEST_START(C_PtrBag_Module_Tests); RUN_TEST(test_ptr_bag_basic_and_optimization); TEST_REPORT(); RETURN_TEST_STATUS; }