369 lines
11 KiB
C
369 lines
11 KiB
C
#include "malunal/containers/vector.h"
|
|
#include "malunal/microtest.h"
|
|
|
|
MICROTEST(vector_container, can_init_and_free) {
|
|
error_t result = {};
|
|
vector_container_t vector = {};
|
|
malunal_size_t temporary = 0;
|
|
|
|
result = vector_container_init(4, 32, libc_allocator(), &vector);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
|
|
allocator_mptr_t allocator;
|
|
result = vector_container_allocator(&vector, &allocator);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
MICROTEST_EXPECT_EQ(allocator, libc_allocator());
|
|
|
|
result = vector_container_stride(&vector, &temporary);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
MICROTEST_EXPECT_EQ(temporary, 4);
|
|
|
|
result = vector_container_count(&vector, &temporary);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
MICROTEST_EXPECT_EQ(temporary, 0);
|
|
|
|
result = vector_container_capacity(&vector, &temporary);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
MICROTEST_EXPECT_EQ(temporary, 32);
|
|
|
|
result = vector_container_free(&vector);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
|
|
result = vector_container_stride(&vector, &temporary);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
MICROTEST_EXPECT_EQ(temporary, 0);
|
|
|
|
result = vector_container_count(&vector, &temporary);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
MICROTEST_EXPECT_EQ(temporary, 0);
|
|
|
|
result = vector_container_capacity(&vector, &temporary);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
MICROTEST_EXPECT_EQ(temporary, 0);
|
|
}
|
|
|
|
MICROTEST(vector_container, append_then_get_round_trips_value) {
|
|
error_t result = {};
|
|
vector_container_t vector = {};
|
|
vector_container_init(4, 32, libc_allocator(), &vector);
|
|
|
|
malunal_int32_t a = 42;
|
|
result = vector_container_append(&vector, &a);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
|
|
malunal_size_t count = 0;
|
|
result = vector_container_count(&vector, &count);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
MICROTEST_EXPECT_EQ(count, 1);
|
|
|
|
malunal_int32_t out = 0;
|
|
result = vector_container_get(&vector, 0, &out);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
MICROTEST_EXPECT_EQ(out, 42);
|
|
|
|
vector_container_free(&vector);
|
|
}
|
|
|
|
MICROTEST(vector_container, append_past_capacity_grows_and_preserves) {
|
|
error_t result = {};
|
|
vector_container_t vector = {};
|
|
vector_container_init(4, 4, libc_allocator(), &vector);
|
|
|
|
malunal_int32_t vals[5] = { 10, 20, 30, 40, 50 };
|
|
for (malunal_int32_t index = 0; index < 5; index++) {
|
|
result = vector_container_append(&vector, &vals[index]);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
}
|
|
|
|
malunal_size_t capacity = 0;
|
|
malunal_size_t count = 0;
|
|
vector_container_capacity(&vector, &capacity);
|
|
vector_container_count(&vector, &count);
|
|
MICROTEST_EXPECT_GT(capacity, 5);
|
|
MICROTEST_EXPECT_EQ(count, 5);
|
|
for (malunal_int32_t index = 0; index < 5; index++) {
|
|
malunal_int32_t out = 0;
|
|
vector_container_get(&vector, index, &out);
|
|
MICROTEST_EXPECT_EQ(out, vals[index]);
|
|
}
|
|
|
|
vector_container_free(&vector);
|
|
}
|
|
|
|
MICROTEST(vector_container, remove_first_matching_element) {
|
|
error_t result = {};
|
|
vector_container_t vector = {};
|
|
vector_container_init(4, 32, libc_allocator(), &vector);
|
|
|
|
malunal_int32_t vals[3] = { 10, 20, 30 };
|
|
vector_container_append(&vector, &vals[0]);
|
|
vector_container_append(&vector, &vals[1]);
|
|
vector_container_append(&vector, &vals[2]);
|
|
|
|
result = vector_container_remove(&vector, &vals[0]);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
|
|
malunal_size_t count = 0;
|
|
vector_container_count(&vector, &count);
|
|
MICROTEST_EXPECT_EQ(count, 2);
|
|
|
|
malunal_int32_t value = 0;
|
|
vector_container_get(&vector, 0, &value);
|
|
MICROTEST_EXPECT_EQ(value, 20);
|
|
|
|
vector_container_free(&vector);
|
|
}
|
|
|
|
MICROTEST(vector_container, remove_of_absent_element_succeeds) {
|
|
error_t result = {};
|
|
vector_container_t vector = {};
|
|
vector_container_init(4, 32, libc_allocator(), &vector);
|
|
|
|
malunal_int32_t a = 1;
|
|
vector_container_append(&vector, &a);
|
|
|
|
malunal_int32_t missing = 404;
|
|
result = vector_container_remove(&vector, &missing);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
|
|
malunal_size_t count = 0;
|
|
vector_container_count(&vector, &count);
|
|
MICROTEST_EXPECT_EQ(count, 1);
|
|
}
|
|
|
|
MICROTEST(vector_container, contains_finds_a_present_element) {
|
|
error_t result = {};
|
|
vector_container_t vector = {};
|
|
vector_container_init(4, 32, libc_allocator(), &vector);
|
|
|
|
malunal_int32_t a = 1;
|
|
malunal_int32_t b = 2;
|
|
vector_container_append(&vector, &a);
|
|
vector_container_append(&vector, &b);
|
|
|
|
result = vector_container_contains(&vector, &b);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
|
|
vector_container_free(&vector);
|
|
}
|
|
|
|
MICROTEST(vector_container, contains_rejects_an_absent_element) {
|
|
error_t result = {};
|
|
vector_container_t vector = {};
|
|
vector_container_init(4, 32, libc_allocator(), &vector);
|
|
|
|
malunal_int32_t a = 1;
|
|
malunal_int32_t b = 2;
|
|
vector_container_append(&vector, &a);
|
|
vector_container_append(&vector, &b);
|
|
|
|
malunal_int32_t missing = 404;
|
|
result = vector_container_contains(&vector, &missing);
|
|
MICROTEST_EXPECT_EQ(result.domain, &ERROR_DOMAIN_CONTAINER_T);
|
|
MICROTEST_EXPECT_EQ(result.code, CONTAINER_ERROR_FAILURE);
|
|
|
|
vector_container_free(&vector);
|
|
}
|
|
|
|
MICROTEST(vector_container, clear_resets_count_but_keeps_capacity) {
|
|
error_t result = {};
|
|
vector_container_t vector = {};
|
|
vector_container_init(4, 32, libc_allocator(), &vector);
|
|
|
|
malunal_int32_t a = 1;
|
|
malunal_int32_t b = 2;
|
|
vector_container_append(&vector, &a);
|
|
vector_container_append(&vector, &b);
|
|
|
|
result = vector_container_clear(&vector);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
|
|
malunal_size_t count = 99;
|
|
malunal_size_t capacity = 0;
|
|
vector_container_count(&vector, &count);
|
|
vector_container_capacity(&vector, &capacity);
|
|
MICROTEST_EXPECT_EQ(count, 0);
|
|
MICROTEST_EXPECT_EQ(capacity, 32);
|
|
|
|
vector_container_free(&vector);
|
|
}
|
|
|
|
MICROTEST(vector_container, set_overwrites_existing_element) {
|
|
error_t result = {};
|
|
vector_container_t vector = {};
|
|
vector_container_init(4, 32, libc_allocator(), &vector);
|
|
|
|
malunal_int32_t vals[3] = { 10, 20, 333 };
|
|
vector_container_append(&vector, &vals[0]);
|
|
vector_container_append(&vector, &vals[1]);
|
|
|
|
result = vector_container_set(&vector, 0, &vals[2]);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
|
|
malunal_int32_t out = 0;
|
|
vector_container_get(&vector, 0, &out);
|
|
MICROTEST_EXPECT_EQ(out, 333);
|
|
|
|
vector_container_free(&vector);
|
|
}
|
|
|
|
MICROTEST(vector_container, get_set_reports_out_of_bounds_at_count) {
|
|
error_t result = {};
|
|
vector_container_t vector = {};
|
|
vector_container_init(4, 32, libc_allocator(), &vector);
|
|
|
|
malunal_int32_t a = 10;
|
|
malunal_int32_t out = 0;
|
|
result = vector_container_get(&vector, 4, &out);
|
|
MICROTEST_EXPECT_EQ(result.domain, &ERROR_DOMAIN_CONTAINER_T);
|
|
MICROTEST_EXPECT_EQ(result.code, CONTAINER_ERROR_OUT_OF_BOUNDS);
|
|
|
|
result = NO_ERROR;
|
|
result = vector_container_set(&vector, 4, &out);
|
|
MICROTEST_EXPECT_EQ(result.domain, &ERROR_DOMAIN_CONTAINER_T);
|
|
MICROTEST_EXPECT_EQ(result.code, CONTAINER_ERROR_OUT_OF_BOUNDS);
|
|
|
|
vector_container_free(&vector);
|
|
}
|
|
|
|
MICROTEST(vector_container, insert_at_end_appends_value) {
|
|
error_t result = {};
|
|
vector_container_t vector = {};
|
|
vector_container_init(4, 32, libc_allocator(), &vector);
|
|
|
|
malunal_int32_t vals[3] = { 10, 20, 30 };
|
|
vector_container_append(&vector, &vals[0]);
|
|
vector_container_append(&vector, &vals[1]);
|
|
|
|
result = vector_container_insert_at(&vector, 2, &vals[2]);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
|
|
malunal_int32_t out = 0;
|
|
vector_container_get(&vector, 2, &out);
|
|
MICROTEST_EXPECT_EQ(out, vals[2]);
|
|
|
|
vector_container_free(&vector);
|
|
}
|
|
|
|
MICROTEST(vector_container, insert_at_middle_shifts_later_elements) {
|
|
error_t result = {};
|
|
vector_container_t vector = {};
|
|
vector_container_init(4, 32, libc_allocator(), &vector);
|
|
|
|
malunal_int32_t vals[3] = { 10, 20, 30 };
|
|
vector_container_append(&vector, &vals[0]);
|
|
vector_container_append(&vector, &vals[2]);
|
|
|
|
result = vector_container_insert_at(&vector, 1, &vals[1]);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
|
|
malunal_int32_t outs[3] = { 0, 0, 0};
|
|
vector_container_get(&vector, 0, &outs[0]);
|
|
vector_container_get(&vector, 1, &outs[1]);
|
|
vector_container_get(&vector, 2, &outs[2]);
|
|
MICROTEST_EXPECT_EQ(outs[0], vals[0]);
|
|
MICROTEST_EXPECT_EQ(outs[1], vals[1]);
|
|
MICROTEST_EXPECT_EQ(outs[2], vals[2]);
|
|
|
|
vector_container_free(&vector);
|
|
}
|
|
|
|
MICROTEST(vector_container, remove_at_last_preserves_earlier_elements) {
|
|
error_t result = {};
|
|
vector_container_t vector = {};
|
|
vector_container_init(4, 32, libc_allocator(), &vector);
|
|
|
|
malunal_int32_t vals[3] = { 10, 20, 30 };
|
|
vector_container_append(&vector, &vals[0]);
|
|
vector_container_append(&vector, &vals[1]);
|
|
vector_container_append(&vector, &vals[2]);
|
|
|
|
result = vector_container_remove_at(&vector, 2);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
|
|
malunal_size_t count = 0;
|
|
vector_container_count(&vector, &count);
|
|
MICROTEST_EXPECT_EQ(count, 2);
|
|
|
|
malunal_int32_t outs[2] = { 0, 0 };
|
|
vector_container_get(&vector, 0, &outs[0]);
|
|
vector_container_get(&vector, 1, &outs[1]);
|
|
MICROTEST_EXPECT_EQ(outs[0], vals[0]);
|
|
MICROTEST_EXPECT_EQ(outs[1], vals[1]);
|
|
|
|
vector_container_free(&vector);
|
|
}
|
|
|
|
MICROTEST(vector_container, remove_at_middle_shifts_later_elements_left) {
|
|
error_t result = {};
|
|
vector_container_t vector = {};
|
|
vector_container_init(4, 32, libc_allocator(), &vector);
|
|
|
|
malunal_int32_t vals[3] = { 10, 20, 30 };
|
|
vector_container_append(&vector, &vals[0]);
|
|
vector_container_append(&vector, &vals[1]);
|
|
vector_container_append(&vector, &vals[2]);
|
|
|
|
result = vector_container_remove_at(&vector, 0);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
|
|
malunal_size_t count = 0;
|
|
vector_container_count(&vector, &count);
|
|
MICROTEST_EXPECT_EQ(count, 2);
|
|
|
|
malunal_int32_t outs[2] = { 0, 0 };
|
|
vector_container_get(&vector, 0, &outs[0]);
|
|
vector_container_get(&vector, 1, &outs[1]);
|
|
MICROTEST_EXPECT_EQ(outs[0], vals[1]);
|
|
MICROTEST_EXPECT_EQ(outs[1], vals[2]);
|
|
|
|
vector_container_free(&vector);
|
|
}
|
|
|
|
MICROTEST(vector_container, remove_at_on_empty_vector_is_out_of_bounds) {
|
|
error_t result = {};
|
|
vector_container_t vector = {};
|
|
vector_container_init(4, 32, libc_allocator(), &vector);
|
|
|
|
result = vector_container_remove_at(&vector, 0);
|
|
MICROTEST_EXPECT_EQ(result.domain, &ERROR_DOMAIN_CONTAINER_T);
|
|
MICROTEST_EXPECT_EQ(result.code, CONTAINER_ERROR_OUT_OF_BOUNDS);
|
|
|
|
vector_container_free(&vector);
|
|
}
|
|
|
|
MICROTEST(vector_container, index_of_finds_present_element) {
|
|
error_t result = {};
|
|
vector_container_t vector = {};
|
|
vector_container_init(4, 32, libc_allocator(), &vector);
|
|
|
|
malunal_int32_t vals[3] = { 50, 60, 70 };
|
|
vector_container_append(&vector, &vals[0]);
|
|
vector_container_append(&vector, &vals[1]);
|
|
vector_container_append(&vector, &vals[2]);
|
|
|
|
malunal_size_t index = (malunal_size_t)-1;
|
|
result = vector_container_index_of(&vector, &vals[1], &index);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
MICROTEST_EXPECT_EQ(index, 1);
|
|
|
|
vector_container_free(&vector);
|
|
}
|
|
|
|
MICROTEST(vector_container, index_of_reports_missing_element) {
|
|
error_t result = {};
|
|
vector_container_t vector = {};
|
|
vector_container_init(4, 32, libc_allocator(), &vector);
|
|
|
|
malunal_int32_t a = 50;
|
|
vector_container_append(&vector, &a);
|
|
|
|
malunal_size_t index = 0;
|
|
malunal_int32_t needle = 333;
|
|
result = vector_container_index_of(&vector, &needle, &index);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
MICROTEST_EXPECT_EQ(index, (malunal_size_t)-1);
|
|
|
|
vector_container_free(&vector);
|
|
}
|