libxml / tests /tests_HTMLparser_htmlAutoCloseTag.c
AryaWu's picture
Upload folder using huggingface_hub
6baed57 verified
#include "unity/unity.h"
#include <libxml/HTMLparser.h>
#include <stdlib.h>
#include <string.h>
/* Forward declaration in case it's not exposed by the public header. */
int htmlAutoCloseTag(xmlDoc *doc, const xmlChar *name, xmlNode *elem);
static xmlDocPtr make_doc_with_root(const char *rootName, xmlNodePtr *outRoot) {
xmlDocPtr doc = xmlNewDoc((const xmlChar *)"1.0");
TEST_ASSERT_NOT_NULL_MESSAGE(doc, "xmlNewDoc failed");
xmlNodePtr root = xmlNewNode(NULL, (const xmlChar *)rootName);
TEST_ASSERT_NOT_NULL_MESSAGE(root, "xmlNewNode failed for root");
xmlDocSetRootElement(doc, root);
if (outRoot) *outRoot = root;
return doc;
}
void setUp(void) {
/* No global setup required */
}
void tearDown(void) {
/* No global teardown required */
}
/* elem == NULL => should return 1 */
void test_htmlAutoCloseTag_null_elem_returns_1(void) {
int ret = htmlAutoCloseTag(NULL, (const xmlChar *)"li", NULL);
TEST_ASSERT_EQUAL_INT(1, ret);
}
/* elem->name equals name => should return 0 */
void test_htmlAutoCloseTag_equal_name_returns_0(void) {
xmlNodePtr root = NULL;
xmlDocPtr doc = make_doc_with_root("p", &root);
int ret = htmlAutoCloseTag(doc, (const xmlChar *)"p", root);
TEST_ASSERT_EQUAL_INT(0, ret);
xmlFreeDoc(doc);
}
/* Direct auto-close: starting 'dt' should auto-close a preceding 'dd' */
void test_htmlAutoCloseTag_direct_autoclose_dd_by_dt_returns_1(void) {
xmlNodePtr root = NULL;
xmlDocPtr doc = make_doc_with_root("dd", &root);
int ret = htmlAutoCloseTag(doc, (const xmlChar *)"dt", root);
TEST_ASSERT_EQUAL_INT(1, ret);
xmlFreeDoc(doc);
}
/* No auto-close between unrelated tags: 'div' vs 'span' => 0 */
void test_htmlAutoCloseTag_no_autoclose_div_vs_span_returns_0(void) {
xmlNodePtr root = NULL;
xmlDocPtr doc = make_doc_with_root("div", &root);
int ret = htmlAutoCloseTag(doc, (const xmlChar *)"span", root);
TEST_ASSERT_EQUAL_INT(0, ret);
xmlFreeDoc(doc);
}
/* Descendant triggers auto-close: <div><dd/></div> with new tag 'dt' => 1 */
void test_htmlAutoCloseTag_descendant_dd_autoclosed_by_dt_returns_1(void) {
xmlNodePtr root = NULL;
xmlDocPtr doc = make_doc_with_root("div", &root);
xmlNodePtr child = xmlNewNode(NULL, (const xmlChar *)"dd");
TEST_ASSERT_NOT_NULL(child);
xmlAddChild(root, child);
int ret = htmlAutoCloseTag(doc, (const xmlChar *)"dt", root);
TEST_ASSERT_EQUAL_INT(1, ret);
xmlFreeDoc(doc);
}
/* Should iterate over children: first child no match, second child matches => 1 */
void test_htmlAutoCloseTag_sibling_second_child_matches_returns_1(void) {
xmlNodePtr root = NULL;
xmlDocPtr doc = make_doc_with_root("div", &root);
xmlNodePtr child1 = xmlNewNode(NULL, (const xmlChar *)"span"); /* no match */
xmlNodePtr child2 = xmlNewNode(NULL, (const xmlChar *)"dd"); /* dt will close */
TEST_ASSERT_NOT_NULL(child1);
TEST_ASSERT_NOT_NULL(child2);
xmlAddChild(root, child1);
xmlAddChild(root, child2);
int ret = htmlAutoCloseTag(doc, (const xmlChar *)"dt", root);
TEST_ASSERT_EQUAL_INT(1, ret);
xmlFreeDoc(doc);
}
/* Top-level equal name should short-circuit to 0 (even if children might match) */
void test_htmlAutoCloseTag_top_equal_name_short_circuits_returns_0(void) {
xmlNodePtr root = NULL;
xmlDocPtr doc = make_doc_with_root("p", &root);
/* Add a child that would be closed by 'dt' to ensure it's ignored due to top-level equal-name */
xmlNodePtr child = xmlNewNode(NULL, (const xmlChar *)"dd");
TEST_ASSERT_NOT_NULL(child);
xmlAddChild(root, child);
int ret = htmlAutoCloseTag(doc, (const xmlChar *)"p", root);
TEST_ASSERT_EQUAL_INT(0, ret);
xmlFreeDoc(doc);
}
/* No descendant matches: ensure returns 0 */
void test_htmlAutoCloseTag_no_descendant_match_returns_0(void) {
xmlNodePtr root = NULL;
xmlDocPtr doc = make_doc_with_root("div", &root);
xmlNodePtr c1 = xmlNewNode(NULL, (const xmlChar *)"span");
xmlNodePtr c2 = xmlNewNode(NULL, (const xmlChar *)"em");
TEST_ASSERT_NOT_NULL(c1);
TEST_ASSERT_NOT_NULL(c2);
xmlAddChild(root, c1);
xmlAddChild(root, c2);
int ret = htmlAutoCloseTag(doc, (const xmlChar *)"span", root);
TEST_ASSERT_EQUAL_INT(0, ret);
xmlFreeDoc(doc);
}
int main(void) {
UNITY_BEGIN();
RUN_TEST(test_htmlAutoCloseTag_null_elem_returns_1);
RUN_TEST(test_htmlAutoCloseTag_equal_name_returns_0);
RUN_TEST(test_htmlAutoCloseTag_direct_autoclose_dd_by_dt_returns_1);
RUN_TEST(test_htmlAutoCloseTag_no_autoclose_div_vs_span_returns_0);
RUN_TEST(test_htmlAutoCloseTag_descendant_dd_autoclosed_by_dt_returns_1);
RUN_TEST(test_htmlAutoCloseTag_sibling_second_child_matches_returns_1);
RUN_TEST(test_htmlAutoCloseTag_top_equal_name_short_circuits_returns_0);
RUN_TEST(test_htmlAutoCloseTag_no_descendant_match_returns_0);
return UNITY_END();
}