重构显示逻辑为 MVP 架构,进行显示模块的解耦
This commit is contained in:
@@ -6,8 +6,8 @@ set(DTU_TEST_COMMON_SOURCES
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/lcd/ascii.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/lcd/lcd.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/key.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/menu.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/display.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/menu/app/menu.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/menu/model/display.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/TCP/tcp.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/thread_utils.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/remoteDisplay.c"
|
||||
@@ -20,12 +20,17 @@ set(DTU_TEST_COMMON_SOURCES
|
||||
# - add_test: 注册到 CTest,支持 ctest 统一执行
|
||||
function(add_dtu_test test_name)
|
||||
add_executable(${test_name} ${ARGN})
|
||||
target_sources(${test_name} PRIVATE
|
||||
"${CMAKE_SOURCE_DIR}/src/common/utf8.c"
|
||||
)
|
||||
# 测试目标可见的头文件目录
|
||||
target_include_directories(${test_name} PRIVATE
|
||||
"${CMAKE_SOURCE_DIR}/include"
|
||||
"${CMAKE_SOURCE_DIR}/src"
|
||||
"${CMAKE_SOURCE_DIR}/src/TCP"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/lcd"
|
||||
"${CMAKE_SOURCE_DIR}/src/common"
|
||||
)
|
||||
# 平台差异:Windows 需要 ws2_32,非 Windows 使用 pthread
|
||||
if(WIN32)
|
||||
@@ -56,14 +61,6 @@ add_dtu_test(
|
||||
"${CMAKE_SOURCE_DIR}/src/TCP/tcp.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/thread_utils.c"
|
||||
)
|
||||
add_dtu_test(
|
||||
test_p0_utf8_next
|
||||
test_p0_utf8_next.c
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/lcd/lcd.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/lcd/lcd_draw.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/lcd/lcd_text.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/lcd/ascii.c"
|
||||
)
|
||||
add_dtu_test(
|
||||
test_p0_utf8_hz12_get
|
||||
test_p0_utf8_hz12_get.c
|
||||
@@ -89,12 +86,35 @@ add_dtu_test(
|
||||
add_dtu_test(
|
||||
test_p1_menu
|
||||
test_p1_menu.c
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/display.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/menu/model/menu_tree_builder.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/menu/view/menu_layout.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/lcd/lcd_text.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/lcd/lcd.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/lcd/ascii.c"
|
||||
)
|
||||
add_dtu_test(
|
||||
test_p1_menu_nav_legacy
|
||||
test_p1_menu_nav_legacy.c
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/menu/presenter/menu_navigator.c"
|
||||
)
|
||||
add_dtu_test(
|
||||
test_p1_menu_navigator
|
||||
test_p1_menu_navigator.c
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/menu/presenter/menu_navigator.c"
|
||||
)
|
||||
add_dtu_test(
|
||||
test_p1_menu_tree_builder
|
||||
test_p1_menu_tree_builder.c
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/menu/model/menu_tree_builder.c"
|
||||
)
|
||||
add_dtu_test(
|
||||
test_p1_menu_layout
|
||||
test_p1_menu_layout.c
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/menu/view/menu_layout.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/lcd/lcd_text.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/lcd/lcd.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/lcd/lcd_draw.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/lcd/lcd_text.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/lcd/ascii.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/key.c"
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------
|
||||
@@ -106,3 +126,21 @@ add_dtu_test(
|
||||
"${CMAKE_SOURCE_DIR}/src/TCP/tcp.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/thread_utils.c"
|
||||
)
|
||||
add_dtu_test(
|
||||
test_p2_menu_runtime_startup
|
||||
test_p2_menu_runtime_startup.c
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/menu/app/menu.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/menu/model/display.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/menu/model/menu_model.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/menu/view/menu_view.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/menu/presenter/menu_presenter.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/menu/model/menu_tree_builder.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/menu/view/menu_layout.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/menu/presenter/menu_navigator.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/menu/view/menu_renderer_lcd.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/lcd/lcd.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/lcd/lcd_draw.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/lcd/lcd_text.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/lcd/ascii.c"
|
||||
"${CMAKE_SOURCE_DIR}/src/Drv/key.c"
|
||||
)
|
||||
|
||||
@@ -1,13 +1,42 @@
|
||||
/* -------------------------------------------------------------------------
|
||||
* 文件名: test_p0_utf8_hz12_get.c
|
||||
* 作用:
|
||||
* 验证中文点阵查询接口 utf8_hz12_get() 的基础行为是否正确。
|
||||
*
|
||||
* 被测接口:
|
||||
* const uint8_t* utf8_hz12_get(uint32_t unicode);
|
||||
*
|
||||
* 测试目标:
|
||||
* 1) 对于字库中存在的码点,应返回非 NULL 位图指针。
|
||||
* 2) 对于字库范围外或不存在的码点,应返回 NULL。
|
||||
*
|
||||
* 说明:
|
||||
* - 本测试只校验“是否命中”这一契约,不校验位图内容本身。
|
||||
* - 若后续需要,可新增逐字节位图校验测试。
|
||||
* ------------------------------------------------------------------------- */
|
||||
#include "../src/Drv/lcd/ascii.h"
|
||||
#include "test_common.h"
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* 测试入口:
|
||||
* 按“命中/低位未命中/高位未命中”三个场景依次断言。
|
||||
*
|
||||
* 返回值约定:
|
||||
* 0 -> 测试通过
|
||||
* 非0 -> 断言失败(由 ASSERT_* 宏返回)
|
||||
* ------------------------------------------------------------------------- */
|
||||
int main(void)
|
||||
{
|
||||
/* 命中用例:U+4F60(“你”)通常在当前字库中存在 */
|
||||
const uint8_t* hit = utf8_hz12_get(0x4F60u); /* 你 */
|
||||
/* 低位未命中:非常低的控制区码点,预期不在中文字库 */
|
||||
const uint8_t* miss_low = utf8_hz12_get(0x0001u);
|
||||
/* 高位未命中:超高码点,预期不在当前 12 点阵中文表中 */
|
||||
const uint8_t* miss_high = utf8_hz12_get(0x10FFFFu);
|
||||
|
||||
/* 命中必须返回有效指针 */
|
||||
ASSERT_TRUE(hit != NULL);
|
||||
/* 非命中必须返回 NULL */
|
||||
ASSERT_TRUE(miss_low == NULL);
|
||||
ASSERT_TRUE(miss_high == NULL);
|
||||
return 0;
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#include "../src/Drv/lcd/lcd_text.h"
|
||||
#include "test_common.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
uint32_t unicode = 0;
|
||||
const unsigned char ascii[] = "A";
|
||||
const unsigned char u2[] = {0xC2, 0xA2, 0x00}; /* U+00A2 */
|
||||
const unsigned char u3[] = {0xE4, 0xBD, 0xA0, 0x00}; /* U+4F60 */
|
||||
const unsigned char invalid[] = {0xF0, 0x00}; /* 4-byte start not supported */
|
||||
const unsigned char truncated2[] = {0xC2, 0x00};
|
||||
const unsigned char truncated3[] = {0xE4, 0xBD, 0x00};
|
||||
|
||||
ASSERT_EQ_INT(1, utf8_next(ascii, &unicode));
|
||||
ASSERT_EQ_U32(0x41u, unicode);
|
||||
|
||||
ASSERT_EQ_INT(2, utf8_next(u2, &unicode));
|
||||
ASSERT_EQ_U32(0x00A2u, unicode);
|
||||
|
||||
ASSERT_EQ_INT(3, utf8_next(u3, &unicode));
|
||||
ASSERT_EQ_U32(0x4F60u, unicode);
|
||||
|
||||
ASSERT_EQ_INT(0, utf8_next(invalid, &unicode));
|
||||
ASSERT_EQ_INT(0, utf8_next(truncated2, &unicode));
|
||||
ASSERT_EQ_INT(0, utf8_next(truncated3, &unicode));
|
||||
return 0;
|
||||
}
|
||||
@@ -1,28 +1,47 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "test_common.h"
|
||||
#include "../src/Drv/menu.c"
|
||||
|
||||
#include "../src/Drv/menu/view/menu_layout.h"
|
||||
#include "../src/Drv/menu/model/menu_tree_builder.h"
|
||||
|
||||
static int noop_proc(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
tagMenuCtrl ctrl;
|
||||
tagMenuItem items[4];
|
||||
uint8_t menu_num[4] = {0};
|
||||
tagPMenuItem first[4] = {0};
|
||||
tagPMenuItem index[4] = {0};
|
||||
uint8_t max_len;
|
||||
|
||||
Menu_Init();
|
||||
ASSERT_TRUE(g_tMenuCtrl.by0LevelNum > 0);
|
||||
ASSERT_TRUE(g_tMenuCtrl.ptHead != NULL);
|
||||
ASSERT_TRUE(g_tMenuCtrl.ptCurrent != NULL);
|
||||
const tagMenuModel model[4] = {
|
||||
{0, "Root", "", 0, 0, 0, (FUNCPTR)noop_proc},
|
||||
{1, "设置", "", 0, 0, 0, (FUNCPTR)noop_proc},
|
||||
{2, "子项", "", 0, 0, 0, (FUNCPTR)noop_proc},
|
||||
{1, "查看", "", 0, 0, 0, (FUNCPTR)noop_proc},
|
||||
};
|
||||
|
||||
ASSERT_EQ_INT(3, utf8_len_cal((uint8_t*)"ABC"));
|
||||
ASSERT_EQ_INT(2, utf8_len_cal((uint8_t*)"你"));
|
||||
memset(&ctrl, 0, sizeof(ctrl));
|
||||
memset(items, 0, sizeof(items));
|
||||
|
||||
first[0] = g_tMenuCtrl.ptHead;
|
||||
index[0] = g_tMenuCtrl.ptHead;
|
||||
max_len = Menu_charLenCal(0, menu_num, first, index);
|
||||
MenuTree_0LevelNumCal(&ctrl, model, 4);
|
||||
ASSERT_EQ_INT(1, ctrl.by0LevelNum);
|
||||
MenuTree_MainCreate(items, model, 4);
|
||||
|
||||
ASSERT_EQ_INT(3, MenuLayout_Utf8LenCal((uint8_t *)"ABC"));
|
||||
ASSERT_EQ_INT(2, MenuLayout_Utf8LenCal((uint8_t *)"你"));
|
||||
|
||||
first[0] = &items[0];
|
||||
index[0] = &items[0];
|
||||
max_len = MenuLayout_CharLenCal(0, menu_num, first, index);
|
||||
ASSERT_TRUE(max_len > 0);
|
||||
ASSERT_TRUE(menu_num[1] > 0);
|
||||
ASSERT_STREQ("设置", (const char *)items[1].byName);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
47
tests/test_p1_menu_layout.c
Normal file
47
tests/test_p1_menu_layout.c
Normal file
@@ -0,0 +1,47 @@
|
||||
#include "test_common.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "../src/Drv/lcd/lcd.h"
|
||||
#include "../src/Drv/menu/app/menu.h"
|
||||
#include "../src/Drv/menu/view/menu_layout.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
tagMenuItem root;
|
||||
tagMenuItem child;
|
||||
MenuLayoutConfig config = {
|
||||
LCD_SIZE_X,
|
||||
LCD_SIZE_Y,
|
||||
MENU_YMIN,
|
||||
MENU_YMAX_FROM_LCD(LCD_SIZE_Y),
|
||||
LINE_HEIGHT,
|
||||
MENU_WITDTH,
|
||||
MENU_XADD,
|
||||
MENU_YADD};
|
||||
|
||||
memset(&root, 0, sizeof(root));
|
||||
memset(&child, 0, sizeof(child));
|
||||
|
||||
memcpy(root.byName, "Root", 5);
|
||||
memcpy(child.byName, "Child", 6);
|
||||
root.byClass = 0;
|
||||
child.byClass = 1;
|
||||
|
||||
root.ptLower = &child;
|
||||
root.ptBehind = &root;
|
||||
root.ptBefore = &root;
|
||||
child.ptHigher = &root;
|
||||
child.ptBehind = &child;
|
||||
child.ptBefore = &child;
|
||||
|
||||
ASSERT_EQ_INT(3, MenuLayout_Utf8LenCal((uint8_t *)"ABC"));
|
||||
ASSERT_EQ_INT(2, MenuLayout_Utf8LenCal((uint8_t *)"你"));
|
||||
|
||||
MenuLayout_PositionCal(&root, 1, &config);
|
||||
ASSERT_TRUE(root.wEPosX > root.wSPosX);
|
||||
ASSERT_TRUE(root.wEPosY > root.wSPosY);
|
||||
ASSERT_TRUE(root.wEPosY <= LCD_SIZE_Y);
|
||||
|
||||
return 0;
|
||||
}
|
||||
93
tests/test_p1_menu_nav_legacy.c
Normal file
93
tests/test_p1_menu_nav_legacy.c
Normal file
@@ -0,0 +1,93 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "test_common.h"
|
||||
|
||||
#include "../src/Drv/key.h"
|
||||
#include "../src/Drv/menu/presenter/menu_navigator.h"
|
||||
|
||||
static int g_exec_count = 0;
|
||||
|
||||
static int on_exec(void)
|
||||
{
|
||||
g_exec_count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void build_legacy_like_tree(MenuNavState *nav, tagMenuItem *root, tagMenuItem *m1, tagMenuItem *m2, tagMenuItem *m1_sub)
|
||||
{
|
||||
memset(nav, 0, sizeof(*nav));
|
||||
memset(root, 0, sizeof(*root));
|
||||
memset(m1, 0, sizeof(*m1));
|
||||
memset(m2, 0, sizeof(*m2));
|
||||
memset(m1_sub, 0, sizeof(*m1_sub));
|
||||
|
||||
root->byClass = 0;
|
||||
root->ptLower = m1;
|
||||
root->ptBefore = root;
|
||||
root->ptBehind = root;
|
||||
root->wPos = 1;
|
||||
|
||||
m1->byClass = 1;
|
||||
m1->wPos = 1;
|
||||
m1->ptHigher = root;
|
||||
m1->ptBefore = m2;
|
||||
m1->ptBehind = m2;
|
||||
m1->ptLower = m1_sub;
|
||||
m1->pfnWinProc = on_exec;
|
||||
|
||||
m2->byClass = 1;
|
||||
m2->wPos = 2;
|
||||
m2->ptHigher = root;
|
||||
m2->ptBefore = m1;
|
||||
m2->ptBehind = m1;
|
||||
m2->pfnWinProc = on_exec;
|
||||
|
||||
m1_sub->byClass = 2;
|
||||
m1_sub->wPos = 1;
|
||||
m1_sub->ptHigher = m1;
|
||||
m1_sub->ptBefore = m1_sub;
|
||||
m1_sub->ptBehind = m1_sub;
|
||||
m1_sub->pfnWinProc = on_exec;
|
||||
|
||||
nav->ptHead = root;
|
||||
nav->ptCurrent = m1;
|
||||
nav->ptCurBak = m1;
|
||||
nav->ptRoute[0] = root;
|
||||
nav->ptRoute[1] = m1;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
MenuNavState nav;
|
||||
tagMenuItem root;
|
||||
tagMenuItem m1;
|
||||
tagMenuItem m2;
|
||||
tagMenuItem m1_sub;
|
||||
MenuNavResult result;
|
||||
|
||||
build_legacy_like_tree(&nav, &root, &m1, &m2, &m1_sub);
|
||||
|
||||
result = MenuNavigator_ProcessKey(&nav, KEY_D);
|
||||
ASSERT_EQ_INT(1, result.needRefresh);
|
||||
ASSERT_TRUE(nav.ptCurrent == &m2);
|
||||
|
||||
result = MenuNavigator_ProcessKey(&nav, KEY_U);
|
||||
ASSERT_EQ_INT(1, result.needRefresh);
|
||||
ASSERT_TRUE(nav.ptCurrent == &m1);
|
||||
|
||||
result = MenuNavigator_ProcessKey(&nav, KEY_ENT);
|
||||
ASSERT_EQ_INT(1, result.needRefresh);
|
||||
ASSERT_TRUE(nav.ptCurrent == &m1_sub);
|
||||
|
||||
result = MenuNavigator_ProcessKey(&nav, KEY_ESC);
|
||||
ASSERT_EQ_INT(1, result.needRefresh);
|
||||
ASSERT_TRUE(nav.ptCurrent == &m1);
|
||||
|
||||
g_exec_count = 0;
|
||||
nav.ptCurrent = &m2;
|
||||
result = MenuNavigator_ProcessKey(&nav, KEY_ENT);
|
||||
ASSERT_EQ_INT(0, result.needRefresh);
|
||||
ASSERT_EQ_INT(1, g_exec_count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
79
tests/test_p1_menu_navigator.c
Normal file
79
tests/test_p1_menu_navigator.c
Normal file
@@ -0,0 +1,79 @@
|
||||
#include "test_common.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "../src/Drv/key.h"
|
||||
#include "../src/Drv/menu/presenter/menu_navigator.h"
|
||||
|
||||
static int g_exec_count = 0;
|
||||
|
||||
static int on_exec(void)
|
||||
{
|
||||
g_exec_count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void build_two_level(MenuNavState *nav, tagMenuItem *root, tagMenuItem *child_a, tagMenuItem *child_b)
|
||||
{
|
||||
memset(nav, 0, sizeof(*nav));
|
||||
memset(root, 0, sizeof(*root));
|
||||
memset(child_a, 0, sizeof(*child_a));
|
||||
memset(child_b, 0, sizeof(*child_b));
|
||||
|
||||
root->byClass = 0;
|
||||
root->wPos = 1;
|
||||
root->ptLower = child_a;
|
||||
root->ptBefore = root;
|
||||
root->ptBehind = root;
|
||||
|
||||
child_a->byClass = 1;
|
||||
child_a->wPos = 1;
|
||||
child_a->ptHigher = root;
|
||||
child_a->ptBefore = child_b;
|
||||
child_a->ptBehind = child_b;
|
||||
child_a->pfnWinProc = on_exec;
|
||||
|
||||
child_b->byClass = 1;
|
||||
child_b->wPos = 2;
|
||||
child_b->ptHigher = root;
|
||||
child_b->ptBefore = child_a;
|
||||
child_b->ptBehind = child_a;
|
||||
child_b->pfnWinProc = on_exec;
|
||||
|
||||
nav->ptHead = root;
|
||||
nav->ptCurrent = child_a;
|
||||
nav->ptCurBak = child_a;
|
||||
nav->ptRoute[0] = root;
|
||||
nav->ptRoute[1] = child_a;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
MenuNavState nav;
|
||||
tagMenuItem root;
|
||||
tagMenuItem a;
|
||||
tagMenuItem b;
|
||||
MenuNavResult result;
|
||||
|
||||
build_two_level(&nav, &root, &a, &b);
|
||||
|
||||
result = MenuNavigator_ProcessKey(&nav, KEY_D);
|
||||
ASSERT_EQ_INT(1, result.needRefresh);
|
||||
ASSERT_TRUE(nav.ptCurrent == &b);
|
||||
|
||||
result = MenuNavigator_ProcessKey(&nav, KEY_U);
|
||||
ASSERT_EQ_INT(1, result.needRefresh);
|
||||
ASSERT_TRUE(nav.ptCurrent == &a);
|
||||
|
||||
g_exec_count = 0;
|
||||
result = MenuNavigator_ProcessKey(&nav, KEY_ENT);
|
||||
ASSERT_EQ_INT(0, result.needRefresh);
|
||||
ASSERT_EQ_INT(1, g_exec_count);
|
||||
|
||||
result = MenuNavigator_ProcessKey(&nav, KEY_ESC);
|
||||
ASSERT_EQ_INT(1, result.skipRenderThisRound);
|
||||
ASSERT_TRUE(nav.ptCurrent == root.ptLower);
|
||||
ASSERT_TRUE(nav.ptRoute[0] == &root);
|
||||
|
||||
return 0;
|
||||
}
|
||||
37
tests/test_p1_menu_tree_builder.c
Normal file
37
tests/test_p1_menu_tree_builder.c
Normal file
@@ -0,0 +1,37 @@
|
||||
#include "test_common.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "../src/Drv/menu/model/menu_tree_builder.h"
|
||||
|
||||
static int noop_proc(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
tagMenuCtrl ctrl;
|
||||
tagMenuItem items[4];
|
||||
const tagMenuModel model[4] = {
|
||||
{0, "Root", "", 0, 0, 0, (FUNCPTR)noop_proc},
|
||||
{1, "A", "", 0, 0, 0, (FUNCPTR)noop_proc},
|
||||
{1, "B", "", 0, 0, 0, (FUNCPTR)noop_proc},
|
||||
{2, "C", "", 0, 0, 0, (FUNCPTR)noop_proc},
|
||||
};
|
||||
|
||||
memset(&ctrl, 0, sizeof(ctrl));
|
||||
memset(items, 0, sizeof(items));
|
||||
|
||||
MenuTree_0LevelNumCal(&ctrl, model, 4);
|
||||
ASSERT_EQ_INT(1, ctrl.by0LevelNum);
|
||||
|
||||
MenuTree_MainCreate(items, model, 4);
|
||||
ASSERT_TRUE(items[0].ptLower == &items[1]);
|
||||
ASSERT_TRUE(items[1].ptBehind == &items[2]);
|
||||
ASSERT_TRUE(items[2].ptBefore == &items[1]);
|
||||
ASSERT_TRUE(items[2].ptLower == &items[3]);
|
||||
ASSERT_TRUE(items[3].ptHigher == &items[2]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
39
tests/test_p2_menu_runtime_startup.c
Normal file
39
tests/test_p2_menu_runtime_startup.c
Normal file
@@ -0,0 +1,39 @@
|
||||
#include "test_common.h"
|
||||
|
||||
#include "../src/Drv/key.h"
|
||||
#include "../src/Drv/menu/app/menu.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int decorated_found = 0;
|
||||
uint16_t itemCount = 0;
|
||||
const tagMenuItem *menuItems;
|
||||
|
||||
MenuApp_Init();
|
||||
Key_Init();
|
||||
menuItems = MenuApp_GetMenuItems(&itemCount);
|
||||
|
||||
for (uint16_t i = 0; i < itemCount; i++)
|
||||
{
|
||||
if (menuItems[i].ptLower != NULL)
|
||||
{
|
||||
uint8_t len = 0;
|
||||
while ((len < 50) && (menuItems[i].byName[len] != '\0'))
|
||||
{
|
||||
len++;
|
||||
}
|
||||
ASSERT_TRUE(len > 0);
|
||||
ASSERT_EQ_INT('\x10', menuItems[i].byName[len - 1]);
|
||||
decorated_found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ASSERT_TRUE(decorated_found == 1);
|
||||
|
||||
/* 首次路由应仅触发首帧绘制,不应崩溃 */
|
||||
MenuApp_PollInput();
|
||||
|
||||
/* 二次刷新路径也不应崩溃 */
|
||||
MenuApp_Render();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user