/*
 * test_node_fragment.c
 *
 * Copyright 2022 Jonathan Schöbel <jonathan@Ubermos-2019>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 *
 *
 */


#include <check.h>
#include <stdbool.h>
#include <stdlib.h>

#include "macro.h"
#include "status.h"

#include "node_fragment.c"


START_TEST(test_node_fragment_no_status)
{
	struct SH_NodeFragment * fragment;
	SH_Data * data;
	const char * tag = "tag";

	data = SH_Data_new (NULL);

	fragment = (struct SH_NodeFragment *)
	           SH_NodeFragment_new (tag, data, NULL);

	ck_assert_ptr_ne (NULL, fragment);

	ck_assert_ptr_eq (NULL, fragment->base.parent);
	ck_assert_str_eq (fragment->tag, tag);

	ck_assert_int_eq (0, fragment->attr_n);
	ck_assert_int_eq (0, fragment->attr_s);

	ck_assert_int_eq (0, fragment->child_n);
	ck_assert_int_eq (0, fragment->child_s);

	SH_NodeFragment_free (fragment);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_with_status)
{
	struct SH_Status status;
	struct SH_NodeFragment * fragment;
	SH_Data * data;
	const char * tag = "tag";

	data = SH_Data_new (NULL);

	_status_preinit (status);
	fragment = (struct SH_NodeFragment *)
	           SH_NodeFragment_new (tag, data, &status);

	ck_assert_ptr_ne (NULL, fragment);
	ck_assert (succeed (&status));

	ck_assert_ptr_eq (NULL, fragment->base.parent);
	ck_assert_str_eq (fragment->tag, tag);

	ck_assert_int_eq (0, fragment->attr_n);
	ck_assert_int_eq (0, fragment->attr_s);

	ck_assert_int_eq (0, fragment->child_n);
	ck_assert_int_eq (0, fragment->child_s);

	SH_NodeFragment_free (fragment);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_raw_no_status)
{
	struct SH_NodeFragment * fragment;
	SH_Data * data;
	char * tag = strdup ("tag");

	data = SH_Data_new (NULL);

	fragment = (struct SH_NodeFragment *)
	           SH_NodeFragment_raw_new (tag, data, NULL);

	ck_assert_ptr_ne (NULL, fragment);

	ck_assert_ptr_eq (NULL, fragment->base.parent);
	ck_assert_ptr_eq (fragment->tag, tag);

	ck_assert_int_eq (0, fragment->attr_n);
	ck_assert_int_eq (0, fragment->attr_s);

	ck_assert_int_eq (0, fragment->child_n);
	ck_assert_int_eq (0, fragment->child_s);

	SH_NodeFragment_free (fragment);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_raw_with_status)
{
	struct SH_Status status;
	struct SH_NodeFragment * fragment;
	SH_Data * data;
	char * tag = strdup ("tag");

	data = SH_Data_new (NULL);

	_status_preinit (status);
	fragment = (struct SH_NodeFragment *)
	           SH_NodeFragment_raw_new (tag, data, &status);

	ck_assert_ptr_ne (NULL, fragment);
	ck_assert (succeed (&status));

	ck_assert_ptr_eq (NULL, fragment->base.parent);
	ck_assert_ptr_eq (fragment->tag, tag);

	ck_assert_int_eq (0, fragment->attr_n);
	ck_assert_int_eq (0, fragment->attr_s);

	ck_assert_int_eq (0, fragment->child_n);
	ck_assert_int_eq (0, fragment->child_s);

	SH_NodeFragment_free (fragment);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_copy_no_status)
{
	struct SH_NodeFragment * fragment;
	struct SH_NodeFragment * copy;
	SH_Data * data;

	data = SH_Data_new (NULL);

	fragment = (struct SH_NodeFragment *)
	           SH_NodeFragment_new ("html", data, NULL);

	copy = (struct SH_NodeFragment *)
	       SH_NodeFragment_copy (fragment, NULL);

	ck_assert_ptr_ne (copy, NULL);
	ck_assert_ptr_ne (fragment, copy);
	ck_assert_ptr_eq (NULL, copy->base.parent);
	ck_assert_str_eq (fragment->tag, copy->tag);
	ck_assert_int_eq (0, copy->attr_n);
	ck_assert_int_eq (0, copy->attr_s);
	ck_assert_int_eq (0, copy->child_n);
	ck_assert_int_eq (0, copy->child_s);
	ck_assert_ptr_ne (NULL, copy->childs);

	SH_NodeFragment_free (fragment);
	SH_NodeFragment_free (copy);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_copy_with_status)
{
	struct SH_Status status;
	struct SH_NodeFragment * fragment;
	struct SH_NodeFragment * copy;
	SH_Data * data;

	data = SH_Data_new (NULL);

	fragment = (struct SH_NodeFragment *)
	           SH_NodeFragment_new ("html", data, NULL);

	_status_preinit (status);
	copy = (struct SH_NodeFragment *)
	       SH_NodeFragment_copy (fragment, &status);
	ck_assert (succeed (&status));

	ck_assert_ptr_ne (copy, NULL);
	ck_assert_ptr_ne (fragment, copy);
	ck_assert_ptr_eq (NULL, copy->base.parent);
	ck_assert_str_eq (fragment->tag, copy->tag);
	ck_assert_int_eq (0, copy->attr_n);
	ck_assert_int_eq (0, copy->attr_s);
	ck_assert_int_eq (0, copy->child_n);
	ck_assert_int_eq (0, copy->child_s);
	ck_assert_ptr_ne (NULL, copy->childs);

	SH_NodeFragment_free (fragment);
	SH_NodeFragment_free (copy);

	SH_Data_free (data);
}
END_TEST

static void
check_childs (struct SH_NodeFragment * fragment,
              struct SH_NodeFragment * copy)
{
	size_t index;

	ck_assert_str_eq (fragment->tag, copy->tag);
	ck_assert_int_eq (fragment->attr_n, copy->attr_n);
	ck_assert_int_eq (fragment->attr_s, copy->attr_s);
	ck_assert_int_eq (fragment->child_n, copy->child_n);
	ck_assert_int_eq (fragment->child_s, copy->child_s);
	ck_assert_ptr_ne (fragment->childs, copy->childs);

	for (index = 0; index < copy->child_n; index++)
	{
		ck_assert_ptr_ne (fragment->childs[index],
				  copy->childs[index]);
		ck_assert_ptr_eq (copy, get_parent (copy->childs[index]));

		check_childs (((struct SH_NodeFragment *)
		              fragment->childs[index]),
			      ((struct SH_NodeFragment *)
			      copy->childs[index]));
	}

	return;
}

START_TEST(test_node_fragment_deepcopy_no_status)
{
	struct SH_NodeFragment * fragment;
	struct SH_NodeFragment * copy;
	struct SH_Fragment * child1;
	struct SH_Fragment * child2;
	SH_Data * data;

	data = SH_Data_new (NULL);

	fragment = (struct SH_NodeFragment *)
	           SH_NodeFragment_new ("html", data, NULL);

	child1 = SH_NodeFragment_new ("head", data, NULL);
	SH_NodeFragment_append_child (fragment, child1, NULL);

	child2 = SH_NodeFragment_new ("title", data, NULL);
	SH_NodeFragment_append_child ((struct SH_NodeFragment *)child1,
	                              child2, NULL);


	child1 = SH_NodeFragment_new ("body", data, NULL);
	SH_NodeFragment_append_child (fragment, child1, NULL);

	child2 = SH_NodeFragment_new ("header", data, NULL);
	SH_NodeFragment_append_child ((struct SH_NodeFragment *)child1,
	                              child2, NULL);

	child2 = SH_NodeFragment_new ("main", data, NULL);
	SH_NodeFragment_append_child ((struct SH_NodeFragment *)child1,
	                              child2, NULL);

	child2 = SH_NodeFragment_new ("footer", data, NULL);
	SH_NodeFragment_append_child ((struct SH_NodeFragment *)child1,
	                              child2, NULL);


	copy = (struct SH_NodeFragment *)
	       SH_NodeFragment_deepcopy (fragment, NULL);

	ck_assert_ptr_ne (NULL, copy);
	ck_assert_ptr_ne (fragment, copy);
	ck_assert_ptr_eq (NULL, copy->base.parent);

	check_childs (fragment, copy);

	SH_NodeFragment_free (fragment);
	SH_NodeFragment_free (copy);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_deepcopy_with_status)
{
	struct SH_Status status;
	struct SH_NodeFragment * fragment;
	struct SH_NodeFragment * copy;
	struct SH_Fragment * child1;
	struct SH_Fragment * child2;
	SH_Data * data;

	data = SH_Data_new (NULL);

	fragment = (struct SH_NodeFragment *)
	           SH_NodeFragment_new ("html", data, NULL);

	child1 = SH_NodeFragment_new ("head", data, NULL);
	SH_NodeFragment_append_child (fragment, child1, NULL);

	child2 = SH_NodeFragment_new ("title", data, NULL);
	SH_NodeFragment_append_child ((struct SH_NodeFragment *)child1,
	                              child2, NULL);


	child1 = SH_NodeFragment_new ("body", data, NULL);
	SH_NodeFragment_append_child (fragment, child1, NULL);

	child2 = SH_NodeFragment_new ("header", data, NULL);
	SH_NodeFragment_append_child ((struct SH_NodeFragment *)child1,
	                              child2, NULL);

	child2 = SH_NodeFragment_new ("main", data, NULL);
	SH_NodeFragment_append_child ((struct SH_NodeFragment *)child1,
	                              child2, NULL);

	child2 = SH_NodeFragment_new ("footer", data, NULL);
	SH_NodeFragment_append_child ((struct SH_NodeFragment *)child1,
	                              child2, NULL);


	_status_preinit (status);
	copy = (struct SH_NodeFragment *)
	       SH_NodeFragment_deepcopy (fragment, &status);
	ck_assert (succeed (&status));

	ck_assert_ptr_ne (NULL, copy);
	ck_assert_ptr_ne (fragment, copy);
	ck_assert_ptr_eq (NULL, copy->base.parent);

	check_childs (fragment, copy);

	SH_NodeFragment_free (fragment);
	SH_NodeFragment_free (copy);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_tag_no_status)
{
	struct SH_Fragment * fragment;
	SH_Data * data;
	char * tag;
	const char * tag1 = "html";

	data = SH_Data_new (NULL);

	/* no error */
	fragment = SH_NodeFragment_new (tag1, data, NULL);

	tag = SH_NodeFragment_get_tag ((struct SH_NodeFragment *)
	                               fragment,
	                               NULL);
	ck_assert_str_eq (tag, tag1);
	free (tag);

	SH_Fragment_free (fragment);
	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_tag_with_status)
{
	struct SH_Status status;
	struct SH_Fragment * fragment;
	SH_Data * data;
	char * tag;
	const char * tag1 = "html";

	data = SH_Data_new (NULL);

	fragment = SH_NodeFragment_new (tag1, data, NULL);

	_status_preinit (status);
	tag = SH_NodeFragment_get_tag ((struct SH_NodeFragment *)
	                               fragment,
	                               &status);
	ck_assert_str_eq (tag, tag1);
	ck_assert (succeed (&status));
	free (tag);

	SH_Fragment_free (fragment);
	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_tag_raw)
{
	struct SH_Fragment * fragment;
	SH_Data * data;
	char * tag;
	const char * tag1 = "html";

	data = SH_Data_new (NULL);

	fragment = SH_NodeFragment_new (tag1, data, NULL);

	tag = SH_NodeFragment_raw_get_tag (((struct SH_NodeFragment *)
	                                   fragment));
	ck_assert_str_eq (tag, tag1);

	SH_Fragment_free (fragment);
	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_attr_alloc)
{
	#define alloc_size get_attr_alloc_size
	ck_assert_int_eq (0, alloc_size (0));
	ck_assert_int_eq (CHILD_CHUNK, alloc_size (1));
	ck_assert_int_eq (CHILD_CHUNK, alloc_size (CHILD_CHUNK));
	ck_assert_int_eq (2*CHILD_CHUNK, alloc_size (CHILD_CHUNK+1));
	ck_assert_int_eq (SIZE_MAX, alloc_size (SIZE_MAX));
	for (size_t i = 0; i < CHILD_CHUNK; i++)
	{
		ck_assert_int_le (SIZE_MAX-i, alloc_size (SIZE_MAX-i));
	}
	#undef alloc_size
}
END_TEST

START_TEST(test_node_fragment_attr_get_no_status)
{
	SH_Attr * attr1;
	const SH_Attr * attr2;
	SH_Data * data;
	SH_NodeFragment * fragment;
	bool result;

	/* setup */
	attr1 = SH_Attr_new ("name", "value", NULL);
	ck_assert_ptr_ne (NULL, attr1);

	data = SH_Data_new (NULL);
	ck_assert_ptr_ne (NULL, data);

	fragment = (SH_NodeFragment *)SH_NodeFragment_new ("html", data,
	                                                   NULL);
	ck_assert_ptr_ne (NULL, fragment);

	result = SH_NodeFragment_append_attr_copy (fragment, attr1, NULL);
	ck_assert_int_eq (TRUE, result);

	/* test - success */
	attr2 = SH_NodeFragment_get_attr (fragment, 0, NULL);
	ck_assert_ptr_ne (NULL, attr2);

	ck_assert (Attr_is_equal (attr1, attr2));

	/* test - fail */
	attr2 = SH_NodeFragment_get_attr (fragment, 1, NULL);
	ck_assert_ptr_eq (NULL, attr2);

	/* cleanup */
	SH_NodeFragment_free (fragment);
	SH_Data_free (data);
	SH_Attr_free (attr1);
}
END_TEST

START_TEST(test_node_fragment_attr_get_with_status)
{
	struct SH_Status status;
	SH_Attr * attr1;
	const SH_Attr * attr2;
	SH_Data * data;
	SH_NodeFragment * fragment;
	bool result;

	/* setup */
	attr1 = SH_Attr_new ("name", "value", NULL);
	ck_assert_ptr_ne (NULL, attr1);

	data = SH_Data_new (NULL);
	ck_assert_ptr_ne (NULL, data);

	fragment = (SH_NodeFragment *)SH_NodeFragment_new ("html", data,
	                                                   NULL);
	ck_assert_ptr_ne (NULL, fragment);

	result = SH_NodeFragment_append_attr_copy (fragment, attr1, NULL);
	ck_assert_int_eq (TRUE, result);

	/* test - success */
	_status_preinit (status);
	attr2 = SH_NodeFragment_get_attr (fragment, 0, &status);
	ck_assert_ptr_ne (NULL, attr2);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert (Attr_is_equal (attr1, attr2));

	/* test - fail */
	_status_preinit (status);
	attr2 = SH_NodeFragment_get_attr (fragment, 1, &status);
	ck_assert_ptr_eq (NULL, attr2);
	ck_assert_int_eq (E_VALUE, status.status);

	/* cleanup */
	SH_NodeFragment_free (fragment);
	SH_Data_free (data);
	SH_Attr_free (attr1);
}
END_TEST

START_TEST(test_node_fragment_attr_insert_no_status)
{
	SH_Attr * attr1;
	SH_Attr * attr2;
	SH_Attr * attr3;
	SH_Data * data;
	struct SH_NodeFragment * fragment;
	bool result;

	/* setup */
	attr1 = SH_Attr_new ("name1", "value1", NULL);
	ck_assert_ptr_ne (NULL, attr1);

	attr2 = SH_Attr_new ("name2", "value2", NULL);
	ck_assert_ptr_ne (NULL, attr2);

	attr3 = SH_Attr_new ("name3", "value3", NULL);
	ck_assert_ptr_ne (NULL, attr3);

	data = SH_Data_new (NULL);
	ck_assert_ptr_ne (NULL, data);

	fragment = (SH_NodeFragment *)SH_NodeFragment_new ("html", data,
	                                                   NULL);
	ck_assert_ptr_ne (NULL, fragment);

	/* test insert - success */
	result = insert_attr (fragment, attr1, 0, NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_int_eq (1, fragment->attr_n);
	ck_assert_int_le (1, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);

	ck_assert_ptr_eq (attr1->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr1->value, fragment->attrs[0].value);

	/* test insert before - success */
	result = insert_attr (fragment, attr2, 0, NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_int_eq (2, fragment->attr_n);
	ck_assert_int_le (2, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);

	ck_assert_ptr_eq (attr2->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr2->value, fragment->attrs[0].value);

	ck_assert_ptr_eq (attr1->name, fragment->attrs[1].name);
	ck_assert_ptr_eq (attr1->value, fragment->attrs[1].value);

	/* test insert after - success */
	result = insert_attr (fragment, attr3, 2, NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_int_eq (3, fragment->attr_n);
	ck_assert_int_le (3, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);

	ck_assert_ptr_eq (attr2->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr2->value, fragment->attrs[0].value);

	ck_assert_ptr_eq (attr1->name, fragment->attrs[1].name);
	ck_assert_ptr_eq (attr1->value, fragment->attrs[1].value);

	ck_assert_ptr_eq (attr3->name, fragment->attrs[2].name);
	ck_assert_ptr_eq (attr3->value, fragment->attrs[2].value);

	/* cleanup */
	SH_NodeFragment_free (fragment);
	SH_Data_free (data);
	free (attr1);
	free (attr2);
	free (attr3);
}
END_TEST

START_TEST(test_node_fragment_attr_insert_with_status)
{
	struct SH_Status status;
	SH_Attr * attr1;
	SH_Attr * attr2;
	SH_Attr * attr3;
	SH_Data * data;
	struct SH_NodeFragment * fragment;
	bool result;

	/* setup */
	attr1 = SH_Attr_new ("name1", "value1", NULL);
	ck_assert_ptr_ne (NULL, attr1);

	attr2 = SH_Attr_new ("name2", "value2", NULL);
	ck_assert_ptr_ne (NULL, attr2);

	attr3 = SH_Attr_new ("name3", "value3", NULL);
	ck_assert_ptr_ne (NULL, attr3);

	data = SH_Data_new (NULL);
	ck_assert_ptr_ne (NULL, data);

	fragment = (SH_NodeFragment *)SH_NodeFragment_new ("html", data,
	                                                   NULL);
	ck_assert_ptr_ne (NULL, fragment);

	/* test insert - success */
	_status_preinit (status);
	result = insert_attr (fragment, attr1, 0, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_int_eq (1, fragment->attr_n);
	ck_assert_int_le (1, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);

	ck_assert_ptr_eq (attr1->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr1->value, fragment->attrs[0].value);

	/* test insert before - success */
	_status_preinit (status);
	result = insert_attr (fragment, attr2, 0, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_int_eq (2, fragment->attr_n);
	ck_assert_int_le (2, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);

	ck_assert_ptr_eq (attr2->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr2->value, fragment->attrs[0].value);

	ck_assert_ptr_eq (attr1->name, fragment->attrs[1].name);
	ck_assert_ptr_eq (attr1->value, fragment->attrs[1].value);

	/* test insert after - success */
	_status_preinit (status);
	result = insert_attr (fragment, attr3, 2, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_int_eq (3, fragment->attr_n);
	ck_assert_int_le (3, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);

	ck_assert_ptr_eq (attr2->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr2->value, fragment->attrs[0].value);

	ck_assert_ptr_eq (attr1->name, fragment->attrs[1].name);
	ck_assert_ptr_eq (attr1->value, fragment->attrs[1].value);

	ck_assert_ptr_eq (attr3->name, fragment->attrs[2].name);
	ck_assert_ptr_eq (attr3->value, fragment->attrs[2].value);

	/* cleanup */
	SH_NodeFragment_free (fragment);
	SH_Data_free (data);
	free (attr1);
	free (attr2);
	free (attr3);
}
END_TEST

START_TEST(test_node_fragment_attr_insert_new_no_status)
{
	char * name;
	char * value;
	SH_Attr * attr1;
	SH_Attr * attr2;
	SH_Attr * attr3;
	SH_Data * data;
	struct SH_NodeFragment * fragment;
	bool result;

	/* setup */
	attr1 = SH_Attr_new ("name1", "value1", NULL);
	ck_assert_ptr_ne (NULL, attr1);

	attr2 = SH_Attr_new ("name2", "value2", NULL);
	ck_assert_ptr_ne (NULL, attr2);

	attr3 = SH_Attr_new ("name3", "value3", NULL);
	ck_assert_ptr_ne (NULL, attr3);

	data = SH_Data_new (NULL);
	ck_assert_ptr_ne (NULL, data);

	fragment = (SH_NodeFragment *)SH_NodeFragment_new ("html", data,
	                                                   NULL);
	ck_assert_ptr_ne (NULL, fragment);

	/* test insert - success */
	name = Attr_get_name (attr1);
	value = Attr_get_value (attr1);

	result = insert_attr_new (fragment, name, value, 0, NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_int_eq (1, fragment->attr_n);
	ck_assert_int_le (1, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);

	ck_assert_ptr_eq (attr1->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr1->value, fragment->attrs[0].value);

	/* test insert before - success */
	name = Attr_get_name (attr2);
	value = Attr_get_value (attr2);

	result = insert_attr_new (fragment, name, value, 0, NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_int_eq (2, fragment->attr_n);
	ck_assert_int_le (2, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);

	ck_assert_ptr_eq (attr2->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr2->value, fragment->attrs[0].value);

	ck_assert_ptr_eq (attr1->name, fragment->attrs[1].name);
	ck_assert_ptr_eq (attr1->value, fragment->attrs[1].value);

	/* test insert after - success */
	name = Attr_get_name (attr3);
	value = Attr_get_value (attr3);

	result = insert_attr_new (fragment, name, value, 2, NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_int_eq (3, fragment->attr_n);
	ck_assert_int_le (3, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);

	ck_assert_ptr_eq (attr2->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr2->value, fragment->attrs[0].value);

	ck_assert_ptr_eq (attr1->name, fragment->attrs[1].name);
	ck_assert_ptr_eq (attr1->value, fragment->attrs[1].value);

	ck_assert_ptr_eq (attr3->name, fragment->attrs[2].name);
	ck_assert_ptr_eq (attr3->value, fragment->attrs[2].value);

	/* cleanup */
	SH_NodeFragment_free (fragment);
	SH_Data_free (data);
	free (attr1);
	free (attr2);
	free (attr3);
}
END_TEST

START_TEST(test_node_fragment_attr_insert_new_with_status)
{
	struct SH_Status status;
	char * name;
	char * value;
	SH_Attr * attr1;
	SH_Attr * attr2;
	SH_Attr * attr3;
	SH_Data * data;
	struct SH_NodeFragment * fragment;
	bool result;

	/* setup */
	attr1 = SH_Attr_new ("name1", "value1", NULL);
	ck_assert_ptr_ne (NULL, attr1);

	attr2 = SH_Attr_new ("name2", "value2", NULL);
	ck_assert_ptr_ne (NULL, attr2);

	attr3 = SH_Attr_new ("name3", "value3", NULL);
	ck_assert_ptr_ne (NULL, attr3);

	data = SH_Data_new (NULL);
	ck_assert_ptr_ne (NULL, data);

	fragment = (SH_NodeFragment *)SH_NodeFragment_new ("html", data,
	                                                   NULL);
	ck_assert_ptr_ne (NULL, fragment);

	/* test insert - success */
	name = Attr_get_name (attr1);
	value = Attr_get_value (attr1);

	_status_preinit (status);
	result = insert_attr_new (fragment, name, value, 0, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_int_eq (1, fragment->attr_n);
	ck_assert_int_le (1, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);

	ck_assert_ptr_eq (attr1->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr1->value, fragment->attrs[0].value);

	/* test insert before - success */
	name = Attr_get_name (attr2);
	value = Attr_get_value (attr2);

	_status_preinit (status);
	result = insert_attr_new (fragment, name, value, 0, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_int_eq (2, fragment->attr_n);
	ck_assert_int_le (2, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);

	ck_assert_ptr_eq (attr2->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr2->value, fragment->attrs[0].value);

	ck_assert_ptr_eq (attr1->name, fragment->attrs[1].name);
	ck_assert_ptr_eq (attr1->value, fragment->attrs[1].value);

	/* test insert after - success */
	name = Attr_get_name (attr3);
	value = Attr_get_value (attr3);

	_status_preinit (status);
	result = insert_attr_new (fragment, name, value, 2, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_int_eq (3, fragment->attr_n);
	ck_assert_int_le (3, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);

	ck_assert_ptr_eq (attr2->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr2->value, fragment->attrs[0].value);

	ck_assert_ptr_eq (attr1->name, fragment->attrs[1].name);
	ck_assert_ptr_eq (attr1->value, fragment->attrs[1].value);

	ck_assert_ptr_eq (attr3->name, fragment->attrs[2].name);
	ck_assert_ptr_eq (attr3->value, fragment->attrs[2].value);

	/* cleanup */
	SH_NodeFragment_free (fragment);
	SH_Data_free (data);
	free (attr1);
	free (attr2);
	free (attr3);
}
END_TEST

START_TEST(test_node_fragment_attr_insert_copy_no_status)
{
	char * name;
	char * value;
	SH_Attr * attr;
	SH_Attr * attr1;
	SH_Attr * attr2;
	SH_Attr * attr3;
	SH_Data * data;
	struct SH_NodeFragment * fragment;
	bool result;

	/* setup */
	attr1 = SH_Attr_new ("name1", "value1", NULL);
	ck_assert_ptr_ne (NULL, attr1);

	attr2 = SH_Attr_new ("name2", "value2", NULL);
	ck_assert_ptr_ne (NULL, attr2);

	attr3 = SH_Attr_new ("name3", "value3", NULL);
	ck_assert_ptr_ne (NULL, attr3);

	data = SH_Data_new (NULL);
	ck_assert_ptr_ne (NULL, data);

	fragment = (SH_NodeFragment *)SH_NodeFragment_new ("html", data,
	                                                   NULL);
	ck_assert_ptr_ne (NULL, fragment);

	/* test insert - success */
	attr = SH_Attr_copy (attr1, NULL);
	ck_assert_ptr_ne (NULL, attr);

	name = Attr_get_name (attr);
	value = Attr_get_value (attr);

	result = insert_attr_copy (fragment, attr, 0, NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_int_eq (1, fragment->attr_n);
	ck_assert_int_le (1, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);

	ck_assert_ptr_ne (name, fragment->attrs[0].name);
	ck_assert_ptr_ne (value, fragment->attrs[0].value);

	ck_assert_str_eq (attr1->name, fragment->attrs[0].name);
	ck_assert_str_eq (attr1->value, fragment->attrs[0].value);

	/* test insert before - success */
	attr = SH_Attr_copy (attr2, NULL);
	ck_assert_ptr_ne (NULL, attr);

	name = Attr_get_name (attr);
	value = Attr_get_value (attr);

	result = insert_attr_copy (fragment, attr, 0, NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_int_eq (2, fragment->attr_n);
	ck_assert_int_le (2, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);

	ck_assert_ptr_ne (name, fragment->attrs[0].name);
	ck_assert_ptr_ne (value, fragment->attrs[0].value);

	ck_assert_str_eq (attr2->name, fragment->attrs[0].name);
	ck_assert_str_eq (attr2->value, fragment->attrs[0].value);

	ck_assert_str_eq (attr1->name, fragment->attrs[1].name);
	ck_assert_str_eq (attr1->value, fragment->attrs[1].value);

	/* test insert after - success */
	attr = SH_Attr_copy (attr3, NULL);
	ck_assert_ptr_ne (NULL, attr);

	name = Attr_get_name (attr);
	value = Attr_get_value (attr);

	result = insert_attr_copy (fragment, attr, 2, NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_int_eq (3, fragment->attr_n);
	ck_assert_int_le (3, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);

	ck_assert_ptr_ne (name, fragment->attrs[2].name);
	ck_assert_ptr_ne (value, fragment->attrs[2].value);

	ck_assert_str_eq (attr2->name, fragment->attrs[0].name);
	ck_assert_str_eq (attr2->value, fragment->attrs[0].value);

	ck_assert_str_eq (attr1->name, fragment->attrs[1].name);
	ck_assert_str_eq (attr1->value, fragment->attrs[1].value);

	ck_assert_str_eq (attr3->name, fragment->attrs[2].name);
	ck_assert_str_eq (attr3->value, fragment->attrs[2].value);

	/* cleanup */
	SH_NodeFragment_free (fragment);
	SH_Data_free (data);
	SH_Attr_free (attr1);
	SH_Attr_free (attr2);
	SH_Attr_free (attr3);
}
END_TEST

START_TEST(test_node_fragment_attr_insert_copy_with_status)
{
	struct SH_Status status;
	char * name;
	char * value;
	SH_Attr * attr;
	SH_Attr * attr1;
	SH_Attr * attr2;
	SH_Attr * attr3;
	SH_Data * data;
	struct SH_NodeFragment * fragment;
	bool result;

	/* setup */
	attr1 = SH_Attr_new ("name1", "value1", NULL);
	ck_assert_ptr_ne (NULL, attr1);

	attr2 = SH_Attr_new ("name2", "value2", NULL);
	ck_assert_ptr_ne (NULL, attr2);

	attr3 = SH_Attr_new ("name3", "value3", NULL);
	ck_assert_ptr_ne (NULL, attr3);

	data = SH_Data_new (NULL);
	ck_assert_ptr_ne (NULL, data);

	fragment = (SH_NodeFragment *)SH_NodeFragment_new ("html", data,
	                                                   NULL);
	ck_assert_ptr_ne (NULL, fragment);

	/* test insert - success */
	attr = SH_Attr_copy (attr1, NULL);
	ck_assert_ptr_ne (NULL, attr);

	name = Attr_get_name (attr);
	value = Attr_get_value (attr);

	_status_preinit (status);
	result = insert_attr_copy (fragment, attr, 0, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_int_eq (1, fragment->attr_n);
	ck_assert_int_le (1, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);

	ck_assert_ptr_ne (name, fragment->attrs[0].name);
	ck_assert_ptr_ne (value, fragment->attrs[0].value);

	ck_assert_str_eq (attr1->name, fragment->attrs[0].name);
	ck_assert_str_eq (attr1->value, fragment->attrs[0].value);

	/* test insert before - success */
	attr = SH_Attr_copy (attr2, NULL);
	ck_assert_ptr_ne (NULL, attr);

	name = Attr_get_name (attr);
	value = Attr_get_value (attr);

	_status_preinit (status);
	result = insert_attr_copy (fragment, attr, 0, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_int_eq (2, fragment->attr_n);
	ck_assert_int_le (2, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);

	ck_assert_ptr_ne (name, fragment->attrs[0].name);
	ck_assert_ptr_ne (value, fragment->attrs[0].value);

	ck_assert_str_eq (attr2->name, fragment->attrs[0].name);
	ck_assert_str_eq (attr2->value, fragment->attrs[0].value);

	ck_assert_str_eq (attr1->name, fragment->attrs[1].name);
	ck_assert_str_eq (attr1->value, fragment->attrs[1].value);

	/* test insert after - success */
	attr = SH_Attr_copy (attr3, NULL);
	ck_assert_ptr_ne (NULL, attr);

	name = Attr_get_name (attr);
	value = Attr_get_value (attr);

	_status_preinit (status);
	result = insert_attr_copy (fragment, attr, 2, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_int_eq (3, fragment->attr_n);
	ck_assert_int_le (3, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);

	ck_assert_ptr_ne (name, fragment->attrs[2].name);
	ck_assert_ptr_ne (value, fragment->attrs[2].value);

	ck_assert_str_eq (attr2->name, fragment->attrs[0].name);
	ck_assert_str_eq (attr2->value, fragment->attrs[0].value);

	ck_assert_str_eq (attr1->name, fragment->attrs[1].name);
	ck_assert_str_eq (attr1->value, fragment->attrs[1].value);

	ck_assert_str_eq (attr3->name, fragment->attrs[2].name);
	ck_assert_str_eq (attr3->value, fragment->attrs[2].value);

	/* cleanup */
	SH_NodeFragment_free (fragment);
	SH_Data_free (data);
	SH_Attr_free (attr1);
	SH_Attr_free (attr2);
	SH_Attr_free (attr3);
}
END_TEST

START_TEST(test_node_fragment_attr_insert_insert_no_status)
{
	SH_Attr * attr1;
	SH_Attr * attr2;
	SH_Attr * attr3;
	SH_Data * data;
	SH_NodeFragment * fragment;
	bool result;

	/* setup */
	attr1 = SH_Attr_new ("name1", "value1", NULL);
	ck_assert_ptr_ne (NULL, attr1);

	attr2 = SH_Attr_new ("name2", "value2", NULL);
	ck_assert_ptr_ne (NULL, attr2);

	attr3 = SH_Attr_new ("name3", "value3", NULL);
	ck_assert_ptr_ne (NULL, attr3);

	data = SH_Data_new (NULL);
	ck_assert_ptr_ne (NULL, data);

	fragment = (SH_NodeFragment *)SH_NodeFragment_new ("html", data,
	                                                   NULL);
	ck_assert_ptr_ne (NULL, fragment);

	/* test - out of bounds */
	result = SH_NodeFragment_insert_attr (fragment, attr1, 1, NULL);
	ck_assert_int_eq (FALSE, result);

	/* test */
	result = SH_NodeFragment_insert_attr (fragment, attr2, 0, NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_ptr_eq (attr2->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr2->value, fragment->attrs[0].value);

	/* test - insert before */
	result = SH_NodeFragment_prepend_attr (fragment, attr1, NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_ptr_eq (attr1->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr1->value, fragment->attrs[0].value);

	/* test - insert after */
	result = SH_NodeFragment_append_attr (fragment, attr3, NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_ptr_eq (attr3->name, fragment->attrs[2].name);
	ck_assert_ptr_eq (attr3->value, fragment->attrs[2].value);

	ck_assert_int_eq (3, fragment->attr_n);
	ck_assert_int_le (3, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);

	ck_assert_ptr_eq (attr1->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr1->value, fragment->attrs[0].value);

	ck_assert_ptr_eq (attr2->name, fragment->attrs[1].name);
	ck_assert_ptr_eq (attr2->value, fragment->attrs[1].value);

	ck_assert_ptr_eq (attr3->name, fragment->attrs[2].name);
	ck_assert_ptr_eq (attr3->value, fragment->attrs[2].value);

	/* cleanup */
	SH_NodeFragment_free (fragment);
	SH_Data_free (data);
	free (attr1);
	free (attr2);
	free (attr3);
}
END_TEST

START_TEST(test_node_fragment_attr_insert_insert_with_status)
{
	struct SH_Status status;
	SH_Attr * attr1;
	SH_Attr * attr2;
	SH_Attr * attr3;
	SH_Data * data;
	SH_NodeFragment * fragment;
	bool result;

	/* setup */
	attr1 = SH_Attr_new ("name1", "value1", NULL);
	ck_assert_ptr_ne (NULL, attr1);

	attr2 = SH_Attr_new ("name2", "value2", NULL);
	ck_assert_ptr_ne (NULL, attr2);

	attr3 = SH_Attr_new ("name3", "value3", NULL);
	ck_assert_ptr_ne (NULL, attr3);

	data = SH_Data_new (NULL);
	ck_assert_ptr_ne (NULL, data);

	fragment = (SH_NodeFragment *)SH_NodeFragment_new ("html", data,
	                                                   NULL);
	ck_assert_ptr_ne (NULL, fragment);

	/* test - out of bounds */
	_status_preinit (status);
	result = SH_NodeFragment_insert_attr (fragment, attr1, 1, &status);
	ck_assert_int_eq (FALSE, result);
	ck_assert_int_eq (E_VALUE, status.status);

	/* test */
	_status_preinit (status);
	result = SH_NodeFragment_insert_attr (fragment, attr2, 0, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_ptr_eq (attr2->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr2->value, fragment->attrs[0].value);

	/* test - insert before */
	_status_preinit (status);
	result = SH_NodeFragment_prepend_attr (fragment, attr1, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_ptr_eq (attr1->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr1->value, fragment->attrs[0].value);

	/* test - insert after */
	_status_preinit (status);
	result = SH_NodeFragment_append_attr (fragment, attr3, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_ptr_eq (attr3->name, fragment->attrs[2].name);
	ck_assert_ptr_eq (attr3->value, fragment->attrs[2].value);

	ck_assert_int_eq (3, fragment->attr_n);
	ck_assert_int_le (3, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);

	ck_assert_ptr_eq (attr1->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr1->value, fragment->attrs[0].value);

	ck_assert_ptr_eq (attr2->name, fragment->attrs[1].name);
	ck_assert_ptr_eq (attr2->value, fragment->attrs[1].value);

	ck_assert_ptr_eq (attr3->name, fragment->attrs[2].name);
	ck_assert_ptr_eq (attr3->value, fragment->attrs[2].value);

	/* cleanup */
	SH_NodeFragment_free (fragment);
	SH_Data_free (data);
	free (attr1);
	free (attr2);
	free (attr3);
}
END_TEST

START_TEST(test_node_fragment_attr_insert_insert_new_no_status)
{
	char * name;
	char * value;
	SH_Attr * attr1;
	SH_Attr * attr2;
	SH_Attr * attr3;
	SH_Data * data;
	SH_NodeFragment * fragment;
	bool result;

	/* setup */
	attr1 = SH_Attr_new ("name1", "value1", NULL);
	ck_assert_ptr_ne (NULL, attr1);

	attr2 = SH_Attr_new ("name2", "value2", NULL);
	ck_assert_ptr_ne (NULL, attr2);

	attr3 = SH_Attr_new ("name3", "value3", NULL);
	ck_assert_ptr_ne (NULL, attr3);

	data = SH_Data_new (NULL);
	ck_assert_ptr_ne (NULL, data);

	fragment = (SH_NodeFragment *)SH_NodeFragment_new ("html", data,
	                                                   NULL);
	ck_assert_ptr_ne (NULL, fragment);

	/* test - out of bounds */
	name = Attr_get_name (attr1);
	value = Attr_get_value (attr1);

	result = SH_NodeFragment_insert_attr_new (fragment, name, value,
	                                          1, NULL);
	ck_assert_int_eq (FALSE, result);

	/* test */
	name = Attr_get_name (attr2);
	value = Attr_get_value (attr2);

	result = SH_NodeFragment_insert_attr_new (fragment, name, value,
	                                          0, NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_ptr_eq (name, fragment->attrs[0].name);
	ck_assert_ptr_eq (value, fragment->attrs[0].value);

	/* test - insert before */
	name = Attr_get_name (attr1);
	value = Attr_get_value (attr1);

	result = SH_NodeFragment_prepend_attr_new (fragment, name, value,
	                                           NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_ptr_eq (name, fragment->attrs[0].name);
	ck_assert_ptr_eq (value, fragment->attrs[0].value);

	/* test - insert after */
	name = Attr_get_name (attr3);
	value = Attr_get_value (attr3);

	result = SH_NodeFragment_append_attr_new (fragment, name, value,
	                                          NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_ptr_eq (name, fragment->attrs[2].name);
	ck_assert_ptr_eq (value, fragment->attrs[2].value);

	ck_assert_int_eq (3, fragment->attr_n);
	ck_assert (Attr_is_equal (attr1, &fragment->attrs[0]));
	ck_assert (Attr_is_equal (attr2, &fragment->attrs[1]));
	ck_assert (Attr_is_equal (attr3, &fragment->attrs[2]));

	/* cleanup */
	SH_NodeFragment_free (fragment);
	SH_Data_free (data);
	free (attr1);
	free (attr2);
	free (attr3);
}
END_TEST

START_TEST(test_node_fragment_attr_insert_insert_new_with_status)
{
	struct SH_Status status;
	char * name;
	char * value;
	SH_Attr * attr1;
	SH_Attr * attr2;
	SH_Attr * attr3;
	SH_Data * data;
	SH_NodeFragment * fragment;
	bool result;

	/* setup */
	attr1 = SH_Attr_new ("name1", "value1", NULL);
	ck_assert_ptr_ne (NULL, attr1);

	attr2 = SH_Attr_new ("name2", "value2", NULL);
	ck_assert_ptr_ne (NULL, attr2);

	attr3 = SH_Attr_new ("name3", "value3", NULL);
	ck_assert_ptr_ne (NULL, attr3);

	data = SH_Data_new (NULL);
	ck_assert_ptr_ne (NULL, data);

	fragment = (SH_NodeFragment *)SH_NodeFragment_new ("html", data,
	                                                   NULL);
	ck_assert_ptr_ne (NULL, fragment);

	/* test - out of bounds */
	name = Attr_get_name (attr1);
	value = Attr_get_value (attr1);

	_status_preinit (status);
	result = SH_NodeFragment_insert_attr_new (fragment, name, value,
	                                          1, &status);
	ck_assert_int_eq (FALSE, result);
	ck_assert_int_eq (E_VALUE, status.status);

	/* test */
	name = Attr_get_name (attr2);
	value = Attr_get_value (attr2);

	_status_preinit (status);
	result = SH_NodeFragment_insert_attr_new (fragment, name, value,
	                                          0, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_ptr_eq (name, fragment->attrs[0].name);
	ck_assert_ptr_eq (value, fragment->attrs[0].value);

	/* test - insert before */
	name = Attr_get_name (attr1);
	value = Attr_get_value (attr1);

	_status_preinit (status);
	result = SH_NodeFragment_prepend_attr_new (fragment, name, value,
	                                           &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_ptr_eq (name, fragment->attrs[0].name);
	ck_assert_ptr_eq (value, fragment->attrs[0].value);

	/* test - insert after */
	name = Attr_get_name (attr3);
	value = Attr_get_value (attr3);

	_status_preinit (status);
	result = SH_NodeFragment_append_attr_new (fragment, name, value,
	                                          &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_ptr_eq (name, fragment->attrs[2].name);
	ck_assert_ptr_eq (value, fragment->attrs[2].value);

	ck_assert_int_eq (3, fragment->attr_n);
	ck_assert (Attr_is_equal (attr1, &fragment->attrs[0]));
	ck_assert (Attr_is_equal (attr2, &fragment->attrs[1]));
	ck_assert (Attr_is_equal (attr3, &fragment->attrs[2]));

	/* cleanup */
	SH_NodeFragment_free (fragment);
	SH_Data_free (data);
	free (attr1);
	free (attr2);
	free (attr3);
}
END_TEST

START_TEST(test_node_fragment_attr_insert_insert_copy_no_status)
{
	char * name;
	char * value;
	SH_Attr * attr1;
	SH_Attr * attr2;
	SH_Attr * attr3;
	SH_Data * data;
	SH_NodeFragment * fragment;
	bool result;

	/* setup */
	attr1 = SH_Attr_new ("name1", "value1", NULL);
	ck_assert_ptr_ne (NULL, attr1);

	attr2 = SH_Attr_new ("name2", "value2", NULL);
	ck_assert_ptr_ne (NULL, attr2);

	attr3 = SH_Attr_new ("name3", "value3", NULL);
	ck_assert_ptr_ne (NULL, attr3);

	data = SH_Data_new (NULL);
	ck_assert_ptr_ne (NULL, data);

	fragment = (SH_NodeFragment *)SH_NodeFragment_new ("html", data,
	                                                   NULL);
	ck_assert_ptr_ne (NULL, fragment);

	/* test - out of bounds */
	result = SH_NodeFragment_insert_attr_copy (fragment, attr1, 1,
	                                           NULL);
	ck_assert_int_eq (FALSE, result);

	/* test */
	name = Attr_get_name (attr2);
	value = Attr_get_value (attr2);

	result = SH_NodeFragment_insert_attr_copy (fragment, attr2, 0,
	                                           NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_ptr_ne (name, fragment->attrs[0].name);
	ck_assert_ptr_ne (value, fragment->attrs[0].value);

	/* test - insert before */
	name = Attr_get_name (attr1);
	value = Attr_get_value (attr1);

	result = SH_NodeFragment_prepend_attr_copy (fragment, attr1,
	                                           NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_ptr_ne (name, fragment->attrs[0].name);
	ck_assert_ptr_ne (value, fragment->attrs[0].value);

	/* test - insert after */
	name = Attr_get_name (attr3);
	value = Attr_get_value (attr3);

	result = SH_NodeFragment_append_attr_copy (fragment, attr3,
	                                           NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_ptr_ne (name, fragment->attrs[2].name);
	ck_assert_ptr_ne (value, fragment->attrs[2].value);

	ck_assert_int_eq (3, fragment->attr_n);
	ck_assert (Attr_is_equal (attr1, &fragment->attrs[0]));
	ck_assert (Attr_is_equal (attr2, &fragment->attrs[1]));
	ck_assert (Attr_is_equal (attr3, &fragment->attrs[2]));

	/* cleanup */
	SH_NodeFragment_free (fragment);
	SH_Data_free (data);
	SH_Attr_free (attr1);
	SH_Attr_free (attr2);
	SH_Attr_free (attr3);
}
END_TEST

START_TEST(test_node_fragment_attr_insert_insert_copy_with_status)
{
	struct SH_Status status;
	char * name;
	char * value;
	SH_Attr * attr1;
	SH_Attr * attr2;
	SH_Attr * attr3;
	SH_Data * data;
	SH_NodeFragment * fragment;
	bool result;

	/* setup */
	attr1 = SH_Attr_new ("name1", "value1", NULL);
	ck_assert_ptr_ne (NULL, attr1);

	attr2 = SH_Attr_new ("name2", "value2", NULL);
	ck_assert_ptr_ne (NULL, attr2);

	attr3 = SH_Attr_new ("name3", "value3", NULL);
	ck_assert_ptr_ne (NULL, attr3);

	data = SH_Data_new (NULL);
	ck_assert_ptr_ne (NULL, data);

	fragment = (SH_NodeFragment *)SH_NodeFragment_new ("html", data,
	                                                   NULL);
	ck_assert_ptr_ne (NULL, fragment);

	/* test - out of bounds */
	_status_preinit (status);
	result = SH_NodeFragment_insert_attr_copy (fragment, attr1, 1,
	                                           &status);
	ck_assert_int_eq (FALSE, result);
	ck_assert_int_eq (E_VALUE, status.status);

	/* test */
	name = Attr_get_name (attr2);
	value = Attr_get_value (attr2);

	_status_preinit (status);
	result = SH_NodeFragment_insert_attr_copy (fragment, attr2, 0,
	                                           &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_ptr_ne (name, fragment->attrs[0].name);
	ck_assert_ptr_ne (value, fragment->attrs[0].value);

	/* test - insert before */
	name = Attr_get_name (attr1);
	value = Attr_get_value (attr1);

	_status_preinit (status);
	result = SH_NodeFragment_prepend_attr_copy (fragment, attr1,
	                                           &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_ptr_ne (name, fragment->attrs[0].name);
	ck_assert_ptr_ne (value, fragment->attrs[0].value);

	/* test - insert after */
	name = Attr_get_name (attr3);
	value = Attr_get_value (attr3);

	_status_preinit (status);
	result = SH_NodeFragment_append_attr_copy (fragment, attr3,
	                                           &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_ptr_ne (name, fragment->attrs[2].name);
	ck_assert_ptr_ne (value, fragment->attrs[2].value);

	ck_assert_int_eq (3, fragment->attr_n);
	ck_assert (Attr_is_equal (attr1, &fragment->attrs[0]));
	ck_assert (Attr_is_equal (attr2, &fragment->attrs[1]));
	ck_assert (Attr_is_equal (attr3, &fragment->attrs[2]));

	/* cleanup */
	SH_NodeFragment_free (fragment);
	SH_Data_free (data);
	SH_Attr_free (attr1);
	SH_Attr_free (attr2);
	SH_Attr_free (attr3);
}
END_TEST

START_TEST(test_node_fragment_attr_remove1_no_status)
{
	SH_Attr * attr;
	SH_Attr * attr1;
	SH_Attr * attr2;
	SH_Attr * attr3;
	SH_Attr * attr4;
	SH_Attr * attr5;
	SH_Attr * attr6;
	SH_Data * data;
	struct SH_NodeFragment * fragment;
	bool result;

	/* setup */
	data = SH_Data_new (NULL);
	ck_assert_ptr_ne (NULL, data);

	attr = malloc (sizeof (SH_Attr));
	ck_assert_ptr_ne (NULL, attr);

	attr1 = SH_Attr_new ("name1", "value1", NULL);
	ck_assert_ptr_ne (NULL, attr1);

	attr2 = SH_Attr_new ("name2", "value2", NULL);
	ck_assert_ptr_ne (NULL, attr2);

	attr3 = SH_Attr_new ("name3", "value3", NULL);
	ck_assert_ptr_ne (NULL, attr3);

	attr4 = SH_Attr_new ("name4", "value4", NULL);
	ck_assert_ptr_ne (NULL, attr4);

	attr5 = SH_Attr_new ("name5", "value5", NULL);
	ck_assert_ptr_ne (NULL, attr5);

	attr6 = SH_Attr_new ("name6", "value6", NULL);
	ck_assert_ptr_ne (NULL, attr6);

	fragment = (SH_NodeFragment *)SH_NodeFragment_new ("html", data,
	                                                   NULL);
	ck_assert_ptr_ne (NULL, fragment);


	result = SH_NodeFragment_append_attr (fragment, attr1, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_attr (fragment, attr2, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_attr (fragment, attr3, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_attr (fragment, attr4, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_attr (fragment, attr5, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_attr (fragment, attr6, NULL);
	ck_assert_int_eq (TRUE, result);


	/* test1 */
	ck_assert_int_eq (6, fragment->attr_n);
	ck_assert_int_le (6, fragment->attr_s);
	ck_assert_int_eq (2*ATTR_CHUNK, fragment->attr_s);

	result = remove_attr (fragment, 0, attr, NULL);
	ck_assert_int_eq (TRUE, result);
	ck_assert_ptr_eq (attr1->name, attr->name);
	ck_assert_ptr_eq (attr1->value, attr->value);

	ck_assert_int_eq (5, fragment->attr_n);
	ck_assert_int_le (5, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);
	ck_assert_ptr_eq (attr2->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr2->value, fragment->attrs[0].value);

	/* test2 */
	result = remove_attr (fragment, 0, attr, NULL);
	ck_assert_int_eq (TRUE, result);
	ck_assert_ptr_eq (attr2->name, attr->name);
	ck_assert_ptr_eq (attr2->value, attr->value);

	ck_assert_int_eq (4, fragment->attr_n);
	ck_assert_int_le (4, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);
	ck_assert_ptr_eq (attr3->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr3->value, fragment->attrs[0].value);

	/* test3 */
	result = remove_attr (fragment, 0, attr, NULL);
	ck_assert_int_eq (TRUE, result);
	ck_assert_ptr_eq (attr3->name, attr->name);
	ck_assert_ptr_eq (attr3->value, attr->value);

	ck_assert_int_eq (3, fragment->attr_n);
	ck_assert_int_le (3, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);
	ck_assert_ptr_eq (attr4->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr4->value, fragment->attrs[0].value);

	/* test4 */
	result = remove_attr (fragment, 0, attr, NULL);
	ck_assert_int_eq (TRUE, result);
	ck_assert_ptr_eq (attr4->name, attr->name);
	ck_assert_ptr_eq (attr4->value, attr->value);

	ck_assert_int_eq (2, fragment->attr_n);
	ck_assert_int_le (2, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);
	ck_assert_ptr_eq (attr5->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr5->value, fragment->attrs[0].value);

	/* test5 */
	result = remove_attr (fragment, 0, attr, NULL);
	ck_assert_int_eq (TRUE, result);
	ck_assert_ptr_eq (attr5->name, attr->name);
	ck_assert_ptr_eq (attr5->value, attr->value);

	ck_assert_int_eq (1, fragment->attr_n);
	ck_assert_int_le (1, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);
	ck_assert_ptr_eq (attr6->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr6->value, fragment->attrs[0].value);

	/* test6 */
	result = remove_attr (fragment, 0, attr, NULL);
	ck_assert_int_eq (TRUE, result);
	ck_assert_ptr_eq (attr6->name, attr->name);
	ck_assert_ptr_eq (attr6->value, attr->value);

	ck_assert_int_eq (0, fragment->attr_n);
	ck_assert_int_le (0, fragment->attr_s);
	ck_assert_int_eq (0, fragment->attr_s);

	/* cleanup */
	SH_NodeFragment_free (fragment);
	SH_Data_free (data);
	SH_Attr_free (attr1);
	SH_Attr_free (attr2);
	SH_Attr_free (attr3);
	SH_Attr_free (attr4);
	SH_Attr_free (attr5);
	SH_Attr_free (attr6);
	free (attr);
}
END_TEST

START_TEST(test_node_fragment_attr_remove1_with_status)
{
	struct SH_Status status;
	SH_Attr * attr;
	SH_Attr * attr1;
	SH_Attr * attr2;
	SH_Attr * attr3;
	SH_Attr * attr4;
	SH_Attr * attr5;
	SH_Attr * attr6;
	SH_Data * data;
	struct SH_NodeFragment * fragment;
	bool result;

	/* setup */
	data = SH_Data_new (NULL);
	ck_assert_ptr_ne (NULL, data);

	attr = malloc (sizeof (SH_Attr));
	ck_assert_ptr_ne (NULL, attr);

	attr1 = SH_Attr_new ("name1", "value1", NULL);
	ck_assert_ptr_ne (NULL, attr1);

	attr2 = SH_Attr_new ("name2", "value2", NULL);
	ck_assert_ptr_ne (NULL, attr2);

	attr3 = SH_Attr_new ("name3", "value3", NULL);
	ck_assert_ptr_ne (NULL, attr3);

	attr4 = SH_Attr_new ("name4", "value4", NULL);
	ck_assert_ptr_ne (NULL, attr4);

	attr5 = SH_Attr_new ("name5", "value5", NULL);
	ck_assert_ptr_ne (NULL, attr5);

	attr6 = SH_Attr_new ("name6", "value6", NULL);
	ck_assert_ptr_ne (NULL, attr6);

	fragment = (SH_NodeFragment *)SH_NodeFragment_new ("html", data,
	                                                   NULL);
	ck_assert_ptr_ne (NULL, fragment);


	result = SH_NodeFragment_append_attr (fragment, attr1, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_attr (fragment, attr2, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_attr (fragment, attr3, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_attr (fragment, attr4, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_attr (fragment, attr5, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_attr (fragment, attr6, NULL);
	ck_assert_int_eq (TRUE, result);


	/* test1 */
	ck_assert_int_eq (6, fragment->attr_n);
	ck_assert_int_le (6, fragment->attr_s);
	ck_assert_int_eq (2*ATTR_CHUNK, fragment->attr_s);

	_status_preinit (status);
	result = remove_attr (fragment, 0, attr, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_ptr_eq (attr1->name, attr->name);
	ck_assert_ptr_eq (attr1->value, attr->value);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_int_eq (5, fragment->attr_n);
	ck_assert_int_le (5, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);
	ck_assert_ptr_eq (attr2->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr2->value, fragment->attrs[0].value);

	/* test2 */
	_status_preinit (status);
	result = remove_attr (fragment, 0, attr, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_ptr_eq (attr2->name, attr->name);
	ck_assert_ptr_eq (attr2->value, attr->value);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_int_eq (4, fragment->attr_n);
	ck_assert_int_le (4, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);
	ck_assert_ptr_eq (attr3->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr3->value, fragment->attrs[0].value);

	/* test3 */
	_status_preinit (status);
	result = remove_attr (fragment, 0, attr, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_ptr_eq (attr3->name, attr->name);
	ck_assert_ptr_eq (attr3->value, attr->value);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_int_eq (3, fragment->attr_n);
	ck_assert_int_le (3, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);
	ck_assert_ptr_eq (attr4->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr4->value, fragment->attrs[0].value);

	/* test4 */
	_status_preinit (status);
	result = remove_attr (fragment, 0, attr, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_ptr_eq (attr4->name, attr->name);
	ck_assert_ptr_eq (attr4->value, attr->value);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_int_eq (2, fragment->attr_n);
	ck_assert_int_le (2, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);
	ck_assert_ptr_eq (attr5->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr5->value, fragment->attrs[0].value);

	/* test5 */
	_status_preinit (status);
	result = remove_attr (fragment, 0, attr, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_ptr_eq (attr5->name, attr->name);
	ck_assert_ptr_eq (attr5->value, attr->value);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_int_eq (1, fragment->attr_n);
	ck_assert_int_le (1, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);
	ck_assert_ptr_eq (attr6->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr6->value, fragment->attrs[0].value);

	/* test6 */
	_status_preinit (status);
	result = remove_attr (fragment, 0, attr, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_ptr_eq (attr6->name, attr->name);
	ck_assert_ptr_eq (attr6->value, attr->value);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_int_eq (0, fragment->attr_n);
	ck_assert_int_le (0, fragment->attr_s);
	ck_assert_int_eq (0, fragment->attr_s);

	/* cleanup */
	SH_NodeFragment_free (fragment);
	SH_Data_free (data);
	SH_Attr_free (attr1);
	SH_Attr_free (attr2);
	SH_Attr_free (attr3);
	SH_Attr_free (attr4);
	SH_Attr_free (attr5);
	SH_Attr_free (attr6);
	free (attr);
}
END_TEST

START_TEST(test_node_fragment_attr_remove2_no_status)
{
	SH_Attr * attr1;
	SH_Attr * attr2;
	SH_Attr * attr3;
	SH_Attr * attr4;
	SH_Attr * attr5;
	SH_Attr * attr6;
	SH_Data * data;
	struct SH_NodeFragment * fragment;
	bool result;

	/* setup */
	data = SH_Data_new (NULL);
	ck_assert_ptr_ne (NULL, data);

	attr1 = SH_Attr_new ("name1", "value1", NULL);
	ck_assert_ptr_ne (NULL, attr1);

	attr2 = SH_Attr_new ("name2", "value2", NULL);
	ck_assert_ptr_ne (NULL, attr2);

	attr3 = SH_Attr_new ("name3", "value3", NULL);
	ck_assert_ptr_ne (NULL, attr3);

	attr4 = SH_Attr_new ("name4", "value4", NULL);
	ck_assert_ptr_ne (NULL, attr4);

	attr5 = SH_Attr_new ("name5", "value5", NULL);
	ck_assert_ptr_ne (NULL, attr5);

	attr6 = SH_Attr_new ("name6", "value6", NULL);
	ck_assert_ptr_ne (NULL, attr6);

	fragment = (SH_NodeFragment *)SH_NodeFragment_new ("html", data,
	                                                   NULL);
	ck_assert_ptr_ne (NULL, fragment);


	result = SH_NodeFragment_append_attr (fragment, attr1, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_attr (fragment, attr2, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_attr (fragment, attr3, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_attr (fragment, attr4, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_attr (fragment, attr5, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_attr (fragment, attr6, NULL);
	ck_assert_int_eq (TRUE, result);


	/* test1 */
	ck_assert_int_eq (6, fragment->attr_n);
	ck_assert_int_le (6, fragment->attr_s);
	ck_assert_int_eq (2*ATTR_CHUNK, fragment->attr_s);

	result = remove_attr (fragment, 0, NULL, NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_int_eq (5, fragment->attr_n);
	ck_assert_int_le (5, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);
	ck_assert_ptr_eq (attr2->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr2->value, fragment->attrs[0].value);

	/* test2 */
	result = remove_attr (fragment, 0, NULL, NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_int_eq (4, fragment->attr_n);
	ck_assert_int_le (4, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);
	ck_assert_ptr_eq (attr3->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr3->value, fragment->attrs[0].value);

	/* test3 */
	result = remove_attr (fragment, 0, NULL, NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_int_eq (3, fragment->attr_n);
	ck_assert_int_le (3, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);
	ck_assert_ptr_eq (attr4->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr4->value, fragment->attrs[0].value);

	/* test4 */
	result = remove_attr (fragment, 0, NULL, NULL);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (2, fragment->attr_n);
	ck_assert_int_le (2, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);
	ck_assert_ptr_eq (attr5->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr5->value, fragment->attrs[0].value);

	/* test5 */
	result = remove_attr (fragment, 0, NULL, NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_int_eq (1, fragment->attr_n);
	ck_assert_int_le (1, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);
	ck_assert_ptr_eq (attr6->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr6->value, fragment->attrs[0].value);

	/* test6 */
	result = remove_attr (fragment, 0, NULL, NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_int_eq (0, fragment->attr_n);
	ck_assert_int_le (0, fragment->attr_s);
	ck_assert_int_eq (0, fragment->attr_s);

	/* cleanup */
	SH_NodeFragment_free (fragment);
	SH_Data_free (data);
	free (attr1);
	free (attr2);
	free (attr3);
	free (attr4);
	free (attr5);
	free (attr6);
}
END_TEST

START_TEST(test_node_fragment_attr_remove2_with_status)
{
	struct SH_Status status;
	SH_Attr * attr1;
	SH_Attr * attr2;
	SH_Attr * attr3;
	SH_Attr * attr4;
	SH_Attr * attr5;
	SH_Attr * attr6;
	SH_Data * data;
	struct SH_NodeFragment * fragment;
	bool result;

	/* setup */
	data = SH_Data_new (NULL);
	ck_assert_ptr_ne (NULL, data);

	attr1 = SH_Attr_new ("name1", "value1", NULL);
	ck_assert_ptr_ne (NULL, attr1);

	attr2 = SH_Attr_new ("name2", "value2", NULL);
	ck_assert_ptr_ne (NULL, attr2);

	attr3 = SH_Attr_new ("name3", "value3", NULL);
	ck_assert_ptr_ne (NULL, attr3);

	attr4 = SH_Attr_new ("name4", "value4", NULL);
	ck_assert_ptr_ne (NULL, attr4);

	attr5 = SH_Attr_new ("name5", "value5", NULL);
	ck_assert_ptr_ne (NULL, attr5);

	attr6 = SH_Attr_new ("name6", "value6", NULL);
	ck_assert_ptr_ne (NULL, attr6);

	fragment = (SH_NodeFragment *)SH_NodeFragment_new ("html", data,
	                                                   NULL);
	ck_assert_ptr_ne (NULL, fragment);


	result = SH_NodeFragment_append_attr (fragment, attr1, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_attr (fragment, attr2, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_attr (fragment, attr3, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_attr (fragment, attr4, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_attr (fragment, attr5, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_attr (fragment, attr6, NULL);
	ck_assert_int_eq (TRUE, result);


	/* test1 */
	ck_assert_int_eq (6, fragment->attr_n);
	ck_assert_int_le (6, fragment->attr_s);
	ck_assert_int_eq (2*ATTR_CHUNK, fragment->attr_s);

	_status_preinit (status);
	result = remove_attr (fragment, 0, NULL, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_int_eq (5, fragment->attr_n);
	ck_assert_int_le (5, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);
	ck_assert_ptr_eq (attr2->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr2->value, fragment->attrs[0].value);

	/* test2 */
	_status_preinit (status);
	result = remove_attr (fragment, 0, NULL, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_int_eq (4, fragment->attr_n);
	ck_assert_int_le (4, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);
	ck_assert_ptr_eq (attr3->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr3->value, fragment->attrs[0].value);

	/* test3 */
	_status_preinit (status);
	result = remove_attr (fragment, 0, NULL, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_int_eq (3, fragment->attr_n);
	ck_assert_int_le (3, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);
	ck_assert_ptr_eq (attr4->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr4->value, fragment->attrs[0].value);

	/* test4 */
	_status_preinit (status);
	result = remove_attr (fragment, 0, NULL, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_int_eq (2, fragment->attr_n);
	ck_assert_int_le (2, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);
	ck_assert_ptr_eq (attr5->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr5->value, fragment->attrs[0].value);

	/* test5 */
	_status_preinit (status);
	result = remove_attr (fragment, 0, NULL, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_int_eq (1, fragment->attr_n);
	ck_assert_int_le (1, fragment->attr_s);
	ck_assert_int_eq (ATTR_CHUNK, fragment->attr_s);
	ck_assert_ptr_eq (attr6->name, fragment->attrs[0].name);
	ck_assert_ptr_eq (attr6->value, fragment->attrs[0].value);

	/* test6 */
	_status_preinit (status);
	result = remove_attr (fragment, 0, NULL, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	ck_assert_int_eq (0, fragment->attr_n);
	ck_assert_int_le (0, fragment->attr_s);
	ck_assert_int_eq (0, fragment->attr_s);

	/* cleanup */
	SH_NodeFragment_free (fragment);
	SH_Data_free (data);
	free (attr1);
	free (attr2);
	free (attr3);
	free (attr4);
	free (attr5);
	free (attr6);
}
END_TEST

START_TEST(test_node_fragment_attr_remove_remove_no_status)
{
	SH_Attr * attr;
	SH_Data * data;
	struct SH_NodeFragment * fragment;
	bool result;

	/* setup */
	attr = SH_Attr_new ("name", "value", NULL);
	ck_assert_ptr_ne (NULL, attr);

	data = SH_Data_new (NULL);
	ck_assert_ptr_ne (NULL, data);

	fragment = (SH_NodeFragment *)SH_NodeFragment_new ("html", data,
	                                                   NULL);
	ck_assert_ptr_ne (NULL, fragment);

	result = SH_NodeFragment_append_attr (fragment, attr, NULL);
	ck_assert_int_eq (TRUE, result);

	/* test - fail */
	result = SH_NodeFragment_remove_attr (fragment, 1, NULL);
	ck_assert_int_eq (FALSE, result);

	/* test - success */
	result = SH_NodeFragment_remove_attr (fragment, 0, NULL);
	ck_assert_int_eq (TRUE, result);

	/* cleanup */
	SH_NodeFragment_free (fragment);
	SH_Data_free (data);
	free (attr);
}
END_TEST

START_TEST(test_node_fragment_attr_remove_remove_with_status)
{
	struct SH_Status status;
	SH_Attr * attr;
	SH_Data * data;
	struct SH_NodeFragment * fragment;
	bool result;

	/* setup */
	attr = SH_Attr_new ("name", "value", NULL);
	ck_assert_ptr_ne (NULL, attr);

	data = SH_Data_new (NULL);
	ck_assert_ptr_ne (NULL, data);

	fragment = (SH_NodeFragment *)SH_NodeFragment_new ("html", data,
	                                                   NULL);
	ck_assert_ptr_ne (NULL, fragment);

	result = SH_NodeFragment_append_attr (fragment, attr, NULL);
	ck_assert_int_eq (TRUE, result);

	/* test - fail */
	_status_preinit (status);
	result = SH_NodeFragment_remove_attr (fragment, 1, &status);
	ck_assert_int_eq (FALSE, result);
	ck_assert_int_eq (E_VALUE, status.status);

	/* test - success */
	_status_preinit (status);
	result = SH_NodeFragment_remove_attr (fragment, 0, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (SUCCESS, status.status);

	/* cleanup */
	SH_NodeFragment_free (fragment);
	SH_Data_free (data);
	free (attr);
}
END_TEST

START_TEST(test_node_fragment_attr_remove_pop_no_status)
{
	SH_Attr * attr;
	SH_Attr * attr_;
	SH_Data * data;
	struct SH_NodeFragment * fragment;
	bool result;

	/* setup */
	attr = SH_Attr_new ("name", "value", NULL);
	ck_assert_ptr_ne (NULL, attr);

	data = SH_Data_new (NULL);
	ck_assert_ptr_ne (NULL, data);

	fragment = (SH_NodeFragment *)SH_NodeFragment_new ("html", data,
	                                                   NULL);
	ck_assert_ptr_ne (NULL, fragment);

	result = SH_NodeFragment_append_attr (fragment, attr, NULL);
	ck_assert_int_eq (TRUE, result);

	/* test - fail */
	attr_ = SH_NodeFragment_pop_attr (fragment, 1, NULL);
	ck_assert_ptr_eq (NULL, attr_);

	/* test - success */
	attr_ = SH_NodeFragment_pop_attr (fragment, 0, NULL);
	ck_assert_ptr_ne (NULL, attr_);
	ck_assert_ptr_eq (attr->name, attr_->name);
	ck_assert_ptr_eq (attr->value, attr_->value);
	SH_Attr_free (attr_);

	/* cleanup */
	SH_NodeFragment_free (fragment);
	SH_Data_free (data);
	free (attr);
}
END_TEST

START_TEST(test_node_fragment_attr_remove_pop_with_status)
{
	struct SH_Status status;
	SH_Attr * attr;
	SH_Attr * attr_;
	SH_Data * data;
	struct SH_NodeFragment * fragment;
	bool result;

	/* setup */
	attr = SH_Attr_new ("name", "value", NULL);
	ck_assert_ptr_ne (NULL, attr);

	data = SH_Data_new (NULL);
	ck_assert_ptr_ne (NULL, data);

	fragment = (SH_NodeFragment *)SH_NodeFragment_new ("html", data,
	                                                   NULL);
	ck_assert_ptr_ne (NULL, fragment);

	result = SH_NodeFragment_append_attr (fragment, attr, NULL);
	ck_assert_int_eq (TRUE, result);

	/* test - fail */
	_status_preinit (status);
	attr_ = SH_NodeFragment_pop_attr (fragment, 1, &status);
	ck_assert_ptr_eq (NULL, attr_);
	ck_assert_int_eq (E_VALUE, status.status);

	/* test - success */
	_status_preinit (status);
	attr_ = SH_NodeFragment_pop_attr (fragment, 0, &status);
	ck_assert_ptr_ne (NULL, attr_);
	ck_assert_int_eq (SUCCESS, status.status);
	ck_assert_ptr_eq (attr->name, attr_->name);
	ck_assert_ptr_eq (attr->value, attr_->value);
	SH_Attr_free (attr_);

	/* cleanup */
	SH_NodeFragment_free (fragment);
	SH_Data_free (data);
	free (attr);
}
END_TEST

START_TEST(test_node_fragment_child_alloc)
{
	#define alloc_size get_child_alloc_size
	ck_assert_int_eq (0, alloc_size (0));
	ck_assert_int_eq (CHILD_CHUNK, alloc_size (1));
	ck_assert_int_eq (CHILD_CHUNK, alloc_size (CHILD_CHUNK));
	ck_assert_int_eq (2*CHILD_CHUNK, alloc_size (CHILD_CHUNK+1));
	ck_assert_int_eq (SIZE_MAX, alloc_size (SIZE_MAX));
	for (size_t i = 0; i < CHILD_CHUNK; i++)
	{
		ck_assert_int_le (SIZE_MAX-i, alloc_size (SIZE_MAX-i));
	}
	#undef alloc_size
}
END_TEST

START_TEST(test_node_fragment_child)
{
	struct SH_Status status;
	struct SH_Fragment * parent;
	struct SH_Fragment * child1;
	struct SH_Fragment * child2;
	struct SH_Data * data;
	bool boolean;

	data = SH_Data_new (NULL);

	parent = SH_NodeFragment_new ("html", data, NULL);
	child1 = SH_NodeFragment_new ("head", data, NULL);
	child2 = SH_NodeFragment_new ("body", data, NULL);

	/* no error */
	ck_assert_int_eq (((struct SH_NodeFragment *) parent)->child_n, 0);

	boolean = SH_NodeFragment_append_child (((struct SH_NodeFragment *) parent),
						child1, NULL);
	ck_assert_int_eq (boolean, TRUE);
	ck_assert_int_eq (((struct SH_NodeFragment *) parent)->child_n,
			  1);
	ck_assert_ptr_eq (((struct SH_NodeFragment *) parent)->childs[0],
			  child1);

	ck_assert_ptr_eq (parent, get_parent (child1));

	/* with error */
	ck_assert_int_eq (((struct SH_NodeFragment *) parent)->child_n, 1);

	_status_preinit (status);
	boolean = SH_NodeFragment_append_child (((struct SH_NodeFragment *) parent),
						child2, &status);
	ck_assert_int_eq (boolean, TRUE);
	ck_assert_int_eq (status.status, SUCCESS);
	ck_assert_int_eq (((struct SH_NodeFragment *) parent)->child_n,
			  2);
	ck_assert_ptr_eq (((struct SH_NodeFragment *) parent)->childs[1],
			  child2);

	ck_assert_ptr_eq (parent, get_parent (child2));

	SH_Fragment_free (parent);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_get_child)
{
	struct SH_Status status;
	struct SH_Fragment * parent;
	struct SH_Fragment * child1;
	const struct SH_Fragment * child2;
	struct SH_Data * data;

	data = SH_Data_new (NULL);

	parent = SH_NodeFragment_new ("html", data, NULL);
	child1 = SH_NodeFragment_new ("body", data, NULL);

	SH_NodeFragment_append_child (((struct SH_NodeFragment *) parent),
				      child1, NULL);

	/* without error */
	child2 = SH_NodeFragment_get_child (((struct SH_NodeFragment *) parent),
					    0, NULL);
	ck_assert_ptr_eq (child1, child2);

	child2 = SH_NodeFragment_get_child (((struct SH_NodeFragment *) parent),
					    1, NULL);
	ck_assert_ptr_eq (NULL, child2);

	/* with error */
	_status_preinit (status);
	child2 = SH_NodeFragment_get_child (((struct SH_NodeFragment *) parent),
					    0, &status);
	ck_assert_ptr_eq (child1, child2);
	ck_assert_int_eq (status.status, SUCCESS);

	_status_preinit (status);
	child2 = SH_NodeFragment_get_child (((struct SH_NodeFragment *) parent),
					    1, &status);
	ck_assert_ptr_eq (NULL, child2);
	ck_assert_int_eq (status.status, E_VALUE);

	SH_Fragment_free (parent);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_is_child)
{
	struct SH_Fragment * parent;
	struct SH_Fragment * child1;
	struct SH_Fragment * child2;
	struct SH_Data * data;
	bool boolean;

	data = SH_Data_new (NULL);

	parent = SH_NodeFragment_new ("html", data, NULL);
	child1 = SH_NodeFragment_new ("head", data, NULL);
	child2 = SH_NodeFragment_new ("title", data, NULL);

	SH_NodeFragment_append_child (((struct SH_NodeFragment *) parent),
				      child1, NULL);
	SH_NodeFragment_append_child (((struct SH_NodeFragment *) child1),
				      child2, NULL);

	boolean = SH_NodeFragment_is_child (((struct SH_NodeFragment *) parent),
					    child1);
	ck_assert_int_eq (boolean, TRUE);

	boolean = SH_NodeFragment_is_child (((struct SH_NodeFragment *) parent),
					    child2);
	ck_assert_int_eq (boolean, FALSE);

	boolean = SH_NodeFragment_is_child (((struct SH_NodeFragment *) child1),
					    child2);
	ck_assert_int_eq (boolean, TRUE);

	SH_Fragment_free (parent);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_is_descendant)
{
	struct SH_Fragment * parent;
	struct SH_Fragment * child1;
	struct SH_Fragment * child2;
	struct SH_Fragment * child3;
	struct SH_Data * data;
	bool boolean;

	data = SH_Data_new (NULL);

	parent = SH_NodeFragment_new ("html", data, NULL);
	child1 = SH_NodeFragment_new ("head", data, NULL);
	child2 = SH_NodeFragment_new ("body", data, NULL);
	child3 = SH_NodeFragment_new ("title", data, NULL);

	SH_NodeFragment_append_child (((struct SH_NodeFragment *) parent),
				       child1, NULL);
	SH_NodeFragment_append_child (((struct SH_NodeFragment *) parent),
				       child2, NULL);
	SH_NodeFragment_append_child (((struct SH_NodeFragment *) child1),
				       child3, NULL);

	boolean = SH_NodeFragment_is_descendant (((struct SH_NodeFragment *) parent),
						  child1);
	ck_assert_int_eq (boolean, TRUE);

	boolean = SH_NodeFragment_is_descendant (((struct SH_NodeFragment *) parent),
						  child2);
	ck_assert_int_eq (boolean, TRUE);

	boolean = SH_NodeFragment_is_descendant (((struct SH_NodeFragment *) parent),
						  child3);
	ck_assert_int_eq (boolean, TRUE);

	boolean = SH_NodeFragment_is_descendant (((struct SH_NodeFragment *) child1),
						  child2);
	ck_assert_int_eq (boolean, FALSE);

	boolean = SH_NodeFragment_is_descendant (((struct SH_NodeFragment *) child1),
						  child3);
	ck_assert_int_eq (boolean, TRUE);

	boolean = SH_NodeFragment_is_descendant (((struct SH_NodeFragment *) child2),
						  child3);
	ck_assert_int_eq (boolean, FALSE);

	SH_Fragment_free (parent);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_is_parent)
{
	struct SH_Fragment * parent;
	struct SH_Fragment * child1;
	struct SH_Fragment * child2;
	struct SH_Data * data;
	bool boolean;

	data = SH_Data_new (NULL);

	parent = SH_NodeFragment_new ("html", data, NULL);
	child1 = SH_NodeFragment_new ("head", data, NULL);
	child2 = SH_NodeFragment_new ("title", data, NULL);

	SH_NodeFragment_append_child (((struct SH_NodeFragment *) parent),
				      child1, NULL);
	SH_NodeFragment_append_child (((struct SH_NodeFragment *) child1),
				      child2, NULL);

	boolean = SH_NodeFragment_is_parent (child1,
	                                     (struct SH_NodeFragment *)
	                                     parent);
	ck_assert_int_eq (boolean, TRUE);

	boolean = SH_NodeFragment_is_parent (child2,
	                                     (struct SH_NodeFragment *)
	                                     parent);
	ck_assert_int_eq (boolean, FALSE);

	boolean = SH_NodeFragment_is_parent (child2,
	                                     (struct SH_NodeFragment *)
	                                     child1);
	ck_assert_int_eq (boolean, TRUE);

	SH_Fragment_free (parent);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_is_ancestor)
{
	struct SH_Fragment * parent;
	struct SH_Fragment * child1;
	struct SH_Fragment * child2;
	struct SH_Fragment * child3;
	struct SH_Data * data;
	bool boolean;

	data = SH_Data_new (NULL);

	parent = SH_NodeFragment_new ("html", data, NULL);
	child1 = SH_NodeFragment_new ("head", data, NULL);
	child2 = SH_NodeFragment_new ("body", data, NULL);
	child3 = SH_NodeFragment_new ("title", data, NULL);

	SH_NodeFragment_append_child (((struct SH_NodeFragment *)parent),
				       child1, NULL);
	SH_NodeFragment_append_child (((struct SH_NodeFragment *)parent),
				       child2, NULL);
	SH_NodeFragment_append_child (((struct SH_NodeFragment *)child1),
				       child3, NULL);

	boolean = SH_NodeFragment_is_ancestor (child1,
	                                       ((struct SH_NodeFragment *)
	                                       parent));
	ck_assert_int_eq (boolean, TRUE);

	boolean = SH_NodeFragment_is_ancestor (child2,
	                                       ((struct SH_NodeFragment *)
	                                       parent));
	ck_assert_int_eq (boolean, TRUE);

	boolean = SH_NodeFragment_is_ancestor (child3,
	                                       ((struct SH_NodeFragment *)
	                                       parent));
	ck_assert_int_eq (boolean, TRUE);

	boolean = SH_NodeFragment_is_ancestor (child2,
	                                       ((struct SH_NodeFragment *)
	                                       child1));
	ck_assert_int_eq (boolean, FALSE);

	boolean = SH_NodeFragment_is_ancestor (child3,
	                                       ((struct SH_NodeFragment *)
	                                       child1));
	ck_assert_int_eq (boolean, TRUE);

	boolean = SH_NodeFragment_is_ancestor (child3,
	                                       ((struct SH_NodeFragment *)
	                                       child2));
	ck_assert_int_eq (boolean, FALSE);

	SH_Fragment_free (parent);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_child_insert_no_status)
{
	SH_Data * data;
	struct SH_NodeFragment * parent;
	struct SH_Fragment * child;
	struct SH_Fragment * child1;
	struct SH_Fragment * child2;
	struct SH_Fragment * child3;
	bool result;

	data = SH_Data_new (NULL);

	parent = (struct SH_NodeFragment *)
	         SH_NodeFragment_new ("body", data, NULL);
	child1 = SH_NodeFragment_new ("header", data, NULL);
	child2 = SH_NodeFragment_new ("main", data, NULL);
	child3 = SH_NodeFragment_new ("footer", data, NULL);

	/* insert - success */
	result = insert_child (parent, child1, 0, NULL);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (1, parent->child_n);
	ck_assert_int_le (1, parent->child_s);
	ck_assert_int_eq (CHILD_CHUNK, parent->child_s);
	ck_assert_ptr_eq (child1, parent->childs[0]);
	ck_assert_ptr_eq (parent, child1->parent);

	/* reinsert - failing */
	result = insert_child (parent, child1, 0, NULL);
	ck_assert_int_eq (FALSE, result);

	/* insert copy - success */
	child = SH_Fragment_copy (child1, NULL);
	result = insert_child (parent, child, 0, NULL);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (2, parent->child_n);
	ck_assert_int_le (2, parent->child_s);
	ck_assert_int_eq (CHILD_CHUNK, parent->child_s);
	ck_assert_ptr_eq (child, parent->childs[0]);
	ck_assert_ptr_eq (child1, parent->childs[1]);
	ck_assert_ptr_eq (parent, child->parent);
	ck_assert_ptr_eq (parent, child1->parent);

	/* insert parent into child - failing */
	result = insert_child ((struct SH_NodeFragment *)child1,
	                       (struct SH_Fragment *)parent,
	                       0, NULL);
	ck_assert_int_eq (FALSE, result);

	/* insert inbetween */
	result = insert_child (parent, child2, 1, NULL);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (3, parent->child_n);
	ck_assert_int_le (3, parent->child_s);
	ck_assert_int_eq (CHILD_CHUNK, parent->child_s);
	ck_assert_ptr_eq (child, parent->childs[0]);
	ck_assert_ptr_eq (child1, parent->childs[2]);
	ck_assert_ptr_eq (child2, parent->childs[1]);
	ck_assert_ptr_eq (parent, child->parent);
	ck_assert_ptr_eq (parent, child1->parent);
	ck_assert_ptr_eq (parent, child2->parent);

	/* insert after */
	result = insert_child (parent, child3, 3, NULL);
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (4, parent->child_n);
	ck_assert_int_le (4, parent->child_s);
	ck_assert_int_eq (CHILD_CHUNK, parent->child_s);
	ck_assert_ptr_eq (child, parent->childs[0]);
	ck_assert_ptr_eq (child1, parent->childs[2]);
	ck_assert_ptr_eq (child2, parent->childs[1]);
	ck_assert_ptr_eq (child3, parent->childs[3]);
	ck_assert_ptr_eq (parent, child->parent);
	ck_assert_ptr_eq (parent, child1->parent);
	ck_assert_ptr_eq (parent, child2->parent);
	ck_assert_ptr_eq (parent, child3->parent);

	SH_NodeFragment_free (parent);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_child_insert_with_status)
{
	struct SH_Status status;
	SH_Data * data;
	struct SH_NodeFragment * parent;
	struct SH_Fragment * child;
	struct SH_Fragment * child1;
	struct SH_Fragment * child2;
	struct SH_Fragment * child3;
	bool result;

	data = SH_Data_new (NULL);

	parent = (struct SH_NodeFragment *)
	         SH_NodeFragment_new ("body", data, NULL);
	child1 = SH_NodeFragment_new ("header", data, NULL);
	child2 = SH_NodeFragment_new ("main", data, NULL);
	child3 = SH_NodeFragment_new ("footer", data, NULL);

	/* insert - success */
	_status_preinit (status);
	result = insert_child (parent, child1, 0, &status);
	ck_assert (succeed (&status));
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (1, parent->child_n);
	ck_assert_int_le (1, parent->child_s);
	ck_assert_int_eq (CHILD_CHUNK, parent->child_s);
	ck_assert_ptr_eq (child1, parent->childs[0]);
	ck_assert_ptr_eq (parent, child1->parent);

	/* reinsert - failing */
	_status_preinit (status);
	result = insert_child (parent, child1, 0, &status);
	ck_assert (failed (&status));
	ck_assert_int_eq (FALSE, result);
	ck_assert_int_eq (E_STATE, status.status);

	/* insert copy - success */
	child = SH_Fragment_copy (child1, NULL);
	_status_preinit (status);
	result = insert_child (parent, child, 0, &status);
	ck_assert (succeed (&status));
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (2, parent->child_n);
	ck_assert_int_le (2, parent->child_s);
	ck_assert_int_eq (CHILD_CHUNK, parent->child_s);
	ck_assert_ptr_eq (child, parent->childs[0]);
	ck_assert_ptr_eq (child1, parent->childs[1]);
	ck_assert_ptr_eq (parent, child->parent);
	ck_assert_ptr_eq (parent, child1->parent);

	/* insert parent into child - failing */
	_status_preinit (status);
	result = insert_child ((struct SH_NodeFragment *)child1,
	                       (struct SH_Fragment *)parent,
	                       0, &status);
	ck_assert (failed (&status));
	ck_assert_int_eq (FALSE, result);
	ck_assert_int_eq (E_STATE, status.status);

	/* insert inbetween */
	_status_preinit (status);
	result = insert_child (parent, child2, 1, &status);
	ck_assert (succeed (&status));
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (3, parent->child_n);
	ck_assert_int_le (3, parent->child_s);
	ck_assert_int_eq (CHILD_CHUNK, parent->child_s);
	ck_assert_ptr_eq (child, parent->childs[0]);
	ck_assert_ptr_eq (child1, parent->childs[2]);
	ck_assert_ptr_eq (child2, parent->childs[1]);
	ck_assert_ptr_eq (parent, child->parent);
	ck_assert_ptr_eq (parent, child1->parent);
	ck_assert_ptr_eq (parent, child2->parent);

	/* insert after */
	_status_preinit (status);
	result = insert_child (parent, child3, 3, &status);
	ck_assert (succeed (&status));
	ck_assert_int_eq (TRUE, result);
	ck_assert_int_eq (4, parent->child_n);
	ck_assert_int_le (4, parent->child_s);
	ck_assert_int_eq (CHILD_CHUNK, parent->child_s);
	ck_assert_ptr_eq (child, parent->childs[0]);
	ck_assert_ptr_eq (child1, parent->childs[2]);
	ck_assert_ptr_eq (child2, parent->childs[1]);
	ck_assert_ptr_eq (child3, parent->childs[3]);
	ck_assert_ptr_eq (parent, child->parent);
	ck_assert_ptr_eq (parent, child1->parent);
	ck_assert_ptr_eq (parent, child2->parent);
	ck_assert_ptr_eq (parent, child3->parent);

	SH_NodeFragment_free (parent);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_child_insert_insert_no_status)
{
	struct SH_NodeFragment * parent;
	struct SH_Fragment * child1;
	struct SH_Fragment * child2;
	struct SH_Fragment * child3;
	SH_Data * data;
	bool result;

	data = SH_Data_new (NULL);

	parent = (struct SH_NodeFragment *)SH_NodeFragment_new ("body",
	                                                        data,
	                                                        NULL);
	child1 = SH_NodeFragment_new ("header", data, NULL);
	child2 = SH_NodeFragment_new ("main", data, NULL);
	child3 = SH_NodeFragment_new ("footer", data, NULL);

	/* out of range - fail */
	result = SH_NodeFragment_insert_child (parent, child1, 1, NULL);
	ck_assert_int_eq (FALSE, result);

	/* insert - success */
	result = SH_NodeFragment_insert_child (parent, child2, 0, NULL);
	ck_assert_int_eq (TRUE, result);

	/* insert before - success */
	result = SH_NodeFragment_prepend_child (parent, child1, NULL);
	ck_assert_int_eq (TRUE, result);

	/* insert after - success */
	result = SH_NodeFragment_append_child (parent, child3, NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_int_eq (3, parent->child_n);
	ck_assert_ptr_eq (child1, parent->childs[0]);
	ck_assert_ptr_eq (child2, parent->childs[1]);
	ck_assert_ptr_eq (child3, parent->childs[2]);

	SH_NodeFragment_free (parent);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_child_insert_insert_with_status)
{
	struct SH_Status status;
	struct SH_NodeFragment * parent;
	struct SH_Fragment * child1;
	struct SH_Fragment * child2;
	struct SH_Fragment * child3;
	SH_Data * data;
	bool result;

	data = SH_Data_new (NULL);

	parent = (struct SH_NodeFragment *)SH_NodeFragment_new ("body",
	                                                        data,
	                                                        NULL);
	child1 = SH_NodeFragment_new ("header", data, NULL);
	child2 = SH_NodeFragment_new ("main", data, NULL);
	child3 = SH_NodeFragment_new ("footer", data, NULL);

	/* out of range - fail */
	_status_preinit (status);
	result = SH_NodeFragment_insert_child (parent, child1, 1,
	                                       &status);
	ck_assert_int_eq (FALSE, result);
	ck_assert_int_eq (E_VALUE, status.status);
	ck_assert (failed (&status));

	/* insert - success */
	_status_preinit (status);
	result = SH_NodeFragment_insert_child (parent, child2, 0,
	                                       &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert (succeed (&status));

	/* insert before - success */
	_status_preinit (status);
	result = SH_NodeFragment_prepend_child (parent, child1,
	                                        &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert (succeed (&status));

	/* insert after - success */
	_status_preinit (status);
	result = SH_NodeFragment_append_child (parent, child3,
	                                       &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert (succeed (&status));

	ck_assert_int_eq (3, parent->child_n);
	ck_assert_ptr_eq (child1, parent->childs[0]);
	ck_assert_ptr_eq (child2, parent->childs[1]);
	ck_assert_ptr_eq (child3, parent->childs[2]);

	SH_NodeFragment_free (parent);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_child_insert_relative_no_status)
{
	struct SH_NodeFragment * parent;
	struct SH_Fragment * child1;
	struct SH_Fragment * child2;
	struct SH_Fragment * child3;
	SH_Data * data;
	bool result;

	data = SH_Data_new (NULL);

	parent = (struct SH_NodeFragment *)SH_NodeFragment_new ("body",
	                                                        data,
	                                                        NULL);
	child1 = SH_NodeFragment_new ("header", data, NULL);
	child2 = SH_NodeFragment_new ("main", data, NULL);
	child3 = SH_NodeFragment_new ("footer", data, NULL);

	/* test erroneous call */
	result = SH_NodeFragment_insert_child_before (child2, child1,
	                                              NULL);
	ck_assert_int_eq (FALSE, result);

	result = SH_NodeFragment_insert_child_after (child2, child3,
	                                             NULL);
	ck_assert_int_eq (FALSE, result);

	/* test bug check */
	child2->parent = parent;

	result = SH_NodeFragment_insert_child_before (child2, child1,
	                                              NULL);
	ck_assert_int_eq (FALSE, result);

	result = SH_NodeFragment_insert_child_after (child2, child3,
	                                             NULL);
	ck_assert_int_eq (FALSE, result);

	child2->parent = NULL;

	/* test real */
	result = SH_NodeFragment_insert_child (parent, child2, 0,
	                                       NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_insert_child_before (child2, child1,
	                                              NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_insert_child_after (child2, child3,
	                                             NULL);
	ck_assert_int_eq (TRUE, result);

	ck_assert_int_eq (3, parent->child_n);
	ck_assert_ptr_eq (child1, parent->childs[0]);
	ck_assert_ptr_eq (child2, parent->childs[1]);
	ck_assert_ptr_eq (child3, parent->childs[2]);

	SH_NodeFragment_free (parent);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_child_insert_relative_with_status)
{
	struct SH_Status status;
	struct SH_NodeFragment * parent;
	struct SH_Fragment * child1;
	struct SH_Fragment * child2;
	struct SH_Fragment * child3;
	SH_Data * data;
	bool result;

	data = SH_Data_new (NULL);

	parent = (struct SH_NodeFragment *)SH_NodeFragment_new ("body",
	                                                        data,
	                                                        NULL);
	child1 = SH_NodeFragment_new ("header", data, NULL);
	child2 = SH_NodeFragment_new ("main", data, NULL);
	child3 = SH_NodeFragment_new ("footer", data, NULL);

	/* test erroneous call */
	_status_preinit (status);
	result = SH_NodeFragment_insert_child_before (child2, child1,
	                                              &status);
	ck_assert_int_eq (FALSE, result);
	ck_assert_int_eq (E_STATE, status.status);
	ck_assert (failed (&status));

	_status_preinit (status);
	result = SH_NodeFragment_insert_child_after (child2, child3,
	                                             &status);
	ck_assert_int_eq (FALSE, result);
	ck_assert_int_eq (E_STATE, status.status);
	ck_assert (failed (&status));

	/* test bug check */
	child2->parent = parent;

	_status_preinit (status);
	result = SH_NodeFragment_insert_child_before (child2, child1,
	                                              &status);
	ck_assert_int_eq (FALSE, result);
	ck_assert_int_eq (E_BUG, status.status);
	ck_assert (failed (&status));

	_status_preinit (status);
	result = SH_NodeFragment_insert_child_after (child2, child3,
	                                             &status);
	ck_assert_int_eq (FALSE, result);
	ck_assert_int_eq (E_BUG, status.status);
	ck_assert (failed (&status));

	child2->parent = NULL;

	/* test real */
	_status_preinit (status);
	result = SH_NodeFragment_insert_child (parent, child2, 0,
	                                       &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert (succeed (&status));

	_status_preinit (status);
	result = SH_NodeFragment_insert_child_before (child2, child1,
	                                              &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert (succeed (&status));

	_status_preinit (status);
	result = SH_NodeFragment_insert_child_after (child2, child3,
	                                             &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert (succeed (&status));

	ck_assert_int_eq (3, parent->child_n);
	ck_assert_ptr_eq (child1, parent->childs[0]);
	ck_assert_ptr_eq (child2, parent->childs[1]);
	ck_assert_ptr_eq (child3, parent->childs[2]);

	SH_NodeFragment_free (parent);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_child_remove_no_status)
{
	struct SH_NodeFragment * parent;
	struct SH_Fragment * child;
	struct SH_Fragment * child1;
	struct SH_Fragment * child2;
	struct SH_Fragment * child3;
	struct SH_Fragment * child4;
	struct SH_Fragment * child5;
	struct SH_Fragment * child6;
	SH_Data * data;
	bool result;

	data = SH_Data_new (NULL);

	parent = (struct SH_NodeFragment *)SH_NodeFragment_new ("body",
	                                                        data,
	                                                        NULL);
	child1 = SH_NodeFragment_new ("p", data, NULL);
	child2 = SH_NodeFragment_new ("p", data, NULL);
	child3 = SH_NodeFragment_new ("p", data, NULL);
	child4 = SH_NodeFragment_new ("p", data, NULL);
	child5 = SH_NodeFragment_new ("p", data, NULL);
	child6 = SH_NodeFragment_new ("p", data, NULL);

	result = SH_NodeFragment_append_child (parent, child1, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_child (parent, child2, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_child (parent, child3, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_child (parent, child4, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_child (parent, child5, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_child (parent, child6, NULL);
	ck_assert_int_eq (TRUE, result);


	ck_assert_int_eq (10, parent->child_s);
	ck_assert_int_eq (6, parent->child_n);
	ck_assert_ptr_eq (child1, parent->childs[0]);

	child = remove_child (parent, 0, NULL);
	ck_assert_ptr_eq (child, child1);
	ck_assert_ptr_eq (NULL, child->parent);
	SH_Fragment_free (child1);
	ck_assert_int_eq (5, parent->child_s);
	ck_assert_int_eq (5, parent->child_n);
	ck_assert_ptr_eq (child2, parent->childs[0]);

	child = remove_child (parent, 0, NULL);
	ck_assert_ptr_eq (child, child2);
	ck_assert_ptr_eq (NULL, child->parent);
	SH_Fragment_free (child2);
	ck_assert_int_eq (5, parent->child_s);
	ck_assert_int_eq (4, parent->child_n);
	ck_assert_ptr_eq (child3, parent->childs[0]);

	child = remove_child (parent, 0, NULL);
	ck_assert_ptr_eq (child, child3);
	ck_assert_ptr_eq (NULL, child->parent);
	SH_Fragment_free (child3);
	ck_assert_int_eq (5, parent->child_s);
	ck_assert_int_eq (3, parent->child_n);
	ck_assert_ptr_eq (child4, parent->childs[0]);

	child = remove_child (parent, 0, NULL);
	ck_assert_ptr_eq (child, child4);
	ck_assert_ptr_eq (NULL, child->parent);
	SH_Fragment_free (child4);
	ck_assert_int_eq (5, parent->child_s);
	ck_assert_int_eq (2, parent->child_n);
	ck_assert_ptr_eq (child5, parent->childs[0]);

	child = remove_child (parent, 0, NULL);
	ck_assert_ptr_eq (child, child5);
	ck_assert_ptr_eq (NULL, child->parent);
	SH_Fragment_free (child5);
	ck_assert_int_eq (5, parent->child_s);
	ck_assert_int_eq (1, parent->child_n);
	ck_assert_ptr_eq (child6, parent->childs[0]);

	child = remove_child (parent, 0, NULL);
	ck_assert_ptr_eq (child, child6);
	ck_assert_ptr_eq (NULL, child->parent);
	SH_Fragment_free (child6);
	ck_assert_int_eq (0, parent->child_s);
	ck_assert_int_eq (0, parent->child_n);

	SH_NodeFragment_free (parent);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_child_remove_with_status)
{
	struct SH_Status status;
	struct SH_NodeFragment * parent;
	struct SH_Fragment * child;
	struct SH_Fragment * child1;
	struct SH_Fragment * child2;
	struct SH_Fragment * child3;
	struct SH_Fragment * child4;
	struct SH_Fragment * child5;
	struct SH_Fragment * child6;
	SH_Data * data;
	bool result;

	data = SH_Data_new (NULL);

	parent = (struct SH_NodeFragment *)SH_NodeFragment_new ("body",
	                                                        data,
	                                                        NULL);
	child1 = SH_NodeFragment_new ("p", data, NULL);
	child2 = SH_NodeFragment_new ("p", data, NULL);
	child3 = SH_NodeFragment_new ("p", data, NULL);
	child4 = SH_NodeFragment_new ("p", data, NULL);
	child5 = SH_NodeFragment_new ("p", data, NULL);
	child6 = SH_NodeFragment_new ("p", data, NULL);

	result = SH_NodeFragment_append_child (parent, child1, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_child (parent, child2, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_child (parent, child3, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_child (parent, child4, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_child (parent, child5, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_append_child (parent, child6, NULL);
	ck_assert_int_eq (TRUE, result);


	ck_assert_int_eq (10, parent->child_s);
	ck_assert_int_eq (6, parent->child_n);
	ck_assert_ptr_eq (child1, parent->childs[0]);

	_status_preinit (status);
	child = remove_child (parent, 0, &status);
	ck_assert_ptr_eq (child, child1);
	ck_assert_ptr_eq (NULL, child->parent);
	ck_assert (succeed (&status));
	SH_Fragment_free (child1);
	ck_assert_int_eq (5, parent->child_s);
	ck_assert_int_eq (5, parent->child_n);
	ck_assert_ptr_eq (child2, parent->childs[0]);

	_status_preinit (status);
	child = remove_child (parent, 0, &status);
	ck_assert_ptr_eq (child, child2);
	ck_assert_ptr_eq (NULL, child->parent);
	ck_assert (succeed (&status));
	SH_Fragment_free (child2);
	ck_assert_int_eq (5, parent->child_s);
	ck_assert_int_eq (4, parent->child_n);
	ck_assert_ptr_eq (child3, parent->childs[0]);

	_status_preinit (status);
	child = remove_child (parent, 0, &status);
	ck_assert_ptr_eq (child, child3);
	ck_assert_ptr_eq (NULL, child->parent);
	ck_assert (succeed (&status));
	SH_Fragment_free (child3);
	ck_assert_int_eq (5, parent->child_s);
	ck_assert_int_eq (3, parent->child_n);
	ck_assert_ptr_eq (child4, parent->childs[0]);

	_status_preinit (status);
	child = remove_child (parent, 0, &status);
	ck_assert_ptr_eq (child, child4);
	ck_assert_ptr_eq (NULL, child->parent);
	ck_assert (succeed (&status));
	SH_Fragment_free (child4);
	ck_assert_int_eq (5, parent->child_s);
	ck_assert_int_eq (2, parent->child_n);
	ck_assert_ptr_eq (child5, parent->childs[0]);

	_status_preinit (status);
	child = remove_child (parent, 0, &status);
	ck_assert_ptr_eq (child, child5);
	ck_assert_ptr_eq (NULL, child->parent);
	ck_assert (succeed (&status));
	SH_Fragment_free (child5);
	ck_assert_int_eq (5, parent->child_s);
	ck_assert_int_eq (1, parent->child_n);
	ck_assert_ptr_eq (child6, parent->childs[0]);

	_status_preinit (status);
	child = remove_child (parent, 0, &status);
	ck_assert_ptr_eq (child, child6);
	ck_assert_ptr_eq (NULL, child->parent);
	ck_assert (succeed (&status));
	SH_Fragment_free (child6);
	ck_assert_int_eq (0, parent->child_s);
	ck_assert_int_eq (0, parent->child_n);

	SH_NodeFragment_free (parent);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_child_remove_remove_self_no_status)
{
	struct SH_Fragment * parent;
	struct SH_Fragment * child;
	SH_Data * data;
	bool result;

	data = SH_Data_new (NULL);

	parent = SH_NodeFragment_new ("html", data, NULL);
	child = SH_NodeFragment_new ("head", data, NULL);

	result = SH_NodeFragment_append_child ((struct SH_NodeFragment *)
	                                       parent, child, NULL);
	ck_assert_int_eq (TRUE, result);

	/* test erroneous call */
	result = SH_Fragment_remove (parent, NULL);
	ck_assert_int_eq (FALSE, result);

	/* test real */
	result = SH_Fragment_remove (child, NULL);
	ck_assert_int_eq (TRUE, result);

	/* test bug check */
	child->parent = (struct SH_NodeFragment *)parent;
	result = SH_Fragment_remove (child, NULL);
	ck_assert_int_eq (FALSE, result);

	SH_Fragment_free (parent);
	SH_Fragment_free (child);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_child_remove_remove_self_with_status)
{
	struct SH_Status status;
	struct SH_Fragment * parent;
	struct SH_Fragment * child;
	SH_Data * data;
	bool result;

	data = SH_Data_new (NULL);

	parent = SH_NodeFragment_new ("html", data, NULL);
	child = SH_NodeFragment_new ("head", data, NULL);

	result = SH_NodeFragment_append_child ((struct SH_NodeFragment *)
	                                       parent, child, NULL);
	ck_assert_int_eq (TRUE, result);

	/* test erroneous call */
	_status_preinit (status);
	result = SH_Fragment_remove (parent, &status);
	ck_assert_int_eq (FALSE, result);
	ck_assert (failed (&status));
	ck_assert_int_eq (E_STATE, status.status);

	/* test real */
	_status_preinit (status);
	result = SH_Fragment_remove (child, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert (succeed (&status));

	/* test bug check */
	child->parent = (struct SH_NodeFragment *)parent;
	_status_preinit (status);
	result = SH_Fragment_remove (child, &status);
	ck_assert_int_eq (FALSE, result);
	ck_assert (failed (&status));
	ck_assert_int_eq (E_BUG, status.status);

	SH_Fragment_free (parent);
	SH_Fragment_free (child);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_child_remove_delete_self_no_status)
{
	struct SH_Fragment * parent;
	struct SH_Fragment * child;
	SH_Data * data;
	bool result;

	data = SH_Data_new (NULL);

	parent = SH_NodeFragment_new ("html", data, NULL);
	child = SH_NodeFragment_new ("head", data, NULL);

	/* test erroneous call */
	result = SH_Fragment_delete (parent, NULL);
	ck_assert_int_eq (FALSE, result);

	/* test bug check */
	child->parent = (struct SH_NodeFragment *)parent;
	result = SH_Fragment_delete (child, NULL);
	ck_assert_int_eq (FALSE, result);
	child->parent = NULL;

	result = SH_NodeFragment_append_child ((struct SH_NodeFragment *)
	                                       parent, child, NULL);
	ck_assert_int_eq (TRUE, result);

	/* test real */
	result = SH_Fragment_delete (child, NULL);
	ck_assert_int_eq (TRUE, result);

	SH_Fragment_free (parent);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_child_remove_delete_self_with_status)
{
	struct SH_Status status;
	struct SH_Fragment * parent;
	struct SH_Fragment * child;
	SH_Data * data;
	bool result;

	data = SH_Data_new (NULL);

	parent = SH_NodeFragment_new ("html", data, NULL);
	child = SH_NodeFragment_new ("head", data, NULL);

	/* test erroneous call */
	_status_preinit (status);
	result = SH_Fragment_remove (parent, &status);
	ck_assert_int_eq (FALSE, result);
	ck_assert (failed (&status));
	ck_assert_int_eq (E_STATE, status.status);

	/* test bug check */
	child->parent = (struct SH_NodeFragment *)parent;
	_status_preinit (status);
	result = SH_Fragment_delete (child, &status);
	ck_assert_int_eq (FALSE, result);
	ck_assert (failed (&status));
	ck_assert_int_eq (E_BUG, status.status);
	child->parent = NULL;

	result = SH_NodeFragment_append_child ((struct SH_NodeFragment *)
	                                       parent, child, NULL);
	ck_assert_int_eq (TRUE, result);

	/* test real */
	_status_preinit (status);
	result = SH_Fragment_delete (child, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert (succeed (&status));

	SH_Fragment_free (parent);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_child_remove_remove_no_status)
{
	struct SH_NodeFragment * parent;
	struct SH_Fragment * child;
	SH_Data * data;
	bool result;

	data = SH_Data_new (NULL);

	parent = (struct SH_NodeFragment *)SH_NodeFragment_new ("html",
	                                                        data,
	                                                        NULL);
	child = SH_NodeFragment_new ("body", data, NULL);

	result = SH_NodeFragment_append_child (parent, child, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_remove_child (parent, 1, NULL);
	ck_assert_int_eq (FALSE, result);

	result = SH_NodeFragment_remove_child (parent, 0, NULL);
	ck_assert_int_eq (TRUE, result);

	SH_NodeFragment_free (parent);
	SH_Fragment_free (child);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_child_remove_remove_with_status)
{
	struct SH_Status status;
	struct SH_NodeFragment * parent;
	struct SH_Fragment * child;
	SH_Data * data;
	bool result;

	data = SH_Data_new (NULL);

	parent = (struct SH_NodeFragment *)SH_NodeFragment_new ("html",
	                                                        data,
	                                                        NULL);
	child = SH_NodeFragment_new ("body", data, NULL);

	result = SH_NodeFragment_append_child (parent, child, NULL);
	ck_assert_int_eq (TRUE, result);

	_status_preinit (status);
	result = SH_NodeFragment_remove_child (parent, 1, &status);
	ck_assert_int_eq (FALSE, result);
	ck_assert (failed (&status));
	ck_assert_int_eq (E_VALUE, status.status);

	_status_preinit (status);
	result = SH_NodeFragment_remove_child (parent, 0, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert (succeed (&status));

	SH_NodeFragment_free (parent);
	SH_Fragment_free (child);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_child_remove_delete_no_status)
{
	struct SH_NodeFragment * parent;
	struct SH_Fragment * child;
	SH_Data * data;
	bool result;

	data = SH_Data_new (NULL);

	parent = (struct SH_NodeFragment *)SH_NodeFragment_new ("html",
	                                                        data,
	                                                        NULL);
	child = SH_NodeFragment_new ("body", data, NULL);

	result = SH_NodeFragment_append_child (parent, child, NULL);
	ck_assert_int_eq (TRUE, result);

	result = SH_NodeFragment_delete_child (parent, 1, NULL);
	ck_assert_int_eq (FALSE, result);

	result = SH_NodeFragment_delete_child (parent, 0, NULL);
	ck_assert_int_eq (TRUE, result);

	SH_NodeFragment_free (parent);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_child_remove_delete_with_status)
{
	struct SH_Status status;
	struct SH_NodeFragment * parent;
	struct SH_Fragment * child;
	SH_Data * data;
	bool result;

	data = SH_Data_new (NULL);

	parent = (struct SH_NodeFragment *)SH_NodeFragment_new ("html",
	                                                        data,
	                                                        NULL);
	child = SH_NodeFragment_new ("body", data, NULL);

	result = SH_NodeFragment_append_child (parent, child, NULL);
	ck_assert_int_eq (TRUE, result);

	_status_preinit (status);
	result = SH_NodeFragment_delete_child (parent, 1, &status);
	ck_assert_int_eq (FALSE, result);
	ck_assert (failed (&status));
	ck_assert_int_eq (E_VALUE, status.status);

	_status_preinit (status);
	result = SH_NodeFragment_delete_child (parent, 0, &status);
	ck_assert_int_eq (TRUE, result);
	ck_assert (succeed (&status));

	SH_NodeFragment_free (parent);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_child_remove_pop_no_status)
{
	struct SH_NodeFragment * parent;
	struct SH_Fragment * child;
	struct SH_Fragment * child1;
	SH_Data * data;
	bool result;

	data = SH_Data_new (NULL);

	parent = (struct SH_NodeFragment *)SH_NodeFragment_new ("html",
	                                                        data,
	                                                        NULL);
	child1 = SH_NodeFragment_new ("body", data, NULL);

	result = SH_NodeFragment_append_child (parent, child1, NULL);
	ck_assert_int_eq (TRUE, result);

	child = SH_NodeFragment_pop_child (parent, 1, NULL);
	ck_assert_ptr_eq (NULL, child);

	child = SH_NodeFragment_pop_child (parent, 0, NULL);
	ck_assert_ptr_eq (child, child1);

	SH_NodeFragment_free (parent);
	SH_Fragment_free (child);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_child_remove_pop_with_status)
{
	struct SH_Status status;
	struct SH_NodeFragment * parent;
	struct SH_Fragment * child;
	struct SH_Fragment * child1;
	SH_Data * data;
	bool result;

	data = SH_Data_new (NULL);

	parent = (struct SH_NodeFragment *)SH_NodeFragment_new ("html",
	                                                        data,
	                                                        NULL);
	child1 = SH_NodeFragment_new ("body", data, NULL);

	result = SH_NodeFragment_append_child (parent, child1, NULL);
	ck_assert_int_eq (TRUE, result);

	_status_preinit (status);
	child = SH_NodeFragment_pop_child (parent, 1, &status);
	ck_assert_ptr_eq (NULL, child);
	ck_assert (failed (&status));
	ck_assert_int_eq (E_VALUE, status.status);

	_status_preinit (status);
	child = SH_NodeFragment_pop_child (parent, 0, &status);
	ck_assert_ptr_eq (child, child1);
	ck_assert (succeed (&status));

	SH_NodeFragment_free (parent);
	SH_Fragment_free (child);

	SH_Data_free (data);
}
END_TEST

START_TEST(test_node_fragment_html)
{
	struct SH_Status status;
	struct SH_Fragment * fragment1;
	struct SH_Fragment * fragment2;
	struct SH_Data * data;
	struct SH_Text * text;
	char * string;
	size_t length;

	data = SH_Data_new (NULL);

	/* no error */
	fragment1 = SH_NodeFragment_new ("html", data, NULL);
	fragment2 = SH_NodeFragment_new ("body", data, NULL);
	SH_NodeFragment_append_child (((struct SH_NodeFragment *) fragment1),
				      fragment2, NULL);

	text = SH_Fragment_to_html (fragment1, INLINE, 0, 1, INDENT_TEXT,
				    NULL);
	string = SH_Text_get_string (text, 0, SIZE_MAX, &length, NULL);
	ck_assert_str_eq (string, "<html><body></body></html>");
	free (string);
	SH_Text_free (text);

	text = SH_Fragment_to_html (fragment1, WRAP, 0, 1, INDENT_TEXT,
				    NULL);
	string = SH_Text_get_string (text, 0, SIZE_MAX, &length, NULL);
	ck_assert_str_eq (string,
			  "<html>\n\t<body>\n\t</body>\n</html>\n");
	free (string);
	SH_Text_free (text);

	SH_Fragment_free (fragment1);

	/* error */
	fragment1 = SH_NodeFragment_new ("html", data, NULL);
	fragment2 = SH_NodeFragment_new ("body", data, NULL);
	SH_NodeFragment_append_child (((struct SH_NodeFragment *) fragment1),
				      fragment2, NULL);

	_status_preinit (status);
	text = SH_Fragment_to_html (fragment1, INLINE, 0, 1, INDENT_TEXT,
				    &status);
	string = SH_Text_get_string (text, 0, SIZE_MAX, &length, NULL);
	ck_assert_str_eq (string, "<html><body></body></html>");
	free (string);
	SH_Text_free (text);
	ck_assert_int_eq (status.status, SUCCESS);

	_status_preinit (status);
	text = SH_Fragment_to_html (fragment1, WRAP, 0, 1, INDENT_TEXT,
				    &status);
	string = SH_Text_get_string (text, 0, SIZE_MAX, &length, NULL);
	ck_assert_str_eq (string,
			  "<html>\n\t<body>\n\t</body>\n</html>\n");
	free (string);
	SH_Text_free (text);
	ck_assert_int_eq (status.status, SUCCESS);

	SH_Fragment_free (fragment1);
	SH_Data_free (data);
}
END_TEST

Suite * fragment_suite (void)
{
	Suite *s;
	TCase *tc_core;

	s = suite_create ("Testsuite SeFHT Fragment");

	/* Core test case */
	tc_core = tcase_create ("Core");

	tcase_add_test (tc_core, test_node_fragment_no_status);
	tcase_add_test (tc_core, test_node_fragment_with_status);
	tcase_add_test (tc_core, test_node_fragment_raw_no_status);
	tcase_add_test (tc_core, test_node_fragment_raw_with_status);
	tcase_add_test (tc_core, test_node_fragment_copy_no_status);
	tcase_add_test (tc_core, test_node_fragment_copy_with_status);
	tcase_add_test (tc_core, test_node_fragment_deepcopy_no_status);
	tcase_add_test (tc_core, test_node_fragment_deepcopy_with_status);
	tcase_add_test (tc_core, test_node_fragment_tag_no_status);
	tcase_add_test (tc_core, test_node_fragment_tag_with_status);
	tcase_add_test (tc_core, test_node_fragment_tag_raw);
	tcase_add_test (tc_core, test_node_fragment_attr_alloc);
	tcase_add_test (tc_core, test_node_fragment_attr_get_no_status);
	tcase_add_test (tc_core, test_node_fragment_attr_get_with_status);
	tcase_add_test (tc_core, test_node_fragment_attr_insert_no_status);
	tcase_add_test (tc_core, test_node_fragment_attr_insert_with_status);
	tcase_add_test (tc_core, test_node_fragment_attr_insert_new_no_status);
	tcase_add_test (tc_core, test_node_fragment_attr_insert_new_with_status);
	tcase_add_test (tc_core, test_node_fragment_attr_insert_copy_no_status);
	tcase_add_test (tc_core, test_node_fragment_attr_insert_copy_with_status);
	tcase_add_test (tc_core, test_node_fragment_attr_insert_insert_no_status);
	tcase_add_test (tc_core, test_node_fragment_attr_insert_insert_with_status);
	tcase_add_test (tc_core, test_node_fragment_attr_insert_insert_new_no_status);
	tcase_add_test (tc_core, test_node_fragment_attr_insert_insert_new_with_status);
	tcase_add_test (tc_core, test_node_fragment_attr_insert_insert_copy_no_status);
	tcase_add_test (tc_core, test_node_fragment_attr_insert_insert_copy_with_status);
	tcase_add_test (tc_core, test_node_fragment_attr_remove1_no_status);
	tcase_add_test (tc_core, test_node_fragment_attr_remove1_with_status);
	tcase_add_test (tc_core, test_node_fragment_attr_remove2_no_status);
	tcase_add_test (tc_core, test_node_fragment_attr_remove2_with_status);
	tcase_add_test (tc_core, test_node_fragment_attr_remove_remove_no_status);
	tcase_add_test (tc_core, test_node_fragment_attr_remove_remove_with_status);
	tcase_add_test (tc_core, test_node_fragment_attr_remove_pop_no_status);
	tcase_add_test (tc_core, test_node_fragment_attr_remove_pop_with_status);
	tcase_add_test (tc_core, test_node_fragment_child_alloc);
	tcase_add_test (tc_core, test_node_fragment_child);
	tcase_add_test (tc_core, test_node_fragment_get_child);
	tcase_add_test (tc_core, test_node_fragment_is_child);
	tcase_add_test (tc_core, test_node_fragment_is_descendant);
	tcase_add_test (tc_core, test_node_fragment_is_parent);
	tcase_add_test (tc_core, test_node_fragment_is_ancestor);
	tcase_add_test (tc_core, test_node_fragment_child_insert_no_status);
	tcase_add_test (tc_core, test_node_fragment_child_insert_with_status);
	tcase_add_test (tc_core, test_node_fragment_child_insert_insert_no_status);
	tcase_add_test (tc_core, test_node_fragment_child_insert_insert_with_status);
	tcase_add_test (tc_core, test_node_fragment_child_insert_relative_no_status);
	tcase_add_test (tc_core, test_node_fragment_child_insert_relative_with_status);
	tcase_add_test (tc_core, test_node_fragment_child_remove_no_status);
	tcase_add_test (tc_core, test_node_fragment_child_remove_with_status);
	tcase_add_test (tc_core, test_node_fragment_child_remove_remove_self_no_status);
	tcase_add_test (tc_core, test_node_fragment_child_remove_remove_self_with_status);
	tcase_add_test (tc_core, test_node_fragment_child_remove_delete_self_no_status);
	tcase_add_test (tc_core, test_node_fragment_child_remove_delete_self_with_status);
	tcase_add_test (tc_core, test_node_fragment_child_remove_remove_no_status);
	tcase_add_test (tc_core, test_node_fragment_child_remove_remove_with_status);
	tcase_add_test (tc_core, test_node_fragment_child_remove_delete_no_status);
	tcase_add_test (tc_core, test_node_fragment_child_remove_delete_with_status);
	tcase_add_test (tc_core, test_node_fragment_child_remove_pop_no_status);
	tcase_add_test (tc_core, test_node_fragment_child_remove_pop_with_status);
	tcase_add_test (tc_core, test_node_fragment_html);
	suite_add_tcase (s, tc_core);

	return s;
}

int main (void)
{
	int number_failed;
	Suite *s;
	SRunner *sr;

	s = fragment_suite ();
	sr = srunner_create (s);

	srunner_run_all (sr, CK_NORMAL);
	number_failed = srunner_ntests_failed (sr);
	srunner_free (sr);

	return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}