diff options
| author | Thomas Vanbesien <tvanbesi@proton.me> | 2026-02-21 15:49:06 +0100 |
|---|---|---|
| committer | Thomas Vanbesien <tvanbesi@proton.me> | 2026-02-21 15:51:44 +0100 |
| commit | 671a58519ef6207b54947ff70eea497ff7eb58ae (patch) | |
| tree | 783a971119bfed965113b84bc306ba941e884663 /tests/src/test_cmp.c | |
| parent | d699849b2360f90c61f645c5d4d4232cd3e1c962 (diff) | |
| download | Libft-671a58519ef6207b54947ff70eea497ff7eb58ae.tar.gz Libft-671a58519ef6207b54947ff70eea497ff7eb58ae.zip | |
Restructure project layout and clean up test suite
Move sources to src/, header to inc/, and tests to tests/src/.
Update Makefiles and .gitignore for the new layout.
Refactor test harness: add crash-wrapper macros (_S_CRASH,
_S_CRASH_I, _S_CRASH_V, _S_CRASH_BUF) replacing 58 hand-written
wrappers, add shared _s_test_int_range helper eliminating duplicate
_s_test_func, add _S_RAND_ITERS constant, move srand() to main()
in all test binaries, and add Doxygen comments to test_utils.h.
Diffstat (limited to 'tests/src/test_cmp.c')
| -rw-r--r-- | tests/src/test_cmp.c | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/tests/src/test_cmp.c b/tests/src/test_cmp.c new file mode 100644 index 0000000..d98b584 --- /dev/null +++ b/tests/src/test_cmp.c @@ -0,0 +1,238 @@ +#include "libft.h" +#include "test_utils.h" + +_S_CRASH (ft_memchr_null, ft_memchr (NULL, 'a', 10)) +_S_CRASH (libc_memchr_null, memchr (NULL, 'a', 10)) +_S_CRASH_I (ft_memcmp_null_s1, ft_memcmp (NULL, "abc", 3)) +_S_CRASH_I (libc_memcmp_null_s1, memcmp (NULL, "abc", 3)) +_S_CRASH_I (ft_memcmp_null_s2, ft_memcmp ("abc", NULL, 3)) +_S_CRASH_I (libc_memcmp_null_s2, memcmp ("abc", NULL, 3)) +_S_CRASH_I (ft_strncmp_null_s1, ft_strncmp (NULL, "abc", 3)) +_S_CRASH_I (libc_strncmp_null_s1, strncmp (NULL, "abc", 3)) +_S_CRASH_I (ft_strncmp_null_s2, ft_strncmp ("abc", NULL, 3)) +_S_CRASH_I (libc_strncmp_null_s2, strncmp ("abc", NULL, 3)) + +/* ====================================== + * memchr + * ====================================== */ + +static void +_s_test_memchr (void) +{ + char buf[] = "Hello, World!"; + char all[256]; + int i; + char label[64]; + + _s_section ("ft_memchr"); + + /* NULL */ + _s_check_both_crash ("memchr NULL", _s_crash_ft_memchr_null, + _s_crash_libc_memchr_null); + + /* find existing char */ + _s_check ("find 'W'", ft_memchr (buf, 'W', 13) == memchr (buf, 'W', 13)); + + /* find first byte */ + _s_check ("find 'H'", ft_memchr (buf, 'H', 13) == memchr (buf, 'H', 13)); + + /* find last byte */ + _s_check ("find '!'", ft_memchr (buf, '!', 13) == memchr (buf, '!', 13)); + + /* not found */ + _s_check ("not found 'z'", + ft_memchr (buf, 'z', 13) == memchr (buf, 'z', 13)); + + /* n=0 */ + _s_check ("n=0", ft_memchr (buf, 'H', 0) == NULL); + + /* char beyond n */ + _s_check ("beyond n", ft_memchr (buf, '!', 5) == memchr (buf, '!', 5)); + + /* search for null byte */ + _s_check ("find '\\0'", ft_memchr (buf, '\0', 14) == memchr (buf, '\0', 14)); + + /* int truncation to unsigned char */ + _s_check ("int truncation", + ft_memchr (buf, 'H' + 256, 13) == memchr (buf, 'H' + 256, 13)); + + /* all byte values */ + for (i = 0; i < 256; i++) + all[i] = i; + for (i = 0; i < 256; i++) + { + snprintf (label, sizeof (label), "byte %d", i); + _s_check (label, ft_memchr (all, i, 256) == memchr (all, i, 256)); + } + + /* randomized */ + for (i = 0; i < _S_RAND_ITERS; i++) + { + unsigned char rnd[256]; + int len = rand () % 256 + 1; + int c = rand () % 256; + int j; + for (j = 0; j < len; j++) + rnd[j] = rand () % 256; + snprintf (label, sizeof (label), "random len=%d c=%d", len, c); + _s_check (label, ft_memchr (rnd, c, len) == memchr (rnd, c, len)); + } +} + +/* ====================================== + * memcmp + * ====================================== */ + +static void +_s_test_memcmp (void) +{ + int i; + unsigned char a[256]; + unsigned char b[256]; + size_t len; + int pos; + char label[64]; + + _s_section ("ft_memcmp"); + + /* NULL */ + _s_check_both_crash ("memcmp NULL s1", _s_crash_ft_memcmp_null_s1, + _s_crash_libc_memcmp_null_s1); + _s_check_both_crash ("memcmp NULL s2", _s_crash_ft_memcmp_null_s2, + _s_crash_libc_memcmp_null_s2); + + /* equal */ + _s_check ("equal", _s_sign (ft_memcmp ("abc", "abc", 3)) + == _s_sign (memcmp ("abc", "abc", 3))); + + /* first less */ + _s_check ("less", _s_sign (ft_memcmp ("abc", "abd", 3)) + == _s_sign (memcmp ("abc", "abd", 3))); + + /* first greater */ + _s_check ("greater", _s_sign (ft_memcmp ("abd", "abc", 3)) + == _s_sign (memcmp ("abd", "abc", 3))); + + /* n=0 */ + _s_check ("n=0", _s_sign (ft_memcmp ("abc", "xyz", 0)) + == _s_sign (memcmp ("abc", "xyz", 0))); + + /* difference at last byte */ + _s_check ("diff at end", _s_sign (ft_memcmp ("abcd", "abce", 4)) + == _s_sign (memcmp ("abcd", "abce", 4))); + + /* unsigned comparison: 0 vs 200 */ + { + unsigned char x[] = { 0 }; + unsigned char y[] = { 200 }; + _s_check ("unsigned 0 vs 200", + _s_sign (ft_memcmp (x, y, 1)) == _s_sign (memcmp (x, y, 1))); + } + + /* randomized */ + for (i = 0; i < _S_RAND_ITERS; i++) + { + len = rand () % 255 + 1; + for (pos = 0; pos < (int)len; pos++) + a[pos] = b[pos] = rand () % 256; + /* introduce a random difference sometimes */ + if (i % 2 == 0) + { + pos = rand () % len; + b[pos] = (a[pos] + 1 + rand () % 255) % 256; + } + snprintf (label, sizeof (label), "random len=%zu", len); + _s_check (label, _s_sign (ft_memcmp (a, b, len)) + == _s_sign (memcmp (a, b, len))); + } +} + +/* ====================================== + * strncmp + * ====================================== */ + +static void +_s_test_strncmp (void) +{ + int i; + char a[128]; + char b[128]; + int len; + char label[64]; + + _s_section ("ft_strncmp"); + + /* NULL */ + _s_check_both_crash ("strncmp NULL s1", _s_crash_ft_strncmp_null_s1, + _s_crash_libc_strncmp_null_s1); + _s_check_both_crash ("strncmp NULL s2", _s_crash_ft_strncmp_null_s2, + _s_crash_libc_strncmp_null_s2); + + /* equal strings */ + _s_check ("equal", _s_sign (ft_strncmp ("abc", "abc", 3)) + == _s_sign (strncmp ("abc", "abc", 3))); + + /* less */ + _s_check ("less", _s_sign (ft_strncmp ("abc", "abd", 3)) + == _s_sign (strncmp ("abc", "abd", 3))); + + /* greater */ + _s_check ("greater", _s_sign (ft_strncmp ("abd", "abc", 3)) + == _s_sign (strncmp ("abd", "abc", 3))); + + /* n=0 */ + _s_check ("n=0", _s_sign (ft_strncmp ("abc", "xyz", 0)) + == _s_sign (strncmp ("abc", "xyz", 0))); + + /* n larger than strings */ + _s_check ("n > len", _s_sign (ft_strncmp ("abc", "abc", 100)) + == _s_sign (strncmp ("abc", "abc", 100))); + + /* difference beyond n */ + _s_check ("diff beyond n", _s_sign (ft_strncmp ("abcX", "abcY", 3)) + == _s_sign (strncmp ("abcX", "abcY", 3))); + + /* empty strings */ + _s_check ("both empty", + _s_sign (ft_strncmp ("", "", 5)) == _s_sign (strncmp ("", "", 5))); + + /* one empty */ + _s_check ("s1 empty", _s_sign (ft_strncmp ("", "a", 5)) + == _s_sign (strncmp ("", "a", 5))); + _s_check ("s2 empty", _s_sign (ft_strncmp ("a", "", 5)) + == _s_sign (strncmp ("a", "", 5))); + + /* different lengths, equal prefix */ + _s_check ("shorter s1", _s_sign (ft_strncmp ("ab", "abc", 5)) + == _s_sign (strncmp ("ab", "abc", 5))); + + /* unsigned comparison */ + _s_check ("unsigned", _s_sign (ft_strncmp ("\xff", "\x01", 1)) + == _s_sign (strncmp ("\xff", "\x01", 1))); + + /* randomized */ + for (i = 0; i < _S_RAND_ITERS; i++) + { + len = rand () % 64 + 1; + for (int j = 0; j < len; j++) + a[j] = b[j] = 'A' + rand () % 26; + a[len] = '\0'; + b[len] = '\0'; + if (i % 2 == 0) + b[rand () % len] = 'A' + rand () % 26; + snprintf (label, sizeof (label), "random n=%d", len); + _s_check (label, _s_sign (ft_strncmp (a, b, len)) + == _s_sign (strncmp (a, b, len))); + } +} + +int +main (void) +{ + srand (time (NULL)); + _s_test_memchr (); + _s_test_memcmp (); + _s_test_strncmp (); + _s_print_results (); + return (_s_fail != 0); +} |
