From 8d84e3c75ccef1b5f8b7f609013c7858aa7f7eea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Sch=C3=B6bel?= <jonathan@xn--schbel-yxa.info> Date: Thu, 16 Mar 2023 13:12:07 +0100 Subject: [PATCH] NodeFragment: added remove methods Various remove methods were added, which are all implemented by an static method, analog to the last commit. --- sefht.geany | 6 +- src/lib/sefht/node_fragment.c | 175 ++++++++++ src/lib/sefht/node_fragment.h | 28 ++ tests/test_node_fragment.c | 587 ++++++++++++++++++++++++++++++++++ 4 files changed, 793 insertions(+), 3 deletions(-) diff --git a/sefht.geany b/sefht.geany index 6469562..a36946c 100644 --- a/sefht.geany +++ b/sefht.geany @@ -41,8 +41,8 @@ FILE_NAME_8=1550;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fpr FILE_NAME_9=1562;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ffragment.h;0;8 FILE_NAME_10=2022;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ffragment_data.c;0;8 FILE_NAME_11=2558;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ffragment_class.c;0;8 -FILE_NAME_12=15959;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fnode_fragment.c;0;8 -FILE_NAME_13=3151;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fnode_fragment.h;0;8 +FILE_NAME_12=15951;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fnode_fragment.c;0;8 +FILE_NAME_13=5930;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fnode_fragment.h;0;8 FILE_NAME_14=25820;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ftext.c;0;8 FILE_NAME_15=904;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ftext.h;0;8 FILE_NAME_16=1779;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator.c;0;8 @@ -56,7 +56,7 @@ FILE_NAME_23=1078;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fp FILE_NAME_24=290;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2FMakefile.am;0;8 FILE_NAME_25=1085;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_cms.c;0;8 FILE_NAME_26=3283;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_data.c;0;8 -FILE_NAME_27=32229;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_node_fragment.c;0;8 +FILE_NAME_27=51595;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_node_fragment.c;0;8 FILE_NAME_28=11068;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_text.c;0;8 FILE_NAME_29=5744;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_validator.c;0;8 FILE_NAME_30=165;None;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftodo.txt;0;8 diff --git a/src/lib/sefht/node_fragment.c b/src/lib/sefht/node_fragment.c index 434b326..6e3e498 100644 --- a/src/lib/sefht/node_fragment.c +++ b/src/lib/sefht/node_fragment.c @@ -704,6 +704,181 @@ SH_NodeFragment_insert_child_after (struct SH_Fragment * fragment, return FALSE; } +static inline +/*@null@*/ +/*@only@*/ +struct SH_Fragment * +remove_child (struct SH_NodeFragment * fragment, size_t position, + /*@out@*/ /*@null@*/ struct SH_Status * status) +{ + size_t index; + size_t new_size; + typeof (fragment->childs) new_childs; + struct SH_Fragment * child; + + child = fragment->childs[position]; + + for (index = position+1; index < fragment->child_n; index++) + { + fragment->childs[index-1] = fragment->childs[index]; + } + + new_size = get_alloc_size (fragment->child_n - 1); + if (new_size < fragment->child_s) + { + new_childs = realloc (fragment->childs, new_size + * sizeof (*new_childs)); + if ((0 != new_size) && (NULL == new_childs)) + { + for (index = fragment->child_n-1; + index > position; + index--) + { + fragment->childs[index] = + fragment->childs[index-1]; + } + + set_status (status, E_ALLOC, 4, + "realloc failed.\n"); + return NULL; + } + + fragment->childs = new_childs; + fragment->child_s = new_size; + } + + fragment->child_n--; + child->parent = NULL; + + set_success (status); + + return child; +} + +bool +SH_Fragment_remove (struct SH_Fragment * fragment, + /*@out@*/ /*@null@*/ struct SH_Status * status) +{ + size_t index; + + #define parent get_parent (fragment) + if (NULL == parent) + { + set_status (status, E_STATE, 2, + "fragment not linked, " + "can't remove it from parent"); + return FALSE; + } + + for (index = 0; index < parent->child_n; index++) + { + if (fragment == parent->childs[index]) + { + return NULL != remove_child (parent, index, + status); + } + } + #undef parent + + set_status (status, E_BUG, 10, + "fragment is both child and not child.\n"); + return FALSE; +} + +bool +SH_Fragment_delete (/*@only@*/ struct SH_Fragment * fragment, + /*@out@*/ /*@null@*/ struct SH_Status * status) +{ + size_t index; + + #define parent get_parent (fragment) + if (NULL == parent) + { + set_status (status, E_STATE, 2, + "fragment not linked, " + "can't remove it from parent"); + return FALSE; + } + + for (index = 0; index < parent->child_n; index++) + { + if (fragment == parent->childs[index]) + { + if (NULL == remove_child (parent, index, status)) + { + return FALSE; + } + + SH_Fragment_free (fragment); + return TRUE; + } + } + #undef parent + + set_status (status, E_BUG, 10, + "fragment is both child and not child.\n"); + return FALSE; +} + +bool +SH_NodeFragment_remove_child (struct SH_NodeFragment * fragment, + size_t position, + /*@out@*/ /*@null@*/ + struct SH_Status * status) +{ + if (position >= fragment->child_n) + { + set_status (status, E_VALUE, 2, + "index out of range.\n"); + return FALSE; + } + + return NULL != remove_child (fragment, position, status); +} + +bool +SH_NodeFragment_delete_child (struct SH_NodeFragment * fragment, + size_t position, + /*@out@*/ /*@null@*/ + struct SH_Status * status) +{ + struct SH_Fragment * child; + + if (position >= fragment->child_n) + { + set_status (status, E_VALUE, 2, + "index out of range.\n"); + return FALSE; + } + + child = remove_child (fragment, position, status); + if (NULL == child) + { + return FALSE; + } + + SH_Fragment_free (child); + return TRUE; +} + +/*@null@*/ +/*@only@*/ +struct SH_Fragment * +SH_NodeFragment_pop_child (struct SH_NodeFragment * fragment, + size_t position, + /*@out@*/ /*@null@*/ + struct SH_Status * status) +{ + if (position >= fragment->child_n) + { + set_status (status, E_VALUE, 2, + "index out of range.\n"); + return NULL; + } + + return remove_child (fragment, position, status); +} + /*@null@*/ /*@only@*/ struct SH_Text * diff --git a/src/lib/sefht/node_fragment.h b/src/lib/sefht/node_fragment.h index 3a50360..44ac67c 100644 --- a/src/lib/sefht/node_fragment.h +++ b/src/lib/sefht/node_fragment.h @@ -177,6 +177,34 @@ SH_NodeFragment_insert_child_after (SH_Fragment * fragment, /*@modifies fileSystem@*/ /*@modifies status@*/; +bool +SH_Fragment_remove (SH_Fragment * fragment, + /*@out@*/ /*@null@*/ struct SH_Status * status); + +bool +SH_Fragment_delete (/*@only@*/ SH_Fragment * fragment, + /*@out@*/ /*@null@*/ struct SH_Status * status); + +bool +SH_NodeFragment_remove_child (SH_NodeFragment * fragment, + size_t position, + /*@out@*/ /*@null@*/ + struct SH_Status * status); + +bool +SH_NodeFragment_delete_child (SH_NodeFragment * fragment, + size_t position, + /*@out@*/ /*@null@*/ + struct SH_Status * status); + +/*@null@*/ +/*@only@*/ +SH_Fragment * +SH_NodeFragment_pop_child (SH_NodeFragment * fragment, + size_t position, + /*@out@*/ /*@null@*/ + struct SH_Status * status); + /*@null@*/ /*@only@*/ SH_Text * diff --git a/tests/test_node_fragment.c b/tests/test_node_fragment.c index 824b519..35f2cdd 100644 --- a/tests/test_node_fragment.c +++ b/tests/test_node_fragment.c @@ -1018,6 +1018,581 @@ START_TEST(test_node_fragment_child_insert_relative_with_error) } END_TEST +START_TEST(test_node_fragment_child_remove_no_error) +{ + 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_error) +{ + 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_error) +{ + 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_error) +{ + 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_error) +{ + 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_error) +{ + 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_error) +{ + 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_error) +{ + 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_error) +{ + 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_error) +{ + 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_error) +{ + 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_error) +{ + 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; @@ -1111,6 +1686,18 @@ Suite * fragment_suite (void) tcase_add_test (tc_core, test_node_fragment_child_insert_insert_with_error); tcase_add_test (tc_core, test_node_fragment_child_insert_relative_no_error); tcase_add_test (tc_core, test_node_fragment_child_insert_relative_with_error); + tcase_add_test (tc_core, test_node_fragment_child_remove_no_error); + tcase_add_test (tc_core, test_node_fragment_child_remove_with_error); + tcase_add_test (tc_core, test_node_fragment_child_remove_remove_self_no_error); + tcase_add_test (tc_core, test_node_fragment_child_remove_remove_self_with_error); + tcase_add_test (tc_core, test_node_fragment_child_remove_delete_self_no_error); + tcase_add_test (tc_core, test_node_fragment_child_remove_delete_self_with_error); + tcase_add_test (tc_core, test_node_fragment_child_remove_remove_no_error); + tcase_add_test (tc_core, test_node_fragment_child_remove_remove_with_error); + tcase_add_test (tc_core, test_node_fragment_child_remove_delete_no_error); + tcase_add_test (tc_core, test_node_fragment_child_remove_delete_with_error); + tcase_add_test (tc_core, test_node_fragment_child_remove_pop_no_error); + tcase_add_test (tc_core, test_node_fragment_child_remove_pop_with_error); tcase_add_test (tc_core, test_node_fragment_html); suite_add_tcase (s, tc_core); -- GitLab