#include "../src/vector.c" #include #include #include #include #include #include #include #include "../src/testing.h" static int test_vector_new_with(void) { int rc = -1; const struct Vector *v = NULL; test_start("vector_new_with()"); { testing("allocating struct Vector with small capacity"); const size_t capacity = 1U; const size_t max_capacity = 2U; const size_t multiplier = 3U; const size_t size = 4U; if (vector_new_with( capacity, max_capacity, multiplier, size, &v )) { logerr("vector_new_with()"); goto out; } assert(v->capacity == capacity); assert(v->count == 0U); assert(v->max_capacity == max_capacity); assert(v->multiplier == multiplier); assert(v->value_size == size); vector_free(v); v = NULL; test_ok(); } { testing("we can't ask for a capacity beyond max_capacity"); const size_t max_capacity = 2U; assert(v == NULL); assert(vector_new_with( max_capacity + 1, max_capacity, 1U, 1U, &v ) == EOVERFLOW); assert(v == NULL); test_ok(); } rc = 0; out: if (v != NULL) { vector_free(v); v = NULL; } return rc; } static int test_vector_new(void) { int rc = -1; const struct Vector *v = NULL; test_start("vector_new()"); { testing("simple allocation of int[]"); const size_t size = sizeof(int); if (vector_new(size, &v)) { logerr("vector_new()"); goto out; } assert(v->capacity == VECTOR_DEFAULT_CAPACITY); assert(v->count == 0); assert(v->max_capacity == VECTOR_MAX_CAPACITY); assert(v->multiplier == GROWTH_MULTIPLIER); assert(v->value_size == size); vector_free(v); v = NULL; test_ok(); } { testing("simple allocation of custom struct"); struct Custom { int a; char b; void *c; } custom; const size_t size = sizeof(custom); if (vector_new(size, &v)) { logerr("vector_new()"); goto out; } assert(v->capacity == VECTOR_DEFAULT_CAPACITY); assert(v->count == 0); assert(v->max_capacity == VECTOR_MAX_CAPACITY); assert(v->multiplier == GROWTH_MULTIPLIER); assert(v->value_size == size); vector_free(v); v = NULL; test_ok(); } rc = 0; out: if (v != NULL) { vector_free(v); v = NULL; } return rc; } static int test_vector_free(void) { int rc = -1; const struct Vector *v = NULL; test_start("vector_free()"); { testing("*v becomes NULL again after vector_free(&v)"); assert(v == NULL); if (vector_new(sizeof(char), &v)) { logerr("vector_new()"); goto out; } assert(v != NULL); vector_free(v); v = NULL; test_ok(); } rc = 0; out: return rc; } static int test_vector_count(void) { int rc = -1; const struct Vector *v = NULL; test_start("vector_count()"); { testing("we get whatever the count is"); if (vector_new(sizeof(unsigned long), &v)) { logerr("vector_new()"); goto out; } assert(vector_count(v) == 0); assert(v->count == 0); const unsigned long value = 123; if (vector_push_back(v, &value)) { logerr("vector_push_back()"); goto out; } assert(vector_count(v) == 1); assert(v->count == 1); vector_free(v); v = NULL; test_ok(); } rc = 0; out: if (v != NULL) { vector_free(v); v = NULL; } return rc; } static void test_next_capacity(void) { test_start("next_capacity()"); // FIXME: write tests } static void test_next_size(void) { test_start("next_size()"); // FIXME: write tests } static int test_vector_nth(void) { int rc = -1; const struct Vector *v = NULL; const int first = 123; const int second = 321; const int third = 555; const int values[] = { first, second, third }; const size_t values_len = sizeof(values) / sizeof(values[0]); test_start("vector_nth()"); { testing("nth with growth"); if (vector_new(sizeof(int), &v)) { logerr("vector_new_with()"); goto out; } for (unsigned int i = 0; i < values_len; i++) { if (vector_push_back(v, &values[i])) { logerr("vector_push_back(v, values[%d])", i); goto out; } } int nth; assert(vector_nth(v, 0U, (void *)&nth) == 0); assert(nth == 123); assert(vector_nth(v, 1U, (void *)&nth) == 0); assert(nth == 321); assert(vector_nth(v, 2U, (void *)&nth) == 0); assert(nth == 555); vector_free(v); v = NULL; test_ok(); } { testing("nth out of bounds errors"); if (vector_new(sizeof(int), &v)) { logerr("vector_new_with()"); goto out; } for (unsigned int i = 0; i < values_len; i++) { if (vector_push_back(v, &values[i])) { logerr("vector_push_back(v, values[%d])", i); goto out; } } int nth = 222; assert(vector_nth(v, 4U, (void *)&nth) != 0); assert(nth == 222); vector_free(v); v = NULL; test_ok(); } rc = 0; out: if (v != NULL) { vector_free(v); v = NULL; } return rc; } static int test_vector_push_back(void) { int rc = -1; const struct Vector *v = NULL; test_start("vector_push_back()"); { testing("a single push back overwrites existing garbage"); if (vector_new(sizeof(long long), &v)) { logerr("vector_new()"); goto out; } const long long before = 123; const long long after = 321; v->values[0] = (void *)before; if (vector_push_back(v, &after)) { logerr("vector_push_back()"); goto out; } assert(v->values[0] == (void *)after); vector_free(v); v = NULL; test_ok(); } { testing("push back beyond capacity causes reallocation"); const unsigned long data = 2222U; if (vector_new(sizeof(unsigned long), &v)) { logerr("vector_new()"); goto out; } assert(v->capacity == VECTOR_DEFAULT_CAPACITY); assert(vector_count(v) == 0); for (unsigned int i = 0; i < v->capacity; i++) { if (vector_push_back(v, &data)) { logerr("vector_push_back(): i = %d", i); goto out; } } assert(v->values[0] == (void *)data); const size_t capacity = v->capacity; assert(capacity == vector_count(v)); // we grow the vector here if (vector_push_back(v, &data)) { logerr("vector_push_vack()"); goto out; } const size_t new_capacity = capacity * v->multiplier; assert(v->capacity == new_capacity); assert(vector_count(v) == capacity + 1U); assert(vector_push_back(v, &data) == 0); assert(v->capacity == new_capacity); assert(v->count == capacity + 2U); vector_free(v); v = NULL; test_ok(); } rc = 0; out: if (v != NULL) { vector_free(v); v = NULL; } return rc; } static int test_vector_pop_back(void) { test_start("vector_pop_back()"); return 0; } int main(void) { int rc = -1; if (test_vector_new_with()) { logerr("test_vector_new_with()"); goto out; } if (test_vector_new()) { logerr("test_vector_new()"); goto out; } if (test_vector_free()) { logerr("test_vector_free()"); goto out; } if (test_vector_count()) { logerr("test_vector_count()"); goto out; } test_next_capacity(); test_next_size(); if (test_vector_nth()) { logerr("test_vector_nth()"); goto out; } if (test_vector_push_back()) { logerr("test_vector_push_back()"); goto out; } if (test_vector_pop_back()) { logerr("test_vector_pop_back()"); goto out; } rc = 0; out: return !!rc; }