game/axl_string_test.c
2025-12-05 22:46:27 +03:00

779 lines
16 KiB
C

/*
* axl_string_tests.c — Unit tests for axl_string.h
*/
#include "axl_string.h"
#include "axl_koan.h"
#include "axl_memory.h"
KOAN(strlen_empty)
{
i8* s = (i8*)"";
ASSERT_UINT_EQ(0, axl_strlen(s));
}
KOAN(strlen_simple)
{
i8* s = (i8*)"hello";
ASSERT_UINT_EQ(5, axl_strlen(s));
}
KOAN(strlen_with_special_chars)
{
i8* s = (i8*)"hello\n\tworld";
ASSERT_UINT_EQ(12, axl_strlen(s));
}
KOAN(strlen_null)
{
ASSERT_UINT_EQ(0, axl_strlen(NULL));
}
KOAN(strcpy_basic)
{
i8* src = (i8*)"test";
i8* dst = (i8*)axl_malloc(10);
ASSERT_NOT_NULL(dst);
i8* result = axl_strcpy(dst, src);
ASSERT_PTR_EQ(dst, result);
ASSERT_STR_EQ("test", dst);
axl_free(dst);
}
KOAN(strcpy_empty)
{
i8* src = (i8*)"";
i8* dst = (i8*)axl_malloc(10);
ASSERT_NOT_NULL(dst);
axl_memset(dst, 0xFF, 10);
i8* result = axl_strcpy(dst, src);
ASSERT_PTR_EQ(dst, result);
ASSERT_STR_EQ("", dst);
axl_free(dst);
}
KOAN(strcpy_null_dst)
{
i8 buf[10];
ASSERT_PTR_EQ(buf, axl_strcpy(buf, NULL));
}
KOAN(strcpy_null_src)
{
ASSERT_NULL(axl_strcpy(NULL, "test"));
}
KOAN(strncpy_exact)
{
i8* src = (i8*)"hello";
i8* dst = (i8*)axl_malloc(10);
ASSERT_NOT_NULL(dst);
i8* result = axl_strncpy(dst, src, 5);
ASSERT_PTR_EQ(dst, result);
ASSERT_TRUE(memcmp(dst, "hello", 5) == 0);
axl_free(dst);
}
KOAN(strncpy_truncates)
{
i8* src = (i8*)"hello world";
i8* dst = (i8*)axl_malloc(10);
ASSERT_NOT_NULL(dst);
i8* result = axl_strncpy(dst, src, 5);
ASSERT_PTR_EQ(dst, result);
ASSERT_TRUE(memcmp(dst, "hello", 5) == 0);
axl_free(dst);
}
KOAN(strncpy_pads_with_nulls)
{
i8* src = (i8*)"hi";
i8* dst = (i8*)axl_malloc(10);
ASSERT_NOT_NULL(dst);
axl_memset(dst, 0xFF, 10);
i8* result = axl_strncpy(dst, src, 5);
ASSERT_PTR_EQ(dst, result);
ASSERT_TRUE(memcmp(dst, "hi\0\0\0", 5) == 0);
axl_free(dst);
}
KOAN(strncpy_zero_n)
{
i8 dst[10] = {'w'};
axl_strncpy(dst, (const i8*)"test", 0);
ASSERT_INT_EQ('w', dst[0]);
}
KOAN(strncpy_embedded_null)
{
i8* dst = (i8*)axl_malloc(10);
i8* src = (i8*)"ab\0cde";
axl_strncpy(dst, src, 5);
ASSERT_TRUE(memcmp(dst, "ab\0\0\0", 5) == 0);
axl_free(dst);
}
KOAN(strcat_basic)
{
i8* dst = (i8*)axl_malloc(20);
ASSERT_NOT_NULL(dst);
axl_strcpy(dst, (i8*)"hello ");
i8* result = axl_strcat(dst, (i8*)"world");
ASSERT_PTR_EQ(dst, result);
ASSERT_STR_EQ("hello world", dst);
axl_free(dst);
}
KOAN(strcat_to_empty)
{
i8* dst = (i8*)axl_malloc(20);
ASSERT_NOT_NULL(dst);
axl_strcpy(dst, (i8*)"");
i8* result = axl_strcat(dst, (i8*)"test");
ASSERT_PTR_EQ(dst, result);
ASSERT_STR_EQ("test", dst);
axl_free(dst);
}
KOAN(strncat_full)
{
i8* dst = (i8*)axl_malloc(20);
ASSERT_NOT_NULL(dst);
axl_strcpy(dst, (i8*)"hello ");
i8* result = axl_strncat(dst, (i8*)"world", 5);
ASSERT_PTR_EQ(dst, result);
ASSERT_STR_EQ("hello world", dst);
axl_free(dst);
}
KOAN(strncat_partial)
{
i8* dst = (i8*)axl_malloc(20);
ASSERT_NOT_NULL(dst);
axl_strcpy(dst, (i8*)"hello ");
i8* result = axl_strncat(dst, (i8*)"worldwide", 5);
ASSERT_PTR_EQ(dst, result);
ASSERT_STR_EQ("hello world", dst);
axl_free(dst);
}
KOAN(strncat_always_null_terminates)
{
i8* dst = (i8*)axl_malloc(20);
ASSERT_NOT_NULL(dst);
axl_strcpy(dst, (i8*)"test");
i8* result = axl_strncat(dst, (i8*)"123456789", 3);
ASSERT_PTR_EQ(dst, result);
ASSERT_STR_EQ("test123", dst);
ASSERT_INT_EQ(0, (int)dst[7]);
axl_free(dst);
}
KOAN(strncat_zero_n)
{
i8 dst[10] = "hi";
axl_strncat(dst, (const i8*)"world", 0);
ASSERT_STR_EQ("hi", dst);
}
KOAN(strcmp_equal)
{
i8* s1 = (i8*)"hello";
i8* s2 = (i8*)"hello";
ASSERT_INT_EQ(0, axl_strcmp(s1, s2));
}
KOAN(strcmp_less)
{
i8* s1 = (i8*)"abc";
i8* s2 = (i8*)"def";
ASSERT_TRUE(axl_strcmp(s1, s2) < 0);
}
KOAN(strcmp_greater)
{
i8* s1 = (i8*)"xyz";
i8* s2 = (i8*)"abc";
ASSERT_TRUE(axl_strcmp(s1, s2) > 0);
}
KOAN(strcmp_prefix)
{
i8* s1 = (i8*)"test";
i8* s2 = (i8*)"testing";
ASSERT_TRUE(axl_strcmp(s1, s2) < 0);
}
KOAN(strcmp_both_empty)
{
i8* s1 = (i8*)"";
i8* s2 = (i8*)"";
ASSERT_INT_EQ(0, axl_strcmp(s1, s2));
}
KOAN(strcmp_first_empty)
{
i8* s1 = (i8*)"";
i8* s2 = (i8*)"hello";
ASSERT_TRUE(axl_strcmp(s1, s2) < 0);
}
KOAN(strncmp_equal_shorter_n)
{
i8* s1 = (i8*)"hello";
i8* s2 = (i8*)"help!";
ASSERT_INT_EQ(0, axl_strncmp(s1, s2, 3));
}
KOAN(strncmp_equal_longer_n)
{
i8* s1 = (i8*)"test";
i8* s2 = (i8*)"test";
ASSERT_INT_EQ(0, axl_strncmp(s1, s2, 10));
}
KOAN(strncmp_differs_at_n)
{
i8* s1 = (i8*)"hello";
i8* s2 = (i8*)"helma";
ASSERT_TRUE(axl_strncmp(s1, s2, 5) < 0);
}
KOAN(strncmp_zero_n)
{
i8* s1 = (i8*)"hello";
i8* s2 = (i8*)"world";
ASSERT_INT_EQ(0, axl_strncmp(s1, s2, 0));
}
KOAN(strncmp_null_ptrs)
{
ASSERT_INT_EQ(0, axl_strncmp(NULL, NULL, 5));
ASSERT_TRUE(axl_strncmp(NULL, (i8*)"test", 5) < 0);
ASSERT_TRUE(axl_strncmp((i8*)"test", NULL, 5) > 0);
}
KOAN(strchr_null)
{
ASSERT_NULL(axl_strchr(NULL, 'a'));
}
KOAN(strchr_empty)
{
i8 str[] = "";
ASSERT_NULL(axl_strchr(str, 'a'));
}
KOAN(strchr_not_found)
{
i8 str[] = "hello";
ASSERT_NULL(axl_strchr(str, 'x'));
}
KOAN(strchr_first_char)
{
i8 str[] = "hello";
ASSERT_PTR_EQ(str, axl_strchr(str, 'h'));
}
KOAN(strchr_last_char)
{
i8 str[] = "hello";
ASSERT_PTR_EQ(str + 4, axl_strchr(str, 'o'));
}
KOAN(strchr_null_terminator)
{
i8 str[] = "hello";
ASSERT_PTR_EQ(str + 5, axl_strchr(str, '\0'));
}
KOAN(strchr_returns_proper_ptr)
{
i8 str[] = "hi Mark";
ASSERT_PTR_EQ(str + 0, axl_strchr(str, 'h'));
ASSERT_PTR_EQ(str + 1, axl_strchr(str, 'i'));
ASSERT_PTR_EQ(str + 2, axl_strchr(str, ' '));
ASSERT_PTR_EQ(str + 3, axl_strchr(str, 'M'));
ASSERT_PTR_EQ(str + 4, axl_strchr(str, 'a'));
ASSERT_PTR_EQ(str + 5, axl_strchr(str, 'r'));
ASSERT_PTR_EQ(str + 6, axl_strchr(str, 'k'));
ASSERT_NULL(axl_strchr(str, 'm'));
ASSERT_PTR_EQ(str + 7, axl_strchr(str, '\0'));
}
KOAN(strstr_null_pointer)
{
ASSERT_NULL(axl_strstr(NULL, "test"));
ASSERT_NULL(axl_strstr("test", NULL));
ASSERT_NULL(axl_strstr(NULL, NULL));
}
KOAN(strstr_empty_string)
{
i8 str[] = "";
ASSERT_NULL(axl_strstr(str, "test"));
ASSERT_PTR_EQ(str, axl_strstr(str, ""));
}
KOAN(strstr_empty_substring)
{
i8 str[] = "hello world";
ASSERT_PTR_EQ(str, axl_strstr(str, ""));
}
KOAN(strstr_exact_match)
{
i8 str[] = "hello world";
ASSERT_PTR_EQ(str, axl_strstr(str, "hello world"));
}
KOAN(strstr_prefix_match)
{
i8 str[] = "hello world";
ASSERT_PTR_EQ(str, axl_strstr(str, "hello"));
}
KOAN(strstr_suffix_match)
{
i8 str[] = "hello world";
ASSERT_PTR_EQ(str + 6, axl_strstr(str, "world"));
}
KOAN(strstr_middle_match)
{
i8 str[] = "hello world";
ASSERT_PTR_EQ(str + 2, axl_strstr(str, "llo"));
}
KOAN(strstr_single_char_match)
{
i8 str[] = "hello world";
ASSERT_PTR_EQ(str + 4, axl_strstr(str, "o"));
}
KOAN(strstr_multiple_occurrences)
{
i8 str[] = "hello world";
ASSERT_PTR_EQ(str + 4, axl_strstr(str, "o"));
}
KOAN(strstr_not_found)
{
i8 str[] = "hello world";
ASSERT_NULL(axl_strstr(str, "xyz"));
ASSERT_NULL(axl_strstr(str, "hello!"));
ASSERT_NULL(axl_strstr(str, "world!"));
}
KOAN(strstr_partial_match_but_not_full)
{
i8 str[] = "hello world";
ASSERT_NULL(axl_strstr(str, "helloo"));
ASSERT_NULL(axl_strstr(str, "worldd"));
}
KOAN(strstr_case_sensitive)
{
i8 str[] = "Hello World";
ASSERT_NULL(axl_strstr(str, "hello"));
ASSERT_NULL(axl_strstr(str, "world"));
ASSERT_PTR_EQ(str, axl_strstr(str, "Hello"));
ASSERT_PTR_EQ(str + 6, axl_strstr(str, "World"));
}
KOAN(strstr_with_null_bytes)
{
i8 str[] = "ab\0cde";
ASSERT_PTR_EQ(str, axl_strstr(str, "ab"));
ASSERT_NULL(axl_strstr(str, "cde"));
}
KOAN(strstr_longer_substring_than_string)
{
i8 str[] = "short";
ASSERT_NULL(axl_strstr(str, "longer string"));
}
KOAN(strstr_repeated_pattern)
{
i8 str[] = "ababab";
ASSERT_PTR_EQ(str, axl_strstr(str, "ab"));
ASSERT_PTR_EQ(str + 1, axl_strstr(str, "baba"));
}
KOAN(strstr_overlapping_match)
{
i8 str[] = "aaaaa";
ASSERT_PTR_EQ(str, axl_strstr(str, "aa"));
ASSERT_PTR_EQ(str, axl_strstr(str, "aaa"));
ASSERT_PTR_EQ(str, axl_strstr(str, "aaaa"));
ASSERT_PTR_EQ(str, axl_strstr(str, "aaaaa"));
}
KOAN(strstr_special_chars)
{
i8 str[] = "hello\tworld\n";
ASSERT_PTR_EQ(str, axl_strstr(str, "hello"));
ASSERT_PTR_EQ(str + 6, axl_strstr(str, "world"));
ASSERT_PTR_EQ(str + 5, axl_strstr(str, "\t"));
ASSERT_PTR_EQ(str + 11, axl_strstr(str, "\n"));
}
KOAN(strrev_null)
{
ASSERT_NULL(axl_strrev(NULL));
}
KOAN(strrev_empty)
{
i8 str[] = "";
i8* result = axl_strrev(str);
ASSERT_PTR_EQ(str, result);
ASSERT_STR_EQ("", str);
}
KOAN(strrev_single_char)
{
i8 str[] = "a";
i8* result = axl_strrev(str);
ASSERT_PTR_EQ(str, result);
ASSERT_STR_EQ("a", str);
}
KOAN(strrev_two_chars)
{
i8 str[] = "ab";
i8* result = axl_strrev(str);
ASSERT_PTR_EQ(str, result);
ASSERT_STR_EQ("ba", str);
}
KOAN(strrev_odd_length)
{
i8 str[] = "hello";
i8* result = axl_strrev(str);
ASSERT_PTR_EQ(str, result);
ASSERT_STR_EQ("olleh", str);
}
KOAN(strrev_even_length)
{
i8 str[] = "world";
i8* result = axl_strrev(str);
ASSERT_PTR_EQ(str, result);
ASSERT_STR_EQ("dlrow", str);
}
KOAN(strrev_palindrome)
{
i8 str[] = "racecar";
i8* result = axl_strrev(str);
ASSERT_PTR_EQ(str, result);
ASSERT_STR_EQ("racecar", str);
}
KOAN(strrev_with_spaces)
{
i8 str[] = "hello world";
i8* result = axl_strrev(str);
ASSERT_PTR_EQ(str, result);
ASSERT_STR_EQ("dlrow olleh", str);
}
KOAN(strrev_with_special_chars)
{
i8 str[] = "a\nb\tc";
i8* result = axl_strrev(str);
ASSERT_PTR_EQ(str, result);
ASSERT_STR_EQ("c\tb\na", str);
}
KOAN(strrev_numbers)
{
i8 str[] = "123456789";
i8* result = axl_strrev(str);
ASSERT_PTR_EQ(str, result);
ASSERT_STR_EQ("987654321", str);
}
KOAN(strrev_mixed)
{
i8 str[] = "a1b2c3";
i8* result = axl_strrev(str);
ASSERT_PTR_EQ(str, result);
ASSERT_STR_EQ("3c2b1a", str);
}
KOAN(strrev_long_string)
{
i8 str[] = "abcdefghijklmnopqrstuvwxyz";
i8* result = axl_strrev(str);
ASSERT_PTR_EQ(str, result);
ASSERT_STR_EQ("zyxwvutsrqponmlkjihgfedcba", str);
}
KOAN(strrev_in_place)
{
i8 str[] = "test";
i8* original_ptr = str;
i8* result = axl_strrev(str);
ASSERT_PTR_EQ(original_ptr, result);
ASSERT_STR_EQ("tset", str);
// Reverse again to get back original
result = axl_strrev(str);
ASSERT_PTR_EQ(original_ptr, result);
ASSERT_STR_EQ("test", str);
}
KOAN(utoa_decimal_zero)
{
i8 buffer[32];
i8* result = axl_utoa(0, buffer, 10);
ASSERT_PTR_EQ(buffer, result);
ASSERT_STR_EQ("0", buffer);
}
KOAN(utoa_decimal_small)
{
i8 buffer[32];
i8* result = axl_utoa(42, buffer, 10);
ASSERT_PTR_EQ(buffer, result);
ASSERT_STR_EQ("42", buffer);
}
KOAN(utoa_decimal_large)
{
i8 buffer[32];
i8* result = axl_utoa(4294967295U, buffer, 10);
ASSERT_PTR_EQ(buffer, result);
ASSERT_STR_EQ("4294967295", buffer);
}
KOAN(utoa_binary)
{
i8 buffer[32];
i8* result = axl_utoa(10, buffer, 2);
ASSERT_PTR_EQ(buffer, result);
ASSERT_STR_EQ("1010", buffer);
}
KOAN(utoa_octal)
{
i8 buffer[32];
i8* result = axl_utoa(255, buffer, 8);
ASSERT_PTR_EQ(buffer, result);
ASSERT_STR_EQ("377", buffer);
}
KOAN(utoa_hexadecimal_lowercase)
{
i8 buffer[32];
i8* result = axl_utoa(0xDEADBEEF, buffer, 16);
ASSERT_PTR_EQ(buffer, result);
ASSERT_STR_EQ("DEADBEEF", buffer);
}
KOAN(utoa_hexadecimal_uppercase)
{
i8 buffer[32];
i8* result = axl_utoa(0xCAFEBABE, buffer, 16);
ASSERT_PTR_EQ(buffer, result);
// Note: implementation should produce lowercase by default
// If uppercase is needed, we'd need a separate function
ASSERT_STR_EQ("CAFEBABE", buffer);
}
KOAN(utoa_base_36)
{
i8 buffer[32];
i8* result = axl_utoa(123456789, buffer, 36);
ASSERT_PTR_EQ(buffer, result);
ASSERT_STR_EQ("21I3V9", buffer);
}
KOAN(utoa_max_base)
{
i8 buffer[32];
i8* result = axl_utoa(35, buffer, 36);
ASSERT_PTR_EQ(buffer, result);
ASSERT_STR_EQ("Z", buffer);
}
KOAN(itoa_positive)
{
i8 buffer[32];
i8* result = axl_itoa(12345, buffer, 10);
ASSERT_PTR_EQ(buffer, result);
ASSERT_STR_EQ("12345", buffer);
}
KOAN(itoa_negative)
{
i8 buffer[32];
i8* result = axl_itoa(-12345, buffer, 10);
ASSERT_PTR_EQ(buffer, result);
ASSERT_STR_EQ("-12345", buffer);
}
KOAN(itoa_zero)
{
i8 buffer[32];
i8* result = axl_itoa(0, buffer, 10);
ASSERT_PTR_EQ(buffer, result);
ASSERT_STR_EQ("0", buffer);
}
KOAN(itoa_min_int)
{
i8 buffer[32];
i8* result = axl_itoa(-9223372036854775807LL - 1, buffer, 10);
ASSERT_PTR_EQ(buffer, result);
ASSERT_STR_EQ("-9223372036854775808", buffer);
}
KOAN(itoa_max_int)
{
i8 buffer[32];
i8* result = axl_itoa(9223372036854775807LL, buffer, 10);
ASSERT_PTR_EQ(buffer, result);
ASSERT_STR_EQ("9223372036854775807", buffer);
}
KOAN(itoa_negative_binary)
{
i8 buffer[32];
i8* result = axl_itoa(-10, buffer, 2);
ASSERT_PTR_EQ(buffer, result);
ASSERT_STR_EQ("-1010", buffer);
}
KOAN(itoa_negative_hex)
{
i8 buffer[32];
i8* result = axl_itoa(-0xDEAD, buffer, 16);
ASSERT_PTR_EQ(buffer, result);
ASSERT_STR_EQ("-DEAD", buffer);
}
KOAN(itoa_positive_octal)
{
i8 buffer[32];
i8* result = axl_itoa(511, buffer, 8);
ASSERT_PTR_EQ(buffer, result);
ASSERT_STR_EQ("777", buffer);
}
KOAN(itoa_negative_octal)
{
i8 buffer[32];
i8* result = axl_itoa(-511, buffer, 8);
ASSERT_PTR_EQ(buffer, result);
ASSERT_STR_EQ("-777", buffer);
}
KOAN(itoa_base_36_positive)
{
i8 buffer[32];
i8* result = axl_itoa(123456789, buffer, 36);
ASSERT_PTR_EQ(buffer, result);
ASSERT_STR_EQ("21I3V9", buffer);
}
KOAN(itoa_base_36_negative)
{
i8 buffer[32];
i8* result = axl_itoa(-123456789, buffer, 36);
ASSERT_PTR_EQ(buffer, result);
ASSERT_STR_EQ("-21I3V9", buffer);
}
KOAN(utoa_buffer_reuse)
{
i8 buffer[32];
i8* result1 = axl_utoa(123, buffer, 10);
ASSERT_PTR_EQ(buffer, result1);
ASSERT_STR_EQ("123", buffer);
i8* result2 = axl_utoa(456, buffer, 10);
ASSERT_PTR_EQ(buffer, result2);
ASSERT_STR_EQ("456", buffer);
}
KOAN(itoa_buffer_reuse)
{
i8 buffer[32];
i8* result1 = axl_itoa(-123, buffer, 10);
ASSERT_PTR_EQ(buffer, result1);
ASSERT_STR_EQ("-123", buffer);
i8* result2 = axl_itoa(456, buffer, 10);
ASSERT_PTR_EQ(buffer, result2);
ASSERT_STR_EQ("456", buffer);
}
KOAN(utoa_edge_cases)
{
i8 buffer[32];
// Test with base 2 (binary)
i8* result1 = axl_utoa(42, buffer, 2);
ASSERT_PTR_EQ(buffer, result1);
ASSERT_STR_EQ("101010", buffer);
// Test with base 8 (octal)
i8* result2 = axl_utoa(777, buffer, 8);
ASSERT_PTR_EQ(buffer, result2);
ASSERT_STR_EQ("1411", buffer);
// Test with base 16 (hex)
i8* result3 = axl_utoa(0xABCD, buffer, 16);
ASSERT_PTR_EQ(buffer, result3);
ASSERT_STR_EQ("ABCD", buffer);
}
KOAN(itoa_edge_cases)
{
i8 buffer[32];
// Test positive to negative transition
i8* result1 = axl_itoa(1, buffer, 10);
ASSERT_PTR_EQ(buffer, result1);
ASSERT_STR_EQ("1", buffer);
i8* result2 = axl_itoa(-1, buffer, 10);
ASSERT_PTR_EQ(buffer, result2);
ASSERT_STR_EQ("-1", buffer);
// Test zero stays zero
i8* result3 = axl_itoa(0, buffer, 10);
ASSERT_PTR_EQ(buffer, result3);
ASSERT_STR_EQ("0", buffer);
}
int main(void)
{
axl_init();
return koan_run_all();
}