| | #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(); |
| | } |