140 lines
4.5 KiB
C
140 lines
4.5 KiB
C
#include "c_AdjList.h"
|
|||
|
|
#include "c_Test.h"
|
||
|
|
|
||
|
|
#include <stdlib.h>
|
||
|
|
#include <stdio.h>
|
||
|
|
|
||
|
|
TEST_CASE(test_array_init_and_destroy) {
|
||
|
|
c_AdjList_t array;
|
||
|
|
c_err_t err = c_AdjList_Init(&array, 10, 0);
|
||
|
|
|
||
|
|
ASSERT_INT_EQ_MSG(C_SUCCESS, err, "Initialization should succeed");
|
||
|
|
ASSERT_PTR_NOT_NULL(array.array);
|
||
|
|
ASSERT_LL_EQ(10, array.capacity);
|
||
|
|
ASSERT_LL_EQ(0, array.size);
|
||
|
|
|
||
|
|
c_AdjList_Destroy(&array);
|
||
|
|
ASSERT_TRUE(array.array == NULL);
|
||
|
|
ASSERT_LL_EQ(0, array.capacity);
|
||
|
|
ASSERT_LL_EQ(0, array.size);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_CASE(test_array_append_and_auto_resize) {
|
||
|
|
c_AdjList_t array;
|
||
|
|
// Start with a small capacity of 2 to force automatic geometric doubling
|
||
|
|
c_AdjList_Init(&array, 2, 0);
|
||
|
|
|
||
|
|
c_err_t err1 = c_AdjList_Append(&array, 42);
|
||
|
|
c_err_t err2 = c_AdjList_Append(&array, 84);
|
||
|
|
|
||
|
|
ASSERT_INT_EQ(C_SUCCESS, err1);
|
||
|
|
ASSERT_INT_EQ(C_SUCCESS, err2);
|
||
|
|
ASSERT_LL_EQ(2, array.size);
|
||
|
|
ASSERT_LL_EQ(2, array.capacity);
|
||
|
|
|
||
|
|
// This 3rd append forces an automatic geometric growth event
|
||
|
|
c_err_t err3 = c_AdjList_Append(&array, 168);
|
||
|
|
ASSERT_INT_EQ(C_SUCCESS, err3);
|
||
|
|
ASSERT_LL_EQ(3, array.size);
|
||
|
|
ASSERT_TRUE(array.capacity > 2); // Capacity must double to 4
|
||
|
|
|
||
|
|
c_uint_t val;
|
||
|
|
c_AdjList_Get(&array, 0, &val); ASSERT_LL_EQ(42, val);
|
||
|
|
c_AdjList_Get(&array, 1, &val); ASSERT_LL_EQ(84, val);
|
||
|
|
c_AdjList_Get(&array, 2, &val); ASSERT_LL_EQ(168, val);
|
||
|
|
|
||
|
|
c_AdjList_Destroy(&array);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_CASE(test_array_get_and_set) {
|
||
|
|
c_AdjList_t array;
|
||
|
|
c_AdjList_Init(&array, 5, 0);
|
||
|
|
|
||
|
|
c_AdjList_Append(&array, 10);
|
||
|
|
c_AdjList_Append(&array, 20);
|
||
|
|
|
||
|
|
// Test mutating an existing valid slot index
|
||
|
|
c_err_t err_set = c_AdjList_Set(&array, 1, 99);
|
||
|
|
ASSERT_INT_EQ_MSG(C_SUCCESS, err_set, "Set inside array size bounds should succeed");
|
||
|
|
|
||
|
|
c_uint_t val;
|
||
|
|
c_AdjList_Get(&array, 1, &val);
|
||
|
|
ASSERT_LL_EQ(99, val);
|
||
|
|
|
||
|
|
// Error Contract Tests: Index boundary violation validation
|
||
|
|
c_err_t err_set_bad = c_AdjList_Set(&array, 5, 555);
|
||
|
|
c_err_t err_get_bad = c_AdjList_Get(&array, 5, &val);
|
||
|
|
ASSERT_INT_EQ_MSG(C_ERR_PARAM, err_set_bad, "Out-of-bounds mutation must fail");
|
||
|
|
ASSERT_INT_EQ_MSG(C_ERR_PARAM, err_get_bad, "Out-of-bounds retrieval must fail");
|
||
|
|
|
||
|
|
c_AdjList_Destroy(&array);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_CASE(test_array_manual_resize) {
|
||
|
|
c_AdjList_t array;
|
||
|
|
c_AdjList_Init(&array, 4, 0);
|
||
|
|
c_AdjList_Append(&array, 100);
|
||
|
|
c_AdjList_Append(&array, 200);
|
||
|
|
|
||
|
|
// Expand capacity manually
|
||
|
|
c_err_t err_expand = c_AdjList_Resize(&array, 20);
|
||
|
|
ASSERT_INT_EQ(C_SUCCESS, err_expand);
|
||
|
|
ASSERT_LL_EQ(20, array.capacity);
|
||
|
|
ASSERT_LL_EQ(2, array.size); // Content sizing remains unchanged
|
||
|
|
|
||
|
|
// Compress capacity down safely
|
||
|
|
c_err_t err_shrink = c_AdjList_Resize(&array, 4);
|
||
|
|
ASSERT_INT_EQ(C_SUCCESS, err_shrink);
|
||
|
|
ASSERT_LL_EQ(4, array.capacity);
|
||
|
|
|
||
|
|
// Error Contract Test: Trying to shrink capacity below the active tracking size
|
||
|
|
c_err_t err_bad_shrink = c_AdjList_Resize(&array, 1);
|
||
|
|
ASSERT_INT_EQ_MSG(C_ERR_PARAM, err_bad_shrink, "Shrinking below active elements count should be rejected");
|
||
|
|
|
||
|
|
c_AdjList_Destroy(&array);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_CASE(test_array_remove_element) {
|
||
|
|
c_AdjList_t array;
|
||
|
|
c_AdjList_Init(&array, 5, 0);
|
||
|
|
|
||
|
|
c_AdjList_Append(&array, 11); // Index 0
|
||
|
|
c_AdjList_Append(&array, 22); // Index 1
|
||
|
|
c_AdjList_Append(&array, 33); // Index 2
|
||
|
|
c_AdjList_Append(&array, 44); // Index 3
|
||
|
|
|
||
|
|
// Remove middle element (22 at index 1)
|
||
|
|
c_err_t err = c_AdjList_Remove(&array, 1);
|
||
|
|
ASSERT_INT_EQ(C_SUCCESS, err);
|
||
|
|
ASSERT_LL_EQ(3, array.size); // Total size scales down
|
||
|
|
|
||
|
|
c_uint_t val;
|
||
|
|
// Order verification check: Elements must shift leftwards
|
||
|
|
c_AdjList_Get(&array, 0, &val); ASSERT_LL_EQ(11, val);
|
||
|
|
c_AdjList_Get(&array, 1, &val); ASSERT_LL_EQ(33, val); // Old index 2 shifted here
|
||
|
|
c_AdjList_Get(&array, 2, &val); ASSERT_LL_EQ(44, val); // Old index 3 shifted here
|
||
|
|
|
||
|
|
// Error Contract Test: Remove non-existent index tracking profile
|
||
|
|
c_err_t err_out_of_bounds = c_AdjList_Remove(&array, 10);
|
||
|
|
ASSERT_INT_EQ(C_ERR_PARAM, err_out_of_bounds);
|
||
|
|
|
||
|
|
c_AdjList_Destroy(&array);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* -------------------------------------------------------------------------- */
|
||
|
|
/* Main Test Runner Execution Rig */
|
||
|
|
|
||
|
|
int main(void) {
|
||
|
|
TEST_START(c_AdjList Component Tests);
|
||
|
|
|
||
|
|
// Execution list configurations
|
||
|
|
RUN_TEST(test_array_init_and_destroy);
|
||
|
|
RUN_TEST(test_array_append_and_auto_resize);
|
||
|
|
RUN_TEST(test_array_get_and_set);
|
||
|
|
RUN_TEST(test_array_manual_resize);
|
||
|
|
RUN_TEST(test_array_remove_element);
|
||
|
|
|
||
|
|
TEST_REPORT();
|
||
|
|
|
||
|
|
RETURN_TEST_STATUS;
|
||
|
|
}
|