#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); }