2026-08-29 01:50:50 +08:00
|
|
|
|
#include "c_ArrayList.h"
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
#include <c_Test.h>
|
|
|
|
|
|
|
2026-08-30 01:48:03 +08:00
|
|
|
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
|
|
|
|
|
/* */
|
2026-08-29 01:50:50 +08:00
|
|
|
|
|
2026-08-30 01:48:03 +08:00
|
|
|
|
typedef struct {
|
2026-08-31 11:50:04 +08:00
|
|
|
|
uint32_t uid;
|
|
|
|
|
|
int data_block;
|
|
|
|
|
|
} UserPayload_t;
|
2026-08-30 01:48:03 +08:00
|
|
|
|
|
2026-08-31 11:50:04 +08:00
|
|
|
|
TEST_CASE(test_c_ArrayList_CRUD) {
|
2026-08-29 01:50:50 +08:00
|
|
|
|
c_ArrayList_t list;
|
2026-08-31 11:50:04 +08:00
|
|
|
|
// 初始化物理插槽总上限被死死限制为 2 的轻量级列表
|
|
|
|
|
|
c_err_t err = c_ArrayList_Init(&list, sizeof(UserPayload_t), 2, &c_DefaultAllocator);
|
|
|
|
|
|
ASSERT_INT_EQ(C_ERR_OK, err);
|
|
|
|
|
|
ASSERT_INT_EQ(0, (int)c_ArrayList_Size(&list)); // 验证内联函数 c_ArrayList_Size 是否正确返回当前 0
|
|
|
|
|
|
ASSERT_INT_EQ(0, (int)list.size);
|
2026-08-29 01:50:50 +08:00
|
|
|
|
|
2026-08-31 11:50:04 +08:00
|
|
|
|
UserPayload_t p1 = { 8001, 10 };
|
|
|
|
|
|
UserPayload_t p2 = { 8002, 20 };
|
|
|
|
|
|
UserPayload_t p3 = { 8003, 30 };
|
2026-08-29 01:50:50 +08:00
|
|
|
|
|
2026-08-31 11:50:04 +08:00
|
|
|
|
// 1. 在容量空间未达到天花板前,轻量 Add 应当平滑写入
|
|
|
|
|
|
ASSERT_INT_EQ(C_ERR_OK, c_ArrayList_Add(&list, &p1));
|
|
|
|
|
|
ASSERT_INT_EQ(C_ERR_OK, c_ArrayList_Add(&list, &p2));
|
|
|
|
|
|
ASSERT_INT_EQ(2, (int)list.size);
|
2026-08-29 01:50:50 +08:00
|
|
|
|
|
2026-08-31 11:50:04 +08:00
|
|
|
|
// 🌟【确定性轻量策略绝杀断言 1】:当塞入第 3 个数据导致容量溢出时,
|
|
|
|
|
|
// 轻量版 Add 必须无条件前置拦截、拒绝隐式重分配,严肃返回状态码 C_ERR_OUTOFBOUND!
|
|
|
|
|
|
ASSERT_INT_EQ(C_ERR_FULL, c_ArrayList_Add(&list, &p3));
|
|
|
|
|
|
ASSERT_INT_EQ(2, (int)list.size); // 大小纹丝不动
|
2026-08-29 01:50:50 +08:00
|
|
|
|
|
2026-08-31 11:50:04 +08:00
|
|
|
|
// 2. 验证 Read 与 Get 的读取差异
|
|
|
|
|
|
UserPayload_t read_buf;
|
|
|
|
|
|
ASSERT_INT_EQ(C_ERR_OK, c_ArrayList_Read(&list, 1, &read_buf));
|
|
|
|
|
|
ASSERT_INT_EQ(8002, (int)read_buf.uid); // 副本安全导出
|
2026-08-29 01:50:50 +08:00
|
|
|
|
|
2026-08-31 11:50:04 +08:00
|
|
|
|
// 通过 Get 拿到内部指针直接进行原地篡改
|
|
|
|
|
|
UserPayload_t* p_raw_ptr = (UserPayload_t*)c_ArrayList_Get(&list, 1);
|
|
|
|
|
|
ASSERT_TRUE(p_raw_ptr != NULL);
|
|
|
|
|
|
p_raw_ptr->data_block = 9999; // 原地篡改内部物理缓冲区
|
2026-08-29 01:50:50 +08:00
|
|
|
|
|
2026-08-31 11:50:04 +08:00
|
|
|
|
ASSERT_INT_EQ(C_ERR_OK, c_ArrayList_Read(&list, 1, &read_buf));
|
|
|
|
|
|
ASSERT_INT_EQ(9999, read_buf.data_block); // 指针篡改成功核回
|
2026-08-29 01:50:50 +08:00
|
|
|
|
|
2026-08-31 11:50:04 +08:00
|
|
|
|
// 🌟【确定性轻量策略绝杀断言 2】:使用轻量版 PopBack 弹出
|
|
|
|
|
|
UserPayload_t pop_buf;
|
|
|
|
|
|
ASSERT_INT_EQ(C_ERR_OK, c_ArrayList_PopBack(&list, &pop_buf));
|
|
|
|
|
|
ASSERT_INT_EQ(8002, (int)pop_buf.uid);
|
|
|
|
|
|
ASSERT_INT_EQ(1, (int)list.size);
|
2026-08-29 01:50:50 +08:00
|
|
|
|
|
2026-08-31 11:50:04 +08:00
|
|
|
|
// 尽管存量已经萎缩到总容量的 1/4 以下,轻量版 PopBack 也决不能引发缩容,容量必须卡死留守在 2!
|
|
|
|
|
|
ASSERT_INT_EQ(2, (int)list.capacity);
|
2026-08-29 01:50:50 +08:00
|
|
|
|
|
|
|
|
|
|
c_ArrayList_Destroy(&list);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-31 11:50:04 +08:00
|
|
|
|
TEST_CASE(test_c_ArrayList_Resize) {
|
2026-08-29 11:39:28 +08:00
|
|
|
|
c_ArrayList_t list;
|
2026-08-31 11:50:04 +08:00
|
|
|
|
c_ArrayList_Init(&list, sizeof(UserPayload_t), 2, NULL); // 降级测试
|
2026-08-29 11:39:28 +08:00
|
|
|
|
|
2026-08-31 11:50:04 +08:00
|
|
|
|
UserPayload_t p1 = { 9001, 100 };
|
|
|
|
|
|
UserPayload_t p2 = { 9002, 200 };
|
|
|
|
|
|
UserPayload_t p3 = { 9003, 300 }; // 会强迫弹性版触发自动倍增
|
2026-08-29 11:39:28 +08:00
|
|
|
|
|
2026-08-31 11:50:04 +08:00
|
|
|
|
// 1. 验证自适应变轨 ResizeAdd
|
|
|
|
|
|
ASSERT_INT_EQ(C_ERR_OK, c_ArrayList_ResizeAdd(&list, &p1));
|
|
|
|
|
|
ASSERT_INT_EQ(C_ERR_OK, c_ArrayList_ResizeAdd(&list, &p2));
|
2026-08-29 11:39:28 +08:00
|
|
|
|
|
2026-08-31 11:50:04 +08:00
|
|
|
|
// 绝杀:第 3 个数据会自适应变轨,将容量从 2 直接倍增拓宽至 4
|
|
|
|
|
|
ASSERT_INT_EQ(C_ERR_OK, c_ArrayList_ResizeAdd(&list, &p3));
|
|
|
|
|
|
ASSERT_INT_EQ(3, (int)list.size);
|
|
|
|
|
|
ASSERT_INT_EQ(4, (int)list.capacity);
|
2026-08-30 01:48:03 +08:00
|
|
|
|
|
2026-08-31 11:50:04 +08:00
|
|
|
|
// 2. 验证中段中段摘除平移覆盖
|
|
|
|
|
|
UserPayload_t remove_verify;
|
|
|
|
|
|
ASSERT_INT_EQ(C_ERR_OK, c_ArrayList_RemoveAt(&list, 1, &remove_verify)); // 拿掉 1 号位的 P2
|
|
|
|
|
|
ASSERT_INT_EQ(9002, (int)remove_verify.uid);
|
|
|
|
|
|
ASSERT_INT_EQ(2, (int)list.size);
|
|
|
|
|
|
|
|
|
|
|
|
// 搬运平移断言:原先在 2 号位的 P3(9003) 应该已经被向前挪移顶替到了 1 号位
|
|
|
|
|
|
UserPayload_t read_verify;
|
|
|
|
|
|
ASSERT_INT_EQ(C_ERR_OK, c_ArrayList_Read(&list, 1, &read_verify));
|
|
|
|
|
|
ASSERT_INT_EQ(9003, (int)read_verify.uid);
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 验证弹性版 PopBackResize 与常数缩容锁
|
|
|
|
|
|
UserPayload_t pop_resize_verify;
|
|
|
|
|
|
ASSERT_INT_EQ(C_ERR_OK, c_ArrayList_PopBackResize(&list, &pop_resize_verify));
|
|
|
|
|
|
ASSERT_INT_EQ(9003, (int)pop_resize_verify.uid);
|
|
|
|
|
|
ASSERT_INT_EQ(1, (int)list.size);
|
|
|
|
|
|
|
|
|
|
|
|
// 🌟【核心弹性缩容断言】:此时 N <= Capacity/4 (1 <= 4/4) 且大于配额上限
|
|
|
|
|
|
// 自适应版 PopBackResize 必须自动通过常数缩容锁将物理存储空间腰斩,重新高效卡回容量 2!
|
|
|
|
|
|
ASSERT_INT_EQ(2, (int)list.capacity);
|
2026-08-30 01:48:03 +08:00
|
|
|
|
|
|
|
|
|
|
c_ArrayList_Destroy(&list);
|
2026-08-29 11:39:28 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-31 11:50:04 +08:00
|
|
|
|
TEST_CASE(test_c_ArrayList_Toxicity_Defenses) {
|
|
|
|
|
|
c_ArrayList_t local_list;
|
|
|
|
|
|
c_ArrayList_Init(&local_list, sizeof(int), 4, NULL);
|
2026-08-30 01:48:03 +08:00
|
|
|
|
|
2026-08-31 11:50:04 +08:00
|
|
|
|
int dummy = 0;
|
|
|
|
|
|
// 验证各类入参毒参数及空仓边界的状态码返回线
|
|
|
|
|
|
ASSERT_INT_EQ(C_ERR_PARAM, c_ArrayList_Init(NULL, sizeof(int), 4, NULL));
|
|
|
|
|
|
ASSERT_INT_EQ(C_ERR_EMPTY, c_ArrayList_PopBack(&local_list, &dummy)); // 拦截 C_ERR_EMPTY
|
|
|
|
|
|
ASSERT_INT_EQ(C_ERR_OUTOFBOUND, c_ArrayList_Set(&local_list, 999, &dummy)); // 越界拦截
|
|
|
|
|
|
ASSERT_TRUE(c_ArrayList_Get(&local_list, 0) == NULL);
|
2026-08-29 11:39:28 +08:00
|
|
|
|
|
2026-08-31 11:50:04 +08:00
|
|
|
|
c_ArrayList_Destroy(&local_list);
|
2026-08-29 11:39:28 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-31 11:50:04 +08:00
|
|
|
|
// ==========================================
|
|
|
|
|
|
// 5. 主集成入口
|
|
|
|
|
|
// ==========================================
|
|
|
|
|
|
int main(void) {
|
|
|
|
|
|
TEST_START(C_ArrayList_DoubleStrategy_TestSuite);
|
2026-08-29 11:39:28 +08:00
|
|
|
|
|
2026-08-31 11:50:04 +08:00
|
|
|
|
RUN_TEST(test_c_ArrayList_CRUD);
|
|
|
|
|
|
RUN_TEST(test_c_ArrayList_Resize);
|
|
|
|
|
|
RUN_TEST(test_c_ArrayList_Toxicity_Defenses);
|
2026-08-29 11:39:28 +08:00
|
|
|
|
|
|
|
|
|
|
TEST_REPORT();
|
2026-08-30 01:48:03 +08:00
|
|
|
|
|
2026-08-31 11:50:04 +08:00
|
|
|
|
return (g_test_registry.failed_count > 0 ? 1 : 0);
|
|
|
|
|
|
}
|