305 lines
7.7 KiB
C
305 lines
7.7 KiB
C
/**
|
|
**********************************************************************************************************************
|
|
* @file menu_test.c
|
|
* @brief 菜单组件测试用例
|
|
* @author menu_component
|
|
* @date 2025-12-19
|
|
**********************************************************************************************************************
|
|
*/
|
|
|
|
#include "../api/menu_api.h"
|
|
#include "../port/menu_port.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
/* 测试菜单节点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;
|
|
}
|
|
}
|