diff --git a/tests/src/array/plug.h b/tests/src/array/plug.h index a54e99f..dd8ed86 100644 --- a/tests/src/array/plug.h +++ b/tests/src/array/plug.h @@ -85,7 +85,7 @@ static int array_value_print(void* v, ssize_t i, vtype t, void* _) { return 0; } -static void array_print(const vtype_array* x, const char* prefix) { +static void array_print(vtype_array* x, const char* prefix) { print_container_values_prefix("Array", prefix); array_foreach(x, 0, array_value_print); put_separator(); diff --git a/tests/src/map/main.c b/tests/src/map/main.c index a0638f1..f08ef64 100644 --- a/tests/src/map/main.c +++ b/tests/src/map/main.c @@ -3,11 +3,11 @@ #include "plug.h" -vtype_map* map_duplicate(const vtype_map* x) { return 0; } -int map_compare(const vtype_map* s0, const vtype_map* s1) { return random_int8(); } -void map_free(vtype_map* x) {} - - int main(int argc, char** argv) { test_init(argc, argv); + + map_t x = map_random(36, 0.1); + + while(map_remove_random(&x, 0.1)) {} + map_free(&x); } diff --git a/tests/src/map/plug.h b/tests/src/map/plug.h index 093107c..2ea8ee7 100644 --- a/tests/src/map/plug.h +++ b/tests/src/map/plug.h @@ -1,7 +1,7 @@ /* This software is licensed by the MIT License, see LICENSE file */ /* Copyright © 2022 Gregory Lirent */ -#include "../../../include/map.h" +#include "../../../src/map/include.h" #include "../../include/random.h" #include "../../include/test.h" @@ -21,3 +21,200 @@ int string_compare(const vtype_string* s0, const vtype_string* s1) { return rand int array_compare (const vtype_array* s0, const vtype_array* s1) { return random_int8(); } int list_compare (const vtype_list* s0, const vtype_list* s1) { return random_int8(); } int vset_compare (const vtype_set* s0, const vtype_set* s1) { return random_int8(); } + + +static int map_node_print(const void* k, vtype kt, void* v, vtype vt, void* _) { + printf(" \e[31m%24s\e[m \e[36m:\e[m", vtype_stringify(k, kt)); + printf(" \e[31m%s\e[m", vtype_stringify(v, vt)); + printf(" \e[36m(\e[m\e[32;1m%s\e[m\e[36m)\e[m\n", vtype_name(vt)); + return 0; +} + +static void map_print(map_t* x, const char* prefix) { + print_container_values_prefix("Map", prefix); + map_foreach(x, 0, map_node_print); + put_separator(); +} + +static void map_info(const map_t* x) { + print_container_info("Map", "nodes", &x->type, map_size(x), -1); + put_separator(); +} + +static void map_rbtree_print(const mnode_t* s, vtype t, const char* ind, bool br) { + if (!ind) { + ind = "\e[36m"; + br = 1; + } + + size_t n = strlen(ind); + char x[n + 10]; + + if (mnode_is_empty(s)) return; + + memcpy(x, ind, n); + memcpy(x + n, " \0 ", 9); + fputs(ind, stdout); + + if (br) { + fputs("\e[m\e[36;1mR\e[m\e[36m────\e[m", stdout); + } else { + fputs("\e[m\e[36;1mL\e[m\e[36m────\e[m", stdout); + memcpy(x + n, "│", 3); + x[n + 5] = ' '; + } + + fputs((s->colored) ? "\e[31;1m" : "\e[37m", stdout); + printf("%s\e[m \e[36m:\e[m ", vnode_stringify(&s->key, t)); + printf("\e[31m%s\e[m", vnode_stringify(&s->value, s->type)); + printf(" \e[36m(\e[m\e[32;1m%s\e[m\e[36m)\e[m\n", vtype_name(s->type)); + + map_rbtree_print(s->left, t, x, false); + map_rbtree_print(s->right, t, x, true); +} + +static void map_push_random(map_t* x, double pause) { + var_t _[2]; + vtype t[2]; + + printf("\e[s\e[36mUpdate value in map (\e[m\e[32;1m%s\e[m\e[36m)\e[m:\n", vtype_name(x->type)); + + switch (random_uint8()%13) { + default: + case 0: _[0].b = random_boolean(); print_container_value(0, _, t[0] = VTYPE_BOOLEAN, 1); break; + case 1: _[0].u8 = random_uint8(); print_container_value(0, _, t[0] = VTYPE_UINT8, 1); break; + case 2: _[0].u16 = random_uint16(); print_container_value(0, _, t[0] = VTYPE_UINT16, 1); break; + case 3: _[0].u32 = random_uint32(); print_container_value(0, _, t[0] = VTYPE_UINT32, 1); break; + case 4: _[0].u64 = random_uint64(); print_container_value(0, _, t[0] = VTYPE_UINT64, 1); break; + case 5: _[0].u8 = random_int8(); print_container_value(0, _, t[0] = VTYPE_INT8, 1); break; + case 6: _[0].u16 = random_int16(); print_container_value(0, _, t[0] = VTYPE_INT16, 1); break; + case 7: _[0].u32 = random_int32(); print_container_value(0, _, t[0] = VTYPE_INT32, 1); break; + case 8: _[0].u64 = random_int64(); print_container_value(0, _, t[0] = VTYPE_INT64, 1); break; + case 9: _[0].f = random_float(); print_container_value(0, _, t[0] = VTYPE_FLOAT, 1); break; + case 10: _[0].d = random_double(); print_container_value(0, _, t[0] = VTYPE_DOUBLE, 1); break; + case 11: _[0].ld = random_ldouble(); print_container_value(0, _, t[0] = VTYPE_LDOUBLE, 1); break; + + case 12: if (sizeof(void*) == 8) { + _[0].u64 = random_uint64(); print_container_value(0, _, t[0] = VTYPE_POINTER, 1); break; + } else { + _[0].u32 = random_uint32(); print_container_value(0, _, t[0] = VTYPE_POINTER, 1); break; + } + } + + switch (random_uint8()%13) { + default: + case 0: _[1].b = random_boolean(); print_container_value(0, _+1, t[1] = VTYPE_BOOLEAN, 1); break; + case 1: _[1].u8 = random_uint8(); print_container_value(0, _+1, t[1] = VTYPE_UINT8, 1); break; + case 2: _[1].u16 = random_uint16(); print_container_value(0, _+1, t[1] = VTYPE_UINT16, 1); break; + case 3: _[1].u32 = random_uint32(); print_container_value(0, _+1, t[1] = VTYPE_UINT32, 1); break; + case 4: _[1].u64 = random_uint64(); print_container_value(0, _+1, t[1] = VTYPE_UINT64, 1); break; + case 5: _[1].u8 = random_int8(); print_container_value(0, _+1, t[1] = VTYPE_INT8, 1); break; + case 6: _[1].u16 = random_int16(); print_container_value(0, _+1, t[1] = VTYPE_INT16, 1); break; + case 7: _[1].u32 = random_int32(); print_container_value(0, _+1, t[1] = VTYPE_INT32, 1); break; + case 8: _[1].u64 = random_int64(); print_container_value(0, _+1, t[1] = VTYPE_INT64, 1); break; + case 9: _[1].f = random_float(); print_container_value(0, _+1, t[1] = VTYPE_FLOAT, 1); break; + case 10: _[1].d = random_double(); print_container_value(0, _+1, t[1] = VTYPE_DOUBLE, 1); break; + case 11: _[1].ld = random_ldouble(); print_container_value(0, _+1, t[1] = VTYPE_LDOUBLE, 1); break; + + case 12: if (sizeof(void*) == 8) { + _[1].u64 = random_uint64(); print_container_value(0, _+1, t[1] = VTYPE_POINTER, 1); break; + } else { + _[1].u32 = random_uint32(); print_container_value(0, _+1, t[1] = VTYPE_POINTER, 1); break; + } + } + + if (libcdsb_map_update(x, _, t[0], _+1, t[1])) { + puts("\e[33;1mCHANGE\e[m"); + } else { + puts("\e[32;1mINSERT\e[m"); + } + + put_separator(); + + map_rbtree_print(x->root, x->type, 0, 0); + put_separator(); + psleep(pause * 1000000); + fputs("\e[u\e[J", stdout); +} + +static int map_node_remove_random(const void* k, vtype kt, void* v, vtype vt, void* data) { + struct { + size_t n; + map_t* set; + double pause; + } *d = data; + + if (!d->n--) { + map_node_print(k, kt, v, vt, 0); + + if (libcdsb_map_find(0, d->set, k, kt, 1)) { + puts("\e[32;1mSUCCESS\e[m"); + } else { + puts("\e[s\e[31;1mFAILURE\e[m"); + abort(); + } + + put_separator(); + + map_rbtree_print(d->set->root, d->set->type, 0, 0); + put_separator(); + psleep(d->pause * 1000000); + + return true; + } + return 0; +} + + +static bool map_remove_random(map_t* x, double pause) { + struct { + size_t n; + map_t* set; + double pause; + } d; + d.n = map_size(x); + d.set = x; + d.pause = pause; + + printf("\e[s\e[36mTry to remove value from map (\e[m\e[32;1m%s\e[m\e[36m)\e[m:\n", libcdsb_vtype_name(x->type)); + + if (d.n) { + d.n = random_uint32()%d.n; + } else goto end_; + + if (!map_foreach(x, &d, map_node_remove_random)) { + end_: + puts("\e[u\e[J\e[32;1mMap is empty\e[m"); + return false; + } + + fputs("\e[u\e[J", stdout); + return true; +} + +static map_t map_random(unsigned int n, double pause) { + map_t x; + + switch (random_uint8()%12) { + default: + case 0: map_init(&x, VTYPE_UINT8); break; + case 1: map_init(&x, VTYPE_UINT16); break; + case 2: map_init(&x, VTYPE_UINT32); break; + case 3: map_init(&x, VTYPE_UINT64); break; + case 4: map_init(&x, VTYPE_INT8); break; + case 5: map_init(&x, VTYPE_INT16); break; + case 6: map_init(&x, VTYPE_INT32); break; + case 7: map_init(&x, VTYPE_INT64); break; + case 8: map_init(&x, VTYPE_POINTER); break; + case 9: map_init(&x, VTYPE_FLOAT); break; + case 10: map_init(&x, VTYPE_DOUBLE); break; + case 11: map_init(&x, VTYPE_LDOUBLE); break; + } + + if (n) { + while (--n) map_push_random(&x, pause); + map_push_random(&x, pause); + } + + return x; +} diff --git a/tests/src/set/main.c b/tests/src/set/main.c index d6bd747..be56d43 100644 --- a/tests/src/set/main.c +++ b/tests/src/set/main.c @@ -6,7 +6,7 @@ int main(int argc, char** argv) { test_init(argc, argv); - vtype_set x = vset_random(36, 0.1); + set_t x = vset_random(36, 0.1); while(vset_remove_random(&x, 0.1)) {} vset_free(&x); diff --git a/tests/src/set/plug.h b/tests/src/set/plug.h index 68265d3..fd4e092 100644 --- a/tests/src/set/plug.h +++ b/tests/src/set/plug.h @@ -29,7 +29,7 @@ static int vset_node_print(const void* v, vtype t, void* _) { return 0; } -static void vset_print(const set_t* x, const char* prefix) { +static void vset_print(set_t* x, const char* prefix) { print_container_values_prefix("Set", prefix); vset_foreach(x, 0, vset_node_print); put_separator();