133 lines
5.0 KiB
C
133 lines
5.0 KiB
C
#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;
|
||
|
|
}
|