mirror of
https://github.com/LHY0125/PathEditor.git
synced 2026-05-10 02:09:46 +08:00
cf19a37a97
- 新增 CMake 测试框架配置,支持 safe_string、string_ext 和 path_manager 模块的单元测试 - 实现 Windows API Mock 机制,便于测试编码转换函数 - 添加 error_code 模块的字符串表示函数,支持英文错误日志 - 在 UI 回调函数中集成国际化翻译,覆盖新建、编辑、导入导出等操作提示 - 扩展 string_list 功能,新增重复路径检查函数 - 更新翻译文件,同步所有用户界面的中英文文本
210 lines
5.3 KiB
C
210 lines
5.3 KiB
C
/*
|
||
* safe_string.c 单元测试
|
||
* 测试安全字符串操作函数
|
||
*/
|
||
#include <stdarg.h>
|
||
#include <stddef.h>
|
||
#include <setjmp.h>
|
||
#include <cmocka.h>
|
||
#include <string.h>
|
||
#include <stdlib.h>
|
||
#include "utils/safe_string.h"
|
||
|
||
/* ==================== safe_strcpy 测试 ==================== */
|
||
|
||
static void test_safe_strcpy_normal(void **state)
|
||
{
|
||
(void)state;
|
||
char dst[32];
|
||
const char *src = "Hello, World!";
|
||
char *result = safe_strcpy(dst, sizeof(dst), src);
|
||
|
||
assert_non_null(result);
|
||
assert_string_equal(dst, src);
|
||
}
|
||
|
||
static void test_safe_strcpy_truncation(void **state)
|
||
{
|
||
(void)state;
|
||
char dst[8];
|
||
const char *src = "This is a long string";
|
||
char *result = safe_strcpy(dst, sizeof(dst), src);
|
||
|
||
assert_non_null(result);
|
||
assert_int_equal(strlen(dst), 7); /* 截断到 7 字符 */
|
||
assert_memory_equal(dst, src, 7); /* 前 7 字符相同 */
|
||
assert_int_equal(dst[7], '\0');
|
||
}
|
||
|
||
static void test_safe_strcpy_null_dst(void **state)
|
||
{
|
||
(void)state;
|
||
const char *src = "test";
|
||
char *result = safe_strcpy(NULL, 10, src);
|
||
assert_null(result);
|
||
}
|
||
|
||
static void test_safe_strcpy_null_src(void **state)
|
||
{
|
||
(void)state;
|
||
char dst[32];
|
||
char *result = safe_strcpy(dst, sizeof(dst), NULL);
|
||
assert_null(result);
|
||
}
|
||
|
||
static void test_safe_strcpy_zero_size(void **state)
|
||
{
|
||
(void)state;
|
||
char dst[32];
|
||
char *result = safe_strcpy(dst, 0, "test");
|
||
assert_null(result);
|
||
}
|
||
|
||
static void test_safe_strcpy_exact_fit(void **state)
|
||
{
|
||
(void)state;
|
||
char dst[6];
|
||
const char *src = "12345"; /* 5字符 + 1终止符 = 6 */
|
||
char *result = safe_strcpy(dst, sizeof(dst), src);
|
||
|
||
assert_non_null(result);
|
||
assert_string_equal(dst, "12345");
|
||
}
|
||
|
||
/* ==================== safe_strcat 测试 ==================== */
|
||
|
||
static void test_safe_strcat_normal(void **state)
|
||
{
|
||
(void)state;
|
||
char dst[32] = "Hello";
|
||
const char *src = ", World!";
|
||
char *result = safe_strcat(dst, sizeof(dst), src);
|
||
|
||
assert_non_null(result);
|
||
assert_string_equal(dst, "Hello, World!");
|
||
}
|
||
|
||
static void test_safe_strcat_truncation(void **state)
|
||
{
|
||
(void)state;
|
||
char dst[12] = "Hello";
|
||
const char *src = ", World!"; /* 总长 12,但最后一个位置要放 \0 */
|
||
char *result = safe_strcat(dst, sizeof(dst), src);
|
||
|
||
assert_non_null(result);
|
||
/* dst 有 11 可用位置 (12-1),"Hello" 占 5,还剩 6 */
|
||
/* ", World!" 有 9 字符,只能放 6 个字符 + \0 */
|
||
assert_true(strlen(dst) <= 11);
|
||
}
|
||
|
||
static void test_safe_strcat_null_dst(void **state)
|
||
{
|
||
(void)state;
|
||
char dst[32] = "test";
|
||
char *result = safe_strcat(NULL, sizeof(dst), "src");
|
||
assert_null(result);
|
||
}
|
||
|
||
static void test_safe_strcat_null_src(void **state)
|
||
{
|
||
(void)state;
|
||
char dst[32] = "test";
|
||
char *result = safe_strcat(dst, sizeof(dst), NULL);
|
||
/* src 为 NULL 时函数返回 NULL */
|
||
assert_null(result);
|
||
}
|
||
|
||
static void test_safe_strcat_empty_dst(void **state)
|
||
{
|
||
(void)state;
|
||
char dst[32] = "";
|
||
const char *src = "Hello";
|
||
char *result = safe_strcat(dst, sizeof(dst), src);
|
||
|
||
assert_non_null(result);
|
||
assert_string_equal(dst, "Hello");
|
||
}
|
||
|
||
/* ==================== safe_strdup 测试 ==================== */
|
||
|
||
static void test_safe_strdup_normal(void **state)
|
||
{
|
||
(void)state;
|
||
const char *src = "Hello, World!";
|
||
char *result = safe_strdup(src);
|
||
|
||
assert_non_null(result);
|
||
assert_string_equal(result, src);
|
||
assert_ptr_not_equal(result, src); /* 必须是新分配的内存 */
|
||
|
||
free(result);
|
||
}
|
||
|
||
static void test_safe_strdup_null(void **state)
|
||
{
|
||
(void)state;
|
||
char *result = safe_strdup(NULL);
|
||
assert_null(result);
|
||
}
|
||
|
||
static void test_safe_strdup_empty_string(void **state)
|
||
{
|
||
(void)state;
|
||
const char *src = "";
|
||
char *result = safe_strdup(src);
|
||
|
||
assert_non_null(result);
|
||
assert_string_equal(result, "");
|
||
|
||
free(result);
|
||
}
|
||
|
||
static void test_safe_strdup_long_string(void **state)
|
||
{
|
||
(void)state;
|
||
/* 构造一个 510 字符的字符串 */
|
||
char src[511];
|
||
for (int i = 0; i < 510; i++) {
|
||
src[i] = 'A';
|
||
}
|
||
src[510] = '\0';
|
||
|
||
char *result = safe_strdup(src);
|
||
|
||
assert_non_null(result);
|
||
assert_int_equal(strlen(result), 510);
|
||
assert_memory_equal(result, src, 510);
|
||
|
||
free(result);
|
||
}
|
||
|
||
/* ==================== 主函数 ==================== */
|
||
|
||
int main(void)
|
||
{
|
||
const struct CMUnitTest tests[] = {
|
||
/* safe_strcpy 测试 */
|
||
cmocka_unit_test(test_safe_strcpy_normal),
|
||
cmocka_unit_test(test_safe_strcpy_truncation),
|
||
cmocka_unit_test(test_safe_strcpy_null_dst),
|
||
cmocka_unit_test(test_safe_strcpy_null_src),
|
||
cmocka_unit_test(test_safe_strcpy_zero_size),
|
||
cmocka_unit_test(test_safe_strcpy_exact_fit),
|
||
|
||
/* safe_strcat 测试 */
|
||
cmocka_unit_test(test_safe_strcat_normal),
|
||
cmocka_unit_test(test_safe_strcat_truncation),
|
||
cmocka_unit_test(test_safe_strcat_null_dst),
|
||
cmocka_unit_test(test_safe_strcat_null_src),
|
||
cmocka_unit_test(test_safe_strcat_empty_dst),
|
||
|
||
/* safe_strdup 测试 */
|
||
cmocka_unit_test(test_safe_strdup_normal),
|
||
cmocka_unit_test(test_safe_strdup_null),
|
||
cmocka_unit_test(test_safe_strdup_empty_string),
|
||
cmocka_unit_test(test_safe_strdup_long_string),
|
||
};
|
||
|
||
return cmocka_run_group_tests(tests, NULL, NULL);
|
||
}
|