#include
#include "../include/grim.h"
#include "../include/parser.h"
#include
#include
void checkNode(Node* node, std::string tagName, unsigned long children, std::string id, std::vector classes, std::unordered_map attributes, std::string note = "") {
INFO("=========================");
INFO("TAG: "+tagName);
INFO("NOTE: "+note+"\n");
INFO("HTML:\n"+node->print());
REQUIRE(node->getTagName() == tagName);
REQUIRE(node->children.size() == children);
REQUIRE(node->getId() == id);
size_t i = 0;
for (auto c : node->classList.values()) {
REQUIRE(c == classes[i]);
i++;
}
for (auto pair : attributes) {
REQUIRE(node->getAttribute(pair.first) == pair.second);
}
}
TEST_CASE( "parseStream can parse various types of HTML strings", "[html]" ) {
SECTION("Parses a simple HTML document") {
std::string html = ""
""
""
"This is a simple test"
""
""
""
"
This is some text for a simple test
"
""
"";
std::stringstream ss(html);
std::unique_ptr document = parseStream(ss);
// Ensure the only child of root is html
Node* current = document->children[0].get();
checkNode(current, "html", 2, "", {}, {{}});
current = current->children[0].get();
checkNode(current, "head", 2, "", {}, {{}});
current = current->children[0].get();
checkNode(current, "title", 1, "", {}, {{}});
current = current->children[0].get();
checkNode(current, "text", 0, "", {}, {{"innerText","This is a simple test"}}, "First innerText check");
current = current->parent->parent->children[1].get();
checkNode(current, "link", 0, "", {}, {{"rel","stylesheet"}, {"href","/style.css"}}
, "Check attribute parsing with different quote types. Also check self closing tags");
current = current->parent->parent->children[1].get();
checkNode(current, "body", 1, "", {}, {{}});
current = current->children[0].get();
checkNode(current, "p", 1, "paragraph", {"class1", "class2"}, {{}}, "Checks for id and class parsing");
current = current->children[0].get();
checkNode(current, "text", 0, "", {}, {{"innerText","This is some text for a simple test"}}, "Second innerText check");
}
SECTION("Inline comment") {
std::string html = "
"
""
"
";
std::stringstream ss(html);
std::unique_ptr document = parseStream(ss);
// Ensure the only child of root is html
Node* current = document->children[0].get();
checkNode(current, "div", 0, "", {}, {{}});
}
SECTION("Multi line comment") {
std::string html = "
"
""
"
";
std::stringstream ss(html);
std::unique_ptr document = parseStream(ss);
// Ensure the only child of root is html
Node* current = document->children[0].get();
checkNode(current, "div", 0, "", {}, {{}});
}
SECTION("Multi line comment with html") {
std::string html = "
"
""
"
";
std::stringstream ss(html);
std::unique_ptr document = parseStream(ss);
// Ensure the only child of root is html
Node* current = document->children[0].get();
checkNode(current, "div", 0, "", {}, {{}});
}
SECTION("Style tag parsing (with HTML in the content prop)") {
std::string html = ""
"
test
";
std::stringstream ss(html);
std::unique_ptr document = parseStream(ss);
// Ensure the only child of root is html
Node* current = document->children[0].get();
checkNode(current, "style", 1, "", {}, {{}});
current = current->children[0].get();
checkNode(current, "text", 0, "", {}, {{"innerText", "body > h1 {"
"margin-left: calc(100% / 50px);"
"background: url(https://example.com/image.png);"
"content: \"
hi
\";"
"}"}});
current = document->children[1].get();
checkNode(current, "h1", 1, "", {}, {{}});
current = current->children[0].get();
checkNode(current, "text", 0, "", {}, {{"innerText", "test"}});
}
SECTION("Script tag prematurly closing a pre tag") {
std::string html = "
"
""
"
";
std::stringstream ss(html);
std::unique_ptr document = parseStream(ss);
// Ensure the only child of root is html
Node* current = document->children[0].get();
checkNode(current, "pre", 1, "", {}, {{}});
current = current->children[0].get();
checkNode(current, "script", 1, "", {}, {{}});
current = current->children[0].get();
checkNode(current, "text", 0, "", {}, {{"innerText", "console.log(\"\");"}});
}
SECTION("Textarea with script tag inside") {
std::string html = "
"
""
"
";
std::stringstream ss(html);
std::unique_ptr document = parseStream(ss);
// Ensure the only child of root is html
Node* current = document->children[0].get();
checkNode(current, "textarea", 1, "", {}, {{}});
current = current->children[0].get();
checkNode(current, "text", 0, "", {}, {{"innerText",""}});
}
}