| #include "unity/unity.h" |
| #include <libxml/HTMLparser.h> |
| #include <libxml/parser.h> |
| #include <stdlib.h> |
| #include <string.h> |
|
|
| |
| extern void test_htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate); |
|
|
| |
| static htmlParserCtxtPtr make_ctx_from_mem(const char *buf, int len) { |
| htmlParserCtxtPtr ctxt = htmlCreateMemoryParserCtxt(buf, len); |
| TEST_ASSERT_NOT_NULL_MESSAGE(ctxt, "Failed to create HTML parser context"); |
| |
| (void)htmlCtxtUseOptions(ctxt, HTML_PARSE_RECOVER | HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING); |
| return ctxt; |
| } |
|
|
| static size_t cur_offset(htmlParserCtxtPtr ctxt) { |
| return (size_t)(ctxt->input->cur - ctxt->input->base); |
| } |
|
|
| static size_t end_offset(htmlParserCtxtPtr ctxt) { |
| return (size_t)(ctxt->input->end - ctxt->input->base); |
| } |
|
|
| |
| void setUp(void) { |
| |
| xmlInitParser(); |
| } |
|
|
| void tearDown(void) { |
| |
| } |
|
|
| |
|
|
| void test_htmlParseTryOrFinish_start_nonterminate_small_avail_returns_early(void) { |
| const char *data = "abc"; |
| htmlParserCtxtPtr ctxt = make_ctx_from_mem(data, (int)strlen(data)); |
| TEST_ASSERT_EQUAL_INT(XML_PARSER_START, ctxt->instate); |
|
|
| size_t before_cur = cur_offset(ctxt); |
| test_htmlParseTryOrFinish(ctxt, 0); |
|
|
| |
| TEST_ASSERT_EQUAL_INT(XML_PARSER_START, ctxt->instate); |
| TEST_ASSERT_EQUAL_size_t(before_cur, cur_offset(ctxt)); |
|
|
| htmlFreeParserCtxt(ctxt); |
| } |
|
|
| void test_htmlParseTryOrFinish_start_terminate_progresses_and_consumes_text(void) { |
| const char *data = "abc"; |
| htmlParserCtxtPtr ctxt = make_ctx_from_mem(data, (int)strlen(data)); |
| size_t end = end_offset(ctxt); |
|
|
| test_htmlParseTryOrFinish(ctxt, 1); |
|
|
| |
| TEST_ASSERT_EQUAL_INT(XML_PARSER_CONTENT, ctxt->instate); |
| TEST_ASSERT_EQUAL_size_t(end, cur_offset(ctxt)); |
| |
| TEST_ASSERT_EQUAL_INT(0, ctxt->endCheckState); |
|
|
| htmlFreeParserCtxt(ctxt); |
| } |
|
|
| void test_htmlParseTryOrFinish_misc_to_start_tag_partial_nonterminate(void) { |
| |
| const char *data = " <p"; |
| htmlParserCtxtPtr ctxt = make_ctx_from_mem(data, (int)strlen(data)); |
|
|
| test_htmlParseTryOrFinish(ctxt, 0); |
|
|
| |
| TEST_ASSERT_EQUAL_INT(XML_PARSER_START_TAG, ctxt->instate); |
| |
| TEST_ASSERT_TRUE(ctxt->checkIndex != 0); |
|
|
| |
| |
| |
| TEST_ASSERT_TRUE(cur_offset(ctxt) < end_offset(ctxt)); |
|
|
| htmlFreeParserCtxt(ctxt); |
| } |
|
|
| void test_htmlParseTryOrFinish_parses_comment_and_advances(void) { |
| const char *data = "<!--x-->"; |
| htmlParserCtxtPtr ctxt = make_ctx_from_mem(data, (int)strlen(data)); |
| size_t end = end_offset(ctxt); |
|
|
| test_htmlParseTryOrFinish(ctxt, 1); |
|
|
| |
| TEST_ASSERT_EQUAL_size_t(end, cur_offset(ctxt)); |
| |
| TEST_ASSERT_NOT_EQUAL_INT(XML_PARSER_EOF, ctxt->instate); |
|
|
| htmlFreeParserCtxt(ctxt); |
| } |
|
|
| void test_htmlParseTryOrFinish_parses_simple_element_and_end_tag_full_terminate(void) { |
| const char *data = "<p>Hi</p>"; |
| htmlParserCtxtPtr ctxt = make_ctx_from_mem(data, (int)strlen(data)); |
| size_t end = end_offset(ctxt); |
|
|
| test_htmlParseTryOrFinish(ctxt, 1); |
|
|
| |
| TEST_ASSERT_EQUAL_size_t(end, cur_offset(ctxt)); |
| |
| TEST_ASSERT_EQUAL_INT(XML_PARSER_CONTENT, ctxt->instate); |
| TEST_ASSERT_EQUAL_INT(0, ctxt->endCheckState); |
|
|
| htmlFreeParserCtxt(ctxt); |
| } |
|
|
| void test_htmlParseTryOrFinish_end_tag_only_transitions_and_consumes(void) { |
| const char *data = "</p>"; |
| htmlParserCtxtPtr ctxt = make_ctx_from_mem(data, (int)strlen(data)); |
| size_t end = end_offset(ctxt); |
|
|
| test_htmlParseTryOrFinish(ctxt, 1); |
|
|
| |
| TEST_ASSERT_EQUAL_size_t(end, cur_offset(ctxt)); |
| |
| TEST_ASSERT_EQUAL_INT(XML_PARSER_CONTENT, ctxt->instate); |
|
|
| htmlFreeParserCtxt(ctxt); |
| } |
|
|
| |
| int main(void) { |
| UNITY_BEGIN(); |
| RUN_TEST(test_htmlParseTryOrFinish_start_nonterminate_small_avail_returns_early); |
| RUN_TEST(test_htmlParseTryOrFinish_start_terminate_progresses_and_consumes_text); |
| RUN_TEST(test_htmlParseTryOrFinish_misc_to_start_tag_partial_nonterminate); |
| RUN_TEST(test_htmlParseTryOrFinish_parses_comment_and_advances); |
| RUN_TEST(test_htmlParseTryOrFinish_parses_simple_element_and_end_tag_full_terminate); |
| RUN_TEST(test_htmlParseTryOrFinish_end_tag_only_transitions_and_consumes); |
| return UNITY_END(); |
| } |