From a2344ef2f59715c248789f16bf1ba2a4570810f8 Mon Sep 17 00:00:00 2001 From: Mosder Date: Fri, 21 Aug 2026 21:13:35 +0200 Subject: feat: added remaining tests for string.h --- include/moslib/string.h | 21 ++++++++-- src/string.c | 4 ++ src/tester.c | 1 + tests/string_tests.c | 108 ++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 124 insertions(+), 10 deletions(-) diff --git a/include/moslib/string.h b/include/moslib/string.h index bc9efff..cbba69f 100644 --- a/include/moslib/string.h +++ b/include/moslib/string.h @@ -59,9 +59,10 @@ // // ---------------------------------------------------------------------------------------------------- // -// To check if two slices are equal, use: +// To check if two slices / slice and string are equal, use: // // int are_eq = ss_eq(ss1, ss2); +// int are_eq = ss_eq_str(ss1, "string"); // // ---------------------------------------------------------------------------------------------------- // @@ -104,9 +105,9 @@ // You can split a slice by a delimiter using ss_split functions: // // StringSlice ss1 = ss_from_str("Hello, World!"); -// StringSlice ss2 = ss_split(&ss1, ','); // ss2 = "Hello", ss3 = " World!" +// StringSlice ss2 = ss_split(&ss1, ','); // ss2 = "Hello", ss1 = " World!" // StringSlice ss3 = ss_split_str(&ss2, "ll"); // ss3 = "He", ss2 = "o" -// StringSlice ss4 = ss_split_ss(&ss1, ss_from_lit("rld")); // ss4 = " Wo", ss1 = "!" +// StringSlice ss4 = ss_split_ss(&ss1, SS_LIT("rld")); // ss4 = " Wo", ss1 = "!" // // They will return a slice containing everything before the delimiter and modify in place the given // slice to contain everything after the delimiter. @@ -161,6 +162,7 @@ #define SS_FMT MOS_SS_FMT #define SS_ARGS MOS_SS_ARGS #define ss_eq mos_ss_eq +#define ss_eq_str mos_ss_eq_str #define ss_trim mos_ss_trim #define ss_trim_left mos_ss_trim_left #define ss_trim_right mos_ss_trim_right @@ -270,6 +272,19 @@ extern void mos_ss_print(MosStringSlice ss); // 1 if slices are equal, 0 otherwise extern int mos_ss_eq(MosStringSlice ss1, MosStringSlice ss2); +// Check if slice is equal to a C string +// +// Arguments: +// ss +// slice to compare +// +// str +// C string to compare +// +// Returns: +// 1 if slice is equal to C string, 0 otherwise +extern int mos_ss_eq_str(MosStringSlice ss, const char *str); + // Time a slice of white space from both the left and the right side // // Arguments: diff --git a/src/string.c b/src/string.c index b40483f..02aa141 100644 --- a/src/string.c +++ b/src/string.c @@ -24,6 +24,10 @@ int mos_ss_eq(MosStringSlice ss1, MosStringSlice ss2) { return 0; } +int mos_ss_eq_str(MosStringSlice ss, const char *str) { + return 0; +} + MosStringSlice mos_ss_trim(MosStringSlice ss) { return (MosStringSlice){0}; } diff --git a/src/tester.c b/src/tester.c index 49e3490..4ac7987 100644 --- a/src/tester.c +++ b/src/tester.c @@ -1,3 +1,4 @@ +#define _XOPEN_SOURCE 600 #define MOS_FORCE_PREFIXES #include "moslib/tester.h" diff --git a/tests/string_tests.c b/tests/string_tests.c index 7247b05..57fe82e 100644 --- a/tests/string_tests.c +++ b/tests/string_tests.c @@ -1,3 +1,4 @@ +#define _XOPEN_SOURCE 600 #include "string_tests.h" #include "moslib/string.h" @@ -47,10 +48,12 @@ Test printing() { Test comparing() { StringSlice ss = ss_from_str("hello world"); test_assert(ss_eq(ss, ss), "slice is not equal to itself"); + test_assert(ss_eq_str(ss, ss.data), "slice is not equal to its C string"); char *hw = strdup("hello world"); StringSlice ss2 = ss_from_str(hw); test_assert(ss_eq(ss, ss2), "slice is not equal to an equal slice"); + test_assert(ss_eq_str(ss, hw), "slice is not equal to an equal string"); free(hw); StringSlice ss3 = ss_from_vars(ss.data, ss.len - 1); @@ -59,23 +62,24 @@ Test comparing() { StringSlice ss4 = ss_from_str("hello"); StringSlice ss5 = ss_from_str("world"); test_assert(ss_eq(ss4, ss5) == 0, "slice is equal when the length is the same but pointer differs"); + test_assert(ss_eq_str(ss4, "world") == 0, "slice is equal to different string"); } Test trimming() { StringSlice ss = ss_from_str(" Hi :) "); StringSlice t = ss_trim(ss); - test_assert(ss_eq(t, ss_from_str("Hi :)")), "ss_trim didn't trim properly"); + test_assert(ss_eq_str(t, "Hi :)"), "trim didn't trim properly"); test_assert(ss_eq(t, ss_trim(t)), "trimming slice twice changes output"); StringSlice tl = ss_trim_left(ss); - test_assert(ss_eq(tl, ss_from_str("Hi :) ")), "ss_trim_left didn't trim properly"); + test_assert(ss_eq_str(tl, "Hi :) "), "trim_left didn't trim properly"); StringSlice tr = ss_trim_right(ss); - test_assert(ss_eq(tr, ss_from_str(" Hi :)")), "ss_trim_right didn't trim properly"); + test_assert(ss_eq_str(tr, " Hi :)"), "trim_right didn't trim properly"); ss = ss_from_str(" "); t = ss_trim(ss); - test_assert(ss_eq(t, ss_from_str("")), "trimming breaks for all whitespace slice"); + test_assert(ss_eq_str(t, ""), "trimming breaks for all whitespace slice"); } Test prefix_suffix() { @@ -99,15 +103,105 @@ Test prefix_suffix() { } Test deleting() { - test_assert(0, "TODO"); + StringSlice ss = ss_from_str("1234567890"); + + size_t deleted = ss_del_left(&ss, 2); + test_assert(deleted == 2, "ss_del_left returned wrong deleted count"); + test_assert(ss_eq_str(ss, "34567890"), "del_left deleted wrong chars"); + + deleted = ss_del_right(&ss, 6); + test_assert(deleted == 6, "ss_del_right returned wrong deleted count"); + test_assert(ss_eq_str(ss, "34"), "del_right deleted wrong chars"); + + deleted = ss_del_left(&ss, 100); + test_assert(deleted == 2, "ss_del_left returned wrong deleted count (n > len)"); + test_assert(ss_eq_str(ss, ""), "del_left deleted wrong chars (n > len)"); + + deleted = ss_del_right(&ss, 15); + test_assert(deleted == 0, "ss_del_right returned wrong deleted count (n > len)"); + test_assert(ss_eq_str(ss, ""), "del_right deleted wrong chars (n > len)"); + + ss = ss_from_str("prepre sufsuf"); + StringSlice pre = ss_from_str("pre"); + StringSlice suf = ss_from_str("suf"); + + int flag = ss_del_prefix(&ss, pre); + test_assert(flag && ss.len == 10, "del_prefix didn't work properly for found prefix"); + flag = ss_del_prefix(&ss, suf); + test_assert(!flag && ss.len == 10, "del_prefix didn't work properly for not found prefix"); + + flag = ss_del_suffix(&ss, suf); + test_assert(flag && ss.len == 7, "del_suffix didn't work properly for found suffix"); + flag = ss_del_prefix(&ss, pre); + test_assert(!flag && ss.len == 7, "del_suffix didn't work properly for not found suffix"); + + flag = ss_del_prefix_str(&ss, "pre"); + test_assert(flag && ss.len == 4, "del_prefix_str didn't work properly for found prefix"); + flag = ss_del_prefix_str(&ss, "suf"); + test_assert(!flag && ss.len == 4, "del_prefix_str didn't work properly for not found prefix"); + + flag = ss_del_suffix_str(&ss, "suf"); + test_assert(flag && ss.len == 1, "del_suffix_str didn't work properly for found suffix"); + flag = ss_del_prefix_str(&ss, "pre"); + test_assert(!flag && ss.len == 1, "del_suffix_str didn't work properly for not found suffix"); } Test splitting() { - test_assert(0, "TODO"); + StringSlice ss1 = ss_from_str("Hello, World!"); + + StringSlice ss2 = ss_split(&ss1, ','); + test_assert(ss_eq_str(ss2, "Hello") && ss_eq_str(ss1, " World!"), "ss_split didn't split proprely"); + + StringSlice ss3 = ss_split_str(&ss2, "ll"); + test_assert(ss_eq_str(ss3, "He") && ss_eq_str(ss2, "o"), "ss_split_str didn't split proprely"); + + StringSlice ss4 = ss_split_ss(&ss1, SS_LIT("rld")); + test_assert(ss_eq_str(ss4, "Wo") && ss_eq_str(ss1, "!"), "ss_split_ss didn't split proprely"); + + ss1 = ss_from_str("hiii"); + + ss2 = ss_split_str(&ss1, ""); + test_assert(ss_eq_str(ss2, "") && ss_eq_str(ss1, "hiii"), "ss_split_str fails empty str edge case"); + + ss2 = ss_split_ss(&ss1, SS_LIT("")); + test_assert(ss_eq_str(ss2, "") && ss_eq_str(ss1, "hiii"), "ss_split_ss fails empty ss edge case"); + + ss2 = ss_split(&ss1, '.'); + test_assert(ss_eq_str(ss2, "hiii") && ss_eq_str(ss1, ""), "ss_split fails not found delim edge case"); + + ss1 = ss_split_str(&ss2, ".."); + test_assert(ss_eq_str(ss1, "hiii") && ss_eq_str(ss2, ""), "ss_split_str fails not found delim edge case"); + + ss2 = ss_split_ss(&ss1, SS_LIT("...")); + test_assert(ss_eq_str(ss2, "hiii") && ss_eq_str(ss1, ""), "ss_split_ss fails not found delim edge case"); + + StringSlice ss_middle = ss_from_str("[left][middle][right]"); + + StringSlice ss_left = ss_split_left(&ss_middle, 6); + test_assert(ss_eq_str(ss_left, "[left]") && ss_eq_str(ss_middle, "[middle][right]"), "ss_split_left didn't split properly"); + + StringSlice ss_right = ss_split_right(&ss_middle, 7); + test_assert(ss_eq_str(ss_right, "[right]") && ss_eq_str(ss_middle, "[middle]"), "ss_split_right didn't split properly"); + + ss_left = ss_split_left(&ss_middle, 20); + test_assert(ss_eq_str(ss_left, "[middle]") && ss_eq_str(ss_middle, ""), "ss_split_left didn't split properly (n > len)"); + + ss_right = ss_split_right(&ss_middle, 500); + test_assert(ss_eq_str(ss_right, "") && ss_eq_str(ss_middle, ""), "ss_split_right didn't split properly (n > len)"); } Test finding() { - test_assert(0, "TODO"); + char *txt = "a slice of FINDME text"; + StringSlice ss = ss_from_str(txt); + + test_assert(ss_eq_str(ss_find(ss, ss_from_str("FINDME")), "FINDME text"), "find didn't find a part of the slice"); + test_assert(ss_eq_str(ss_find_str(ss, "FINDME"), "FINDME text"), "find_str didn't find a part of the slice"); + + test_assert(ss_eq(ss_find(ss, ss_from_str("")), ss), "find didn't return whole slice for empty target"); + test_assert(ss_eq(ss_find_str(ss, ""), ss), "find_str didn't return whole slice for empty target"); + + test_assert(ss_eq_str(ss_find(ss, ss_from_str("abcd")), ""), "find didn't return empty slice for not found target"); + test_assert(ss_eq_str(ss_find_str(ss, "abcd"), ""), "find_str didn't return empty slice for not found target"); } Test utf8_len_test() { -- cgit v1.2.3