summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/map.c60
-rw-r--r--tests/sptree.c68
-rw-r--r--tests/spvec.c84
-rw-r--r--tests/test.h16
-rw-r--r--tests/vec.c73
5 files changed, 282 insertions, 19 deletions
diff --git a/tests/map.c b/tests/map.c
index 6c42787..9af0b01 100644
--- a/tests/map.c
+++ b/tests/map.c
@@ -1,37 +1,79 @@
#include <assert.h>
#include <stdio.h>
+#include "test.h"
+/* required defs */
#define MAP_KEY int
#define MAP_TYPE int
-#define MAP_HASH(a) CONTS_MAP_NO_HASH(a)
+#define MAP_HASH(a) ints_generic_hash(&(a))
#define MAP_CMP(a, b) ((a) - (b))
#define MAP_NAME ints
+
+/* optional defs */
+#define MAP_MALLOC mallocc
+#define MAP_CALLOC callocc
+#define MAP_REALLOC reallocc
+#define MAP_FREE free
+
#include <conts/map.h>
int main()
{
+#if defined(COVERAGE)
+ assert(!covsrv_init());
+ atexit(covsrv_destroy);
+#endif
+
/* heuristic, but if we know how many elements we'll need, we should
* give it to the create function. */
- struct ints ints = ints_create(0);
- for (int i = 0; i < 1000000; ++i) {
- ints_insert(&ints, i, i);
+ struct ints ints = ints_create(10);
+
+ /* check that trying to search for something in an empty map doesn*t
+ * crash */
+ assert(ints_find(&ints, 0) == NULL);
+
+ /* similarly, iterating an empty map doesn't do anything */
+ foreach(ints, iter, &ints) {
+ assert(false && "iterating empty map");
}
- assert(ints_len(&ints) == 1000000);
- for (int i = 0; i < 1000000; ++i) {
+ for (int i = 0; i < ITER; ++i) {
+ if (!ints_insert(&ints, i, i)) {
+ fprintf(stderr, "failed inserting %d\n", i);
+ ints_destroy(&ints);
+ return -1;
+ }
+ }
+ assert(ints_len(&ints) == ITER);
+
+
+ for (int i = 0; i < ITER; ++i) {
int *v = ints_find(&ints, i);
assert(v && *v == i);
}
+ /* check that trying to find something that doesn't exist doesn't crash */
+ assert(ints_find(&ints, 123456789) == NULL);
+
+ /* check that trying to remove something that doesn't exist is a noop */
+ size_t len = ints_len(&ints);
+ ints_remove(&ints, 123456789);
+ assert(ints_len(&ints) == len);
+
+ /* check that trying to insert 0 again gets us the existing 0 */
+ int *orig = ints_find(&ints, 0);
+ int *new = ints_insert(&ints, 0, 0);
+ assert(orig == new);
+
size_t count = 0;
foreach(ints, iter, &ints) {
- assert(iter->key == iter->data);
+ assert(iter.t->key == iter.t->data);
count++;
}
- assert(count == 1000000);
+ assert(count == ITER);
- for (int i = 0; i < 1000000; ++i) {
+ for (int i = 0; i < ITER; ++i) {
ints_remove(&ints, i);
}
diff --git a/tests/sptree.c b/tests/sptree.c
index b8d1e5a..3499d61 100644
--- a/tests/sptree.c
+++ b/tests/sptree.c
@@ -1,24 +1,57 @@
#include <assert.h>
+#include <stdlib.h>
#include <stdio.h>
+#include "test.h"
+/* required defs */
#define SPTREE_TYPE int
#define SPTREE_CMP(a, b) ((b) - (a))
#define SPTREE_NAME ints
+
+/* optional defs */
+#define SPTREE_MALLOC mallocc
+#define SPTREE_CALLOC callocc
+#define SPTREE_REALLOC reallocc
+#define SPTREE_FREE free
+
#include <conts/sptree.h>
+#define RANDITER (ITER / 100)
+
+int inserted[RANDITER];
+
int main()
{
+#if defined(COVERAGE)
+ assert(!covsrv_init());
+ atexit(covsrv_destroy);
+#endif
+
struct ints ints = ints_create();
- for (int i = 0; i < 1000000; ++i) {
- ints_insert(&ints, i);
+ /* check that iterating an empty tree doesn't do anything */
+ foreach(ints, iter, &ints) {
+ assert(false && "iterating empty tree");
}
- assert(ints_len(&ints) == 1000000);
- for (int i = 0; i < 1000000; ++i) {
+ for (int i = 0; i < ITER; ++i) {
+ if (!ints_insert(&ints, i)) {
+ fprintf(stderr, "failed inserting %d\n", i);
+ ints_destroy(&ints);
+ return -1;
+ }
+ }
+ assert(ints_len(&ints) == ITER);
+
+ for (int i = 0; i < ITER; ++i) {
int *v = ints_find(&ints, i);
assert(v && *v == i);
}
+ /* check that inserting duplicate returns the original */
+ int *orig = ints_find(&ints, 0);
+ ints_insert(&ints, 0);
+ assert(ints_find(&ints, 0) == orig);
+
int i = 0;
foreach(ints, iter, &ints) {
/* since my trees are ordered, this must hold, although you
@@ -28,10 +61,35 @@ int main()
i++;
}
- for (int i = 0; i < 1000000; ++i) {
+ for (int i = 0; i < ITER; ++i) {
ints_remove(&ints, i);
}
assert(ints_len(&ints) == 0);
+
+ /* check that removing nonexistant item (or empty tree) doesn't crash */
+ ints_remove(&ints, 0);
+
+ /* insert random integers to hopefully exercise the code a bit more */
+ srand(0);
+
+ for (int i = 0; i < RANDITER; ++i) {
+ inserted[i] = rand();
+
+ /* covsrv shouldn't fail anymore */
+ assert(ints_insert(&ints, inserted[i]));
+ }
+
+ for (int i = 0; i < RANDITER; ++i) {
+ int *v = ints_find(&ints, inserted[i]);
+ assert(v && *v == inserted[i]);
+ }
+
+ for (int i = 0; i < RANDITER; ++i) {
+ ints_remove(&ints, inserted[i]);
+ }
+
+ assert(ints_len(&ints) == 0);
+
ints_destroy(&ints);
}
diff --git a/tests/spvec.c b/tests/spvec.c
new file mode 100644
index 0000000..b169884
--- /dev/null
+++ b/tests/spvec.c
@@ -0,0 +1,84 @@
+#include <stdio.h>
+#include <assert.h>
+#include "test.h"
+
+/* required defs */
+#define SPVEC_TYPE int
+#define SPVEC_NAME ints
+
+/* optional defs */
+#define SPVEC_MALLOC mallocc
+#define SPVEC_CALLOC callocc
+#define SPVEC_REALLOC reallocc
+#define SPVEC_FREE free
+
+#include <conts/spvec.h>
+
+int main()
+{
+#if defined(COVERAGE)
+ assert(!covsrv_init());
+ atexit(covsrv_destroy);
+#endif
+ struct ints ints = ints_create();
+ foreach(ints, iter, &ints) {
+ assert(false && "iterating empty spvec");
+ }
+
+ /* ensure stability before we do anything else */
+ assert(ints_reserve(&ints, 1));
+ int *p = ints_at(&ints, 0);
+
+ /* should allocate at least a few extra buckets */
+ assert(ints_reserve(&ints, 256));
+ assert(p == ints_at(&ints, 0));
+
+ /* test out resetting as well while we're at it*/
+ assert(ints_len(&ints) == 256);
+ ints_reset(&ints);
+ assert(ints_len(&ints) == 0);
+
+ for (int i = 0; i < ITER; ++i) {
+ if (!ints_append(&ints, i)) {
+ fprintf(stderr, "failed appending %d to vec\n", i);
+ ints_destroy(&ints);
+ return -1;
+ }
+ }
+ assert(ints_len(&ints) == ITER);
+
+ for (int i = 0; i < ITER; ++i) {
+ int *v = ints_at(&ints, i);
+ assert(v && *v == i);
+ }
+
+ int i = 0;
+ foreach(ints, iter, &ints) {
+ assert(iter.v && *iter.v == i);
+ i++;
+ }
+
+ /* TEN million !!1! */
+ if (!ints_reserve(&ints, 10 * ITER)) {
+ fprintf(stderr, "failed reserving vec\n");
+ ints_destroy(&ints);
+ return -1;
+ }
+
+ /* set size back to keep test runtime reasonable
+ * (is shrink necessary when we already have reserve? I
+ * guess it shows intention a bit better and just asserts instead of
+ * maybe fails?) */
+ ints_shrink(&ints, ITER);
+
+ /* so the above is equivalent to */
+ assert(ints_reserve(&ints, ITER));
+ assert(ints_len(&ints) == ITER);
+
+ for (int i = ITER - 1; i >= 0; --i) {
+ ints_remove(&ints, i);
+ }
+ assert(ints_len(&ints) == 0);
+
+ ints_destroy(&ints);
+}
diff --git a/tests/test.h b/tests/test.h
new file mode 100644
index 0000000..ea50db0
--- /dev/null
+++ b/tests/test.h
@@ -0,0 +1,16 @@
+#ifndef TEST_H
+#define TEST_H
+
+#include <covsrv/covsrv.h>
+
+#define cover_ptr(name, ...) ({covsrv_die() ? NULL : name (__VA_ARGS__);})
+
+#define mallocc(...) cover_ptr(malloc, __VA_ARGS__)
+#define callocc(...) cover_ptr(calloc, __VA_ARGS__)
+#define reallocc(...) cover_ptr(realloc, __VA_ARGS__)
+
+#ifndef ITER
+#define ITER 1000000
+#endif
+
+#endif /* TEST_H */
diff --git a/tests/vec.c b/tests/vec.c
index a84096c..09a8deb 100644
--- a/tests/vec.c
+++ b/tests/vec.c
@@ -1,18 +1,47 @@
+#include <stdio.h>
#include <assert.h>
+#include "test.h"
+/* required defs */
#define VEC_TYPE int
#define VEC_NAME ints
+
+/* optional defs */
+#define VEC_MALLOC mallocc
+#define VEC_CALLOC callocc
+#define VEC_REALLOC reallocc
+#define VEC_FREE free
+
#include <conts/vec.h>
+/* used for sorting testing */
+static int int_comp(int *a, int *b)
+{
+ return *a - *b;
+}
+
int main()
{
+#if defined(COVERAGE)
+ assert(!covsrv_init());
+ atexit(covsrv_destroy);
+#endif
+
struct ints ints = ints_create(0);
- for (int i = 0; i < 1000000; ++i) {
- ints_append(&ints, i);
+ foreach(ints, iter, &ints) {
+ assert(false && "iterating empty vec");
}
- assert(ints_len(&ints) == 1000000);
- for (int i = 0; i < 1000000; ++i) {
+ for (int i = 0; i < ITER; ++i) {
+ if (!ints_append(&ints, i)) {
+ fprintf(stderr, "failed appending %d to vec\n", i);
+ ints_destroy(&ints);
+ return -1;
+ }
+ }
+ assert(ints_len(&ints) == ITER);
+
+ for (int i = 0; i < ITER; ++i) {
int *v = ints_at(&ints, i);
assert(v && *v == i);
}
@@ -23,10 +52,44 @@ int main()
i++;
}
- for (int i = 1000000 - 1; i >= 0; --i) {
+ if (!ints_reserve(&ints, 10 * ITER)) {
+ fprintf(stderr, "failed reserving vec\n");
+ ints_destroy(&ints);
+ return -1;
+ }
+
+ /* set size back to keep test runtime reasonable
+ * (is shrink necessary when we already have reserve? I
+ * guess it shows intention a bit better and just asserts instead of
+ * maybe fails?) */
+ ints_shrink(&ints, ITER);
+
+ /* so the above is equivalent to */
+ assert(ints_reserve(&ints, ITER));
+ assert(ints_len(&ints) == ITER);
+
+ for (int i = ITER - 1; i >= 0; --i) {
ints_remove(&ints, i);
}
assert(ints_len(&ints) == 0);
+ /* test out resetting as well */
+ assert(ints_reserve(&ints, 10));
+ assert(ints_len(&ints) == 10);
+
+ ints_reset(&ints);
+ assert(ints_len(&ints) == 0);
+
+ /* try out sorting and special accesses */
+ ints_append(&ints, 3);
+ ints_append(&ints, 2);
+ ints_append(&ints, 1);
+
+ ints_sort(&ints, int_comp);
+
+ assert(*ints_back(&ints) == 3);
+ assert(*ints_pop(&ints) == 3);
+ assert(*ints_back(&ints) == 2);
+
ints_destroy(&ints);
}