Files

109 lines
4.3 KiB
C
Raw Permalink Normal View History

2026-08-31 22:49:42 +08:00
#include "c_TrieSet.h"
#include "c_Test.h"
#include <stdlib.h>
#include <stdio.h>
TEST_CASE(test_c_TrieSet_UniqueUnsignedFlow) {
c_TrieSet_t set;
// 初始化变长集合,检验默认 Fallback 降级分配器播种
c_err_t err = c_TrieSet_Init(&set, NULL);
ASSERT_INT_EQ(C_ERR_OK, err);
ASSERT_INT_EQ(0, (int)set.size);
// 1. Add 基础添加与 Contains 判定
ASSERT_INT_EQ(C_ERR_OK, c_TrieSet_Add(&set, "sea"));
ASSERT_INT_EQ(C_ERR_OK, c_TrieSet_Add(&set, "seashells"));
ASSERT_INT_EQ(C_ERR_OK, c_TrieSet_Add(&set, "she"));
ASSERT_INT_EQ(3, (int)set.size);
ASSERT_TRUE(c_TrieSet_Contains(&set, "seashells"));
ASSERT_TRUE(!c_TrieSet_Contains(&set, "seash")); // 物理路径虽通但非有效键完结,必须卡死返回 false
// 2. 🌟【绝杀点 1:去重防御】:尝试向集合再次强注已存在的同名元素 "sea"
// 控制流必须前置拦截,交回标准的 C_ERR_EXIST 异常状态,全局集合计数死守为 3 守恒不变!
ASSERT_INT_EQ(C_ERR_EXIST, c_TrieSet_Add(&set, "sea"));
ASSERT_INT_EQ(3, (int)set.size);
// 3. 🌟【绝杀点 2:自底向上惰性剪枝】:移出带有嵌套延伸子代分支的枢纽根节点 "sea"
ASSERT_INT_EQ(C_ERR_OK, c_TrieSet_Remove(&set, "sea"));
ASSERT_INT_EQ(2, (int)set.size);
ASSERT_TRUE(!c_TrieSet_Contains(&set, "sea"));
// 级联拓扑检查:因为 "sea" 的后方还衍生着独立有效元素 "seashells"
// 惰性剪枝控制流应当自适应切断 sea 处的标记,但必须完美完好保留长后缀的子孙分支!
ASSERT_TRUE(c_TrieSet_Contains(&set, "seashells"));
// 4. 移出完全孤立的独苗元素 "she"
ASSERT_INT_EQ(C_ERR_OK, c_TrieSet_Remove(&set, "she"));
ASSERT_INT_EQ(1, (int)set.size);
// 彻底解构注销
c_TrieSet_Destroy(&set);
}
TEST_CASE(test_c_TrieSet_Toxicity_Defenses) {
c_TrieSet_t local_set;
c_TrieSet_Init(&local_set, &c_DefaultAllocator);
// 5. 验证极值边界及非法参数的强过滤拦截
ASSERT_INT_EQ(C_ERR_PARAM, c_TrieSet_Init(NULL, NULL));
ASSERT_INT_EQ(C_ERR_PARAM, c_TrieSet_Add(NULL, "toxic"));
ASSERT_INT_EQ(C_ERR_EMPTY, c_TrieSet_Remove(&local_set, "toxic")); // 空仓删除安全返回 C_ERR_EMPTY
c_TrieSet_Destroy(&local_set);
}
TEST_CASE(test_c_TrieSet_StringBuffer_Pipeline) {
c_TrieSet_t set;
c_TrieSet_Init(&set, &c_DefaultAllocator);
// 密布注入去重键
c_TrieSet_Add(&set, "api/v1/user");
c_TrieSet_Add(&set, "api/v1/user/profile");
c_TrieSet_Add(&set, "api/v1/user/profile/avatar");
c_TrieSet_Add(&set, "api/v2/auth");
c_TrieSet_Add(&set, "app/v1/user");
c_StringList_t result_list;
c_StringList_Init(&result_list, 4, &c_DefaultAllocator);
// 1. KeysWithPrefix 前缀联想测试
c_err_t err = c_TrieSet_KeysWithPrefix(&set, "api/v1/user", &result_list);
ASSERT_INT_EQ(C_ERR_OK, err);
ASSERT_INT_EQ(3, (int)c_StringList_Size(&result_list));
ASSERT_TRUE(strcmp("api/v1/user", c_StringList_Get(&result_list, 0)) == 0);
ASSERT_TRUE(strcmp("api/v1/user/profile/avatar", c_StringList_Get(&result_list, 2)) == 0);
// 2. KeysThatMatch 通配符正则走查
c_StringList_Clear(&result_list);
err = c_TrieSet_KeysThatMatch(&set, "ap./v1/user", &result_list);
ASSERT_INT_EQ(C_ERR_OK, err);
ASSERT_INT_EQ(2, (int)c_StringList_Size(&result_list));
ASSERT_TRUE(strcmp("api/v1/user", c_StringList_Get(&result_list, 0)) == 0);
// 3. LongestPrefixOf 掩码最长前缀分级寻址
c_StringList_Clear(&result_list);
const char* network_url = "api/v1/user/profile/settings/security_token";
err = c_TrieSet_LongestPrefixOf(&set, network_url, &result_list);
ASSERT_INT_EQ(C_ERR_OK, err);
ASSERT_INT_EQ(1, (int)c_StringList_Size(&result_list));
ASSERT_TRUE(strcmp("api/v1/user/profile", c_StringList_Get(&result_list, 0)) == 0);
c_StringList_Destroy(&result_list);
c_TrieSet_Destroy(&set);
}
// ==========================================
// 5. 主集成入口
// ==========================================
int main(void) {
TEST_START(C_TrieSET_UniqueUnsigned_TestSuite);
RUN_TEST(test_c_TrieSet_UniqueUnsignedFlow);
RUN_TEST(test_c_TrieSet_Toxicity_Defenses);
RUN_TEST(test_c_TrieSet_StringBuffer_Pipeline);
TEST_REPORT();
return (g_test_registry.failed_count > 0 ? 1 : 0);
}