225 lines
7.9 KiB
C
225 lines
7.9 KiB
C
// Kyler Olsen
|
|
// YREA SLS
|
|
// String Tests
|
|
// November 2025
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdint.h>
|
|
|
|
#include "sls/string.h"
|
|
#include "sls/lexer.h"
|
|
#include "sls/errors.h"
|
|
#include "tests/tests.h"
|
|
|
|
static const size_t NUM_STRING_TESTS = 10;
|
|
|
|
static TestResult pass_string_test(SlsStr test_name) {
|
|
TestResult result = {.name = test_name, .status = TEST_NOT_IMPLEMENTED};
|
|
result.status = TEST_PASS;
|
|
return result;
|
|
}
|
|
|
|
static TestResult fail_string_test(SlsStr test_name, SlsStr message) {
|
|
TestResult result = { .name = test_name, .status = TEST_NOT_IMPLEMENTED };
|
|
result.status = TEST_ERROR;
|
|
result.message = sls_str_cpy(message);
|
|
|
|
if (result.message.str == NULL) {
|
|
result.error = (SlsError){ SLS_STR("Out Of Memory Error."), 1 };
|
|
result.status = TEST_ERROR;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// Test sls_str_malloc and sls_str_cpy
|
|
static TestResult test_malloc_and_copy() {
|
|
const char* original = "Hello, SLS!";
|
|
SlsStr s = sls_str_malloc(original, strlen(original));
|
|
if (!s.str) return fail_string_test(SLS_STR("test_malloc_and_copy"), SLS_STR("Allocation failed"));
|
|
|
|
if (strcmp(s.str, original) != 0) {
|
|
sls_str_free(&s);
|
|
return fail_string_test(SLS_STR("test_malloc_and_copy"), SLS_STR("Copied string mismatch"));
|
|
}
|
|
|
|
SlsStr copy = sls_str_cpy(s);
|
|
if (!copy.str || strcmp(copy.str, original) != 0) {
|
|
sls_str_free(&s);
|
|
sls_str_free(©);
|
|
return fail_string_test(SLS_STR("test_malloc_and_copy"), SLS_STR("sls_str_cpy failed"));
|
|
}
|
|
|
|
sls_str_free(&s);
|
|
sls_str_free(©);
|
|
return pass_string_test(SLS_STR("test_malloc_and_copy"));
|
|
}
|
|
|
|
// Test sls_str_cmp
|
|
static TestResult test_compare_strings() {
|
|
SlsStr a = sls_str_malloc("abc", 3);
|
|
SlsStr b = sls_str_malloc("abc", 3);
|
|
SlsStr c = sls_str_malloc("abd", 3);
|
|
|
|
if (sls_str_cmp(a, b) != 0) goto fail;
|
|
if (sls_str_cmp(a, c) >= 0) goto fail;
|
|
if (sls_str_cmp(c, a) <= 0) goto fail;
|
|
|
|
sls_str_free(&a);
|
|
sls_str_free(&b);
|
|
sls_str_free(&c);
|
|
return pass_string_test(SLS_STR("test_compare_strings"));
|
|
|
|
fail:
|
|
sls_str_free(&a);
|
|
sls_str_free(&b);
|
|
sls_str_free(&c);
|
|
return fail_string_test(SLS_STR("test_compare_strings"), SLS_STR("Comparison test failed"));
|
|
}
|
|
|
|
// Test sls_format for basic placeholders
|
|
static TestResult test_format_basic_placeholders() {
|
|
SlsStr fmt = SLS_STR("Char: %c, Int: %d, Long: %l, Unsigned: %u, Size: %z, Float: %f, C-String: %y");
|
|
const char *s = "Test";
|
|
SlsStr result = sls_format(fmt, 'X', -42, (int64_t)1234567890123, (uint64_t)9876543210, (size_t)1024, 3.14, s);
|
|
|
|
if (!result.str) return fail_string_test(SLS_STR("test_format_basic_placeholders"), SLS_STR("Formatting returned NULL"));
|
|
|
|
const char* expected = "Char: X, Int: -42, Long: 1234567890123, Unsigned: 9876543210, Size: 1024, Float: 3.14, C-String: Test";
|
|
if (strcmp(result.str, expected) != 0) {
|
|
sls_str_free(&result);
|
|
return fail_string_test(SLS_STR("test_format_basic_placeholders"), SLS_STR("Formatted string mismatch"));
|
|
}
|
|
|
|
sls_str_free(&result);
|
|
return pass_string_test(SLS_STR("test_format_basic_placeholders"));
|
|
}
|
|
|
|
// Test sls_format for SLS types: %s, %t, %a, %i, %e, %b
|
|
static TestResult test_format_sls_types() {
|
|
// Placeholder values
|
|
SlsStr sls_str_val = SLS_STR("SLS_STRING");
|
|
TokenType tok = 0; // Assuming TOKEN_TYPES_NAMES[0] exists
|
|
ArrayType arr = 0; // Assuming ARRAY_TYPES_NAMES[0] exists
|
|
IntegerBuiltInType ib = 0; // Assuming INTEGER_TYPES_NAMES[0] exists
|
|
SlsError err = {SLS_STR("ErrorMessage"), 1};
|
|
Boolean boolean_true = TRUE;
|
|
|
|
SlsStr fmt = SLS_STR("Str:%s Tok:%t Arr:%a IntType:%i Err:%e Bool:%b");
|
|
SlsStr result = sls_format(fmt, sls_str_val, tok, arr, ib, err, boolean_true);
|
|
|
|
if (!result.str) return fail_string_test(SLS_STR("test_format_sls_types"), SLS_STR("Formatting returned NULL"));
|
|
|
|
char expected[256];
|
|
snprintf(expected, 256, "Str:%s Tok:%s Arr:%s IntType:%s Err:%s Bool:TRUE",
|
|
sls_str_val.str,
|
|
TOKEN_TYPES_NAMES[tok],
|
|
ARRAY_TYPES_NAMES[arr],
|
|
INTEGER_TYPES_NAMES[ib],
|
|
err.message.str);
|
|
|
|
if (strcmp(result.str, expected) != 0) {
|
|
sls_str_free(&result);
|
|
return fail_string_test(SLS_STR("test_format_sls_types"), SLS_STR("Formatted string mismatch for SLS types"));
|
|
}
|
|
|
|
sls_str_free(&result);
|
|
return pass_string_test(SLS_STR("test_format_sls_types"));
|
|
}
|
|
|
|
// Test sls_format with %% escape
|
|
static TestResult test_format_percent_escape() {
|
|
SlsStr fmt = SLS_STR("Progress: 100%% complete");
|
|
SlsStr result = sls_format(fmt);
|
|
|
|
if (!result.str) return fail_string_test(SLS_STR("test_format_percent_escape"), SLS_STR("Formatting returned NULL"));
|
|
if (strcmp(result.str, "Progress: 100% complete") != 0) {
|
|
sls_str_free(&result);
|
|
return fail_string_test(SLS_STR("test_format_percent_escape"), SLS_STR("Percent escape failed"));
|
|
}
|
|
|
|
sls_str_free(&result);
|
|
return pass_string_test(SLS_STR("test_format_percent_escape"));
|
|
}
|
|
|
|
// Test sls_str_new allocation and zero-init
|
|
static TestResult test_new_string_allocation() {
|
|
SlsStr s = sls_str_new(10);
|
|
if (!s.str) return fail_string_test(SLS_STR("test_new_string_allocation"), SLS_STR("Allocation failed"));
|
|
|
|
for (size_t i = 0; i < s.len; i++) {
|
|
if (s.str[i] != 0) {
|
|
sls_str_free(&s);
|
|
return fail_string_test(SLS_STR("test_new_string_allocation"), SLS_STR("Memory not zero-initialized"));
|
|
}
|
|
}
|
|
|
|
sls_str_free(&s);
|
|
return pass_string_test(SLS_STR("test_new_string_allocation"));
|
|
}
|
|
|
|
// Test empty string
|
|
static TestResult test_empty_string() {
|
|
SlsStr s = sls_str_malloc("", 0);
|
|
if (!s.str || s.len != 0) return fail_string_test(SLS_STR("test_empty_string"), SLS_STR("Empty string allocation failed"));
|
|
sls_str_free(&s);
|
|
return pass_string_test(SLS_STR("test_empty_string"));
|
|
}
|
|
|
|
// Test long string
|
|
static TestResult test_long_string() {
|
|
size_t len = 1024;
|
|
char* long_str = malloc(len + 1);
|
|
for (size_t i = 0; i < len; i++) long_str[i] = 'A';
|
|
long_str[len] = '\0';
|
|
|
|
SlsStr s = sls_str_malloc(long_str, len);
|
|
if (!s.str || s.len != len) {
|
|
free(long_str);
|
|
return fail_string_test(SLS_STR("test_long_string"), SLS_STR("Long string allocation failed"));
|
|
}
|
|
|
|
sls_str_free(&s);
|
|
free(long_str);
|
|
return pass_string_test(SLS_STR("test_long_string"));
|
|
}
|
|
|
|
// Test NULL pointer handling in sls_str_free
|
|
static TestResult test_free_null() {
|
|
SlsStr s = SLS_STR_NULL;
|
|
sls_str_free(&s); // Should safely do nothing
|
|
return pass_string_test(SLS_STR("test_free_null"));
|
|
}
|
|
|
|
// Test sls_str_nlen edge cases
|
|
static TestResult test_str_nlen_edge() {
|
|
const char* str = "ABCDE";
|
|
if (sls_str_nlen(str, 0) != 0) return fail_string_test(SLS_STR("test_str_nlen_edge"), SLS_STR("Maxlen=0 failed"));
|
|
if (sls_str_nlen(str, 3) != 3) return fail_string_test(SLS_STR("test_str_nlen_edge"), SLS_STR("Maxlen=3 failed"));
|
|
if (sls_str_nlen(str, 10) != 5) return fail_string_test(SLS_STR("test_str_nlen_edge"), SLS_STR("Maxlen>strlen failed"));
|
|
return pass_string_test(SLS_STR("test_str_nlen_edge"));
|
|
}
|
|
|
|
// Run all string tests
|
|
TestsReport run_string_tests() {
|
|
TestsReport report = {
|
|
.section = SLS_STR("string_tests"),
|
|
.count = NUM_STRING_TESTS,
|
|
.tests = malloc(sizeof(TestResult) * NUM_STRING_TESTS)
|
|
};
|
|
|
|
size_t i = 0;
|
|
report.tests[i++] = test_malloc_and_copy();
|
|
report.tests[i++] = test_compare_strings();
|
|
report.tests[i++] = test_format_basic_placeholders();
|
|
report.tests[i++] = test_format_sls_types();
|
|
report.tests[i++] = test_format_percent_escape();
|
|
report.tests[i++] = test_new_string_allocation();
|
|
report.tests[i++] = test_empty_string();
|
|
report.tests[i++] = test_long_string();
|
|
report.tests[i++] = test_free_null();
|
|
report.tests[i++] = test_str_nlen_edge();
|
|
return report;
|
|
}
|