Files

133 lines
5.0 KiB
C
Raw Permalink Normal View History

2026-08-10 01:21:15 +08:00
#include "c_ArrayQueue.h"
#include <stdlib.h>
#include <stdio.h>
typedef struct {
char name[16];
int score;
} Player_t;
void test_log(const char* test_name) {
printf("[PASS] %s\n", test_name);
}
int main() {
printf("==================================================\n");
printf(" 開始執行 c_ArrayQueue 全新調整版完整測試用例\n");
printf("==================================================\n\n");
// ==========================================
// 1. 測試初始化 (Init)
// ==========================================
c_ArrayQueue_t q;
// 初始容量設為 2 以驗證後續的自動擴容
c_err_t err = c_ArrayQueue_Init(&q, sizeof(Player_t), 2);
assert(err == C_ERR_SUCCESS);
assert(q.size == 0);
assert(q.capacity == 2);
assert(q.obj_size == sizeof(Player_t));
test_log("1. 佇列初始化狀態驗證成功");
// ==========================================
// 2. 測試推入與動態擴容 (Push)
// ==========================================
Player_t p1 = {"Alice", 95};
Player_t p2 = {"Bob", 88};
Player_t p3 = {"Charlie", 92};
err = c_ArrayQueue_Push(&q, &p1); assert(err == C_ERR_SUCCESS);
err = c_ArrayQueue_Push(&q, &p2); assert(err == C_ERR_SUCCESS);
assert(q.size == 2);
assert(q.capacity == 2);
// 推入第三筆,預期觸發翻倍擴容 (2 -> 4)
err = c_ArrayQueue_Push(&q, &p3);
assert(err == C_ERR_SUCCESS);
assert(q.size == 3);
assert(q.capacity == 4);
test_log("2. 資料值複製推入與自動動態擴容成功");
// ==========================================
// 3. 測試查看最前端元素 (Peek)
// ==========================================
// 由於是 FIFO,目前最前端應該是第一個推進去的 Alice
Player_t* p_peek = (Player_t*)c_ArrayQueue_Peek(&q);
assert(p_peek != NULL);
assert(strcmp(p_peek->name, "Alice") == 0);
assert(p_peek->score == 95);
assert(q.size == 3); // 驗證 Peek 不會影響 size
test_log("3. 唯讀查看最前端元素 (Peek) 成功");
// ==========================================
// 4. 測試隨機刪除與平移 (Remove)
// ==========================================
// 目前佇列內容:Index 0="Alice", Index 1="Bob", Index 2="Charlie"
// 嘗試隨機刪除中間的 "Bob" (Index 1)
err = c_ArrayQueue_Remove(&q, 1);
assert(err == C_ERR_SUCCESS);
assert(q.size == 2);
// 驗證原本 Index 2 的 "Charlie" 是否成功向前平移到 Index 1
// 我們可以推入一個暫時資料來間接確認,或者看 Peek(依然要是Alice)
p_peek = (Player_t*)c_ArrayQueue_Peek(&q);
assert(strcmp(p_peek->name, "Alice") == 0);
// 測試刪除越界防呆
err = c_ArrayQueue_Remove(&q, 5);
assert(err == C_ERR_INDEX);
test_log("4. 隨機刪除 (Remove) 與記憶體平移成功");
// ==========================================
// 5. 測試全新安全版先進先出彈出 (Pop - 使用者自備緩衝區)
// ==========================================
// 目前佇列剩餘內容:Index 0="Alice", Index 1="Charlie"
Player_t local_buf;
// 第一次 Pop:預期安全複製出 "Alice"
err = c_ArrayQueue_Pop(&q, &local_buf);
assert(err == C_ERR_SUCCESS);
assert(strcmp(local_buf.name, "Alice") == 0);
assert(local_buf.score == 95);
assert(q.size == 1);
// 彈出後,最前端應平移更新為 "Charlie"
p_peek = (Player_t*)c_ArrayQueue_Peek(&q);
assert(strcmp(p_peek->name, "Charlie") == 0);
// 第二次 Pop:預期安全複製出 "Charlie"
err = c_ArrayQueue_Pop(&q, &local_buf);
assert(err == C_ERR_SUCCESS);
assert(strcmp(local_buf.name, "Charlie") == 0);
assert(q.size == 0);
// 第三次 Pop:此時佇列已空,預期回傳 C_ERR_OUT_OF_BOUNDS
err = c_ArrayQueue_Pop(&q, &local_buf);
assert(err == C_ERR_EMPTY);
// 空佇列時 Peek 應回傳 NULL
assert(c_ArrayQueue_Peek(&q) == NULL);
test_log("5. 全新安全彈出 (Pop) 語義與空佇列防呆驗證成功");
// ==========================================
// 6. 介面參數無效指標檢查
// ==========================================
assert(c_ArrayQueue_Init(NULL, sizeof(Player_t), 4) == C_ERR_PARAM);
assert(c_ArrayQueue_Push(NULL, &p1) == C_ERR_PARAM);
assert(c_ArrayQueue_Pop(NULL, &local_buf) == C_ERR_PARAM);
// assert(c_ArrayQueue_Pop(&q, NULL) == C_ERR_PARAM);
test_log("6. 介面 NULL 指標防呆驗證成功");
// ==========================================
// 7. 測試銷毀與記憶體釋放 (Destroy)
// ==========================================
c_ArrayQueue_Destroy(&q);
assert(q.array == NULL);
assert(q.size == 0);
assert(q.capacity == 0);
assert(q.obj_size == 0);
test_log("7. 佇列資源銷毀與指標重置成功");
printf("\n==================================================\n");
printf(" 恭喜!調整版 c_ArrayQueue 所有單元測試順利通過!\n");
printf("==================================================\n");
return 0;
}