This commit is contained in:
2026-08-30 01:48:03 +08:00
parent 84ebd52c24
commit 7940b67827
170 changed files with 2704 additions and 21276 deletions
+48 -123
View File
@@ -2,150 +2,75 @@
#include <stdlib.h>
#include <stdio.h>
#include <c_Test.h>
#include <c_BuddyAllocator.h>
#include "c_Alignment.h"
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
static c_ArrayQueue_t g_queue;
TEST_CASE(test_queue_basic_operations) {
c_ArrayQueue_t queue;
// 启动环境:初始化一个初始容量为 4 的 int 类型队列
void setup_queue() {
c_err_t err = c_ArrayQueue_Init(&g_queue, sizeof(int), 4);
if (err != C_ERR_OK) {
printf(" " COLOR_RED "[ERROR] Queue Setup failed!" COLOR_RESET "\n");
}
}
c_Buddy_t buddy;
uint8_t* backing_buffer = (uint8_t*)malloc(1024);
// 初始化一個 1024 總大小的區塊
c_Buddy_Init(&buddy, backing_buffer, 1024, C_ALIGN_SIZE);
c_BuddyAllocator_t buddyAllocator;
c_Allocator_t allocator = c_BuddyAllocator_Build(&buddyAllocator, &buddy);
// 清理环境:安全销毁队列
void teardown_queue() {
c_ArrayQueue_Destroy(&g_queue);
}
// 初始化容量为 3 的整型队列
ASSERT_INT_EQ(C_SUCCESS, c_ArrayQueue_Init(&queue, sizeof(int), 3, &allocator));
ASSERT_TRUE(c_ArrayQueue_IsEmpty(&queue));
// 用例 1:测试常规入队、查看对头、出队(FIFO 基础逻辑)
void test_queue_push_pop_basic() {
// 1. 入队 3 个元素
int v1 = 10, v2 = 20, v3 = 30;
ASSERT_INT_EQ(C_SUCCESS, c_ArrayQueue_Enqueue(&queue, &v1));
ASSERT_INT_EQ(C_SUCCESS, c_ArrayQueue_Enqueue(&queue, &v2));
ASSERT_INT_EQ(C_SUCCESS, c_ArrayQueue_Enqueue(&queue, &v3));
ASSERT_INT_EQ(3, c_ArrayQueue_Size(&queue));
// 入队 3 个元素
ASSERT_INT_EQ_MSG(C_ERR_OK, c_ArrayQueue_Push(&g_queue, &v1), "Push 10 failed");
ASSERT_INT_EQ_MSG(C_ERR_OK, c_ArrayQueue_Push(&g_queue, &v2), "Push 20 failed");
ASSERT_INT_EQ_MSG(C_ERR_OK, c_ArrayQueue_Push(&g_queue, &v3), "Push 30 failed");
// 2. 检查 Peek
ASSERT_INT_EQ(10, *(int*)c_ArrayQueue_Peek(&queue));
// 检查大小
ASSERT_INT_EQ_MSG(3, g_queue.size, "Size should be 3");
// Peek 检查队头(应该依然是 10,且不弹出元素)
int* front_ptr = (int*)c_ArrayQueue_Peek(&g_queue);
ASSERT_MSG(front_ptr != NULL, "Peek should not return NULL");
ASSERT_INT_EQ_MSG(10, *front_ptr, "Peek value mismatches");
// 开始 Pop 出队,验证 FIFO 顺序
// 3. 出队 1 个元素(此时 head 移动,腾出索引 0 的空间)
int out_val = 0;
ASSERT_INT_EQ(C_SUCCESS, c_ArrayQueue_Dequeue(&queue, &out_val));
ASSERT_INT_EQ(10, out_val);
ASSERT_INT_EQ(2, c_ArrayQueue_Size(&queue));
ASSERT_INT_EQ_MSG(C_ERR_OK, c_ArrayQueue_Pop(&g_queue, &out_val), "Pop 1 failed");
ASSERT_INT_EQ_MSG(10, out_val, "First out should be 10");
// 4. 再次入队,触发环形回绕(tail 绕回到索引 0 处插入)
int v4 = 40;
ASSERT_INT_EQ(C_SUCCESS, c_ArrayQueue_Enqueue(&queue, &v4));
ASSERT_INT_EQ(3, c_ArrayQueue_Size(&queue));
ASSERT_INT_EQ(3, queue.capacity); // 刚好填满,未触发扩容
ASSERT_INT_EQ_MSG(C_ERR_OK, c_ArrayQueue_Pop(&g_queue, &out_val), "Pop 2 failed");
ASSERT_INT_EQ_MSG(20, out_val, "Second out should be 20");
// 5. 核心:在“回绕状态下”强行插入第 5 个元素,迫使其触发 EnsureCapacity 扩容与平整化
int v5 = 50;
ASSERT_INT_EQ(C_SUCCESS, c_ArrayQueue_Enqueue(&queue, &v5));
ASSERT_INT_EQ(4, c_ArrayQueue_Size(&queue));
ASSERT_INT_EQ(6, queue.capacity); // 翻倍扩容到了 6
ASSERT_INT_EQ_MSG(2, g_queue.capacity, "Capacity management check"); // 选测:如果你内部写了 Pop 自动缩容
ASSERT_INT_EQ_MSG(1, g_queue.size, "Size should drop to 1");
}
// 6. 严苛校验扩容理顺后的出队顺序是否依然正确 (FIFO)
ASSERT_INT_EQ(C_SUCCESS, c_ArrayQueue_Dequeue(&queue, &out_val));
ASSERT_INT_EQ(20, out_val);
ASSERT_INT_EQ(C_SUCCESS, c_ArrayQueue_Dequeue(&queue, &out_val));
ASSERT_INT_EQ(30, out_val);
ASSERT_INT_EQ(C_SUCCESS, c_ArrayQueue_Dequeue(&queue, &out_val));
ASSERT_INT_EQ(40, out_val);
ASSERT_INT_EQ(C_SUCCESS, c_ArrayQueue_Dequeue(&queue, &out_val));
ASSERT_INT_EQ(50, out_val);
// 用例 2:测试队列在空(Empty)或未初始化状态下的防御表现
void test_queue_empty_bounds() {
int out_val = 999;
// 空队列直接 Pop 应该报错
c_err_t err = c_ArrayQueue_Pop(&g_queue, &out_val);
ASSERT_MSG(err != C_ERR_OK, "Pop on empty queue should return an error code");
ASSERT_INT_EQ_MSG(999, out_val, "Output value should remain untouched on failure");
// 空队列 Peek 应该返回 NULL
ASSERT_MSG(c_ArrayQueue_Peek(&g_queue) == NULL, "Peek on empty queue must return NULL");
}
// 用例 3:测试循环环绕与动态扩容(如果是循环队列,该用例极度核心)
void test_queue_wrap_around_and_expand() {
int v = 0;
int out = 0;
// 1. 先把初始容量 4 填满
for (int i = 1; i <= 4; i++) {
v = i * 10; // 10, 20, 30, 40
c_ArrayQueue_Push(&g_queue, &v);
}
// 2. 弹出 2 个元素(释放前面两个格子的空间,触发头部指针往后移动)
c_ArrayQueue_Pop(&g_queue, &out); // 弹出 10
c_ArrayQueue_Pop(&g_queue, &out); // 弹出 20
// 3. 再次塞入 2 个元素(如果是循环队列,这俩元素会被存到刚才释放的 0 和 1 索引槽位)
v = 50; c_ArrayQueue_Push(&g_queue, &v);
v = 60; c_ArrayQueue_Push(&g_queue, &v);
// 4. 此时队列满(包含 30, 40, 50, 60),再次 Push 触发扩容
v = 70;
c_err_t err = c_ArrayQueue_Push(&g_queue, &v);
ASSERT_INT_EQ_MSG(C_ERR_OK, err, "Push triggering growth failed");
ASSERT_MSG(g_queue.capacity > 4, "Queue failed to expand capacity");
// 5. 依次全部弹出,验证即使经历过“环绕”与“扩容搬移内存”,FIFO 序列依旧保持绝对准确
int expected_sequence[] = {30, 40, 50, 60, 70};
for (int i = 0; i < 5; i++) {
c_ArrayQueue_Pop(&g_queue, &out);
char msg[100];
sprintf(msg, "Sequence broke at check-index [%d], expected %d", i, expected_sequence[i]);
ASSERT_INT_EQ_MSG(expected_sequence[i], out, msg);
}
}
// 用例 4:测试任意位置删除(c_ArrayQueue_Remove
void test_queue_remove_by_index() {
int values[] = {100, 200, 300, 400};
for (int i = 0; i < 4; i++) {
c_ArrayQueue_Push(&g_queue, &values[i]);
}
// 尝试删除越界索引(当前有 4 个元素,有效索引为 0~3,删除 5 应该失败)
c_err_t err_out = c_ArrayQueue_Remove(&g_queue, 5);
ASSERT_MSG(err_out != C_ERR_OK, "Remove out of bounds should fail");
// 删除当前队列中的中间元素(索引 1,即删除 200)
c_err_t err_ok = c_ArrayQueue_Remove(&g_queue, 1);
ASSERT_INT_EQ_MSG(C_ERR_OK, err_ok, "Remove element failed");
ASSERT_INT_EQ_MSG(3, g_queue.size, "Size should be 3 after removal");
// 依次 Pop 验证剩下的元素顺序是否已经平滑前移(应该是 100 -> 300 -> 400
int out = 0;
c_ArrayQueue_Pop(&g_queue, &out);
ASSERT_INT_EQ_MSG(100, out, "First element should still be 100");
c_ArrayQueue_Pop(&g_queue, &out);
ASSERT_INT_EQ_MSG(300, out, "Element 300 should shift forward to index 1");
c_ArrayQueue_Pop(&g_queue, &out);
ASSERT_INT_EQ_MSG(400, out, "Element 400 should shift forward to index 2");
ASSERT_TRUE(c_ArrayQueue_IsEmpty(&queue));
c_ArrayQueue_Destroy(&queue);
free(backing_buffer);
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
int main(int argc, char** argv){
TEST_START(Starting Unit Tests);
RUN_TEST_FIXTURE(test_queue_push_pop_basic, setup_queue, teardown_queue);
RUN_TEST_FIXTURE(test_queue_empty_bounds, setup_queue, teardown_queue);
RUN_TEST_FIXTURE(test_queue_wrap_around_and_expand, setup_queue, teardown_queue);
RUN_TEST_FIXTURE(test_queue_remove_by_index, setup_queue, teardown_queue);
// 打印最终统计报告
TEST_START(C_ArrayQueue_Module_Tests);
RUN_TEST(test_queue_basic_operations);
TEST_REPORT();
RETURN_TEST_STATUS;
return 0;
}