String.h
Some checks failed
Build Dusk / run-tests (push) Successful in 2m2s
Build Dusk / build-linux (push) Successful in 2m1s
Build Dusk / build-psp (push) Failing after 1m21s

This commit is contained in:
2026-01-05 17:20:17 -06:00
parent a793ac2ff7
commit 83b799caa8
7 changed files with 1007 additions and 18 deletions

871
test/util/test_string.c Normal file
View File

@@ -0,0 +1,871 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "dusktest.h"
#include "util/string.h"
static void test_stringIsWhitespace(void **state) {
(void)state;
assert_true(stringIsWhitespace(' ')); // Space is whitespace
assert_true(stringIsWhitespace('\t')); // Tab is whitespace
assert_true(stringIsWhitespace('\n')); // Newline is whitespace
assert_true(stringIsWhitespace('\r')); // Carriage return is whitespace
assert_true(stringIsWhitespace('\v')); // Vertical tab is whitespace
assert_true(stringIsWhitespace('\f')); // Form feed is whitespace
assert_false(stringIsWhitespace('A')); // 'A' is not whitespace
assert_false(stringIsWhitespace('1')); // '1' is not whitespace
assert_false(stringIsWhitespace('_')); // '_' is not whitespace
assert_false(stringIsWhitespace('-')); // '-' is not whitespace
}
static void test_stringCopy(void **state) {
(void)state;
char dest[16];
stringCopy(dest, "hello", sizeof(dest));
assert_string_equal(dest, "hello"); // Normal copy
// Empty string
stringCopy(dest, "", sizeof(dest));
assert_string_equal(dest, ""); // Should copy empty string
// Euffer just fits
stringCopy(dest, "123456789012345", 16); // 15 chars + null
assert_string_equal(dest, "123456789012345"); // Should fit exactly
// Cannot copy from NULL source
expect_assert_failure(stringCopy(dest, NULL, sizeof(dest)));
// Cannot copy to NULL destination
expect_assert_failure(stringCopy(NULL, "hello", sizeof(dest)));
// Must have destSize > 0
expect_assert_failure(stringCopy(dest, "hello", 0));
// Must have destSize large enough for source
expect_assert_failure(stringCopy(dest, "this string is too long", 10));
}
static void test_stringCompare(void **state) {
(void)state;
// Check for equality
assert_int_equal(stringCompare("abc", "abc"), 0);
assert_int_equal(stringCompare("", ""), 0);
assert_int_equal(stringCompare("a", "a"), 0);
assert_int_equal(stringCompare("longer string", "longer string"), 0);
// Check for less than cases
assert_true(stringCompare("", "a") < 0);
assert_true(stringCompare("abc", "abd") < 0);
// Check for greater than cases
assert_true(stringCompare("abd", "abc") > 0);
assert_true(stringCompare("a", "") > 0);
// Cannot compare NULL strings
expect_assert_failure(stringCompare(NULL, "abc"));
expect_assert_failure(stringCompare("abc", NULL));
}
static void test_stringCompareInsensitive(void **state) {
(void)state;
assert_int_equal(stringCompareInsensitive("abc", "ABC"), 0);
assert_true(stringCompareInsensitive("abc", "abd") < 0);
assert_true(stringCompareInsensitive("abd", "abc") > 0);
assert_true(stringCompareInsensitive("", "A") < 0);
assert_true(stringCompareInsensitive("A", "") > 0);
// Cannot compare NULL strings
expect_assert_failure(stringCompareInsensitive(NULL, "abc"));
expect_assert_failure(stringCompareInsensitive("abc", NULL));
}
static void test_stringTrim(void **state) {
(void)state;
char buf[32];
stringCopy(buf, " hello ", sizeof(buf));
stringTrim(buf);
assert_string_equal(buf, "hello"); // Trims spaces
// Non-space whitespace
stringCopy(buf, "\t\nhello world\r\n", sizeof(buf));
stringTrim(buf);
assert_string_equal(buf, "hello world");
// Only whitespace
stringCopy(buf, " ", sizeof(buf));
stringTrim(buf);
assert_string_equal(buf, "");
// No whitespace
stringCopy(buf, "no-trim", sizeof(buf));
stringTrim(buf);
assert_string_equal(buf, "no-trim");
// Left whitespace only
stringCopy(buf, " left", sizeof(buf));
stringTrim(buf);
assert_string_equal(buf, "left");
// Right whitespace only
stringCopy(buf, "right ", sizeof(buf));
stringTrim(buf);
assert_string_equal(buf, "right");
// Cannot trim NULL string
expect_assert_failure(stringTrim(NULL));
// Can trim empty string
stringCopy(buf, "", sizeof(buf));
stringTrim(buf);
assert_string_equal(buf, "");
}
static void test_stringFindLastChar(void **state) {
(void)state;
const char *str = "hello world";
char *result = stringFindLastChar(str, 'o');
assert_non_null(result);
assert_int_equal(*result, 'o');
assert_int_equal(result - str, 7); // Position of last 'o'
result = stringFindLastChar(str, 'h');
assert_non_null(result);
assert_int_equal(*result, 'h');
assert_int_equal(result - str, 0); // Position of 'h'
result = stringFindLastChar(str, 'z');
assert_null(result); // 'z' not found
// Cannot search NULL string
expect_assert_failure(stringFindLastChar(NULL, 'a'));
}
static void test_stringFormat(void **state) {
(void)state;
// Test a string format
char buffer[32];
int32_t len = stringFormat(buffer, sizeof(buffer), "Hello %s!", "World");
assert_int_equal(len, 12);
assert_string_equal(buffer, "Hello World!");
// Test a number format
len = stringFormat(buffer, sizeof(buffer), "Number: %d", 42);
assert_int_equal(len, 10);
assert_string_equal(buffer, "Number: 42");
// Test floats with different precision
len = stringFormat(buffer, sizeof(buffer), "Float: %.2f", 3.14159);
assert_int_equal(len, 11);
assert_string_equal(buffer, "Float: 3.14");
len = stringFormat(buffer, sizeof(buffer), "Float: %.4f", 3.14159);
assert_int_equal(len, 13);
assert_string_equal(buffer, "Float: 3.1416");
// Test integer formatting
len = stringFormat(buffer, sizeof(buffer), "Hex: 0x%X", 255);
assert_int_equal(len, 9);
assert_string_equal(buffer, "Hex: 0xFF");
// Test empty format
len = stringFormat(buffer, sizeof(buffer), "");
assert_int_equal(len, 0);
assert_string_equal(buffer, "");
// Test no substitutions
len = stringFormat(buffer, sizeof(buffer), "No substitutions");
assert_int_equal(len, 16);
assert_string_equal(buffer, "No substitutions");
// Test buffer too small
expect_assert_failure(stringFormat(buffer, 5, "This is too long"));
expect_assert_failure(stringFormat(buffer, sizeof(buffer), "Hello %s", "This string is way too long to fit within the buffer that we have allocated"));
// Test NULL destination, simply returns required length
len = stringFormat(NULL, 0, "Hello %s!", "World");
assert_int_equal(len, 12);
len = stringFormat(NULL, 0, "Number: %d", 42);
assert_int_equal(len, 10);
// Cannot have NULL format
expect_assert_failure(stringFormat(buffer, sizeof(buffer), NULL));
// Must have destSize > 0 if dest is not NULL
expect_assert_failure(stringFormat(buffer, 0, "Hello"));
}
static void test_stringToI32(void **state) {
(void)state;
char_t buffer[64];
int32_t value;
bool_t result;
// Standard integers
stringCopy(buffer, "12345", sizeof(buffer));
assert_true(result = stringToI32(buffer, &value));
assert_int_equal(value, 12345);
stringCopy(buffer, "-6789", sizeof(buffer));
assert_true(result = stringToI32(buffer, &value));
assert_int_equal(value, -6789);
stringCopy(buffer, "+123", sizeof(buffer));
assert_true(result = stringToI32(buffer, &value));
assert_int_equal(value, 123);
// Cannot convert invalid strings
stringCopy(buffer, "abc", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
stringCopy(buffer, "123abc", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
stringCopy(buffer, "", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
stringCopy(buffer, " ", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
stringCopy(buffer, " 123", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
stringCopy(buffer, "123 ", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
stringCopy(buffer, " 1234 ", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
stringCopy(buffer, "+-123", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
stringCopy(buffer, "\t123", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
stringCopy(buffer, "12 34", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
stringCopy(buffer, "--123", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
stringCopy(buffer, "++123", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
stringCopy(buffer, "+", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
stringCopy(buffer, "-", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
// Non ascii numbers
stringCopy(buffer, "", sizeof(buffer)); // Fullwidth digits
assert_false(result = stringToI32(buffer, &value));
// Cannot take math
stringCopy(buffer, "100+20", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
stringCopy(buffer, "50-10", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
stringCopy(buffer, "5*6", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
stringCopy(buffer, "20/4", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
// Cannot handle decimal points
stringCopy(buffer, "12.34", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
// Cannot handle non-numbers
stringCopy(buffer, "12-34", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
stringCopy(buffer, "e", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
stringCopy(buffer, " ", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
stringCopy(buffer, "3.273390607896142e+150 ", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
stringCopy(buffer, "9999999999999999999999999", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
// Cannot handle really low numbers
stringCopy(buffer, "-9999999999999999999999999", sizeof(buffer));
assert_false(result = stringToI32(buffer, &value));
// Cannot handle items outside int32 range
stringCopy(buffer, "2147483648", sizeof(buffer)); // INT32_MAX + 1
assert_false(result = stringToI32(buffer, &value));
stringCopy(buffer, "-2147483649", sizeof(buffer)); // INT32_MIN - 1
assert_false(result = stringToI32(buffer, &value));
// CAN handle INT32 limits
stringCopy(buffer, "2147483647", sizeof(buffer)); // INT32_MAX
assert_true(result = stringToI32(buffer, &value));
assert_int_equal(value, 2147483647);
stringCopy(buffer, "-2147483648", sizeof(buffer)); // INT32_MIN
assert_true(result = stringToI32(buffer, &value));
assert_int_equal(value, -2147483648);
// Cannot have NULL string
expect_assert_failure(stringToI32(NULL, &value));
// Cannot have NULL output pointer
stringCopy(buffer, "123", sizeof(buffer));
expect_assert_failure(stringToI32(buffer, NULL));
}
static void test_stringToI64(void **state) {
(void)state;
char_t buffer[64];
int64_t value;
bool_t result;
// Standard integers
stringCopy(buffer, "12345678901234", sizeof(buffer));
assert_true(result = stringToI64(buffer, &value));
assert_int_equal(value, 12345678901234LL);
stringCopy(buffer, "-67890123456789", sizeof(buffer));
assert_true(result = stringToI64(buffer, &value));
assert_int_equal(value, -67890123456789LL);
// Cannot convert invalid strings
stringCopy(buffer, "abc", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
stringCopy(buffer, "123abc", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
// Cannot convert invalid strings
stringCopy(buffer, "abc", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
stringCopy(buffer, "123abc", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
stringCopy(buffer, "", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
stringCopy(buffer, " ", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
stringCopy(buffer, " 123", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
stringCopy(buffer, "123 ", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
stringCopy(buffer, " 1234 ", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
stringCopy(buffer, "+-123", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
stringCopy(buffer, "\t123", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
stringCopy(buffer, "12 34", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
stringCopy(buffer, "--123", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
stringCopy(buffer, "++123", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
stringCopy(buffer, "+", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
stringCopy(buffer, "-", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
// Non ascii numbers
stringCopy(buffer, "", sizeof(buffer)); // Fullwidth digits
assert_false(result = stringToI64(buffer, &value));
// Cannot take math
stringCopy(buffer, "100+20", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
stringCopy(buffer, "50-10", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
stringCopy(buffer, "5*6", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
stringCopy(buffer, "20/4", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
// Cannot handle decimal points
stringCopy(buffer, "12.34", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
// Cannot handle non-numbers
stringCopy(buffer, "12-34", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
stringCopy(buffer, "e", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
stringCopy(buffer, " ", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
stringCopy(buffer, "3.273390607896142e+150 ", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
stringCopy(buffer, "9999999999999999999999999", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
// Cannot handle really low numbers
stringCopy(buffer, "-9999999999999999999999999", sizeof(buffer));
assert_false(result = stringToI64(buffer, &value));
// Cannot handle items outside int64 range
stringCopy(buffer, "9223372036854775808", sizeof(buffer)); // INT64_MAX + 1
assert_false(result = stringToI64(buffer, &value));
stringCopy(buffer, "-9223372036854775809", sizeof(buffer)); // INT64_MIN - 1
assert_false(result = stringToI64(buffer, &value));
// CAN handle INT64 limits
stringCopy(buffer, "9223372036854775807", sizeof(buffer)); // INT64_MAX
assert_true(result = stringToI64(buffer, &value));
assert_int_equal(value, 9223372036854775807LL);
stringCopy(buffer, "-9223372036854775808", sizeof(buffer)); // INT64_MIN
assert_true(result = stringToI64(buffer, &value));
assert_int_equal(value, -9223372036854775808LL);
// Cannot have NULL string
expect_assert_failure(stringToI64(NULL, &value));
// Cannot have NULL output pointer
stringCopy(buffer, "123", sizeof(buffer));
expect_assert_failure(stringToI64(buffer, NULL));
}
static void test_stringToI16(void **state) {
(void)state;
char_t buffer[64];
int16_t value;
bool_t result;
// Standard integers (within int16 range)
stringCopy(buffer, "12345", sizeof(buffer));
assert_true(result = stringToI16(buffer, &value));
assert_int_equal(value, (int16_t)12345);
stringCopy(buffer, "-23456", sizeof(buffer));
assert_true(result = stringToI16(buffer, &value));
assert_int_equal(value, (int16_t)-23456);
// Cannot convert invalid strings
stringCopy(buffer, "abc", sizeof(buffer));
assert_false(result = stringToI16(buffer, &value));
stringCopy(buffer, "123abc", sizeof(buffer));
assert_false(result = stringToI16(buffer, &value));
stringCopy(buffer, "", sizeof(buffer));
assert_false(result = stringToI16(buffer, &value));
stringCopy(buffer, " ", sizeof(buffer));
assert_false(result = stringToI16(buffer, &value));
stringCopy(buffer, " 123", sizeof(buffer));
assert_false(result = stringToI16(buffer, &value));
stringCopy(buffer, "123 ", sizeof(buffer));
assert_false(result = stringToI16(buffer, &value));
stringCopy(buffer, " 1234 ", sizeof(buffer));
assert_false(result = stringToI16(buffer, &value));
stringCopy(buffer, "+-123", sizeof(buffer));
assert_false(result = stringToI16(buffer, &value));
stringCopy(buffer, "\t123", sizeof(buffer));
assert_false(result = stringToI16(buffer, &value));
stringCopy(buffer, "12 34", sizeof(buffer));
assert_false(result = stringToI16(buffer, &value));
stringCopy(buffer, "--123", sizeof(buffer));
assert_false(result = stringToI16(buffer, &value));
stringCopy(buffer, "++123", sizeof(buffer));
assert_false(result = stringToI16(buffer, &value));
stringCopy(buffer, "+", sizeof(buffer));
assert_false(result = stringToI16(buffer, &value));
stringCopy(buffer, "-", sizeof(buffer));
assert_false(result = stringToI16(buffer, &value));
// Non-ascii numbers
stringCopy(buffer, "", sizeof(buffer)); // Fullwidth digits
assert_false(result = stringToI16(buffer, &value));
// Cannot take math
stringCopy(buffer, "100+20", sizeof(buffer));
assert_false(result = stringToI16(buffer, &value));
stringCopy(buffer, "50-10", sizeof(buffer));
assert_false(result = stringToI16(buffer, &value));
stringCopy(buffer, "5*6", sizeof(buffer));
assert_false(result = stringToI16(buffer, &value));
stringCopy(buffer, "20/4", sizeof(buffer));
assert_false(result = stringToI16(buffer, &value));
// Cannot handle decimal points
stringCopy(buffer, "12.34", sizeof(buffer));
assert_false(result = stringToI16(buffer, &value));
// Cannot handle non-numbers / mixed formats
stringCopy(buffer, "12-34", sizeof(buffer));
assert_false(result = stringToI16(buffer, &value));
stringCopy(buffer, "e", sizeof(buffer));
assert_false(result = stringToI16(buffer, &value));
stringCopy(buffer, " ", sizeof(buffer));
assert_false(result = stringToI16(buffer, &value));
stringCopy(buffer, "3.273390607896142e+150 ", sizeof(buffer));
assert_false(result = stringToI16(buffer, &value));
// Out of int16 range (overflow)
stringCopy(buffer, "32768", sizeof(buffer)); // INT16_MAX + 1
assert_false(result = stringToI16(buffer, &value));
// Out of int16 range (underflow)
stringCopy(buffer, "-32769", sizeof(buffer)); // INT16_MIN - 1
assert_false(result = stringToI16(buffer, &value));
// CAN handle int16 limits
stringCopy(buffer, "32767", sizeof(buffer)); // INT16_MAX
assert_true(result = stringToI16(buffer, &value));
assert_int_equal(value, (int16_t)32767);
stringCopy(buffer, "-32768", sizeof(buffer)); // INT16_MIN
assert_true(result = stringToI16(buffer, &value));
assert_int_equal(value, (int16_t)-32768);
// Cannot have NULL string
expect_assert_failure(stringToI16(NULL, &value));
// Cannot have NULL output pointer
stringCopy(buffer, "123", sizeof(buffer));
expect_assert_failure(stringToI16(buffer, NULL));
}
static void test_stringToU16(void **state) {
(void)state;
char_t buffer[64];
uint16_t value;
bool_t result;
// Standard integers (within uint16 range)
stringCopy(buffer, "0", sizeof(buffer));
assert_true(result = stringToU16(buffer, &value));
assert_int_equal(value, (uint16_t)0);
stringCopy(buffer, "12345", sizeof(buffer));
assert_true(result = stringToU16(buffer, &value));
assert_int_equal(value, (uint16_t)12345);
// Cannot convert invalid strings
stringCopy(buffer, "abc", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
stringCopy(buffer, "123abc", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
stringCopy(buffer, "", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
stringCopy(buffer, " ", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
stringCopy(buffer, " 123", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
stringCopy(buffer, "123 ", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
stringCopy(buffer, " 1234 ", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
stringCopy(buffer, "+-123", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
stringCopy(buffer, "\t123", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
stringCopy(buffer, "12 34", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
stringCopy(buffer, "--123", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
stringCopy(buffer, "++123", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
stringCopy(buffer, "+", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
// Unsigned: no minus sign
stringCopy(buffer, "-", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
stringCopy(buffer, "-1", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
// Non-ascii numbers
stringCopy(buffer, "", sizeof(buffer)); // Fullwidth digits
assert_false(result = stringToU16(buffer, &value));
// Cannot take math
stringCopy(buffer, "100+20", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
stringCopy(buffer, "50-10", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
stringCopy(buffer, "5*6", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
stringCopy(buffer, "20/4", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
// Cannot handle decimal points
stringCopy(buffer, "12.34", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
// Cannot handle non-numbers / mixed formats
stringCopy(buffer, "12-34", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
stringCopy(buffer, "e", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
stringCopy(buffer, " ", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
stringCopy(buffer, "3.273390607896142e+150 ", sizeof(buffer));
assert_false(result = stringToU16(buffer, &value));
// Out of uint16 range (overflow)
stringCopy(buffer, "65536", sizeof(buffer)); // UINT16_MAX + 1
assert_false(result = stringToU16(buffer, &value));
// CAN handle uint16 limits
stringCopy(buffer, "65535", sizeof(buffer)); // UINT16_MAX
assert_true(result = stringToU16(buffer, &value));
assert_int_equal(value, (uint16_t)65535);
// Cannot have NULL string
expect_assert_failure(stringToU16(NULL, &value));
// Cannot have NULL output pointer
stringCopy(buffer, "123", sizeof(buffer));
expect_assert_failure(stringToU16(buffer, NULL));
}
static void test_stringToF32(void **state) {
(void)state;
char_t buffer[64];
float value;
bool_t result;
// Standard values
stringCopy(buffer, "0", sizeof(buffer));
assert_true(result = stringToF32(buffer, &value));
assert_float_equal(value, 0.0f, 0.000001f);
stringCopy(buffer, "123.5", sizeof(buffer));
assert_true(result = stringToF32(buffer, &value));
assert_float_equal(value, 123.5f, 0.000001f);
stringCopy(buffer, "-45.25", sizeof(buffer));
assert_true(result = stringToF32(buffer, &value));
assert_float_equal(value, -45.25f, 0.000001f);
stringCopy(buffer, "1.0", sizeof(buffer));
assert_true(result = stringToF32(buffer, &value));
assert_float_equal(value, 1.0f, 0.000001f);
// Integers should also parse
stringCopy(buffer, "42", sizeof(buffer));
assert_true(result = stringToF32(buffer, &value));
assert_float_equal(value, 42.0f, 0.000001f);
stringCopy(buffer, "-7", sizeof(buffer));
assert_true(result = stringToF32(buffer, &value));
assert_float_equal(value, -7.0f, 0.000001f);
// Cannot do European format
stringCopy(buffer, "123,45", sizeof(buffer));
assert_false(result = stringToF32(buffer, &value));
// Cannot convert invalid strings
stringCopy(buffer, "abc", sizeof(buffer));
assert_false(result = stringToF32(buffer, &value));
stringCopy(buffer, "123abc", sizeof(buffer));
assert_false(result = stringToF32(buffer, &value));
stringCopy(buffer, "", sizeof(buffer));
assert_false(result = stringToF32(buffer, &value));
stringCopy(buffer, " ", sizeof(buffer));
assert_false(result = stringToF32(buffer, &value));
stringCopy(buffer, " ", sizeof(buffer));
assert_false(result = stringToF32(buffer, &value));
stringCopy(buffer, " 1.23", sizeof(buffer));
assert_false(result = stringToF32(buffer, &value));
stringCopy(buffer, "1.23 ", sizeof(buffer));
assert_false(result = stringToF32(buffer, &value));
stringCopy(buffer, " 1.23 ", sizeof(buffer));
assert_false(result = stringToF32(buffer, &value));
// Invalid sign usage
stringCopy(buffer, "+-1.2", sizeof(buffer));
assert_false(result = stringToF32(buffer, &value));
stringCopy(buffer, "--1.2", sizeof(buffer));
assert_false(result = stringToF32(buffer, &value));
stringCopy(buffer, "++1.2", sizeof(buffer));
assert_false(result = stringToF32(buffer, &value));
stringCopy(buffer, "+", sizeof(buffer));
assert_false(result = stringToF32(buffer, &value));
stringCopy(buffer, "-", sizeof(buffer));
assert_false(result = stringToF32(buffer, &value));
// Multiple decimal points
stringCopy(buffer, "1.2.3", sizeof(buffer));
assert_false(result = stringToF32(buffer, &value));
// Non-ascii digits
stringCopy(buffer, "", sizeof(buffer)); // Fullwidth
assert_false(result = stringToF32(buffer, &value));
// Cannot take math
stringCopy(buffer, "1+2", sizeof(buffer));
assert_false(result = stringToF32(buffer, &value));
stringCopy(buffer, "5-3", sizeof(buffer));
assert_false(result = stringToF32(buffer, &value));
stringCopy(buffer, "2*3", sizeof(buffer));
assert_false(result = stringToF32(buffer, &value));
stringCopy(buffer, "6/2", sizeof(buffer));
assert_false(result = stringToF32(buffer, &value));
// Scientific notation allowed
stringCopy(buffer, "1e3", sizeof(buffer));
assert_true(result = stringToF32(buffer, &value));
stringCopy(buffer, "3.4E10", sizeof(buffer));
assert_true(result = stringToF32(buffer, &value));
// Overflow (beyond float32 max)
stringCopy(buffer, "3.5e38", sizeof(buffer));
assert_false(result = stringToF32(buffer, &value));
// Underflow (too small, magnitude)
stringCopy(buffer, "1e-50", sizeof(buffer));
assert_false(result = stringToF32(buffer, &value));
// Edge of float32 range (decimal form)
stringCopy(buffer, "340282346638528859811704183484516925440.0",
sizeof(buffer)); // ~FLT_MAX
assert_true(result = stringToF32(buffer, &value));
// Valid near-limits (implementation-dependent, keep conservative)
stringCopy(buffer, "3.4028234e38", sizeof(buffer));
assert_true(result = stringToF32(buffer, &value));
// Cannot have NULL string
expect_assert_failure(stringToF32(NULL, &value));
// Cannot have NULL output pointer
stringCopy(buffer, "1.23", sizeof(buffer));
expect_assert_failure(stringToF32(buffer, NULL));
}
static void test_stringEndsWith(void **state) {
(void)state;
assert_true(stringEndsWith("hello.c", ".c"));
assert_true(stringEndsWith("Hello World!", "World!"));
assert_false(stringEndsWith("document.pdf", ".doc"));
assert_false(stringEndsWith("image.jpeg", ".png"));
assert_false(stringEndsWith("short", "longer"));
// Cannot have NULL strings
expect_assert_failure(stringEndsWith(NULL, "world"));
expect_assert_failure(stringEndsWith("hello", NULL));
}
static void test_stringEndsWithCaseInsensitive(void **state) {
(void)state;
assert_true(stringEndsWithCaseInsensitive("hello.C", ".c"));
assert_true(stringEndsWithCaseInsensitive("Hello World!", "world!"));
assert_false(stringEndsWithCaseInsensitive("document.pdf", ".DOC"));
assert_false(stringEndsWithCaseInsensitive("image.jpeg", ".PNG"));
assert_false(stringEndsWithCaseInsensitive("short", "LONGER"));
// Cannot have NULL strings
expect_assert_failure(stringEndsWithCaseInsensitive(NULL, "WORLD"));
expect_assert_failure(stringEndsWithCaseInsensitive("hello", NULL));
}
int main(int argc, char **argv) {
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_stringIsWhitespace),
cmocka_unit_test(test_stringCopy),
cmocka_unit_test(test_stringCompare),
cmocka_unit_test(test_stringCompareInsensitive),
cmocka_unit_test(test_stringTrim),
cmocka_unit_test(test_stringFindLastChar),
cmocka_unit_test(test_stringFormat),
cmocka_unit_test(test_stringToI32),
cmocka_unit_test(test_stringToI64),
cmocka_unit_test(test_stringToI16),
cmocka_unit_test(test_stringToU16),
cmocka_unit_test(test_stringToF32),
cmocka_unit_test(test_stringEndsWith),
cmocka_unit_test(test_stringEndsWithCaseInsensitive),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}