测试用例
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
#include "c_ArrayStack.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <c_Test.h>
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
static c_ArrayStack_t g_stack;
|
||||
|
||||
// 启动环境:初始化一个初始容量为 2 的 int 类型栈
|
||||
static void setup_stack() {
|
||||
c_err_t err = c_ArrayStack_Init(&g_stack, sizeof(int), 2);
|
||||
if (err != C_ERR_OK) {
|
||||
printf(" " COLOR_RED "[ERROR] Stack Setup failed!" COLOR_RESET "\n");
|
||||
}
|
||||
}
|
||||
|
||||
// 清理环境:安全销毁栈,杜绝内存泄漏
|
||||
static void teardown_stack() {
|
||||
c_ArrayStack_Destroy(&g_stack);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
|
||||
// 用例 1:测试 LIFO(后进先出)核心逻辑、IsEmpty 状态及 Peek 观察
|
||||
static void test_stack_push_pop_lifo() {
|
||||
// 初始状态应该为空
|
||||
ASSERT_MSG(c_ArrayStack_IsEmpty(&g_stack) == true, "Stack should be empty initially");
|
||||
|
||||
int v1 = 111, v2 = 222;
|
||||
ASSERT_INT_EQ_MSG(C_ERR_OK, c_ArrayStack_Push(&g_stack, &v1), "Push 111 failed");
|
||||
ASSERT_INT_EQ_MSG(C_ERR_OK, c_ArrayStack_Push(&g_stack, &v2), "Push 222 failed");
|
||||
|
||||
// 此时不应该为空,大小应为 2
|
||||
ASSERT_MSG(c_ArrayStack_IsEmpty(&g_stack) == false, "Stack should not be empty");
|
||||
ASSERT_INT_EQ_MSG(2, g_stack.size, "Stack size should be 2");
|
||||
|
||||
// 测试 Peek:应该看到最后压入的 222,且栈大小不变
|
||||
int* top_ptr = (int*)c_ArrayStack_Peek(&g_stack);
|
||||
ASSERT_MSG(top_ptr != NULL, "Peek should not return NULL");
|
||||
ASSERT_INT_EQ_MSG(222, *top_ptr, "Peek value should be 222");
|
||||
ASSERT_INT_EQ_MSG(2, g_stack.size, "Size must remain 2 after peek");
|
||||
|
||||
// 测试 Pop:验证 LIFO 顺序
|
||||
int out_val = 0;
|
||||
ASSERT_INT_EQ_MSG(C_ERR_OK, c_ArrayStack_Pop(&g_stack, &out_val), "First pop failed");
|
||||
ASSERT_INT_EQ_MSG(222, out_val, "First popped value should be 222 (LIFO)");
|
||||
|
||||
ASSERT_INT_EQ_MSG(C_ERR_OK, c_ArrayStack_Pop(&g_stack, &out_val), "Second pop failed");
|
||||
ASSERT_INT_EQ_MSG(111, out_val, "Second popped value should be 111");
|
||||
|
||||
// 最终应该重新变为空栈
|
||||
ASSERT_MSG(c_ArrayStack_IsEmpty(&g_stack) == true, "Stack should be empty after popping all elements");
|
||||
}
|
||||
|
||||
|
||||
// 用例 2:测试空栈(Empty)的边界防御表现
|
||||
static void test_stack_empty_bounds() {
|
||||
int dummy = 999;
|
||||
|
||||
// 空栈执行 Pop 应该安全报错(例如返回 C_ERR_EMPTY 或非 OK 状态)
|
||||
c_err_t err = c_ArrayStack_Pop(&g_stack, &dummy);
|
||||
ASSERT_MSG(err != C_ERR_OK, "Pop on empty stack should return an error code");
|
||||
ASSERT_INT_EQ_MSG(999, dummy, "Output buffer should remain unchanged on failure");
|
||||
|
||||
// 空栈执行 Peek 应该安全返回 NULL
|
||||
ASSERT_MSG(c_ArrayStack_Peek(&g_stack) == NULL, "Peek on empty stack must return NULL");
|
||||
}
|
||||
|
||||
|
||||
// 用例 3:动态自动扩容测试
|
||||
static void test_stack_auto_expansion() {
|
||||
// 初始容量设为了 2,连续压入 4 个数据触发自动扩容
|
||||
for (int i = 1; i <= 4; i++) {
|
||||
int val = i * 10;
|
||||
c_err_t err = c_ArrayStack_Push(&g_stack, &val);
|
||||
char msg[64];
|
||||
sprintf(msg, "Pushing element %d failed", val);
|
||||
ASSERT_INT_EQ_MSG(C_ERR_OK, err, msg);
|
||||
}
|
||||
|
||||
// 校验容量是否增长
|
||||
ASSERT_MSG(g_stack.capacity > 2, "Stack capacity should have grown");
|
||||
ASSERT_INT_EQ_MSG(4, g_stack.size, "Stack size should be 4");
|
||||
|
||||
// 倒序弹出校验,确保扩容重构内存后历史数据未损坏
|
||||
int out_val = 0;
|
||||
int expected_vals[] = {40, 30, 20, 10};
|
||||
for (int i = 0; i < 4; i++) {
|
||||
c_ArrayStack_Pop(&g_stack, &out_val);
|
||||
char msg[64];
|
||||
sprintf(msg, "Mismatched LIFO element at step %d", i);
|
||||
ASSERT_INT_EQ_MSG(expected_vals[i], out_val, msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 用例 4:测试从任意指定索引删除元素(c_ArrayStack_Remove)
|
||||
static void test_stack_remove_by_index() {
|
||||
// 压入底 -> 顶:10, 20, 30, 40
|
||||
// 索引映射:index 0 -> 10, index 1 -> 20, index 2 -> 30, index 3 -> 40
|
||||
for (int i = 1; i <= 4; i++) {
|
||||
int val = i * 10;
|
||||
c_ArrayStack_Push(&g_stack, &val);
|
||||
}
|
||||
|
||||
// 1. 测试越界删除防御(有效索引为 0~3)
|
||||
c_err_t err_invalid = c_ArrayStack_Remove(&g_stack, 4);
|
||||
ASSERT_MSG(err_invalid != C_ERR_OK, "Remove out of bounds should fail");
|
||||
|
||||
// 2. 删除中间的元素:索引 1 (对应数字 20)
|
||||
c_err_t err_ok = c_ArrayStack_Remove(&g_stack, 1);
|
||||
ASSERT_INT_EQ_MSG(C_ERR_OK, err_ok, "Remove middle element failed");
|
||||
ASSERT_INT_EQ_MSG(3, g_stack.size, "Size should drop to 3 after remove");
|
||||
|
||||
// 3. 验证删除后的整体结构。由于移除了 20,剩下的数组结构应为:10, 30, 40
|
||||
// 按照栈的 LIFO 弹出顺序,依次拿到的应该是 40 -> 30 -> 10
|
||||
int out_val = 0;
|
||||
|
||||
c_ArrayStack_Pop(&g_stack, &out_val);
|
||||
ASSERT_INT_EQ_MSG(40, out_val, "Top should still be 40");
|
||||
|
||||
c_ArrayStack_Pop(&g_stack, &out_val);
|
||||
ASSERT_INT_EQ_MSG(30, out_val, "Next should be 30 (since 20 was removed)");
|
||||
|
||||
c_ArrayStack_Pop(&g_stack, &out_val);
|
||||
ASSERT_INT_EQ_MSG(10, out_val, "Bottom element should be 10");
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
int main(int argc, char** argv){
|
||||
|
||||
TEST_START(Starting Unit Tests);
|
||||
|
||||
// 运行需要内存环境的用例
|
||||
RUN_TEST_FIXTURE(test_stack_push_pop_lifo, setup_stack, teardown_stack);
|
||||
RUN_TEST_FIXTURE(test_stack_empty_bounds, setup_stack, teardown_stack);
|
||||
RUN_TEST_FIXTURE(test_stack_auto_expansion, setup_stack, teardown_stack);
|
||||
RUN_TEST_FIXTURE(test_stack_remove_by_index, setup_stack, teardown_stack);
|
||||
|
||||
|
||||
// 打印最终统计报告
|
||||
TEST_REPORT();
|
||||
|
||||
RETURN_TEST_STATUS;
|
||||
}
|
||||
Reference in New Issue
Block a user