#include #include "c_Str.h" #include #include const char *test_str = "abcdefg"; // 長度為 7 char test_output_buffer[128]; int buf_idx = 0; int test_put(int c, void *cl) { if (buf_idx < 127) { test_output_buffer[buf_idx++] = (char)c; } return c; } // Global print wrapper to test formatting execution void test_printf(const char *fmt, ...) { va_list_box ap; va_start(ap.ap, fmt); c_Fmt_vfmt(test_put, NULL, fmt, &ap); va_end(ap.ap); } void test_log(const char* name) { printf("[PASS] %s\n", name); } int main() { printf("==================================================\n"); printf(" 開始執行 c_Str 核心功能組件 最終整合單元測試\n"); printf("==================================================\n\n"); char *res_str = NULL; // 1. 測試 c_Str_pos // test_str = "abcdefg" (len=7) // 1 -> index 0 -> 位置 1 // 0 -> 尾端倒數 (0+7) = index 7 -> 位置 8 // -1 -> 尾端倒數 (-1+7) = index 6 -> 位置 7 assert(c_Str_pos(test_str, 1) == 1); assert(c_Str_pos(test_str, 0) == 8); assert(c_Str_pos(test_str, -1) == 7); test_log("c_Str_pos (1-based 位置計算驗證)"); // 2. 測試 c_Str_len // 從 1 (開頭) 到 0 (結尾) -> 全長 7 // 從 2 ('b') 到 5 ('e' 後方) -> 5 - 1 = 4 ('bcde') assert(c_Str_len(test_str, 1, 0) == 7); assert(c_Str_len(test_str, 2, 5) == 3); test_log("c_Str_len (區間長度計算驗證)"); // 3. 測試 c_Str_sub res_str = c_Str_sub(test_str, 2, 5); // 提取 'bcd' assert(strcmp(res_str, "bcd") == 0); c_Str_free(res_str); test_log("c_Str_sub (子字串提取驗證)"); // 4. 測試 c_Str_dup res_str = c_Str_dup(test_str, 2, 4, 3); // 'bc' 重複 3 次 assert(strcmp(res_str, "bcbcbc") == 0); c_Str_free(res_str); test_log("c_Str_dup (子字串重複複製驗證)"); // 5. 測試 c_Str_reverse res_str = c_Str_reverse(test_str, 2, 5); // 'bcd' 反轉 -> 'dcb' assert(strcmp(res_str, "dcb") == 0); c_Str_free(res_str); test_log("c_Str_reverse (子字串反轉驗證)"); // 6. 測試 c_Str_cat res_str = c_Str_cat("XYZ", 1, 0, "123", 1, 3); // "XYZ" + "12" -> "XYZ12" assert(strcmp(res_str, "XYZ12") == 0); c_Str_free(res_str); test_log("c_Str_cat (雙字串區間拼接驗證)"); // 7. 測試 c_Str_catv (多字串可變參數拼接,必須以 NULL 結尾) res_str = c_Str_catv("ABC", 1, 0, "XYZ", 2, 4, (char*)NULL); // "ABC" + "YZ" assert(strcmp(res_str, "ABCYZ") == 0); c_Str_free(res_str); test_log("c_Str_catv (多參數變長字串拼接驗證)"); // 8. 測試 c_Str_map (字元映射/置換) // 初始化對照表:將 'b' 換成 'X','d' 換成 'Y' c_Str_map(NULL, 0, 0, "bd", "XY"); res_str = c_Str_map(test_str, 1, 0, NULL, NULL); // "abcdefg" -> "aXcYe f g" assert(strcmp(res_str, "aXcYefg") == 0); c_Str_free(res_str); test_log("c_Str_map (字元對照表置換驗證)"); // 9. 測試 c_Str_cmp // "abcdefg" 區間 [2,4] 是 "bc";"abc" 區間 [2,4] 是 "bc" -> 相等 (0) assert(c_Str_cmp(test_str, 2, 4, "abc", 2, 4) == 0); // "bc" 與 "bcd" 比對 -> 前者較短且完全匹配,預期回傳 -1 assert(c_Str_cmp(test_str, 2, 4, "abcdefg", 2, 5) == -1); test_log("c_Str_cmp (區間字串深度比對驗證)"); // 10. 測試 c_Str_chr (正向尋找字元,回傳 1-based 位置) // 在 "abcdefg" 中找 'c' -> 位於 index 2 -> 回傳 3 assert(c_Str_chr(test_str, 1, 0, 'c') == 3); assert(c_Str_chr(test_str, 1, 0, 'z') == 0); // 找不到 test_log("c_Str_chr (正向字元查找位置驗證)"); // 11. 測試 c_Str_rchr (反向尋找字元) // 在 "abcdecd" 中找 'c' assert(c_Str_rchr("abcdecd", 1, 0, 'c') == 6); test_log("c_Str_rchr (反向字元查找位置驗證)"); // 12. 測試 c_Str_upto (正向尋找集合中任一字元首次出現位置) // "abcdefg" 中尋找 "xyz" 或 "d" -> 'd' 最先被匹配 (index 3) -> 回傳 4 assert(c_Str_upto(test_str, 1, 0, "xyz d") == 4); test_log("c_Str_upto (字元集合正向切分點驗證)"); // 13. 測試 c_Str_rupto (反向尋找集合中任一字元首次出現位置) // "abcdefg" 中反向找 "ab" -> 'b' 最先被找到 (index 1) -> 回傳 2 assert(c_Str_rupto(test_str, 1, 0, "ab") == 2); test_log("c_Str_rupto (字元集合反向切分點驗證)"); // 14. 測試 c_Str_find (正向尋找子字串) // "abcdefg" 中找 "cde" -> 開始於 index 2 -> 回傳 3 assert(c_Str_find(test_str, 1, 0, "cde") == 3); test_log("c_Str_find (正向子字串搜尋匹配驗證)"); // 15. 測試 c_Str_rfind (反向尋找子字串) // "ababax" 中反向找 "aba" -> 應匹配到 index 2 開始的 "aba" -> 回傳 3 assert(c_Str_rfind("ababax", 1, 0, "aba") == 3); test_log("c_Str_rfind (反向子字串搜尋匹配驗證)"); // 16. 測試 c_Str_any (檢查指定 index 的單一字元是否在集合中) // test_str="abcdefg", i=3 -> index 2 ('c')。'c' 有在 "cba" 之中 -> 回傳 index+2 = 4 assert(c_Str_any(test_str, 3, "cba") == 4); assert(c_Str_any(test_str, 3, "xyz") == 0); // 'c' 不在 xyz 中 test_log("c_Str_any (特定點字元集命中檢查驗證)"); // 17. 測試 c_Str_many (從指定起點向後匹配連續屬於集合的字元,直到不屬於為止) // "aaabX" 從 1 開始,連續符合 "abc" 的有 'a','a','a','b' (4個) -> 停止於 index 4 -> 回傳 4+1 = 5 assert(c_Str_many("aaabX", 1, 0, "abc") == 5); test_log("c_Str_many (正向連續字元集跨越範圍驗證)"); // 18. 測試 c_Str_rmany (從指定終點向前匹配連續屬於集合的字元) // "Xbbba" 從 0(結尾) 向前,符合 "abc" 的有 'a','b','b','b' (4個) -> 停止於 index 0 ('X') -> 回傳 index+2 = 2 assert(c_Str_rmany("Xbbba", 1, 0, "abc") == 2); test_log("c_Str_rmany (反向連續字元集跨越範圍驗證)"); // 19. 測試 c_Str_match (檢查指定起點是否「精準開頭匹配」該子字串) // "abcdefg" 在位置 3 (index 2, 'c') 是否精準匹配 "cde" -> 是,符合長度 3 -> 回傳 index+len+1 = 2+3+1 = 6 assert(c_Str_match(test_str, 3, 0, "cde") == 6); assert(c_Str_match(test_str, 3, 0, "xyz") == 0); test_log("c_Str_match (指定起點子字串精準頭匹配驗證)"); // 20. 測試 c_Str_rmatch (檢查指定終點是否「精準結尾匹配」該子字串) // "abcde" 在 0(結尾, index 5) 向前看是否精準匹配 "cde" (len=3) -> index 5-3=2 開始是 "cde" -> 成功,回傳 2+1 = 3 assert(c_Str_rmatch("abcde", 1, 0, "cde") == 3); test_log("c_Str_rmatch (指定終點子字串精準尾匹配驗證)"); // 21. 測試 c_Str_fmt (驗證自訂格式化回呼整合) #if 0 unsigned char flags[256] = { 0 }; mock_put_count = 0; // 傳入字串 "hello", 起點 2 ('e'), 終點 5 ('o' 後方) -> 預期提取出 "ell" run_str_fmt_test(0, flags, 0, 0, "hello", 2, 5); assert(mock_put_count == 3); // "ell" 長度為 3,應呼叫 3 次 put test_log("c_Str_fmt (格式化輸出器區間提取回呼驗證)"); #endif memset(test_output_buffer, 0, sizeof(test_output_buffer)); buf_idx = 0; c_Fmt_t old_handler = c_Fmt_register('S', c_Str_fmt); assert(old_handler == NULL); printf("[PASS] c_Str_fmt successfully registered to specifier character 'S'.\n"); const char* sample_sentence = "the c-container-library platform"; test_printf("Extracted Token: [%S]", sample_sentence, 5, 16); test_output_buffer[buf_idx] = '\0'; printf(" Rendered Output String: %s\n", test_output_buffer); assert(strcmp(test_output_buffer, "Extracted Token: [c-container]") == 0); printf("[PASS] Core Fmt engine correctly processed parameters via c_Str_fmt.\n"); printf("\n==================================================\n"); printf(" 恭喜!c_Str 基礎工具類共計 22 個核心介面全數單元測試通過!\n"); printf("==================================================\n"); return 0; }