diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/Makefile | 3 | ||||
| -rw-r--r-- | tests/src/test_itoa.c | 99 | ||||
| -rw-r--r-- | tests/src/test_put.c | 197 | ||||
| -rw-r--r-- | tests/src/test_split.c | 234 | ||||
| -rw-r--r-- | tests/src/test_striteri.c | 105 | ||||
| -rw-r--r-- | tests/src/test_strjoin.c | 111 | ||||
| -rw-r--r-- | tests/src/test_strmapi.c | 108 | ||||
| -rw-r--r-- | tests/src/test_strtrim.c | 162 | ||||
| -rw-r--r-- | tests/src/test_substr.c | 135 |
9 files changed, 1153 insertions, 1 deletions
diff --git a/tests/Makefile b/tests/Makefile index c0c8059..61b7d44 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -7,7 +7,8 @@ BINDIR = bin LIB = ../lib/libft.a TESTS = test_strlen test_is test_mem test_cmp test_case test_strl test_search \ - test_atoi test_alloc + test_atoi test_alloc test_substr test_strjoin test_strtrim \ + test_split test_itoa test_strmapi test_striteri test_put BINS = $(TESTS:%=$(BINDIR)/%) diff --git a/tests/src/test_itoa.c b/tests/src/test_itoa.c new file mode 100644 index 0000000..17cafe3 --- /dev/null +++ b/tests/src/test_itoa.c @@ -0,0 +1,99 @@ +#include "libft.h" +#include "test_utils.h" +#include <limits.h> + +static void +_s_test_itoa (void) +{ + int i; + char label[128]; + char expected[64]; + + _s_section ("ft_itoa"); + + /* zero */ + { + char *p = ft_itoa (0); + _s_check ("zero", p && strcmp (p, "0") == 0); + free (p); + } + + /* positive */ + { + char *p = ft_itoa (42); + _s_check ("positive", p && strcmp (p, "42") == 0); + free (p); + } + + /* negative */ + { + char *p = ft_itoa (-42); + _s_check ("negative", p && strcmp (p, "-42") == 0); + free (p); + } + + /* INT_MAX */ + { + char *p = ft_itoa (INT_MAX); + snprintf (expected, sizeof (expected), "%d", INT_MAX); + _s_check ("INT_MAX", p && strcmp (p, expected) == 0); + free (p); + } + + /* INT_MIN */ + { + char *p = ft_itoa (INT_MIN); + snprintf (expected, sizeof (expected), "%d", INT_MIN); + _s_check ("INT_MIN", p && strcmp (p, expected) == 0); + free (p); + } + + /* single digit positive */ + { + char *p = ft_itoa (7); + _s_check ("single digit", p && strcmp (p, "7") == 0); + free (p); + } + + /* single digit negative */ + { + char *p = ft_itoa (-1); + _s_check ("neg single digit", p && strcmp (p, "-1") == 0); + free (p); + } + + /* powers of ten */ + { + char *p; + + p = ft_itoa (10); + _s_check ("10", p && strcmp (p, "10") == 0); + free (p); + p = ft_itoa (100); + _s_check ("100", p && strcmp (p, "100") == 0); + free (p); + p = ft_itoa (-1000); + _s_check ("-1000", p && strcmp (p, "-1000") == 0); + free (p); + } + + /* randomized */ + for (i = 0; i < _S_RAND_ITERS; i++) + { + int n = rand () - RAND_MAX / 2; + char *p = ft_itoa (n); + snprintf (expected, sizeof (expected), "%d", n); + snprintf (label, sizeof (label), "random n=%d", n); + _s_check (label, p && strcmp (p, expected) == 0); + free (p); + } +} + +int +main (void) +{ + srand (time (NULL)); + _s_test_itoa (); + _s_print_results (); + return (_s_fail != 0); +} diff --git a/tests/src/test_put.c b/tests/src/test_put.c new file mode 100644 index 0000000..3c7f6dc --- /dev/null +++ b/tests/src/test_put.c @@ -0,0 +1,197 @@ +#include "libft.h" +#include "test_utils.h" +#include <limits.h> + +/* ── helper: capture fd output into a buffer ──────────────────────── */ + +static int +_s_read_pipe (void (*fn) (int), char *buf, size_t bufsz) +{ + int fds[2]; + ssize_t n; + + if (pipe (fds) < 0) + return (-1); + fn (fds[1]); + close (fds[1]); + n = read (fds[0], buf, bufsz - 1); + close (fds[0]); + if (n < 0) + return (-1); + buf[n] = '\0'; + return (n); +} + +/* ====================================== + * ft_putchar_fd + * ====================================== */ + +static void +_s_putchar_a (int fd) +{ + ft_putchar_fd ('a', fd); +} +static void +_s_putchar_nl (int fd) +{ + ft_putchar_fd ('\n', fd); +} +static void +_s_putchar_zero (int fd) +{ + ft_putchar_fd ('\0', fd); +} + +static void +_s_test_putchar_fd (void) +{ + char buf[64]; + + _s_section ("ft_putchar_fd"); + + _s_read_pipe (_s_putchar_a, buf, sizeof (buf)); + _s_check ("char 'a'", strcmp (buf, "a") == 0); + + _s_read_pipe (_s_putchar_nl, buf, sizeof (buf)); + _s_check ("newline", strcmp (buf, "\n") == 0); + + { + int n = _s_read_pipe (_s_putchar_zero, buf, sizeof (buf)); + _s_check ("null byte", n == 1 && buf[0] == '\0'); + } +} + +/* ====================================== + * ft_putstr_fd + * ====================================== */ + +static void +_s_putstr_hello (int fd) +{ + ft_putstr_fd ("hello", fd); +} +static void +_s_putstr_empty (int fd) +{ + ft_putstr_fd ("", fd); +} + +_S_CRASH_V (ft_putstr_null, ft_putstr_fd (NULL, 1)) + +static void +_s_test_putstr_fd (void) +{ + char buf[256]; + + _s_section ("ft_putstr_fd"); + + _s_check ("NULL crashes", _s_crashes (_s_crash_ft_putstr_null)); + + _s_read_pipe (_s_putstr_hello, buf, sizeof (buf)); + _s_check ("hello", strcmp (buf, "hello") == 0); + + { + int n = _s_read_pipe (_s_putstr_empty, buf, sizeof (buf)); + _s_check ("empty", n == 0); + } +} + +/* ====================================== + * ft_putendl_fd + * ====================================== */ + +static void +_s_putendl_hello (int fd) +{ + ft_putendl_fd ("hello", fd); +} +static void +_s_putendl_empty (int fd) +{ + ft_putendl_fd ("", fd); +} + +_S_CRASH_V (ft_putendl_null, ft_putendl_fd (NULL, 1)) + +static void +_s_test_putendl_fd (void) +{ + char buf[256]; + + _s_section ("ft_putendl_fd"); + + _s_check ("NULL crashes", _s_crashes (_s_crash_ft_putendl_null)); + + _s_read_pipe (_s_putendl_hello, buf, sizeof (buf)); + _s_check ("hello\\n", strcmp (buf, "hello\n") == 0); + + _s_read_pipe (_s_putendl_empty, buf, sizeof (buf)); + _s_check ("empty\\n", strcmp (buf, "\n") == 0); +} + +/* ====================================== + * ft_putnbr_fd + * ====================================== */ + +static void +_s_putnbr_0 (int fd) +{ + ft_putnbr_fd (0, fd); +} +static void +_s_putnbr_42 (int fd) +{ + ft_putnbr_fd (42, fd); +} +static void +_s_putnbr_neg (int fd) +{ + ft_putnbr_fd (-42, fd); +} +static void +_s_putnbr_max (int fd) +{ + ft_putnbr_fd (INT_MAX, fd); +} +static void +_s_putnbr_min (int fd) +{ + ft_putnbr_fd (INT_MIN, fd); +} + +static void +_s_test_putnbr_fd (void) +{ + char buf[64]; + char expected[64]; + + _s_section ("ft_putnbr_fd"); + + _s_read_pipe (_s_putnbr_0, buf, sizeof (buf)); + _s_check ("zero", strcmp (buf, "0") == 0); + + _s_read_pipe (_s_putnbr_42, buf, sizeof (buf)); + _s_check ("positive", strcmp (buf, "42") == 0); + + _s_read_pipe (_s_putnbr_neg, buf, sizeof (buf)); + _s_check ("negative", strcmp (buf, "-42") == 0); + + _s_read_pipe (_s_putnbr_max, buf, sizeof (buf)); + snprintf (expected, sizeof (expected), "%d", INT_MAX); + _s_check ("INT_MAX", strcmp (buf, expected) == 0); + + _s_read_pipe (_s_putnbr_min, buf, sizeof (buf)); + snprintf (expected, sizeof (expected), "%d", INT_MIN); + _s_check ("INT_MIN", strcmp (buf, expected) == 0); +} + +int +main (void) +{ + _s_test_putchar_fd (); + _s_test_putstr_fd (); + _s_test_putendl_fd (); + _s_test_putnbr_fd (); + _s_print_results (); + return (_s_fail != 0); +} diff --git a/tests/src/test_split.c b/tests/src/test_split.c new file mode 100644 index 0000000..55847a2 --- /dev/null +++ b/tests/src/test_split.c @@ -0,0 +1,234 @@ +#include "libft.h" +#include "test_utils.h" + +_S_CRASH (ft_split_null, ft_split (NULL, ' ')) + +static void +_s_free_split (char **arr) +{ + size_t i; + + if (!arr) + return; + i = 0; + while (arr[i]) + free (arr[i++]); + free (arr); +} + +static size_t +_s_arr_len (char **arr) +{ + size_t n; + + n = 0; + while (arr[n]) + n++; + return (n); +} + +static void +_s_test_split (void) +{ + int i; + char label[128]; + + _s_section ("ft_split"); + + /* NULL crashes */ + _s_check ("NULL crashes", _s_crashes (_s_crash_ft_split_null)); + + /* basic split */ + { + char **arr = ft_split ("hello world foo", ' '); + _s_check ("basic count", arr && _s_arr_len (arr) == 3); + _s_check ("basic [0]", arr && strcmp (arr[0], "hello") == 0); + _s_check ("basic [1]", arr && strcmp (arr[1], "world") == 0); + _s_check ("basic [2]", arr && strcmp (arr[2], "foo") == 0); + _s_check ("basic NULL-term", arr && arr[3] == NULL); + _s_free_split (arr); + } + + /* leading delimiters */ + { + char **arr = ft_split (" hello", ' '); + _s_check ("leading delim count", arr && _s_arr_len (arr) == 1); + _s_check ("leading delim [0]", arr && strcmp (arr[0], "hello") == 0); + _s_free_split (arr); + } + + /* trailing delimiters */ + { + char **arr = ft_split ("hello ", ' '); + _s_check ("trailing delim count", arr && _s_arr_len (arr) == 1); + _s_check ("trailing delim [0]", arr && strcmp (arr[0], "hello") == 0); + _s_free_split (arr); + } + + /* consecutive delimiters */ + { + char **arr = ft_split ("a,,b,,c", ','); + _s_check ("consec count", arr && _s_arr_len (arr) == 3); + _s_check ("consec [0]", arr && strcmp (arr[0], "a") == 0); + _s_check ("consec [1]", arr && strcmp (arr[1], "b") == 0); + _s_check ("consec [2]", arr && strcmp (arr[2], "c") == 0); + _s_free_split (arr); + } + + /* no delimiter in string */ + { + char **arr = ft_split ("hello", ' '); + _s_check ("no delim count", arr && _s_arr_len (arr) == 1); + _s_check ("no delim [0]", arr && strcmp (arr[0], "hello") == 0); + _s_free_split (arr); + } + + /* empty string */ + { + char **arr = ft_split ("", ' '); + _s_check ("empty count", arr && _s_arr_len (arr) == 0); + _s_check ("empty NULL-term", arr && arr[0] == NULL); + _s_free_split (arr); + } + + /* string is only delimiters */ + { + char **arr = ft_split (" ", ' '); + _s_check ("only delims count", arr && _s_arr_len (arr) == 0); + _s_check ("only delims NULL-term", arr && arr[0] == NULL); + _s_free_split (arr); + } + + /* single character string, is delimiter */ + { + char **arr = ft_split (",", ','); + _s_check ("single delim count", arr && _s_arr_len (arr) == 0); + _s_free_split (arr); + } + + /* single character string, not delimiter */ + { + char **arr = ft_split ("a", ','); + _s_check ("single non-delim count", arr && _s_arr_len (arr) == 1); + _s_check ("single non-delim [0]", arr && strcmp (arr[0], "a") == 0); + _s_free_split (arr); + } + + /* delimiter '\0' — whole string is one word */ + { + char **arr = ft_split ("hello", '\0'); + _s_check ("nul delim count", arr && _s_arr_len (arr) == 1); + _s_check ("nul delim [0]", arr && strcmp (arr[0], "hello") == 0); + _s_free_split (arr); + } + + /* each word is independently allocated */ + { + char **arr = ft_split ("a b c", ' '); + _s_check ("independent ptrs", arr && arr[0] != arr[1] && arr[1] != arr[2]); + _s_free_split (arr); + } + + /* randomized: build string from words, split, verify */ + for (i = 0; i < _S_RAND_ITERS; i++) + { + int nwords = rand () % 10 + 1; + int pads = rand () % 5; + char **words = malloc (nwords * sizeof (char *)); + char *src; + char **arr; + size_t total; + int j, k; + int ok; + + if (!words) + continue; + + /* generate random words (letters only) */ + total = 0; + ok = 1; + for (j = 0; j < nwords; j++) + { + int wlen = rand () % 20 + 1; + words[j] = malloc (wlen + 1); + if (!words[j]) + { + ok = 0; + break; + } + for (k = 0; k < wlen; k++) + words[j][k] = 'A' + rand () % 26; + words[j][wlen] = '\0'; + total += wlen; + } + if (!ok) + { + for (k = 0; k < j; k++) + free (words[k]); + free (words); + continue; + } + + /* build: pads + word + delimiters + ... + pads */ + total += (nwords - 1) + 2 * pads; + src = malloc (total + 1); + if (!src) + { + for (j = 0; j < nwords; j++) + free (words[j]); + free (words); + continue; + } + + k = 0; + for (j = 0; j < pads; j++) + src[k++] = ','; + for (j = 0; j < nwords; j++) + { + size_t wlen = strlen (words[j]); + memcpy (src + k, words[j], wlen); + k += wlen; + if (j < nwords - 1) + src[k++] = ','; + } + for (j = 0; j < pads; j++) + src[k++] = ','; + src[k] = '\0'; + + arr = ft_split (src, ','); + snprintf (label, sizeof (label), "random nwords=%d pads=%d", nwords, + pads); + if (!arr || (int)_s_arr_len (arr) != nwords) + { + _s_check (label, 0); + } + else + { + int match = 1; + for (j = 0; j < nwords; j++) + { + if (strcmp (arr[j], words[j]) != 0) + { + match = 0; + break; + } + } + _s_check (label, match && arr[nwords] == NULL); + } + + for (j = 0; j < nwords; j++) + free (words[j]); + free (words); + free (src); + _s_free_split (arr); + } +} + +int +main (void) +{ + srand (time (NULL)); + _s_test_split (); + _s_print_results (); + return (_s_fail != 0); +} diff --git a/tests/src/test_striteri.c b/tests/src/test_striteri.c new file mode 100644 index 0000000..0874c02 --- /dev/null +++ b/tests/src/test_striteri.c @@ -0,0 +1,105 @@ +#include "libft.h" +#include "test_utils.h" +#include <ctype.h> + +_S_CRASH_V (ft_striteri_null, ft_striteri (NULL, NULL)) + +static void +_s_to_upper (unsigned int i, char *c) +{ + (void)i; + *c = toupper (*c); +} + +static void +_s_add_index (unsigned int i, char *c) +{ + *c = *c + i; +} + +static void +_s_test_striteri (void) +{ + int i; + char label[128]; + + _s_section ("ft_striteri"); + + /* NULL crashes */ + _s_check ("NULL crashes", _s_crashes (_s_crash_ft_striteri_null)); + + /* basic: to uppercase in place */ + { + char s[] = "hello"; + ft_striteri (s, _s_to_upper); + _s_check ("to_upper", strcmp (s, "HELLO") == 0); + } + + /* function receives correct index */ + { + char s[] = "aaaa"; + ft_striteri (s, _s_add_index); + _s_check ("index passed", + s[0] == 'a' && s[1] == 'b' && s[2] == 'c' && s[3] == 'd'); + } + + /* empty string: no crash, no change */ + { + char s[] = ""; + ft_striteri (s, _s_to_upper); + _s_check ("empty", strcmp (s, "") == 0); + } + + /* single character */ + { + char s[] = "a"; + ft_striteri (s, _s_to_upper); + _s_check ("single char", strcmp (s, "A") == 0); + } + + /* modifies in place (same pointer) */ + { + char s[] = "hello"; + char *orig = s; + ft_striteri (s, _s_to_upper); + _s_check ("in place", s == orig); + } + + /* randomized: apply to_upper, compare with manual */ + for (i = 0; i < _S_RAND_ITERS; i++) + { + int len = rand () % 200 + 1; + char *src = malloc (len + 1); + char *expected = malloc (len + 1); + int j; + + if (!src || !expected) + { + free (src); + free (expected); + continue; + } + for (j = 0; j < len; j++) + { + src[j] = 'a' + rand () % 26; + expected[j] = toupper (src[j]); + } + src[len] = '\0'; + expected[len] = '\0'; + + ft_striteri (src, _s_to_upper); + snprintf (label, sizeof (label), "random len=%d", len); + _s_check (label, strcmp (src, expected) == 0); + free (src); + free (expected); + } +} + +int +main (void) +{ + srand (time (NULL)); + _s_test_striteri (); + _s_print_results (); + return (_s_fail != 0); +} diff --git a/tests/src/test_strjoin.c b/tests/src/test_strjoin.c new file mode 100644 index 0000000..023f84d --- /dev/null +++ b/tests/src/test_strjoin.c @@ -0,0 +1,111 @@ +#include "libft.h" +#include "test_utils.h" + +_S_CRASH (ft_strjoin_null_s1, ft_strjoin (NULL, "hello")) +_S_CRASH (ft_strjoin_null_s2, ft_strjoin ("hello", NULL)) +_S_CRASH (ft_strjoin_null_both, ft_strjoin (NULL, NULL)) + +static void +_s_test_strjoin (void) +{ + int i; + char label[128]; + + _s_section ("ft_strjoin"); + + /* NULL crashes */ + _s_check ("NULL s1 crashes", _s_crashes (_s_crash_ft_strjoin_null_s1)); + _s_check ("NULL s2 crashes", _s_crashes (_s_crash_ft_strjoin_null_s2)); + _s_check ("NULL both crashes", _s_crashes (_s_crash_ft_strjoin_null_both)); + + /* two normal strings */ + { + char *p = ft_strjoin ("hello ", "world"); + _s_check ("basic", p && strcmp (p, "hello world") == 0); + free (p); + } + + /* first string empty */ + { + char *p = ft_strjoin ("", "world"); + _s_check ("s1 empty", p && strcmp (p, "world") == 0); + free (p); + } + + /* second string empty */ + { + char *p = ft_strjoin ("hello", ""); + _s_check ("s2 empty", p && strcmp (p, "hello") == 0); + free (p); + } + + /* both empty */ + { + char *p = ft_strjoin ("", ""); + _s_check ("both empty", p && strcmp (p, "") == 0); + free (p); + } + + /* returns independent copy */ + { + char s1[] = "abc"; + char s2[] = "def"; + char *p = ft_strjoin (s1, s2); + _s_check ("independent ptr", p && p != s1 && p != s2); + s1[0] = 'X'; + _s_check ("mutation safe", p[0] == 'a'); + free (p); + } + + /* randomized */ + for (i = 0; i < _S_RAND_ITERS; i++) + { + int len1 = rand () % 200 + 1; + int len2 = rand () % 200 + 1; + char *s1 = malloc (len1 + 1); + char *s2 = malloc (len2 + 1); + char *expected; + char *p; + int j; + + if (!s1 || !s2) + { + free (s1); + free (s2); + continue; + } + for (j = 0; j < len1; j++) + s1[j] = 'A' + rand () % 26; + s1[len1] = '\0'; + for (j = 0; j < len2; j++) + s2[j] = 'a' + rand () % 26; + s2[len2] = '\0'; + + expected = malloc (len1 + len2 + 1); + if (!expected) + { + free (s1); + free (s2); + continue; + } + memcpy (expected, s1, len1); + memcpy (expected + len1, s2, len2 + 1); + + p = ft_strjoin (s1, s2); + snprintf (label, sizeof (label), "random len1=%d len2=%d", len1, len2); + _s_check (label, p && strcmp (p, expected) == 0); + free (s1); + free (s2); + free (expected); + free (p); + } +} + +int +main (void) +{ + srand (time (NULL)); + _s_test_strjoin (); + _s_print_results (); + return (_s_fail != 0); +} diff --git a/tests/src/test_strmapi.c b/tests/src/test_strmapi.c new file mode 100644 index 0000000..31dba65 --- /dev/null +++ b/tests/src/test_strmapi.c @@ -0,0 +1,108 @@ +#include "libft.h" +#include "test_utils.h" +#include <ctype.h> + +_S_CRASH (ft_strmapi_null, ft_strmapi (NULL, NULL)) + +static char +_s_to_upper (unsigned int i, char c) +{ + (void)i; + return (toupper (c)); +} + +static char +_s_add_index (unsigned int i, char c) +{ + return (c + i); +} + +static void +_s_test_strmapi (void) +{ + int i; + char label[128]; + + _s_section ("ft_strmapi"); + + /* NULL crashes */ + _s_check ("NULL crashes", _s_crashes (_s_crash_ft_strmapi_null)); + + /* basic: to uppercase */ + { + char *p = ft_strmapi ("hello", _s_to_upper); + _s_check ("to_upper", p && strcmp (p, "HELLO") == 0); + free (p); + } + + /* function receives correct index */ + { + char *p = ft_strmapi ("aaaa", _s_add_index); + _s_check ("index passed", + p && p[0] == 'a' && p[1] == 'b' && p[2] == 'c' && p[3] == 'd'); + free (p); + } + + /* empty string */ + { + char *p = ft_strmapi ("", _s_to_upper); + _s_check ("empty", p && strcmp (p, "") == 0); + free (p); + } + + /* returns independent copy */ + { + char s[] = "hello"; + char *p = ft_strmapi (s, _s_to_upper); + _s_check ("independent ptr", p && p != s); + _s_check ("original unchanged", strcmp (s, "hello") == 0); + free (p); + } + + /* single character */ + { + char *p = ft_strmapi ("a", _s_to_upper); + _s_check ("single char", p && strcmp (p, "A") == 0); + free (p); + } + + /* randomized: apply to_upper, compare with manual */ + for (i = 0; i < _S_RAND_ITERS; i++) + { + int len = rand () % 200 + 1; + char *src = malloc (len + 1); + char *expected = malloc (len + 1); + char *p; + int j; + + if (!src || !expected) + { + free (src); + free (expected); + continue; + } + for (j = 0; j < len; j++) + { + src[j] = 'a' + rand () % 26; + expected[j] = toupper (src[j]); + } + src[len] = '\0'; + expected[len] = '\0'; + + p = ft_strmapi (src, _s_to_upper); + snprintf (label, sizeof (label), "random len=%d", len); + _s_check (label, p && strcmp (p, expected) == 0); + free (src); + free (expected); + free (p); + } +} + +int +main (void) +{ + srand (time (NULL)); + _s_test_strmapi (); + _s_print_results (); + return (_s_fail != 0); +} diff --git a/tests/src/test_strtrim.c b/tests/src/test_strtrim.c new file mode 100644 index 0000000..aa57ef7 --- /dev/null +++ b/tests/src/test_strtrim.c @@ -0,0 +1,162 @@ +#include "libft.h" +#include "test_utils.h" + +_S_CRASH (ft_strtrim_null_s1, ft_strtrim (NULL, " ")) +_S_CRASH (ft_strtrim_null_set, ft_strtrim ("hello", NULL)) +_S_CRASH (ft_strtrim_null_both, ft_strtrim (NULL, NULL)) + +static void +_s_test_strtrim (void) +{ + int i; + char label[128]; + + _s_section ("ft_strtrim"); + + /* NULL crashes */ + _s_check ("NULL s1 crashes", _s_crashes (_s_crash_ft_strtrim_null_s1)); + _s_check ("NULL set crashes", _s_crashes (_s_crash_ft_strtrim_null_set)); + _s_check ("NULL both crashes", _s_crashes (_s_crash_ft_strtrim_null_both)); + + /* trim spaces from both ends */ + { + char *p = ft_strtrim (" hello ", " "); + _s_check ("spaces both ends", p && strcmp (p, "hello") == 0); + free (p); + } + + /* trim multiple characters */ + { + char *p = ft_strtrim ("xxhelloxx", "x"); + _s_check ("single trim char", p && strcmp (p, "hello") == 0); + free (p); + } + + /* trim set with multiple chars */ + { + char *p = ft_strtrim (".-hello-.", ".-"); + _s_check ("multi-char set", p && strcmp (p, "hello") == 0); + free (p); + } + + /* nothing to trim */ + { + char *p = ft_strtrim ("hello", " "); + _s_check ("nothing to trim", p && strcmp (p, "hello") == 0); + free (p); + } + + /* everything trimmed */ + { + char *p = ft_strtrim ("aaaa", "a"); + _s_check ("all trimmed", p && strcmp (p, "") == 0); + free (p); + } + + /* empty string */ + { + char *p = ft_strtrim ("", "abc"); + _s_check ("empty s1", p && strcmp (p, "") == 0); + free (p); + } + + /* empty set */ + { + char *p = ft_strtrim (" hello ", ""); + _s_check ("empty set", p && strcmp (p, " hello ") == 0); + free (p); + } + + /* trim only leading */ + { + char *p = ft_strtrim ("xxhello", "x"); + _s_check ("leading only", p && strcmp (p, "hello") == 0); + free (p); + } + + /* trim only trailing */ + { + char *p = ft_strtrim ("helloxx", "x"); + _s_check ("trailing only", p && strcmp (p, "hello") == 0); + free (p); + } + + /* set chars in the middle are preserved */ + { + char *p = ft_strtrim (" hello world ", " "); + _s_check ("middle preserved", p && strcmp (p, "hello world") == 0); + free (p); + } + + /* single character string, in set */ + { + char *p = ft_strtrim ("x", "x"); + _s_check ("single char trimmed", p && strcmp (p, "") == 0); + free (p); + } + + /* single character string, not in set */ + { + char *p = ft_strtrim ("x", "y"); + _s_check ("single char kept", p && strcmp (p, "x") == 0); + free (p); + } + + /* returns independent copy */ + { + char s1[] = "hello"; + char *p = ft_strtrim (s1, ""); + _s_check ("independent ptr", p && p != s1); + free (p); + } + + /* randomized */ + for (i = 0; i < _S_RAND_ITERS; i++) + { + int core_len = rand () % 100 + 1; + int pad_len = rand () % 20; + char *src; + char *p; + char *expected; + int j; + + src = malloc (pad_len + core_len + pad_len + 1); + expected = malloc (core_len + 1); + if (!src || !expected) + { + free (src); + free (expected); + continue; + } + + /* pad with spaces, core with letters */ + for (j = 0; j < pad_len; j++) + src[j] = ' '; + for (j = 0; j < core_len; j++) + { + src[pad_len + j] = 'A' + rand () % 26; + expected[j] = src[pad_len + j]; + } + expected[core_len] = '\0'; + for (j = 0; j < pad_len; j++) + src[pad_len + core_len + j] = ' '; + src[pad_len + core_len + pad_len] = '\0'; + + p = ft_strtrim (src, " "); + snprintf (label, sizeof (label), "random core=%d pad=%d", core_len, + pad_len); + _s_check (label, p && strcmp (p, expected) == 0); + free (src); + free (expected); + free (p); + } +} + +int +main (void) +{ + srand (time (NULL)); + _s_test_strtrim (); + _s_print_results (); + return (_s_fail != 0); +} diff --git a/tests/src/test_substr.c b/tests/src/test_substr.c new file mode 100644 index 0000000..30e59ce --- /dev/null +++ b/tests/src/test_substr.c @@ -0,0 +1,135 @@ +#include "libft.h" +#include "test_utils.h" + +_S_CRASH (ft_substr_null, ft_substr (NULL, 0, 5)) + +static void +_s_test_substr (void) +{ + int i; + char label[128]; + + _s_section ("ft_substr"); + + /* NULL crashes */ + _s_check ("NULL crashes", _s_crashes (_s_crash_ft_substr_null)); + + /* basic substring from the middle */ + { + char *p = ft_substr ("hello world", 6, 5); + _s_check ("middle", p && strcmp (p, "world") == 0); + free (p); + } + + /* from the start */ + { + char *p = ft_substr ("hello", 0, 3); + _s_check ("from start", p && strcmp (p, "hel") == 0); + free (p); + } + + /* len larger than remaining string */ + { + char *p = ft_substr ("hello", 2, 100); + _s_check ("len > remaining", p && strcmp (p, "llo") == 0); + free (p); + } + + /* start beyond string length */ + { + char *p = ft_substr ("hello", 10, 5); + _s_check ("start > slen", p && strcmp (p, "") == 0); + free (p); + } + + /* start == string length */ + { + char *p = ft_substr ("hello", 5, 5); + _s_check ("start == slen", p && strcmp (p, "") == 0); + free (p); + } + + /* empty source string */ + { + char *p = ft_substr ("", 0, 10); + _s_check ("empty src", p && strcmp (p, "") == 0); + free (p); + } + + /* len == 0 */ + { + char *p = ft_substr ("hello", 0, 0); + _s_check ("len=0", p && strcmp (p, "") == 0); + free (p); + } + + /* full string copy */ + { + char *p = ft_substr ("hello", 0, 5); + _s_check ("full copy", p && strcmp (p, "hello") == 0); + free (p); + } + + /* single character */ + { + char *p = ft_substr ("hello", 4, 1); + _s_check ("single char", p && strcmp (p, "o") == 0); + free (p); + } + + /* returns independent copy */ + { + char src[] = "hello"; + char *p = ft_substr (src, 0, 5); + _s_check ("independent ptr", p && p != src); + free (p); + } + + /* randomized */ + for (i = 0; i < _S_RAND_ITERS; i++) + { + int slen = rand () % 200 + 1; + char *src = malloc (slen + 1); + unsigned int start; + size_t len; + char *p; + int j; + + if (!src) + continue; + for (j = 0; j < slen; j++) + src[j] = 'A' + rand () % 26; + src[slen] = '\0'; + + start = rand () % (slen + 5); + len = rand () % (slen + 5); + p = ft_substr (src, start, len); + + if (start >= (unsigned int)slen) + { + snprintf (label, sizeof (label), "random start=%u >= slen=%d", start, + slen); + _s_check (label, p && strcmp (p, "") == 0); + } + else + { + size_t remaining = slen - start; + size_t expected = remaining < len ? remaining : len; + snprintf (label, sizeof (label), "random start=%u len=%zu slen=%d", + start, len, slen); + _s_check (label, p && strlen (p) == expected + && strncmp (p, src + start, expected) == 0); + } + free (p); + free (src); + } +} + +int +main (void) +{ + srand (time (NULL)); + _s_test_substr (); + _s_print_results (); + return (_s_fail != 0); +} |
