/** ********************************************************************************************************************** * @file menu_test.c * @brief 菜单组件测试用例 * @author menu_component * @date 2025-12-19 ********************************************************************************************************************** */ #include "../api/menu_api.h" #include "../port/menu_port.h" #include #include /* 测试菜单节点ID定义 */ #define TEST_MENU_ID_ROOT 1U #define TEST_MENU_ID_ITEM1 2U #define TEST_MENU_ID_ITEM2 3U #define TEST_MENU_ID_ITEM3 4U #define TEST_MENU_ID_SUB1 5U #define TEST_MENU_ID_SUB2 6U /* 测试全局变量 */ static uint32_t sg_test_tick = 0; static bool sg_test_callback_called = false; static MenuNodeId sg_test_last_node_id = 0; /* 测试回调函数 */ static MenuErrCode test_enter_callback(MenuNodeId node_id, struct MenuCoreCtx* core_ctx) { (void)core_ctx; sg_test_callback_called = true; sg_test_last_node_id = node_id; printf("Callback called for node %d\n", node_id); return MENU_ERR_OK; } static MenuErrCode test_exit_callback(MenuNodeId node_id, struct MenuCoreCtx* core_ctx) { (void)core_ctx; sg_test_callback_called = true; sg_test_last_node_id = node_id; printf("Exit callback called for node %d\n", node_id); return MENU_ERR_OK; } /* 测试硬件驱动 */ static uint32_t test_get_tick(void) { return sg_test_tick++; } static void test_printf(const char* fmt, va_list args) { vprintf(fmt, args); } static MenuPortDriver sg_test_driver = { .printf = test_printf, .get_tick = test_get_tick, .delay_ms = NULL, .display = NULL, .key_scan = NULL, .irq_ctrl = NULL, .error_handler = NULL, .modbus_send = NULL, .modbus_receive = NULL, }; /* 测试函数 */ /** * @brief 测试菜单初始化和反初始化 */ static bool test_menu_init_deinit(void) { printf("\n=== Test: Menu Init/Deinit ===\n"); // 初始化硬件端口 MenuErrCode err = menu_port_init(&sg_test_driver); if (err != MENU_ERR_OK) { printf("FAIL: Failed to initialize port\n"); return false; } // 初始化菜单 err = menu_init(); if (err != MENU_ERR_OK) { printf("FAIL: Failed to initialize menu\n"); return false; } // 反初始化菜单 err = menu_deinit(); if (err != MENU_ERR_OK) { printf("FAIL: Failed to deinitialize menu\n"); return false; } // 反初始化硬件端口 err = menu_port_deinit(); if (err != MENU_ERR_OK) { printf("FAIL: Failed to deinitialize port\n"); return false; } printf("PASS: Menu init/deinit test passed\n"); return true; } /** * @brief 测试菜单节点注册 */ static bool test_menu_node_register(void) { printf("\n=== Test: Menu Node Register ===\n"); // 初始化 menu_port_init(&sg_test_driver); menu_init(); // 注册根节点 MenuNodeId root_id = menu_register_node(TEST_MENU_ID_ROOT, 0, "Root Menu", test_enter_callback, test_exit_callback); if (root_id != TEST_MENU_ID_ROOT) { printf("FAIL: Failed to register root node\n"); menu_deinit(); menu_port_deinit(); return false; } printf("PASS: Root node registered\n"); // 注册子节点 MenuNodeId item1_id = menu_register_node(TEST_MENU_ID_ITEM1, TEST_MENU_ID_ROOT, "Item 1", test_enter_callback, NULL); if (item1_id != TEST_MENU_ID_ITEM1) { printf("FAIL: Failed to register item 1\n"); menu_deinit(); menu_port_deinit(); return false; } printf("PASS: Item 1 registered\n"); MenuNodeId item2_id = menu_register_node(TEST_MENU_ID_ITEM2, TEST_MENU_ID_ROOT, "Item 2", test_enter_callback, NULL); if (item2_id != TEST_MENU_ID_ITEM2) { printf("FAIL: Failed to register item 2\n"); menu_deinit(); menu_port_deinit(); return false; } printf("PASS: Item 2 registered\n"); // 注册孙子节点 MenuNodeId sub1_id = menu_register_node(TEST_MENU_ID_SUB1, TEST_MENU_ID_ITEM1, "Sub Item 1", test_enter_callback, NULL); if (sub1_id != TEST_MENU_ID_SUB1) { printf("FAIL: Failed to register sub item 1\n"); menu_deinit(); menu_port_deinit(); return false; } printf("PASS: Sub item 1 registered\n"); // 清理 menu_deinit(); menu_port_deinit(); printf("PASS: Menu node register test passed\n"); return true; } /** * @brief 测试菜单事件处理 */ static bool test_menu_event_processing(void) { printf("\n=== Test: Menu Event Processing ===\n"); // 初始化 menu_port_init(&sg_test_driver); menu_init(); // 注册测试节点 menu_register_node(TEST_MENU_ID_ROOT, 0, "Root Menu", test_enter_callback, test_exit_callback); menu_register_node(TEST_MENU_ID_ITEM1, TEST_MENU_ID_ROOT, "Item 1", test_enter_callback, NULL); menu_register_node(TEST_MENU_ID_ITEM2, TEST_MENU_ID_ROOT, "Item 2", test_enter_callback, NULL); // 重置测试状态 sg_test_callback_called = false; sg_test_last_node_id = 0; // 发送上键事件 MenuErrCode err = menu_post_event(MENU_EVENT_KEY_UP, 1); if (err != MENU_ERR_OK) { printf("FAIL: Failed to post UP event\n"); menu_deinit(); menu_port_deinit(); return false; } printf("PASS: UP event posted\n"); // 发送下键事件 err = menu_post_event(MENU_EVENT_KEY_DOWN, 1); if (err != MENU_ERR_OK) { printf("FAIL: Failed to post DOWN event\n"); menu_deinit(); menu_port_deinit(); return false; } printf("PASS: DOWN event posted\n"); // 处理菜单主循环 menu_main_loop(test_get_tick()); printf("PASS: Menu main loop processed\n"); // 清理 menu_deinit(); menu_port_deinit(); printf("PASS: Menu event processing test passed\n"); return true; } /** * @brief 测试菜单状态查询 */ static bool test_menu_state_query(void) { printf("\n=== Test: Menu State Query ===\n"); // 初始化 menu_port_init(&sg_test_driver); menu_init(); // 注册测试节点 menu_register_node(TEST_MENU_ID_ROOT, 0, "Root Menu", NULL, NULL); // 查询当前状态 MenuState state = menu_get_state(); printf("Current state: %d\n", state); // 查询当前节点 MenuNodeId curr_node = menu_get_current_node(); printf("Current node: %d\n", curr_node); // 查询导航深度 uint8_t depth = menu_get_nav_depth(); printf("Navigation depth: %d\n", depth); // 清理 menu_deinit(); menu_port_deinit(); printf("PASS: Menu state query test passed\n"); return true; } /** * @brief 主测试函数 */ int main(int argc, char* argv[]) { (void)argc; (void)argv; printf("Menu Component Test Suite\n"); printf("========================\n"); int test_count = 0; int pass_count = 0; // 运行所有测试 test_count++; if (test_menu_init_deinit()) { pass_count++; } test_count++; if (test_menu_node_register()) { pass_count++; } test_count++; if (test_menu_event_processing()) { pass_count++; } test_count++; if (test_menu_state_query()) { pass_count++; } // 打印测试结果 printf("\n========================\n"); printf("Test Results: %d/%d tests passed\n", pass_count, test_count); printf("========================\n"); if (pass_count == test_count) { printf("All tests passed!\n"); return EXIT_SUCCESS; } else { printf("Some tests failed!\n"); return EXIT_FAILURE; } }