|
|
#include "unity/unity.h" |
|
|
#include <libxml/HTMLparser.h> |
|
|
|
|
|
#include <libxml/parser.h> |
|
|
#include <libxml/tree.h> |
|
|
#include <libxml/xmlmemory.h> |
|
|
#include <string.h> |
|
|
#include <stdlib.h> |
|
|
|
|
|
|
|
|
extern int test_htmlNodeInfoPush(htmlParserCtxtPtr ctxt, htmlParserNodeInfo *value); |
|
|
|
|
|
static xmlNodePtr make_dummy_node(const char *name) { |
|
|
return xmlNewNode(NULL, (const xmlChar *)name); |
|
|
} |
|
|
|
|
|
void setUp(void) { |
|
|
xmlInitParser(); |
|
|
} |
|
|
|
|
|
void tearDown(void) { |
|
|
xmlCleanupParser(); |
|
|
} |
|
|
|
|
|
|
|
|
static void assert_nodeinfo_equal(const htmlParserNodeInfo *a, const htmlParserNodeInfo *b) { |
|
|
TEST_ASSERT_NOT_NULL(a); |
|
|
TEST_ASSERT_NOT_NULL(b); |
|
|
TEST_ASSERT_EQUAL_PTR(a->node, b->node); |
|
|
TEST_ASSERT_EQUAL_UINT64(a->begin_pos, b->begin_pos); |
|
|
TEST_ASSERT_EQUAL_UINT64(a->begin_line, b->begin_line); |
|
|
TEST_ASSERT_EQUAL_UINT64(a->end_pos, b->end_pos); |
|
|
TEST_ASSERT_EQUAL_UINT64(a->end_line, b->end_line); |
|
|
} |
|
|
|
|
|
|
|
|
void test_htmlNodeInfoPush_initial_alloc_and_store(void) { |
|
|
htmlParserCtxtPtr ctxt = htmlNewParserCtxt(); |
|
|
TEST_ASSERT_NOT_NULL(ctxt); |
|
|
|
|
|
|
|
|
ctxt->nodeInfoTab = NULL; |
|
|
ctxt->nodeInfoMax = 0; |
|
|
ctxt->nodeInfoNr = 0; |
|
|
ctxt->nodeInfo = NULL; |
|
|
|
|
|
xmlNodePtr n1 = make_dummy_node("n1"); |
|
|
TEST_ASSERT_NOT_NULL(n1); |
|
|
|
|
|
htmlParserNodeInfo info1; |
|
|
memset(&info1, 0, sizeof(info1)); |
|
|
info1.node = n1; |
|
|
info1.begin_pos = 10; |
|
|
info1.begin_line = 2; |
|
|
info1.end_pos = 20; |
|
|
info1.end_line = 3; |
|
|
|
|
|
int ret = test_htmlNodeInfoPush(ctxt, &info1); |
|
|
|
|
|
|
|
|
TEST_ASSERT_NOT_NULL(ctxt->nodeInfoTab); |
|
|
TEST_ASSERT_TRUE(ctxt->nodeInfoMax > 0); |
|
|
TEST_ASSERT_EQUAL_INT(1, ctxt->nodeInfoNr); |
|
|
TEST_ASSERT_EQUAL_PTR(&ctxt->nodeInfoTab[0], ctxt->nodeInfo); |
|
|
|
|
|
assert_nodeinfo_equal(&info1, &ctxt->nodeInfoTab[0]); |
|
|
|
|
|
xmlFreeNode(n1); |
|
|
htmlFreeParserCtxt(ctxt); |
|
|
} |
|
|
|
|
|
|
|
|
void test_htmlNodeInfoPush_no_growth_needed(void) { |
|
|
htmlParserCtxtPtr ctxt = htmlNewParserCtxt(); |
|
|
TEST_ASSERT_NOT_NULL(ctxt); |
|
|
|
|
|
|
|
|
int cap = 4; |
|
|
ctxt->nodeInfoTab = (xmlParserNodeInfo *)xmlMalloc(sizeof(ctxt->nodeInfoTab[0]) * cap); |
|
|
TEST_ASSERT_NOT_NULL(ctxt->nodeInfoTab); |
|
|
ctxt->nodeInfoMax = cap; |
|
|
ctxt->nodeInfoNr = 0; |
|
|
ctxt->nodeInfo = NULL; |
|
|
|
|
|
xmlNodePtr n1 = make_dummy_node("a"); |
|
|
xmlNodePtr n2 = make_dummy_node("b"); |
|
|
TEST_ASSERT_NOT_NULL(n1); |
|
|
TEST_ASSERT_NOT_NULL(n2); |
|
|
|
|
|
htmlParserNodeInfo info1, info2; |
|
|
memset(&info1, 0, sizeof(info1)); |
|
|
memset(&info2, 0, sizeof(info2)); |
|
|
info1.node = n1; info1.begin_pos = 1; info1.begin_line = 1; info1.end_pos = 2; info1.end_line = 2; |
|
|
info2.node = n2; info2.begin_pos = 3; info2.begin_line = 3; info2.end_pos = 4; info2.end_line = 4; |
|
|
|
|
|
int ret0 = test_htmlNodeInfoPush(ctxt, &info1); |
|
|
TEST_ASSERT_EQUAL_INT(0, ret0); |
|
|
TEST_ASSERT_EQUAL_INT(1, ctxt->nodeInfoNr); |
|
|
TEST_ASSERT_EQUAL_PTR(&ctxt->nodeInfoTab[0], ctxt->nodeInfo); |
|
|
assert_nodeinfo_equal(&info1, &ctxt->nodeInfoTab[0]); |
|
|
|
|
|
int ret1 = test_htmlNodeInfoPush(ctxt, &info2); |
|
|
TEST_ASSERT_EQUAL_INT(1, ret1); |
|
|
TEST_ASSERT_EQUAL_INT(2, ctxt->nodeInfoNr); |
|
|
TEST_ASSERT_EQUAL_PTR(&ctxt->nodeInfoTab[1], ctxt->nodeInfo); |
|
|
assert_nodeinfo_equal(&info2, &ctxt->nodeInfoTab[1]); |
|
|
|
|
|
xmlFreeNode(n1); |
|
|
xmlFreeNode(n2); |
|
|
htmlFreeParserCtxt(ctxt); |
|
|
} |
|
|
|
|
|
|
|
|
void test_htmlNodeInfoPush_growth_and_preserve_existing(void) { |
|
|
htmlParserCtxtPtr ctxt = htmlNewParserCtxt(); |
|
|
TEST_ASSERT_NOT_NULL(ctxt); |
|
|
|
|
|
|
|
|
ctxt->nodeInfoTab = (xmlParserNodeInfo *)xmlMalloc(sizeof(ctxt->nodeInfoTab[0]) * 1); |
|
|
TEST_ASSERT_NOT_NULL(ctxt->nodeInfoTab); |
|
|
ctxt->nodeInfoMax = 1; |
|
|
ctxt->nodeInfoNr = 1; |
|
|
ctxt->nodeInfo = &ctxt->nodeInfoTab[0]; |
|
|
|
|
|
xmlNodePtr n0 = make_dummy_node("first"); |
|
|
xmlNodePtr n1 = make_dummy_node("second"); |
|
|
TEST_ASSERT_NOT_NULL(n0); |
|
|
TEST_ASSERT_NOT_NULL(n1); |
|
|
|
|
|
htmlParserNodeInfo first, second; |
|
|
memset(&first, 0, sizeof(first)); |
|
|
memset(&second, 0, sizeof(second)); |
|
|
first.node = n0; first.begin_pos = 10; first.begin_line = 1; first.end_pos = 11; first.end_line = 2; |
|
|
second.node = n1; second.begin_pos = 20; second.begin_line = 3; second.end_pos = 21; second.end_line = 4; |
|
|
|
|
|
|
|
|
ctxt->nodeInfoTab[0] = first; |
|
|
|
|
|
|
|
|
int ret = test_htmlNodeInfoPush(ctxt, &second); |
|
|
TEST_ASSERT_EQUAL_INT(1, ret); |
|
|
TEST_ASSERT_TRUE(ctxt->nodeInfoMax > 1); |
|
|
TEST_ASSERT_EQUAL_INT(2, ctxt->nodeInfoNr); |
|
|
TEST_ASSERT_NOT_NULL(ctxt->nodeInfoTab); |
|
|
TEST_ASSERT_EQUAL_PTR(&ctxt->nodeInfoTab[1], ctxt->nodeInfo); |
|
|
|
|
|
assert_nodeinfo_equal(&first, &ctxt->nodeInfoTab[0]); |
|
|
assert_nodeinfo_equal(&second, &ctxt->nodeInfoTab[1]); |
|
|
|
|
|
xmlFreeNode(n0); |
|
|
xmlFreeNode(n1); |
|
|
htmlFreeParserCtxt(ctxt); |
|
|
} |
|
|
|
|
|
|
|
|
void test_htmlNodeInfoPush_multiple_pushes(void) { |
|
|
htmlParserCtxtPtr ctxt = htmlNewParserCtxt(); |
|
|
TEST_ASSERT_NOT_NULL(ctxt); |
|
|
|
|
|
|
|
|
ctxt->nodeInfoTab = NULL; |
|
|
ctxt->nodeInfoMax = 0; |
|
|
ctxt->nodeInfoNr = 0; |
|
|
ctxt->nodeInfo = NULL; |
|
|
|
|
|
const int count = 100; |
|
|
xmlNodePtr nodes[count]; |
|
|
|
|
|
for (int i = 0; i < count; i++) { |
|
|
nodes[i] = make_dummy_node("x"); |
|
|
TEST_ASSERT_NOT_NULL(nodes[i]); |
|
|
|
|
|
htmlParserNodeInfo info; |
|
|
memset(&info, 0, sizeof(info)); |
|
|
info.node = nodes[i]; |
|
|
info.begin_pos = (unsigned long)i; |
|
|
info.begin_line = (unsigned long)(i + 1); |
|
|
info.end_pos = (unsigned long)(2 * i); |
|
|
info.end_line = (unsigned long)(2 * i + 1); |
|
|
|
|
|
int ret = test_htmlNodeInfoPush(ctxt, &info); |
|
|
TEST_ASSERT_EQUAL_INT(i, ret); |
|
|
TEST_ASSERT_EQUAL_INT(i + 1, ctxt->nodeInfoNr); |
|
|
|
|
|
|
|
|
assert_nodeinfo_equal(&info, &ctxt->nodeInfoTab[i]); |
|
|
TEST_ASSERT_EQUAL_PTR(&ctxt->nodeInfoTab[i], ctxt->nodeInfo); |
|
|
} |
|
|
|
|
|
TEST_ASSERT_TRUE(ctxt->nodeInfoMax >= ctxt->nodeInfoNr); |
|
|
TEST_ASSERT_EQUAL_INT(count, ctxt->nodeInfoNr); |
|
|
|
|
|
|
|
|
for (int i = 0; i < count; i++) { |
|
|
xmlFreeNode(nodes[i]); |
|
|
} |
|
|
htmlFreeParserCtxt(ctxt); |
|
|
} |
|
|
|
|
|
int main(void) { |
|
|
UNITY_BEGIN(); |
|
|
RUN_TEST(test_htmlNodeInfoPush_initial_alloc_and_store); |
|
|
RUN_TEST(test_htmlNodeInfoPush_no_growth_needed); |
|
|
RUN_TEST(test_htmlNodeInfoPush_growth_and_preserve_existing); |
|
|
RUN_TEST(test_htmlNodeInfoPush_multiple_pushes); |
|
|
return UNITY_END(); |
|
|
} |