Author: Mason Wright
Email:
[email protected]
Date: Sun, 6 Jul 2025 20:30:31 -0600
tests/css_selector.cc
e840f1eeb0ae26af69e1ae146ea9938e28e9f1af
Testing hook
Clone
-
.gitignore
-
Makefile
-
config
-
include/catch_amalgamated.cpp
-
include/catch_amalgamated.hpp
-
include/grim.h
-
include/parser.h
-
index.html
-
main.cc
-
src/adapter.cc
-
src/events.cc
-
src/grim.cc
-
src/parser.cc
-
style.css
M
tests/css_selector.cc
-
tests/html_node.cc
-
tests/html_parser.cc
Commits
b966b2a517365074e5c381dbdea05b3221dc0198
e840f1eeb0ae26af69e1ae146ea9938e28e9f1af
e4e05418a640eaed08cd1ec7cd8644eb1dbcca50
4e01ba8ad2c3361fa4be3d896288020948b58b5e
aae562ac1350480e4889aabb35899f776c5b59e9
6c3ae0e31eb0893f20e3872117f92cc6b9a942af
350e7d88bb2feb9db00c6e032cc6623f215b7adf
95e6c70d23e99ffcf70e5bbe12503496e5d8f232
e188783659b9bc3b9993a647e93ed110e7f41db6
5e4c38ff3c212cdd9881427ef3f8c2706539a190
e50ea9e1356a74af18fdd171337ef9dc931e1f4e
8f2e83556d12aaebe8e8597ea6923804b0eb7a43
1627c585128af263181053ab2cf1a4cdcd14ee21
def3513f75b325464ad88a33c741c4ca80572b77
a21501590980a905fa9b902897d700a42a08b7f0
56074a6bfe4498d092f3a227297c8c20e2bb962c
d9cf1485b7ae0614130494f0e73237921323b9a1
80f04b134ae32ad8a9d526007b33dd02f6600f05
23d6c65f9368d3c622a55a3068a6b2f1efa0c8d4
09c195df02536b6a796bd648fce9669397b96109
f2b5c8202fbc904e2ed78260e3fdbd55164799d2
4bfba076120f389994fc46a98e8b7a2622314400
e36ac5417e10ee9b9f94f340e1ccf28afc5705ea
d00dc89a86dd7e2fcfd4618bc3a1c8cfba9e3c3d
d9eef16adaf292f3748db5fb5aa98463de10d712
18ff2ec1bfc1cf9fcd17c1acb05c3b41f8f0ed83
9e7fd2980d723437ea621b78d395fa72ca3f4922
Diff
diff --git a/tests/css_selector.cc b/tests/css_selector.cc index 90725cc..ee88bda 100644 --- a/tests/css_selector.cc +++ b/tests/css_selector.cc @@ -234,2 +233,0 @@ TEST_CASE("testSelector", "[CSS]") { - // nth-child - // nth-*
#include
#include "../include/grim.h" #include "../include/parser.h" #include
#include
#include
void checkSelectorParts(std::string selector, std::vector
> expected) { INFO("========================="); INFO("Selector: "+selector+"\n"); std::vector
> css = parseSelectorParts(selector); REQUIRE(css.size() == expected.size()); std::string note = ""; for (size_t a = 0; a < css.size(); a++) { std::string str = "{"; for (size_t b = 0; b < css[a].size(); b++) { str += "\""+css[a][b]+"\","; } str += "},"; note += str; } INFO("PARSED: "+note); for (size_t a = 0; a < css.size(); a++) { REQUIRE(css[a].size() == expected[a].size()); for (size_t b = 0; b < css[a].size(); b++) { REQUIRE(css[a][b] == expected[a][b]); } } } TEST_CASE( "CSS Selection", "[css]" ) { SECTION("parseSelectorParts can parse a simple CSS selector") { // This function only parses the last part of the selector checkSelectorParts("div > h1", {{"div", ">", "h1"}}); BENCHMARK("div > h1") { return parseSelectorParts("div > h1"); }; } SECTION("parseSelectorParts can parse a simple CSS selector with a psuedo class selector") { checkSelectorParts("div > h1:checked", {{"div", ">", "h1","[checked]"}}); BENCHMARK("div > h1:checked") { return parseSelectorParts("div > h1:checked"); }; } SECTION("parseSelectorParts can parse a attribute selector") { checkSelectorParts("a[href=\"https://www.example.com/\"]", {{"a", "[href=\"https://www.example.com/\"]"}}); BENCHMARK("a[href=\"https://www.example.com/\"]") { return parseSelectorParts("a[href=\"https://www.example.com/\"]"); }; } SECTION("parseSelectorParts can parse has()") { checkSelectorParts("h1:has(+ h2)", {{"h1",":has(+ h2)"}}); BENCHMARK("h1:has(+ h2)") { return parseSelectorParts("h1:has(+ h2)"); }; } SECTION("parseSelectorParts can parse a complex where() selector") { checkSelectorParts(":where(ol, ul, menu:unsupported)", {{":where(ol, ul, menu:unsupported)"}}); BENCHMARK(":where(ol, ul, menu:unsupported)") { return parseSelectorParts(":where(ol, ul, menu:unsupported)"); }; } SECTION("parseSelectorParts can parse multiple simple selectors"){ checkSelectorParts("input:required, div#id + h1.c1.c2, input[type='password'].class", {{"input", "[required]"},{"div", "#id", "+", "h1", ".c1", ".c2"},{"input", "[type=\"password\"]", ".class"}}); BENCHMARK("input:required, div#id + h1.c1.c2, input[type='password'].class") { return parseSelectorParts("input:required, div#id + h1.c1.c2, input[type='password'].class"); }; } SECTION("parseSelectorParts can parse a selector with a decendent combinator") { checkSelectorParts("div h1", {{"div", " ", "h1"}}); BENCHMARK("div h1") { return parseSelectorParts("div h1"); }; } SECTION("parseSelectorParts can parse a selector with a decendent combinator") { checkSelectorParts("div:has(h1):checked", {{"div", ":has(h1)", "[checked]"}}); BENCHMARK("div h1") { return parseSelectorParts("div h1"); }; } SECTION("parseSelectorParts can parse a selector with only a id") { checkSelectorParts("#id", {{"#id"}}); BENCHMARK("#id") { return parseSelectorParts("#id"); }; } SECTION("parseSelectorParts can parse a selector with multiple selectors") { checkSelectorParts("h1, h1 ~p, :last-child", {{"h1"},{"h1","~","p"}, {"[last-child]"}}); BENCHMARK("h1, h1 ~p, :last-child") { return parseSelectorParts("h1, h1 ~p, :last-child"); }; } SECTION("parseSelectorParts can parse a relative selector without another reference") { checkSelectorParts("+ p", {{"+", "p"}}); } } TEST_CASE("testSelector", "[CSS]") { std::string html = "" "" "" "
This is a simple test
" "
" "" "" "
Header
" "
This is some text for a simple test
" "
" "
" "" ""; std::stringstream ss(html); std::unique_ptr
document = parseStream(ss); SECTION("testSelector can match a element given it's tagName") { auto html = document->children[0].get(); REQUIRE(testSelector(html, parseSelectorParts("html"))); REQUIRE_FALSE(testSelector(html, parseSelectorParts("h1"))); } SECTION("testSelector can match a element by it's attributes only") { auto link = document->children[0]->children[0]->children[1].get(); REQUIRE(testSelector(link, parseSelectorParts("[rel=\"stylesheet\"]"))); } SECTION("testSelector can match a element by it's attributes and tagName") { auto link = document->children[0]->children[0]->children[1].get(); REQUIRE(testSelector(link, parseSelectorParts("link[rel=\"stylesheet\"]"))); REQUIRE_FALSE(testSelector(link, parseSelectorParts("title[rel=\"stylesheet\"]"))); } SECTION("testSelector can match a element by it's id only") { auto h1 = document->children[0]->children[1]->children[0].get(); REQUIRE(testSelector(h1, parseSelectorParts("#h1Tag"))); } SECTION("testSelector can match a element by it's id and tagName") { auto h1 = document->children[0]->children[1]->children[0].get(); REQUIRE(testSelector(h1, parseSelectorParts("h1#h1Tag"))); } SECTION("testSelector can match a element by it's class and not matach on a non class") { auto p = document->children[0]->children[1]->children[1].get(); REQUIRE(testSelector(p, parseSelectorParts(".class1"))); REQUIRE_FALSE(testSelector(p, parseSelectorParts(".class3"))); } SECTION("testSelector can match a child combinator") { auto h1 = document->children[0]->children[1]->children[0].get(); REQUIRE(testSelector(h1, parseSelectorParts("body > h1"))); REQUIRE_FALSE(testSelector(h1, parseSelectorParts("html > h1"))); } SECTION("testSelector can match a next sibling combinator") { auto p = document->children[0]->children[1]->children[1].get(); REQUIRE(testSelector(p, parseSelectorParts("h1 + p"))); REQUIRE_FALSE(testSelector(p, parseSelectorParts("h1 + div"))); } SECTION("testSelector can match a descendant combinator") { auto p = document->children[0]->children[1]->children[1].get(); REQUIRE(testSelector(p, parseSelectorParts("body p"))); REQUIRE_FALSE(testSelector(p, parseSelectorParts("h1 p"))); } SECTION("testSelector can match a subsequent-sibling combinator") { auto p = document->children[0]->children[1]->children[1].get(); REQUIRE(testSelector(p, parseSelectorParts("h1 ~ p"))); REQUIRE_FALSE(testSelector(p, parseSelectorParts("div ~ p"))); } SECTION("testSelector can match a element with a pseudo class") { auto input = document->children[0]->children[1]->children[3].get(); REQUIRE(testSelector(input, parseSelectorParts("input:required"))); REQUIRE(testSelector(input, parseSelectorParts(":checked"))); REQUIRE_FALSE(testSelector(input, parseSelectorParts("input:enabled"))); } SECTION("testSelector can match a element with first-child") { auto h1 = document->children[0]->children[1]->children[0].get(); REQUIRE(testSelector(h1, parseSelectorParts(":first-child"))); } SECTION("testSelector can match a element with last-child") { auto input = document->children[0]->children[1]->children[3].get(); REQUIRE(testSelector(input, parseSelectorParts(":last-child"))); } SECTION("testSelector can match multiple selectors") { auto input = document->children[0]->children[1]->children[3].get(); REQUIRE(testSelector(input, parseSelectorParts("h1, h1 ~p, :last-child"))); REQUIRE_FALSE(testSelector(input, parseSelectorParts("h1, h1 ~p, :first-child"))); BENCHMARK("Multiselector and parse") { return testSelector(input, parseSelectorParts("h1, h1 ~p, :last-child")); }; auto parts = parseSelectorParts("h1, h1 ~p, :last-child"); BENCHMARK("Multiselector pre-parse") { return testSelector(input, parts); }; } SECTION("testSelector can match :is() selectors") { auto input = document->children[0]->children[1]->children[3].get(); REQUIRE(testSelector(input, parseSelectorParts(":is(h1, input, div)"))); REQUIRE_FALSE(testSelector(input, parseSelectorParts(":is(h1, html, div)"))); } SECTION("testSelector can match :where() selectors") { auto input = document->children[0]->children[1]->children[3].get(); REQUIRE(testSelector(input, parseSelectorParts(":where(h1, input, div)"))); REQUIRE_FALSE(testSelector(input, parseSelectorParts(":where(h1, html, div)"))); } SECTION("testSelector can match :not() selectors") { auto input = document->children[0]->children[1]->children[3].get(); REQUIRE(testSelector(input, parseSelectorParts(":not(h1, html, div)"))); REQUIRE_FALSE(testSelector(input, parseSelectorParts(":not(h1, input, div)"))); } SECTION("testSelector can match nested :not(:is()) selectors") { auto input = document->children[0]->children[1]->children[3].get(); REQUIRE(testSelector(input, parseSelectorParts(":not(:is(h1, html, div))"))); REQUIRE_FALSE(testSelector(input, parseSelectorParts(":not(:is(h1, input, div))"))); BENCHMARK("is not test") { return testSelector(input, parseSelectorParts(":not(:is(h1, html, div))")); }; } SECTION("testSelector can match a :has() selector") { auto h1 = document->children[0]->children[1]->children[0].get(); REQUIRE(testSelector(h1, parseSelectorParts("h1:has(+ p)"))); REQUIRE_FALSE(testSelector(h1, parseSelectorParts("h1:has(+ p:required)"))); } // make for: // pseudo elements // * // pseudo selectors(:has, :where etc) // nth-child // nth-* }