Compare commits
3 Commits
557a43e265
...
d5c745f8e1
Author | SHA1 | Date | |
---|---|---|---|
d5c745f8e1 | |||
eaecb59ba8 | |||
a0f2f48ef2 |
8
Makefile
8
Makefile
@ -19,9 +19,13 @@ $(EXEC_NAME): filter $(OBJS)
|
||||
|
||||
debug: debug_flag $(EXEC_NAME)
|
||||
|
||||
test: filter_test $(OBJS)
|
||||
$(CC) $(FLAGS) $(LIBS) -lcmocka $(OBJS) -o test
|
||||
test: compile_test run_test
|
||||
|
||||
compile_test: filter_test $(OBJS)
|
||||
$(CC) $(DEBUG_FLAGS) $(LIBS) -lcmocka $(OBJS) -o test
|
||||
|
||||
run_test:
|
||||
./test
|
||||
|
||||
$(OBJDIR)/%.o: $(SRCDIR)/%$(EXT)
|
||||
$(CC) $(FLAGS) $(DEPFLAGS) -c -o $@ $<
|
||||
|
189
src/tests.c
189
src/tests.c
@ -5,6 +5,10 @@
|
||||
#include <setjmp.h>
|
||||
#include <cmocka.h>
|
||||
|
||||
// store a copy of the nodes created in test2_setup, to check if any
|
||||
// of the tests modified them
|
||||
static PtrArray test_group2_nodes_copy = {0};
|
||||
|
||||
static void test_wm_treenode_new(void **state)
|
||||
{
|
||||
TreeNode *node = wm_treenode_new(NODE_VERTICAL, NULL);
|
||||
@ -108,14 +112,195 @@ static void test_wm_all_nodes_to_ptrarray(void **state)
|
||||
wm_ptrarray_free(&all_nodes);
|
||||
}
|
||||
|
||||
static void test_wm_postorder_traversal(void **state)
|
||||
{
|
||||
TreeNode *node1 = (TreeNode*)*state;
|
||||
|
||||
PtrArray postorder = wm_postorder_traversal(node1);
|
||||
TreeNode **postorder_nodes = (TreeNode**)postorder.ptrs;
|
||||
|
||||
assert_int_equal(postorder.size, 8);
|
||||
|
||||
assert_int_equal(postorder_nodes[0]->id, 4);
|
||||
assert_int_equal(postorder_nodes[1]->id, 5);
|
||||
assert_int_equal(postorder_nodes[2]->id, 6);
|
||||
assert_int_equal(postorder_nodes[3]->id, 2);
|
||||
assert_int_equal(postorder_nodes[4]->id, 7);
|
||||
assert_int_equal(postorder_nodes[5]->id, 8);
|
||||
assert_int_equal(postorder_nodes[6]->id, 3);
|
||||
assert_int_equal(postorder_nodes[7]->id, 1);
|
||||
|
||||
wm_ptrarray_free(&postorder);
|
||||
}
|
||||
|
||||
static void test_wm_treenode_lmd(void **state)
|
||||
{
|
||||
TreeNode *node1 = (TreeNode*)*state;
|
||||
TreeNode *node2 = node1->children.nodes[0];
|
||||
TreeNode *node3 = node1->children.nodes[1];
|
||||
TreeNode *node4 = node2->children.nodes[0];
|
||||
TreeNode *node5 = node2->children.nodes[1];
|
||||
TreeNode *node6 = node2->children.nodes[2];
|
||||
TreeNode *node7 = node3->children.nodes[0];
|
||||
TreeNode *node8 = node3->children.nodes[1];
|
||||
|
||||
assert_int_equal(wm_treenode_lmd(node1)->id, node4->id);
|
||||
assert_int_equal(wm_treenode_lmd(node2)->id, node4->id);
|
||||
assert_int_equal(wm_treenode_lmd(node3)->id, node7->id);
|
||||
assert_int_equal(wm_treenode_lmd(node4)->id, node4->id);
|
||||
assert_int_equal(wm_treenode_lmd(node5)->id, node5->id);
|
||||
assert_int_equal(wm_treenode_lmd(node6)->id, node6->id);
|
||||
assert_int_equal(wm_treenode_lmd(node7)->id, node7->id);
|
||||
assert_int_equal(wm_treenode_lmd(node8)->id, node8->id);
|
||||
}
|
||||
|
||||
static void test_wm_is_treenode_keyroot(void **state)
|
||||
{
|
||||
TreeNode *node1 = (TreeNode*)*state;
|
||||
|
||||
PtrArray postorder = wm_postorder_traversal(node1);
|
||||
TreeNode **postorder_nodes = (TreeNode**)postorder.ptrs;
|
||||
|
||||
assert_int_equal(postorder.size, 8);
|
||||
|
||||
assert_int_equal(wm_is_treenode_keyroot(postorder_nodes[0]), false);
|
||||
assert_int_equal(wm_is_treenode_keyroot(postorder_nodes[1]), true);
|
||||
assert_int_equal(wm_is_treenode_keyroot(postorder_nodes[2]), true);
|
||||
assert_int_equal(wm_is_treenode_keyroot(postorder_nodes[3]), false);
|
||||
assert_int_equal(wm_is_treenode_keyroot(postorder_nodes[4]), false);
|
||||
assert_int_equal(wm_is_treenode_keyroot(postorder_nodes[5]), true);
|
||||
assert_int_equal(wm_is_treenode_keyroot(postorder_nodes[6]), true);
|
||||
assert_int_equal(wm_is_treenode_keyroot(postorder_nodes[7]), true);
|
||||
|
||||
wm_ptrarray_free(&postorder);
|
||||
}
|
||||
|
||||
static void test_wm_treenode_all_lmds(void **state)
|
||||
{
|
||||
TreeNode *node1 = (TreeNode*)*state;
|
||||
|
||||
PtrArray ret = wm_treenode_all_lmds(node1);
|
||||
TreeNode **lmds = (TreeNode**)ret.ptrs;
|
||||
|
||||
assert_int_equal(ret.size, 8);
|
||||
|
||||
assert_int_equal(lmds[0]->id, 4);
|
||||
assert_int_equal(lmds[1]->id, 5);
|
||||
assert_int_equal(lmds[2]->id, 6);
|
||||
assert_int_equal(lmds[3]->id, 4);
|
||||
assert_int_equal(lmds[4]->id, 7);
|
||||
assert_int_equal(lmds[5]->id, 8);
|
||||
assert_int_equal(lmds[6]->id, 7);
|
||||
assert_int_equal(lmds[7]->id, 4);
|
||||
|
||||
wm_ptrarray_free(&ret);
|
||||
}
|
||||
|
||||
static int test2_setup(void **state)
|
||||
{
|
||||
TreeNode *node1 = wm_treenode_new(NODE_VERTICAL, NULL);
|
||||
TreeNode *node2 = wm_treenode_new(NODE_VERTICAL, node1);
|
||||
TreeNode *node3 = wm_treenode_new(NODE_VERTICAL, node1);
|
||||
TreeNode *node4 = wm_treenode_new(NODE_VERTICAL, node2);
|
||||
TreeNode *node5 = wm_treenode_new(NODE_VERTICAL, node2);
|
||||
TreeNode *node6 = wm_treenode_new(NODE_VERTICAL, node2);
|
||||
TreeNode *node7 = wm_treenode_new(NODE_VERTICAL, node3);
|
||||
TreeNode *node8 = wm_treenode_new(NODE_VERTICAL, node3);
|
||||
|
||||
wm_nodearray_push(&node1->children, node2);
|
||||
wm_nodearray_push(&node1->children, node3);
|
||||
wm_nodearray_push(&node2->children, node4);
|
||||
wm_nodearray_push(&node2->children, node5);
|
||||
wm_nodearray_push(&node2->children, node6);
|
||||
wm_nodearray_push(&node3->children, node7);
|
||||
wm_nodearray_push(&node3->children, node8);
|
||||
|
||||
node1->id = 1;
|
||||
node2->id = 2;
|
||||
node3->id = 3;
|
||||
node4->id = 4;
|
||||
node5->id = 5;
|
||||
node6->id = 6;
|
||||
node7->id = 7;
|
||||
node8->id = 8;
|
||||
|
||||
assert_null(node1->parent);
|
||||
assert_ptr_equal(node2->parent, node1);
|
||||
assert_ptr_equal(node3->parent, node1);
|
||||
assert_ptr_equal(node4->parent, node2);
|
||||
assert_ptr_equal(node5->parent, node2);
|
||||
assert_ptr_equal(node6->parent, node2);
|
||||
assert_ptr_equal(node7->parent, node3);
|
||||
assert_ptr_equal(node8->parent, node3);
|
||||
|
||||
assert_int_equal(node1->children.size, 2);
|
||||
assert_int_equal(node2->children.size, 3);
|
||||
assert_int_equal(node3->children.size, 2);
|
||||
|
||||
assert_int_equal(node1->id, 1);
|
||||
assert_int_equal(node1->children.nodes[0]->id, 2);
|
||||
assert_int_equal(node1->children.nodes[1]->id, 3);
|
||||
assert_int_equal(node2->children.nodes[0]->id, 4);
|
||||
assert_int_equal(node2->children.nodes[1]->id, 5);
|
||||
assert_int_equal(node2->children.nodes[2]->id, 6);
|
||||
assert_int_equal(node3->children.nodes[0]->id, 7);
|
||||
assert_int_equal(node3->children.nodes[1]->id, 8);
|
||||
|
||||
*state = node1;
|
||||
|
||||
PtrArray nodes = wm_all_nodes_to_ptrarray((TreeNode*)*state);
|
||||
|
||||
PtrArray nodes_copy = wm_ptrarray_new();
|
||||
for (size_t i = 0; i < nodes.size; i++) {
|
||||
TreeNode *node_copy = malloc(sizeof(TreeNode));
|
||||
*node_copy = *((TreeNode**)nodes.ptrs)[i];
|
||||
wm_ptrarray_push(&nodes_copy, node_copy);
|
||||
}
|
||||
|
||||
test_group2_nodes_copy = nodes_copy;
|
||||
|
||||
wm_ptrarray_free(&nodes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test2_teardown(void **state)
|
||||
{
|
||||
PtrArray nodes = wm_all_nodes_to_ptrarray((TreeNode*)*state);
|
||||
|
||||
// check if any of the original nodes were modified
|
||||
for (size_t i = 0; i < test_group2_nodes_copy.size; i++) {
|
||||
TreeNode *node_copy = ((TreeNode**)test_group2_nodes_copy.ptrs)[i];
|
||||
assert_memory_equal(node_copy, nodes.ptrs[i], sizeof(TreeNode));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < nodes.size; i++) {
|
||||
wm_treenode_free(nodes.ptrs[i]);
|
||||
free((TreeNode*)test_group2_nodes_copy.ptrs[i]);
|
||||
}
|
||||
|
||||
wm_ptrarray_free(&nodes);
|
||||
wm_ptrarray_free(&test_group2_nodes_copy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
const struct CMUnitTest tests[] = {
|
||||
const struct CMUnitTest test_group1[] = {
|
||||
cmocka_unit_test(test_wm_treenode_new),
|
||||
cmocka_unit_test(test_wm_nodearray_push),
|
||||
cmocka_unit_test(test_wm_find_client_nodes_ptr),
|
||||
cmocka_unit_test(test_wm_all_nodes_to_ptrarray),
|
||||
};
|
||||
|
||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
const struct CMUnitTest test_group2[] = {
|
||||
cmocka_unit_test(test_wm_postorder_traversal),
|
||||
cmocka_unit_test(test_wm_treenode_lmd),
|
||||
cmocka_unit_test(test_wm_is_treenode_keyroot),
|
||||
cmocka_unit_test(test_wm_treenode_all_lmds),
|
||||
};
|
||||
|
||||
cmocka_run_group_tests(test_group1, NULL, NULL);
|
||||
cmocka_run_group_tests(test_group2, test2_setup, test2_teardown);
|
||||
}
|
||||
|
92
src/util.c
92
src/util.c
@ -221,6 +221,98 @@ void wm_log_state(Wm *wm, const char *prefixstr, const char* logfile)
|
||||
wm_ptrarray_free(&ws_str);
|
||||
}
|
||||
|
||||
TreeNode* wm_treenode_lmd(TreeNode *node)
|
||||
{
|
||||
assert(node);
|
||||
|
||||
if (node->children.size == 0) return node;
|
||||
|
||||
return wm_treenode_lmd(node->children.nodes[0]);
|
||||
}
|
||||
|
||||
PtrArray wm_treenode_all_lmds(TreeNode *node)
|
||||
{
|
||||
assert(node);
|
||||
|
||||
PtrArray postorder = wm_postorder_traversal(node);
|
||||
PtrArray ret = wm_ptrarray_new();
|
||||
|
||||
for (size_t i = 0; i < postorder.size; i++) {
|
||||
TreeNode *lmd = wm_treenode_lmd(postorder.ptrs[i]);
|
||||
|
||||
wm_ptrarray_push(&ret, (void*)lmd);
|
||||
}
|
||||
|
||||
wm_ptrarray_free(&postorder);
|
||||
return ret;
|
||||
}
|
||||
|
||||
PtrArray wm_postorder_traversal(TreeNode *tree)
|
||||
{
|
||||
assert(tree);
|
||||
|
||||
TreeNode *root = tree;
|
||||
|
||||
typedef struct {
|
||||
TreeNode *node;
|
||||
size_t index;
|
||||
} NodeWithIndex;
|
||||
|
||||
int root_index = 0;
|
||||
|
||||
PtrArray stack = wm_ptrarray_new();
|
||||
PtrArray ret = wm_ptrarray_new();
|
||||
|
||||
while (root != NULL || stack.size > 0) {
|
||||
if (root != NULL) {
|
||||
NodeWithIndex *n = malloc(sizeof(NodeWithIndex));
|
||||
n->node = root;
|
||||
n->index = root_index;
|
||||
wm_ptrarray_push(&stack, n);
|
||||
root_index = 0;
|
||||
|
||||
if (root->children.size >= 1)
|
||||
root = root->children.nodes[0];
|
||||
else root = NULL;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
NodeWithIndex *nptr;
|
||||
wm_ptrarray_pop(&stack, (void**)&nptr);
|
||||
NodeWithIndex n = *nptr;
|
||||
free(nptr);
|
||||
wm_ptrarray_push(&ret, n.node);
|
||||
|
||||
while (stack.size > 0 && n.index == ((NodeWithIndex**)stack.ptrs)
|
||||
[stack.size-1]->node->children.size - 1) {
|
||||
wm_ptrarray_pop(&stack, (void**)&nptr);
|
||||
n = *nptr;
|
||||
free(nptr);
|
||||
|
||||
wm_ptrarray_push(&ret, n.node);
|
||||
}
|
||||
|
||||
if (stack.size > 0) {
|
||||
root = ((NodeWithIndex**)stack.ptrs)[stack.size-1]->node
|
||||
->children.nodes[n.index + 1];
|
||||
root_index = n.index + 1;
|
||||
}
|
||||
}
|
||||
|
||||
wm_ptrarray_free(&stack);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool wm_is_treenode_keyroot(TreeNode *node)
|
||||
{
|
||||
assert(node);
|
||||
if (!node->parent) return true;
|
||||
|
||||
return wm_treenode_lmd(node) != wm_treenode_lmd(node->parent);
|
||||
}
|
||||
|
||||
void wm_treenode_print(TreeNode *node)
|
||||
{
|
||||
char *str = wm_treenode_to_str(node);
|
||||
|
@ -89,7 +89,6 @@ bool wm_nodearray_remove(NodeArray *arr, size_t index);
|
||||
void __wm_nodearray_free(NodeArray *arr);
|
||||
ClientArray wm_nodearray_find_clients(TreeNode *root);
|
||||
|
||||
|
||||
PtrArray wm_ptrarray_new();
|
||||
void wm_ptrarray_push(PtrArray *arr, void* ptr);
|
||||
bool wm_ptrarray_pop(PtrArray *arr, void **ret);
|
||||
@ -103,6 +102,11 @@ TreeNode* wm_treenode_split_get_sibling(TreeNode *node);
|
||||
PtrArray wm_all_nodes_to_ptrarray(TreeNode *root);
|
||||
void wm_log_state(Wm *wm, const char *prefixstr, const char* logfile);
|
||||
|
||||
TreeNode* wm_treenode_lmd(TreeNode *node);
|
||||
PtrArray wm_treenode_all_lmds(TreeNode *node);
|
||||
PtrArray wm_postorder_traversal(TreeNode *tree);
|
||||
bool wm_is_treenode_keyroot(TreeNode *node);
|
||||
|
||||
ClientArray wm_clientarray_new();
|
||||
void wm_clientarray_push(ClientArray *arr, Client node);
|
||||
bool wm_clientarray_pop(ClientArray *arr, Client *ret);
|
||||
|
Loading…
x
Reference in New Issue
Block a user