457 lines
11 KiB
C
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);
|
|
}
|