Files
cKit/Foundation/c_ArrayQueue.t.c
T
2026-08-29 11:39:28 +08:00

152 lines
5.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "c_ArrayQueue.h"
#include <stdlib.h>
#include <stdio.h>
#include <c_Test.h>
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
static c_ArrayQueue_t g_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");
}
}
// 清理环境:安全销毁队列
void teardown_queue() {
c_ArrayQueue_Destroy(&g_queue);
}
// 用例 1:测试常规入队、查看对头、出队(FIFO 基础逻辑)
void test_queue_push_pop_basic() {
int v1 = 10, v2 = 20, v3 = 30;
// 入队 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");
// 检查大小
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 顺序
int out_val = 0;
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");
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");
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");
}
// 用例 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");
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
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_REPORT();
RETURN_TEST_STATUS;
return 0;
}