#include "../src/string.c" #include "../src/testing.h" static int test_string_new_with(void) { int rc = -1; const struct String *s = NULL; test_start("string_new_with()"); { testing("length value isn't checked"); const char *const string = "abc"; if (string_new_with(string, 123U, &s)) { logerr("string_new_with()"); goto out; } assert(s->length == 123U); test_ok(); } rc = 0; out: if (s != NULL) { string_free(&s); } return rc; } static int test_string_new(void) { int rc = -1; test_start("string_new()"); { testing("simple allocation of a string"); const struct String *s; if (string_new("a string", &s)) { logerr("string_new()"); goto out; } assert(s->length == 8U); assert(strcmp(cstr(s), "a string") == 0); string_free(&s); test_ok(); } rc = 0; out: return rc; } static int test_string_free(void) { int rc = -1; const struct String *s = NULL; test_start("string_free()"); { testing("*v becomes NULL again after string_free(&s)"); assert(s == NULL); if (string_new("", &s)) { logerr("string_new()"); goto out; } assert(s != NULL); string_free(&s); assert(s == NULL); test_ok(); } rc = 0; out: return rc; } static int test_cstr(void) { int rc = -1; const struct String *s = NULL; test_start("cstr()"); const char *const string = "some string"; const size_t length = strlen(string); if (string_new(string, &s)) { logerr("string_new()"); goto out; } { testing("we can dump a NULL-terminated string"); assert(strcmp(cstr(s), string) == 0); assert(cstr(s)[length] == '\0'); test_ok(); } rc = 0; out: if (s != NULL) { string_free(&s); } return rc; } static int test_string_compare(void) { int rc = -1; const struct String *s1 = NULL; const struct String *s2 = NULL; const struct String *s3 = NULL; const struct String *s4 = NULL; test_start("string_compare()"); if (string_new("aac", &s1)) { logerr("string_new()"); goto out; } if (string_new("abc", &s2)) { logerr("string_new()"); goto out; } if (string_new("acc", &s3)) { logerr("string_new()"); goto out; } if (string_new("abc", &s4)) { logerr("string_new()"); goto out; } { testing("different identities"); assert(s1 != s2); assert(s1 != s3); assert(s1 != s4); assert(s2 != s3); assert(s2 != s4); assert(s3 != s4); test_ok(); } { testing("self equality"); assert(string_compare(s1, s1) == Comparison_EQ); assert(string_compare(s2, s2) == Comparison_EQ); assert(string_compare(s3, s3) == Comparison_EQ); assert(string_compare(s4, s4) == Comparison_EQ); test_ok(); } { testing("lesser/greater values"); assert(string_compare(s1, s2) == Comparison_LT); assert(string_compare(s1, s3) == Comparison_LT); assert(string_compare(s1, s4) == Comparison_LT); assert(string_compare(s2, s3) == Comparison_LT); assert(string_compare(s4, s3) == Comparison_LT); assert(string_compare(s2, s1) == Comparison_GT); assert(string_compare(s3, s1) == Comparison_GT); assert(string_compare(s4, s1) == Comparison_GT); assert(string_compare(s3, s2) == Comparison_GT); assert(string_compare(s3, s4) == Comparison_GT); test_ok(); } { testing("equal values"); assert(string_compare(s2, s4) == Comparison_EQ); assert(string_compare(s4, s2) == Comparison_EQ); test_ok(); } rc = 0; out: if (s4 != NULL) { string_free(&s4); } if (s3 != NULL) { string_free(&s3); } if (s2 != NULL) { string_free(&s2); } if (s1 != NULL) { string_free(&s1); } return rc; } static void test_string_equals(void) { test_start("string_equals()"); const struct String *const s1 = &(struct String) { .length = 1U, .bytes = (const uint8_t *)"", }; const struct String *const s2 = &(struct String) { .length = 1U, .bytes = (const uint8_t *)"", }; const struct String *const s3 = &(struct String) { .length = 2U, .bytes = (const uint8_t *)" ", }; { testing("equal values"); assert(string_equals(s1, s2)); test_ok(); } { testing("different values"); assert(!string_equals(s1, s3)); assert(!string_equals(s2, s3)); test_ok(); } } static int test_string_append(void) { int rc = -1; const struct String *s = NULL; const struct String *s1 = NULL; const struct String *s2 = NULL; const struct String *s3 = NULL; test_start("string_append()"); if (string_new("", &s1)) { logerr("string_new()"); goto out; } if (string_new("", &s2)) { logerr("string_new()"); goto out; } if (string_new("abc", &s3)) { logerr("string_new()"); goto out; } { testing("empty strings"); if (string_append(s1, s2, &s)) { logerr("string_append()"); goto out; } assert(string_equals(s, s1)); string_free(&s); if (string_append(s2, s2, &s)) { logerr("string_append()"); goto out; } assert(string_equals(s, s1)); string_free(&s); if (string_append(s1, s3, &s)) { logerr("string_append()"); goto out; } assert(string_equals(s, s3)); string_free(&s); if (string_append(s2, s3, &s)) { logerr("string_append()"); goto out; } assert(string_equals(s, s3)); string_free(&s); test_ok(); } { testing("same string in both arguments"); if (string_append(s3, s3, &s)) { logerr("string_append()"); goto out; } assert(string_equals(s, &(struct String) { .length = 6U, .bytes = (const uint8_t *)"abcabc", })); string_free(&s); test_ok(); } rc = 0; out: if (s3 != NULL) { string_free(&s3); } if (s2 != NULL) { string_free(&s2); } if (s1 != NULL) { string_free(&s1); } if (s != NULL) { string_free(&s); } return rc; } int main(void) { int rc = EXIT_FAILURE; if (test_string_new_with()) { logerr("test_string_new_with()"); goto out; } if (test_string_new()) { logerr("test_string_new()"); goto out; } if (test_string_free()) { logerr("test_string_free()"); goto out; } if (test_cstr()) { logerr("test_cstr()"); goto out; } if (test_string_compare()) { logerr("test_string_compare()"); goto out; } test_string_equals(); if (test_string_append()) { logerr("test_string_append()"); goto out; } rc = EXIT_SUCCESS; out: return rc; }