File size: 6,637 Bytes
6baed57 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
#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 < 6 & 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();
} |