END_TEST START_TEST(test_xtree_delete) { xtree_t* tree = &mytree_by_addchild; /* bad args */ fail_unless(xtree_depth(tree) == 3, NULL); fail_unless(xtree_delete(NULL, tree->root) == NULL, "bad return"); fail_unless(xtree_get_count(tree) == 7, "bad count update"); fail_unless(tree->state & XTREE_STATE_DEPTHCACHED, "level should still be cached"); fail_unless(xtree_delete(tree, NULL) == NULL, "bad return"); fail_unless(xtree_get_count(tree) == 7, "bad count update"); fail_unless(tree->state & XTREE_STATE_DEPTHCACHED, "level should still be cached"); fail_unless(xtree_depth(tree) == 3, NULL); /* tree structure */ fail_unless(xtree_delete(tree, tree->root->start) == tree->root, "parent of 6 should have been root node"); fail_unless(xtree_depth(tree) == 3, NULL); fail_unless(tree->root->start->data == (void*)2 && tree->root->start->next->data == (void*)3 && tree->root->start->next->next->data == (void*)5, "children should be now 2 -> 3 -> 5"); fail_unless(tree->root->start->previous == NULL, "bad children list edges"); fail_unless(xtree_get_count(tree) == 6, "bad count update"); fail_unless(tree->state & XTREE_STATE_DEPTHCACHED, "level should still be cached"); fail_unless(tree->depth == 3 && xtree_depth(tree) == 3, "depth should not have changed"); /* structure and depth changing */ fail_unless(xtree_delete(tree, tree->root->start->start) == tree->root->start, "parent of 7 should have been node 2"); fail_unless(xtree_depth(tree) == 3, NULL); fail_unless(tree->state & XTREE_STATE_DEPTHCACHED, "level should still be cached"); fail_unless(tree->depth == 3, "depth should not have changed"); fail_unless(xtree_get_count(tree) == 5, "bad count update"); fail_unless(xtree_delete(tree, tree->root->start->start) == tree->root->start, "parent of 4 should have been node 2"); fail_unless(tree->root->start->start == NULL && tree->root->start->end == NULL, "bad edges for node 2"); fail_unless(tree->root->start->data == (void*)2 && tree->root->start->next->data == (void*)3 && tree->root->start->next->next->data == (void*)5, "tree deconstruction"); fail_unless(tree->root->start->previous == NULL && tree->root->end->next == NULL, "tree edges deconstruction"); fail_unless(~tree->state & XTREE_STATE_DEPTHCACHED, "level should not be cached"); fail_unless(xtree_depth(tree) == 2, "the last removal should have reduced depth"); /* root node delete test */ fail_unless(xtree_delete(tree, tree->root) == NULL, "bad return"); }
/* here we construct a tree in the following form : * 1 * / / \ \ * 6 2 3 5 * / \ * 7 4 * numbers are chronological adding order. */ void addchild_walk_test() { xtree_t *my_tree = (xtree_t *)xmalloc(sizeof(xtree_t)); person_t *person = NULL; person_t *direct_parent_person = NULL; person_t *parent_of_delete_person = NULL; char buf[256]; xtree_node_t* node = NULL; xtree_node_t* direct_parent_node = NULL; xtree_node_t* parent_of_delete_node = NULL; uint32_t arg = 0; int i; /* init my_tree with free element function */ xtree_init(my_tree, xtree_free_node_func); for (i = 1; i < 8; i++) { person = (person_t *)xmalloc(sizeof(person_t)); person->id = i; person->age = i; snprintf(buf, 256, "name_%d", i); person->name = xstrdup(buf); if (1 == i) xtree_add_child(my_tree, NULL, person, XTREE_APPEND); else if (2 == i) xtree_add_child(my_tree, my_tree->root, person, XTREE_APPEND); else if (3 == i) xtree_add_child(my_tree, my_tree->root, person, XTREE_APPEND); else if (4 == i) /* my_tree->root is 1, then 1's ->start is 2 */ xtree_add_child(my_tree, my_tree->root->start, person, XTREE_APPEND); else if (5 == i) xtree_add_child(my_tree, my_tree->root, person, XTREE_APPEND); else if (6 == i) xtree_add_child(my_tree, my_tree->root, person, XTREE_PREPEND); else if (7 == i) /* my_tree->root is 1, then 1's ->start is 2 */ /* XTREE_PREPEND */ xtree_add_child(my_tree, my_tree->root->start->next, person, XTREE_PREPEND); } arg = 4; node = xtree_find(my_tree, find_compare_func, &arg); if (NULL != node) { person = (person_t *) node->data; puts("xtree_find success!, my info: "); printf("person->id = %lu\n", person->id); printf("person->age = %lu\n", person->age); printf("person->name = %s\n", person->name); /* print person's depth */ printf("person\'s depth = %lu\n", xtree_node_depth(node)); puts("my parent\'s info: "); direct_parent_node = xtree_get_parent(my_tree, node); direct_parent_person = (person_t *) direct_parent_node->data; printf("direct_parent_person->id = %lu\n", direct_parent_person->id); printf("direct_parent_person->age = %lu\n", direct_parent_person->age); printf("direct_parent_person->name = %s\n", direct_parent_person->name); /* print parent's depth */ printf("parent's depth = %lu\n", xtree_node_depth(direct_parent_person)); puts("try to delete the parent node (2):"); parent_of_delete_node = xtree_delete(my_tree, direct_parent_node); parent_of_delete_person = (person_t *)parent_of_delete_node->data; printf("parent_of_delete_person->id = %lu\n", parent_of_delete_person->id); printf("parent_of_delete_person->age = %lu\n", parent_of_delete_person->age); printf("parent_of_delete_person->name = %s\n", parent_of_delete_person->name); } puts("at last, free all nodes in the tree:"); /* to free element */ xtree_free(my_tree); /* to free my_tree itself memory */ xfree(my_tree); }