File size: 4,409 Bytes
78d2150 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
#include "../../unity/unity.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/* Unity fixtures */
void setUp(void) {
/* no-op */
}
void tearDown(void) {
/* no-op */
}
/* Helper to initialize an empty line object */
static void init_empty_line(struct line* l)
{
memset(l, 0, sizeof(*l));
}
/* Test: basic append on an empty line should allocate and store the field */
static void test_extract_field_basic_append(void)
{
struct line l;
init_empty_line(&l);
char buf[] = "hello";
extract_field(&l, buf, (idx_t)5);
TEST_ASSERT_EQUAL_INT(1, (int)l.nfields);
TEST_ASSERT_TRUE(l.nfields_allocated >= 1);
TEST_ASSERT_NOT_NULL(l.fields);
TEST_ASSERT_EQUAL_PTR(buf, l.fields[0].beg);
TEST_ASSERT_EQUAL_INT(5, (int)l.fields[0].len);
/* cleanup */
freeline(&l);
}
/* Test: multiple appends should grow capacity as needed and preserve entries */
static void test_extract_field_multiple_growth_and_preserve(void)
{
struct line l;
init_empty_line(&l);
enum { N = 50 }; /* enough iterations to ensure multiple growths */
char storage[N][16];
for (int i = 0; i < N; ++i)
{
/* create distinct content and pointers */
int n = snprintf(storage[i], sizeof(storage[i]), "f%02d", i);
if (n < 0) n = 0;
extract_field(&l, storage[i], (idx_t)n);
/* After each insertion, verify counters and last entry */
TEST_ASSERT_EQUAL_INT(i + 1, (int)l.nfields);
TEST_ASSERT_TRUE(l.nfields_allocated >= l.nfields);
TEST_ASSERT_EQUAL_PTR(storage[i], l.fields[i].beg);
TEST_ASSERT_EQUAL_INT(n, (int)l.fields[i].len);
/* Also spot-check some earlier entries remain intact */
if (i >= 3)
{
TEST_ASSERT_EQUAL_PTR(storage[0], l.fields[0].beg);
TEST_ASSERT_EQUAL_PTR(storage[1], l.fields[1].beg);
TEST_ASSERT_EQUAL_PTR(storage[2], l.fields[2].beg);
}
}
/* Verify all entries match after the loop */
for (int i = 0; i < N; ++i)
{
int n = (int)strlen(storage[i]); /* was written by snprintf */
TEST_ASSERT_EQUAL_PTR(storage[i], l.fields[i].beg);
TEST_ASSERT_EQUAL_INT(n, (int)l.fields[i].len);
}
/* cleanup */
freeline(&l);
}
/* Test: when there is preallocated capacity, pointer should not change on insert */
static void test_extract_field_no_realloc_when_capacity_available(void)
{
struct line l;
init_empty_line(&l);
/* Preallocate capacity for 8 fields */
l.nfields_allocated = 8;
l.fields = (struct field*) malloc(sizeof(struct field) * l.nfields_allocated);
TEST_ASSERT_NOT_NULL(l.fields);
struct field* oldptr = l.fields;
char buf1[] = "A";
extract_field(&l, buf1, (idx_t)1);
TEST_ASSERT_EQUAL_PTR(oldptr, l.fields);
TEST_ASSERT_EQUAL_INT(1, (int)l.nfields);
TEST_ASSERT_EQUAL_PTR(buf1, l.fields[0].beg);
TEST_ASSERT_EQUAL_INT(1, (int)l.fields[0].len);
/* cleanup */
freeline(&l);
}
/* Test: zero-length field should be recorded and increase count */
static void test_extract_field_zero_length(void)
{
struct line l;
init_empty_line(&l);
char dummy = 'X';
extract_field(&l, &dummy, (idx_t)0);
TEST_ASSERT_EQUAL_INT(1, (int)l.nfields);
TEST_ASSERT_EQUAL_PTR(&dummy, l.fields[0].beg);
TEST_ASSERT_EQUAL_INT(0, (int)l.fields[0].len);
/* Add another zero-length to ensure multiple zero-length fields work */
char dummy2 = 'Y';
extract_field(&l, &dummy2, (idx_t)0);
TEST_ASSERT_EQUAL_INT(2, (int)l.nfields);
TEST_ASSERT_EQUAL_PTR(&dummy2, l.fields[1].beg);
TEST_ASSERT_EQUAL_INT(0, (int)l.fields[1].len);
/* cleanup */
freeline(&l);
}
/* Test: large length value should be stored as-is (no copying performed) */
static void test_extract_field_large_len_value(void)
{
struct line l;
init_empty_line(&l);
char buf[] = "x";
idx_t large_len = (idx_t)123456; /* arbitrary large length, not used for access */
extract_field(&l, buf, large_len);
TEST_ASSERT_EQUAL_INT(1, (int)l.nfields);
TEST_ASSERT_EQUAL_PTR(buf, l.fields[0].beg);
TEST_ASSERT_EQUAL_INT((int)large_len, (int)l.fields[0].len);
/* cleanup */
freeline(&l);
}
int main(void)
{
UNITY_BEGIN();
RUN_TEST(test_extract_field_basic_append);
RUN_TEST(test_extract_field_multiple_growth_and_preserve);
RUN_TEST(test_extract_field_no_realloc_when_capacity_available);
RUN_TEST(test_extract_field_zero_length);
RUN_TEST(test_extract_field_large_len_value);
return UNITY_END();
} |