aboutsummaryrefslogtreecommitdiffstats
path: root/tests/src/test_strl.c
diff options
context:
space:
mode:
authorThomas Vanbesien <tvanbesi@proton.me>2026-02-21 15:49:06 +0100
committerThomas Vanbesien <tvanbesi@proton.me>2026-02-21 15:51:44 +0100
commit671a58519ef6207b54947ff70eea497ff7eb58ae (patch)
tree783a971119bfed965113b84bc306ba941e884663 /tests/src/test_strl.c
parentd699849b2360f90c61f645c5d4d4232cd3e1c962 (diff)
downloadLibft-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_strl.c')
-rw-r--r--tests/src/test_strl.c227
1 files changed, 227 insertions, 0 deletions
diff --git a/tests/src/test_strl.c b/tests/src/test_strl.c
new file mode 100644
index 0000000..a2caa22
--- /dev/null
+++ b/tests/src/test_strl.c
@@ -0,0 +1,227 @@
+#include "libft.h"
+#include "test_utils.h"
+#include <bsd/string.h>
+
+_S_CRASH (ft_strlcpy_null_dst, ft_strlcpy (NULL, "abc", 10))
+_S_CRASH (libc_strlcpy_null_dst, strlcpy (NULL, "abc", 10))
+_S_CRASH_BUF (ft_strlcpy_null_src, 10, _s_sink = ft_strlcpy (buf, NULL, 10))
+_S_CRASH_BUF (libc_strlcpy_null_src, 10, _s_sink = strlcpy (buf, NULL, 10))
+_S_CRASH (ft_strlcat_null_dst, ft_strlcat (NULL, "abc", 10))
+_S_CRASH (libc_strlcat_null_dst, strlcat (NULL, "abc", 10))
+
+/* strlcat NULL src needs an initialized buffer — keep manual */
+static void
+_s_crash_ft_strlcat_null_src (void)
+{
+ char buf[10] = "hi";
+ _s_sink = ft_strlcat (buf, NULL, 10);
+}
+static void
+_s_crash_libc_strlcat_null_src (void)
+{
+ char buf[10] = "hi";
+ _s_sink = strlcat (buf, NULL, 10);
+}
+
+/* ======================================
+ * strlcpy
+ * ====================================== */
+
+static void
+_s_test_strlcpy (void)
+{
+ char ft_dst[64];
+ char libc_dst[64];
+ size_t ft_ret;
+ size_t libc_ret;
+ int i;
+ size_t size;
+ char src[64];
+ char label[64];
+
+ _s_section ("ft_strlcpy");
+
+ /* NULL */
+ _s_check_both_crash ("strlcpy NULL dst", _s_crash_ft_strlcpy_null_dst,
+ _s_crash_libc_strlcpy_null_dst);
+ _s_check_both_crash ("strlcpy NULL src", _s_crash_ft_strlcpy_null_src,
+ _s_crash_libc_strlcpy_null_src);
+
+ /* basic copy */
+ ft_ret = ft_strlcpy (ft_dst, "hello", 64);
+ libc_ret = strlcpy (libc_dst, "hello", 64);
+ _s_check ("basic copy ret", ft_ret == libc_ret);
+ _s_check ("basic copy buf", strcmp (ft_dst, libc_dst) == 0);
+
+ /* size=0 */
+ memset (ft_dst, 'X', 64);
+ memset (libc_dst, 'X', 64);
+ ft_ret = ft_strlcpy (ft_dst, "hello", 0);
+ libc_ret = strlcpy (libc_dst, "hello", 0);
+ _s_check ("size=0 ret", ft_ret == libc_ret);
+ _s_check ("size=0 buf unchanged", ft_dst[0] == 'X');
+
+ /* truncation */
+ ft_ret = ft_strlcpy (ft_dst, "hello world", 6);
+ libc_ret = strlcpy (libc_dst, "hello world", 6);
+ _s_check ("truncate ret", ft_ret == libc_ret);
+ _s_check ("truncate buf", strcmp (ft_dst, libc_dst) == 0);
+ _s_check ("truncate null term", ft_dst[5] == '\0');
+
+ /* exact fit */
+ ft_ret = ft_strlcpy (ft_dst, "abc", 4);
+ libc_ret = strlcpy (libc_dst, "abc", 4);
+ _s_check ("exact fit ret", ft_ret == libc_ret);
+ _s_check ("exact fit buf", strcmp (ft_dst, libc_dst) == 0);
+
+ /* empty src */
+ ft_ret = ft_strlcpy (ft_dst, "", 64);
+ libc_ret = strlcpy (libc_dst, "", 64);
+ _s_check ("empty src ret", ft_ret == libc_ret);
+ _s_check ("empty src buf", strcmp (ft_dst, libc_dst) == 0);
+
+ /* size=1 */
+ ft_ret = ft_strlcpy (ft_dst, "hello", 1);
+ libc_ret = strlcpy (libc_dst, "hello", 1);
+ _s_check ("size=1 ret", ft_ret == libc_ret);
+ _s_check ("size=1 buf", ft_dst[0] == '\0');
+
+ /* randomized */
+ for (i = 0; i < _S_RAND_ITERS; i++)
+ {
+ int len = rand () % 60 + 1;
+ int j;
+ for (j = 0; j < len; j++)
+ src[j] = 'A' + rand () % 26;
+ src[len] = '\0';
+ size = rand () % 64;
+ memset (ft_dst, 'Z', 64);
+ memset (libc_dst, 'Z', 64);
+ ft_ret = ft_strlcpy (ft_dst, src, size);
+ libc_ret = strlcpy (libc_dst, src, size);
+ snprintf (label, sizeof (label), "random len=%d size=%zu", len, size);
+ _s_check (label,
+ ft_ret == libc_ret && memcmp (ft_dst, libc_dst, 64) == 0);
+ }
+}
+
+/* ======================================
+ * strlcat
+ * ====================================== */
+
+static void
+_s_test_strlcat (void)
+{
+ char ft_dst[64];
+ char libc_dst[64];
+ size_t ft_ret;
+ size_t libc_ret;
+ int i;
+ size_t size;
+ char label[64];
+
+ _s_section ("ft_strlcat");
+
+ /* NULL */
+ _s_check_both_crash ("strlcat NULL dst", _s_crash_ft_strlcat_null_dst,
+ _s_crash_libc_strlcat_null_dst);
+ _s_check_both_crash ("strlcat NULL src", _s_crash_ft_strlcat_null_src,
+ _s_crash_libc_strlcat_null_src);
+
+ /* basic concat */
+ strcpy (ft_dst, "hello");
+ strcpy (libc_dst, "hello");
+ ft_ret = ft_strlcat (ft_dst, " world", 64);
+ libc_ret = strlcat (libc_dst, " world", 64);
+ _s_check ("basic ret", ft_ret == libc_ret);
+ _s_check ("basic buf", strcmp (ft_dst, libc_dst) == 0);
+
+ /* size=0 */
+ strcpy (ft_dst, "hi");
+ strcpy (libc_dst, "hi");
+ ft_ret = ft_strlcat (ft_dst, "abc", 0);
+ libc_ret = strlcat (libc_dst, "abc", 0);
+ _s_check ("size=0 ret", ft_ret == libc_ret);
+
+ /* size == dstlen (no room to append) */
+ strcpy (ft_dst, "hello");
+ strcpy (libc_dst, "hello");
+ ft_ret = ft_strlcat (ft_dst, "abc", 5);
+ libc_ret = strlcat (libc_dst, "abc", 5);
+ _s_check ("size == dstlen ret", ft_ret == libc_ret);
+ _s_check ("size == dstlen buf", strcmp (ft_dst, libc_dst) == 0);
+
+ /* size less than dst len */
+ strcpy (ft_dst, "hello");
+ strcpy (libc_dst, "hello");
+ ft_ret = ft_strlcat (ft_dst, "abc", 3);
+ libc_ret = strlcat (libc_dst, "abc", 3);
+ _s_check ("size < dstlen ret", ft_ret == libc_ret);
+ _s_check ("size < dstlen buf", strcmp (ft_dst, libc_dst) == 0);
+
+ /* truncation */
+ strcpy (ft_dst, "hello");
+ strcpy (libc_dst, "hello");
+ ft_ret = ft_strlcat (ft_dst, " world", 8);
+ libc_ret = strlcat (libc_dst, " world", 8);
+ _s_check ("truncate ret", ft_ret == libc_ret);
+ _s_check ("truncate buf", strcmp (ft_dst, libc_dst) == 0);
+
+ /* exact fit */
+ strcpy (ft_dst, "abc");
+ strcpy (libc_dst, "abc");
+ ft_ret = ft_strlcat (ft_dst, "de", 6);
+ libc_ret = strlcat (libc_dst, "de", 6);
+ _s_check ("exact fit ret", ft_ret == libc_ret);
+ _s_check ("exact fit buf", strcmp (ft_dst, libc_dst) == 0);
+
+ /* empty src */
+ strcpy (ft_dst, "hello");
+ strcpy (libc_dst, "hello");
+ ft_ret = ft_strlcat (ft_dst, "", 64);
+ libc_ret = strlcat (libc_dst, "", 64);
+ _s_check ("empty src ret", ft_ret == libc_ret);
+ _s_check ("empty src buf", strcmp (ft_dst, libc_dst) == 0);
+
+ /* empty dst */
+ ft_dst[0] = '\0';
+ libc_dst[0] = '\0';
+ ft_ret = ft_strlcat (ft_dst, "hello", 64);
+ libc_ret = strlcat (libc_dst, "hello", 64);
+ _s_check ("empty dst ret", ft_ret == libc_ret);
+ _s_check ("empty dst buf", strcmp (ft_dst, libc_dst) == 0);
+
+ /* randomized */
+ for (i = 0; i < _S_RAND_ITERS; i++)
+ {
+ int dlen = rand () % 30;
+ int slen = rand () % 30 + 1;
+ int j;
+ for (j = 0; j < dlen; j++)
+ ft_dst[j] = libc_dst[j] = 'A' + rand () % 26;
+ ft_dst[dlen] = libc_dst[dlen] = '\0';
+ char src[64];
+ for (j = 0; j < slen; j++)
+ src[j] = 'a' + rand () % 26;
+ src[slen] = '\0';
+ size = rand () % 64;
+ memset (ft_dst + dlen + 1, 'Z', 63 - dlen);
+ memset (libc_dst + dlen + 1, 'Z', 63 - dlen);
+ ft_ret = ft_strlcat (ft_dst, src, size);
+ libc_ret = strlcat (libc_dst, src, size);
+ snprintf (label, sizeof (label), "random dlen=%d slen=%d size=%zu", dlen,
+ slen, size);
+ _s_check (label,
+ ft_ret == libc_ret && memcmp (ft_dst, libc_dst, 64) == 0);
+ }
+}
+
+int
+main (void)
+{
+ srand (time (NULL));
+ _s_test_strlcpy ();
+ _s_test_strlcat ();
+ _s_print_results ();
+ return (_s_fail != 0);
+}