Added basic tests for SlsStr
This commit is contained in:
parent
beae4f0b9d
commit
2ec9d1d1a9
|
|
@ -37,6 +37,7 @@ typedef struct {
|
||||||
TestResult* tests;
|
TestResult* tests;
|
||||||
} TestsReport;
|
} TestsReport;
|
||||||
|
|
||||||
|
TestsReport run_string_tests();
|
||||||
TestsReport run_lexer_tests();
|
TestsReport run_lexer_tests();
|
||||||
|
|
||||||
#endif // SLS_TESTS_H
|
#endif // SLS_TESTS_H
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,224 @@
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
@ -22,7 +22,7 @@ typedef struct {
|
||||||
uint16_t total;
|
uint16_t total;
|
||||||
} TestCounts;
|
} TestCounts;
|
||||||
|
|
||||||
static void lexer_test_report(TestsReport reports, TestCounts *counts) {
|
static void test_report(TestsReport reports, TestCounts *counts) {
|
||||||
counts->total += reports.count;
|
counts->total += reports.count;
|
||||||
for (size_t i = 0; i < reports.count; i++) {
|
for (size_t i = 0; i < reports.count; i++) {
|
||||||
switch (reports.tests[i].status) {
|
switch (reports.tests[i].status) {
|
||||||
|
|
@ -78,8 +78,10 @@ int main(void) {
|
||||||
.total = 0,
|
.total = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
TestsReport lexer_reports = run_lexer_tests();
|
printf(" ===== SlsStr Tests =====\n");
|
||||||
lexer_test_report(lexer_reports, &counts);
|
test_report(run_string_tests(), &counts);
|
||||||
|
printf(" ===== Lexer Tests =====\n");
|
||||||
|
test_report(run_lexer_tests(), &counts);
|
||||||
|
|
||||||
printf(" ===== Tests Overview =====\n");
|
printf(" ===== Tests Overview =====\n");
|
||||||
if (counts.errored > 0)
|
if (counts.errored > 0)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue