#include "../../unity/unity.h" #include #include #include /* The structs and the target function are available from the including TU. */ /* Helper to create a buffer_record with a specified number of linked struct line nodes. If alloc_buf is true, also allocate a small data buffer. */ static struct buffer_record* helper_make_buffer(size_t n_nodes, int alloc_buf) { struct buffer_record *buf = (struct buffer_record*)malloc(sizeof *buf); TEST_ASSERT_NOT_NULL_MESSAGE(buf, "Failed to allocate buffer_record"); /* Initialize fields conservatively */ memset(buf, 0, sizeof *buf); buf->bytes_alloc = 0; buf->bytes_used = 0; buf->start_line = 0; buf->first_available = 0; buf->num_lines = 0; buf->line_start = NULL; buf->curr_line = NULL; buf->next = NULL; if (alloc_buf) { buf->buffer = (char*)malloc(128); TEST_ASSERT_NOT_NULL_MESSAGE(buf->buffer, "Failed to allocate buf->buffer"); memset(buf->buffer, 'A', 127); buf->buffer[127] = '\0'; buf->bytes_alloc = 128; buf->bytes_used = 64; } else { buf->buffer = NULL; } struct line *head = NULL; struct line *prev = NULL; for (size_t i = 0; i < n_nodes; i++) { struct line *node = (struct line*)malloc(sizeof *node); TEST_ASSERT_NOT_NULL_MESSAGE(node, "Failed to allocate line node"); memset(node, 0, sizeof *node); node->used = 0; node->insert_index = 0; node->retrieve_index = 0; node->next = NULL; if (!head) head = node; if (prev) prev->next = node; prev = node; } buf->line_start = head; buf->curr_line = (head && head->next) ? head->next : head; return buf; } void setUp(void) { /* No global state to prepare for these tests */ } void tearDown(void) { /* Nothing to clean up; each test frees via free_buffer */ } /* Test: free_buffer handles a NULL data buffer and no line nodes */ void test_free_buffer_null_buffer_no_lines(void) { struct buffer_record *buf = helper_make_buffer(0, 0); /* Call the function under test */ free_buffer(buf); /* If we reached here without crashing, consider it success */ TEST_ASSERT_TRUE(1); } /* Test: free_buffer handles a single line node and an allocated data buffer */ void test_free_buffer_single_line_node_with_buffer(void) { struct buffer_record *buf = helper_make_buffer(1, 1); free_buffer(buf); TEST_ASSERT_TRUE(1); } /* Test: free_buffer handles a long chain of 1000 line nodes efficiently */ void test_free_buffer_long_chain_many_nodes(void) { struct buffer_record *buf = helper_make_buffer(1000, 1); free_buffer(buf); TEST_ASSERT_TRUE(1); } /* Test: free_buffer ignores curr_line and other fields, freeing from line_start */ void test_free_buffer_curr_line_not_head_fields_populated(void) { struct buffer_record *buf = helper_make_buffer(5, 1); /* Populate fields to non-zero to ensure they don't affect freeing */ buf->bytes_alloc = 1024; buf->bytes_used = 512; buf->start_line = 10; buf->first_available = 12; buf->num_lines = 5; /* Make curr_line point somewhere in the middle */ if (buf->line_start && buf->line_start->next) { buf->curr_line = buf->line_start->next->next ? buf->line_start->next->next : buf->line_start->next; } free_buffer(buf); TEST_ASSERT_TRUE(1); } int main(void) { UNITY_BEGIN(); RUN_TEST(test_free_buffer_null_buffer_no_lines); RUN_TEST(test_free_buffer_single_line_node_with_buffer); RUN_TEST(test_free_buffer_long_chain_many_nodes); RUN_TEST(test_free_buffer_curr_line_not_head_fields_populated); return UNITY_END(); }