#include "c_ArrayStack.h" #include #include typedef struct { char url[64]; int depth; } BrowserHistory_t; void test_log(const char* test_name) { printf("[PASS] %s\n", test_name); } int main() { printf("==================================================\n"); printf(" 開始執行 c_ArrayStack 完整版測試用例\n"); printf("==================================================\n\n"); // ========================================== // 1. 測試初始化 (Init) // ========================================== c_ArrayStack_t s; c_err_t err = c_ArrayStack_Init(&s, sizeof(BrowserHistory_t), 2); // 初始容量設為 2 測試擴容 assert(err == C_ERR_SUCCESS); assert(s.size == 0); assert(s.capacity == 2); test_log("1. 堆疊初始化成功"); // ========================================== // 2. 測試資料推入與動態擴容 (Push) // ========================================== BrowserHistory_t page1 = {"github.com", 1}; BrowserHistory_t page2 = {"google.com", 2}; BrowserHistory_t page3 = {"stackoverflow.com", 3}; err = c_ArrayStack_Push(&s, &page1); assert(err == C_ERR_SUCCESS); err = c_ArrayStack_Push(&s, &page2); assert(err == C_ERR_SUCCESS); assert(s.size == 2); assert(s.capacity == 2); // 推入第三筆,預期自動觸發擴容翻倍 (2 -> 4) err = c_ArrayStack_Push(&s, &page3); assert(err == C_ERR_SUCCESS); assert(s.size == 3); assert(s.capacity == 4); test_log("2. 後進先出資料推入與動態擴容成功"); // ========================================== // 3. 測試查看堆疊頂端 (Peek) // ========================================== // 目前最頂端應該是最後推入的 stackoverflow.com BrowserHistory_t* p_peek = (BrowserHistory_t*)c_ArrayStack_Peek(&s); assert(p_peek != NULL); assert(strcmp(p_peek->url, "stackoverflow.com") == 0); assert(p_peek->depth == 3); assert(s.size == 3); // 驗證 Peek 不影響大小 test_log("3. 堆疊頂端唯讀查看 (Peek) 成功"); // ========================================== // 4. 測試隨機刪除 (Remove) // ========================================== // 目前狀態:Index 0="github.com", Index 1="google.com", Index 2="stackoverflow.com" // 嘗試隨機刪除中間的 "google.com" (Index 1) err = c_ArrayStack_Remove(&s, 1); assert(err == C_ERR_SUCCESS); assert(s.size == 2); // 驗證原本頂端的 "stackoverflow.com" 是否因平移前進到了 Index 1 // 此時的頂端(Index: size-1 = 1)依然必須是 stackoverflow.com p_peek = (BrowserHistory_t*)c_ArrayStack_Peek(&s); assert(strcmp(p_peek->url, "stackoverflow.com") == 0); // 測試刪除越界防呆 assert(c_ArrayStack_Remove(&s, 99) == C_ERR_INDEX); test_log("4. 內部隨機刪除 (Remove) 與記憶體平移成功"); // ========================================== // 5. 測試後進先出彈出 (Pop - 使用者自備緩衝區) // ========================================== // 目前堆疊內剩餘:Index 0="github.com", Index 1="stackoverflow.com" BrowserHistory_t local_buf; // 第一次 Pop:預期複製取出目前頂端的 "stackoverflow.com" err = c_ArrayStack_Pop(&s, &local_buf); assert(err == C_ERR_SUCCESS); assert(strcmp(local_buf.url, "stackoverflow.com") == 0); assert(s.size == 1); // 彈出後,頂端應更新為最初推進去的 "github.com" p_peek = (BrowserHistory_t*)c_ArrayStack_Peek(&s); assert(strcmp(p_peek->url, "github.com") == 0); // 第二次 Pop:預期複製取出 "github.com" err = c_ArrayStack_Pop(&s, &local_buf); assert(err == C_ERR_SUCCESS); assert(strcmp(local_buf.url, "github.com") == 0); assert(s.size == 0); // 第三次 Pop:此時堆疊已空,預期回傳越界錯誤 err = c_ArrayStack_Pop(&s, &local_buf); assert(err == C_ERR_EMPTY); assert(c_ArrayStack_Peek(&s) == NULL); test_log("5. 後進先出安全彈出 (Pop) 與空堆疊防呆成功"); // ========================================== // 6. 介面指標防呆檢查 // ========================================== assert(c_ArrayStack_Init(NULL, sizeof(BrowserHistory_t), 4) == C_ERR_PARAM); assert(c_ArrayStack_Push(NULL, &page1) == C_ERR_PARAM); assert(c_ArrayStack_Pop(&s, NULL) == C_ERR_PARAM); test_log("6. 介面 NULL 指標防呆驗證成功"); // ========================================== // 7. 銷毀堆疊 (Destroy) // ========================================== c_ArrayStack_Destroy(&s); assert(s.array == NULL); assert(s.size == 0); assert(s.capacity == 0); test_log("7. 堆疊銷毀與記憶體釋放成功"); printf("\n==================================================\n"); printf(" 恭喜!c_ArrayStack 所有單元測試順利通過!\n"); printf("==================================================\n"); return 0; }