diff options
| author | Thomas Vanbesien <tvanbesi@proton.me> | 2026-02-21 12:39:20 +0100 |
|---|---|---|
| committer | Thomas Vanbesien <tvanbesi@proton.me> | 2026-02-21 12:39:34 +0100 |
| commit | d699849b2360f90c61f645c5d4d4232cd3e1c962 (patch) | |
| tree | c929ec20ca3b16fe3d34bd75e412ca49f7420125 /tests/test_search.c | |
| download | Libft-d699849b2360f90c61f645c5d4d4232cd3e1c962.tar.gz Libft-d699849b2360f90c61f645c5d4d4232cd3e1c962.zip | |
Initial commit: libft Part 1 with tests and documentation
Reimplements 24 libc functions with Doxygen-documented header
and test suite comparing against libc.
Diffstat (limited to 'tests/test_search.c')
| -rw-r--r-- | tests/test_search.c | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/tests/test_search.c b/tests/test_search.c new file mode 100644 index 0000000..faaaccd --- /dev/null +++ b/tests/test_search.c @@ -0,0 +1,285 @@ +#include "../libft.h" +#include "test_utils.h" +#include <bsd/string.h> + +static void +_s_ft_strchr_null (void) +{ + _s_sink = (size_t)ft_strchr (NULL, 'a'); +} +static void +_s_libc_strchr_null (void) +{ + _s_sink = (size_t)strchr (NULL, 'a'); +} +static void +_s_ft_strrchr_null (void) +{ + _s_sink = (size_t)ft_strrchr (NULL, 'a'); +} +static void +_s_libc_strrchr_null (void) +{ + _s_sink = (size_t)strrchr (NULL, 'a'); +} +static void +_s_ft_strnstr_null_big (void) +{ + _s_sink = (size_t)ft_strnstr (NULL, "abc", 10); +} +static void +_s_libc_strnstr_null_big (void) +{ + _s_sink = (size_t)strnstr (NULL, "abc", 10); +} +static void +_s_ft_strnstr_null_little (void) +{ + _s_sink = (size_t)ft_strnstr ("abc", NULL, 10); +} +static void +_s_libc_strnstr_null_little (void) +{ + _s_sink = (size_t)strnstr ("abc", NULL, 10); +} + +/* ====================================== + * strchr + * ====================================== */ + +static void +_s_test_strchr (void) +{ + char buf[] = "hello world"; + int i; + char label[64]; + + printf ("-- strchr --\n"); + + /* NULL */ + _s_check_both_crash ("strchr NULL", _s_ft_strchr_null, _s_libc_strchr_null); + + /* find first occurrence */ + _s_check ("find 'l'", ft_strchr (buf, 'l') == strchr (buf, 'l')); + + /* find first char */ + _s_check ("find 'h'", ft_strchr (buf, 'h') == strchr (buf, 'h')); + + /* find last char */ + _s_check ("find 'd'", ft_strchr (buf, 'd') == strchr (buf, 'd')); + + /* not found */ + _s_check ("not found 'z'", ft_strchr (buf, 'z') == strchr (buf, 'z')); + + /* find null terminator */ + _s_check ("find '\\0'", ft_strchr (buf, '\0') == strchr (buf, '\0')); + + /* empty string */ + _s_check ("empty + 'a'", ft_strchr ("", 'a') == strchr ("", 'a')); + _s_check ("empty + '\\0'", ft_strchr ("", '\0') == strchr ("", '\0')); + + /* int truncation to char */ + _s_check ("int truncation", + ft_strchr (buf, 'h' + 256) == strchr (buf, 'h' + 256)); + + /* all printable ASCII */ + for (i = 32; i < 127; i++) + { + snprintf (label, sizeof (label), "char %d in buf", i); + _s_check (label, ft_strchr (buf, i) == strchr (buf, i)); + } + + /* randomized */ + srand (time (NULL)); + for (i = 0; i < 50; i++) + { + char rnd[128]; + int len = rand () % 127 + 1; + int j; + int c; + for (j = 0; j < len; j++) + rnd[j] = 'A' + rand () % 52; + rnd[len] = '\0'; + c = 'A' + rand () % 52; + snprintf (label, sizeof (label), "random len=%d c=%c", len, c); + _s_check (label, ft_strchr (rnd, c) == strchr (rnd, c)); + } +} + +/* ====================================== + * strrchr + * ====================================== */ + +static void +_s_test_strrchr (void) +{ + char buf[] = "hello world"; + int i; + char label[64]; + + printf ("-- strrchr --\n"); + + /* NULL */ + _s_check_both_crash ("strrchr NULL", _s_ft_strrchr_null, + _s_libc_strrchr_null); + + /* find last occurrence */ + _s_check ("find 'l'", ft_strrchr (buf, 'l') == strrchr (buf, 'l')); + + /* only one occurrence */ + _s_check ("find 'w'", ft_strrchr (buf, 'w') == strrchr (buf, 'w')); + + /* find first char */ + _s_check ("find 'h'", ft_strrchr (buf, 'h') == strrchr (buf, 'h')); + + /* find last char */ + _s_check ("find 'd'", ft_strrchr (buf, 'd') == strrchr (buf, 'd')); + + /* not found */ + _s_check ("not found 'z'", ft_strrchr (buf, 'z') == strrchr (buf, 'z')); + + /* find null terminator */ + _s_check ("find '\\0'", ft_strrchr (buf, '\0') == strrchr (buf, '\0')); + + /* empty string */ + _s_check ("empty + 'a'", ft_strrchr ("", 'a') == strrchr ("", 'a')); + _s_check ("empty + '\\0'", ft_strrchr ("", '\0') == strrchr ("", '\0')); + + /* int truncation to char */ + _s_check ("int truncation", + ft_strrchr (buf, 'l' + 256) == strrchr (buf, 'l' + 256)); + + /* multiple occurrences */ + _s_check ("'o' last", + ft_strrchr ("foo bar boo", 'o') == strrchr ("foo bar boo", 'o')); + + /* all printable ASCII */ + for (i = 32; i < 127; i++) + { + snprintf (label, sizeof (label), "char %d in buf", i); + _s_check (label, ft_strrchr (buf, i) == strrchr (buf, i)); + } + + /* randomized */ + for (i = 0; i < 50; i++) + { + char rnd[128]; + int len = rand () % 127 + 1; + int j; + int c; + for (j = 0; j < len; j++) + rnd[j] = 'A' + rand () % 52; + rnd[len] = '\0'; + c = 'A' + rand () % 52; + snprintf (label, sizeof (label), "random len=%d c=%c", len, c); + _s_check (label, ft_strrchr (rnd, c) == strrchr (rnd, c)); + } +} + +/* ====================================== + * strnstr + * ====================================== */ + +static void +_s_test_strnstr (void) +{ + char hay[] = "hello world, hello earth"; + + printf ("-- strnstr --\n"); + + /* NULL */ + _s_check_both_crash ("strnstr NULL big", _s_ft_strnstr_null_big, + _s_libc_strnstr_null_big); + _s_check_both_crash ("strnstr NULL little", _s_ft_strnstr_null_little, + _s_libc_strnstr_null_little); + + /* empty needle */ + _s_check ("empty needle", ft_strnstr (hay, "", 24) == strnstr (hay, "", 24)); + + /* empty haystack */ + _s_check ("empty haystack", + ft_strnstr ("", "abc", 0) == strnstr ("", "abc", 0)); + _s_check ("both empty", ft_strnstr ("", "", 0) == strnstr ("", "", 0)); + + /* basic find */ + _s_check ("find 'world'", + ft_strnstr (hay, "world", 24) == strnstr (hay, "world", 24)); + + /* find at start */ + _s_check ("find 'hello'", + ft_strnstr (hay, "hello", 24) == strnstr (hay, "hello", 24)); + + /* find at end */ + _s_check ("find 'earth'", + ft_strnstr (hay, "earth", 24) == strnstr (hay, "earth", 24)); + + /* not found */ + _s_check ("not found 'xyz'", + ft_strnstr (hay, "xyz", 24) == strnstr (hay, "xyz", 24)); + + /* needle longer than len */ + _s_check ("needle beyond len", + ft_strnstr (hay, "world", 8) == strnstr (hay, "world", 8)); + + /* len=0 */ + _s_check ("len=0", + ft_strnstr (hay, "hello", 0) == strnstr (hay, "hello", 0)); + + /* exact match at boundary */ + _s_check ("exact boundary", + ft_strnstr (hay, "world", 11) == strnstr (hay, "world", 11)); + + /* one short of match */ + _s_check ("one short", + ft_strnstr (hay, "world", 10) == strnstr (hay, "world", 10)); + + /* single char needle */ + _s_check ("single char 'w'", + ft_strnstr (hay, "w", 24) == strnstr (hay, "w", 24)); + + /* needle same as haystack */ + _s_check ("needle == haystack", + ft_strnstr ("abc", "abc", 3) == strnstr ("abc", "abc", 3)); + + /* needle longer than haystack */ + _s_check ("needle > haystack", + ft_strnstr ("ab", "abc", 3) == strnstr ("ab", "abc", 3)); + + /* partial match then fail */ + _s_check ("partial match", + ft_strnstr ("aab", "ab", 3) == strnstr ("aab", "ab", 3)); + + /* randomized */ + for (int i = 0; i < 50; i++) + { + char rbig[128]; + char rlittle[16]; + int blen = rand () % 100 + 20; + int llen = rand () % 10 + 1; + size_t n; + int j; + char label[64]; + for (j = 0; j < blen; j++) + rbig[j] = 'A' + rand () % 4; + rbig[blen] = '\0'; + for (j = 0; j < llen; j++) + rlittle[j] = 'A' + rand () % 4; + rlittle[llen] = '\0'; + n = rand () % (blen + 10); + snprintf (label, sizeof (label), "random blen=%d llen=%d n=%zu", blen, + llen, n); + _s_check (label, + ft_strnstr (rbig, rlittle, n) == strnstr (rbig, rlittle, n)); + } +} + +int +main (void) +{ + printf ("=== search functions ===\n"); + _s_test_strchr (); + _s_test_strrchr (); + _s_test_strnstr (); + _s_print_results (); + return (_s_fail != 0); +} |
