201 lines
8.6 KiB
C
201 lines
8.6 KiB
C
#include <string.h>
|
|
|
|
#include "test_common.h"
|
|
|
|
#include "../src/Drv/pages/menu/view.h"
|
|
#include "../src/Drv/pages/menu/model.h"
|
|
#include "../src/Drv/pages/menu/page.h"
|
|
|
|
/* -------------------------------------------------------------------------
|
|
* 函数名: main
|
|
* 功能:
|
|
* 覆盖菜单模块的白盒/黑盒关键能力,验证:
|
|
* 1) Model 初始化与辅助函数
|
|
* 2) 菜单树构建与显示名称装饰
|
|
* 3) View 初始化后的端口与接口绑定
|
|
* 4) MenuPage 生命周期入口是否完整绑定
|
|
*
|
|
* 参数:
|
|
* 无
|
|
*
|
|
* 返回值:
|
|
* - 0 : 测试通过
|
|
* ------------------------------------------------------------------------- */
|
|
int main(void)
|
|
{
|
|
/* 用于 MenuView_CharLenCal / Position 相关白盒测试的临时数组 */
|
|
tagPMenuItem first[4] = {0};
|
|
tagPMenuItem index[4] = {0};
|
|
uint8_t max_len;
|
|
|
|
/* 页面实例:用于验证 MenuPage_GetInstance 生命周期回调绑定 */
|
|
page_t *menuPage;
|
|
|
|
/* 真实菜单模型对象:用于测试 MenuModel_Init 及其派生结果 */
|
|
menu_model_t menuModel;
|
|
|
|
/* 视图对象:用于验证 MenuView_Init 的接口与渲染端口初始化 */
|
|
MenuView view;
|
|
|
|
/* 自定义最小菜单树:用于单独测试 BuildTree / DecorateDisplayNames */
|
|
tagMenuItem customItems[4];
|
|
tagMenuItem customItems2[7];
|
|
tagMenuModel customModelTab[4] =
|
|
{
|
|
{0, "Root", "", 0, 0x0000, 0, NULL},
|
|
{1, "ChildA", "", 0, 0x0000, 0, NULL},
|
|
{2, "Leaf", "", 0, 0x0000, 0, NULL},
|
|
{1, "ChildB", "", 0, 0x0000, 0, NULL}
|
|
};
|
|
tagMenuModel customModelTab2[7] =
|
|
{
|
|
{0, "RootA", "", 0, 0x0000, 0, NULL},
|
|
{1, "A1", "", 0, 0x0000, 0, NULL},
|
|
{2, "A1a", "", 0, 0x0000, 0, NULL},
|
|
{1, "A2", "", 0, 0x0000, 0, NULL},
|
|
{0, "RootB", "", 0, 0x0000, 0, NULL},
|
|
{1, "B1", "", 0, 0x0000, 0, NULL},
|
|
{0, "RootC", "", 0, 0x0000, 0, NULL}
|
|
};
|
|
|
|
/* ---------------------------------------------------------------------
|
|
* Case 1:
|
|
* 测试 MenuModel_Init / MenuModel_CountTopLevel
|
|
* - 初始化真实菜单模型
|
|
* - 验证 0 级菜单数量统计结果有效
|
|
* --------------------------------------------------------------------- */
|
|
memset(&menuModel, 0, sizeof(menuModel));
|
|
MenuModel_Init(&menuModel);
|
|
|
|
/* ---------------------------------------------------------------------
|
|
* Case 2:
|
|
* 测试 MenuView_Utf8LenCal
|
|
* - 验证英文与中文字符串长度计算逻辑
|
|
* --------------------------------------------------------------------- */
|
|
ASSERT_EQ_INT(3, MenuModel_Utf8LenCal((uint8_t *)"ABC"));
|
|
ASSERT_EQ_INT(2, MenuModel_Utf8LenCal((uint8_t *)"你"));
|
|
|
|
/* ---------------------------------------------------------------------
|
|
* Case 3:
|
|
* 测试 MenuModel_IndexMenuItems / MenuModel_GetMenuMaxDisplayLen
|
|
* - 使用真实菜单模型验证 0 基序号初始化、子节点数量统计与子菜单宽度统计
|
|
* --------------------------------------------------------------------- */
|
|
first[0] = &menuModel.menuItems[0];
|
|
index[0] = &menuModel.menuItems[0];
|
|
first[1] = menuModel.menuItems[0].links.lower;
|
|
max_len = MenuModel_GetMenuMaxDisplayLen(first[1]);
|
|
ASSERT_TRUE(max_len > 0);
|
|
ASSERT_EQ_INT(0, menuModel.menuItems[0].rect.wPos);
|
|
ASSERT_EQ_INT(0, first[1]->rect.wPos);
|
|
ASSERT_TRUE(menuModel.menuItems[0].rect.wNum > 0);
|
|
if (first[1]->links.lower == NULL)
|
|
{
|
|
ASSERT_EQ_INT(0, first[1]->rect.wNum);
|
|
}
|
|
else
|
|
{
|
|
ASSERT_TRUE(first[1]->rect.wNum > 0);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------
|
|
* Case 4:
|
|
* 测试 MenuModel_DecorateDisplayNames 的真实初始化结果
|
|
* - 验证存在子菜单的项名称非空,并被正确用于显示
|
|
* --------------------------------------------------------------------- */
|
|
/* 有子菜单的项会被装饰追加 '\x10'(右箭头标记) */
|
|
ASSERT_TRUE(((const char *)menuModel.menuItems[1].menuDef.byName)[0] != '\0');
|
|
|
|
/* ---------------------------------------------------------------------
|
|
* Case 5:
|
|
* 测试 MenuModel_BuildTree
|
|
* - 使用自定义 4 节点菜单表验证父子、同层、闭环链路关系
|
|
* --------------------------------------------------------------------- */
|
|
memset(customItems, 0, sizeof(customItems));
|
|
|
|
MenuModel_BuildTree(customItems, customModelTab, 4);
|
|
MenuModel_IndexMenuItems(customItems, 4);
|
|
ASSERT_TRUE(customItems[0].links.lower == &customItems[1]);
|
|
ASSERT_TRUE(customItems[1].links.higher == &customItems[0]);
|
|
ASSERT_TRUE(customItems[1].links.lower == &customItems[2]);
|
|
ASSERT_TRUE(customItems[2].links.higher == &customItems[1]);
|
|
ASSERT_TRUE(customItems[1].links.behind == &customItems[3]);
|
|
ASSERT_TRUE(customItems[3].links.before == &customItems[1]);
|
|
ASSERT_TRUE(customItems[3].links.higher == &customItems[0]);
|
|
ASSERT_TRUE(customItems[3].links.behind == &customItems[1]); /* 同层闭环 */
|
|
ASSERT_EQ_INT(0, customItems[0].rect.wPos);
|
|
ASSERT_EQ_INT(2, customItems[0].rect.wNum);
|
|
ASSERT_EQ_INT(0, customItems[1].rect.wPos);
|
|
ASSERT_EQ_INT(1, customItems[1].rect.wNum);
|
|
ASSERT_EQ_INT(1, customItems[3].rect.wPos);
|
|
ASSERT_EQ_INT(0, customItems[3].rect.wNum);
|
|
ASSERT_EQ_INT(0, customItems[2].rect.wPos);
|
|
ASSERT_EQ_INT(0, customItems[2].rect.wNum);
|
|
|
|
/* ---------------------------------------------------------------------
|
|
* Case 5.1:
|
|
* 强化测试 MenuModel_IndexMenuItems
|
|
* - 覆盖多顶层、多兄弟、跨层回退后的 0 基 wPos / wNum 统计
|
|
* --------------------------------------------------------------------- */
|
|
memset(customItems2, 0, sizeof(customItems2));
|
|
MenuModel_BuildTree(customItems2, customModelTab2, 7);
|
|
MenuModel_IndexMenuItems(customItems2, 7);
|
|
ASSERT_EQ_INT(0, customItems2[0].rect.wPos);
|
|
ASSERT_EQ_INT(2, customItems2[0].rect.wNum);
|
|
ASSERT_EQ_INT(0, customItems2[1].rect.wPos);
|
|
ASSERT_EQ_INT(1, customItems2[1].rect.wNum);
|
|
ASSERT_EQ_INT(0, customItems2[2].rect.wPos);
|
|
ASSERT_EQ_INT(0, customItems2[2].rect.wNum);
|
|
ASSERT_EQ_INT(1, customItems2[3].rect.wPos);
|
|
ASSERT_EQ_INT(0, customItems2[3].rect.wNum);
|
|
ASSERT_EQ_INT(1, customItems2[4].rect.wPos);
|
|
ASSERT_EQ_INT(1, customItems2[4].rect.wNum);
|
|
ASSERT_EQ_INT(0, customItems2[5].rect.wPos);
|
|
ASSERT_EQ_INT(0, customItems2[5].rect.wNum);
|
|
ASSERT_EQ_INT(2, customItems2[6].rect.wPos);
|
|
ASSERT_EQ_INT(0, customItems2[6].rect.wNum);
|
|
|
|
/* ---------------------------------------------------------------------
|
|
* Case 6:
|
|
* 测试 MenuModel_DecorateDisplayNames
|
|
* - 验证有子节点的项追加 '\x10'
|
|
* - 验证叶子节点名称不被追加装饰符
|
|
* --------------------------------------------------------------------- */
|
|
MenuModel_DecorateDisplayNames(customItems, 4);
|
|
ASSERT_TRUE(customItems[0].menuDef.byName[4] == '\x10');
|
|
ASSERT_TRUE(customItems[0].menuDef.byName[5] == '\0');
|
|
ASSERT_TRUE(customItems[1].menuDef.byName[6] == '\x10');
|
|
ASSERT_TRUE(customItems[1].menuDef.byName[7] == '\0');
|
|
ASSERT_TRUE(customItems[2].menuDef.byName[4] == '\0'); /* 叶子节点不追加 */
|
|
|
|
/* ---------------------------------------------------------------------
|
|
* Case 7:
|
|
* 测试 MenuView_Init / MenuView_GetPortForTest
|
|
* - 验证 View 初始化后渲染端口、布局参数、接口函数指针均可用
|
|
* --------------------------------------------------------------------- */
|
|
/* View 初始化后,渲染端口派生数据和对外接口必须可用 */
|
|
memset(&view, 0, sizeof(view));
|
|
ASSERT_TRUE(MenuView_GetPortForTest() == NULL);
|
|
MenuView_Init(&view);
|
|
ASSERT_TRUE(MenuView_GetPortForTest() != NULL);
|
|
ASSERT_TRUE(view.update_selection_new_level != NULL);
|
|
ASSERT_TRUE(view.update_selection_same_level != NULL);
|
|
ASSERT_TRUE(view.full_refresh != NULL);
|
|
|
|
/* ---------------------------------------------------------------------
|
|
* Case 8:
|
|
* 测试 MenuPage_GetInstance
|
|
* - 验证页面生命周期入口已经完整绑定
|
|
* --------------------------------------------------------------------- */
|
|
/* 页面生命周期入口必须完整绑定,避免注册后生命周期不执行 */
|
|
menuPage = MenuPage_GetInstance();
|
|
ASSERT_TRUE(menuPage != NULL);
|
|
ASSERT_TRUE(menuPage->on_create != NULL);
|
|
ASSERT_TRUE(menuPage->on_enter != NULL);
|
|
ASSERT_TRUE(menuPage->on_exit != NULL);
|
|
ASSERT_TRUE(menuPage->on_destroy != NULL);
|
|
ASSERT_TRUE(menuPage->on_event != NULL);
|
|
ASSERT_TRUE(menuPage->on_loop != NULL);
|
|
|
|
return 0;
|
|
}
|