Refactor tests (#31)

Refactor tests in order for the component or logic that they are testing to be contained into individual sub-tests instead of all tests being contained in one big test for the whole data structure.

Add testing for out-of-memory (OOM) conditions. This makes the source code now 100% covered.

Bug fix! A bug has been identified and fixed in the list data structure in the list_add_last function. This bug would occur when adding an item to the back of the list because the pointers were not being updated properly.

Minor Bug fix! A bug has been identified and fixed in the unordered_set, unordered_map, unordered_multiset, and unordered_multimap data structures in their respective unordered_xxx_put functions. This bug would occur in an out-of-memory condition, which would cause the size of the collection to increase without actually adding the new element to it.
This commit is contained in:
Bailey Thompson
2019-05-04 17:59:20 -04:00
committed by GitHub
parent 10a11dc1aa
commit e2d596e4bd
36 changed files with 3750 additions and 2295 deletions

View File

@@ -3,7 +3,7 @@ project(Containers C)
set(CMAKE_C_STANDARD 90)
set(CMAKE_C_FLAGS "-pedantic -Werror -g -O0 -Wall -fprofile-arcs -ftest-coverage")
set(CMAKE_C_FLAGS "-pedantic -ldl -g -O0 -Wall -fprofile-arcs -ftest-coverage")
add_executable(Containers tst/test.c tst/test.h
src/array.c src/array.h tst/array.c

View File

@@ -38,3 +38,4 @@ Data structures which adapt other containers to enhance functionality.
* stack - adapts a container to provide stack (last-in first-out)
* queue - adapts a container to provide queue (first-in first-out)
* priority_queue - adapts a container to provide priority queue

View File

@@ -154,7 +154,8 @@ int array_get(void *const data, array me, const int index)
}
/**
* Frees the array memory.
* Frees the array memory. Performing further operations after calling this
* function results in undefined behavior.
*
* @param me the array to free from memory
*

View File

@@ -460,7 +460,8 @@ int deque_clear(deque me)
}
/**
* Destroys the deque.
* Destroys the deque. Performing further operations after calling this function
* results in undefined behavior.
*
* @param me the deque to destroy
*

View File

@@ -367,7 +367,8 @@ void forward_list_clear(forward_list me)
}
/**
* Destroys the singly-linked list.
* Destroys the singly-linked list. Performing further operations after calling
* this function results in undefined behavior.
*
* @param me the singly-linked list to destroy
*

View File

@@ -153,28 +153,7 @@ static struct node *list_get_node_at(list me, const int index)
*/
int list_add_first(list me, void *const data)
{
struct node *const traverse = me->head;
struct node *const add = malloc(sizeof(struct node));
if (!add) {
return -ENOMEM;
}
add->data = malloc(me->bytes_per_item);
if (!add->data) {
free(add);
return -ENOMEM;
}
add->prev = NULL;
memcpy(add->data, data, me->bytes_per_item);
add->next = traverse;
if (traverse) {
traverse->prev = add;
}
me->head = add;
if (!me->tail) {
me->tail = traverse;
}
me->item_count++;
return 0;
return list_add_at(me, 0, data);
}
/**
@@ -190,19 +169,10 @@ int list_add_first(list me, void *const data)
*/
int list_add_at(list me, const int index, void *const data)
{
struct node *traverse;
struct node *add;
if (index < 0 || index > me->item_count) {
return -EINVAL;
}
if (index == 0) {
return list_add_first(me, data);
}
if (index == me->item_count) {
return list_add_last(me, data);
}
/* The new node will go right before this node. */
traverse = list_get_node_at(me, index);
add = malloc(sizeof(struct node));
if (!add) {
return -ENOMEM;
@@ -212,11 +182,31 @@ int list_add_at(list me, const int index, void *const data)
free(add);
return -ENOMEM;
}
add->prev = traverse->prev;
memcpy(add->data, data, me->bytes_per_item);
add->next = traverse;
traverse->prev->next = add;
traverse->prev = add;
if (!me->head) {
add->prev = NULL;
add->next = NULL;
me->head = add;
me->tail = add;
} else if (index == 0) {
struct node *const traverse = me->head;
traverse->prev = add;
add->prev = NULL;
add->next = traverse;
me->head = add;
} else if (index == me->item_count) {
struct node *const traverse = me->tail;
traverse->next = add;
add->prev = traverse;
add->next = NULL;
me->tail = add;
} else {
struct node *const traverse = list_get_node_at(me, index);
add->prev = traverse->prev;
add->next = traverse;
traverse->prev->next = add;
traverse->prev = add;
}
me->item_count++;
return 0;
}
@@ -232,25 +222,7 @@ int list_add_at(list me, const int index, void *const data)
*/
int list_add_last(list me, void *const data)
{
struct node *const traverse = me->tail;
struct node *const add = malloc(sizeof(struct node));
if (!add) {
return -ENOMEM;
}
add->data = malloc(me->bytes_per_item);
if (!add->data) {
free(add);
return -ENOMEM;
}
add->prev = traverse;
memcpy(add->data, data, me->bytes_per_item);
add->next = NULL;
if (traverse) {
traverse->next = add;
}
me->tail = add;
me->item_count++;
return 0;
return list_add_at(me, me->item_count, data);
}
/*
@@ -437,7 +409,8 @@ void list_clear(list me)
}
/**
* Destroys the doubly-linked list.
* Destroys the doubly-linked list. Performing further operations after calling
* this function results in undefined behavior.
*
* @param me the doubly-linked list to destroy
*

View File

@@ -212,7 +212,6 @@ static struct node *map_repair(map me,
return grand_child;
}
/* Impossible to get here. */
return NULL;
}
/*
@@ -612,7 +611,8 @@ void map_clear(map me)
}
/**
* Frees the map memory.
* Frees the map memory. Performing further operations after calling this
* function results in undefined behavior.
*
* @param me the map to free from memory
*

View File

@@ -228,7 +228,6 @@ static struct node *multimap_repair(multimap me,
return grand_child;
}
/* Impossible to get here. */
return NULL;
}
/*
@@ -750,7 +749,8 @@ void multimap_clear(multimap me)
}
/**
* Frees the multi-map memory.
* Frees the multi-map memory. Performing further operations after calling this
* function results in undefined behavior.
*
* @param me the multi-map to free from memory
*

View File

@@ -210,7 +210,6 @@ static struct node *multiset_repair(multiset me,
return grand_child;
}
/* Impossible to get here. */
return NULL;
}
/*
@@ -625,7 +624,8 @@ void multiset_clear(multiset me)
}
/**
* Frees the multi-set memory.
* Frees the multi-set memory. Performing further operations after calling this
* function results in undefined behavior.
*
* @param me the multi-set to free from memory
*

View File

@@ -223,7 +223,8 @@ int priority_queue_clear(priority_queue me)
}
/**
* Frees the priority queue memory.
* Frees the priority queue memory. Performing further operations after calling
* this function results in undefined behavior.
*
* @param me the priority queue to free from memory
*

View File

@@ -178,7 +178,8 @@ int queue_clear(queue me)
}
/**
* Destroys the queue.
* Destroys the queue. Performing further operations after calling this function
* results in undefined behavior.
*
* @param me the queue to destroy
*

View File

@@ -207,7 +207,6 @@ static struct node *set_repair(set me,
return grand_child;
}
/* Impossible to get here. */
return NULL;
}
/*
@@ -576,7 +575,8 @@ void set_clear(set me)
}
/**
* Frees the set memory.
* Frees the set memory. Performing further operations after calling this
* function results in undefined behavior.
*
* @param me the set to free from memory
*

View File

@@ -157,7 +157,8 @@ int stack_clear(stack me)
}
/**
* Destroys the stack and frees the memory associated with it.
* Frees the stack memory. Performing further operations after calling this
* function results in undefined behavior.
*
* @param me the stack to destroy
*

View File

@@ -257,9 +257,15 @@ static struct node *const unordered_map_create_element(unordered_map me,
*/
int unordered_map_put(unordered_map me, void *const key, void *const value)
{
const unsigned long hash = unordered_map_hash(me, key);
const int index = (int) (hash % me->capacity);
int index;
if (me->size + 1 >= RESIZE_AT * me->capacity) {
const int rc = unordered_map_resize(me);
if (rc != 0) {
return rc;
}
}
index = (int) (hash % me->capacity);
if (!me->buckets[index]) {
me->buckets[index] = unordered_map_create_element(me, hash, key, value);
if (!me->buckets[index]) {
@@ -284,9 +290,6 @@ int unordered_map_put(unordered_map me, void *const key, void *const value)
}
}
me->size++;
if (me->size >= RESIZE_AT * me->capacity) {
return unordered_map_resize(me);
}
return 0;
}
@@ -411,7 +414,8 @@ int unordered_map_clear(unordered_map me)
}
/**
* Frees the unordered map memory.
* Frees the unordered map memory. Performing further operations after calling
* this function results in undefined behavior.
*
* @param me the unordered map to free from memory
*

View File

@@ -280,7 +280,14 @@ int unordered_multimap_put(unordered_multimap me,
void *const value)
{
const unsigned long hash = unordered_multimap_hash(me, key);
const int index = (int) (hash % me->capacity);
int index;
if (me->size + 1 >= RESIZE_AT * me->capacity) {
const int rc = unordered_multimap_resize(me);
if (rc != 0) {
return rc;
}
}
index = (int) (hash % me->capacity);
if (!me->buckets[index]) {
me->buckets[index] =
unordered_multimap_create_element(me, hash, key, value);
@@ -299,9 +306,6 @@ int unordered_multimap_put(unordered_multimap me,
}
}
me->size++;
if (me->size >= RESIZE_AT * me->capacity) {
return unordered_multimap_resize(me);
}
return 0;
}
@@ -538,7 +542,8 @@ int unordered_multimap_clear(unordered_multimap me)
}
/**
* Frees the unordered multi-map memory.
* Frees the unordered multi-map memory. Performing further operations after
* calling this function results in undefined behavior.
*
* @param me the unordered multi-map to free from memory
*

View File

@@ -247,9 +247,15 @@ unordered_multiset_create_element(unordered_multiset me,
*/
int unordered_multiset_put(unordered_multiset me, void *const key)
{
const unsigned long hash = unordered_multiset_hash(me, key);
const int index = (int) (hash % me->capacity);
int index;
if (me->used + 1 >= RESIZE_AT * me->capacity) {
const int rc = unordered_multiset_resize(me);
if (rc != 0) {
return rc;
}
}
index = (int) (hash % me->capacity);
if (!me->buckets[index]) {
me->buckets[index] = unordered_multiset_create_element(me, hash, key);
if (!me->buckets[index]) {
@@ -277,9 +283,6 @@ int unordered_multiset_put(unordered_multiset me, void *const key)
}
me->size++;
me->used++;
if (me->used >= RESIZE_AT * me->capacity) {
return unordered_multiset_resize(me);
}
return 0;
}
@@ -440,7 +443,8 @@ int unordered_multiset_clear(unordered_multiset me)
}
/**
* Frees the unordered multi-set memory.
* Frees the unordered multi-set memory. Performing further operations after
* calling this function results in undefined behavior.
*
* @param me the unordered multi-set to free from memory
*

View File

@@ -241,9 +241,15 @@ static struct node *const unordered_set_create_element(unordered_set me,
*/
int unordered_set_put(unordered_set me, void *const key)
{
const unsigned long hash = unordered_set_hash(me, key);
const int index = (int) (hash % me->capacity);
int index;
if (me->size + 1 >= RESIZE_AT * me->capacity) {
const int rc = unordered_set_resize(me);
if (rc != 0) {
return rc;
}
}
index = (int) (hash % me->capacity);
if (!me->buckets[index]) {
me->buckets[index] = unordered_set_create_element(me, hash, key);
if (!me->buckets[index]) {
@@ -266,9 +272,6 @@ int unordered_set_put(unordered_set me, void *const key)
}
}
me->size++;
if (me->size >= RESIZE_AT * me->capacity) {
return unordered_set_resize(me);
}
return 0;
}
@@ -366,7 +369,8 @@ int unordered_set_clear(unordered_set me)
}
/**
* Frees the unordered set memory.
* Frees the unordered set memory. Performing further operations after calling
* this function results in undefined behavior.
*
* @param me the unordered set to free from memory
*

View File

@@ -405,7 +405,8 @@ int vector_clear(vector me)
}
/**
* Frees the vector memory.
* Frees the vector memory. Performing further operations after calling this
* function results in undefined behavior.
*
* @param me the vector to free from memory
*

View File

@@ -1,35 +1,54 @@
#include "test.h"
#include "../src/array.h"
void test_array(void)
static void test_invalid_init(void)
{
array me;
int i;
int *data;
int arr[10] = {0};
int array[2] = {0xdeadbeef, 0xdeadbeef};
int get;
assert(!array_init(-1, sizeof(int)));
assert(!array_init(1, 0));
me = array_init(10, sizeof(int));
}
static void test_empty_array(void)
{
int get = 0xdeadbeef;
int arr[2] = {0xdeadbeef, 0xdeadbeef};
array me = array_init(0, sizeof(int));
assert(me);
assert(array_size(me) == 10);
assert(array_size(me) == 0);
array_copy_to_array(arr, me);
assert(arr[0] == 0xdeadbeef);
assert(arr[1] == 0xdeadbeef);
assert(!array_get_data(me));
assert(array_set(me, 0, &get) == -EINVAL);
assert(array_get(&get, me, 0) == -EINVAL);
assert(!array_destroy(me));
}
static void test_individual_operations(array me)
{
int i;
for (i = 0; i < 10; i++) {
get = 0xdeadbeef;
int get = 0xdeadbeef;
array_get(&get, me, i);
assert(get == 0);
}
for (i = 0; i < 10; i++) {
get = 0xdeadbeef;
int get = 0xdeadbeef;
array_set(me, i, &i);
array_get(&get, me, i);
assert(get == i);
}
for (i = 0; i < 10; i++) {
get = 0xdeadbeef;
int get = 0xdeadbeef;
array_get(&get, me, i);
assert(get == i);
}
}
static void test_array_copying(array me)
{
int i;
int *data;
int arr[10] = {0};
array_copy_to_array(arr, me);
for (i = 0; i < 10; i++) {
assert(arr[i] == i);
@@ -38,18 +57,39 @@ void test_array(void)
for (i = 0; i < 10; i++) {
assert(data[i] == i);
}
get = 0xdeadbeef;
}
static void test_out_of_bounds(array me)
{
int get = 0xdeadbeef;
assert(array_set(me, -1, &get) == -EINVAL);
assert(array_get(&get, me, -1) == -EINVAL);
}
static void test_not_empty_array(void)
{
array me = array_init(10, sizeof(int));
assert(me);
assert(array_size(me) == 10);
test_individual_operations(me);
test_array_copying(me);
test_out_of_bounds(me);
me = array_destroy(me);
assert(!me);
me = array_init(0, sizeof(int));
assert(array_size(me) == 0);
array_copy_to_array(array, me);
assert(array[0] == 0xdeadbeef);
assert(array[1] == 0xdeadbeef);
assert(!array_get_data(me));
assert(array_set(me, 0, &get) == -EINVAL);
assert(array_get(&get, me, 0) == -EINVAL);
assert(!array_destroy(me));
}
static void test_init_out_of_memory(void)
{
fail_malloc = 1;
assert(!array_init(10, sizeof(int)));
fail_calloc = 1;
assert(!array_init(10, sizeof(int)));
}
void test_array(void)
{
test_invalid_init();
test_empty_array();
test_not_empty_array();
test_init_out_of_memory();
}

View File

@@ -1,22 +1,18 @@
#include "test.h"
#include "../src/deque.h"
void test_deque(void)
static void test_invalid_init(void)
{
assert(!deque_init(0));
}
static void test_copy(deque me)
{
int val[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int get_arr[10] = {0};
int trimmed[5] = {0};
int arr[3] = {0};
deque me;
int get;
int add;
int set;
int i;
assert(!deque_init(0));
me = deque_init(sizeof(int));
assert(me);
assert(deque_size(me) == 0);
assert(deque_is_empty(me));
for (i = 0; i < 10; i++) {
deque_push_front(me, &val[i]);
get = 0;
@@ -43,7 +39,14 @@ void test_deque(void)
for (i = 0; i < 3; i++) {
assert(10 - i == trimmed[i]);
}
add = 3;
}
static void test_linear_operations(deque me)
{
int arr[3] = {0};
int get;
int set;
int add = 3;
deque_push_back(me, &add);
add = -2;
deque_push_back(me, &add);
@@ -103,20 +106,161 @@ void test_deque(void)
assert(arr[0] == -5);
assert(arr[1] == -6);
assert(arr[2] == -7);
}
static void test_invalid_input(deque me)
{
int set;
assert(deque_set_at(me, 4, &set) == -EINVAL);
assert(deque_get_at(&set, me, 4) == -EINVAL);
assert(deque_set_at(me, -1, &set) == -EINVAL);
assert(deque_get_at(&set, me, -1) == -EINVAL);
}
static void test_basic(void)
{
deque me = deque_init(sizeof(int));
assert(me);
assert(deque_size(me) == 0);
assert(deque_is_empty(me));
test_copy(me);
test_linear_operations(me);
test_invalid_input(me);
deque_clear(me);
assert(deque_size(me) == 0);
assert(deque_is_empty(me));
me = deque_destroy(me);
assert(!me);
/* Testing automatic trim */
me = deque_init(sizeof(int));
assert(!deque_destroy(me));
}
static void test_trim(void)
{
deque me = deque_init(sizeof(int));
int i;
for (i = 0; i < 100; i++) {
int get;
deque_push_back(me, &i);
deque_pop_front(&get, me);
}
deque_destroy(me);
}
static void test_init_out_of_memory(void)
{
fail_malloc = 1;
assert(!deque_init(sizeof(int)));
fail_malloc = 1;
delay_fail_malloc = 1;
assert(!deque_init(sizeof(int)));
fail_malloc = 1;
delay_fail_malloc = 2;
assert(!deque_init(sizeof(int)));
}
static void test_trim_out_of_memory(void)
{
deque me = deque_init(sizeof(int));
int i;
for (i = 0; i < 32; i++) {
deque_push_back(me, &i);
}
assert(deque_size(me) == 32);
fail_malloc = 1;
assert(deque_trim(me) == -ENOMEM);
for (i = 0; i < 32; i++) {
int get = 0xdeadbeef;
deque_get_at(&get, me, i);
assert(get == i);
}
assert(deque_size(me) == 32);
assert(!deque_destroy(me));
}
static void test_push_front_out_of_memory(void)
{
deque me = deque_init(sizeof(int));
int i;
for (i = 0; i < 5; i++) {
assert(deque_push_front(me, &i) == 0);
}
assert(deque_size(me) == 5);
fail_realloc = 1;
assert(deque_push_front(me, &i) == -ENOMEM);
assert(deque_size(me) == 5);
for (i = 0; i < 5; i++) {
int get = 0xdeadbeef;
deque_get_at(&get, me, i);
}
fail_malloc = 1;
assert(deque_push_front(me, &i) == -ENOMEM);
assert(deque_size(me) == 5);
for (i = 0; i < 5; i++) {
int get = 0xdeadbeef;
deque_get_at(&get, me, i);
}
assert(!deque_destroy(me));
}
static void test_push_back_out_of_memory(void)
{
deque me = deque_init(sizeof(int));
int i;
for (i = 0; i < 3; i++) {
assert(deque_push_back(me, &i) == 0);
}
assert(deque_size(me) == 3);
fail_realloc = 1;
assert(deque_push_back(me, &i) == -ENOMEM);
assert(deque_size(me) == 3);
for (i = 0; i < 3; i++) {
int get = 0xdeadbeef;
deque_get_at(&get, me, i);
}
fail_malloc = 1;
assert(deque_push_back(me, &i) == -ENOMEM);
assert(deque_size(me) == 3);
for (i = 0; i < 3; i++) {
int get = 0xdeadbeef;
deque_get_at(&get, me, i);
}
assert(!deque_destroy(me));
}
static void test_clear_out_of_memory(void)
{
deque me = deque_init(sizeof(int));
int i;
for (i = 0; i < 32; i++) {
deque_push_back(me, &i);
}
assert(deque_size(me) == 32);
fail_malloc = 1;
assert(deque_clear(me) == -ENOMEM);
for (i = 0; i < 32; i++) {
int get = 0xdeadbeef;
deque_get_at(&get, me, i);
assert(get == i);
}
assert(deque_size(me) == 32);
fail_malloc = 1;
delay_fail_malloc = 1;
assert(deque_clear(me) == -ENOMEM);
for (i = 0; i < 32; i++) {
int get = 0xdeadbeef;
deque_get_at(&get, me, i);
assert(get == i);
}
assert(deque_size(me) == 32);
assert(!deque_destroy(me));
}
void test_deque(void)
{
test_invalid_init();
test_basic();
test_trim();
test_init_out_of_memory();
test_trim_out_of_memory();
test_push_front_out_of_memory();
test_push_back_out_of_memory();
test_clear_out_of_memory();
}

View File

@@ -1,20 +1,17 @@
#include "test.h"
#include "../src/forward_list.h"
void test_forward_list(void)
static void test_invalid_init(void)
{
assert(!forward_list_init(0));
}
static void test_front(forward_list me)
{
int val[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int get_arr[10] = {0};
int trimmed[5] = {0};
int arr[3] = {0};
int add;
forward_list me;
int get;
int set;
int i;
assert(!forward_list_init(0));
me = forward_list_init(sizeof(int));
assert(me);
assert(forward_list_size(me) == 0);
assert(forward_list_is_empty(me));
for (i = 0; i < 10; i++) {
@@ -36,13 +33,25 @@ void test_forward_list(void)
for (i = 0; i < 7; i++) {
forward_list_remove_last(me);
}
}
static void test_linear_operations(forward_list me)
{
int trimmed[5] = {0};
int index;
int first;
int add;
int get;
int set;
int i;
forward_list_copy_to_array(trimmed, me);
assert(forward_list_size(me) == 3);
for (i = 0; i < 3; i++) {
assert(10 - i == trimmed[i]);
}
index = forward_list_size(me);
add = 3;
forward_list_add_last(me, &add);
forward_list_add_at(me, index, &add);
add = -1;
forward_list_add_at(me, 1, &add);
add = -2;
@@ -70,6 +79,12 @@ void test_forward_list(void)
forward_list_remove_first(me);
forward_list_remove_at(me, 2);
forward_list_remove_last(me);
get = 34;
forward_list_add_at(me, 0, &get);
first = 0xdeadbeef;
forward_list_get_first(&first, me);
assert(first == get);
forward_list_remove_first(me);
assert(forward_list_size(me) == 3);
get = 345;
forward_list_get_first(&get, me);
@@ -84,6 +99,12 @@ void test_forward_list(void)
forward_list_set_at(me, 1, &set);
set = 14;
forward_list_set_last(me, &set);
}
static void test_array_copy(forward_list me)
{
int arr[3] = {0};
int set;
forward_list_copy_to_array(arr, me);
assert(arr[0] == 12);
assert(arr[1] == 13);
@@ -98,6 +119,11 @@ void test_forward_list(void)
assert(arr[0] == -5);
assert(arr[1] == -6);
assert(arr[2] == -7);
}
static void test_invalid_index(forward_list me)
{
int set = 0xdeadbeef;
assert(forward_list_set_at(me, 4, &set) == -EINVAL);
assert(forward_list_get_at(&set, me, 4) == -EINVAL);
assert(forward_list_remove_at(me, 4) == -EINVAL);
@@ -111,6 +137,135 @@ void test_forward_list(void)
assert(forward_list_is_empty(me));
assert(forward_list_remove_first(me) == -EINVAL);
assert(forward_list_remove_last(me) == -EINVAL);
me = forward_list_destroy(me);
assert(!me);
}
static void test_basic(void)
{
forward_list me = forward_list_init(sizeof(int));
assert(me);
test_front(me);
test_linear_operations(me);
test_array_copy(me);
test_invalid_index(me);
assert(!forward_list_destroy(me));
}
static void test_init_out_of_memory(void)
{
fail_malloc = 1;
assert(!forward_list_init(sizeof(int)));
}
static void test_add_first_out_of_memory(void)
{
int i;
forward_list me = forward_list_init(sizeof(int));
assert(me);
for (i = 0; i < 16; i++) {
assert(forward_list_add_first(me, &i) == 0);
}
assert(forward_list_size(me) == 16);
fail_malloc = 1;
assert(forward_list_add_first(me, &i) == -ENOMEM);
assert(forward_list_size(me) == 16);
for (i = 0; i < 16; i++) {
int get = 0xdeadbeef;
assert(forward_list_get_at(&get, me, i) == 0);
assert(get == 15 - i);
}
fail_malloc = 1;
delay_fail_malloc = 1;
assert(forward_list_add_first(me, &i) == -ENOMEM);
assert(forward_list_size(me) == 16);
for (i = 0; i < 16; i++) {
int get = 0xdeadbeef;
assert(forward_list_get_at(&get, me, i) == 0);
assert(get == 15 - i);
}
assert(!forward_list_destroy(me));
}
static void test_add_at_out_of_memory(void)
{
int get;
int i;
forward_list me = forward_list_init(sizeof(int));
assert(me);
i = 982;
assert(forward_list_add_first(me, &i) == 0);
i = 157;
assert(forward_list_add_first(me, &i) == 0);
for (i = 1; i < 15; i++) {
assert(forward_list_add_at(me, i, &i) == 0);
}
assert(forward_list_size(me) == 16);
fail_malloc = 1;
assert(forward_list_add_at(me, 5, &i) == -ENOMEM);
assert(forward_list_size(me) == 16);
get = 0xdeadbeef;
assert(forward_list_get_at(&get, me, 0) == 0);
assert(get == 157);
for (i = 1; i < 15; i++) {
get = 0xdeadbeef;
assert(forward_list_get_at(&get, me, i) == 0);
assert(get == i);
}
get = 0xdeadbeef;
assert(forward_list_get_at(&get, me, 15) == 0);
assert(get == 982);
fail_malloc = 1;
delay_fail_malloc = 1;
assert(forward_list_add_at(me, 5, &i) == -ENOMEM);
assert(forward_list_size(me) == 16);
get = 0xdeadbeef;
assert(forward_list_get_at(&get, me, 0) == 0);
assert(get == 157);
for (i = 1; i < 15; i++) {
get = 0xdeadbeef;
assert(forward_list_get_at(&get, me, i) == 0);
assert(get == i);
}
get = 0xdeadbeef;
assert(forward_list_get_at(&get, me, 15) == 0);
assert(get == 982);
assert(!forward_list_destroy(me));
}
static void test_add_last_out_of_memory(void)
{
int i;
forward_list me = forward_list_init(sizeof(int));
assert(me);
for (i = 0; i < 16; i++) {
assert(forward_list_add_last(me, &i) == 0);
}
assert(forward_list_size(me) == 16);
fail_malloc = 1;
assert(forward_list_add_last(me, &i) == -ENOMEM);
assert(forward_list_size(me) == 16);
for (i = 0; i < 16; i++) {
int get = 0xdeadbeef;
assert(forward_list_get_at(&get, me, i) == 0);
assert(get == i);
}
fail_malloc = 1;
delay_fail_malloc = 1;
assert(forward_list_add_last(me, &i) == -ENOMEM);
assert(forward_list_size(me) == 16);
for (i = 0; i < 16; i++) {
int get = 0xdeadbeef;
assert(forward_list_get_at(&get, me, i) == 0);
assert(get == i);
}
assert(!forward_list_destroy(me));
}
void test_forward_list(void)
{
test_invalid_init();
test_basic();
test_init_out_of_memory();
test_add_first_out_of_memory();
test_add_at_out_of_memory();
test_add_last_out_of_memory();
}

View File

@@ -1,22 +1,17 @@
#include "test.h"
#include "../src/list.h"
void test_list(void)
static void test_invalid_init(void)
{
assert(!list_init(0));
}
static void test_front(list me)
{
int val[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int get_arr[10] = {0};
int trimmed[5] = {0};
int arr[3] = {0};
list me;
int first;
int index;
int add;
int get;
int set;
int i;
assert(!list_init(0));
me = list_init(sizeof(int));
assert(me);
assert(list_size(me) == 0);
assert(list_is_empty(me));
for (i = 0; i < 10; i++) {
@@ -38,6 +33,17 @@ void test_list(void)
for (i = 0; i < 7; i++) {
list_remove_last(me);
}
}
static void test_linear_operations(list me)
{
int trimmed[5] = {0};
int index;
int first;
int add;
int get;
int set;
int i;
list_copy_to_array(trimmed, me);
assert(list_size(me) == 3);
for (i = 0; i < 3; i++) {
@@ -93,6 +99,12 @@ void test_list(void)
list_set_at(me, 1, &set);
set = 14;
list_set_last(me, &set);
}
static void test_array_copy(list me)
{
int arr[3] = {0};
int set;
list_copy_to_array(arr, me);
assert(arr[0] == 12);
assert(arr[1] == 13);
@@ -107,6 +119,11 @@ void test_list(void)
assert(arr[0] == -5);
assert(arr[1] == -6);
assert(arr[2] == -7);
}
static void test_invalid_index(list me)
{
int set = 0xdeadbeef;
assert(list_set_at(me, 4, &set) == -EINVAL);
assert(list_get_at(&set, me, 4) == -EINVAL);
assert(list_remove_at(me, 4) == -EINVAL);
@@ -120,6 +137,135 @@ void test_list(void)
assert(list_is_empty(me));
assert(list_remove_first(me) == -EINVAL);
assert(list_remove_last(me) == -EINVAL);
me = list_destroy(me);
assert(!me);
}
static void test_basic(void)
{
list me = list_init(sizeof(int));
assert(me);
test_front(me);
test_linear_operations(me);
test_array_copy(me);
test_invalid_index(me);
assert(!list_destroy(me));
}
static void test_init_out_of_memory(void)
{
fail_malloc = 1;
assert(!list_init(sizeof(int)));
}
static void test_add_first_out_of_memory(void)
{
int i;
list me = list_init(sizeof(int));
assert(me);
for (i = 0; i < 16; i++) {
assert(list_add_first(me, &i) == 0);
}
assert(list_size(me) == 16);
fail_malloc = 1;
assert(list_add_first(me, &i) == -ENOMEM);
assert(list_size(me) == 16);
for (i = 0; i < 16; i++) {
int get = 0xdeadbeef;
assert(list_get_at(&get, me, i) == 0);
assert(get == 15 - i);
}
fail_malloc = 1;
delay_fail_malloc = 1;
assert(list_add_first(me, &i) == -ENOMEM);
assert(list_size(me) == 16);
for (i = 0; i < 16; i++) {
int get = 0xdeadbeef;
assert(list_get_at(&get, me, i) == 0);
assert(get == 15 - i);
}
assert(!list_destroy(me));
}
static void test_add_at_out_of_memory(void)
{
int get;
int i;
list me = list_init(sizeof(int));
assert(me);
i = 982;
assert(list_add_first(me, &i) == 0);
i = 157;
assert(list_add_first(me, &i) == 0);
for (i = 1; i < 15; i++) {
assert(list_add_at(me, i, &i) == 0);
}
assert(list_size(me) == 16);
fail_malloc = 1;
assert(list_add_at(me, 5, &i) == -ENOMEM);
assert(list_size(me) == 16);
get = 0xdeadbeef;
assert(list_get_at(&get, me, 0) == 0);
assert(get == 157);
for (i = 1; i < 15; i++) {
get = 0xdeadbeef;
assert(list_get_at(&get, me, i) == 0);
assert(get == i);
}
get = 0xdeadbeef;
assert(list_get_at(&get, me, 15) == 0);
assert(get == 982);
fail_malloc = 1;
delay_fail_malloc = 1;
assert(list_add_at(me, 5, &i) == -ENOMEM);
assert(list_size(me) == 16);
get = 0xdeadbeef;
assert(list_get_at(&get, me, 0) == 0);
assert(get == 157);
for (i = 1; i < 15; i++) {
get = 0xdeadbeef;
assert(list_get_at(&get, me, i) == 0);
assert(get == i);
}
get = 0xdeadbeef;
assert(list_get_at(&get, me, 15) == 0);
assert(get == 982);
assert(!list_destroy(me));
}
static void test_add_last_out_of_memory(void)
{
int i;
list me = list_init(sizeof(int));
assert(me);
for (i = 0; i < 16; i++) {
assert(list_add_last(me, &i) == 0);
}
assert(list_size(me) == 16);
fail_malloc = 1;
assert(list_add_last(me, &i) == -ENOMEM);
assert(list_size(me) == 16);
for (i = 0; i < 16; i++) {
int get = 0xdeadbeef;
assert(list_get_at(&get, me, i) == 0);
assert(get == i);
}
fail_malloc = 1;
delay_fail_malloc = 1;
assert(list_add_last(me, &i) == -ENOMEM);
assert(list_size(me) == 16);
for (i = 0; i < 16; i++) {
int get = 0xdeadbeef;
assert(list_get_at(&get, me, i) == 0);
assert(get == i);
}
assert(!list_destroy(me));
}
void test_list(void)
{
test_invalid_init();
test_basic();
test_init_out_of_memory();
test_add_first_out_of_memory();
test_add_at_out_of_memory();
test_add_last_out_of_memory();
}

1032
tst/map.c

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -42,29 +42,32 @@ static int compare_int(const void *const one, const void *const two)
return a - b;
}
int stub_priority_queue_push(priority_queue me, void *const data)
static int stub_priority_queue_push(priority_queue me, void *const data)
{
const int ret = priority_queue_push(me, data);
priority_queue_verify(me);
return ret;
}
int stub_priority_queue_pop(void *const data, priority_queue me)
static int stub_priority_queue_pop(void *const data, priority_queue me)
{
const int ret = priority_queue_pop(data, me);
priority_queue_verify(me);
return ret;
}
void test_priority_queue(void)
static void test_invalid_init(void)
{
assert(!priority_queue_init(0, compare_int));
assert(!priority_queue_init(sizeof(int), NULL));
}
static void test_basic(void)
{
priority_queue me;
int item;
int latest;
int i;
assert(!priority_queue_init(0, compare_int));
assert(!priority_queue_init(sizeof(int), NULL));
me = priority_queue_init(sizeof(int), compare_int);
priority_queue me = priority_queue_init(sizeof(int), compare_int);
assert(me);
assert(priority_queue_size(me) == 0);
assert(priority_queue_is_empty(me));
@@ -128,6 +131,57 @@ void test_priority_queue(void)
assert(!priority_queue_front(&item, me));
assert(item == 0xdeadbeef);
assert(priority_queue_is_empty(me));
me = priority_queue_destroy(me);
assert(!me);
assert(!priority_queue_destroy(me));
}
static void test_init_out_of_memory(void)
{
fail_malloc = 1;
assert(!priority_queue_init(sizeof(int), compare_int));
fail_malloc = 1;
delay_fail_malloc = 1;
assert(!priority_queue_init(sizeof(int), compare_int));
fail_malloc = 1;
delay_fail_malloc = 2;
assert(!priority_queue_init(sizeof(int), compare_int));
}
static void test_push_out_of_memory(void)
{
int i;
int get = 0xdeadbeef;
priority_queue me = priority_queue_init(sizeof(int), compare_int);
for (i = 0; i < 16; i++) {
assert(priority_queue_push(me, &i) == 0);
}
assert(priority_queue_size(me) == 16);
fail_malloc = 1;
assert(priority_queue_push(me, &get) == -ENOMEM);
for (i = 0; i < 16; i++) {
get = 0xdeadbeef;
assert(priority_queue_pop(&get, me));
assert(get == 15 - i);
}
assert(priority_queue_size(me) == 0);
priority_queue_clear(me);
for (i = 0; i < 11; i++) {
assert(priority_queue_push(me, &i) == 0);
}
assert(priority_queue_size(me) == 11);
fail_realloc = 1;
assert(priority_queue_push(me, &get) == -ENOMEM);
for (i = 0; i < 11; i++) {
get = 0xdeadbeef;
assert(priority_queue_pop(&get, me));
assert(get == 10 - i);
}
assert(!priority_queue_destroy(me));
}
void test_priority_queue(void)
{
test_invalid_init();
test_basic();
test_init_out_of_memory();
test_push_out_of_memory();
}

View File

@@ -1,19 +1,17 @@
#include "test.h"
#include "../src/queue.h"
void test_queue(void)
static void test_invalid_init(void)
{
assert(!queue_init(0));
}
static void test_linear_operations(queue me)
{
int val[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int get_arr[10] = {0};
queue me;
int get;
int stuff;
int old_size;
int pop_count;
int get;
int i;
assert(!queue_init(0));
me = queue_init(sizeof(int));
assert(me);
assert(queue_size(me) == 0);
assert(queue_is_empty(me));
for (i = 0; i < 10; i++) {
@@ -27,6 +25,13 @@ void test_queue(void)
}
assert(queue_size(me) == 10);
assert(!queue_is_empty(me));
}
static void test_array_copy(queue me)
{
int get_arr[10] = {0};
int get;
int i;
queue_copy_to_array(get_arr, me);
for (i = 0; i < 10; i++) {
assert(get_arr[i] == i + 1);
@@ -36,6 +41,11 @@ void test_queue(void)
assert(queue_pop(&get, me));
assert(get == i + 1);
}
}
static void test_array_trim(queue me)
{
int get;
queue_trim(me);
assert(queue_size(me) == 1);
queue_clear(me);
@@ -44,9 +54,25 @@ void test_queue(void)
assert(!queue_pop(&get, me));
assert(!queue_front(&get, me));
assert(!queue_back(&get, me));
me = queue_destroy(me);
assert(!me);
me = queue_init(sizeof(int));
}
static void test_basic(void)
{
queue me = queue_init(sizeof(int));
assert(me);
test_linear_operations(me);
test_array_copy(me);
test_array_trim(me);
assert(!queue_destroy(me));
}
static void test_large_alloc(void)
{
int old_size;
int pop_count;
int get;
int i;
queue me = queue_init(sizeof(int));
assert(me);
for (i = 123; i < 123456; i++) {
queue_push(me, &i);
@@ -58,12 +84,41 @@ void test_queue(void)
pop_count++;
}
assert(pop_count == old_size);
queue_destroy(me);
/* Testing automatic trim. */
me = queue_init(sizeof(int));
assert(!queue_destroy(me));
}
static void test_automated_trim(void)
{
queue me = queue_init(sizeof(int));
int get;
int i;
for (i = 0; i < 100; i++) {
queue_push(me, &i);
queue_pop(&get, me);
}
queue_destroy(me);
assert(!queue_destroy(me));
}
static void test_init_out_of_memory(void)
{
fail_malloc = 1;
assert(!queue_init(sizeof(int)));
fail_malloc = 1;
delay_fail_malloc = 1;
assert(!queue_init(sizeof(int)));
fail_malloc = 1;
delay_fail_malloc = 2;
assert(!queue_init(sizeof(int)));
fail_malloc = 1;
delay_fail_malloc = 3;
assert(!queue_init(sizeof(int)));
}
void test_queue(void)
{
test_invalid_init();
test_basic();
test_large_alloc();
test_automated_trim();
test_init_out_of_memory();
}

855
tst/set.c
View File

@@ -2,7 +2,7 @@
#include "../src/set.h"
/*
* Include this struct for the stubs.
* Include this struct to verify the tree.
*/
struct internal_set {
size_t key_size;
@@ -11,6 +11,64 @@ struct internal_set {
struct node *root;
};
/*
* Include this struct to verify the tree.
*/
struct node {
struct node *parent;
int balance;
void *key;
struct node *left;
struct node *right;
};
/*
* Verifies that the AVL tree rules are followed. The balance factor of an item
* must be the right height minus the left height. Also, the left key must be
* less than the right key.
*/
static int set_verify_recursive(struct node *const item)
{
int left;
int right;
int max;
if (!item) {
return 0;
}
left = set_verify_recursive(item->left);
right = set_verify_recursive(item->right);
max = left > right ? left : right;
assert(right - left == item->balance);
if (item->left && item->right) {
const int left_val = *(int *) item->left->key;
const int right_val = *(int *) item->right->key;
assert(left_val < right_val);
}
if (item->left) {
assert(item->left->parent == item);
assert(item->left->parent->key == item->key);
}
if (item->right) {
assert(item->right->parent == item);
assert(item->right->parent->key == item->key);
}
return max + 1;
}
static int set_compute_size(struct node *const item)
{
if (!item) {
return 0;
}
return 1 + set_compute_size(item->left) + set_compute_size(item->right);
}
static void set_verify(set me)
{
set_verify_recursive(me->root);
assert(set_compute_size(me->root) == set_size(me));
}
static int compare_int(const void *const one, const void *const two)
{
const int a = *(int *) one;
@@ -18,141 +76,312 @@ static int compare_int(const void *const one, const void *const two)
return a - b;
}
void test_set(void)
static void test_invalid_init(void)
{
int c[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
set me;
int key;
int count;
int flip;
int i;
int j;
int num;
int p;
assert(!set_init(0, compare_int));
assert(!set_init(sizeof(int), NULL));
me = set_init(sizeof(int), compare_int);
}
static void mutation_order(set me, const int *const arr, const int size)
{
int i;
int actual_size = 0;
assert(set_is_empty(me));
for (i = 0; i < size; i++) {
int num = arr[i];
if (num > 0) {
assert(set_put(me, &num) == 0);
actual_size++;
} else {
int actual_num = -1 * num;
assert(set_remove(me, &actual_num));
actual_size--;
}
}
assert(set_size(me) == actual_size);
set_verify(me);
}
/*
* Targets the (child->balance == 0) branch.
*/
static void test_rotate_left_balanced_child(set me)
{
int i;
int arr[] = {2, 4, 1, 3, 5, -1};
int size = sizeof(arr) / sizeof(arr[0]);
mutation_order(me, arr, size);
for (i = 2; i <= 5; i++) {
assert(set_contains(me, &i));
}
}
/*
* Targets the else branch.
*/
static void test_rotate_left_unbalanced_child(set me)
{
int i;
int arr[] = {1, 2, 3};
int size = sizeof(arr) / sizeof(arr[0]);
mutation_order(me, arr, size);
for (i = 1; i <= 3; i++) {
assert(set_contains(me, &i));
}
}
/*
* Targets (parent->balance == 2 && child->balance >= 0) in the set_repair
* function.
*/
static void test_rotate_left(void)
{
set me = set_init(sizeof(int), compare_int);
assert(me);
/* left-left */
key = 5;
set_put(me, &key);
key = 3;
set_put(me, &key);
key = 1;
set_put(me, &key);
key = 0xdeadbeef;
set_contains(me, &key);
test_rotate_left_balanced_child(me);
set_clear(me);
/* right-right */
key = 1;
set_put(me, &key);
key = 3;
set_put(me, &key);
key = 5;
set_put(me, &key);
key = 0xdeadbeef;
set_contains(me, &key);
test_rotate_left_unbalanced_child(me);
assert(!set_destroy(me));
}
/*
* Targets the (child->balance == 0) branch.
*/
static void test_rotate_right_balanced_child(set me)
{
int i;
int arr[] = {4, 2, 5, 1, 3, -5};
int size = sizeof(arr) / sizeof(arr[0]);
mutation_order(me, arr, size);
for (i = 1; i <= 4; i++) {
assert(set_contains(me, &i));
}
}
/*
* Targets the else branch.
*/
static void test_rotate_right_unbalanced_child(set me)
{
int i;
int arr[] = {3, 2, 1};
int size = sizeof(arr) / sizeof(arr[0]);
mutation_order(me, arr, size);
for (i = 1; i <= 3; i++) {
assert(set_contains(me, &i));
}
}
/*
* Targets (parent->balance == -2 && child->balance <= 0) in the set_repair
* function.
*/
static void test_rotate_right(void)
{
set me = set_init(sizeof(int), compare_int);
assert(me);
test_rotate_right_balanced_child(me);
set_clear(me);
/* left-right */
key = 5;
set_put(me, &key);
key = 1;
set_put(me, &key);
key = 3;
set_put(me, &key);
key = 0xdeadbeef;
set_contains(me, &key);
test_rotate_right_unbalanced_child(me);
assert(!set_destroy(me));
}
/*
* Targets the (grand_child->balance == 1) branch.
*/
static void test_rotate_left_right_positively_balanced_grand_child(set me)
{
int i;
int arr[] = {5, 2, 6, 1, 3, 4};
int size = sizeof(arr) / sizeof(arr[0]);
mutation_order(me, arr, size);
for (i = 1; i <= 6; i++) {
assert(set_contains(me, &i));
}
}
/*
* Targets the (grand_child->balance == 0) branch.
*/
static void test_rotate_left_right_neutral_balanced_grand_child(set me)
{
int i;
int arr[] = {3, 1, 2};
int size = sizeof(arr) / sizeof(arr[0]);
mutation_order(me, arr, size);
for (i = 1; i <= 3; i++) {
assert(set_contains(me, &i));
}
}
/*
* Targets the else branch.
*/
static void test_rotate_left_right_negatively_balanced_grand_child(set me)
{
int i;
int arr[] = {5, 2, 6, 1, 4, 3};
int size = sizeof(arr) / sizeof(arr[0]);
mutation_order(me, arr, size);
for (i = 1; i <= 6; i++) {
assert(set_contains(me, &i));
}
}
/*
* Targets (parent->balance == -2 && child->balance == 1) in the set_repair
* function.
*/
static void test_rotate_left_right(void)
{
set me = set_init(sizeof(int), compare_int);
assert(me);
test_rotate_left_right_positively_balanced_grand_child(me);
set_clear(me);
/* right-left */
key = 1;
set_put(me, &key);
key = 5;
set_put(me, &key);
key = 3;
set_put(me, &key);
key = 0xdeadbeef;
set_contains(me, &key);
test_rotate_left_right_neutral_balanced_grand_child(me);
set_clear(me);
/* Two children edge case. */
key = 8;
test_rotate_left_right_negatively_balanced_grand_child(me);
assert(!set_destroy(me));
}
/*
* Targets the (grand_child->balance == 1) branch.
*/
static void test_rotate_right_left_positively_balanced_grand_child(set me)
{
int i;
int arr[] = {2, 1, 5, 3, 6, 4};
int size = sizeof(arr) / sizeof(arr[0]);
mutation_order(me, arr, size);
for (i = 1; i <= 6; i++) {
assert(set_contains(me, &i));
}
}
/*
* Targets the (grand_child->balance == 0) branch.
*/
static void test_rotate_right_left_neutral_balanced_grand_child(set me)
{
int i;
int arr[] = {1, 3, 2};
int size = sizeof(arr) / sizeof(arr[0]);
mutation_order(me, arr, size);
for (i = 1; i <= 3; i++) {
assert(set_contains(me, &i));
}
}
/*
* Targets the else branch.
*/
static void test_rotate_right_left_negatively_balanced_grand_child(set me)
{
int i;
int arr[] = {2, 1, 5, 4, 6, 3};
int size = sizeof(arr) / sizeof(arr[0]);
mutation_order(me, arr, size);
for (i = 1; i <= 6; i++) {
assert(set_contains(me, &i));
}
}
/*
* Targets (parent->balance == 2 && child->balance == -1) in the set_repair
* function.
*/
static void test_rotate_right_left(void)
{
set me = set_init(sizeof(int), compare_int);
assert(me);
test_rotate_right_left_positively_balanced_grand_child(me);
set_clear(me);
test_rotate_right_left_neutral_balanced_grand_child(me);
set_clear(me);
test_rotate_right_left_negatively_balanced_grand_child(me);
assert(!set_destroy(me));
}
/*
* Targets the set_repair function.
*/
static void test_auto_balancing(void)
{
test_rotate_left();
test_rotate_right();
test_rotate_left_right();
test_rotate_right_left();
}
static void test_put_already_existing(void)
{
int key = 5;
set me = set_init(sizeof(int), compare_int);
assert(me);
assert(set_size(me) == 0);
set_put(me, &key);
key = 5;
set_put(me, &key);
key = 11;
set_put(me, &key);
key = 2;
set_put(me, &key);
key = 6;
set_put(me, &key);
key = 10;
set_put(me, &key);
key = 15;
set_put(me, &key);
key = 1;
assert(set_size(me) == 1);
set_put(me, &key);
assert(set_size(me) == 1);
assert(!set_destroy(me));
}
static void test_remove_nothing(void)
{
int key;
set me = set_init(sizeof(int), compare_int);
assert(me);
key = 3;
set_put(me, &key);
key = 4;
set_put(me, &key);
key = 5;
assert(!set_remove(me, &key));
assert(!set_destroy(me));
}
static void test_contains(void)
{
int key;
set me = set_init(sizeof(int), compare_int);
assert(me);
key = 7;
set_put(me, &key);
key = 9;
set_put(me, &key);
key = 12;
set_put(me, &key);
key = 13;
set_put(me, &key);
key = 16;
set_put(me, &key);
key = 14;
set_put(me, &key);
set_clear(me);
/* Two children edge case. */
key = 8;
set_put(me, &key);
key = 4;
set_put(me, &key);
key = 12;
set_put(me, &key);
key = 2;
set_put(me, &key);
key = 6;
set_put(me, &key);
key = 10;
set_put(me, &key);
key = 15;
assert(!set_contains(me, &key));
key = 3;
set_put(me, &key);
key = 1;
set_put(me, &key);
key = 3;
set_put(me, &key);
key = 5;
set_put(me, &key);
key = 7;
set_put(me, &key);
key = 9;
set_put(me, &key);
key = 11;
set_put(me, &key);
key = 13;
set_put(me, &key);
key = 16;
set_put(me, &key);
key = 14;
set_put(me, &key);
set_clear(me);
/* Add a lot of items. */
count = 0;
flip = 0;
key = 0;
assert(!set_contains(me, &key));
key = 1;
assert(set_contains(me, &key));
key = 2;
assert(!set_contains(me, &key));
key = 3;
assert(set_contains(me, &key));
key = 4;
assert(!set_contains(me, &key));
key = 5;
assert(set_contains(me, &key));
key = 6;
assert(!set_contains(me, &key));
assert(!set_destroy(me));
}
static void test_stress_add(void)
{
int count = 0;
int flip = 0;
int i;
set me = set_init(sizeof(int), compare_int);
assert(me);
for (i = 1234; i < 82400; i++) {
int is_already_present;
int is_now_present;
num = i % 765;
int num = i % 765;
is_already_present = set_contains(me, &num);
set_put(me, &num);
is_now_present = set_contains(me, &num);
assert(is_now_present);
if (!is_already_present && is_now_present) {
assert(set_contains(me, &num));
if (!is_already_present) {
count++;
}
if (i == 1857 && !flip) {
@@ -161,134 +390,14 @@ void test_set(void)
}
}
assert(count == set_size(me));
set_contains(me, &key);
set_destroy(me);
me = set_init(sizeof(int), compare_int);
assert(set_size(me) == 0);
assert(set_is_empty(me));
key = 4;
set_put(me, &key);
assert(set_size(me) == 1);
set_put(me, &key);
assert(set_size(me) == 1);
assert(!set_is_empty(me));
assert(set_contains(me, &key));
key = 7;
assert(!set_contains(me, &key));
set_put(me, &key);
assert(set_size(me) == 2);
assert(set_contains(me, &key));
for (i = 0; i < 10; i++) {
set_put(me, &c[i]);
assert(set_contains(me, &c[i]));
}
assert(set_size(me) == 9);
for (i = 0; i < 10; i++) {
assert(set_contains(me, &c[i]));
}
for (i = -100; i < 100; i++) {
int contains = 0;
for (j = 0; j < 10; j++) {
if (c[j] == i) {
contains = 1;
}
}
assert(set_contains(me, &i) == contains);
}
num = -3;
assert(!set_remove(me, &num));
assert(set_size(me) == 9);
assert(!set_contains(me, &num));
num = 6;
assert(set_remove(me, &num));
assert(set_size(me) == 8);
assert(!set_contains(me, &num));
num = 4;
assert(set_remove(me, &num));
assert(set_size(me) == 7);
assert(!set_contains(me, &num));
num = 7;
assert(set_remove(me, &num));
assert(set_size(me) == 6);
assert(!set_contains(me, &num));
num = 9;
assert(set_remove(me, &num));
assert(set_size(me) == 5);
assert(!set_contains(me, &num));
num = -5;
assert(set_remove(me, &num));
assert(set_size(me) == 4);
assert(!set_contains(me, &num));
num = 0;
assert(set_remove(me, &num));
assert(set_size(me) == 3);
assert(!set_contains(me, &num));
num = 1;
assert(set_remove(me, &num));
assert(set_size(me) == 2);
assert(!set_contains(me, &num));
num = 5;
assert(set_remove(me, &num));
assert(set_size(me) == 1);
assert(!set_contains(me, &num));
num = 2;
assert(set_remove(me, &num));
assert(set_size(me) == 0);
assert(!set_contains(me, &num));
/* Add a lot of items and remove individually. */
for (i = 5000; i < 6000; i++) {
set_put(me, &i);
assert(set_contains(me, &i));
}
assert(set_size(me) == 1000);
for (i = 5000; i < 5500; i++) {
set_remove(me, &i);
assert(!set_contains(me, &i));
}
assert(set_size(me) == 500);
assert(!set_is_empty(me));
set_clear(me);
assert(set_size(me) == 0);
assert(set_is_empty(me));
/* Add a lot of items and clear. */
for (i = 5000; i < 6000; i++) {
set_put(me, &i);
assert(set_contains(me, &i));
}
assert(set_size(me) == 1000);
set_clear(me);
p = 0xdeadbeef;
assert(!set_remove(me, &p));
assert(set_size(me) == 0);
assert(set_is_empty(me));
me = set_destroy(me);
assert(!me);
/* Create odd shape graph. */
me = set_init(sizeof(int), compare_int);
key = 10;
set_put(me, &key);
key = 5;
set_put(me, &key);
key = 15;
set_put(me, &key);
key = 3;
set_put(me, &key);
key = 8;
set_put(me, &key);
key = 12;
set_put(me, &key);
key = 18;
set_put(me, &key);
key = 12;
set_remove(me, &key);
key = 5;
set_remove(me, &key);
key = 3;
set_remove(me, &key);
key = 8;
set_remove(me, &key);
set_clear(me);
/* Allocate many nodes. */
assert(!set_destroy(me));
}
static void test_stress_remove(void)
{
int i;
set me = set_init(sizeof(int), compare_int);
assert(me);
for (i = 8123; i < 12314; i += 3) {
set_put(me, &i);
assert(set_contains(me, &i));
@@ -297,151 +406,119 @@ void test_set(void)
set_remove(me, &i);
assert(!set_contains(me, &i));
}
set_clear(me);
/* Create another odd shape graph. */
key = 20;
set_put(me, &key);
key = 10;
set_put(me, &key);
key = 40;
set_put(me, &key);
key = 5;
set_put(me, &key);
key = 15;
set_put(me, &key);
key = 30;
set_put(me, &key);
key = 50;
set_put(me, &key);
key = 25;
set_put(me, &key);
key = 35;
set_put(me, &key);
key = 36;
set_put(me, &key);
key = 34;
set_put(me, &key);
key = 33;
set_put(me, &key);
key = 32;
set_put(me, &key);
key = 30;
set_remove(me, &key);
key = 32;
assert(set_contains(me, &key));
set_clear(me);
/* One sided tree. */
key = 10;
set_put(me, &key);
key = 9;
set_put(me, &key);
key = 8;
set_put(me, &key);
key = 7;
set_put(me, &key);
key = 8;
set_remove(me, &key);
key = 7;
assert(set_contains(me, &key));
set_destroy(me);
/* Replace two sided two children. */
me = set_init(sizeof(int), compare_int);
key = 5;
set_put(me, &key);
key = 1;
set_put(me, &key);
key = 6;
set_put(me, &key);
key = -1;
set_put(me, &key);
key = 3;
set_put(me, &key);
key = 7;
set_put(me, &key);
key = -2;
set_put(me, &key);
key = 0;
set_put(me, &key);
key = 2;
set_put(me, &key);
key = 4;
set_put(me, &key);
key = 1;
set_remove(me, &key);
assert(!set_contains(me, &key));
set_clear(me);
key = 5;
set_put(me, &key);
key = 1;
set_put(me, &key);
key = 6;
set_put(me, &key);
key = -1;
set_put(me, &key);
key = 3;
set_put(me, &key);
key = 7;
set_put(me, &key);
key = -2;
set_put(me, &key);
key = 0;
set_put(me, &key);
key = 4;
set_put(me, &key);
key = 1;
set_remove(me, &key);
assert(!set_contains(me, &key));
me = set_destroy(me);
assert(!me);
me = set_init(sizeof(int), compare_int);
for (i = 4817; i > -2983; i -= 11) {
set_put(me, &i);
assert(set_contains(me, &i));
}
for (i = -432; i < 3849; i += 7) {
set_remove(me, &i);
assert(!set_contains(me, &i));
}
set_clear(me);
key = 5;
set_put(me, &key);
key = 7;
set_put(me, &key);
key = 5;
set_remove(me, &key);
set_clear(me);
/* Two children edge case on the other side. */
key = 8;
set_put(me, &key);
key = 4;
set_put(me, &key);
key = 12;
set_put(me, &key);
key = 2;
set_put(me, &key);
key = 6;
set_put(me, &key);
key = 10;
set_put(me, &key);
key = 16;
set_put(me, &key);
key = 1;
set_put(me, &key);
key = 3;
set_put(me, &key);
key = 5;
set_put(me, &key);
key = 7;
set_put(me, &key);
key = 9;
set_put(me, &key);
key = 11;
set_put(me, &key);
key = 15;
set_put(me, &key);
key = 17;
set_put(me, &key);
key = 13;
set_put(me, &key);
set_clear(me);
assert(!set_destroy(me));
}
static void test_unique_delete_one_child(set me)
{
int arr1[] = {2, 1, -2};
int arr2[] = {1, 2, -1};
int arr3[] = {3, 2, 4, 1, -2};
int arr4[] = {3, 1, 4, 2, -1};
int arr5[] = {3, 1, 4, 2, -4};
int arr6[] = {2, 1, 3, 4, -3};
int sz1 = sizeof(arr1) / sizeof(arr1[0]);
int sz2 = sizeof(arr2) / sizeof(arr2[0]);
int sz3 = sizeof(arr3) / sizeof(arr3[0]);
int sz4 = sizeof(arr4) / sizeof(arr4[0]);
int sz5 = sizeof(arr5) / sizeof(arr5[0]);
int sz6 = sizeof(arr6) / sizeof(arr6[0]);
mutation_order(me, arr1, sz1);
set_clear(me);
mutation_order(me, arr2, sz2);
set_clear(me);
mutation_order(me, arr3, sz3);
set_clear(me);
mutation_order(me, arr4, sz4);
set_clear(me);
mutation_order(me, arr5, sz5);
set_clear(me);
mutation_order(me, arr6, sz6);
}
static void test_unique_delete_two_children(set me)
{
int arr1[] = {2, 1, 3, -2};
int arr2[] = {4, 2, 5, 1, 3, -2};
int arr3[] = {2, 1, 4, 3, 5, -4};
int sz1 = sizeof(arr1) / sizeof(arr1[0]);
int sz2 = sizeof(arr2) / sizeof(arr2[0]);
int sz3 = sizeof(arr3) / sizeof(arr3[0]);
mutation_order(me, arr1, sz1);
set_clear(me);
mutation_order(me, arr2, sz2);
set_clear(me);
mutation_order(me, arr3, sz3);
}
static void test_unique_deletion_patterns(void)
{
set me = set_init(sizeof(int), compare_int);
assert(me);
test_unique_delete_one_child(me);
set_clear(me);
test_unique_delete_two_children(me);
assert(!set_destroy(me));
}
static void test_init_out_of_memory(void)
{
fail_malloc = 1;
assert(!set_init(sizeof(int), compare_int));
}
static void test_put_root_out_of_memory(set me)
{
int key = 2;
fail_malloc = 1;
assert(set_put(me, &key) == -ENOMEM);
fail_malloc = 1;
delay_fail_malloc = 1;
assert(set_put(me, &key) == -ENOMEM);
}
static void test_put_on_left_out_of_memory(set me)
{
int key = 1;
fail_malloc = 1;
assert(set_put(me, &key) == -ENOMEM);
fail_malloc = 1;
delay_fail_malloc = 1;
assert(set_put(me, &key) == -ENOMEM);
}
static void test_put_on_right_out_of_memory(set me)
{
int key = 3;
fail_malloc = 1;
assert(set_put(me, &key) == -ENOMEM);
fail_malloc = 1;
delay_fail_malloc = 1;
assert(set_put(me, &key) == -ENOMEM);
}
static void test_put_out_of_memory(void)
{
int key = 2;
set me = set_init(sizeof(int), compare_int);
assert(me);
test_put_root_out_of_memory(me);
assert(set_put(me, &key) == 0);
test_put_on_left_out_of_memory(me);
test_put_on_right_out_of_memory(me);
assert(!set_destroy(me));
}
void test_set(void)
{
test_invalid_init();
test_auto_balancing();
test_put_already_existing();
test_remove_nothing();
test_contains();
test_stress_add();
test_stress_remove();
test_unique_deletion_patterns();
test_init_out_of_memory();
test_put_out_of_memory();
}

View File

@@ -1,16 +1,16 @@
#include "test.h"
#include "../src/stack.h"
void test_stack(void)
static void test_invalid_init(void)
{
assert(!stack_init(0));
}
static void test_linear_operations(stack me)
{
int val[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int get_arr[10] = {0};
stack me;
int get;
int i;
assert(!stack_init(0));
me = stack_init(sizeof(int));
assert(me);
assert(stack_size(me) == 0);
assert(stack_is_empty(me));
for (i = 0; i < 10; i++) {
@@ -19,6 +19,13 @@ void test_stack(void)
assert(stack_top(&get, me));
assert(get == val[i]);
}
}
static void test_array_copy(stack me)
{
int get_arr[10] = {0};
int get;
int i;
assert(stack_size(me) == 10);
assert(!stack_is_empty(me));
stack_copy_to_array(get_arr, me);
@@ -37,13 +44,48 @@ void test_stack(void)
get = 0;
assert(!stack_pop(&get, me));
assert(!stack_top(&get, me));
me = stack_destroy(me);
assert(!me);
/* Testing automatic trim. */
me = stack_init(sizeof(int));
}
static void test_basic(void)
{
stack me = stack_init(sizeof(int));
assert(me);
test_linear_operations(me);
test_array_copy(me);
assert(!stack_destroy(me));
}
static void test_automated_trim(void)
{
stack me = stack_init(sizeof(int));
int get;
int i;
for (i = 0; i < 100; i++) {
stack_push(me, &i);
stack_pop(&get, me);
}
stack_destroy(me);
assert(!stack_destroy(me));
}
static void test_init_out_of_memory(void)
{
fail_malloc = 1;
assert(!stack_init(sizeof(int)));
fail_malloc = 1;
delay_fail_malloc = 1;
assert(!stack_init(sizeof(int)));
fail_malloc = 1;
delay_fail_malloc = 2;
assert(!stack_init(sizeof(int)));
fail_malloc = 1;
delay_fail_malloc = 3;
assert(!stack_init(sizeof(int)));
}
void test_stack(void)
{
test_invalid_init();
test_basic();
test_automated_trim();
test_init_out_of_memory();
}

View File

@@ -1,5 +1,70 @@
#include "test.h"
#define _GNU_SOURCE
#include <dlfcn.h>
#ifndef RTLD_NEXT
#define RTLD_NEXT ((void *) -1L)
#endif
int fail_malloc = 0;
int fail_calloc = 0;
int fail_realloc = 0;
int delay_fail_malloc = 0;
int delay_fail_calloc = 0;
int delay_fail_realloc = 0;
static void *(*real_malloc)(size_t);
static void *(*real_calloc)(size_t, size_t);
static void *(*real_realloc)(void *, size_t);
void *malloc(size_t size)
{
if (!real_malloc) {
real_malloc = dlsym(RTLD_NEXT, "malloc");
}
if (delay_fail_malloc == 0 && fail_malloc == 1) {
fail_malloc = 0;
return NULL;
}
if (delay_fail_malloc > 0) {
delay_fail_malloc--;
}
return real_malloc(size);
}
void *calloc(size_t count, size_t size)
{
if (!real_calloc) {
real_calloc = dlsym(RTLD_NEXT, "calloc");
}
if (delay_fail_calloc == 0 && fail_calloc == 1) {
fail_calloc = 0;
return NULL;
}
if (delay_fail_calloc > 0) {
delay_fail_calloc--;
}
return real_calloc(count, size);
}
void *realloc(void *ptr, size_t new_size)
{
if (!real_realloc) {
real_realloc = dlsym(RTLD_NEXT, "realloc");
}
if (delay_fail_realloc == 0 && fail_realloc == 1) {
fail_realloc = 0;
return NULL;
}
if (delay_fail_realloc > 0) {
delay_fail_realloc--;
}
return real_realloc(ptr, new_size);
}
int main(void)
{
test_array();

View File

@@ -5,6 +5,14 @@
#include <errno.h>
#include <assert.h>
extern int fail_malloc;
extern int fail_calloc;
extern int fail_realloc;
extern int delay_fail_malloc;
extern int delay_fail_calloc;
extern int delay_fail_realloc;
void test_array(void);
void test_vector(void);
void test_deque(void);

View File

@@ -18,25 +18,26 @@ static unsigned long hash_int(const void *const key)
return hash;
}
static unsigned long bad_hash_int(const void *const key)
static unsigned long bad_hash_int()
{
return 5;
}
void test_unordered_map(void)
static void test_invalid_init(void)
{
int val_arr[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
unordered_map me;
int key;
int num;
int value;
int i;
int j;
assert(!unordered_map_init(0, sizeof(int), hash_int, compare_int));
assert(!unordered_map_init(sizeof(int), 0, hash_int, compare_int));
assert(!unordered_map_init(sizeof(int), sizeof(int), NULL, compare_int));
assert(!unordered_map_init(sizeof(int), sizeof(int), hash_int, NULL));
me = unordered_map_init(sizeof(int), sizeof(int), hash_int, compare_int);
}
static void test_put(unordered_map me)
{
int val_arr[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
int key;
int value;
int i;
int j;
assert(unordered_map_size(me) == 0);
assert(unordered_map_is_empty(me));
key = 4;
@@ -73,7 +74,11 @@ void test_unordered_map(void)
}
assert(unordered_map_contains(me, &i) == contains);
}
num = -3;
}
static void test_remove(unordered_map me)
{
int num = -3;
assert(!unordered_map_remove(me, &num));
assert(unordered_map_size(me) == 9);
assert(!unordered_map_contains(me, &num));
@@ -113,7 +118,12 @@ void test_unordered_map(void)
assert(unordered_map_remove(me, &num));
assert(unordered_map_size(me) == 0);
assert(!unordered_map_contains(me, &num));
/* Add a lot of items and remove individually. */
}
static void test_stress_remove(unordered_map me)
{
int value = 27;
int i;
for (i = 5000; i < 6000; i++) {
unordered_map_put(me, &i, &value);
assert(unordered_map_contains(me, &i));
@@ -128,7 +138,13 @@ void test_unordered_map(void)
unordered_map_clear(me);
assert(unordered_map_size(me) == 0);
assert(unordered_map_is_empty(me));
/* Add a lot of items and clear. */
}
static void test_stress_clear(unordered_map me)
{
int value = 57;
int key;
int i;
for (i = 5000; i < 6000; i++) {
unordered_map_put(me, &i, &value);
assert(unordered_map_contains(me, &i));
@@ -142,10 +158,27 @@ void test_unordered_map(void)
assert(!unordered_map_remove(me, &key));
assert(unordered_map_size(me) == 0);
assert(unordered_map_is_empty(me));
me = unordered_map_destroy(me);
assert(!me);
me = unordered_map_init(sizeof(int), sizeof(int), bad_hash_int,
compare_int);
}
static void test_basic(void)
{
unordered_map me = unordered_map_init(sizeof(int), sizeof(int), hash_int,
compare_int);
assert(me);
test_put(me);
test_remove(me);
test_stress_remove(me);
test_stress_clear(me);
assert(!unordered_map_destroy(me));
}
static void test_bad_hash(void)
{
int num;
int key;
int value;
unordered_map me = unordered_map_init(sizeof(int), sizeof(int),
bad_hash_int, compare_int);
num = 1;
unordered_map_put(me, &num, &num);
num = 2;
@@ -166,4 +199,108 @@ void test_unordered_map(void)
value = 0xdeadbeef;
assert(!unordered_map_get(&value, me, &key));
assert(value == 0xdeadbeef);
assert(!unordered_map_destroy(me));
}
static void test_init_out_of_memory(void)
{
fail_malloc = 1;
assert(!unordered_map_init(sizeof(int), sizeof(int), bad_hash_int,
compare_int));
fail_calloc = 1;
assert(!unordered_map_init(sizeof(int), sizeof(int), bad_hash_int,
compare_int));
}
static void test_rehash_out_of_memory(void)
{
int key = 5;
int value = 7;
unordered_map me = unordered_map_init(sizeof(int), sizeof(int),
bad_hash_int, compare_int);
assert(me);
unordered_map_put(me, &key, &value);
assert(unordered_map_size(me) == 1);
assert(unordered_map_contains(me, &key));
fail_calloc = 1;
assert(unordered_map_rehash(me) == -ENOMEM);
assert(unordered_map_size(me) == 1);
assert(unordered_map_contains(me, &key));
assert(!unordered_map_destroy(me));
}
static void test_put_out_of_memory(void)
{
int key = 5;
int value = 7;
unordered_map me = unordered_map_init(sizeof(int), sizeof(int),
bad_hash_int, compare_int);
assert(me);
fail_malloc = 1;
assert(unordered_map_put(me, &key, &value) == -ENOMEM);
fail_malloc = 1;
delay_fail_malloc = 1;
assert(unordered_map_put(me, &key, &value) == -ENOMEM);
fail_malloc = 1;
delay_fail_malloc = 2;
assert(unordered_map_put(me, &key, &value) == -ENOMEM);
assert(unordered_map_put(me, &key, &value) == 0);
key = 7;
fail_malloc = 1;
assert(unordered_map_put(me, &key, &value) == -ENOMEM);
fail_malloc = 1;
delay_fail_malloc = 1;
assert(unordered_map_put(me, &key, &value) == -ENOMEM);
fail_malloc = 1;
delay_fail_malloc = 2;
assert(unordered_map_put(me, &key, &value) == -ENOMEM);
assert(!unordered_map_destroy(me));
}
static void test_resize_out_of_memory(void)
{
int i;
unordered_map me = unordered_map_init(sizeof(int), sizeof(int), hash_int,
compare_int);
for (i = 0; i < 5; i++) {
assert(unordered_map_put(me, &i, &i) == 0);
}
assert(unordered_map_size(me) == 5);
i++;
fail_calloc = 1;
assert(unordered_map_put(me, &i, &i) == -ENOMEM);
assert(unordered_map_size(me) == 5);
for (i = 0; i < 5; i++) {
assert(unordered_map_contains(me, &i));
}
assert(!unordered_map_destroy(me));
}
static void test_clear_out_of_memory(void)
{
int key = 5;
int value = 7;
unordered_map me = unordered_map_init(sizeof(int), sizeof(int), hash_int,
compare_int);
assert(me);
assert(unordered_map_put(me, &key, &value) == 0);
assert(unordered_map_size(me) == 1);
assert(unordered_map_contains(me, &key));
fail_calloc = 1;
assert(unordered_map_clear(me) == -ENOMEM);
assert(unordered_map_size(me) == 1);
assert(unordered_map_contains(me, &key));
assert(!unordered_map_destroy(me));
}
void test_unordered_map(void)
{
test_invalid_init();
test_basic();
test_bad_hash();
test_init_out_of_memory();
test_rehash_out_of_memory();
test_put_out_of_memory();
test_resize_out_of_memory();
test_clear_out_of_memory();
}

View File

@@ -18,22 +18,13 @@ static unsigned long hash_int(const void *const key)
return hash;
}
static unsigned long bad_hash_int(const void *const key)
static unsigned long bad_hash_int()
{
return 5;
}
void test_unordered_multimap(void)
static void test_invalid_init(void)
{
int c[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
unordered_multimap me;
int key;
int value;
int num;
int count;
int val;
int i;
int j;
assert(!unordered_multimap_init(0, sizeof(int), hash_int, compare_int,
compare_int));
assert(!unordered_multimap_init(sizeof(int), 0, hash_int, compare_int,
@@ -44,13 +35,18 @@ void test_unordered_multimap(void)
compare_int));
assert(!unordered_multimap_init(sizeof(int), sizeof(int), hash_int,
compare_int, NULL));
me = unordered_multimap_init(sizeof(int), sizeof(int), hash_int,
compare_int, compare_int);
assert(me);
}
static void test_put(unordered_multimap me)
{
int val_arr[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
int value = 123;
int key;
int i;
int j;
assert(unordered_multimap_size(me) == 0);
assert(unordered_multimap_is_empty(me));
key = 4;
value = 123;
unordered_multimap_put(me, &key, &value);
assert(unordered_multimap_size(me) == 1);
unordered_multimap_put(me, &key, &value);
@@ -71,23 +67,28 @@ void test_unordered_multimap(void)
unordered_multimap_remove(me, &key, &value);
assert(unordered_multimap_size(me) == 0);
for (i = 0; i < 10; i++) {
unordered_multimap_put(me, &c[i], &value);
assert(unordered_multimap_contains(me, &c[i]));
unordered_multimap_put(me, &val_arr[i], &value);
assert(unordered_multimap_contains(me, &val_arr[i]));
}
assert(unordered_multimap_size(me) == 10);
for (i = 0; i < 10; i++) {
assert(unordered_multimap_contains(me, &c[i]));
assert(unordered_multimap_contains(me, &val_arr[i]));
}
for (i = -100; i < 100; i++) {
int contains = 0;
for (j = 0; j < 10; j++) {
if (c[j] == i) {
if (val_arr[j] == i) {
contains = 1;
}
}
assert(unordered_multimap_contains(me, &i) == contains);
}
num = -3;
}
static void test_remove(unordered_multimap me)
{
int value = 123;
int num = -3;
assert(!unordered_multimap_remove(me, &num, &value));
assert(unordered_multimap_size(me) == 10);
assert(!unordered_multimap_contains(me, &num));
@@ -119,7 +120,14 @@ void test_unordered_multimap(void)
assert(unordered_multimap_remove(me, &num, &value));
assert(unordered_multimap_size(me) == 3);
assert(!unordered_multimap_contains(me, &num));
num = 5;
}
static void test_multiple_values_one_key(unordered_multimap me)
{
int value = 123;
int num = 5;
int count;
int val;
assert(unordered_multimap_count(me, &num) == 2);
unordered_multimap_get_start(me, &num);
count = 0;
@@ -141,7 +149,12 @@ void test_unordered_multimap(void)
assert(unordered_multimap_remove(me, &num, &value));
assert(unordered_multimap_size(me) == 0);
assert(!unordered_multimap_contains(me, &num));
/* Add a lot of items and remove individually. */
}
static void test_stress_remove(unordered_multimap me)
{
int value = 123;
int i;
for (i = 5000; i < 6000; i++) {
unordered_multimap_put(me, &i, &value);
assert(unordered_multimap_contains(me, &i));
@@ -156,7 +169,13 @@ void test_unordered_multimap(void)
unordered_multimap_clear(me);
assert(unordered_multimap_size(me) == 0);
assert(unordered_multimap_is_empty(me));
/* Add a lot of items and clear. */
}
static void test_stress_clear(unordered_multimap me)
{
int value = 123;
int key;
int i;
for (i = 5000; i < 6000; i++) {
unordered_multimap_put(me, &i, &value);
assert(unordered_multimap_contains(me, &i));
@@ -180,11 +199,29 @@ void test_unordered_multimap(void)
assert(unordered_multimap_size(me) == 11);
unordered_multimap_remove_all(me, &key);
assert(unordered_multimap_size(me) == 1);
me = unordered_multimap_destroy(me);
assert(!me);
me = unordered_multimap_init(sizeof(int), sizeof(int), bad_hash_int,
compare_int, compare_int);
key = 1;
}
static void test_basic(void)
{
unordered_multimap me = unordered_multimap_init(sizeof(int), sizeof(int),
hash_int, compare_int,
compare_int);
assert(me);
test_put(me);
test_remove(me);
test_multiple_values_one_key(me);
test_stress_remove(me);
test_stress_clear(me);
assert(!unordered_multimap_destroy(me));
}
static void test_bad_hash(void)
{
unordered_multimap me = unordered_multimap_init(sizeof(int), sizeof(int),
bad_hash_int, compare_int,
compare_int);
int value = 123;
int key = 1;
unordered_multimap_put(me, &key, &value);
key = 2;
unordered_multimap_put(me, &key, &value);
@@ -201,9 +238,16 @@ void test_unordered_multimap(void)
assert(unordered_multimap_size(me) == 4);
unordered_multimap_rehash(me);
assert(unordered_multimap_size(me) == 4);
me = unordered_multimap_init(sizeof(int), sizeof(int), bad_hash_int,
compare_int, compare_int);
key = 1;
assert(!unordered_multimap_destroy(me));
}
static void test_collision(void)
{
unordered_multimap me = unordered_multimap_init(sizeof(int), sizeof(int),
bad_hash_int, compare_int,
compare_int);
int value = 123;
int key = 1;
unordered_multimap_put(me, &key, &value);
key = 2;
unordered_multimap_put(me, &key, &value);
@@ -224,10 +268,16 @@ void test_unordered_multimap(void)
assert(unordered_multimap_size(me) == 0);
assert(!unordered_multimap_remove_all(me, &key));
assert(unordered_multimap_size(me) == 0);
me = unordered_multimap_init(sizeof(int), sizeof(int), bad_hash_int,
compare_int, compare_int);
key = 1;
value = 10;
assert(!unordered_multimap_destroy(me));
}
static void test_bad_hash_collision(void)
{
unordered_multimap me = unordered_multimap_init(sizeof(int), sizeof(int),
bad_hash_int, compare_int,
compare_int);
int key = 1;
int value = 10;
unordered_multimap_put(me, &key, &value);
key = 2;
value = 11;
@@ -250,4 +300,118 @@ void test_unordered_multimap(void)
value = 30;
assert(!unordered_multimap_get_next(&value, me));
assert(value == 30);
assert(!unordered_multimap_destroy(me));
}
static void test_init_out_of_memory(void)
{
fail_malloc = 1;
assert(!unordered_multimap_init(sizeof(int), sizeof(int), hash_int,
compare_int, compare_int));
fail_calloc = 1;
assert(!unordered_multimap_init(sizeof(int), sizeof(int), hash_int,
compare_int, compare_int));
fail_calloc = 1;
delay_fail_calloc = 1;
assert(!unordered_multimap_init(sizeof(int), sizeof(int), hash_int,
compare_int, compare_int));
}
static void test_rehash_out_of_memory(void)
{
int key = 5;
int value = 7;
unordered_multimap me = unordered_multimap_init(sizeof(int), sizeof(int),
bad_hash_int, compare_int,
compare_int);
assert(me);
unordered_multimap_put(me, &key, &value);
assert(unordered_multimap_size(me) == 1);
assert(unordered_multimap_contains(me, &key));
fail_calloc = 1;
assert(unordered_multimap_rehash(me) == -ENOMEM);
assert(unordered_multimap_size(me) == 1);
assert(unordered_multimap_contains(me, &key));
assert(!unordered_multimap_destroy(me));
}
static void test_put_out_of_memory(void)
{
int key = 5;
int value = 7;
unordered_multimap me = unordered_multimap_init(sizeof(int), sizeof(int),
bad_hash_int, compare_int,
compare_int);
assert(me);
fail_malloc = 1;
assert(unordered_multimap_put(me, &key, &value) == -ENOMEM);
fail_malloc = 1;
delay_fail_malloc = 1;
assert(unordered_multimap_put(me, &key, &value) == -ENOMEM);
fail_malloc = 1;
delay_fail_malloc = 2;
assert(unordered_multimap_put(me, &key, &value) == -ENOMEM);
assert(unordered_multimap_put(me, &key, &value) == 0);
key = 7;
fail_malloc = 1;
assert(unordered_multimap_put(me, &key, &value) == -ENOMEM);
fail_malloc = 1;
delay_fail_malloc = 1;
assert(unordered_multimap_put(me, &key, &value) == -ENOMEM);
fail_malloc = 1;
delay_fail_malloc = 2;
assert(unordered_multimap_put(me, &key, &value) == -ENOMEM);
assert(!unordered_multimap_destroy(me));
}
static void test_resize_out_of_memory(void)
{
int i;
unordered_multimap me = unordered_multimap_init(sizeof(int), sizeof(int),
hash_int, compare_int,
compare_int);
for (i = 0; i < 5; i++) {
assert(unordered_multimap_put(me, &i, &i) == 0);
}
assert(unordered_multimap_size(me) == 5);
i++;
fail_calloc = 1;
assert(unordered_multimap_put(me, &i, &i) == -ENOMEM);
assert(unordered_multimap_size(me) == 5);
for (i = 0; i < 5; i++) {
assert(unordered_multimap_contains(me, &i));
}
assert(!unordered_multimap_destroy(me));
}
static void test_clear_out_of_memory(void)
{
int key = 5;
int value = 7;
unordered_multimap me = unordered_multimap_init(sizeof(int), sizeof(int),
hash_int, compare_int,
compare_int);
assert(me);
assert(unordered_multimap_put(me, &key, &value) == 0);
assert(unordered_multimap_size(me) == 1);
assert(unordered_multimap_contains(me, &key));
fail_calloc = 1;
assert(unordered_multimap_clear(me) == -ENOMEM);
assert(unordered_multimap_size(me) == 1);
assert(unordered_multimap_contains(me, &key));
assert(!unordered_multimap_destroy(me));
}
void test_unordered_multimap(void)
{
test_invalid_init();
test_basic();
test_bad_hash();
test_collision();
test_bad_hash_collision();
test_init_out_of_memory();
test_rehash_out_of_memory();
test_put_out_of_memory();
test_resize_out_of_memory();
test_clear_out_of_memory();
}

View File

@@ -18,24 +18,24 @@ static unsigned long hash_int(const void *const key)
return hash;
}
static unsigned long bad_hash_int(const void *const key)
static unsigned long bad_hash_int()
{
return 5;
}
void test_unordered_multiset(void)
static void test_invalid_init(void)
{
int c[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
unordered_multiset me;
int key;
int num;
int i;
int j;
assert(!unordered_multiset_init(0, hash_int, compare_int));
assert(!unordered_multiset_init(sizeof(int), NULL, compare_int));
assert(!unordered_multiset_init(sizeof(int), hash_int, NULL));
me = unordered_multiset_init(sizeof(int), hash_int, compare_int);
assert(me);
}
static void test_put(unordered_multiset me)
{
int val_arr[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
int key;
int i;
int j;
assert(unordered_multiset_size(me) == 0);
assert(unordered_multiset_is_empty(me));
key = 4;
@@ -59,23 +59,27 @@ void test_unordered_multiset(void)
unordered_multiset_remove(me, &key);
assert(unordered_multiset_size(me) == 0);
for (i = 0; i < 10; i++) {
unordered_multiset_put(me, &c[i]);
assert(unordered_multiset_contains(me, &c[i]));
unordered_multiset_put(me, &val_arr[i]);
assert(unordered_multiset_contains(me, &val_arr[i]));
}
assert(unordered_multiset_size(me) == 10);
for (i = 0; i < 10; i++) {
assert(unordered_multiset_contains(me, &c[i]));
assert(unordered_multiset_contains(me, &val_arr[i]));
}
for (i = -100; i < 100; i++) {
int contains = 0;
for (j = 0; j < 10; j++) {
if (c[j] == i) {
if (val_arr[j] == i) {
contains = 1;
}
}
assert(unordered_multiset_contains(me, &i) == contains);
}
num = -3;
}
static void test_remove(unordered_multiset me)
{
int num = -3;
assert(!unordered_multiset_remove(me, &num));
assert(unordered_multiset_size(me) == 10);
assert(!unordered_multiset_contains(me, &num));
@@ -119,7 +123,11 @@ void test_unordered_multiset(void)
assert(unordered_multiset_remove(me, &num));
assert(unordered_multiset_size(me) == 0);
assert(!unordered_multiset_contains(me, &num));
/* Add a lot of items and remove individually. */
}
static void test_stress_remove(unordered_multiset me)
{
int i;
for (i = 5000; i < 6000; i++) {
unordered_multiset_put(me, &i);
assert(unordered_multiset_contains(me, &i));
@@ -134,7 +142,12 @@ void test_unordered_multiset(void)
unordered_multiset_clear(me);
assert(unordered_multiset_size(me) == 0);
assert(unordered_multiset_is_empty(me));
/* Add a lot of items and clear. */
}
static void test_stress_clear(unordered_multiset me)
{
int key;
int i;
for (i = 5000; i < 6000; i++) {
unordered_multiset_put(me, &i);
assert(unordered_multiset_contains(me, &i));
@@ -158,9 +171,26 @@ void test_unordered_multiset(void)
assert(unordered_multiset_size(me) == 11);
unordered_multiset_remove_all(me, &key);
assert(unordered_multiset_size(me) == 1);
me = unordered_multiset_destroy(me);
assert(!me);
me = unordered_multiset_init(sizeof(int), bad_hash_int, compare_int);
}
static void test_basic(void)
{
unordered_multiset me = unordered_multiset_init(sizeof(int), hash_int,
compare_int);
assert(me);
test_put(me);
test_remove(me);
test_stress_remove(me);
test_stress_clear(me);
assert(!unordered_multiset_destroy(me));
}
static void test_bad_hash(void)
{
int num;
unordered_multiset me = unordered_multiset_init(sizeof(int), bad_hash_int,
compare_int);
assert(me);
num = 1;
unordered_multiset_put(me, &num);
num = 2;
@@ -178,7 +208,15 @@ void test_unordered_multiset(void)
assert(unordered_multiset_size(me) == 4);
unordered_multiset_rehash(me);
assert(unordered_multiset_size(me) == 4);
me = unordered_multiset_init(sizeof(int), bad_hash_int, compare_int);
assert(!unordered_multiset_destroy(me));
}
static void test_collision(void)
{
int num;
unordered_multiset me = unordered_multiset_init(sizeof(int), bad_hash_int,
compare_int);
assert(me);
num = 1;
unordered_multiset_put(me, &num);
num = 2;
@@ -200,4 +238,98 @@ void test_unordered_multiset(void)
assert(unordered_multiset_size(me) == 0);
assert(!unordered_multiset_remove_all(me, &num));
assert(unordered_multiset_size(me) == 0);
assert(!unordered_multiset_destroy(me));
}
static void test_init_out_of_memory(void)
{
fail_malloc = 1;
assert(!unordered_multiset_init(sizeof(int), hash_int, compare_int));
fail_calloc = 1;
assert(!unordered_multiset_init(sizeof(int), hash_int, compare_int));
}
static void test_rehash_out_of_memory(void)
{
int key = 5;
unordered_multiset me = unordered_multiset_init(sizeof(int), hash_int,
compare_int);
assert(me);
unordered_multiset_put(me, &key);
assert(unordered_multiset_size(me) == 1);
assert(unordered_multiset_contains(me, &key));
fail_calloc = 1;
assert(unordered_multiset_rehash(me) == -ENOMEM);
assert(unordered_multiset_size(me) == 1);
assert(unordered_multiset_contains(me, &key));
assert(!unordered_multiset_destroy(me));
}
static void test_put_out_of_memory(void)
{
int key = 5;
unordered_multiset me = unordered_multiset_init(sizeof(int), bad_hash_int,
compare_int);
assert(me);
fail_malloc = 1;
assert(unordered_multiset_put(me, &key) == -ENOMEM);
fail_malloc = 1;
delay_fail_malloc = 1;
assert(unordered_multiset_put(me, &key) == -ENOMEM);
assert(unordered_multiset_put(me, &key) == 0);
key = 7;
fail_malloc = 1;
assert(unordered_multiset_put(me, &key) == -ENOMEM);
fail_malloc = 1;
delay_fail_malloc = 1;
assert(unordered_multiset_put(me, &key) == -ENOMEM);
assert(!unordered_multiset_destroy(me));
}
static void test_resize_out_of_memory(void)
{
int i;
unordered_multiset me = unordered_multiset_init(sizeof(int), hash_int,
compare_int);
for (i = 0; i < 5; i++) {
assert(unordered_multiset_put(me, &i) == 0);
}
assert(unordered_multiset_size(me) == 5);
i++;
fail_calloc = 1;
assert(unordered_multiset_put(me, &i) == -ENOMEM);
assert(unordered_multiset_size(me) == 5);
for (i = 0; i < 5; i++) {
assert(unordered_multiset_contains(me, &i));
}
assert(!unordered_multiset_destroy(me));
}
static void test_clear_out_of_memory(void)
{
int key = 5;
unordered_multiset me = unordered_multiset_init(sizeof(int), hash_int,
compare_int);
assert(me);
assert(unordered_multiset_put(me, &key) == 0);
assert(unordered_multiset_size(me) == 1);
assert(unordered_multiset_contains(me, &key));
fail_calloc = 1;
assert(unordered_multiset_clear(me) == -ENOMEM);
assert(unordered_multiset_size(me) == 1);
assert(unordered_multiset_contains(me, &key));
assert(!unordered_multiset_destroy(me));
}
void test_unordered_multiset(void)
{
test_invalid_init();
test_basic();
test_bad_hash();
test_collision();
test_init_out_of_memory();
test_rehash_out_of_memory();
test_put_out_of_memory();
test_resize_out_of_memory();
test_clear_out_of_memory();
}

View File

@@ -18,25 +18,24 @@ static unsigned long hash_int(const void *const key)
return hash;
}
static unsigned long bad_hash_int(const void *const key)
static unsigned long bad_hash_int()
{
return 5;
}
void test_unordered_set(void)
static void test_invalid_init(void)
{
int val_arr[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
unordered_set me;
int key;
int num;
int p;
int i;
int j;
assert(!unordered_set_init(0, hash_int, compare_int));
assert(!unordered_set_init(sizeof(int), NULL, compare_int));
assert(!unordered_set_init(sizeof(int), hash_int, NULL));
me = unordered_set_init(sizeof(int), hash_int, compare_int);
assert(me);
}
static void test_put(unordered_set me)
{
int val_arr[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
int key;
int i;
int j;
assert(unordered_set_size(me) == 0);
assert(unordered_set_is_empty(me));
key = 4;
@@ -68,7 +67,11 @@ void test_unordered_set(void)
}
assert(unordered_set_contains(me, &i) == contains);
}
num = -3;
}
static void test_remove(unordered_set me)
{
int num = -3;
assert(!unordered_set_remove(me, &num));
assert(unordered_set_size(me) == 9);
assert(!unordered_set_contains(me, &num));
@@ -108,7 +111,11 @@ void test_unordered_set(void)
assert(unordered_set_remove(me, &num));
assert(unordered_set_size(me) == 0);
assert(!unordered_set_contains(me, &num));
/* Add a lot of items and remove individually. */
}
static void test_stress_remove(unordered_set me)
{
int i;
for (i = 5000; i < 6000; i++) {
unordered_set_put(me, &i);
assert(unordered_set_contains(me, &i));
@@ -123,7 +130,12 @@ void test_unordered_set(void)
unordered_set_clear(me);
assert(unordered_set_size(me) == 0);
assert(unordered_set_is_empty(me));
/* Add a lot of items and clear. */
}
static void test_stress_clear(unordered_set me)
{
int i;
int p = 0xdeadbeef;
for (i = 5000; i < 6000; i++) {
unordered_set_put(me, &i);
assert(unordered_set_contains(me, &i));
@@ -133,13 +145,28 @@ void test_unordered_set(void)
unordered_set_rehash(me);
assert(hash_count == 1000);
unordered_set_clear(me);
p = 0xdeadbeef;
assert(!unordered_set_remove(me, &p));
assert(unordered_set_size(me) == 0);
assert(unordered_set_is_empty(me));
me = unordered_set_destroy(me);
assert(!me);
me = unordered_set_init(sizeof(int), bad_hash_int, compare_int);
}
static void test_basic(void)
{
unordered_set me = unordered_set_init(sizeof(int), hash_int, compare_int);
assert(me);
test_put(me);
test_remove(me);
test_stress_remove(me);
test_stress_clear(me);
assert(!unordered_set_destroy(me));
}
static void test_bad_hash(void)
{
int num;
unordered_set me = unordered_set_init(sizeof(int), bad_hash_int,
compare_int);
assert(me);
num = 1;
unordered_set_put(me, &num);
num = 2;
@@ -156,4 +183,94 @@ void test_unordered_set(void)
assert(unordered_set_size(me) == 3);
unordered_set_rehash(me);
assert(unordered_set_size(me) == 3);
assert(!unordered_set_destroy(me));
}
static void test_init_out_of_memory(void)
{
fail_malloc = 1;
assert(!unordered_set_init(sizeof(int), hash_int, compare_int));
fail_calloc = 1;
assert(!unordered_set_init(sizeof(int), hash_int, compare_int));
}
static void test_rehash_out_of_memory(void)
{
int key = 5;
unordered_set me = unordered_set_init(sizeof(int), hash_int, compare_int);
assert(me);
unordered_set_put(me, &key);
assert(unordered_set_size(me) == 1);
assert(unordered_set_contains(me, &key));
fail_calloc = 1;
assert(unordered_set_rehash(me) == -ENOMEM);
assert(unordered_set_size(me) == 1);
assert(unordered_set_contains(me, &key));
assert(!unordered_set_destroy(me));
}
static void test_put_out_of_memory(void)
{
int key = 5;
unordered_set me = unordered_set_init(sizeof(int), bad_hash_int,
compare_int);
assert(me);
fail_malloc = 1;
assert(unordered_set_put(me, &key) == -ENOMEM);
fail_malloc = 1;
delay_fail_malloc = 1;
assert(unordered_set_put(me, &key) == -ENOMEM);
assert(unordered_set_put(me, &key) == 0);
key = 7;
fail_malloc = 1;
assert(unordered_set_put(me, &key) == -ENOMEM);
fail_malloc = 1;
delay_fail_malloc = 1;
assert(unordered_set_put(me, &key) == -ENOMEM);
assert(!unordered_set_destroy(me));
}
static void test_resize_out_of_memory(void)
{
int i;
unordered_set me = unordered_set_init(sizeof(int), hash_int, compare_int);
for (i = 0; i < 5; i++) {
assert(unordered_set_put(me, &i) == 0);
}
assert(unordered_set_size(me) == 5);
i++;
fail_calloc = 1;
assert(unordered_set_put(me, &i) == -ENOMEM);
assert(unordered_set_size(me) == 5);
for (i = 0; i < 5; i++) {
assert(unordered_set_contains(me, &i));
}
assert(!unordered_set_destroy(me));
}
static void test_clear_out_of_memory(void)
{
int key = 5;
unordered_set me = unordered_set_init(sizeof(int), hash_int, compare_int);
assert(me);
assert(unordered_set_put(me, &key) == 0);
assert(unordered_set_size(me) == 1);
assert(unordered_set_contains(me, &key));
fail_calloc = 1;
assert(unordered_set_clear(me) == -ENOMEM);
assert(unordered_set_size(me) == 1);
assert(unordered_set_contains(me, &key));
assert(!unordered_set_destroy(me));
}
void test_unordered_set(void)
{
test_invalid_init();
test_basic();
test_bad_hash();
test_init_out_of_memory();
test_rehash_out_of_memory();
test_put_out_of_memory();
test_resize_out_of_memory();
test_clear_out_of_memory();
}

View File

@@ -2,88 +2,18 @@
#include "test.h"
#include "../src/vector.h"
static void test_vector_of_vectors(void)
static void test_invalid_init(void)
{
/* Test using a vector of vectors of ints */
vector outer = vector_init(sizeof(vector));
/* Add vectors to the outer vector */
int i;
int j;
for (i = 0; i < 5; i++) {
vector inner = vector_init(sizeof(int));
for (j = 1; j <= 10; j++) {
vector_add_last(inner, &j);
}
assert(vector_size(inner) == 10);
vector_add_last(outer, &inner);
}
assert(vector_size(outer) == 5);
/* Delete the vectors in the outer vector */
for (i = 0; i < 5; i++) {
vector inner = NULL;
vector_get_first(&inner, outer);
for (j = 0; j < 10; j++) {
int num = 0xdeadbeef;
vector_get_at(&num, inner, j);
assert(num == j + 1);
}
vector_remove_first(outer);
vector_destroy(inner);
}
assert(vector_is_empty(outer));
vector_destroy(outer);
assert(!vector_init(0));
}
static void test_vector_dynamic(void)
static void test_adding(vector me)
{
char **str = malloc(5 * sizeof(char **));
int i;
int j;
vector str_vector;
for (i = 0; i < 5; i++) {
str[i] = malloc(10 * sizeof(char *));
for (j = 0; j < 9; j++) {
str[i][j] = (char) ('a' + i);
}
str[i][9] = '\0';
}
str_vector = vector_init(sizeof(char *));
assert(str_vector);
for (i = 0; i < 5; i++) {
vector_add_last(str_vector, &str[i]);
}
assert(vector_size(str_vector) == 5);
for (i = 0; i < 5; i++) {
char *retrieve = NULL;
vector_get_first(&retrieve, str_vector);
vector_remove_first(str_vector);
assert(strcmp(retrieve, str[i]) == 0);
free(retrieve);
}
free(str);
assert(vector_size(str_vector) == 0);
str_vector = vector_destroy(str_vector);
assert(!str_vector);
}
void test_vector(void)
{
int val[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int get_arr[10] = {0};
int trimmed[5] = {0};
int arr[3] = {0};
int get;
vector me;
int i;
int *data;
int add;
int set;
assert(!vector_init(0));
me = vector_init(sizeof(int));
assert(me);
assert(vector_size(me) == 0);
assert(vector_is_empty(me));
int get;
int i;
for (i = 0; i < 10; i++) {
vector_add_first(me, &val[i]);
get = 0;
@@ -104,6 +34,12 @@ void test_vector(void)
assert(data[i] == val[9 - i]);
}
assert(vector_capacity(me) >= vector_size(me));
}
static void test_trim(vector me)
{
int trimmed[5] = {0};
int i;
vector_trim(me);
vector_reserve(me, 3);
for (i = 0; i < 7; i++) {
@@ -114,7 +50,15 @@ void test_vector(void)
for (i = 0; i < 3; i++) {
assert(10 - i == trimmed[i]);
}
add = 3;
}
static void test_linear_operations(vector me)
{
int arr[3] = {0};
int get;
int set;
int add = 3;
assert(vector_size(me) == 3);
vector_add_last(me, &add);
add = -1;
vector_add_at(me, 1, &add);
@@ -171,6 +115,12 @@ void test_vector(void)
assert(arr[0] == -5);
assert(arr[1] == -6);
assert(arr[2] == -7);
}
static void test_invalid_operations(vector me)
{
int set;
int i;
assert(vector_reserve(me, 100) == 0);
assert(vector_set_at(me, 4, &set) == -EINVAL);
assert(vector_get_at(&set, me, 4) == -EINVAL);
@@ -190,8 +140,139 @@ void test_vector(void)
assert(vector_is_empty(me));
assert(vector_remove_first(me) == -EINVAL);
assert(vector_remove_last(me) == -EINVAL);
me = vector_destroy(me);
assert(!me);
test_vector_dynamic();
test_vector_of_vectors();
}
static void test_basic(void)
{
vector me = vector_init(sizeof(int));
assert(me);
assert(vector_size(me) == 0);
assert(vector_is_empty(me));
test_adding(me);
test_trim(me);
test_linear_operations(me);
test_invalid_operations(me);
assert(!vector_destroy(me));
}
static void test_vector_of_vectors(void)
{
/* Test using a vector of vectors of ints. */
vector outer = vector_init(sizeof(vector));
/* Add vectors to the outer vector. */
int i;
int j;
for (i = 0; i < 5; i++) {
vector inner = vector_init(sizeof(int));
for (j = 1; j <= 10; j++) {
vector_add_last(inner, &j);
}
assert(vector_size(inner) == 10);
vector_add_last(outer, &inner);
}
assert(vector_size(outer) == 5);
/* Delete the vectors in the outer vector. */
for (i = 0; i < 5; i++) {
vector inner = NULL;
vector_get_first(&inner, outer);
for (j = 0; j < 10; j++) {
int num = 0xdeadbeef;
vector_get_at(&num, inner, j);
assert(num == j + 1);
}
vector_remove_first(outer);
vector_destroy(inner);
}
assert(vector_is_empty(outer));
vector_destroy(outer);
}
static void test_dynamic(void)
{
char **str = malloc(5 * sizeof(char **));
int i;
int j;
vector str_vector;
for (i = 0; i < 5; i++) {
str[i] = malloc(10 * sizeof(char *));
for (j = 0; j < 9; j++) {
str[i][j] = (char) ('a' + i);
}
str[i][9] = '\0';
}
str_vector = vector_init(sizeof(char *));
assert(str_vector);
for (i = 0; i < 5; i++) {
vector_add_last(str_vector, &str[i]);
}
assert(vector_size(str_vector) == 5);
for (i = 0; i < 5; i++) {
char *retrieve = NULL;
vector_get_first(&retrieve, str_vector);
vector_remove_first(str_vector);
assert(strcmp(retrieve, str[i]) == 0);
free(retrieve);
}
free(str);
assert(vector_size(str_vector) == 0);
assert(!vector_destroy(str_vector));
}
static void test_init_out_of_memory(void)
{
fail_malloc = 1;
assert(!vector_init(sizeof(int)));
fail_malloc = 1;
delay_fail_malloc = 1;
assert(!vector_init(sizeof(int)));
}
static void test_set_space_out_of_memory(void)
{
vector me = vector_init(sizeof(int));
int i;
for (i = 0; i < 7; i++) {
assert(vector_add_last(me, &i) == 0);
}
fail_realloc = 1;
assert(vector_reserve(me, 9) == -ENOMEM);
assert(vector_size(me) == 7);
assert(vector_capacity(me) == 8);
for (i = 0; i < 7; i++) {
int get = 0xdeadbeef;
vector_get_at(&get, me, i);
assert(get == i);
}
assert(!vector_destroy(me));
}
static void test_add_out_of_memory(void)
{
vector me = vector_init(sizeof(int));
int i;
for (i = 0; i < 7; i++) {
assert(vector_add_last(me, &i) == 0);
}
i++;
fail_realloc = 1;
assert(vector_add_last(me, &i) == -ENOMEM);
assert(vector_size(me) == 7);
assert(vector_capacity(me) == 8);
for (i = 0; i < 7; i++) {
int get = 0xdeadbeef;
vector_get_at(&get, me, i);
assert(get == i);
}
assert(!vector_destroy(me));
}
void test_vector(void)
{
test_invalid_init();
test_basic();
test_vector_of_vectors();
test_dynamic();
test_init_out_of_memory();
test_set_space_out_of_memory();
test_add_out_of_memory();
}