200 lines
5.0 KiB
C
200 lines
5.0 KiB
C
#include "blue/core/misc.h"
|
|
|
|
#include <CuTest.h>
|
|
#include <blue/core/btree.h>
|
|
#include <blue/core/queue.h>
|
|
#include <blue/core/stringstream.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
|
|
struct test_tree_node {
|
|
int value;
|
|
b_btree_node node;
|
|
};
|
|
|
|
struct test_queue_entry {
|
|
int value;
|
|
b_queue_entry entry;
|
|
};
|
|
|
|
B_BTREE_DEFINE_SIMPLE_INSERT(struct test_tree_node, node, value, test_tree_insert);
|
|
|
|
void test_btree_insert(CuTest *tc)
|
|
{
|
|
b_btree tree = {0};
|
|
struct test_tree_node nodes[3] = {0};
|
|
|
|
for (int i = 0; i < sizeof nodes / sizeof *nodes; i++) {
|
|
nodes[i].value = i;
|
|
}
|
|
|
|
test_tree_insert(&tree, &nodes[0]);
|
|
|
|
CuAssertPtrEquals(tc, NULL, nodes[0].node.b_left);
|
|
CuAssertPtrEquals(tc, NULL, nodes[0].node.b_right);
|
|
CuAssertIntEquals(tc, 1, nodes[0].node.b_height);
|
|
|
|
test_tree_insert(&tree, &nodes[1]);
|
|
|
|
CuAssertPtrEquals(tc, NULL, nodes[0].node.b_left);
|
|
CuAssertPtrEquals(tc, &nodes[1].node, nodes[0].node.b_right);
|
|
CuAssertIntEquals(tc, 2, nodes[0].node.b_height);
|
|
|
|
CuAssertPtrEquals(tc, NULL, nodes[1].node.b_left);
|
|
CuAssertPtrEquals(tc, NULL, nodes[1].node.b_right);
|
|
CuAssertIntEquals(tc, 1, nodes[1].node.b_height);
|
|
|
|
test_tree_insert(&tree, &nodes[2]);
|
|
|
|
CuAssertPtrEquals(tc, &nodes[0].node, nodes[1].node.b_left);
|
|
CuAssertPtrEquals(tc, &nodes[2].node, nodes[1].node.b_right);
|
|
CuAssertIntEquals(tc, 2, nodes[1].node.b_height);
|
|
|
|
CuAssertPtrEquals(tc, NULL, nodes[0].node.b_left);
|
|
CuAssertPtrEquals(tc, NULL, nodes[0].node.b_right);
|
|
CuAssertIntEquals(tc, 1, nodes[0].node.b_height);
|
|
|
|
CuAssertPtrEquals(tc, NULL, nodes[2].node.b_left);
|
|
CuAssertPtrEquals(tc, NULL, nodes[2].node.b_right);
|
|
CuAssertIntEquals(tc, 1, nodes[2].node.b_height);
|
|
}
|
|
|
|
void test_btree_iterate(CuTest *tc)
|
|
{
|
|
static const size_t nr_nodes = 256;
|
|
srand(time(NULL));
|
|
|
|
b_btree tree = {0};
|
|
struct test_tree_node *nodes = calloc(nr_nodes, sizeof *nodes);
|
|
CuAssertPtrNotNull(tc, nodes);
|
|
|
|
for (int i = 0; i < nr_nodes; i++) {
|
|
nodes[i].value = rand();
|
|
test_tree_insert(&tree, &nodes[i]);
|
|
}
|
|
|
|
int prev = -1;
|
|
b_btree_iterator it;
|
|
b_btree_foreach (&it, &tree) {
|
|
struct test_tree_node *node
|
|
= b_unbox(struct test_tree_node, it.node, node);
|
|
CuAssertPtrNotNull(tc, node);
|
|
|
|
if (prev == -1) {
|
|
prev = node->value;
|
|
continue;
|
|
}
|
|
|
|
CuAssertTrue(tc, prev <= node->value);
|
|
prev = node->value;
|
|
}
|
|
|
|
free(nodes);
|
|
}
|
|
|
|
void test_queue_insert(CuTest *tc)
|
|
{
|
|
struct test_queue_entry entries[5] = {0};
|
|
for (int i = 0; i < sizeof entries / sizeof *entries; i++) {
|
|
entries[i].value = i;
|
|
}
|
|
|
|
b_queue q = B_QUEUE_INIT;
|
|
|
|
b_queue_push_back(&q, &entries[0].entry);
|
|
b_queue_push_back(&q, &entries[2].entry);
|
|
b_queue_push_back(&q, &entries[4].entry);
|
|
b_queue_insert_after(&q, &entries[3].entry, &entries[2].entry);
|
|
b_queue_insert_before(&q, &entries[1].entry, &entries[2].entry);
|
|
|
|
CuAssertPtrEquals(tc, NULL, entries[0].entry.qe_prev);
|
|
CuAssertPtrEquals(tc, &entries[1].entry, entries[0].entry.qe_next);
|
|
|
|
CuAssertPtrEquals(tc, &entries[0].entry, entries[1].entry.qe_prev);
|
|
CuAssertPtrEquals(tc, &entries[2].entry, entries[1].entry.qe_next);
|
|
|
|
CuAssertPtrEquals(tc, &entries[1].entry, entries[2].entry.qe_prev);
|
|
CuAssertPtrEquals(tc, &entries[3].entry, entries[2].entry.qe_next);
|
|
|
|
CuAssertPtrEquals(tc, &entries[2].entry, entries[3].entry.qe_prev);
|
|
CuAssertPtrEquals(tc, &entries[4].entry, entries[3].entry.qe_next);
|
|
|
|
CuAssertPtrEquals(tc, &entries[3].entry, entries[4].entry.qe_prev);
|
|
CuAssertPtrEquals(tc, NULL, entries[4].entry.qe_next);
|
|
}
|
|
|
|
void test_queue_iterate(CuTest *tc)
|
|
{
|
|
b_queue q = B_QUEUE_INIT;
|
|
struct test_queue_entry entries[32] = {0};
|
|
|
|
for (int i = 0; i < sizeof entries / sizeof *entries; i++) {
|
|
entries[i].value = i;
|
|
b_queue_push_back(&q, &entries[i].entry);
|
|
}
|
|
|
|
int prev = -1;
|
|
b_queue_iterator it;
|
|
b_queue_foreach (&it, &q) {
|
|
struct test_queue_entry *e
|
|
= b_unbox(struct test_queue_entry, it.entry, entry);
|
|
CuAssertPtrNotNull(tc, e);
|
|
|
|
if (prev == -1) {
|
|
prev = e->value;
|
|
continue;
|
|
}
|
|
|
|
CuAssertTrue(tc, prev < e->value);
|
|
prev = e->value;
|
|
}
|
|
}
|
|
|
|
void test_stringstream_1(CuTest *tc)
|
|
{
|
|
char buf[1024];
|
|
b_stringstream *s = b_stringstream_create_with_buffer(buf, sizeof buf);
|
|
|
|
b_stream_write_string(s, "hello", NULL);
|
|
b_stream_write_fmt(s, NULL, "(%d + %.1f)", 32, 2.3);
|
|
|
|
char *end = b_stringstream_steal(s);
|
|
b_stringstream_unref(s);
|
|
|
|
CuAssertStrEquals(tc, "hello(32 + 2.3)", end);
|
|
}
|
|
|
|
void test_stringstream_2(CuTest *tc)
|
|
{
|
|
char buf[1024];
|
|
b_stringstream *s = b_stringstream_create_with_buffer(buf, sizeof buf);
|
|
|
|
b_stream_write_string(s, "{\n", NULL);
|
|
b_stream_push_indent(s, 1);
|
|
|
|
b_stream_write_string(s, "a = 32,\n", NULL);
|
|
b_stream_write_string(s, "b = 64\n", NULL);
|
|
|
|
b_stream_pop_indent(s);
|
|
b_stream_write_string(s, "}", NULL);
|
|
|
|
char *str = b_stringstream_steal(s);
|
|
b_stringstream_unref(s);
|
|
|
|
CuAssertStrEquals(tc, "{\n a = 32,\n b = 64\n}", str);
|
|
}
|
|
|
|
CuSuite *get_all_tests(void)
|
|
{
|
|
CuSuite *suite = CuSuiteNew();
|
|
|
|
SUITE_ADD_TEST(suite, test_btree_insert);
|
|
SUITE_ADD_TEST(suite, test_btree_iterate);
|
|
SUITE_ADD_TEST(suite, test_queue_insert);
|
|
SUITE_ADD_TEST(suite, test_queue_iterate);
|
|
SUITE_ADD_TEST(suite, test_stringstream_1);
|
|
SUITE_ADD_TEST(suite, test_stringstream_2);
|
|
|
|
return suite;
|
|
}
|