From 5312fcffaae36f73e031f9b9c2e84792053fe06d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Sun, 12 Apr 2026 20:33:35 +0200 Subject: [PATCH] test(sv): add remaining tests --- include/c-libs/string-view.h | 12 +++++- test/string-view.c | 84 +++++++++++++++++++++++++++++++++++- 2 files changed, 93 insertions(+), 3 deletions(-) diff --git a/include/c-libs/string-view.h b/include/c-libs/string-view.h index 59c53b5..bd9c917 100644 --- a/include/c-libs/string-view.h +++ b/include/c-libs/string-view.h @@ -1,7 +1,9 @@ #ifndef CLIBS_STRING_VIEW_H #define CLIBS_STRING_VIEW_H +#include #include +#include #include #include #include @@ -198,8 +200,9 @@ StringView sv_new_sized(const char *str, size_t len) { StringView sv_new(const char *str) { return sv_new_sized(str, strlen(str)); } StringView sv_drop(StringView sv, size_t n) { + const char *nd = sv.data + n; return (StringView){ - .data = sv.data + n, + .data = nd < sv.end ? nd : sv.end, .end = sv.end, }; } @@ -212,9 +215,10 @@ StringView sv_take(StringView sv, size_t n) { } StringView sv_shrink(StringView sv, size_t n) { + const char *ne = sv.end - n; return (StringView){ .data = sv.data, - .end = sv.end - n, + .end = ne > sv.data ? ne : sv.data, }; } @@ -344,6 +348,10 @@ char *sv_concat_with_sep(const StringView *svs, size_t n, StringView sep) { write_head += l; } + *write_head = '\0'; + + assert(write_head - data == len - 1); + return data; } diff --git a/test/string-view.c b/test/string-view.c index bb14e5c..b06be7a 100644 --- a/test/string-view.c +++ b/test/string-view.c @@ -1,5 +1,6 @@ #include "c-libs/string-view.h" #include +#include Test(sv, construction) { const char *data = "abcdefg"; @@ -14,7 +15,7 @@ Test(sv, construction) { cr_assert(sv2.end == data + 2); } -Test(sv, inspection) { +Test(sv, basic_manipulation) { const char *data = "abcdefg"; size_t len = strlen(data); @@ -25,6 +26,87 @@ Test(sv, inspection) { cr_assert_str_eq(data, clone); cr_assert(sv_eq(sv1, sv1)); cr_assert_not(sv_eq(sv1, sv_drop(sv1, 1))); + cr_assert(sv_eq(sv_new("bcdefg"), sv_drop(sv1, 1))); + cr_assert(sv_eq(sv_new("efg"), sv_drop(sv1, 4))); + cr_assert(sv_eq(sv_new(""), sv_drop(sv1, 100))); + + cr_assert(sv_eq(sv_new("abc"), sv_take(sv1, 3))); + cr_assert(sv_eq(sv_new(""), sv_take(sv1, 0))); + cr_assert(sv_eq(sv_new(data), sv_take(sv1, 100))); + + cr_assert(sv_eq(sv_new("abcd"), sv_shrink(sv1, 3))); + cr_assert(sv_eq(sv_new(data), sv_shrink(sv1, 0))); + cr_assert(sv_eq(sv_new(""), sv_shrink(sv1, 100))); free(clone); } + +Test(sv, advanced_manipulation) { + const char *data = "a,b,c,d,e,f,g"; + StringView sv1 = sv_new(data); + + cr_assert(sv_eq(sv_new("e,f,g"), sv_seek(sv1, 'e'))); + cr_assert(sv_eq(sv_new("f,g"), sv_seek(sv1, 'f'))); + cr_assert(sv_eq(sv_new(data), sv_seek(sv1, 'a'))); + cr_assert(sv_eq(sv_new(""), sv_seek(sv1, 'x'))); + + cr_assert(sv_eq(sv_new("a"), sv_seek_back(sv1, 'a'))); + cr_assert(sv_eq(sv_new("a,b"), sv_seek_back(sv1, 'b'))); + cr_assert(sv_eq(sv_new(""), sv_seek_back(sv1, 'x'))); + + cr_assert(sv_eq(sv_new(",b,c,d,e,f,g"), sv_trim_front(sv1, isalnum))); + cr_assert(sv_eq(sv_new("a,b,c,d,e,f,"), sv_trim_back(sv1, isalnum))); + cr_assert(sv_eq(sv_new(",b,c,d,e,f,"), sv_trim(sv1, isalnum))); +} + +Test(sv, splitting) { + const char *data = "Hello : world : simple : splits"; + StringView sv1 = sv_new(data); + + cr_assert(sv_eq(sv_new("Hello "), sv_split_at(&sv1, ':'))); + cr_assert(sv_eq(sv_new(" world : simple : splits"), sv1)); + + cr_assert(sv_eq(sv_new(" world "), sv_split_at(&sv1, ':'))); + cr_assert(sv_eq(sv_new(" simple : splits"), sv1)); + + cr_assert(sv_eq(sv_new(" simple "), sv_split_at(&sv1, ':'))); + cr_assert(sv_eq(sv_new(" splits"), sv1)); + + cr_assert(sv_eq(sv_new(" splits"), sv_split_at(&sv1, ':'))); + cr_assert(sv_eq(sv_new(""), sv1)); + + sv1 = sv_new(data); + sv_split_at(&sv1, '?'); + cr_assert(sv_len(sv1) == 0); + + sv1 = sv_new(data); + + StringView sep = sv_new(" : "); + + cr_assert(sv_eq(sv_new("Hello"), sv_split_at_sv(&sv1, sep))); + cr_assert(sv_eq(sv_new("world : simple : splits"), sv1)); + + cr_assert(sv_eq(sv_new("world"), sv_split_at_sv(&sv1, sep))); + cr_assert(sv_eq(sv_new("simple : splits"), sv1)); + + cr_assert(sv_eq(sv_new("simple"), sv_split_at_sv(&sv1, sep))); + cr_assert(sv_eq(sv_new("splits"), sv1)); + + cr_assert(sv_eq(sv_new("splits"), sv_split_at_sv(&sv1, sep))); + cr_assert(sv_eq(sv_new(""), sv1)); +} + +Test(sv, aux) { + StringView elems[4] = { + sv_new("This"), + sv_new("Is"), + sv_new("A"), + sv_new("Test"), + }; + + char *out = sv_concat_with_sep(elems, 4, sv_new(" - ")); + + cr_assert_str_eq(out, "This - Is - A - Test"); + + free(out); +}