colla/tests/str_tests.c
alessandro bason a66e58193f .
2025-06-24 17:47:08 +02:00

457 lines
11 KiB
C

#include "runner.h"
#include "../str.h"
#include "../arena.h"
#include <stdio.h>
// String (str_t) Tests
UNIT_TEST(str_init_basic) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
str_t s = str_init(&arena, "hello");
ASSERT(s.len == 5);
ASSERT(s.buf != NULL);
ASSERT(memcmp(s.buf, "hello", 5) == 0);
arena_cleanup(&arena);
}
UNIT_TEST(str_init_len) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
str_t s = str_init_len(&arena, "hello world", 5);
ASSERT(s.len == 5);
ASSERT(s.buf != NULL);
ASSERT(memcmp(s.buf, "hello", 5) == 0);
arena_cleanup(&arena);
}
UNIT_TEST(str_fmt) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
str_t s = str_fmt(&arena, "Number: %d, String: %s", 42, "test");
ASSERT(s.buf != NULL);
ASSERT(memcmp(s.buf, "Number: 42, String: test", s.len) == 0);
arena_cleanup(&arena);
}
UNIT_TEST(str_equals) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
str_t s1 = str_init(&arena, "hello");
str_t s2 = str_init(&arena, "hello");
str_t s3 = str_init(&arena, "world");
ASSERT(str_equals(s1, s2) == true);
ASSERT(str_equals(s1, s3) == false);
arena_cleanup(&arena);
}
UNIT_TEST(str_compare) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
str_t s1 = str_init(&arena, "abc");
str_t s2 = str_init(&arena, "abc");
str_t s3 = str_init(&arena, "abd");
str_t s4 = str_init(&arena, "abb");
ASSERT(str_compare(s1, s2) == 0);
ASSERT(str_compare(s1, s3) < 0);
ASSERT(str_compare(s1, s4) > 0);
arena_cleanup(&arena);
}
UNIT_TEST(str_dup) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
str_t s1 = str_init(&arena, "test");
str_t s2 = str_dup(&arena, s1);
ASSERT(s1.len == s2.len);
ASSERT(s1.buf != s2.buf); // Different memory locations
ASSERT(memcmp(s1.buf, s2.buf, s1.len) == 0);
arena_cleanup(&arena);
}
UNIT_TEST(str_cat) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
str_t s1 = str_init(&arena, "hello ");
str_t s2 = str_init(&arena, "world");
str_t s3 = str_cat(&arena, s1, s2);
ASSERT(s3.len == s1.len + s2.len);
ASSERT(memcmp(s3.buf, "hello world", s3.len) == 0);
arena_cleanup(&arena);
}
UNIT_TEST(str_is_empty) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
str_t s1 = str_init(&arena, "test");
str_t s2 = STR_EMPTY;
ASSERT(str_is_empty(s1) == false);
ASSERT(str_is_empty(s2) == true);
arena_cleanup(&arena);
}
UNIT_TEST(str_lower_upper) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
str_t s1 = str_init(&arena, "TeSt");
str_lower(&s1);
ASSERT(memcmp(s1.buf, "test", 4) == 0);
str_t s2 = str_init(&arena, "TeSt");
str_upper(&s2);
ASSERT(memcmp(s2.buf, "TEST", 4) == 0);
arena_cleanup(&arena);
}
UNIT_TEST(str_replace) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
str_t s = str_init(&arena, "hello");
str_replace(&s, 'l', 'x');
ASSERT(memcmp(s.buf, "hexxo", 5) == 0);
arena_cleanup(&arena);
}
UNIT_TEST(str_sub) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
str_t s = str_init(&arena, "hello world");
strview_t sv = str_sub(s, 6, 11);
ASSERT(sv.len == 5);
ASSERT(memcmp(sv.buf, "world", 5) == 0);
arena_cleanup(&arena);
}
// String View (strview_t) Tests
UNIT_TEST(strv_init) {
strview_t sv = strv_init("hello");
ASSERT(sv.len == 5);
ASSERT(sv.buf != NULL);
ASSERT(memcmp(sv.buf, "hello", 5) == 0);
}
UNIT_TEST(strv_init_len) {
strview_t sv = strv_init_len("hello world", 5);
ASSERT(sv.len == 5);
ASSERT(sv.buf != NULL);
ASSERT(memcmp(sv.buf, "hello", 5) == 0);
}
UNIT_TEST(strv_init_str) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
str_t s = str_init(&arena, "hello");
strview_t sv = strv_init_str(s);
ASSERT(sv.len == s.len);
ASSERT(sv.buf == s.buf);
arena_cleanup(&arena);
}
UNIT_TEST(strv_is_empty) {
strview_t sv1 = strv_init("test");
strview_t sv2 = STRV_EMPTY;
ASSERT(strv_is_empty(sv1) == false);
ASSERT(strv_is_empty(sv2) == true);
}
UNIT_TEST(strv_equals) {
strview_t sv1 = strv_init("hello");
strview_t sv2 = strv_init("hello");
strview_t sv3 = strv_init("world");
ASSERT(strv_equals(sv1, sv2) == true);
ASSERT(strv_equals(sv1, sv3) == false);
}
UNIT_TEST(strv_compare) {
strview_t sv1 = strv_init("abc");
strview_t sv2 = strv_init("abc");
strview_t sv3 = strv_init("abd");
strview_t sv4 = strv_init("abb");
ASSERT(strv_compare(sv1, sv2) == 0);
ASSERT(strv_compare(sv1, sv3) < 0);
ASSERT(strv_compare(sv1, sv4) > 0);
}
UNIT_TEST(strv_front_back) {
strview_t sv = strv_init("hello");
ASSERT(strv_front(sv) == 'h');
ASSERT(strv_back(sv) == 'o');
}
UNIT_TEST(strv_remove_prefix_suffix) {
strview_t sv = strv_init("hello");
strview_t prefix_removed = strv_remove_prefix(sv, 2);
ASSERT(prefix_removed.len == 3);
ASSERT(memcmp(prefix_removed.buf, "llo", 3) == 0);
strview_t suffix_removed = strv_remove_suffix(sv, 2);
ASSERT(suffix_removed.len == 3);
ASSERT(memcmp(suffix_removed.buf, "hel", 3) == 0);
}
UNIT_TEST(strv_trim) {
strview_t sv1 = strv_init(" hello ");
strview_t sv2 = strv_init(" hello");
strview_t sv3 = strv_init("hello ");
strview_t trimmed1 = strv_trim(sv1);
strview_t trimmed2 = strv_trim_left(sv2);
strview_t trimmed3 = strv_trim_right(sv3);
ASSERT(trimmed1.len == 5);
ASSERT(memcmp(trimmed1.buf, "hello", 5) == 0);
ASSERT(trimmed2.len == 5);
ASSERT(memcmp(trimmed2.buf, "hello", 5) == 0);
ASSERT(trimmed3.len == 5);
ASSERT(memcmp(trimmed3.buf, "hello", 5) == 0);
}
UNIT_TEST(strv_sub) {
strview_t sv = strv_init("hello world");
strview_t sub = strv_sub(sv, 6, 11);
ASSERT(sub.len == 5);
ASSERT(memcmp(sub.buf, "world", 5) == 0);
}
UNIT_TEST(strv_starts_ends_with) {
strview_t sv = strv_init("hello");
ASSERT(strv_starts_with(sv, 'h') == true);
ASSERT(strv_starts_with(sv, 'e') == false);
ASSERT(strv_ends_with(sv, 'o') == true);
ASSERT(strv_ends_with(sv, 'l') == false);
strview_t prefix = strv_init("hel");
strview_t suffix = strv_init("llo");
ASSERT(strv_starts_with_view(sv, prefix) == true);
ASSERT(strv_ends_with_view(sv, suffix) == true);
}
UNIT_TEST(strv_contains) {
strview_t sv = strv_init("hello world");
ASSERT(strv_contains(sv, 'e') == true);
ASSERT(strv_contains(sv, 'z') == false);
strview_t sub = strv_init("world");
ASSERT(strv_contains_view(sv, sub) == true);
strview_t chars = strv_init("xyz");
ASSERT(strv_contains_either(sv, chars) == false);
strview_t chars2 = strv_init("xyo");
ASSERT(strv_contains_either(sv, chars2) == true);
}
UNIT_TEST(strv_find) {
strview_t sv = strv_init("hello world");
ASSERT(strv_find(sv, 'o', 0) == 4);
ASSERT(strv_find(sv, 'o', 5) == 7);
ASSERT(strv_find(sv, 'z', 0) == STR_NONE);
strview_t sub = strv_init("world");
ASSERT(strv_find_view(sv, sub, 0) == 6);
strview_t chars = strv_init("xwo");
ASSERT(strv_find_either(sv, chars, 0) == 4); // 'w' at position 6
}
UNIT_TEST(strv_rfind) {
strview_t sv = strv_init("hello world");
ASSERT(strv_rfind(sv, 'o', 0) == 7);
ASSERT(strv_rfind(sv, 'o', 5) == 4);
ASSERT(strv_rfind(sv, 'z', 0) == STR_NONE);
strview_t sub = strv_init("world");
ASSERT(strv_rfind_view(sv, sub, 0) == 6);
}
// Character Functions Tests
UNIT_TEST(char_functions) {
ASSERT(char_is_space(' ') == true);
ASSERT(char_is_space('\t') == true);
ASSERT(char_is_space('a') == false);
ASSERT(char_is_alpha('a') == true);
ASSERT(char_is_alpha('Z') == true);
ASSERT(char_is_alpha('1') == false);
ASSERT(char_is_num('0') == true);
ASSERT(char_is_num('9') == true);
ASSERT(char_is_num('a') == false);
ASSERT(char_lower('A') == 'a');
ASSERT(char_lower('a') == 'a');
ASSERT(char_lower('1') == '1');
}
// Input Stream Tests
UNIT_TEST(instream_basic) {
strview_t sv = strv_init("hello world");
instream_t is = istr_init(sv);
ASSERT(istr_get(&is) == 'h');
ASSERT(istr_get(&is) == 'e');
ASSERT(istr_peek(&is) == 'l');
ASSERT(istr_peek_next(&is) == 'l');
ASSERT(istr_get(&is) == 'l');
ASSERT(istr_prev(&is) == 'l');
ASSERT(istr_prev_prev(&is) == 'e');
istr_skip(&is, 2);
ASSERT(istr_peek(&is) == ' ');
istr_skip_whitespace(&is);
ASSERT(istr_peek(&is) == 'w');
istr_rewind(&is);
ASSERT(istr_peek(&is) == 'h');
ASSERT(istr_tell(&is) == 0);
ASSERT(istr_remaining(&is) == 11);
ASSERT(istr_is_finished(&is) == false);
}
UNIT_TEST(instream_ignore) {
strview_t sv = strv_init("hello,world");
instream_t is = istr_init(sv);
istr_ignore(&is, ',');
ASSERT(istr_peek(&is) == ',');
istr_ignore_and_skip(&is, ',');
ASSERT(istr_peek(&is) == 'w');
}
UNIT_TEST(instream_get_values) {
strview_t sv = strv_init("true 42 3.14 hello");
instream_t is = istr_init(sv);
bool b;
ASSERT(istr_get_bool(&is, &b) == true);
ASSERT(b == true);
istr_skip_whitespace(&is);
u32 u;
ASSERT(istr_get_u32(&is, &u) == true);
ASSERT(u == 42);
istr_skip_whitespace(&is);
double d;
ASSERT(istr_get_num(&is, &d) == true);
ASSERT(d > 3.13 && d < 3.15);
istr_skip_whitespace(&is);
strview_t word = istr_get_view(&is, ' ');
ASSERT(word.len == 5);
ASSERT(memcmp(word.buf, "hello", 5) == 0);
}
// Output Stream Tests
UNIT_TEST(outstream_basic) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
outstream_t os = ostr_init(&arena);
ostr_putc(&os, 'h');
ostr_putc(&os, 'i');
ASSERT(ostr_tell(&os) == 2);
ASSERT(ostr_back(&os) == 'i');
ostr_print(&os, " %d", 42);
strview_t result = ostr_as_view(&os);
ASSERT(result.len == 5);
ASSERT(memcmp(result.buf, "hi 42", 5) == 0);
ostr_pop(&os, 3);
result = ostr_as_view(&os);
ASSERT(result.len == 2);
ASSERT(memcmp(result.buf, "hi", 2) == 0);
ostr_clear(&os);
ASSERT(ostr_tell(&os) == 0);
arena_cleanup(&arena);
}
UNIT_TEST(outstream_append) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
outstream_t os = ostr_init(&arena);
ostr_append_bool(&os, true);
ostr_putc(&os, ' ');
ostr_append_uint(&os, 42);
ostr_putc(&os, ' ');
ostr_append_int(&os, -10);
ostr_putc(&os, ' ');
ostr_append_num(&os, 3.14);
str_t result = ostr_to_str(&os);
ASSERT(result.len > 0);
arena_cleanup(&arena);
}
// Binary Input Stream Tests
UNIT_TEST(binary_stream) {
u8 data[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
buffer_t buffer = {data, sizeof(data)};
ibstream_t bs = ibstr_init(buffer);
ASSERT(ibstr_remaining(&bs) == 8);
ASSERT(ibstr_tell(&bs) == 0);
ASSERT(ibstr_is_finished(&bs) == false);
u8 val8;
ASSERT(ibstr_get_u8(&bs, &val8) == true);
ASSERT(val8 == 0x01);
u16 val16;
ASSERT(ibstr_get_u16(&bs, &val16) == true);
ASSERT(val16 == 0x0302); // Assuming little-endian
ibstr_skip(&bs, 1);
u32 val32;
ASSERT(ibstr_get_u32(&bs, &val32) == true);
ASSERT(val32 == 0x08070605); // Assuming little-endian
ASSERT(ibstr_is_finished(&bs) == true);
}