From bf02cede2bf7e71dfddac8561ccd7ee5cbb308da Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Tue, 17 Jan 2023 10:48:42 +0100 Subject: [PATCH] Refactored tests --- README.md | 43 +- src/cmc/cmc/list/ext/struct.h | 4 +- src/cmc/{cmc_deque.h => deque.h} | 0 src/cmc/{cmc_list.h => list.h} | 0 src/cmc/{cmc_stack.h => stack.h} | 0 tests/Makefile | 11 + tests/main.c | 102 ++ tests/unt_deque.h | 1725 ++++++++++++++++++++++++++++++ tests/unt_list.h | 1072 +++++++++++++++++++ tests/unt_stack.h | 854 +++++++++++++++ tests/utl.h | 171 +++ 11 files changed, 3942 insertions(+), 40 deletions(-) rename src/cmc/{cmc_deque.h => deque.h} (100%) rename src/cmc/{cmc_list.h => list.h} (100%) rename src/cmc/{cmc_stack.h => stack.h} (100%) create mode 100644 tests/Makefile create mode 100644 tests/main.c create mode 100644 tests/unt_deque.h create mode 100644 tests/unt_list.h create mode 100644 tests/unt_stack.h create mode 100644 tests/utl.h diff --git a/README.md b/README.md index 3fc17e4..668a488 100644 --- a/README.md +++ b/README.md @@ -30,8 +30,6 @@ * [Available Collections](#available-collections) * [Other Features](#other-features) * [Design Decisions](#design-decisions) -* [What to use](#what-to-use) -* [Code Review](#code-review) ## Installation @@ -158,13 +156,10 @@ Every macro is suffixed by `CMC` and each section is separated by an underscore * __documentation__ - The markdowns used by [mdBook](https://github.com/rust-lang/mdBook) to generate the website * __examples__ - Examples using the C Macro Collections Library * __src__ - All headers part of the C Macro Collections Library - * __macro\_collections.h__ - Master header containing all collections and utilities * __tests__ - Where all tests are hosted ## Available Collections -Check out the STATUS file at the root of the project for more information. - __The following table is an overview of all the currently available or upcoming data structures__: | Collection | Abstract Data Type | Data Structure | Details | @@ -194,21 +189,21 @@ __The following table is an overview of all the currently available or upcoming These are some features within the library that are implemented by all collections. -### Two-way iterators +## Two-way iterators All collections come with a two-way iterator. You can go back and forwards in constant time and access elements in constant time. -### Custom Allocation +## Custom Allocation All collections have a `cmc_alloc_node` which provides pointers to the four dynamic memory allocation functions in C: `malloc`, `calloc`, `realloc` and `free`. These pointers can be customized for each individual collection created or a default can be used, as specified in `cmc_alloc_node_default`. -### Callbacks +## Callbacks Every function that operates on a collection can be separated in 5 different types. Create, Read, Update, Delete and (an extra one besides CRUD) Resize. You can define one callback function for each operation. Check out the documentation to see when each callback function is called. -### Functions Table +## Functions Table -Functions table is a `struct` of function pointers containing 'methods' for a custom data type. Some methods are optional and others are needed in order to a collection to operate. They are: +Functions table is a `struct` of function pointers containing 'methods' for a custom data type. Some methods are optional and others are needed in order for a collection to operate. They are: #### CMP @@ -293,31 +288,3 @@ You can use them as Stacks, Queues and Deques, but with modern memory hierarchy ### You can't structurally modify a collection when iterating over it Modifying a collection will possibly invalidate all iterators currently initialized by it. Currently, the only collection that allows this is the LinkedList (using the node-based functions, not the iterator). - -## What to use - -(Outdated) - -The following table shows how each collection is implemented and how well they do when using as common [abstract data types](https://en.wikipedia.org/wiki/Abstract_data_type). - -* **Ideal** - The collection implements correctly the abstract data type; -* **Not Ideal** - The implementation is fulfilled but some functionalities are either not part of the ADT or not present; -* **Bad** - It can be done, but its a bad idea. - -![DataStructuresDiagram](https://i.imgur.com/hFqBSlC.png) - -![GoodColor](https://img.shields.io/badge/Ideal_Implementation-%236abf69.svg) -![AverageColor](https://img.shields.io/badge/Not_Ideal_Implementation-%2363a4ff.svg) -![BadColor](https://img.shields.io/badge/Bad_Implementation-%23ff6659.svg) - -## Code Review - -Check out some code reviews that covers some parts the project. Most of them were posted a long time ago and are probably outdated. - -| About | Link | -| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- | -| Unit Test *./utl/test.h* | [![Code Review](http://www.zomis.net/codereview/shield/?qid=222954)](http://codereview.stackexchange.com/q/222954/178948) | -| Interval Heap *./cmc/intervalheap.h* | [![Code Review](http://www.zomis.net/codereview/shield/?qid=223595)](http://codereview.stackexchange.com/q/223595/178948) | -| Hash Set *./cmc/hashset.h* | [![Code Review](http://www.zomis.net/codereview/shield/?qid=217333)](http://codereview.stackexchange.com/q/217333/178948) | -| Linked List *./cmc/linkedlist.h* | [![Code Review](http://www.zomis.net/codereview/shield/?qid=216737)](http://codereview.stackexchange.com/q/216737/178948) | -| Others | [![Code Review](http://www.zomis.net/codereview/shield/?qid=213553)](http://codereview.stackexchange.com/q/213553/178948) | diff --git a/src/cmc/cmc/list/ext/struct.h b/src/cmc/cmc/list/ext/struct.h index 88eba84..bbebe63 100644 --- a/src/cmc/cmc/list/ext/struct.h +++ b/src/cmc/cmc/list/ext/struct.h @@ -27,7 +27,7 @@ * * List bi-directional iterator. */ -#ifdef CMC_EXT_DEQUE_ITER +#ifdef CMC_EXT_LIST_ITER /* List Iterator */ struct CMC_DEF_ITER(SNAME) @@ -45,4 +45,4 @@ struct CMC_DEF_ITER(SNAME) bool end; }; -#endif /* CMC_EXT_DEQUE_ITER */ +#endif /* CMC_EXT_LIST_ITER */ diff --git a/src/cmc/cmc_deque.h b/src/cmc/deque.h similarity index 100% rename from src/cmc/cmc_deque.h rename to src/cmc/deque.h diff --git a/src/cmc/cmc_list.h b/src/cmc/list.h similarity index 100% rename from src/cmc/cmc_list.h rename to src/cmc/list.h diff --git a/src/cmc/cmc_stack.h b/src/cmc/stack.h similarity index 100% rename from src/cmc/cmc_stack.h rename to src/cmc/stack.h diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000..11957a5 --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,11 @@ +CC=gcc +CFLAGS=-Wall -fprofile-arcs -ftest-coverage -g -O0 +INCLUDE=-I ../src + +main: + $(CC) ./main.c $(INCLUDE) $(CFLAGS) -o $@.exe + valgrind --leak-check=yes ./$@.exe + gcov -p main.gcda + +clean: + rm ./*.gcov ./*.gcda ./*.gcno ./*.exe -f diff --git a/tests/main.c b/tests/main.c new file mode 100644 index 0000000..8d954bf --- /dev/null +++ b/tests/main.c @@ -0,0 +1,102 @@ +#include +#include + +// #include "unt_bitset.h" +#include "unt_deque.h" +// #include "unt_hashbidimap.h" +// #include "unt_hashmap.h" +// #include "unt_hashmultimap.h" +// #include "unt_hashmultiset.h" +// #include "unt_hashset.h" +// #include "unt_heap.h" +// #include "unt_intervalheap.h" +// #include "unt_linkedlist.h" +#include "unt_list.h" +// #include "unt_queue.h" +// #include "unt_sortedlist.h" +#include "unt_stack.h" +// #include "unt_treemap.h" +// #include "unt_treeset.h" + +// #include "unt_foreach.h" + +#include "cmc/utl/assert.h" +#include "cmc/utl/timer.h" + +#include "utl.h" + +#define cmc_run(unit, unit_fails, test_fails) \ + do \ + { \ + uintmax_t f = unit(); \ + if (f != 0) \ + unit_fails += 1; \ + test_fails += f; \ + } while (0) + +int main(void) +{ + // clang-format off + printf(" +---------------------------------------------------------------+\n"); + printf(" | C Macro Collections Library |\n"); + printf(" | |\n"); + printf(" | Test Suite |\n"); + printf(" | |\n"); + printf(" | https://github.com/LeoVen/C-Macro-Collections |\n"); + printf(" | Leonardo Vencovsky (leonardo.vencovsky@gmail.com) |\n"); + printf(" +---------------------------------------------------------------+\n\n"); + // clang-format on + + struct cmc_timer timer; + + cmc_timer_start(timer); + uintmax_t tests = 0, units = 0; + + // cmc_run(CMCBitSet, units, tests); + // cmc_run(CMCBitSetIter, units, tests); + cmc_run(CMCDeque, units, tests); + cmc_run(CMCDequeIter, units, tests); + // cmc_run(CMCHashBidiMap, units, tests); + // cmc_run(CMCHashBidiMapIter, units, tests); + // cmc_run(CMCHashMap, units, tests); + // cmc_run(CMCHashMapIter, units, tests); + // cmc_run(CMCHashMultiMap, units, tests); + // cmc_run(CMCHashMultiMapIter, units, tests); + // cmc_run(CMCHashMultiSet, units, tests); + // cmc_run(CMCHashMultiSetIter, units, tests); + // cmc_run(CMCHashSet, units, tests); + // cmc_run(CMCHashSetIter, units, tests); + // cmc_run(CMCHeap, units, tests); + // cmc_run(CMCHeapIter, units, tests); + // cmc_run(CMCIntervalHeap, units, tests); + // cmc_run(CMCIntervalHeapIter, units, tests); + // cmc_run(CMCLinkedList, units, tests); + // cmc_run(CMCLinkedListIter, units, tests); + cmc_run(CMCList, units, tests); + cmc_run(CMCListIter, units, tests); + // cmc_run(CMCQueue, units, tests); + // cmc_run(CMCQueueIter, units, tests); + // cmc_run(CMCSortedList, units, tests); + // cmc_run(CMCSortedListIter, units, tests); + cmc_run(CMCStack, units, tests); + cmc_run(CMCStackIter, units, tests); + // cmc_run(CMCTreeMap, units, tests); + // cmc_run(CMCTreeMapIter, units, tests); + // cmc_run(CMCTreeSet, units, tests); + // cmc_run(CMCTreeSetIter, units, tests); + + // cmc_run(ForEach, units, tests); + + cmc_timer_stop(timer); + + printf(" +---------------------------------------------------------------+\n"); + printf(" | SUMMARY |\n"); + printf(" +---------------------------------------------------------------+\n"); + printf(" | Total Units Failed : %25" PRIuMAX " units |\n", units); + printf(" | Total Tests Failed : %25" PRIuMAX " tests |\n", tests); + printf(" | Total Asserts Failed : %25" PRIuMAX " asserts |\n", cmc_assert_failed); + printf(" | Total Runtime : %25.0lf milliseconds |\n", timer.result); + printf(" +---------------------------------------------------------------+\n"); + + return tests; +} diff --git a/tests/unt_deque.h b/tests/unt_deque.h new file mode 100644 index 0000000..244b4a1 --- /dev/null +++ b/tests/unt_deque.h @@ -0,0 +1,1725 @@ +#ifndef CMC_TESTS_UNT_DEQUE_H +#define CMC_TESTS_UNT_DEQUE_H + +#include "utl.h" + +#define V size_t +#define PFX d +#define SNAME deque +#define CMC_EXT_DEQUE_INIT +#define CMC_EXT_DEQUE_ITER +#include "cmc/deque.h" + +struct deque_fval *d_fval = &(struct deque_fval){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp +}; + +struct deque_fval *d_fval_counter = &(struct deque_fval){ + .cmp = v_c_cmp, .cpy = v_c_cpy, .str = v_c_str, .free = v_c_free, .hash = v_c_hash, .pri = v_c_pri +}; + +struct cmc_alloc_node *d_alloc_node = + &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; + +CMC_CREATE_UNIT(CMCDeque, true, { + CMC_CREATE_TEST(PFX##_new(), { + struct deque *d = d_new(1000000, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + cmc_assert_not_equals(ptr, NULL, d->buffer); + cmc_assert_equals(size_t, 1000000, d->capacity); + cmc_assert_equals(size_t, 0, d->count); + cmc_assert_equals(size_t, 0, d->front); + cmc_assert_equals(size_t, 0, d->back); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d->flag); + cmc_assert_equals(ptr, d_fval, d->f_val); + cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, d->alloc->malloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, d->alloc->calloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, d->alloc->realloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.free, d->alloc->free); + cmc_assert_equals(ptr, NULL, d->callbacks); + + d_free(d); + + d = d_new(0, d_fval); + cmc_assert_equals(ptr, NULL, d); + + d = d_new(1000, NULL); + cmc_assert_equals(ptr, NULL, d); + + d = d_new(UINT64_MAX, d_fval); + cmc_assert_equals(ptr, NULL, d); + }); + + CMC_CREATE_TEST(PFX##_new_custom(), { + struct deque *d = d_new_custom(1000000, d_fval, d_alloc_node, callbacks); + + cmc_assert_not_equals(ptr, NULL, d); + cmc_assert_not_equals(ptr, NULL, d->buffer); + cmc_assert_equals(size_t, 1000000, d->capacity); + cmc_assert_equals(size_t, 0, d->count); + cmc_assert_equals(size_t, 0, d->front); + cmc_assert_equals(size_t, 0, d->back); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d->flag); + cmc_assert_equals(ptr, d_fval, d->f_val); + cmc_assert_equals(ptr, d_alloc_node, d->alloc); + cmc_assert_equals(ptr, callbacks, d->callbacks); + + d_free(d); + + d = d_new_custom(0, d_fval, d_alloc_node, callbacks); + cmc_assert_equals(ptr, NULL, d); + + d = d_new_custom(1000, NULL, d_alloc_node, callbacks); + cmc_assert_equals(ptr, NULL, d); + + d = d_new_custom(UINT64_MAX, d_fval, d_alloc_node, callbacks); + cmc_assert_equals(ptr, NULL, d); + }); + + CMC_CREATE_TEST(PFX##_init(), { + struct deque d = d_init(1000000, d_fval); + + cmc_assert_not_equals(ptr, NULL, d.buffer); + cmc_assert_equals(size_t, 1000000, d.capacity); + cmc_assert_equals(size_t, 0, d.count); + cmc_assert_equals(size_t, 0, d.front); + cmc_assert_equals(size_t, 0, d.back); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d.flag); + cmc_assert_equals(ptr, d_fval, d.f_val); + cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, d.alloc->malloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, d.alloc->calloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, d.alloc->realloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.free, d.alloc->free); + cmc_assert_equals(ptr, NULL, d.callbacks); + + d_release(d); + + d = d_init(0, d_fval); + + cmc_assert_equals(size_t, 0, d.capacity); + cmc_assert_equals(ptr, NULL, d.buffer); + + d = d_init(1000, NULL); + + cmc_assert_equals(size_t, 0, d.capacity); + cmc_assert_equals(ptr, NULL, d.buffer); + + d = d_init(UINT64_MAX, d_fval); + + cmc_assert_equals(size_t, 0, d.capacity); + cmc_assert_equals(ptr, NULL, d.buffer); + + if (d.buffer) + d_release(d); + }); + + CMC_CREATE_TEST(PFX##_init_custom(), { + struct deque d = d_init_custom(1000000, d_fval, d_alloc_node, callbacks); + + cmc_assert_not_equals(ptr, NULL, d.buffer); + cmc_assert_equals(size_t, 1000000, d.capacity); + cmc_assert_equals(size_t, 0, d.count); + cmc_assert_equals(size_t, 0, d.front); + cmc_assert_equals(size_t, 0, d.back); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d.flag); + cmc_assert_equals(ptr, d_fval, d.f_val); + cmc_assert_equals(ptr, d_alloc_node, d.alloc); + cmc_assert_equals(ptr, callbacks, d.callbacks); + + d_release(d); + + d = d_init_custom(0, d_fval, d_alloc_node, callbacks); + + cmc_assert_equals(size_t, 0, d.capacity); + cmc_assert_equals(ptr, NULL, d.buffer); + + d = d_init_custom(1000, NULL, d_alloc_node, callbacks); + + cmc_assert_equals(size_t, 0, d.capacity); + cmc_assert_equals(ptr, NULL, d.buffer); + + d = d_init_custom(UINT64_MAX, d_fval, d_alloc_node, callbacks); + + cmc_assert_equals(size_t, 0, d.capacity); + cmc_assert_equals(ptr, NULL, d.buffer); + + if (d.buffer) + d_release(d); + }); + + CMC_CREATE_TEST(PFX##_clear(), { + v_total_free = 0; + struct deque *d = d_new(100, d_fval_counter); + + cmc_assert_not_equals(ptr, NULL, d); + + for (size_t i = 0; i < 50; i++) + d_push_back(d, i); + + cmc_assert_equals(size_t, 50, d_count(d)); + + d->flag = CMC_FLAG_ERROR; + d_clear(d); + + cmc_assert_equals(size_t, 50, v_total_free); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + + cmc_assert_equals(size_t, 0, d_count(d)); + cmc_assert_equals(size_t, 100, d_capacity(d)); + + for (size_t i = 1; i <= 1000; i++) + { + if (i % 2 == 0) + d_push_front(d, i); + else + d_push_back(d, i); + } + + cmc_assert_equals(size_t, 1000, d_count(d)); + + size_t sum = 0; + for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) + sum += d->buffer[i]; + + cmc_assert_equals(size_t, 500500, sum); + + d->flag = CMC_FLAG_ERROR; + d_clear(d); + + cmc_assert_equals(size_t, 1050, v_total_free); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + + sum = 0; + for (size_t i = 0; i < d->capacity; i++) + sum += d->buffer[i]; + + cmc_assert_equals(size_t, 0, sum); + + d_free(d); + + cmc_assert_equals(size_t, 1050, v_total_free); + + v_total_free = 0; + }); + + CMC_CREATE_TEST(PFX##_free(), { + v_total_free = 0; + + struct deque *d = d_new(100, d_fval_counter); + + cmc_assert_not_equals(ptr, NULL, d); + + for (size_t i = 1; i <= 1000; i++) + { + if (i % 2 == 0) + d_push_front(d, i); + else + d_push_back(d, i); + } + + cmc_assert_equals(size_t, 1000, d_count(d)); + + size_t sum = 0; + for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) + sum += d->buffer[i]; + + cmc_assert_equals(size_t, 500500, sum); + + d_free(d); + + cmc_assert_equals(size_t, 1000, v_total_free); + + v_total_free = 0; + }); + + CMC_CREATE_TEST(PFX##_release(), { + v_total_free = 0; + + struct deque d = d_init(100, d_fval_counter); + + cmc_assert_not_equals(ptr, NULL, d.buffer); + + for (size_t i = 1; i <= 1000; i++) + { + if (i % 2 == 0) + d_push_front(&d, i); + else + d_push_back(&d, i); + } + + cmc_assert_equals(size_t, 1000, d_count(&d)); + + size_t sum = 0; + for (size_t i = d.front, j = 0; j < d.count; i = (i + 1) % d.capacity, j++) + sum += d.buffer[i]; + + cmc_assert_equals(size_t, 500500, sum); + + d_release(d); + + cmc_assert_equals(size_t, 1000, v_total_free); + + v_total_free = 0; + }); + + CMC_CREATE_TEST(PFX##_customize(), { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + d->flag = CMC_FLAG_ERROR; + d_customize(d, d_alloc_node, callbacks); + + cmc_assert_equals(ptr, d_alloc_node, d->alloc); + cmc_assert_equals(ptr, callbacks, d->callbacks); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + + d->flag = CMC_FLAG_ERROR; + d_customize(d, NULL, NULL); + + cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, d->alloc->malloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, d->alloc->calloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, d->alloc->realloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.free, d->alloc->free); + cmc_assert_equals(ptr, NULL, d->callbacks); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + + d_free(d); + }); + + CMC_CREATE_TEST(PFX##_push_front(), { + total_create = 0; + struct deque *d = d_new_custom(100, d_fval, NULL, callbacks); + + cmc_assert_not_equals(ptr, NULL, d); + + d->flag = CMC_FLAG_ERROR; + cmc_assert(d_push_front(d, 10)); + + cmc_assert_equals(size_t, 1, d_count(d)); + cmc_assert_equals(int32_t, 1, total_create); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + + d_customize(d, NULL, NULL); + + d_clear(d); + + for (size_t i = 0; i < 150; i++) + d_push_front(d, i); + + cmc_assert_equals(size_t, 150, d_count(d)); + cmc_assert_greater(size_t, 100, d_capacity(d)); + + d_free(d); + + d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + for (size_t i = 1; i <= 10000; i++) + d_push_front(d, i); + + size_t sum = 0; + + for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) + { + sum += d->buffer[i]; + } + + cmc_assert_equals(size_t, 50005000, sum); + + d_free(d); + + cmc_assert_equals(int32_t, 1, total_create); + total_create = 0; + }); + + CMC_CREATE_TEST(PFX##_push_back(), { + total_create = 0; + struct deque *d = d_new_custom(100, d_fval, NULL, callbacks); + + cmc_assert_not_equals(ptr, NULL, d); + + d->flag = CMC_FLAG_ERROR; + cmc_assert(d_push_front(d, 10)); + + cmc_assert_equals(size_t, 1, d_count(d)); + cmc_assert_equals(int32_t, 1, total_create); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + + d_customize(d, NULL, NULL); + + d_clear(d); + + for (size_t i = 0; i < 150; i++) + d_push_back(d, i); + + cmc_assert_equals(size_t, 150, d_count(d)); + cmc_assert_greater(size_t, 100, d_capacity(d)); + + d_free(d); + + d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + for (size_t i = 1; i <= 10000; i++) + d_push_back(d, i); + + size_t sum = 0; + + for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) + { + sum += d->buffer[i]; + } + + cmc_assert_equals(size_t, 50005000, sum); + + d_free(d); + + cmc_assert_equals(int32_t, 1, total_create); + total_create = 0; + }); + + CMC_CREATE_TEST(PFX##_pop_front(), { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + cmc_assert(!d_pop_front(d)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); + + cmc_assert(d_push_front(d, 10)); + d->flag = CMC_FLAG_ERROR; + cmc_assert(d_pop_front(d)); + + cmc_assert_equals(size_t, 0, d_count(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + + cmc_assert(d_push_back(d, 10)); + cmc_assert(d_pop_front(d)); + + cmc_assert_equals(size_t, 0, d_count(d)); + + d_free(d); + + d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + for (size_t i = 1; i <= 20000; i++) + d_push_front(d, i); + + cmc_assert_equals(size_t, 20000, d_count(d)); + + for (size_t i = 0; i < 10000; i++) + d_pop_front(d); + + size_t sum = 0; + + for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) + { + sum += d->buffer[i]; + } + + cmc_assert_equals(size_t, 50005000, sum); + + d_clear(d); + + for (size_t i = 1; i <= 20000; i++) + d_push_front(d, i); + + cmc_assert_equals(size_t, 20000, d_count(d)); + + for (size_t i = 0; i < 10000; i++) + d_pop_front(d); + + sum = 0; + + for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) + { + sum += d->buffer[i]; + } + + cmc_assert_equals(size_t, 50005000, sum); + + d_free(d); + }); + + CMC_CREATE_TEST(PFX##_pop_back(), { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + cmc_assert(!d_pop_back(d)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); + + cmc_assert(d_push_front(d, 10)); + d->flag = CMC_FLAG_ERROR; + cmc_assert(d_pop_back(d)); + + cmc_assert_equals(size_t, 0, d_count(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + + cmc_assert(d_push_back(d, 10)); + cmc_assert(d_pop_back(d)); + + cmc_assert_equals(size_t, 0, d_count(d)); + + d_free(d); + + d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + for (size_t i = 1; i <= 20000; i++) + d_push_back(d, i); + + for (size_t i = 0; i < 10000; i++) + d_pop_back(d); + + size_t sum = 0; + + for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) + { + sum += d->buffer[i]; + } + + cmc_assert_equals(size_t, 50005000, sum); + + d_clear(d); + + for (size_t i = 1; i <= 20000; i++) + d_push_back(d, i); + + cmc_assert_equals(size_t, 20000, d_count(d)); + + for (size_t i = 0; i < 10000; i++) + d_pop_back(d); + + sum = 0; + + for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) + { + sum += d->buffer[i]; + } + + cmc_assert_equals(size_t, 50005000, sum); + + d_free(d); + }); + + CMC_CREATE_TEST(PFX##_front(), { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + d_front(d); + + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); + + cmc_assert(d_push_front(d, 99)); + d->flag = CMC_FLAG_ERROR; + cmc_assert_equals(size_t, 99, d_front(d)); + + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + + cmc_assert(d_push_back(d, 98)); + cmc_assert_equals(size_t, 99, d_front(d)); + cmc_assert(d_pop_front(d)); + cmc_assert_equals(size_t, 98, d_front(d)); + + d_clear(d); + + cmc_assert(d_push_back(d, 99)); + cmc_assert_equals(size_t, 99, d_front(d)); + + d_clear(d); + + cmc_assert_equals(size_t, 0, d_count(d)); + + for (size_t i = 1; i <= 10000; i++) + { + if (i % 2 == 0) + d_push_front(d, i); + else + d_push_back(d, i); + } + + size_t sum = 0; + for (size_t i = 0; i < 5000; i++) + { + sum += d_front(d); + cmc_assert_equals(int32_t, 0, d_front(d) % 2); + d_pop_front(d); + } + + cmc_assert_equals(size_t, 5000, d_count(d)); + cmc_assert_equals(size_t, 25005000, sum); + + d_clear(d); + + d_free(d); + }); + + CMC_CREATE_TEST(PFX##_back(), { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + d_back(d); + + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); + + cmc_assert(d_push_back(d, 99)); + d->flag = CMC_FLAG_ERROR; + cmc_assert_equals(size_t, 99, d_back(d)); + + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + + cmc_assert(d_push_front(d, 98)); + cmc_assert_equals(size_t, 99, d_back(d)); + cmc_assert(d_pop_back(d)); + cmc_assert_equals(size_t, 98, d_back(d)); + + d_clear(d); + + cmc_assert(d_push_front(d, 99)); + cmc_assert_equals(size_t, 99, d_back(d)); + + d_clear(d); + + cmc_assert_equals(size_t, 0, d_count(d)); + + for (size_t i = 1; i <= 10000; i++) + { + if (i % 2 == 0) + d_push_back(d, i); + else + d_push_front(d, i); + } + + size_t sum = 0; + for (size_t i = 0; i < 5000; i++) + { + sum += d_back(d); + cmc_assert_equals(int32_t, 0, d_back(d) % 2); + d_pop_back(d); + } + + cmc_assert_equals(size_t, 5000, d_count(d)); + cmc_assert_equals(size_t, 25005000, sum); + + d_free(d); + }); + + CMC_CREATE_TEST(PFX##_contains(), { + struct deque *d = d_new(100, d_fval); + + for (size_t i = 0; i < 100; i++) + { + if (i % 2 == 0) + d_push_back(d, i); + else + d_push_front(d, i); + } + + for (size_t i = 0; i < 100; i++) + cmc_assert(d_contains(d, i)); + + d_free(d); + + d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + for (size_t i = 1; i <= 20; i++) + d_push_back(d, i); + + for (size_t i = 1; i <= 20; i++) + cmc_assert(d_contains(d, i)); + + d_clear(d); + + for (size_t i = 1; i <= 20; i++) + d_push_front(d, i); + + for (size_t i = 1; i <= 20; i++) + cmc_assert(d_contains(d, i)); + + d_free(d); + + d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + cmc_assert(!d_contains(d, 10)); + + d_free(d); + + d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + cmc_assert(!d_contains(d, 10)); + + cmc_assert(d_push_back(d, 100)); + + cmc_assert(d_contains(d, 100)); + cmc_assert(!d_contains(d, 101)); + + cmc_assert(d_pop_front(d)); + cmc_assert(d_push_front(d, 100)); + + cmc_assert(d_contains(d, 100)); + cmc_assert(!d_contains(d, 101)); + + d_free(d); + }); + + CMC_CREATE_TEST(PFX##_empty(), { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + cmc_assert(d_empty(d)); + + cmc_assert(d_push_back(d, 1)); + + cmc_assert(!d_empty(d)); + + cmc_assert(d_pop_front(d)); + + cmc_assert(d_empty(d)); + + cmc_assert(d_push_front(d, 1)); + + cmc_assert(!d_empty(d)); + + cmc_assert(d_pop_back(d)); + + cmc_assert(d_empty(d)); + + d_free(d); + }); + + CMC_CREATE_TEST(PFX##_full(), { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + cmc_assert(!d_full(d)); + + for (size_t i = 0; i != d_capacity(d); i++) + d_push_front(d, i); + + cmc_assert(d_full(d)); + + d_free(d); + }); + + CMC_CREATE_TEST(PFX##_count(), { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + cmc_assert_equals(size_t, 0, d_count(d)); + + for (size_t i = 0; i < 100; i++) + d_push_back(d, i); + + cmc_assert_equals(size_t, 100, d_count(d)); + + d_free(d); + }); + + CMC_CREATE_TEST(PFX##_capacity(), { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + cmc_assert_equals(size_t, 100, d_capacity(d)); + + d_free(d); + }); + + CMC_CREATE_TEST(PFX##_resize(), { + total_resize = 0; + struct deque *d = d_new_custom(100, d_fval, NULL, callbacks); + + cmc_assert_not_equals(ptr, NULL, d); + + cmc_assert_equals(size_t, 100, d_capacity(d)); + d->flag = CMC_FLAG_ERROR; + cmc_assert(d_resize(d, 100)); + cmc_assert_equals(size_t, 100, d_capacity(d)); + + cmc_assert_equals(int32_t, 1, total_resize); + + cmc_assert(d_resize(d, 200)); + cmc_assert_equals(size_t, 200, d_capacity(d)); + + cmc_assert(d_resize(d, 100)); + cmc_assert_equals(size_t, 100, d_capacity(d)); + + cmc_assert_equals(int32_t, 3, total_resize); + + for (size_t i = 0; i < 150; i++) + { + if (i % 2 == 0) + cmc_assert(d_push_back(d, i)); + else + cmc_assert(d_push_front(d, i)); + } + + cmc_assert_equals(size_t, 150, d_count(d)); + cmc_assert(d_resize(d, d_count(d))); + cmc_assert_equals(size_t, 150, d_capacity(d)); + + cmc_assert(!d_resize(d, d_count(d) - 10)); + cmc_assert_equals(int32_t, CMC_FLAG_INVALID, d_flag(d)); + + d_free(d); + + // item preservation + d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + for (size_t i = 1; i <= 150; i++) + { + if (i % 2 != 0) + cmc_assert(d_push_back(d, i)); + else + cmc_assert(d_push_front(d, i)); + } + + cmc_assert(d_resize(d, d_count(d))); + + size_t sum = 0; + + for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) + { + sum += d->buffer[i]; + } + + cmc_assert_equals(size_t, 11325, sum); + + d_free(d); + total_resize = 0; + }); + + CMC_CREATE_TEST(PFX##_copy_of(), { + v_total_cpy = 0; + struct deque *d1 = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d1); + + for (size_t i = 1; i <= 150; i++) + { + if (i % 2 != 0) + d_push_back(d1, i); + else + d_push_front(d1, i); + } + + struct deque *d2 = d_copy_of(d1); + + cmc_assert_not_equals(ptr, NULL, d2); + cmc_assert_equals(size_t, d_count(d1), d_count(d2)); + + for (size_t i1 = d1->front, i2 = d2->front, j = 0; j < d1->count; j++) + { + cmc_assert_equals(size_t, d1->buffer[i1], d2->buffer[i2]); + + i1 = (i1 + 1) % d1->capacity; + i2 = (i2 + 1) % d2->capacity; + } + + cmc_assert(d_push_front(d1, 10)); + cmc_assert(d_push_front(d2, 10)); + cmc_assert(d_push_back(d1, 11)); + cmc_assert(d_push_back(d2, 11)); + + cmc_assert(d_equals(d1, d2)); + + d_free(d1); + d_free(d2); + + // v_total_cpy + d1 = d_new_custom(100, d_fval_counter, d_alloc_node, NULL); + + cmc_assert_not_equals(ptr, NULL, d1); + + d2 = d_copy_of(d1); + + cmc_assert_not_equals(ptr, NULL, d1); + + cmc_assert_equals(int32_t, 0, v_total_cpy); + + d_free(d2); + + for (size_t i = 0; i < 1000; i++) + { + if (i % 2 != 0) + d_push_back(d1, i); + else + d_push_front(d1, i); + } + + cmc_assert_equals(size_t, 1000, d1->count); + + d2 = d_copy_of(d1); + + cmc_assert_equals(int32_t, 1000, v_total_cpy); + + d_free(d1); + d_free(d2); + v_total_cpy = 0; + }); + + CMC_CREATE_TEST(PFX##_equals(), { + v_total_cmp = 0; + struct deque *d1 = d_new(100, d_fval); + struct deque *d2 = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d1); + cmc_assert_not_equals(ptr, NULL, d2); + + for (size_t i = 1; i <= 150; i++) + { + if (i % 2 != 0) + { + d_push_back(d1, i); + d_push_back(d2, i); + } + else + { + d_push_front(d1, i); + d_push_front(d2, i); + } + } + + cmc_assert(d_equals(d1, d2)); + + d_free(d1); + d_free(d2); + + // from copy + d1 = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d1); + + for (size_t i = 1; i <= 150; i++) + { + if (i % 2 != 0) + cmc_assert(d_push_back(d1, i)); + else + cmc_assert(d_push_front(d1, i)); + } + + d2 = d_copy_of(d1); + + cmc_assert_not_equals(ptr, NULL, d2); + + cmc_assert(d_equals(d1, d2)); + + d_free(d1); + d_free(d2); + + // count = 0 + d1 = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d1); + + d2 = d_copy_of(d1); + + cmc_assert_not_equals(ptr, NULL, d2); + + cmc_assert(d_equals(d1, d2)); + + d_free(d1); + d_free(d2); + + // false eq + d1 = d_new(100, d_fval); + d2 = d_new_custom(100, d_fval_counter, d_alloc_node, NULL); + + cmc_assert(d_equals(d1, d2)); + + cmc_assert_equals(int32_t, 0, v_total_cmp); + + d_push_back(d1, 100); + + cmc_assert(!d_equals(d1, d2)); + + d_push_back(d2, 100); + + cmc_assert(d_equals(d1, d2)); + + d_push_front(d1, 10); + d_push_front(d2, 10); + + cmc_assert(d_equals(d1, d2)); + + d_push_back(d1, 40); + d_push_back(d2, 41); + + cmc_assert(!d_equals(d1, d2)); + + v_total_cmp = 0; + + d_clear(d1); + d_clear(d2); + + for (size_t i = 0; i < 1000; i++) + { + if (i % 2 == 0) + { + d_push_back(d1, i); + d_push_back(d2, i); + } + else + { + d_push_front(d1, i); + d_push_front(d2, i); + } + } + + // d2's cmp is used and v_total_cmp is incremented each time + cmc_assert(d_equals(d2, d1)); + + cmc_assert_equals(int32_t, 1000, v_total_cmp); + + d_free(d1); + d_free(d2); + v_total_cmp = 0; + }); + + CMC_CREATE_TEST(Mixed IO, { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + cmc_assert(d_push_front(d, 10)); + cmc_assert(d_push_front(d, 10)); + cmc_assert(d_pop_back(d)); + cmc_assert(d_pop_back(d)); + + cmc_assert_equals(size_t, 0, d_count(d)); + + cmc_assert(d_push_back(d, 10)); + cmc_assert(d_push_back(d, 10)); + cmc_assert(d_pop_back(d)); + cmc_assert(d_pop_back(d)); + + cmc_assert_equals(size_t, 0, d_count(d)); + + cmc_assert(d_push_front(d, 10)); + cmc_assert(d_push_front(d, 10)); + cmc_assert(d_pop_front(d)); + cmc_assert(d_pop_front(d)); + + cmc_assert_equals(size_t, 0, d_count(d)); + + cmc_assert(d_push_back(d, 10)); + cmc_assert(d_push_back(d, 10)); + cmc_assert(d_pop_front(d)); + cmc_assert(d_pop_front(d)); + + cmc_assert_equals(size_t, 0, d_count(d)); + // ---------- + cmc_assert(d_push_back(d, 10)); + cmc_assert(d_push_front(d, 10)); + cmc_assert(d_pop_back(d)); + cmc_assert(d_pop_front(d)); + + cmc_assert_equals(size_t, 0, d_count(d)); + + cmc_assert(d_push_back(d, 10)); + cmc_assert(d_push_front(d, 10)); + cmc_assert(d_pop_front(d)); + cmc_assert(d_pop_back(d)); + + cmc_assert_equals(size_t, 0, d_count(d)); + + cmc_assert(d_push_front(d, 10)); + cmc_assert(d_push_back(d, 10)); + cmc_assert(d_pop_back(d)); + cmc_assert(d_pop_front(d)); + + cmc_assert_equals(size_t, 0, d_count(d)); + + cmc_assert(d_push_front(d, 10)); + cmc_assert(d_push_back(d, 10)); + cmc_assert(d_pop_front(d)); + cmc_assert(d_pop_back(d)); + + cmc_assert_equals(size_t, 0, d_count(d)); + + d_free(d); + }); + + CMC_CREATE_TEST(buffer_growth[capacity = 1], { + struct deque *d = d_new(1, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + for (size_t i = 0; i < 50; i++) + d_push_back(d, i); + + cmc_assert_equals(size_t, 50, d_count(d)); + cmc_assert_lesser_equals(size_t, d_capacity(d), d_count(d)); + + d_free(d); + }); + + CMC_CREATE_TEST(buffer_growth[item preservation], { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + for (size_t i = 1; i <= 1200; i++) + { + if (i % 2 == 0) + d_push_front(d, i); + else + d_push_back(d, i); + } + + size_t sum = 0; + for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) + sum += d->buffer[i]; + + cmc_assert_equals(size_t, 1200, d_count(d)); + cmc_assert_equals(size_t, 720600, sum); + + d_free(d); + }); + + CMC_CREATE_TEST(flags, { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + + // customize + d->flag = CMC_FLAG_ERROR; + d_customize(d, &cmc_alloc_node_default, &(struct cmc_callbacks){ 0 }); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + + // push_front + d->flag = CMC_FLAG_ERROR; + cmc_assert(d_push_front(d, 1)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + + // pop_front + d->flag = CMC_FLAG_ERROR; + cmc_assert(d_pop_front(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + cmc_assert(!d_pop_front(d)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); + + // push_back + cmc_assert(d_push_back(d, 1)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + + // pop_back + d->flag = CMC_FLAG_ERROR; + cmc_assert(d_pop_back(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + cmc_assert(!d_pop_back(d)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); + + // front + d->flag = CMC_FLAG_ERROR; + cmc_assert(d_front(d) == 0); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); + + cmc_assert(d_push_back(d, 1)); + d->flag = CMC_FLAG_ERROR; + cmc_assert(d_front(d) == 1); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + + // clear + d->flag = CMC_FLAG_ERROR; + d_clear(d); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + + // back + cmc_assert(d_back(d) == 0); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); + + cmc_assert(d_push_front(d, 1)); + cmc_assert(d_back(d) == 1); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + + // contains + d->flag = CMC_FLAG_ERROR; + cmc_assert(d_contains(d, 1)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + + // copy_of + d->flag = CMC_FLAG_ERROR; + struct deque *d2 = d_copy_of(d); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d2)); + + // equals + cmc_assert(d_pop_back(d)); + cmc_assert(d_pop_back(d2)); + d->flag = CMC_FLAG_ERROR; + d2->flag = CMC_FLAG_ERROR; + d_front(d); + d_front(d2); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d2)); + cmc_assert(d_equals(d, d2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d2)); + + d_free(d); + d_free(d2); + }); + + CMC_CREATE_TEST(callbacks, { + struct deque *d = d_new_custom(100, d_fval, NULL, callbacks); + + total_create = 0; + total_read = 0; + total_update = 0; + total_delete = 0; + total_resize = 0; + + cmc_assert(d_push_front(d, 10)); + cmc_assert_equals(int32_t, 1, total_create); + + cmc_assert(d_push_back(d, 10)); + cmc_assert_equals(int32_t, 2, total_create); + + cmc_assert(d_pop_front(d)); + cmc_assert_equals(int32_t, 1, total_delete); + + cmc_assert(d_pop_back(d)); + cmc_assert_equals(int32_t, 2, total_delete); + + cmc_assert(d_push_front(d, 10)); + cmc_assert(d_push_front(d, 5)); + cmc_assert_equals(int32_t, 4, total_create); + + cmc_assert_equals(size_t, 5, d_front(d)); + cmc_assert_equals(int32_t, 1, total_read); + + cmc_assert_equals(size_t, 10, d_back(d)); + cmc_assert_equals(int32_t, 2, total_read); + + cmc_assert(d_contains(d, 10)); + cmc_assert(!d_contains(d, 1)); + cmc_assert_equals(int32_t, 4, total_read); + + cmc_assert(d_resize(d, 1000)); + cmc_assert_equals(int32_t, 1, total_resize); + + cmc_assert(d_resize(d, 10)); + cmc_assert_equals(int32_t, 2, total_resize); + + cmc_assert_equals(int32_t, 4, total_create); + cmc_assert_equals(int32_t, 4, total_read); + cmc_assert_equals(int32_t, 0, total_update); + cmc_assert_equals(int32_t, 2, total_delete); + cmc_assert_equals(int32_t, 2, total_resize); + + d_customize(d, NULL, NULL); + + cmc_assert_equals(ptr, NULL, d->callbacks); + + d_clear(d); + cmc_assert(d_push_front(d, 10)); + cmc_assert(d_push_back(d, 10)); + cmc_assert(d_pop_front(d)); + cmc_assert(d_pop_back(d)); + cmc_assert(d_push_front(d, 10)); + cmc_assert(d_push_front(d, 5)); + cmc_assert_equals(size_t, 5, d_front(d)); + cmc_assert_equals(size_t, 10, d_back(d)); + cmc_assert(d_contains(d, 10)); + cmc_assert(!d_contains(d, 1)); + cmc_assert(d_resize(d, 1000)); + cmc_assert(d_resize(d, 10)); + + cmc_assert_equals(int32_t, 4, total_create); + cmc_assert_equals(int32_t, 4, total_read); + cmc_assert_equals(int32_t, 0, total_update); + cmc_assert_equals(int32_t, 2, total_delete); + cmc_assert_equals(int32_t, 2, total_resize); + + cmc_assert_equals(ptr, NULL, d->callbacks); + + d_free(d); + + total_create = 0; + total_read = 0; + total_update = 0; + total_delete = 0; + total_resize = 0; + }); +}); + +CMC_CREATE_UNIT(CMCDequeIter, true, { + CMC_CREATE_TEST(PFX##_iter_start(), { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + struct deque_iter it = d_iter_start(d); + + cmc_assert_equals(ptr, d, it.target); + cmc_assert_equals(size_t, d->front, it.cursor); + cmc_assert_equals(size_t, 0, it.index); + cmc_assert_equals(bool, true, it.start); + cmc_assert_equals(bool, true, it.end); + + cmc_assert(d_iter_at_start(&it)); + cmc_assert(d_iter_at_end(&it)); + + cmc_assert(d_push_front(d, 1)); + cmc_assert(d_push_front(d, 2)); + + it = d_iter_start(d); + + cmc_assert_equals(size_t, 0, it.index); + cmc_assert_equals(bool, false, it.end); + cmc_assert_equals(size_t, d->front, it.cursor); + + d_free(d); + }); + + CMC_CREATE_TEST(PFX##_iter_end(), { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + struct deque_iter it = d_iter_end(d); + + cmc_assert_equals(ptr, d, it.target); + cmc_assert_equals(size_t, d->back, it.cursor); + cmc_assert_equals(size_t, 0, it.index); + cmc_assert_equals(bool, true, it.start); + cmc_assert_equals(bool, true, it.end); + + cmc_assert(d_iter_at_start(&it)); + cmc_assert(d_iter_at_end(&it)); + + cmc_assert(d_push_back(d, 1)); + cmc_assert(d_push_back(d, 2)); + cmc_assert(d_push_back(d, 3)); + + it = d_iter_end(d); + + cmc_assert_equals(size_t, d->count - 1, it.index); + cmc_assert_equals(size_t, d->back - 1, it.cursor); + cmc_assert_equals(bool, false, it.start); + + d_free(d); + }); + + CMC_CREATE_TEST(PFX##_iter_at_start(), { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + struct deque_iter it = d_iter_start(d); + + // Empty checks + cmc_assert(d_iter_at_start(&it)); + it = d_iter_end(d); + cmc_assert(d_iter_at_start(&it)); + + // Non-empty checks + cmc_assert(d_push_back(d, 1)); + it = d_iter_end(d); + cmc_assert(!d_iter_at_start(&it)); + it = d_iter_start(d); + cmc_assert(d_iter_at_start(&it)); + + d_clear(d); + + cmc_assert(d_push_front(d, 1)); + it = d_iter_end(d); + cmc_assert(!d_iter_at_start(&it)); + it = d_iter_start(d); + cmc_assert(d_iter_at_start(&it)); + + d_free(d); + }); + + CMC_CREATE_TEST(PFX##_iter_at_end(), { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + struct deque_iter it = d_iter_start(d); + + // Empty check + cmc_assert(d_iter_at_end(&it)); + it = d_iter_end(d); + cmc_assert(d_iter_at_end(&it)); + + // Non-empty checks + cmc_assert(d_push_back(d, 1)); + it = d_iter_end(d); + cmc_assert(d_iter_at_end(&it)); + it = d_iter_start(d); + cmc_assert(!d_iter_at_end(&it)); + + d_clear(d); + + cmc_assert(d_push_front(d, 1)); + it = d_iter_end(d); + cmc_assert(d_iter_at_end(&it)); + it = d_iter_start(d); + cmc_assert(!d_iter_at_end(&it)); + + d_free(d); + }); + + CMC_CREATE_TEST(PFX##_iter_to_start(), { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + struct deque_iter it = d_iter_start(d); + + cmc_assert(!d_iter_to_start(&it)); + + for (size_t i = 1; i <= 100; i++) + { + if (i % 2 == 0) + d_push_back(d, i); + else + d_push_front(d, i); + } + + cmc_assert_equals(size_t, 100, d->count); + + it = d_iter_end(d); + + cmc_assert(!d_iter_at_start(&it)); + cmc_assert(d_iter_at_end(&it)); + + cmc_assert_equals(size_t, 100, d_iter_value(&it)); + + cmc_assert(d_iter_to_start(&it)); + + cmc_assert(d_iter_at_start(&it)); + cmc_assert(!d_iter_at_end(&it)); + + cmc_assert_equals(size_t, 99, d_iter_value(&it)); + + d_free(d); + }); + + CMC_CREATE_TEST(PFX##_iter_to_end(), { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + struct deque_iter it = d_iter_end(d); + + cmc_assert(!d_iter_to_end(&it)); + + for (size_t i = 1; i <= 100; i++) + { + if (i % 2 == 0) + d_push_back(d, i); + else + d_push_front(d, i); + } + + it = d_iter_start(d); + + cmc_assert(d_iter_at_start(&it)); + cmc_assert(!d_iter_at_end(&it)); + + cmc_assert_equals(size_t, 99, d_iter_value(&it)); + + cmc_assert(d_iter_to_end(&it)); + + cmc_assert(!d_iter_at_start(&it)); + cmc_assert(d_iter_at_end(&it)); + + cmc_assert_equals(size_t, 100, d_iter_value(&it)); + + d_free(d); + }); + + CMC_CREATE_TEST(PFX##_iter_next(), { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + struct deque_iter it = d_iter_start(d); + + cmc_assert(!d_iter_next(&it)); + + for (size_t i = 1; i <= 1000; i++) + { + if (i % 2 == 0) + d_push_back(d, i); + else + d_push_front(d, i); + } + + size_t sum = 0; + for (it = d_iter_start(d); !d_iter_at_end(&it); d_iter_next(&it)) + { + sum += d_iter_value(&it); + } + + cmc_assert_equals(size_t, 500500, sum); + + sum = 0; + + d_iter_to_start(&it); + do + { + sum += d_iter_value(&it); + } while (d_iter_next(&it)); + + cmc_assert_equals(size_t, 500500, sum); + + d_free(d); + }); + + CMC_CREATE_TEST(PFX##_iter_prev(), { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + struct deque_iter it = d_iter_end(d); + + cmc_assert(!d_iter_prev(&it)); + + for (size_t i = 1; i <= 1000; i++) + { + if (i % 2 == 0) + d_push_back(d, i); + else + d_push_front(d, i); + } + + size_t sum = 0; + for (it = d_iter_end(d); !d_iter_at_start(&it); d_iter_prev(&it)) + { + sum += d_iter_value(&it); + } + + cmc_assert_equals(size_t, 500500, sum); + + sum = 0; + + d_iter_to_end(&it); + do + { + sum += d_iter_value(&it); + } while (d_iter_prev(&it)); + + cmc_assert_equals(size_t, 500500, sum); + + d_free(d); + }); + + CMC_CREATE_TEST(PFX##_iter_advance(), { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + struct deque_iter it = d_iter_start(d); + + cmc_assert(!d_iter_advance(&it, 1)); + + for (size_t i = 0; i <= 1000; i++) + { + if (i % 2 == 0) + d_push_back(d, i); // will sum all even numbers + else + d_push_back(d, 0); + } + + it = d_iter_start(d); + + cmc_assert(!d_iter_advance(&it, 0)); + cmc_assert(!d_iter_advance(&it, d->count)); + + size_t sum = 0; + for (it = d_iter_start(d);;) + { + sum += d_iter_value(&it); + + if (!d_iter_advance(&it, 2)) + break; + } + + cmc_assert_equals(size_t, 250500, sum); + + d_iter_to_start(&it); + cmc_assert(d_iter_advance(&it, d->count - 1)); + + d_free(d); + }); + + CMC_CREATE_TEST(PFX##_iter_rewind(), { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + struct deque_iter it = d_iter_end(d); + + cmc_assert(!d_iter_rewind(&it, 1)); + + for (size_t i = 0; i <= 1000; i++) + { + if (i % 2 == 0) + d_push_front(d, i); // will sum all even numbers + else + d_push_front(d, 0); + } + + it = d_iter_end(d); + + cmc_assert(!d_iter_rewind(&it, 0)); + cmc_assert(!d_iter_rewind(&it, d->count)); + + size_t sum = 0; + for (it = d_iter_end(d);;) + { + sum += d_iter_value(&it); + + if (!d_iter_rewind(&it, 2)) + break; + } + + cmc_assert_equals(size_t, 250500, sum); + + d_iter_to_end(&it); + cmc_assert(d_iter_rewind(&it, d->count - 1)); + + d_free(d); + }); + + CMC_CREATE_TEST(PFX##_iter_go_to(), { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + struct deque_iter it = d_iter_end(d); + cmc_assert(!d_iter_go_to(&it, 0)); + + it = d_iter_start(d); + cmc_assert(!d_iter_go_to(&it, 0)); + + for (size_t i = 0; i <= 1000; i++) + d_push_back(d, i); + + it = d_iter_start(d); + + size_t sum = 0; + for (size_t i = 0; i < 1001; i++) + { + d_iter_go_to(&it, i); + + sum += d_iter_value(&it); + } + + cmc_assert_equals(size_t, 500500, sum); + + sum = 0; + for (size_t i = 1001; i > 0; i--) + { + cmc_assert(d_iter_go_to(&it, i - 1)); + + sum += d_iter_value(&it); + } + + cmc_assert_equals(size_t, 500500, sum); + + sum = 0; + for (size_t i = 0; i < 1001; i += 100) + { + cmc_assert(d_iter_go_to(&it, i)); + cmc_assert_equals(size_t, i, d_iter_index(&it)); + + sum += d_iter_value(&it); + } + + cmc_assert_equals(size_t, 5500, sum); + + d_free(d); + }); + + CMC_CREATE_TEST(PFX##_iter_value(), { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + struct deque_iter it = d_iter_end(d); + + cmc_assert_equals(size_t, (size_t){ 0 }, d_iter_value(&it)); + + cmc_assert(d_push_back(d, 10)); + + it = d_iter_start(d); + + cmc_assert_equals(size_t, 10, d_iter_value(&it)); + + d_free(d); + }); + + CMC_CREATE_TEST(PFX##_iter_rvalue(), { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + struct deque_iter it = d_iter_end(d); + + cmc_assert_equals(ptr, NULL, d_iter_rvalue(&it)); + + cmc_assert(d_push_back(d, 10)); + + it = d_iter_start(d); + + cmc_assert_not_equals(ptr, NULL, d_iter_rvalue(&it)); + cmc_assert_equals(size_t, 10, *d_iter_rvalue(&it)); + + d_free(d); + }); + + CMC_CREATE_TEST(PFX##_iter_index(), { + struct deque *d = d_new(100, d_fval); + + cmc_assert_not_equals(ptr, NULL, d); + + for (size_t i = 0; i <= 1000; i++) + d_push_back(d, i); + + struct deque_iter it = d_iter_start(d); + + for (size_t i = 0; i < 1001; i++) + { + cmc_assert_equals(size_t, i, d_iter_index(&it)); + d_iter_next(&it); + } + + it = d_iter_end(d); + for (size_t i = 1001; i > 0; i--) + { + cmc_assert_equals(size_t, i - 1, d_iter_index(&it)); + d_iter_prev(&it); + } + + d_free(d); + }); +}); + +#endif /* CMC_TESTS_UNT_DEQUE_H */ diff --git a/tests/unt_list.h b/tests/unt_list.h new file mode 100644 index 0000000..38993fb --- /dev/null +++ b/tests/unt_list.h @@ -0,0 +1,1072 @@ +#ifndef CMC_TESTS_UNT_LIST_H +#define CMC_TESTS_UNT_LIST_H + +#include "utl.h" + +#define V size_t +#define PFX l +#define SNAME list +#define CMC_EXT_LIST_INIT +#define CMC_EXT_LIST_ITER +#define CMC_EXT_LIST_SEQ +#include "cmc/list.h" + +struct list_fval *l_fval = &(struct list_fval){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp +}; + +CMC_CREATE_UNIT(CMCList, true, { + CMC_CREATE_TEST(new, { + struct list *l = l_new(1000000, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + cmc_assert_not_equals(ptr, NULL, l->buffer); + cmc_assert_equals(size_t, 1000000, l_capacity(l)); + cmc_assert_equals(size_t, 0, l_count(l)); + + l_free(l); + }); + + CMC_CREATE_TEST(new[capacity = 0], { + struct list *l = l_new(0, l_fval); + + cmc_assert_equals(ptr, NULL, l); + }); + + CMC_CREATE_TEST(new[capacity = UINT64_MAX], { + struct list *l = l_new(UINT64_MAX, l_fval); + + cmc_assert_equals(ptr, NULL, l); + }); + + CMC_CREATE_TEST(clear[count capacity], { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + for (size_t i = 0; i < 50; i++) + l_push_back(l, i); + + cmc_assert_equals(size_t, 50, l_count(l)); + + l_clear(l); + + cmc_assert_equals(size_t, 0, l_count(l)); + cmc_assert_equals(size_t, 100, l_capacity(l)); + + l_free(l); + }); + + CMC_CREATE_TEST(buffer_growth[capacity = 1], { + struct list *l = l_new(1, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + for (size_t i = 0; i < 100; i++) + l_push_back(l, i); + + cmc_assert_equals(size_t, 100, l_count(l)); + + for (size_t i = 0; i < 100; i++) + cmc_assert_equals(size_t, i, l_get(l, i)); + + l_free(l); + }); + + CMC_CREATE_TEST(push_front[count], { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + for (size_t i = 0; i < 250; i++) + cmc_assert(l_push_front(l, i)); + + cmc_assert_equals(size_t, 250, l_count(l)); + + l_free(l); + }); + + CMC_CREATE_TEST(push_front[capacity], { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + for (size_t i = 0; i < 250; i++) + cmc_assert(l_push_front(l, i)); + + cmc_assert_lesser_equals(size_t, l_capacity(l), l_count(l)); + + l_free(l); + }); + + CMC_CREATE_TEST(push_front[item preservation], { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + for (size_t i = 0; i < 250; i++) + cmc_assert(l_push_front(l, i)); + + for (size_t i = 0; i < l_count(l); i++) + cmc_assert_equals(size_t, l_get(l, i), l_count(l) - i - 1); + + l_free(l); + }); + + CMC_CREATE_TEST(push_at[count], { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + cmc_assert(l_push_back(l, 0)); + cmc_assert(l_push_back(l, 249)); + + for (size_t i = 1; i < 249; i++) + cmc_assert(l_push_at(l, i, l_count(l) - 1)); + + cmc_assert_equals(size_t, 250, l_count(l)); + + l_free(l); + }); + + CMC_CREATE_TEST(push_at[capacity], { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + cmc_assert(l_push_back(l, 0)); + cmc_assert(l_push_back(l, 249)); + + for (size_t i = 1; i < 249; i++) + cmc_assert(l_push_at(l, i, l_count(l) - 1)); + + cmc_assert_lesser_equals(size_t, l_capacity(l), l_count(l)); + + l_free(l); + }); + + CMC_CREATE_TEST(push_at[item preservation], { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + cmc_assert(l_push_back(l, 0)); + cmc_assert(l_push_back(l, 249)); + + for (size_t i = 1; i < 249; i++) + cmc_assert(l_push_at(l, i, l_count(l) - 1)); + + for (size_t i = 0; i < l_count(l); i++) + cmc_assert_equals(size_t, l_get(l, i), i); + + l_free(l); + }); + + CMC_CREATE_TEST(push_back[count], { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + for (size_t i = 0; i < 250; i++) + cmc_assert(l_push_back(l, i)); + + cmc_assert_equals(size_t, 250, l_count(l)); + + l_free(l); + }); + + CMC_CREATE_TEST(push_back[capacity], { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + for (size_t i = 0; i < 250; i++) + cmc_assert(l_push_back(l, i)); + + cmc_assert_lesser_equals(size_t, l_capacity(l), l_count(l)); + + l_free(l); + }); + + CMC_CREATE_TEST(push_back[item preservation], { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + for (size_t i = 0; i < 250; i++) + cmc_assert(l_push_back(l, i)); + + for (size_t i = 0; i < l_count(l); i++) + cmc_assert_equals(size_t, l_get(l, i), i); + + l_free(l); + }); + + CMC_CREATE_TEST(pop_front[count], { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + for (size_t i = 0; i < 250; i++) + l_push_back(l, i); + + cmc_assert(l_pop_front(l)); + + l_free(l); + }); + + CMC_CREATE_TEST(pop_front[item preservation], { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + for (size_t i = 0; i < 250; i++) + l_push_back(l, i); + + cmc_assert(l_pop_front(l)); + + for (size_t i = 0; i < l_count(l); i++) + cmc_assert_equals(size_t, l_get(l, i), i + 1); + + l_free(l); + }); + + CMC_CREATE_TEST(pop_front[count = 0], { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + cmc_assert(!l_pop_front(l)); + + l_free(l); + }); + + CMC_CREATE_TEST(pop_front[count = 1], { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + cmc_assert(l_push_back(l, 10)); + cmc_assert(l_pop_front(l)); + + l_free(l); + }); + + CMC_CREATE_TEST(pop_front[buffer_clear], { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + cmc_assert(l_push_back(l, 1)); + cmc_assert(l_push_front(l, 2)); + + cmc_assert(l_pop_front(l)); + + cmc_assert_equals(size_t, 0, l->buffer[1]); + + l_free(l); + }); + + CMC_CREATE_TEST(pop_at[count = 0], { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + cmc_assert(!l_pop_at(l, 1)); + + l_free(l); + }); + + CMC_CREATE_TEST(pop_at[count = 1], { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + cmc_assert(l_push_back(l, 1)); + cmc_assert(l_pop_at(l, 0)); + + cmc_assert_equals(size_t, 0, l->buffer[0]); + + l_free(l); + }); + + CMC_CREATE_TEST(pop_at[buffer_clear], { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + cmc_assert(l_push_back(l, 1)); + cmc_assert(l_push_back(l, 2)); + cmc_assert(l_push_back(l, 3)); + cmc_assert(l_pop_at(l, 1)); + + l_free(l); + }); + + CMC_CREATE_TEST(pop_back[count = 0], { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + cmc_assert(!l_pop_back(l)); + + l_free(l); + }); + + CMC_CREATE_TEST(pop_back[count = 1], { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + cmc_assert(l_push_back(l, 10)); + cmc_assert(l_pop_back(l)); + + l_free(l); + }); + + CMC_CREATE_TEST(flags, { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + + // clear + l->flag = CMC_FLAG_ERROR; + l_clear(l); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + + // customize + l->flag = CMC_FLAG_ERROR; + l_customize(l, NULL, NULL); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + + // push_front + l->flag = CMC_FLAG_ERROR; + cmc_assert(l_push_front(l, 10)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + + // push_at + cmc_assert(!l_push_at(l, 5, 2)); + cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l)); + cmc_assert(l_push_at(l, 5, 1)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + + // push_back + l->flag = CMC_FLAG_ERROR; + cmc_assert(l_push_back(l, 0)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + + // pop_front + l->flag = CMC_FLAG_ERROR; + cmc_assert(l_pop_front(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + + l_clear(l); + cmc_assert(!l_pop_front(l)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l)); + + // pop_back + cmc_assert(l_push_front(l, 10)); + l->flag = CMC_FLAG_ERROR; + cmc_assert(l_pop_back(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + + cmc_assert(!l_pop_front(l)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l)); + + // pop_at + l->flag = CMC_FLAG_ERROR; + cmc_assert(!l_pop_at(l, 0)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l)); + + cmc_assert(l_push_back(l, 10)); + cmc_assert(!l_pop_at(l, 1)); + cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l)); + + cmc_assert(l_pop_at(l, 0)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + + // seq_push_front + cmc_assert(!l_seq_push_front(l, NULL, 0)); + cmc_assert_equals(int32_t, CMC_FLAG_INVALID, l_flag(l)); + + cmc_assert(l_seq_push_front(l, (size_t[2]){ 1, 2 }, 2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + + // seq_push_at + cmc_assert(!l_seq_push_at(l, NULL, 0, 0)); + cmc_assert_equals(int32_t, CMC_FLAG_INVALID, l_flag(l)); + + cmc_assert(!l_seq_push_at(l, (size_t[2]){ 1, 2 }, 2, 10)); + cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l)); + + cmc_assert(l_seq_push_at(l, (size_t[2]){ 1, 2 }, 2, l_count(l) - 1)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + + // seq_push_back + cmc_assert(!l_seq_push_back(l, NULL, 0)); + cmc_assert_equals(int32_t, CMC_FLAG_INVALID, l_flag(l)); + + cmc_assert(l_seq_push_back(l, (size_t[2]){ 1, 2 }, 2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + + // seq_pop_at + cmc_assert(!l_seq_pop_at(l, 10, 1)); + cmc_assert_equals(int32_t, CMC_FLAG_INVALID, l_flag(l)); + + cmc_assert(!l_seq_pop_at(l, 100, 200)); + cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l)); + + cmc_assert(l_seq_pop_at(l, 1, l_count(l) - 2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + + // seq_sublist + struct list *l2 = l_seq_sublist(l, 10, 1); + cmc_assert_equals(ptr, NULL, l2); + cmc_assert_equals(int32_t, CMC_FLAG_INVALID, l_flag(l)); + + l2 = l_seq_sublist(l, 100, 200); + cmc_assert_equals(ptr, NULL, l2); + cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l)); + + l2 = l_seq_sublist(l, 0, l_count(l) - 1); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l2)); + + l_clear(l); + + // l_front + l_front(l); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l)); + + cmc_assert(l_push_back(l, 10)); + l->flag = CMC_FLAG_ERROR; + l_front(l); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + + l_clear(l); + + // l_back + l_back(l); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l)); + + cmc_assert(l_push_back(l, 10)); + l->flag = CMC_FLAG_ERROR; + l_back(l); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + + l_clear(l); + + // get, get_ref + l_get(l, 0); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l)); + l->flag = CMC_FLAG_ERROR; + l_get_ref(l, 0); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l)); + + cmc_assert(l_push_back(l, 10)); + + l_get(l, 1); + cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l)); + l->flag = CMC_FLAG_ERROR; + l_get_ref(l, 1); + cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l)); + + l_get(l, 0); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + l->flag = CMC_FLAG_ERROR; + l_get_ref(l, 0); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + + // index_of + l->flag = CMC_FLAG_ERROR; + l_index_of(l, 10, false); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + + // contains + l->flag = CMC_FLAG_ERROR; + cmc_assert(l_contains(l, 10)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + + // copy_of + l->flag = CMC_FLAG_ERROR; + struct list *l3 = l_copy_of(l); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l3)); + + // equals + l->flag = CMC_FLAG_ERROR; + l3->flag = CMC_FLAG_ERROR; + cmc_assert(l_equals(l, l3)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l3)); + + l_free(l); + l_free(l2); + l_free(l3); + }); + + CMC_CREATE_TEST(callbacks, { + struct list *l = l_new_custom(100, l_fval, NULL, callbacks); + + cmc_assert_not_equals(ptr, NULL, l); + + total_create = 0; + total_read = 0; + total_update = 0; + total_delete = 0; + total_resize = 0; + + cmc_assert(l_push_front(l, 10)); + cmc_assert_equals(int32_t, 1, total_create); + + cmc_assert(l_push_back(l, 10)); + cmc_assert_equals(int32_t, 2, total_create); + + cmc_assert(l_push_at(l, 10, 1)); + cmc_assert_equals(int32_t, 3, total_create); + + cmc_assert(l_pop_at(l, 1)); + cmc_assert_equals(int32_t, 1, total_delete); + + cmc_assert(l_pop_front(l)); + cmc_assert_equals(int32_t, 2, total_delete); + + cmc_assert(l_pop_back(l)); + cmc_assert_equals(int32_t, 3, total_delete); + + cmc_assert(l_push_back(l, 10)); + cmc_assert_equals(int32_t, 4, total_create); + + cmc_assert_equals(size_t, 10, l_front(l)); + cmc_assert_equals(int32_t, 1, total_read); + + cmc_assert_equals(size_t, 10, l_back(l)); + cmc_assert_equals(int32_t, 2, total_read); + + cmc_assert_equals(size_t, 10, l_get(l, 0)); + cmc_assert_equals(int32_t, 3, total_read); + + cmc_assert_not_equals(ptr, NULL, l_get_ref(l, 0)); + cmc_assert_equals(int32_t, 4, total_read); + + cmc_assert(l_contains(l, 10)); + cmc_assert_equals(int32_t, 5, total_read); + + cmc_assert(l_seq_push_front(l, (size_t[]){ 7, 8, 9 }, 3)); + cmc_assert_equals(int32_t, 5, total_create); + + cmc_assert(l_seq_push_back(l, (size_t[]){ 14, 15, 16 }, 3)); + cmc_assert_equals(int32_t, 6, total_create); + + cmc_assert(l_seq_push_at(l, (size_t[]){ 11, 12, 13 }, 3, 4)); + cmc_assert_equals(int32_t, 7, total_create); + + cmc_assert(l_seq_pop_at(l, 1, 4)); + cmc_assert_equals(int32_t, 4, total_delete); + + struct list *l2 = l_seq_sublist(l, 0, 4); + cmc_assert_equals(int32_t, 5, total_delete); + + cmc_assert(l_resize(l, 1000)); + cmc_assert_equals(int32_t, 1, total_resize); + + cmc_assert(l_resize(l2, 1000)); + cmc_assert_equals(int32_t, 2, total_resize); + + cmc_assert_equals(int32_t, 7, total_create); + cmc_assert_equals(int32_t, 5, total_read); + cmc_assert_equals(int32_t, 0, total_update); + cmc_assert_equals(int32_t, 5, total_delete); + cmc_assert_equals(int32_t, 2, total_resize); + + l_customize(l, NULL, NULL); + + cmc_assert_equals(ptr, NULL, l->callbacks); + + l_clear(l); + cmc_assert(l_push_front(l, 10)); + cmc_assert(l_push_back(l, 10)); + cmc_assert(l_push_at(l, 10, 1)); + cmc_assert(l_pop_at(l, 1)); + cmc_assert(l_pop_front(l)); + cmc_assert(l_pop_back(l)); + cmc_assert(l_push_back(l, 10)); + cmc_assert_equals(size_t, 10, l_front(l)); + cmc_assert_equals(size_t, 10, l_back(l)); + cmc_assert_equals(size_t, 10, l_get(l, 0)); + cmc_assert_not_equals(ptr, NULL, l_get_ref(l, 0)); + cmc_assert(l_contains(l, 10)); + cmc_assert(l_seq_push_front(l, (size_t[]){ 7, 8, 9 }, 3)); + cmc_assert(l_seq_push_back(l, (size_t[]){ 14, 15, 16 }, 3)); + cmc_assert(l_seq_push_at(l, (size_t[]){ 11, 12, 13 }, 3, 4)); + cmc_assert(l_seq_pop_at(l, 1, 4)); + struct list *l3 = l_seq_sublist(l, 0, 4); + cmc_assert(l_resize(l, 1000)); + cmc_assert(l_resize(l3, 1000)); + + cmc_assert_equals(int32_t, 7, total_create); + cmc_assert_equals(int32_t, 5, total_read); + cmc_assert_equals(int32_t, 0, total_update); + cmc_assert_equals(int32_t, 5, total_delete); + cmc_assert_equals(int32_t, 2, total_resize); + + cmc_assert_equals(ptr, NULL, l->callbacks); + + l_free(l); + l_free(l2); + l_free(l3); + + total_create = 0; + total_read = 0; + total_update = 0; + total_delete = 0; + total_resize = 0; + }); +}) + +CMC_CREATE_UNIT(CMCListIter, true, { + CMC_CREATE_TEST(PFX##_iter_start(), { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + struct list_iter it = l_iter_start(l); + + cmc_assert_equals(ptr, l, it.target); + cmc_assert_equals(size_t, 0, it.cursor); + cmc_assert_equals(bool, true, it.start); + cmc_assert_equals(bool, true, it.end); + + cmc_assert(l_iter_at_start(&it)); + cmc_assert(l_iter_at_end(&it)); + + cmc_assert(l_push_front(l, 1)); + cmc_assert(l_push_front(l, 2)); + + it = l_iter_start(l); + + cmc_assert_equals(size_t, 0, it.cursor); + cmc_assert_equals(bool, false, it.end); + + l_free(l); + }); + + CMC_CREATE_TEST(PFX##_iter_end(), { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + struct list_iter it = l_iter_end(l); + + cmc_assert_equals(ptr, l, it.target); + cmc_assert_equals(size_t, 0, it.cursor); + cmc_assert_equals(bool, true, it.start); + cmc_assert_equals(bool, true, it.end); + + cmc_assert(l_iter_at_start(&it)); + cmc_assert(l_iter_at_end(&it)); + + cmc_assert(l_push_back(l, 1)); + cmc_assert(l_push_back(l, 2)); + cmc_assert(l_push_back(l, 3)); + + it = l_iter_end(l); + + cmc_assert_equals(size_t, l->count - 1, it.cursor); + cmc_assert_equals(bool, false, it.start); + + l_free(l); + }); + + CMC_CREATE_TEST(PFX##_iter_at_start(), { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + struct list_iter it = l_iter_start(l); + + // Empty checks + cmc_assert(l_iter_at_start(&it)); + it = l_iter_end(l); + cmc_assert(l_iter_at_start(&it)); + + // Non-empty checks + cmc_assert(l_push_back(l, 1)); + it = l_iter_end(l); + cmc_assert(!l_iter_at_start(&it)); + it = l_iter_start(l); + cmc_assert(l_iter_at_start(&it)); + + l_clear(l); + + cmc_assert(l_push_front(l, 1)); + it = l_iter_end(l); + cmc_assert(!l_iter_at_start(&it)); + it = l_iter_start(l); + cmc_assert(l_iter_at_start(&it)); + + l_free(l); + }); + + CMC_CREATE_TEST(PFX##_iter_at_end(), { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + struct list_iter it = l_iter_start(l); + + // Empty check + cmc_assert(l_iter_at_end(&it)); + it = l_iter_end(l); + cmc_assert(l_iter_at_end(&it)); + + // Non-empty checks + cmc_assert(l_push_back(l, 1)); + it = l_iter_end(l); + cmc_assert(l_iter_at_end(&it)); + it = l_iter_start(l); + cmc_assert(!l_iter_at_end(&it)); + + l_clear(l); + + cmc_assert(l_push_front(l, 1)); + it = l_iter_end(l); + cmc_assert(l_iter_at_end(&it)); + it = l_iter_start(l); + cmc_assert(!l_iter_at_end(&it)); + + l_free(l); + }); + + CMC_CREATE_TEST(PFX##_iter_to_start(), { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + struct list_iter it = l_iter_start(l); + + cmc_assert(!l_iter_to_start(&it)); + + for (size_t i = 1; i <= 100; i++) + { + if (i % 2 == 0) + l_push_back(l, i); + else + l_push_front(l, i); + } + + cmc_assert_equals(size_t, 100, l->count); + + it = l_iter_end(l); + + cmc_assert(!l_iter_at_start(&it)); + cmc_assert(l_iter_at_end(&it)); + + cmc_assert_equals(size_t, 100, l_iter_value(&it)); + + cmc_assert(l_iter_to_start(&it)); + + cmc_assert(l_iter_at_start(&it)); + cmc_assert(!l_iter_at_end(&it)); + + cmc_assert_equals(size_t, 99, l_iter_value(&it)); + + l_free(l); + }); + + CMC_CREATE_TEST(PFX##_iter_to_end(), { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + struct list_iter it = l_iter_end(l); + + cmc_assert(!l_iter_to_end(&it)); + + for (size_t i = 1; i <= 100; i++) + { + if (i % 2 == 0) + l_push_back(l, i); + else + l_push_front(l, i); + } + + it = l_iter_start(l); + + cmc_assert(l_iter_at_start(&it)); + cmc_assert(!l_iter_at_end(&it)); + + cmc_assert_equals(size_t, 99, l_iter_value(&it)); + + cmc_assert(l_iter_to_end(&it)); + + cmc_assert(!l_iter_at_start(&it)); + cmc_assert(l_iter_at_end(&it)); + + cmc_assert_equals(size_t, 100, l_iter_value(&it)); + + l_free(l); + }); + + CMC_CREATE_TEST(PFX##_iter_next(), { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + struct list_iter it = l_iter_start(l); + + cmc_assert(!l_iter_next(&it)); + + for (size_t i = 1; i <= 1000; i++) + { + if (i % 2 == 0) + l_push_back(l, i); + else + l_push_front(l, i); + } + + size_t sum = 0; + for (it = l_iter_start(l); !l_iter_at_end(&it); l_iter_next(&it)) + { + sum += l_iter_value(&it); + } + + cmc_assert_equals(size_t, 500500, sum); + + sum = 0; + + l_iter_to_start(&it); + do + { + sum += l_iter_value(&it); + } while (l_iter_next(&it)); + + cmc_assert_equals(size_t, 500500, sum); + + l_free(l); + }); + + CMC_CREATE_TEST(PFX##_iter_prev(), { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + struct list_iter it = l_iter_end(l); + + cmc_assert(!l_iter_prev(&it)); + + for (size_t i = 1; i <= 1000; i++) + { + if (i % 2 == 0) + l_push_back(l, i); + else + l_push_front(l, i); + } + + size_t sum = 0; + for (it = l_iter_end(l); !l_iter_at_start(&it); l_iter_prev(&it)) + { + sum += l_iter_value(&it); + } + + cmc_assert_equals(size_t, 500500, sum); + + sum = 0; + + l_iter_to_end(&it); + do + { + sum += l_iter_value(&it); + } while (l_iter_prev(&it)); + + cmc_assert_equals(size_t, 500500, sum); + + l_free(l); + }); + + CMC_CREATE_TEST(PFX##_iter_advance(), { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + struct list_iter it = l_iter_start(l); + + cmc_assert(!l_iter_advance(&it, 1)); + + for (size_t i = 0; i <= 1000; i++) + { + if (i % 2 == 0) + l_push_back(l, i); // will sum all even numbers + else + l_push_back(l, 0); + } + + it = l_iter_start(l); + + cmc_assert(!l_iter_advance(&it, 0)); + cmc_assert(!l_iter_advance(&it, l->count)); + + size_t sum = 0; + for (it = l_iter_start(l);;) + { + sum += l_iter_value(&it); + + if (!l_iter_advance(&it, 2)) + break; + } + + cmc_assert_equals(size_t, 250500, sum); + + l_iter_to_start(&it); + cmc_assert(l_iter_advance(&it, l->count - 1)); + + l_free(l); + }); + + CMC_CREATE_TEST(PFX##_iter_rewind(), { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + struct list_iter it = l_iter_end(l); + + cmc_assert(!l_iter_rewind(&it, 1)); + + for (size_t i = 0; i <= 1000; i++) + { + if (i % 2 == 0) + l_push_front(l, i); // will sum all even numbers + else + l_push_front(l, 0); + } + + it = l_iter_end(l); + + cmc_assert(!l_iter_rewind(&it, 0)); + cmc_assert(!l_iter_rewind(&it, l->count)); + + size_t sum = 0; + for (it = l_iter_end(l);;) + { + sum += l_iter_value(&it); + + if (!l_iter_rewind(&it, 2)) + break; + } + + cmc_assert_equals(size_t, 250500, sum); + + l_iter_to_end(&it); + cmc_assert(l_iter_rewind(&it, l->count - 1)); + + l_free(l); + }); + + CMC_CREATE_TEST(PFX##_iter_go_to(), { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + struct list_iter it = l_iter_end(l); + cmc_assert(!l_iter_go_to(&it, 0)); + + it = l_iter_start(l); + cmc_assert(!l_iter_go_to(&it, 0)); + + for (size_t i = 0; i <= 1000; i++) + l_push_back(l, i); + + it = l_iter_start(l); + + size_t sum = 0; + for (size_t i = 0; i < 1001; i++) + { + l_iter_go_to(&it, i); + + sum += l_iter_value(&it); + } + + cmc_assert_equals(size_t, 500500, sum); + + sum = 0; + for (size_t i = 1001; i > 0; i--) + { + cmc_assert(l_iter_go_to(&it, i - 1)); + + sum += l_iter_value(&it); + } + + cmc_assert_equals(size_t, 500500, sum); + + sum = 0; + for (size_t i = 0; i < 1001; i += 100) + { + cmc_assert(l_iter_go_to(&it, i)); + cmc_assert_equals(size_t, i, l_iter_index(&it)); + + sum += l_iter_value(&it); + } + + cmc_assert_equals(size_t, 5500, sum); + + l_free(l); + }); + + CMC_CREATE_TEST(PFX##_iter_value(), { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + struct list_iter it = l_iter_end(l); + + cmc_assert_equals(size_t, (size_t){ 0 }, l_iter_value(&it)); + + cmc_assert(l_push_back(l, 10)); + + it = l_iter_start(l); + + cmc_assert_equals(size_t, 10, l_iter_value(&it)); + + l_free(l); + }); + + CMC_CREATE_TEST(PFX##_iter_rvalue(), { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + struct list_iter it = l_iter_end(l); + + cmc_assert_equals(ptr, NULL, l_iter_rvalue(&it)); + + cmc_assert(l_push_back(l, 10)); + + it = l_iter_start(l); + + cmc_assert_not_equals(ptr, NULL, l_iter_rvalue(&it)); + cmc_assert_equals(size_t, 10, *l_iter_rvalue(&it)); + + l_free(l); + }); + + CMC_CREATE_TEST(PFX##_iter_index(), { + struct list *l = l_new(100, l_fval); + + cmc_assert_not_equals(ptr, NULL, l); + + for (size_t i = 0; i <= 1000; i++) + l_push_back(l, i); + + struct list_iter it = l_iter_start(l); + + for (size_t i = 0; i < 1001; i++) + { + cmc_assert_equals(size_t, i, l_iter_index(&it)); + l_iter_next(&it); + } + + it = l_iter_end(l); + for (size_t i = 1001; i > 0; i--) + { + cmc_assert_equals(size_t, i - 1, l_iter_index(&it)); + l_iter_prev(&it); + } + + l_free(l); + }); +}); + +#endif /* CMC_TESTS_UNT_LIST_H */ diff --git a/tests/unt_stack.h b/tests/unt_stack.h new file mode 100644 index 0000000..6e365c9 --- /dev/null +++ b/tests/unt_stack.h @@ -0,0 +1,854 @@ +#ifndef CMC_TESTS_UNT_STACK_H +#define CMC_TESTS_UNT_STACK_H + +#include "utl.h" + +#define V size_t +#define PFX s +#define SNAME stack +#define CMC_EXT_STACK_INIT +#define CMC_EXT_STACK_ITER +#include "cmc/stack.h" + +struct stack_fval *s_fval = &(struct stack_fval){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp +}; + +CMC_CREATE_UNIT(CMCStack, true, { + CMC_CREATE_TEST(new, { + struct stack *s = s_new(1000000, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + cmc_assert_not_equals(ptr, NULL, s->buffer); + cmc_assert_equals(size_t, 1000000, s_capacity(s)); + cmc_assert_equals(size_t, 0, s_count(s)); + cmc_assert_not_equals(ptr, NULL, s->buffer); + + s_free(s); + }); + + CMC_CREATE_TEST(new[capacity = 0], { + struct stack *s = s_new(0, s_fval); + + cmc_assert_equals(ptr, NULL, s); + }); + + CMC_CREATE_TEST(new[capacity = UINT64_MAX], { + struct stack *s = s_new(UINT64_MAX, s_fval); + + cmc_assert_equals(ptr, NULL, s); + }); + + CMC_CREATE_TEST(clear[count capacity], { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + for (size_t i = 0; i < 50; i++) + cmc_assert(s_push(s, i)); + + cmc_assert_equals(size_t, 50, s_count(s)); + + s_clear(s); + + cmc_assert_equals(size_t, 0, s_count(s)); + cmc_assert_equals(size_t, 100, s_capacity(s)); + + s_free(s); + }); + + CMC_CREATE_TEST(buffer_growth[capacity = 1], { + struct stack *s = s_new(1, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + for (size_t i = 0; i < 50; i++) + cmc_assert(s_push(s, i)); + + cmc_assert_equals(size_t, 50, s_count(s)); + cmc_assert_lesser_equals(size_t, s_capacity(s), s_count(s)); + + s_free(s); + }); + + CMC_CREATE_TEST(push[count], { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + for (size_t i = 0; i < 250; i++) + cmc_assert(s_push(s, i)); + + cmc_assert_equals(size_t, 250, s_count(s)); + + s_free(s); + }); + + CMC_CREATE_TEST(push[capacity], { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + for (size_t i = 0; i < 250; i++) + cmc_assert(s_push(s, i)); + + cmc_assert_lesser_equals(size_t, s_capacity(s), s_count(s)); + + s_free(s); + }); + + CMC_CREATE_TEST(push[item preservation], { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + for (size_t i = 0; i < 250; i++) + cmc_assert(s_push(s, i)); + + for (size_t i = 0; i < s_count(s); i++) + cmc_assert_equals(size_t, i, s->buffer[i]); + + s_free(s); + }); + + CMC_CREATE_TEST(pop[count], { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + for (size_t i = 0; i < 250; i++) + cmc_assert(s_push(s, i)); + + cmc_assert(s_pop(s)); + + cmc_assert_equals(size_t, 249, s_count(s)); + + s_free(s); + }); + + CMC_CREATE_TEST(pop[capacity], { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + for (size_t i = 0; i < 250; i++) + cmc_assert(s_push(s, i)); + + cmc_assert(s_pop(s)); + + cmc_assert_lesser_equals(size_t, s_capacity(s), s_count(s)); + + s_free(s); + }); + + CMC_CREATE_TEST(pop[item preservation], { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + for (size_t i = 0; i < 250; i++) + cmc_assert(s_push(s, i)); + + cmc_assert(s_pop(s)); + cmc_assert(s_pop(s)); + + for (size_t i = 0; i < s_count(s); i++) + cmc_assert_equals(size_t, i, s->buffer[i]); + + s_free(s); + }); + + CMC_CREATE_TEST(pop[count = 0], { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + cmc_assert_equals(bool, false, s_pop(s)); + + s_free(s); + }); + + CMC_CREATE_TEST(top, { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + for (size_t i = 0; i < 250; i++) + cmc_assert(s_push(s, i)); + + cmc_assert(s_pop(s)); + cmc_assert(s_pop(s)); + + cmc_assert_equals(size_t, 247, s_top(s)); + + s_free(s); + }); + + CMC_CREATE_TEST(top[count = 0], { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + cmc_assert(s_push(s, 1)); + + cmc_assert(s_pop(s)); + + cmc_assert_equals(size_t, (size_t){ 0 }, s_top(s)); + + s_free(s); + }); + + CMC_CREATE_TEST(top[count = 1], { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + cmc_assert(s_push(s, 10)); + cmc_assert_equals(size_t, 1, s_count(s)); + cmc_assert_equals(size_t, 10, s_top(s)); + + s_free(s); + }); + + CMC_CREATE_TEST(contains, { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + for (size_t i = 0; i < 150; i++) + cmc_assert(s_push(s, i)); + + for (size_t i = 0; i < 150; i++) + cmc_assert(s_contains(s, i)); + + s_free(s); + }); + + CMC_CREATE_TEST(contains[count = 0], { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + cmc_assert_equals(bool, false, s_contains(s, 10)); + + s_free(s); + }); + + CMC_CREATE_TEST(empty, { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + cmc_assert(s_empty(s)); + + s_free(s); + }); + + CMC_CREATE_TEST(empty[after_io], { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + cmc_assert(s_push(s, 10)); + cmc_assert(s_pop(s)); + cmc_assert(s_empty(s)); + + s_free(s); + }); + + CMC_CREATE_TEST(full, { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + for (size_t i = 0; i < s_capacity(s); i++) + cmc_assert(s_push(s, i)); + + cmc_assert(s_full(s)); + + s_free(s); + }); + + CMC_CREATE_TEST(full[capacity = 1], { + struct stack *s = s_new(1, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + cmc_assert(s_push(s, 10)); + + cmc_assert(s_full(s)); + + s_free(s); + }); + + CMC_CREATE_TEST(flags, { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); + + // clear + s->flag = CMC_FLAG_ERROR; + s_clear(s); + cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); + + // customize + s->flag = CMC_FLAG_ERROR; + s_customize(s, NULL, NULL); + cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); + + // push + s->flag = CMC_FLAG_ERROR; + cmc_assert(s_push(s, 1)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); + + // pop + s->flag = CMC_FLAG_ERROR; + cmc_assert(s_pop(s)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); + + cmc_assert(!s_pop(s)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, s_flag(s)); + + // top + s->flag = CMC_FLAG_ERROR; + s_top(s); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, s_flag(s)); + + cmc_assert(s_push(s, 1)); + s_top(s); + cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); + + // contains + s->flag = CMC_FLAG_ERROR; + cmc_assert(s_contains(s, 1)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); + + // copy_of + s->flag = CMC_FLAG_ERROR; + struct stack *s2 = s_copy_of(s); + cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s2)); + + // equals + s->flag = CMC_FLAG_ERROR; + s2->flag = CMC_FLAG_ERROR; + cmc_assert(s_equals(s, s2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s2)); + + s_free(s); + s_free(s2); + }); + + CMC_CREATE_TEST(callbacks, { + struct stack *s = s_new_custom(100, s_fval, NULL, callbacks); + + cmc_assert_not_equals(ptr, NULL, s); + + total_create = 0; + total_read = 0; + total_update = 0; + total_delete = 0; + total_resize = 0; + + cmc_assert(s_push(s, 10)); + cmc_assert_equals(int32_t, 1, total_create); + + cmc_assert(s_pop(s)); + cmc_assert_equals(int32_t, 1, total_delete); + + cmc_assert(s_push(s, 1)); + cmc_assert_equals(int32_t, 2, total_create); + + cmc_assert_equals(size_t, 1, s_top(s)); + cmc_assert_equals(int32_t, 1, total_read); + + cmc_assert(s_contains(s, 1)); + cmc_assert_equals(int32_t, 2, total_read); + + cmc_assert(s_resize(s, 1000)); + cmc_assert_equals(int32_t, 1, total_resize); + + cmc_assert(s_resize(s, 10)); + cmc_assert_equals(int32_t, 2, total_resize); + + cmc_assert_equals(int32_t, 2, total_create); + cmc_assert_equals(int32_t, 2, total_read); + cmc_assert_equals(int32_t, 0, total_update); + cmc_assert_equals(int32_t, 1, total_delete); + cmc_assert_equals(int32_t, 2, total_resize); + + s_customize(s, NULL, NULL); + + s_clear(s); + cmc_assert(s_push(s, 10)); + cmc_assert(s_pop(s)); + cmc_assert(s_push(s, 1)); + cmc_assert_equals(size_t, 1, s_top(s)); + cmc_assert(s_contains(s, 1)); + cmc_assert(s_resize(s, 1000)); + cmc_assert(s_resize(s, 10)); + + cmc_assert_equals(int32_t, 2, total_create); + cmc_assert_equals(int32_t, 2, total_read); + cmc_assert_equals(int32_t, 0, total_update); + cmc_assert_equals(int32_t, 1, total_delete); + cmc_assert_equals(int32_t, 2, total_resize); + + cmc_assert_equals(ptr, NULL, s->callbacks); + + s_free(s); + + total_create = 0; + total_read = 0; + total_update = 0; + total_delete = 0; + total_resize = 0; + }); +}); + +CMC_CREATE_UNIT(CMCStackIter, true, { + CMC_CREATE_TEST(PFX##_iter_start(), { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + struct stack_iter it = s_iter_start(s); + + cmc_assert_equals(ptr, s, it.target); + cmc_assert_equals(size_t, 0, it.cursor); + cmc_assert_equals(bool, true, it.start); + cmc_assert_equals(bool, true, it.end); + + cmc_assert(s_iter_at_start(&it)); + cmc_assert(s_iter_at_end(&it)); + + cmc_assert(s_push(s, 1)); + cmc_assert(s_push(s, 2)); + + it = s_iter_start(s); + + cmc_assert_equals(size_t, s->count - 1, it.cursor); + cmc_assert_equals(bool, false, it.end); + + s_free(s); + }); + + CMC_CREATE_TEST(PFX##_iter_end(), { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + struct stack_iter it = s_iter_end(s); + + cmc_assert_equals(ptr, s, it.target); + cmc_assert_equals(size_t, 0, it.cursor); + cmc_assert_equals(bool, true, it.start); + cmc_assert_equals(bool, true, it.end); + + cmc_assert(s_iter_at_start(&it)); + cmc_assert(s_iter_at_end(&it)); + + cmc_assert(s_push(s, 1)); + cmc_assert(s_push(s, 2)); + cmc_assert(s_push(s, 3)); + + it = s_iter_end(s); + + cmc_assert_equals(size_t, 0, it.cursor); + cmc_assert_equals(bool, false, it.start); + + s_free(s); + }); + + CMC_CREATE_TEST(PFX##_iter_at_start(), { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + struct stack_iter it = s_iter_start(s); + + // Empty checks + cmc_assert(s_iter_at_start(&it)); + it = s_iter_end(s); + cmc_assert(s_iter_at_start(&it)); + + // Non-empty checks + cmc_assert(s_push(s, 1)); + it = s_iter_end(s); + cmc_assert(!s_iter_at_start(&it)); + it = s_iter_start(s); + cmc_assert(s_iter_at_start(&it)); + + s_free(s); + }); + + CMC_CREATE_TEST(PFX##_iter_at_end(), { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + struct stack_iter it = s_iter_start(s); + + // Empty check + cmc_assert(s_iter_at_end(&it)); + it = s_iter_end(s); + cmc_assert(s_iter_at_end(&it)); + + // Non-empty checks + cmc_assert(s_push(s, 1)); + it = s_iter_end(s); + cmc_assert(s_iter_at_end(&it)); + it = s_iter_start(s); + cmc_assert(!s_iter_at_end(&it)); + + s_free(s); + }); + + CMC_CREATE_TEST(PFX##_iter_to_start(), { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + struct stack_iter it = s_iter_start(s); + + cmc_assert(!s_iter_to_start(&it)); + + for (size_t i = 1; i <= 100; i++) + s_push(s, i); + + cmc_assert_equals(size_t, 100, s->count); + + it = s_iter_end(s); + + cmc_assert(!s_iter_at_start(&it)); + cmc_assert(s_iter_at_end(&it)); + + cmc_assert_equals(size_t, 1, s_iter_value(&it)); + + cmc_assert(s_iter_to_start(&it)); + + cmc_assert(s_iter_at_start(&it)); + cmc_assert(!s_iter_at_end(&it)); + + cmc_assert_equals(size_t, 100, s_iter_value(&it)); + + s_free(s); + }); + + CMC_CREATE_TEST(PFX##_iter_to_end(), { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + struct stack_iter it = s_iter_end(s); + + cmc_assert(!s_iter_to_end(&it)); + + for (size_t i = 1; i <= 100; i++) + s_push(s, i); + + it = s_iter_start(s); + + cmc_assert(s_iter_at_start(&it)); + cmc_assert(!s_iter_at_end(&it)); + + cmc_assert_equals(size_t, 100, s_iter_value(&it)); + + cmc_assert(s_iter_to_end(&it)); + + cmc_assert(!s_iter_at_start(&it)); + cmc_assert(s_iter_at_end(&it)); + + cmc_assert_equals(size_t, 1, s_iter_value(&it)); + + s_free(s); + }); + + CMC_CREATE_TEST(PFX##_iter_next(), { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + struct stack_iter it = s_iter_start(s); + + cmc_assert(!s_iter_next(&it)); + + for (size_t i = 1; i <= 1000; i++) + s_push(s, i); + + size_t sum = 0; + for (it = s_iter_start(s); !s_iter_at_end(&it); s_iter_next(&it)) + { + sum += s_iter_value(&it); + } + + cmc_assert_equals(size_t, 500500, sum); + + sum = 0; + + s_iter_to_start(&it); + do + { + sum += s_iter_value(&it); + } while (s_iter_next(&it)); + + cmc_assert_equals(size_t, 500500, sum); + + s_free(s); + }); + + CMC_CREATE_TEST(PFX##_iter_prev(), { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + struct stack_iter it = s_iter_end(s); + + cmc_assert(!s_iter_prev(&it)); + + for (size_t i = 1; i <= 1000; i++) + s_push(s, i); + + size_t sum = 0; + for (it = s_iter_end(s); !s_iter_at_start(&it); s_iter_prev(&it)) + { + sum += s_iter_value(&it); + } + + cmc_assert_equals(size_t, 500500, sum); + + sum = 0; + + s_iter_to_end(&it); + do + { + sum += s_iter_value(&it); + } while (s_iter_prev(&it)); + + cmc_assert_equals(size_t, 500500, sum); + + s_free(s); + }); + + CMC_CREATE_TEST(PFX##_iter_advance(), { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + struct stack_iter it = s_iter_start(s); + + cmc_assert(!s_iter_advance(&it, 1)); + + for (size_t i = 0; i <= 1000; i++) + s_push(s, i); + + it = s_iter_start(s); + + cmc_assert(!s_iter_advance(&it, 0)); + cmc_assert(!s_iter_advance(&it, s->count)); + + size_t sum = 0; + for (it = s_iter_start(s);;) + { + sum += s_iter_value(&it); + + if (!s_iter_advance(&it, 2)) + break; + } + + cmc_assert_equals(size_t, 250500, sum); + + s_iter_to_start(&it); + cmc_assert(s_iter_advance(&it, s->count - 1)); + + // sum (1000, 990, 980, 970, ..., 910, 900) + sum = 0; + it = s_iter_start(s); + for (size_t val = s_iter_value(&it); val > 900; s_iter_advance(&it, 10)) + { + val = s_iter_value(&it); + sum += val; + } + + cmc_assert_equals(size_t, 10450, sum); + + s_free(s); + }); + + CMC_CREATE_TEST(PFX##_iter_rewind(), { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + struct stack_iter it = s_iter_end(s); + + cmc_assert(!s_iter_rewind(&it, 1)); + + for (size_t i = 0; i <= 1000; i++) + s_push(s, i); + + it = s_iter_end(s); + + cmc_assert(!s_iter_rewind(&it, 0)); + cmc_assert(!s_iter_rewind(&it, s->count)); + + size_t sum = 0; + for (it = s_iter_end(s);;) + { + sum += s_iter_value(&it); + + if (!s_iter_rewind(&it, 2)) + break; + } + + cmc_assert_equals(size_t, 250500, sum); + + s_iter_to_end(&it); + cmc_assert(s_iter_rewind(&it, s->count - 1)); + + // sum (0, 10, 20, ..., 90, 100) + sum = 0; + it = s_iter_end(s); + for (size_t val = s_iter_value(&it); val < 100; s_iter_rewind(&it, 10)) + { + val = s_iter_value(&it); + sum += val; + } + + cmc_assert_equals(size_t, 550, sum); + + s_free(s); + }); + + CMC_CREATE_TEST(PFX##_iter_go_to(), { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + struct stack_iter it = s_iter_end(s); + cmc_assert(!s_iter_go_to(&it, 0)); + + it = s_iter_start(s); + cmc_assert(!s_iter_go_to(&it, 0)); + + for (size_t i = 1001; i > 0; i--) + s_push(s, i - 1); + + it = s_iter_start(s); + + size_t sum = 0; + for (size_t i = 0; i < 1001; i++) + { + s_iter_go_to(&it, i); + + sum += s_iter_value(&it); + } + + cmc_assert_equals(size_t, 500500, sum); + + sum = 0; + for (size_t i = 1001; i > 0; i--) + { + cmc_assert(s_iter_go_to(&it, i - 1)); + + sum += s_iter_value(&it); + } + + cmc_assert_equals(size_t, 500500, sum); + + sum = 0; + for (size_t i = 1000; i > 0; i -= 100) + { + cmc_assert(s_iter_go_to(&it, 1000 - i)); + cmc_assert_equals(size_t, i, s_iter_index(&it)); + + sum += s_iter_value(&it); + } + + cmc_assert_equals(size_t, 5500, sum); + + s_free(s); + }); + + CMC_CREATE_TEST(PFX##_iter_value(), { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + struct stack_iter it = s_iter_end(s); + + cmc_assert_equals(size_t, (size_t){ 0 }, s_iter_value(&it)); + + cmc_assert(s_push(s, 10)); + + it = s_iter_start(s); + + cmc_assert_equals(size_t, 10, s_iter_value(&it)); + + s_free(s); + }); + + CMC_CREATE_TEST(PFX##_iter_rvalue(), { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + struct stack_iter it = s_iter_end(s); + + cmc_assert_equals(ptr, NULL, s_iter_rvalue(&it)); + + cmc_assert(s_push(s, 10)); + + it = s_iter_start(s); + + cmc_assert_not_equals(ptr, NULL, s_iter_rvalue(&it)); + cmc_assert_equals(size_t, 10, *s_iter_rvalue(&it)); + + s_free(s); + }); + + CMC_CREATE_TEST(PFX##_iter_index(), { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + for (size_t i = 0; i <= 1000; i++) + s_push(s, i); + + struct stack_iter it = s_iter_start(s); + + for (size_t i = 0; i < 1001; i++) + { + cmc_assert_equals(size_t, i, s_iter_index(&it)); + s_iter_next(&it); + } + + it = s_iter_end(s); + for (size_t i = 1001; i > 0; i--) + { + cmc_assert_equals(size_t, i - 1, s_iter_index(&it)); + s_iter_prev(&it); + } + + s_free(s); + }); +}); + +#ifdef CMC_TEST_MAIN +int main(void) +{ + int result = CMCStack() + CMCStackIter(); + + printf(" +---------------------------------------------------------------+"); + printf("\n"); + printf(" | CMCStack Suit : %-48s |\n", result == 0 ? "PASSED" : "FAILED"); + printf(" +---------------------------------------------------------------+"); + printf("\n\n\n"); + + return result; +} +#endif + +#endif /* CMC_TESTS_UNT_STACK_H */ diff --git a/tests/utl.h b/tests/utl.h new file mode 100644 index 0000000..2645acd --- /dev/null +++ b/tests/utl.h @@ -0,0 +1,171 @@ +/* Utility file to be included in the unit tests */ +#ifndef CMC_TESTS_UTL +#define CMC_TESTS_UTL + +#include +#include +#include + +#include "cmc/cor/hashtable.h" +#include "cmc/utl/assert.h" +#include "cmc/utl/foreach.h" +#include "cmc/utl/futils.h" +#include "cmc/utl/test.h" + +size_t numhash(size_t a) +{ + return a; +} + +size_t hashcapminus1(size_t a) +{ + (void)a; + return cmc_hashtable_primes[0] - 1; +} + +size_t hashcapminus4(size_t a) +{ + (void)a; + return cmc_hashtable_primes[0] - 1; +} + +size_t hash0(size_t a) +{ + (void)a; + return 0; +} + +// counter ftab functions + +int32_t k_total_cmp = 0; +int32_t k_total_cpy = 0; +int32_t k_total_str = 0; +int32_t k_total_free = 0; +int32_t k_total_hash = 0; +int32_t k_total_pri = 0; + +int32_t v_total_cmp = 0; +int32_t v_total_cpy = 0; +int32_t v_total_str = 0; +int32_t v_total_free = 0; +int32_t v_total_hash = 0; +int32_t v_total_pri = 0; + +int k_c_cmp(size_t a, size_t b) +{ + k_total_cmp++; + return (a > b) - (a < b); +} + +size_t k_c_cpy(size_t a) +{ + k_total_cpy++; + return a; +} + +bool k_c_str(FILE *fptr, size_t a) +{ + k_total_str++; + return fprintf(fptr, "%" PRIuMAX " ", a) > 0; +} + +void k_c_free(size_t a) +{ + (void)a; + k_total_free++; +} + +size_t k_c_hash(size_t x) +{ + k_total_hash++; + x = ((x >> 16) ^ x) * 0x45d9f3b; + x = ((x >> 16) ^ x) * 0x45d9f3b; + x = (x >> 16) ^ x; + return x; +} + +int k_c_pri(size_t a, size_t b) +{ + k_total_pri++; + return (a > b) - (a < b); +} + +int v_c_cmp(size_t a, size_t b) +{ + v_total_cmp++; + return (a > b) - (a < b); +} + +size_t v_c_cpy(size_t a) +{ + v_total_cpy++; + return a; +} + +bool v_c_str(FILE *fptr, size_t a) +{ + v_total_str++; + return fprintf(fptr, "%" PRIuMAX " ", a) > 0; +} + +void v_c_free(size_t a) +{ + (void)a; + v_total_free++; +} + +size_t v_c_hash(size_t x) +{ + v_total_hash++; + x = ((x >> 16) ^ x) * 0x45d9f3b; + x = ((x >> 16) ^ x) * 0x45d9f3b; + x = (x >> 16) ^ x; + return x; +} + +int v_c_pri(size_t a, size_t b) +{ + v_total_pri++; + return (a > b) - (a < b); +} + +// callbacks + +int total_create = 0; +int total_read = 0; +int total_update = 0; +int total_delete = 0; +int total_resize = 0; + +void callback_create(void) +{ + total_create++; +} + +void callback_read(void) +{ + total_read++; +} + +void callback_update(void) +{ + total_update++; +} + +void callback_delete(void) +{ + total_delete++; +} + +void callback_resize(void) +{ + total_resize++; +} + +struct cmc_callbacks *callbacks = &(struct cmc_callbacks){ .create = callback_create, + .read = callback_read, + .update = callback_update, + .delete = callback_delete, + .resize = callback_resize }; + +#endif /* CMC_TESTS_UTL */