#include "unity/unity.h" #include #include #include #include #include /* Unity fixtures */ void setUp(void) { /* Setup code here, or leave empty */ } void tearDown(void) { /* Cleanup code here, or leave empty */ } /* Helper to build a document with a root element of given name */ static xmlDocPtr make_doc_with_root(const char *root_name, xmlNodePtr *out_root) { xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0"); TEST_ASSERT_NOT_NULL_MESSAGE(doc, "Failed to create xmlDoc"); xmlNodePtr root = xmlNewNode(NULL, BAD_CAST root_name); TEST_ASSERT_NOT_NULL_MESSAGE(root, "Failed to create root node"); xmlDocSetRootElement(doc, root); if (out_root) *out_root = root; return doc; } void test_htmlIsAutoClosed_null_elem_with_null_doc(void) { int res = htmlIsAutoClosed(NULL, NULL); TEST_ASSERT_EQUAL_INT(1, res); } void test_htmlIsAutoClosed_null_elem_with_real_doc(void) { xmlNodePtr root = NULL; xmlDocPtr doc = make_doc_with_root("p", &root); int res = htmlIsAutoClosed(doc, NULL); TEST_ASSERT_EQUAL_INT(1, res); xmlFreeDoc(doc); } void test_htmlIsAutoClosed_no_children_returns_0(void) { xmlNodePtr root = NULL; xmlDocPtr doc = make_doc_with_root("p", &root); int res = htmlIsAutoClosed(doc, root); TEST_ASSERT_EQUAL_INT(0, res); xmlFreeDoc(doc); } void test_htmlIsAutoClosed_immediate_same_name_child_ignored_returns_0(void) { xmlNodePtr root = NULL; xmlDocPtr doc = make_doc_with_root("p", &root); /* Immediate child with same name as parent */ xmlNodePtr child = xmlNewChild(root, NULL, BAD_CAST "p", NULL); TEST_ASSERT_NOT_NULL(child); int res = htmlIsAutoClosed(doc, root); TEST_ASSERT_EQUAL_INT(0, res); xmlFreeDoc(doc); } void test_htmlIsAutoClosed_child_non_trigger_returns_0(void) { xmlNodePtr root = NULL; xmlDocPtr doc = make_doc_with_root("p", &root); /* span does not auto-close p */ xmlNodePtr child = xmlNewChild(root, NULL, BAD_CAST "span", NULL); TEST_ASSERT_NOT_NULL(child); int res = htmlIsAutoClosed(doc, root); TEST_ASSERT_EQUAL_INT(0, res); xmlFreeDoc(doc); } void test_htmlIsAutoClosed_child_triggers_autoclose_returns_1(void) { xmlNodePtr root = NULL; xmlDocPtr doc = make_doc_with_root("p", &root); /* div should auto-close p according to HTML rules */ xmlNodePtr child = xmlNewChild(root, NULL, BAD_CAST "div", NULL); TEST_ASSERT_NOT_NULL(child); int res = htmlIsAutoClosed(doc, root); TEST_ASSERT_EQUAL_INT(1, res); xmlFreeDoc(doc); } void test_htmlIsAutoClosed_descendant_triggers_autoclose_returns_1(void) { xmlNodePtr root = NULL; xmlDocPtr doc = make_doc_with_root("p", &root); /* Non-trigger child with a trigger descendant: span > div */ xmlNodePtr span = xmlNewChild(root, NULL, BAD_CAST "span", NULL); TEST_ASSERT_NOT_NULL(span); xmlNodePtr div = xmlNewChild(span, NULL, BAD_CAST "div", NULL); TEST_ASSERT_NOT_NULL(div); int res = htmlIsAutoClosed(doc, root); TEST_ASSERT_EQUAL_INT(1, res); xmlFreeDoc(doc); } void test_htmlIsAutoClosed_multiple_children_only_one_triggers_returns_1(void) { xmlNodePtr root = NULL; xmlDocPtr doc = make_doc_with_root("p", &root); xmlNodePtr c1 = xmlNewChild(root, NULL, BAD_CAST "span", NULL); xmlNodePtr c2 = xmlNewChild(root, NULL, BAD_CAST "em", NULL); xmlNodePtr c3 = xmlNewChild(root, NULL, BAD_CAST "div", NULL); /* trigger */ TEST_ASSERT_NOT_NULL(c1); TEST_ASSERT_NOT_NULL(c2); TEST_ASSERT_NOT_NULL(c3); int res = htmlIsAutoClosed(doc, root); TEST_ASSERT_EQUAL_INT(1, res); xmlFreeDoc(doc); } void test_htmlIsAutoClosed_null_doc_parameter_works_with_valid_tree(void) { xmlNodePtr root = NULL; xmlDocPtr doc = make_doc_with_root("p", &root); /* Attach a trigger child but pass NULL as doc */ xmlNodePtr div = xmlNewChild(root, NULL, BAD_CAST "div", NULL); TEST_ASSERT_NOT_NULL(div); int res = htmlIsAutoClosed(NULL, root); TEST_ASSERT_EQUAL_INT(1, res); xmlFreeDoc(doc); } int main(void) { xmlInitParser(); UNITY_BEGIN(); RUN_TEST(test_htmlIsAutoClosed_null_elem_with_null_doc); RUN_TEST(test_htmlIsAutoClosed_null_elem_with_real_doc); RUN_TEST(test_htmlIsAutoClosed_no_children_returns_0); RUN_TEST(test_htmlIsAutoClosed_immediate_same_name_child_ignored_returns_0); RUN_TEST(test_htmlIsAutoClosed_child_non_trigger_returns_0); RUN_TEST(test_htmlIsAutoClosed_child_triggers_autoclose_returns_1); RUN_TEST(test_htmlIsAutoClosed_descendant_triggers_autoclose_returns_1); RUN_TEST(test_htmlIsAutoClosed_multiple_children_only_one_triggers_returns_1); RUN_TEST(test_htmlIsAutoClosed_null_doc_parameter_works_with_valid_tree); int ret = UNITY_END(); xmlCleanupParser(); return ret; }