109 lines
4.3 KiB
C
109 lines
4.3 KiB
C
#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);
|
||
}
|