30#include "../src/html.h"
32#define Red "\033[0;31m"
33#define Green "\033[0;32m"
34#define NOCOLOR "\033[0m"
36static int testCount = 0;
37static int passCount = 0;
39static void check(
bool cond,
const char *desc) {
43 std::cout <<
Green <<
" PASS: " << desc <<
NOCOLOR << std::endl;
45 std::cout <<
Red <<
" FAIL: " << desc <<
NOCOLOR << std::endl;
51 std::cout <<
"=== parentElement() after parse ===" << std::endl;
53 std::string html =
"<div id=\"outer\"><p id=\"inner\">hi</p></div>";
61 check(outer !=
nullptr && inner !=
nullptr,
"found both elements by id");
63 check(inner->
parentElement() == outer,
"inner element's parent is the outer div");
64 check(outer->
parentElement() != outer,
"outer element's parent is not itself");
69 std::cout <<
"=== appendChild / insertChild parent ===" << std::endl;
76 "appendChild's new node has the container as its parent");
84 "insertChild's new node has the container as its parent");
88 std::cout <<
"=== copy re-parents subtree ===" << std::endl;
90 std::string html =
"<div id=\"outer\"><p id=\"inner\">hi</p></div>";
101 check(copiedInner !=
nullptr && copiedOuter !=
nullptr,
102 "found both elements by id in the copied tree");
103 if (copiedInner && copiedOuter && origOuter) {
105 "copied inner element's parent is the COPIED outer div");
107 "copied inner element's parent is NOT the original outer div");
112 std::cout <<
"=== remove() first child ===" << std::endl;
114 std::string html =
"<ul><li id=\"a\">1</li><li id=\"b\">2</li><li id=\"c\">3</li></ul>";
119 check(ul !=
nullptr,
"found <ul>");
128 check(newFirst !=
nullptr,
"ul still has a first child after removing the old one");
132 "ul's first child is now \"b\" (the old first child's next sibling)");
134 "the new first child's prevElement is cleared (no dangling back-pointer)");
136 check(third !=
nullptr &&
138 "the rest of the sibling chain (\"c\") survived (the original bug lost it)");
144 std::cout <<
"=== remove() non-first child (previously crashed) ===" << std::endl;
146 std::string html =
"<ul><li id=\"a\">1</li><li id=\"b\">2</li><li id=\"c\">3</li></ul>";
152 check(ul !=
nullptr && b !=
nullptr,
"found <ul> and \"b\"");
158 check(
true,
"removing a middle child (reached via sibling advancement) doesn't crash");
160 check(a !=
nullptr && a->
nextElement() !=
nullptr,
"\"a\" still has a next sibling");
163 check(c->
getAtributte(
"id") ==
"c",
"\"a\"'s next sibling is now \"c\", skipping removed \"b\"");
165 "\"c\"'s prevElement correctly points to \"a\", not left dangling at removed \"b\"");
171 std::cout <<
"\n=== " << passCount <<
"/" << testCount <<
" tests passed ===" << std::endl;
173 return (passCount == testCount) ? 0 : -1;
Abstract base class for all nodes in the HTML tree.
Element * prevElement() const
Element * parentElement() const
Element * nextElement() const
const std::string getAtributte(const std::string &name) const
void appendChild(const Element *el)
void insertChild(const Element *el)
Element * firstChild() const
HtmlElement * getElementbyID(const std::string &id) const
libhtmlpp::Element & parse()
Parses the current buffer into a DOM-like tree and returns the root element.