Exemple #1
0
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);
}