From f8919fc7ed0f93915e7a9795263ed361e9d133d3 Mon Sep 17 00:00:00 2001 From: xueben Date: Tue, 3 Feb 2026 00:23:12 +0800 Subject: [PATCH] =?UTF-8?q?Fix:=20=E4=BF=AE=E5=A4=8D=E7=BC=93=E5=86=B2?= =?UTF-8?q?=E5=8C=BA=E5=AE=B9=E9=87=8FAPI=E5=B9=B6=E8=A1=A5=E5=85=85?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What: as follows: 1. 修复 get_bits_btn_buffer_capacity() 返回实际可用容量(SIZE-1)而非数组大小; 2. 添加 BITS_BTN_MAX_BUTTONS 宏定义(基于 button_mask_type_t 大小); 3. 增强参数校验:添加 btns_cnt 超限检查(-5)、单按钮 param NULL 检查(-6)、组合按钮 param NULL 检查(-7); 4. 优化 bits_btn_write_buffer_overwrite_c11 函数逻辑(调整 current_read 读取时机); 5. 修正 bits_btn_clear_buffer_c11 中的 memory_order_relaxed 为 memory_order_release; 6. bits_button_set_buffer_ops 声明添加 #ifdef BITS_BTN_USE_USER_BUFFER 条件编译; 7. 补充7个测试用例:参数校验4个(按钮数超限、param NULL)、缓冲区覆写3个(数据正确性、多轮覆写、计数准确性); 8. 更新文档:bits_button_init 添加错误码说明、get_bits_btn_buffer_capacity 说明容量语义; --- bits_button.c | 54 +++++-- bits_button.h | 25 +++- test/cases/basic/test_buffer_operations.c | 142 ++++++++++++++++++ test/cases/edge/test_error_handling.c | 173 +++++++++++++++++----- test/test_main_new.c | 14 ++ 5 files changed, 352 insertions(+), 56 deletions(-) diff --git a/bits_button.c b/bits_button.c index dba8a2d..5e335f1 100644 --- a/bits_button.c +++ b/bits_button.c @@ -1,5 +1,5 @@ #include "bits_button.h" -#include "string.h" +#include static bits_button_t bits_btn_entity; static bits_btn_debug_printf_func debug_printf = NULL; @@ -96,7 +96,9 @@ static size_t get_bits_btn_buffer_used_count_c11(void) static size_t get_bits_btn_buffer_capacity_c11(void) { - return BITS_BTN_BUFFER_SIZE; + // A circular buffer needs to reserve 1 empty slot to distinguish between full and empty states, + // so the actual available capacity is SIZE - 1. + return BITS_BTN_BUFFER_SIZE - 1; } /** @@ -107,8 +109,8 @@ static void bits_btn_clear_buffer_c11(void) { bits_btn_ring_buffer_t *buf = &ring_buffer; - atomic_store_explicit(&buf->read_idx, 0, memory_order_relaxed); - atomic_store_explicit(&buf->write_idx, 0, memory_order_relaxed); + atomic_store_explicit(&buf->write_idx, 0, memory_order_release); + atomic_store_explicit(&buf->read_idx, 0, memory_order_release); } static size_t get_bits_btn_buffer_overwrite_count_c11(void) @@ -161,11 +163,8 @@ static uint8_t bits_btn_write_buffer_overwrite_c11(bits_btn_result_t *result) // Get the current write position size_t current_write = atomic_load_explicit(&buf->write_idx, memory_order_relaxed); size_t next_write = (current_write + 1) % BITS_BTN_BUFFER_SIZE; + size_t current_read = atomic_load_explicit(&buf->read_idx, memory_order_acquire); - // Get the current read position (ensure the latest value is seen) - size_t current_read = atomic_load_explicit(&buf->read_idx, memory_order_consume); - - buf->buffer[current_write] = *result; // Advance the read pointer when the buffer is full if (next_write == current_read) { @@ -173,8 +172,12 @@ static uint8_t bits_btn_write_buffer_overwrite_c11(bits_btn_result_t *result) size_t new_read = (current_read + 1) % BITS_BTN_BUFFER_SIZE; atomic_store_explicit(&buf->read_idx, new_read, memory_order_release); + current_read = new_read; } + // Write data (space is guaranteed to be safe at this point) + buf->buffer[current_write] = *result; + // Update the write pointer (ensure data is visible before index update) atomic_store_explicit(&buf->write_idx, next_write, memory_order_release); return true; @@ -407,14 +410,23 @@ int32_t bits_button_init(button_obj_t* btns bits_button_t *button = &bits_btn_entity; debug_printf = bis_btn_debug_printf; - if (btns == NULL || read_button_level_func == NULL || - (btns_combo_cnt > 0 && btns_combo == NULL)) + if ((btns == NULL) + || (btns_cnt == 0) + || (read_button_level_func == NULL) + || (btns_combo_cnt > 0 && btns_combo == NULL)) { if(debug_printf) debug_printf("Invalid init parameters !\n"); return -2; } + if (btns_cnt > BITS_BTN_MAX_BUTTONS) + { + if (debug_printf) + debug_printf("Error: Too many buttons (%d > max %d)\n", btns_cnt, (int)BITS_BTN_MAX_BUTTONS); + return -5; + } + memset(button, 0, sizeof(bits_button_t)); button->btns = btns; @@ -434,6 +446,28 @@ int32_t bits_button_init(button_obj_t* btns return -3; } + // Check single button param pointers + for (uint16_t i = 0; i < btns_cnt; i++) + { + if (btns[i].param == NULL) + { + if (debug_printf) + debug_printf("Error: Button[%d] param is NULL\n", i); + return -6; + } + } + + // Check combo button param pointers + for (uint16_t i = 0; i < btns_combo_cnt; i++) + { + if (btns_combo[i].btn.param == NULL) + { + if (debug_printf) + debug_printf("Error: Combo button[%d] param is NULL\n", i); + return -7; + } + } + for(uint16_t i = 0; i < btns_combo_cnt; i++) { button_obj_combo_t *combo = &button->btns_combo[i]; diff --git a/bits_button.h b/bits_button.h index 43baa9d..34baa5a 100644 --- a/bits_button.h +++ b/bits_button.h @@ -5,8 +5,8 @@ extern "C" { #endif -#include "stdint.h" -#include "stdio.h" +#include +#include #ifndef BITS_BTN_MAX_COMBO_BUTTONS #define BITS_BTN_MAX_COMBO_BUTTONS 8 // 默认最大支持8个组合按钮 @@ -16,6 +16,9 @@ typedef uint32_t key_value_type_t; typedef uint32_t state_bits_type_t; typedef state_bits_type_t button_mask_type_t; +// Maximum number of buttons based on mask type size +#define BITS_BTN_MAX_BUTTONS (sizeof(button_mask_type_t) * 8) + typedef enum { BTN_STATE_IDLE , @@ -169,12 +172,16 @@ typedef struct * This function is called when a button event (press, release, etc.) is detected. * @param bis_btn_debug_printf: Function pointer for debug logging. Pass NULL if debug output is not needed. * - * @retval Status code indicating the result of the initialization: +* @retval Status code indicating the result of the initialization: * - 0: Success. All parameters are valid, and the button system is initialized. * - -1: Invalid key ID in combination button configuration. A key ID specified in a * combination button configuration does not exist in the single button array. * - -2: Invalid input parameters. Returned if either `btns` or `read_button_level_func` is NULL. - * - -3: Too many combo buttons. The number of combo buttons exceeds the maximum allowed. + * - -3: Too many combo buttons. The number of combo buttons exceeds BITS_BTN_MAX_COMBO_BUTTONS. + * - -4: User buffer mode requires setting buffer ops before init. + * - -5: Too many buttons. The number of buttons exceeds BITS_BTN_MAX_BUTTONS. + * - -6: Button param is NULL. A single button has NULL param pointer. + * - -7: Combo button param is NULL. A combo button has NULL param pointer. */ int32_t bits_button_init(button_obj_t* btns , \ uint16_t btns_cnt , \ @@ -237,6 +244,7 @@ uint8_t bits_btn_is_buffer_full(void); */ uint8_t bits_btn_is_buffer_empty(void); +#ifdef BITS_BTN_USE_USER_BUFFER /** * @brief Set custom buffer operations for external buffer management. * This function allows users to register their own buffer implementation @@ -245,14 +253,19 @@ uint8_t bits_btn_is_buffer_empty(void); * Pass NULL to restore default buffer operations. * @retval None * @note This function should be called before bits_button_init(). + * Only available when BITS_BTN_USE_USER_BUFFER is defined. */ void bits_button_set_buffer_ops(const bits_btn_buffer_ops_t *user_buffer_ops); +#endif /** - * @brief Get the total capacity of the button result buffer. + * @brief Get the usable capacity of the button result buffer. * This function returns the maximum number of button events that * can be stored in the buffer. - * @retval The total buffer capacity in number of elements. Returns 0 if buffer is disabled. + * @note The underlying array size is capacity + 1 due to ring buffer + * implementation requirements (one slot reserved to distinguish + * full/empty states). + * @retval The usable buffer capacity in number of elements. Returns 0 if buffer is disabled. */ size_t get_bits_btn_buffer_capacity(void); diff --git a/test/cases/basic/test_buffer_operations.c b/test/cases/basic/test_buffer_operations.c index e6c4094..1439170 100644 --- a/test/cases/basic/test_buffer_operations.c +++ b/test/cases/basic/test_buffer_operations.c @@ -203,4 +203,146 @@ void test_buffer_edge_cases(void) { TEST_ASSERT_TRUE(bits_btn_is_buffer_empty()); printf("缓冲区边界情况测试通过\n"); +} + +// ==================== 覆写功能测试 ==================== + +void test_buffer_overwrite_data_correctness(void) { + printf("\n=== 测试覆写后数据正确性 ===\n"); + + // 使用多个按键产生可区分的事件 + static const bits_btn_obj_param_t param = TEST_DEFAULT_PARAM(); + button_obj_t buttons[10]; + for (int i = 0; i < 10; i++) { + buttons[i] = (button_obj_t)BITS_BUTTON_INIT(i + 1, 1, ¶m); + } + + bits_button_init(buttons, 10, NULL, 0, + test_framework_mock_read_button, + test_framework_event_callback, + test_framework_log_printf); + + size_t capacity = get_bits_btn_buffer_capacity(); + + // 填满缓冲区:使用 key_id 1 产生 capacity 个事件 + for (size_t i = 0; i < capacity; i++) { + mock_button_click(1, STANDARD_CLICK_TIME_MS); + time_simulate_time_window_end(); + bits_button_ticks(); + } + + // 再写入 3 个新事件,使用 key_id 2 区分 + for (int i = 0; i < 3; i++) { + mock_button_click(2, STANDARD_CLICK_TIME_MS); + time_simulate_time_window_end(); + bits_button_ticks(); + } + + // 读取所有事件,验证最旧的被覆盖 + bits_btn_result_t result; + size_t key1_count = 0; + size_t key2_count = 0; + + while (bits_button_get_key_result(&result)) { + if (result.key_id == 1) key1_count++; + else if (result.key_id == 2) key2_count++; + } + + // 验证:key_id=2 的事件应该有 3 个(最新写入的) + TEST_ASSERT_EQUAL_MESSAGE(3, key2_count, "应有3个新事件(key_id=2)"); + + // 验证:key_id=1 的事件应该是 capacity - 3 个(被覆盖了3个) + TEST_ASSERT_EQUAL_MESSAGE(capacity - 3, key1_count, + "旧事件(key_id=1)应被覆盖3个"); + + printf("覆写后数据正确性测试通过: 旧事件被正确覆盖\n"); +} + +void test_buffer_overwrite_multiple_cycles(void) { + printf("\n=== 测试连续多轮覆写 ===\n"); + + static const bits_btn_obj_param_t param = TEST_DEFAULT_PARAM(); + button_obj_t button = BITS_BUTTON_INIT(1, 1, ¶m); + bits_button_init(&button, 1, NULL, 0, + test_framework_mock_read_button, + test_framework_event_callback, + test_framework_log_printf); + + size_t capacity = get_bits_btn_buffer_capacity(); + size_t total_writes = capacity * 2 + 5; // 写入超过2轮 + + size_t initial_overwrite = get_bits_btn_buffer_overwrite_count(); + + // 连续写入大量事件 + for (size_t i = 0; i < total_writes; i++) { + mock_button_click(1, STANDARD_CLICK_TIME_MS); + time_simulate_time_window_end(); + bits_button_ticks(); + } + + size_t final_overwrite = get_bits_btn_buffer_overwrite_count(); + size_t overwrite_delta = final_overwrite - initial_overwrite; + + // 验证覆写次数 + size_t expected_overwrites = total_writes - capacity; + TEST_ASSERT_EQUAL_MESSAGE(expected_overwrites, overwrite_delta, + "覆写次数应等于 (总写入数 - 缓冲区容量)"); + + // 验证只能读到 capacity 个事件 + bits_btn_result_t result; + size_t read_count = 0; + while (bits_button_get_key_result(&result)) { + read_count++; + if (read_count > capacity + 10) break; // 防止无限循环 + } + + TEST_ASSERT_EQUAL_MESSAGE(capacity, read_count, + "只能读到缓冲区容量个事件"); + + printf("连续多轮覆写测试通过: 覆写 %zu 次, 读取 %zu 个事件\n", + overwrite_delta, read_count); +} + +void test_buffer_overwrite_count_accuracy(void) { + printf("\n=== 测试覆写计数准确性 ===\n"); + + static const bits_btn_obj_param_t param = TEST_DEFAULT_PARAM(); + button_obj_t button = BITS_BUTTON_INIT(1, 1, ¶m); + bits_button_init(&button, 1, NULL, 0, + test_framework_mock_read_button, + test_framework_event_callback, + test_framework_log_printf); + + size_t capacity = get_bits_btn_buffer_capacity(); + + // 记录初始覆写计数 + size_t count_before_fill = get_bits_btn_buffer_overwrite_count(); + + // 填满缓冲区(不应触发覆写) + for (size_t i = 0; i < capacity; i++) { + mock_button_click(1, STANDARD_CLICK_TIME_MS); + time_simulate_time_window_end(); + bits_button_ticks(); + } + + size_t count_after_fill = get_bits_btn_buffer_overwrite_count(); + TEST_ASSERT_EQUAL_MESSAGE(count_before_fill, count_after_fill, + "填满缓冲区不应触发覆写"); + + // 再写入 5 个事件(应触发 5 次覆写) + const size_t extra_writes = 5; + for (size_t i = 0; i < extra_writes; i++) { + mock_button_click(1, STANDARD_CLICK_TIME_MS); + time_simulate_time_window_end(); + bits_button_ticks(); + } + + size_t count_after_extra = get_bits_btn_buffer_overwrite_count(); + size_t actual_overwrites = count_after_extra - count_after_fill; + + TEST_ASSERT_EQUAL_MESSAGE(extra_writes, actual_overwrites, + "覆写计数应精确等于额外写入次数"); + + printf("覆写计数准确性测试通过: 额外写入 %zu 次, 覆写计数增加 %zu\n", + extra_writes, actual_overwrites); } \ No newline at end of file diff --git a/test/cases/edge/test_error_handling.c b/test/cases/edge/test_error_handling.c index 642d64b..8dd6c8f 100644 --- a/test/cases/edge/test_error_handling.c +++ b/test/cases/edge/test_error_handling.c @@ -23,72 +23,72 @@ void error_handling_tearDown(void) { void test_null_pointer_handling(void) { printf("\n=== 测试空指针处理 ===\n"); - + // 测试空按键数组 int32_t result = bits_button_init(NULL, 1, NULL, 0, - test_framework_mock_read_button, - test_framework_event_callback, + test_framework_mock_read_button, + test_framework_event_callback, test_framework_log_printf); TEST_ASSERT_EQUAL(-2, result); // 应该返回无效参数错误 - + // 测试空读取函数 static const bits_btn_obj_param_t param = TEST_DEFAULT_PARAM(); button_obj_t button = BITS_BUTTON_INIT(1, 1, ¶m); - + result = bits_button_init(&button, 1, NULL, 0, NULL, // 空读取函数 - test_framework_event_callback, + test_framework_event_callback, test_framework_log_printf); TEST_ASSERT_EQUAL(-2, result); // 应该返回无效参数错误 - + // 测试空事件回调(这个应该是允许的) result = bits_button_init(&button, 1, NULL, 0, - test_framework_mock_read_button, + test_framework_mock_read_button, NULL, // 空事件回调 test_framework_log_printf); TEST_ASSERT_EQUAL(0, result); // 应该成功 - + // 测试空调试函数(这个应该是允许的) result = bits_button_init(&button, 1, NULL, 0, - test_framework_mock_read_button, - test_framework_event_callback, + test_framework_mock_read_button, + test_framework_event_callback, NULL); // 空调试函数 TEST_ASSERT_EQUAL(0, result); // 应该成功 - + printf("空指针处理测试通过: 正确处理各种空指针情况\n"); } void test_invalid_parameters(void) { printf("\n=== 测试无效参数 ===\n"); - + static const bits_btn_obj_param_t param = TEST_DEFAULT_PARAM(); button_obj_t button = BITS_BUTTON_INIT(1, 1, ¶m); - + // 测试零按键数量 int32_t result = bits_button_init(&button, 0, NULL, 0, - test_framework_mock_read_button, - test_framework_event_callback, + test_framework_mock_read_button, + test_framework_event_callback, test_framework_log_printf); // 根据实现,这可能是有效的或无效的 printf("零按键数量初始化结果: %d\n", result); - + // 测试无效的组合按键配置 static uint16_t invalid_combo_keys[] = {99, 100}; // 不存在的按键ID - button_obj_combo_t invalid_combo = + button_obj_combo_t invalid_combo = BITS_BUTTON_COMBO_INIT(200, 1, ¶m, invalid_combo_keys, 2, 1); - + result = bits_button_init(&button, 1, &invalid_combo, 1, - test_framework_mock_read_button, - test_framework_event_callback, + test_framework_mock_read_button, + test_framework_event_callback, test_framework_log_printf); TEST_ASSERT_EQUAL(-1, result); // 应该返回无效按键ID错误 - + printf("无效参数测试通过: 正确检测和处理无效参数\n"); } void test_boundary_values(void) { printf("\n=== 测试边界值 ===\n"); - + // 测试极端的参数值 static const bits_btn_obj_param_t extreme_param = { .short_press_time_ms = 1, // 极短时间 @@ -96,43 +96,43 @@ void test_boundary_values(void) { .long_press_period_triger_ms = 1, // 极短周期 .time_window_time_ms = 65535 // 极长窗口 }; - + button_obj_t button = BITS_BUTTON_INIT(1, 1, &extreme_param); int32_t result = bits_button_init(&button, 1, NULL, 0, - test_framework_mock_read_button, - test_framework_event_callback, + test_framework_mock_read_button, + test_framework_event_callback, test_framework_log_printf); TEST_ASSERT_EQUAL(0, result); // 应该能成功初始化 - + // 测试极端按键ID button_obj_t extreme_button = BITS_BUTTON_INIT(65535, 1, &extreme_param); result = bits_button_init(&extreme_button, 1, NULL, 0, - test_framework_mock_read_button, - test_framework_event_callback, + test_framework_mock_read_button, + test_framework_event_callback, test_framework_log_printf); TEST_ASSERT_EQUAL(0, result); // 应该能成功初始化 - + // 测试基本功能是否正常(使用合理的按键ID避免溢出) mock_button_click(255, 100); // 使用uint8_t范围内的值 time_simulate_time_window_end(); - + // 由于时间窗口极长,可能需要特殊处理 printf("边界值测试通过: 极端参数值能正确处理\n"); } void test_resource_exhaustion(void) { printf("\n=== 测试资源耗尽 ===\n"); - + // 测试最大数量的组合按键 static const bits_btn_obj_param_t param = TEST_DEFAULT_PARAM(); button_obj_t buttons[BITS_BTN_MAX_COMBO_BUTTONS + 2]; button_obj_combo_t combo_buttons[BITS_BTN_MAX_COMBO_BUTTONS + 1]; - + // 创建按键 for (int i = 0; i < BITS_BTN_MAX_COMBO_BUTTONS + 2; i++) { buttons[i] = (button_obj_t)BITS_BUTTON_INIT(i + 1, 1, ¶m); } - + // 创建组合按键(超过最大数量) static uint16_t combo_keys[BITS_BTN_MAX_COMBO_BUTTONS + 1][2]; for (int i = 0; i < BITS_BTN_MAX_COMBO_BUTTONS + 1; i++) { @@ -141,18 +141,111 @@ void test_resource_exhaustion(void) { combo_buttons[i] = (button_obj_combo_t)BITS_BUTTON_COMBO_INIT( 100 + i, 1, ¶m, combo_keys[i], 2, 1); } - + // 尝试初始化超过最大数量的组合按键 - int32_t result = bits_button_init(buttons, BITS_BTN_MAX_COMBO_BUTTONS + 2, + int32_t result = bits_button_init(buttons, BITS_BTN_MAX_COMBO_BUTTONS + 2, combo_buttons, BITS_BTN_MAX_COMBO_BUTTONS + 1, - test_framework_mock_read_button, - test_framework_event_callback, + test_framework_mock_read_button, + test_framework_event_callback, test_framework_log_printf); - + // 根据实现,可能成功或失败 printf("超过最大组合按键数量的初始化结果: %d\n", result); - + // 测试缓冲区资源耗尽(在buffer_operations.c中已测试) printf("资源耗尽测试通过: 正确处理资源限制\n"); } +// ==================== 参数校验测试 ==================== + +void test_max_buttons_boundary(void) { + printf("\n=== 测试最大按钮数边界(应成功) ===\n"); + + static const bits_btn_obj_param_t param = TEST_DEFAULT_PARAM(); + + // 创建恰好 BITS_BTN_MAX_BUTTONS 个按钮 + button_obj_t buttons[BITS_BTN_MAX_BUTTONS]; + for (size_t i = 0; i < BITS_BTN_MAX_BUTTONS; i++) { + buttons[i] = (button_obj_t)BITS_BUTTON_INIT(i + 1, 1, ¶m); + } + + int32_t result = bits_button_init(buttons, BITS_BTN_MAX_BUTTONS, NULL, 0, + test_framework_mock_read_button, + test_framework_event_callback, + test_framework_log_printf); + + TEST_ASSERT_EQUAL(0, result); // 应成功 + + printf("最大按钮数边界测试通过: %d 个按钮初始化成功\n", + (int)BITS_BTN_MAX_BUTTONS); +} + +void test_too_many_buttons(void) { + printf("\n=== 测试超过最大按钮数(应失败) ===\n"); + + static const bits_btn_obj_param_t param = TEST_DEFAULT_PARAM(); + + // 创建 BITS_BTN_MAX_BUTTONS + 1 个按钮 + button_obj_t buttons[BITS_BTN_MAX_BUTTONS + 1]; + for (size_t i = 0; i < BITS_BTN_MAX_BUTTONS + 1; i++) { + buttons[i] = (button_obj_t)BITS_BUTTON_INIT(i + 1, 1, ¶m); + } + + int32_t result = bits_button_init(buttons, BITS_BTN_MAX_BUTTONS + 1, NULL, 0, + test_framework_mock_read_button, + test_framework_event_callback, + test_framework_log_printf); + + TEST_ASSERT_EQUAL(-5, result); // 应返回按钮数量超限错误 + + printf("超过最大按钮数测试通过: 正确返回错误码 -5\n"); +} + +void test_button_param_null(void) { + printf("\n=== 测试单按钮 param 为 NULL ===\n"); + + static const bits_btn_obj_param_t param = TEST_DEFAULT_PARAM(); + + // 创建按钮数组,其中一个的 param 为 NULL + button_obj_t buttons[] = { + BITS_BUTTON_INIT(1, 1, ¶m), + BITS_BUTTON_INIT(2, 1, NULL), // param 为 NULL + BITS_BUTTON_INIT(3, 1, ¶m) + }; + + int32_t result = bits_button_init(buttons, 3, NULL, 0, + test_framework_mock_read_button, + test_framework_event_callback, + test_framework_log_printf); + + TEST_ASSERT_EQUAL(-6, result); // 应返回按钮 param 为空错误 + + printf("单按钮 param 为 NULL 测试通过: 正确返回错误码 -6\n"); +} + +void test_combo_button_param_null(void) { + printf("\n=== 测试组合按钮 param 为 NULL ===\n"); + + static const bits_btn_obj_param_t param = TEST_DEFAULT_PARAM(); + + // 创建单按钮 + button_obj_t buttons[] = { + BITS_BUTTON_INIT(1, 1, ¶m), + BITS_BUTTON_INIT(2, 1, ¶m) + }; + + // 创建 param 为 NULL 的组合按钮 + static uint16_t combo_keys[] = {1, 2}; + button_obj_combo_t combo = + BITS_BUTTON_COMBO_INIT(100, 1, NULL, combo_keys, 2, 1); // param 为 NULL + + int32_t result = bits_button_init(buttons, 2, &combo, 1, + test_framework_mock_read_button, + test_framework_event_callback, + test_framework_log_printf); + + TEST_ASSERT_EQUAL(-7, result); // 应返回组合按钮 param 为空错误 + + printf("组合按钮 param 为 NULL 测试通过: 正确返回错误码 -7\n"); +} + diff --git a/test/test_main_new.c b/test/test_main_new.c index 5a1078f..b47d820 100644 --- a/test/test_main_new.c +++ b/test/test_main_new.c @@ -37,6 +37,9 @@ extern void test_memory_usage(void); extern void test_buffer_overflow_protection(void); extern void test_buffer_state_tracking(void); extern void test_buffer_edge_cases(void); +extern void test_buffer_overwrite_data_correctness(void); +extern void test_buffer_overwrite_multiple_cycles(void); +extern void test_buffer_overwrite_count_accuracy(void); // 高级组合按键测试 extern void test_advanced_three_key_combo(void); @@ -54,6 +57,10 @@ extern void test_null_pointer_handling(void); extern void test_invalid_parameters(void); extern void test_boundary_values(void); extern void test_resource_exhaustion(void); +extern void test_max_buttons_boundary(void); +extern void test_too_many_buttons(void); +extern void test_button_param_null(void); +extern void test_combo_button_param_null(void); // 初始化测试 extern void test_successful_initialization(void); @@ -157,6 +164,9 @@ int main(void) { RUN_TEST(test_buffer_overflow_protection); RUN_TEST(test_buffer_state_tracking); RUN_TEST(test_buffer_edge_cases); + RUN_TEST(test_buffer_overwrite_data_correctness); + RUN_TEST(test_buffer_overwrite_multiple_cycles); + RUN_TEST(test_buffer_overwrite_count_accuracy); printf("\n【高级组合按键测试】\n"); RUN_TEST(test_advanced_three_key_combo); @@ -174,6 +184,10 @@ int main(void) { RUN_TEST(test_invalid_parameters); RUN_TEST(test_boundary_values); RUN_TEST(test_resource_exhaustion); + RUN_TEST(test_max_buttons_boundary); + RUN_TEST(test_too_many_buttons); + RUN_TEST(test_button_param_null); + RUN_TEST(test_combo_button_param_null); printf("\n【初始化配置测试】\n"); RUN_TEST(test_successful_initialization);