File size: 4,914 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 |
#include "unity/unity.h"
#include <libxml/HTMLparser.h>
#include <libxml/tree.h>
#include <libxml/parser.h>
#include <stdlib.h>
#include <string.h>
/* 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;
} |