CHORE: Bug fixing. Major changes to bugs and also unit testing
This commit is contained in:
@@ -0,0 +1,686 @@
|
||||
#include <assert.h>
|
||||
#include <char/char.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <utils/utils.h>
|
||||
|
||||
#if defined(__has_feature)
|
||||
#if __has_feature(address_sanitizer)
|
||||
const char*
|
||||
__asan_default_options(void)
|
||||
{
|
||||
return "allocator_may_return_null=1";
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* =========================================================================
|
||||
* 1. BASIC LIFECYCLE & NULL GUARDS
|
||||
* ========================================================================= */
|
||||
|
||||
static void
|
||||
test_push_back_single(void)
|
||||
{
|
||||
printf("[1] Testing push_back with a single character...\n");
|
||||
_VecCharInternal vec = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
_vec_char_push_back(&vec, 'A', &err);
|
||||
|
||||
assert(err.flags == 0);
|
||||
assert(vec._internal_size == 1);
|
||||
assert(vec._internal_arr[0] == 'A');
|
||||
_vec_char_delete(&vec, &err);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_null_guards(void)
|
||||
{
|
||||
printf("[2] Testing null pointer checks in __null_check...\n");
|
||||
_VecCharInternal vec = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
|
||||
size_t res1 = __null_check(&vec, nullptr);
|
||||
assert(res1 == ERR_ERR_T_NULL);
|
||||
|
||||
size_t res2 = __null_check((const _VecCharInternal*)nullptr, &err);
|
||||
assert(res2 == ERR_VEC_NULL);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
|
||||
err = (err_t)ERR_T_INIT;
|
||||
size_t res3 = __null_check(&vec, &err);
|
||||
assert(res3 == ERR_BUF_NULL);
|
||||
assert((err.flags & ERR_BUF_NULL) != 0);
|
||||
|
||||
err = (err_t)ERR_T_INIT;
|
||||
size_t res4 = __null_check(vec._internal_arr, &err);
|
||||
assert(res4 == ERR_BUF_NULL);
|
||||
assert((err.flags & ERR_BUF_NULL) != 0);
|
||||
|
||||
err = (err_t)ERR_T_INIT;
|
||||
size_t res5 = __null_check((const char*)nullptr, nullptr);
|
||||
assert(res5 == ERR_ERR_T_NULL);
|
||||
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_origin_override(void)
|
||||
{
|
||||
printf("[3] Testing __origin_override...\n");
|
||||
err_t err = ERR_T_INIT;
|
||||
|
||||
size_t res_null_status = __origin_override(nullptr, "TEST");
|
||||
assert(res_null_status == ERR_ERR_T_NULL);
|
||||
|
||||
size_t res = __origin_override(&err, nullptr);
|
||||
assert(res == ERR_STR_NULL);
|
||||
assert((err.flags & ERR_STR_NULL) != 0);
|
||||
|
||||
err = (err_t)ERR_T_INIT;
|
||||
__origin_override(&err, "INITIAL");
|
||||
assert(strcmp(err.origin, "INITIAL") == 0);
|
||||
|
||||
// Override existing origin -> ERR_ORIGIN_UNALTERABLE
|
||||
__origin_override(&err, "REPLACED");
|
||||
assert((err.flags & ERR_ORIGIN_UNALTERABLE) != 0);
|
||||
assert(strcmp(err.origin, "INITIAL") == 0);
|
||||
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
* 2. PRINT & COPY
|
||||
* ========================================================================= */
|
||||
|
||||
static void
|
||||
test_print_vec(void)
|
||||
{
|
||||
_VecCharInternal vec = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
|
||||
printf("[4] Testing print_vec with null vector\n");
|
||||
_vec_char_print_vec(nullptr, &err);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[5] Testing print_vec with null array\n");
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_print_vec(&vec, &err);
|
||||
assert((err.flags & ERR_BUF_NULL) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[6] Testing print_vec with null err\n");
|
||||
_vec_char_print_vec(&vec, nullptr);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[7] Testing print_vec with valid parameters\n");
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_push_back(&vec, 'a', &err);
|
||||
_vec_char_push_back(&vec, 'b', &err);
|
||||
_vec_char_print_vec(&vec, &err);
|
||||
_vec_char_delete(&vec, &err);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_cpy(void)
|
||||
{
|
||||
char arr[3] = { 'a', 'b', 'c' };
|
||||
_VecCharInternal blank = VEC_INIT;
|
||||
|
||||
printf("[8] Testing _vec_char_cpy with null source arr\n");
|
||||
err_t err1 = ERR_T_INIT;
|
||||
_VecCharInternal tmp = _vec_char_cpy(nullptr, 3, &err1);
|
||||
assert(blank._internal_arr == tmp._internal_arr &&
|
||||
blank._internal_capacity == tmp._internal_capacity &&
|
||||
blank._internal_size == tmp._internal_size &&
|
||||
blank._internal_max_size == tmp._internal_max_size);
|
||||
assert((err1.flags & ERR_BUF_NULL) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[9] Testing _vec_char_cpy with null err\n");
|
||||
_VecCharInternal res2 = _vec_char_cpy(arr, 3, nullptr);
|
||||
assert(blank._internal_arr == res2._internal_arr &&
|
||||
blank._internal_capacity == res2._internal_capacity &&
|
||||
blank._internal_size == res2._internal_size &&
|
||||
blank._internal_max_size == res2._internal_max_size);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[10] Testing _vec_char_cpy with size 0\n");
|
||||
err_t err3 = ERR_T_INIT;
|
||||
_VecCharInternal res3 = _vec_char_cpy(arr, 0, &err3);
|
||||
assert(blank._internal_arr == res3._internal_arr &&
|
||||
blank._internal_capacity == res3._internal_capacity &&
|
||||
blank._internal_size == res3._internal_size &&
|
||||
blank._internal_max_size == res3._internal_max_size);
|
||||
assert((err3.flags & ERR_SIZE_ZERO) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[11] Testing _vec_char_cpy with size exceeding max_size\n");
|
||||
err_t err4 = ERR_T_INIT;
|
||||
_VecCharInternal res4 =
|
||||
_vec_char_cpy(arr, res3._internal_max_size + 1, &err4);
|
||||
assert(blank._internal_arr == res4._internal_arr &&
|
||||
blank._internal_capacity == res4._internal_capacity &&
|
||||
blank._internal_size == res4._internal_size &&
|
||||
blank._internal_max_size == res4._internal_max_size);
|
||||
assert((err4.flags & ERR_SIZE_OVERFLOW) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[12] Testing _vec_char_cpy allocation failure\n");
|
||||
err_t err5 = ERR_T_INIT;
|
||||
size_t huge_size = ((size_t)1 << 40);
|
||||
_VecCharInternal res5 = _vec_char_cpy(arr, huge_size, &err5);
|
||||
assert((err5.flags & ERR_ALLOC_FAIL) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[13] Testing _vec_char_cpy with valid inputs\n");
|
||||
err_t err = ERR_T_INIT;
|
||||
char res[4] = { 'a', 'b', 'c', 'd' };
|
||||
_VecCharInternal vec = _vec_char_cpy(res, 4, &err);
|
||||
assert(err.flags == 0);
|
||||
assert(vec._internal_size == 4);
|
||||
assert(vec._internal_capacity == 4);
|
||||
assert(memcmp(vec._internal_arr, res, 4) == 0);
|
||||
_vec_char_delete(&vec, &err);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
* 3. PUSH, POP, CAPACITY & SIZING
|
||||
* ========================================================================= */
|
||||
|
||||
static void
|
||||
test_push_back(void)
|
||||
{
|
||||
printf("[14] Testing _vec_char_push_back null vec\n");
|
||||
err_t err = ERR_T_INIT;
|
||||
_vec_char_push_back(nullptr, 'a', &err);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[15] Testing _vec_char_push_back null err\n");
|
||||
_VecCharInternal vec1 = VEC_INIT;
|
||||
_vec_char_push_back(&vec1, 'a', nullptr);
|
||||
assert(vec1._internal_size == 1);
|
||||
_vec_char_delete(&vec1, &err);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[16] Testing _vec_char_push_back size overflow\n");
|
||||
_VecCharInternal vec2 = VEC_INIT;
|
||||
err_t err2 = ERR_T_INIT;
|
||||
vec2._internal_size = vec2._internal_max_size;
|
||||
_vec_char_push_back(&vec2, 'a', &err2);
|
||||
assert((err2.flags & ERR_SIZE_OVERFLOW) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[17] Testing push_back capacity growth realloc\n");
|
||||
err_t err3 = ERR_T_INIT;
|
||||
_VecCharInternal vec3 = VEC_INIT;
|
||||
for (char c = '0'; c <= '9'; c++)
|
||||
{
|
||||
_vec_char_push_back(&vec3, c, &err3);
|
||||
assert(err3.flags == 0);
|
||||
}
|
||||
assert(vec3._internal_size == 10);
|
||||
assert(vec3._internal_capacity >= 10);
|
||||
_vec_char_delete(&vec3, &err3);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_pop_back(void)
|
||||
{
|
||||
_VecCharInternal vec = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
|
||||
printf("[18] Testing _vec_char_pop_back null vector\n");
|
||||
_vec_char_pop_back(nullptr, &err);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[19] Testing _vec_char_pop_back size 0\n");
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_push_back(&vec, 'x', &err);
|
||||
_vec_char_pop_back(&vec,
|
||||
&err); // size is now 0, but buffer is allocated
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_pop_back(&vec, &err);
|
||||
assert((err.flags & ERR_SIZE_ZERO) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[20] Testing _vec_char_pop_back valid pop\n");
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_push_back(&vec, 'a', &err);
|
||||
_vec_char_push_back(&vec, 'b', &err);
|
||||
assert(vec._internal_size == 2);
|
||||
_vec_char_pop_back(&vec, &err);
|
||||
assert(vec._internal_size == 1);
|
||||
assert(vec._internal_arr[0] == 'a');
|
||||
assert(vec._internal_arr[1] == 0);
|
||||
_vec_char_delete(&vec, &err);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_reserve(void)
|
||||
{
|
||||
_VecCharInternal vec = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
|
||||
printf("[21] Testing _vec_char_reserve null vector\n");
|
||||
_vec_char_reserve(nullptr, 1, &err);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[22] Testing _vec_char_reserve capacity 0\n");
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_reserve(&vec, 0, &err);
|
||||
assert((err.flags & ERR_SIZE_ZERO) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[23] Testing _vec_char_reserve calloc on unallocated buffer\n");
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_reserve(&vec, 32, &err);
|
||||
assert(err.flags == 0);
|
||||
assert(vec._internal_capacity == 32);
|
||||
assert(vec._internal_arr != nullptr);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[24] Testing _vec_char_reserve realloc to larger capacity\n");
|
||||
_vec_char_reserve(&vec, 64, &err);
|
||||
assert(err.flags == 0);
|
||||
assert(vec._internal_capacity == 64);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[25] Testing _vec_char_reserve truncating size\n");
|
||||
vec._internal_size = 50;
|
||||
_vec_char_reserve(&vec, 20, &err);
|
||||
assert(vec._internal_size == 20);
|
||||
assert(vec._internal_capacity == 20);
|
||||
_vec_char_delete(&vec, &err);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_shrink_to_fit(void)
|
||||
{
|
||||
_VecCharInternal vec = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
|
||||
printf("[26] Testing _vec_char_shrink_to_fit null vector\n");
|
||||
_vec_char_shrink_to_fit(nullptr, &err);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf(
|
||||
"[27] Testing _vec_char_shrink_to_fit size 0 with allocated "
|
||||
"buffer\n");
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_push_back(&vec, 'a', &err);
|
||||
_vec_char_pop_back(&vec, &err);
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_shrink_to_fit(&vec, &err);
|
||||
assert((err.flags & ERR_SIZE_ZERO) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[28] Testing _vec_char_shrink_to_fit normal shrinkage\n");
|
||||
_vec_char_reserve(&vec, 128, &err);
|
||||
for (char c = '0'; c < '5'; c++)
|
||||
{
|
||||
_vec_char_push_back(&vec, c, &err);
|
||||
}
|
||||
assert(vec._internal_capacity == 128);
|
||||
assert(vec._internal_size == 5);
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_shrink_to_fit(&vec, &err);
|
||||
assert(err.flags == 0);
|
||||
assert(vec._internal_capacity == 5);
|
||||
assert(vec._internal_size == 5);
|
||||
_vec_char_delete(&vec, &err);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
* 4. GETTERS, ELEMENT ACCESS & CLEAR
|
||||
* ========================================================================= */
|
||||
|
||||
static void
|
||||
test_getters_and_access(void)
|
||||
{
|
||||
printf("[29] Testing getters, clear, and boundary element access...\n");
|
||||
_VecCharInternal vec = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
|
||||
// 1. Null pointer check
|
||||
assert(_vec_char_data(nullptr, &err) == nullptr);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
|
||||
err = (err_t)ERR_T_INIT;
|
||||
assert(_vec_char_size(nullptr, &err) == 0);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
|
||||
err = (err_t)ERR_T_INIT;
|
||||
assert(_vec_char_capacity(nullptr, &err) == 0);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
|
||||
err = (err_t)ERR_T_INIT;
|
||||
assert(_vec_char_max_size(nullptr, &err) == 0);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
|
||||
// 2. Unallocated buffer check for empty()
|
||||
err = (err_t)ERR_T_INIT;
|
||||
size_t unalloc_empty = _vec_char_empty(&vec, &err);
|
||||
assert((err.flags & ERR_BUF_NULL) != 0);
|
||||
assert(unalloc_empty != 0);
|
||||
|
||||
// 3. Allocate the buffer and pop so size is 0 with valid arr
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_push_back(&vec, 'x', &err);
|
||||
_vec_char_pop_back(&vec, &err);
|
||||
err = (err_t)ERR_T_INIT;
|
||||
|
||||
// Now _internal_arr is non-null and size is 0:
|
||||
assert(_vec_char_empty(&vec, &err) == 0);
|
||||
|
||||
// Boundary element access on size 0
|
||||
err = (err_t)ERR_T_INIT;
|
||||
assert(_vec_char_front(&vec, &err) == 0 ||
|
||||
(err.flags & ERR_OUT_OF_BOUNDS) != 0);
|
||||
|
||||
err = (err_t)ERR_T_INIT;
|
||||
assert(_vec_char_back(&vec, &err) == 0 ||
|
||||
(err.flags & ERR_OUT_OF_BOUNDS) != 0);
|
||||
|
||||
// 4. Populate container
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_push_back(&vec, 'x', &err);
|
||||
_vec_char_push_back(&vec, 'y', &err);
|
||||
_vec_char_push_back(&vec, 'z', &err);
|
||||
|
||||
assert(_vec_char_size(&vec, &err) == 3);
|
||||
assert(_vec_char_capacity(&vec, &err) >= 3);
|
||||
assert(_vec_char_data(&vec, &err) == vec._internal_arr);
|
||||
assert(_vec_char_front(&vec, &err) == 'x');
|
||||
assert(_vec_char_back(&vec, &err) == 'z');
|
||||
assert(_vec_char_begin(&vec, &err) == 0);
|
||||
assert(_vec_char_end(&vec, &err) == 2);
|
||||
|
||||
// Out of bounds at()
|
||||
err = (err_t)ERR_T_INIT;
|
||||
assert(_vec_char_at(&vec, 10, &err) == nullptr);
|
||||
assert((err.flags & ERR_OUT_OF_BOUNDS) != 0);
|
||||
|
||||
// Clear container
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_clear(&vec, &err);
|
||||
assert(vec._internal_size == 0);
|
||||
assert(vec._internal_arr[0] == 0);
|
||||
|
||||
_vec_char_delete(&vec, &err);
|
||||
assert(vec._internal_arr == nullptr);
|
||||
assert(vec._internal_size == 0);
|
||||
assert(vec._internal_capacity == 0);
|
||||
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
* 5. SWAP, ERASE, RESIZE, ASSIGN & INSERT
|
||||
* ========================================================================= */
|
||||
|
||||
static void
|
||||
test_swap(void)
|
||||
{
|
||||
printf("[30] Testing _vec_char_swap...\n");
|
||||
_VecCharInternal a = VEC_INIT;
|
||||
_VecCharInternal b = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
|
||||
// Null vector checks
|
||||
_vec_char_swap(nullptr, &b, &err);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_swap(&a, nullptr, &err);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
|
||||
// Normal swap
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_push_back(&a, 'A', &err);
|
||||
_vec_char_push_back(&b, 'B', &err);
|
||||
_vec_char_push_back(&b, 'C', &err);
|
||||
|
||||
_vec_char_swap(&a, &b, &err);
|
||||
assert(a._internal_size == 2);
|
||||
assert(a._internal_arr[0] == 'B');
|
||||
assert(b._internal_size == 1);
|
||||
assert(b._internal_arr[0] == 'A');
|
||||
|
||||
_vec_char_delete(&a, &err);
|
||||
_vec_char_delete(&b, &err);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_erase_variants(void)
|
||||
{
|
||||
printf("[31] Testing _vec_char_erase single & range overloads...\n");
|
||||
_VecCharInternal vec = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
|
||||
for (char c = '0'; c <= '5'; c++)
|
||||
{
|
||||
_vec_char_push_back(&vec, c, &err);
|
||||
} // "012345"
|
||||
|
||||
// Single element erase out of bounds (noop)
|
||||
_vec_char_erase(&vec, 10, &err);
|
||||
assert(vec._internal_size == 6);
|
||||
|
||||
// Erase index 2 ('2') -> "01345"
|
||||
_vec_char_erase(&vec, 2, &err);
|
||||
assert(vec._internal_size == 5);
|
||||
assert(vec._internal_arr[2] == '3');
|
||||
|
||||
// Range erase invalid bounds
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_erase(&vec, 4, 2, &err); // iter_end <= iter_start
|
||||
assert((err.flags & ERR_OUT_OF_BOUNDS) != 0);
|
||||
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_erase(&vec, 0, 10, &err); // iter_end > size
|
||||
assert((err.flags & ERR_OUT_OF_BOUNDS) != 0);
|
||||
|
||||
// Range erase middle: index 1 through 3 ("0[13]45" -> "045")
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_erase(&vec, 1, 3, &err);
|
||||
assert(vec._internal_size == 3);
|
||||
assert(vec._internal_arr[0] == '0');
|
||||
assert(vec._internal_arr[1] == '4');
|
||||
assert(vec._internal_arr[2] == '5');
|
||||
|
||||
_vec_char_delete(&vec, &err);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_resize(void)
|
||||
{
|
||||
printf("[32] Testing _vec_char_resize (zero-fill & value-fill)...\n");
|
||||
_VecCharInternal vec = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
|
||||
// Null vector
|
||||
_vec_char_resize((_VecCharInternal*)nullptr, 10, &err);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
|
||||
// Resize unallocated buffer to size 5
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_resize(&vec, 5, &err);
|
||||
assert(err.flags == 0);
|
||||
assert(vec._internal_size == 5);
|
||||
assert(vec._internal_arr[0] == 0);
|
||||
|
||||
// Same size requested
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_resize(&vec, 5, &err);
|
||||
assert((err.flags & ERR_OUT_OF_BOUNDS) != 0);
|
||||
|
||||
// Exceeds max size
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_resize(&vec, vec._internal_max_size + 1, &err);
|
||||
assert((err.flags & ERR_SIZE_OVERFLOW) != 0);
|
||||
|
||||
// Grow with value fill
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_resize(&vec, 8, 'Z', &err);
|
||||
assert(vec._internal_size == 8);
|
||||
assert(vec._internal_arr[5] == 'Z');
|
||||
assert(vec._internal_arr[7] == 'Z');
|
||||
|
||||
// Shrink with value fill
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_resize(&vec, 3, 'A', &err);
|
||||
assert(vec._internal_size == 3);
|
||||
|
||||
_vec_char_delete(&vec, &err);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_assign(void)
|
||||
{
|
||||
printf("[33] Testing _vec_char_assign overloads...\n");
|
||||
_VecCharInternal dst = VEC_INIT;
|
||||
_VecCharInternal src = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
|
||||
// Populate src: 'A', 'B', 'C', 'D', 'E'
|
||||
for (char c = 'A'; c <= 'E'; c++)
|
||||
{
|
||||
_vec_char_push_back(&src, c, &err);
|
||||
}
|
||||
|
||||
// Allocate dst buffer first so it is not unallocated
|
||||
_vec_char_push_back(&dst, 'z', &err);
|
||||
err = (err_t)ERR_T_INIT;
|
||||
|
||||
// 1. Fill assign: 4 'X's
|
||||
_vec_char_assign(&dst, 4, 'X', &err);
|
||||
assert(err.flags == 0);
|
||||
assert(dst._internal_size == 4);
|
||||
assert(dst._internal_arr[0] == 'X');
|
||||
assert(dst._internal_arr[3] == 'X');
|
||||
|
||||
// 2. Fill assign with 0 amount
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_assign(&dst, 0, 'Y', &err);
|
||||
assert((err.flags & ERR_SIZE_ZERO) != 0);
|
||||
|
||||
// 3. Range assign self-buffer check
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_assign(&dst, &dst, 0, 2, &err);
|
||||
assert((err.flags & ERR_DOUBLE_BUF) != 0);
|
||||
|
||||
// 4. Range assign invalid sub-range (start >= end)
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_assign(&dst, &src, 3, 2, &err);
|
||||
assert((err.flags & ERR_OUT_OF_BOUNDS) != 0);
|
||||
|
||||
// 5. Range assign out of bounds end
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_assign(&dst, &src, 0, 10, &err);
|
||||
assert((err.flags & ERR_OUT_OF_BOUNDS) != 0);
|
||||
|
||||
_vec_char_delete(&dst, &err);
|
||||
_vec_char_delete(&src, &err);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_insert(void)
|
||||
{
|
||||
printf("[34] Testing _vec_char_insert overloads...\n");
|
||||
_VecCharInternal vec = VEC_INIT;
|
||||
_VecCharInternal other = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
|
||||
// Single insert on unallocated buffer
|
||||
_vec_char_insert(&vec, 0, 'M', &err);
|
||||
assert(vec._internal_size == 1);
|
||||
assert(vec._internal_arr[0] == 'M');
|
||||
|
||||
// Single insert out of bounds
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_insert(&vec, 5, 'O', &err);
|
||||
assert((err.flags & ERR_OUT_OF_BOUNDS) != 0);
|
||||
|
||||
// Single insert at middle: index 0 ('A', then 'M' shifts to 1)
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_insert(&vec, 0, 'A', &err);
|
||||
assert(vec._internal_size == 2);
|
||||
assert(vec._internal_arr[0] == 'A');
|
||||
assert(vec._internal_arr[1] == 'M');
|
||||
|
||||
// Repeated insert: insert 3 'B's at index 1 -> 'A', 'B', 'B', 'B', 'M'
|
||||
_vec_char_insert(&vec, 1, 3, 'B', &err);
|
||||
assert(vec._internal_size == 5);
|
||||
assert(vec._internal_arr[1] == 'B');
|
||||
assert(vec._internal_arr[3] == 'B');
|
||||
assert(vec._internal_arr[4] == 'M');
|
||||
|
||||
// Repeated insert amount 0
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_insert(&vec, 0, 0, 'Z', &err);
|
||||
assert((err.flags & ERR_SIZE_ZERO) != 0);
|
||||
|
||||
// Vector-from-vector range insert
|
||||
_vec_char_push_back(&other, '1', &err);
|
||||
_vec_char_push_back(&other, '2', &err);
|
||||
|
||||
// Double buffer check
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_insert(&vec, &vec, 0, 0, 1, &err);
|
||||
assert((err.flags & ERR_DOUBLE_BUF) != 0);
|
||||
|
||||
_vec_char_delete(&vec, &err);
|
||||
_vec_char_delete(&other, &err);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
* MAIN TEST RUNNER
|
||||
* ========================================================================= */
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
printf("=========================================\n");
|
||||
printf(" Starting Complete libvec Unit Test Suite\n");
|
||||
printf("=========================================\n");
|
||||
|
||||
test_push_back_single();
|
||||
test_null_guards();
|
||||
test_origin_override();
|
||||
test_print_vec();
|
||||
test_cpy();
|
||||
test_push_back();
|
||||
test_pop_back();
|
||||
test_reserve();
|
||||
test_shrink_to_fit();
|
||||
test_getters_and_access();
|
||||
test_swap();
|
||||
test_erase_variants();
|
||||
test_resize();
|
||||
test_assign();
|
||||
test_insert();
|
||||
|
||||
printf("=========================================\n");
|
||||
printf(" All 34 Test Suites Executed Successfully!\n");
|
||||
printf("=========================================\n");
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user