libxml / tests /tests_HTMLtree_htmlBufNodeDumpFormat.c
AryaWu's picture
Upload folder using huggingface_hub
6baed57 verified
#include "unity/unity.h"
#include <libxml/HTMLtree.h>
#include <libxml/tree.h>
#include <libxml/parser.h>
#include <libxml/xmlstring.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
/* Internal libxml buffer API used by the function under test */
#include "private/buf.h"
/* Wrapper for the static function under test (declared in the module) */
extern size_t test_htmlBufNodeDumpFormat(xmlBufPtr buf, xmlDocPtr doc, xmlNodePtr cur, int format);
static xmlBufPtr make_buf(void) {
xmlBufPtr buf = xmlBufCreate();
TEST_ASSERT_NOT_NULL_MESSAGE(buf, "Failed to create xmlBuf");
return buf;
}
static void assert_buf_equals(xmlBufPtr buf, const char *expected) {
size_t expected_len = strlen(expected);
const xmlChar *content = xmlBufContent(buf);
size_t used = xmlBufUse(buf);
TEST_ASSERT_EQUAL_UINT64((uint64_t)expected_len, (uint64_t)used);
TEST_ASSERT_NOT_NULL(content);
TEST_ASSERT_EQUAL_INT(0, memcmp((const char *)content, expected, expected_len));
}
void setUp(void) {
/* Ensure parser is initialized for any libxml operations */
xmlInitParser();
}
void tearDown(void) {
/* Cleanup global state after each test */
xmlCleanupParser();
}
/* Error handling tests */
void test_htmlBufNodeDumpFormat_null_cur_returns_minus_one(void) {
xmlBufPtr buf = make_buf();
size_t ret = test_htmlBufNodeDumpFormat(buf, NULL, NULL, 0);
TEST_ASSERT_EQUAL_UINT64((uint64_t)(size_t)-1, (uint64_t)ret);
xmlBufFree(buf);
}
void test_htmlBufNodeDumpFormat_null_buf_returns_minus_one(void) {
xmlNodePtr node = xmlNewNode(NULL, BAD_CAST "div");
TEST_ASSERT_NOT_NULL(node);
size_t ret = test_htmlBufNodeDumpFormat(NULL, NULL, node, 0);
TEST_ASSERT_EQUAL_UINT64((uint64_t)(size_t)-1, (uint64_t)ret);
xmlFreeNode(node);
}
/* Basic serialization tests */
void test_htmlBufNodeDumpFormat_empty_html_empty_elem_br(void) {
xmlBufPtr buf = make_buf();
xmlNodePtr node = xmlNewNode(NULL, BAD_CAST "br");
TEST_ASSERT_NOT_NULL(node);
size_t ret = test_htmlBufNodeDumpFormat(buf, NULL, node, 0);
const char *expected = "<br>";
TEST_ASSERT_EQUAL_UINT64((uint64_t)strlen(expected), (uint64_t)ret);
assert_buf_equals(buf, expected);
xmlFreeNode(node);
xmlBufFree(buf);
}
void test_htmlBufNodeDumpFormat_non_empty_without_children_div(void) {
xmlBufPtr buf = make_buf();
xmlNodePtr node = xmlNewNode(NULL, BAD_CAST "div");
TEST_ASSERT_NOT_NULL(node);
size_t ret = test_htmlBufNodeDumpFormat(buf, NULL, node, 0);
const char *expected = "<div></div>";
TEST_ASSERT_EQUAL_UINT64((uint64_t)strlen(expected), (uint64_t)ret);
assert_buf_equals(buf, expected);
xmlFreeNode(node);
xmlBufFree(buf);
}
void test_htmlBufNodeDumpFormat_text_child_with_escaping(void) {
xmlBufPtr buf = make_buf();
xmlNodePtr node = xmlNewNode(NULL, BAD_CAST "div");
TEST_ASSERT_NOT_NULL(node);
xmlNodePtr text = xmlNewText(BAD_CAST "5 < 6 & 7");
TEST_ASSERT_NOT_NULL(text);
xmlAddChild(node, text);
size_t ret = test_htmlBufNodeDumpFormat(buf, NULL, node, 0);
const char *expected = "<div>5 &lt; 6 &amp; 7</div>";
TEST_ASSERT_EQUAL_UINT64((uint64_t)strlen(expected), (uint64_t)ret);
assert_buf_equals(buf, expected);
xmlFreeNode(node); /* Frees children as well */
xmlBufFree(buf);
}
void test_htmlBufNodeDumpFormat_namespace_prefix_and_declaration(void) {
xmlBufPtr buf = make_buf();
xmlNodePtr node = xmlNewNode(NULL, BAD_CAST "span");
TEST_ASSERT_NOT_NULL(node);
/* Declare and set namespace prefix x with href "urn:test" */
xmlNsPtr ns = xmlNewNs(node, BAD_CAST "urn:test", BAD_CAST "x");
TEST_ASSERT_NOT_NULL(ns);
xmlSetNs(node, ns);
size_t ret = test_htmlBufNodeDumpFormat(buf, NULL, node, 0);
const char *expected = "<x:span xmlns:x=\"urn:test\"></x:span>";
TEST_ASSERT_EQUAL_UINT64((uint64_t)strlen(expected), (uint64_t)ret);
assert_buf_equals(buf, expected);
xmlFreeNode(node);
xmlBufFree(buf);
}
void test_htmlBufNodeDumpFormat_multiple_calls_append_and_return_increment(void) {
xmlBufPtr buf = make_buf();
xmlNodePtr node = xmlNewNode(NULL, BAD_CAST "div");
TEST_ASSERT_NOT_NULL(node);
const char *once = "<div></div>";
size_t ret1 = test_htmlBufNodeDumpFormat(buf, NULL, node, 0);
TEST_ASSERT_EQUAL_UINT64((uint64_t)strlen(once), (uint64_t)ret1);
assert_buf_equals(buf, once);
size_t before = xmlBufUse(buf);
size_t ret2 = test_htmlBufNodeDumpFormat(buf, NULL, node, 0);
TEST_ASSERT_EQUAL_UINT64((uint64_t)strlen(once), (uint64_t)ret2);
size_t after = xmlBufUse(buf);
TEST_ASSERT_EQUAL_UINT64((uint64_t)(before + strlen(once)), (uint64_t)after);
const xmlChar *content = xmlBufContent(buf);
TEST_ASSERT_NOT_NULL(content);
TEST_ASSERT_EQUAL_INT(0, memcmp((const char *)content, once, strlen(once)));
TEST_ASSERT_EQUAL_INT(0, memcmp((const char *)content + strlen(once), once, strlen(once)));
xmlFreeNode(node);
xmlBufFree(buf);
}
void test_htmlBufNodeDumpFormat_formatting_newlines_with_block_children(void) {
xmlBufPtr buf = make_buf();
/* Build: <div><span>1</span><span>2</span></div> to trigger newlines with format=1 */
xmlNodePtr div = xmlNewNode(NULL, BAD_CAST "div");
TEST_ASSERT_NOT_NULL(div);
xmlNodePtr span1 = xmlNewNode(NULL, BAD_CAST "span");
xmlAddChild(span1, xmlNewText(BAD_CAST "1"));
xmlAddChild(div, span1);
xmlNodePtr span2 = xmlNewNode(NULL, BAD_CAST "span");
xmlAddChild(span2, xmlNewText(BAD_CAST "2"));
xmlAddChild(div, span2);
size_t ret = test_htmlBufNodeDumpFormat(buf, NULL, div, 1);
/* Expected behavior: newline after opening div and before closing div */
const char *expected = "<div>\n<span>1</span><span>2</span>\n</div>";
TEST_ASSERT_EQUAL_UINT64((uint64_t)strlen(expected), (uint64_t)ret);
assert_buf_equals(buf, expected);
xmlFreeNode(div);
xmlBufFree(buf);
}
int main(void) {
UNITY_BEGIN();
RUN_TEST(test_htmlBufNodeDumpFormat_null_cur_returns_minus_one);
RUN_TEST(test_htmlBufNodeDumpFormat_null_buf_returns_minus_one);
RUN_TEST(test_htmlBufNodeDumpFormat_empty_html_empty_elem_br);
RUN_TEST(test_htmlBufNodeDumpFormat_non_empty_without_children_div);
RUN_TEST(test_htmlBufNodeDumpFormat_text_child_with_escaping);
RUN_TEST(test_htmlBufNodeDumpFormat_namespace_prefix_and_declaration);
RUN_TEST(test_htmlBufNodeDumpFormat_multiple_calls_append_and_return_increment);
RUN_TEST(test_htmlBufNodeDumpFormat_formatting_newlines_with_block_children);
return UNITY_END();
}