aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_search.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_search.c')
-rw-r--r--tests/test_search.c285
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);
+}