mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
[tests] One test fails
This commit is contained in:
parent
4311445f49
commit
c0c7fbc784
@ -94,20 +94,28 @@ explode(char delim, std::string const & s)
|
|||||||
result.push_back(std::move(token));
|
result.push_back(std::move(token));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (s.back() == delim)
|
||||||
|
{
|
||||||
|
result.push_back(std::string());
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
preg_replace(std::string & pattern, const char *replacement, std::string & subject)
|
preg_replace(std::string & pattern, const char *replacement, std::string & subject)
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
return std::regex_replace(subject, std::regex(pattern), replacement);
|
return std::regex_replace(subject, std::regex(pattern), replacement);
|
||||||
|
} catch (const std::regex_error &e) {
|
||||||
|
std::cout << e.what() << " " << pattern << "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
typedef std::string (*my_callback)(const std::smatch &m);
|
typedef std::string (*my_callback)(const std::smatch &m);
|
||||||
|
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
preg_replace_callback(std::string & pattern, my_callback callback, std::string & subject)
|
preg_replace_callback(std::string & pattern, my_callback callback, std::string & subject)
|
||||||
{
|
{
|
||||||
@ -136,7 +144,7 @@ class Translator;
|
|||||||
class Rule
|
class Rule
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::string apply(std::string &selector)
|
virtual std::string apply(std::string &selector)
|
||||||
{
|
{
|
||||||
return selector;
|
return selector;
|
||||||
}
|
}
|
||||||
@ -153,30 +161,133 @@ class RegexRule : public Rule
|
|||||||
RegexRule(const char *pat, const char *repl) : pattern(pat), replacement(repl)
|
RegexRule(const char *pat, const char *repl) : pattern(pat), replacement(repl)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
std::string apply(std::string &selector)
|
||||||
|
{
|
||||||
|
std::string r(pattern);
|
||||||
|
|
||||||
|
// std::cout << "RegexRule: pattern=" << r << " replacement=" << replacement << " selector=" << selector << "\n";
|
||||||
|
|
||||||
|
return preg_replace(r, replacement, selector);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class NotRule : public Rule
|
class NotRule : public Rule
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
Translator *t;
|
||||||
public:
|
public:
|
||||||
NotRule(Translator *t)
|
NotRule(Translator *tt);
|
||||||
{
|
std::string apply(std::string &selector);
|
||||||
}
|
std::string callback(const std::smatch &matches);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::string
|
||||||
|
not_rule_callback(const std::smatch &m);
|
||||||
|
|
||||||
|
class NotRule *currentNotRule;
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
is_digits(const std::string &str)
|
||||||
|
{
|
||||||
|
return std::all_of(str.begin(), str.end(), ::isdigit); // C++11
|
||||||
|
}
|
||||||
|
|
||||||
|
class NthChildRule;
|
||||||
|
|
||||||
|
class NthChildRule *currentNth;
|
||||||
|
|
||||||
|
std::string
|
||||||
|
nth_callback(const std::smatch &m);
|
||||||
|
|
||||||
class NthChildRule : public Rule
|
class NthChildRule : public Rule
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NthChildRule()
|
NthChildRule()
|
||||||
{
|
{
|
||||||
|
currentNth = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string apply(std::string & selector)
|
||||||
|
{
|
||||||
|
std::cout << "NthChildRule " << selector << "\n";
|
||||||
|
std::string pat("([a-zA-Z0-9_\\-*]+):nth-child\\(([^)]*)\\)");
|
||||||
|
return preg_replace_callback(pat, nth_callback, selector);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string callback(const std::smatch &matches)
|
||||||
|
{
|
||||||
|
// std::cout << matches[0] << " " << matches[1] << " " << matches[2] << std::endl;
|
||||||
|
std::ostringstream os;
|
||||||
|
std::ostringstream res;
|
||||||
|
os << matches[2];
|
||||||
|
|
||||||
|
if (os.str() == "n")
|
||||||
|
{
|
||||||
|
res << matches[1];
|
||||||
|
}
|
||||||
|
else if (os.str() == "even")
|
||||||
|
{
|
||||||
|
res << matches[1] << "[(count(preceding-sibling::*) + 1) mod 2=0]";
|
||||||
|
}
|
||||||
|
else if (os.str() == "odd")
|
||||||
|
{
|
||||||
|
res << matches[1] << "[(count(preceding-sibling::*) + 1) mod 2=1]";
|
||||||
|
}
|
||||||
|
else if (is_digits(os.str()))
|
||||||
|
{
|
||||||
|
res << "*[" << matches[2] << "]/self::" << matches[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// std::cout << "else" << std::endl;
|
||||||
|
|
||||||
|
std::string pat("^([\\d]*)n.*?([\\d]*)$");
|
||||||
|
std::string m = matches[2].str();
|
||||||
|
std::string b1 = preg_replace(pat, "$1+$2", m);
|
||||||
|
//std::cout << b1 << std::endl;
|
||||||
|
auto b = explode('+', b1);
|
||||||
|
//std::cout << b[0] << std::endl;
|
||||||
|
//std::cout << b[1] << std::endl;
|
||||||
|
res << matches[1] << "[(count(preceding-sibling::*)+1)>=" << b[1] << " and ((count(preceding-sibling::*)+1)-"
|
||||||
|
<< b[1] << ") mod " << b[0] << "=0]";
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.str();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::string
|
||||||
|
nth_callback(const std::smatch &m)
|
||||||
|
{
|
||||||
|
auto fun = std::bind(&NthChildRule::callback, ::currentNth, std::placeholders::_1);
|
||||||
|
|
||||||
|
return fun(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
not_rule_callback(const std::smatch &m)
|
||||||
|
{
|
||||||
|
auto fun = std::bind(&NotRule::callback, ::currentNotRule, std::placeholders::_1);
|
||||||
|
|
||||||
|
return fun(m);
|
||||||
|
}
|
||||||
|
|
||||||
class DollarEqualRule : public Rule
|
class DollarEqualRule : public Rule
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DollarEqualRule()
|
DollarEqualRule()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string apply(std::string &selector)
|
||||||
|
{
|
||||||
|
// std::cout << "DollarEqualRule: selector=" << selector << "\n";
|
||||||
|
|
||||||
|
std::string pattern("\\[([a-zA-Z0-9\\_\\-]+)\\$=([^\\]]+)\\]");
|
||||||
|
|
||||||
|
return preg_replace_callback(pattern, dollar_equal_rule_callback, selector);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Translator
|
class Translator
|
||||||
@ -218,7 +329,7 @@ private:
|
|||||||
// all descendant or self to //
|
// all descendant or self to //
|
||||||
new RegexRule("(^|[^a-zA-Z0-9\\_\\-\\*])([#\\.])([a-zA-Z0-9\\_\\-]+)", "$1*$2$3"),
|
new RegexRule("(^|[^a-zA-Z0-9\\_\\-\\*])([#\\.])([a-zA-Z0-9\\_\\-]+)", "$1*$2$3"),
|
||||||
new RegexRule("([\\>\\+\\|\\~\\,\\s])([a-zA-Z\\*]+)", "$1//$2"),
|
new RegexRule("([\\>\\+\\|\\~\\,\\s])([a-zA-Z\\*]+)", "$1//$2"),
|
||||||
new RegexRule("\\s+\\/\\//", "//"),
|
new RegexRule("\\s+\\/\\/", "//"),
|
||||||
|
|
||||||
// :first-child
|
// :first-child
|
||||||
new RegexRule("([a-zA-Z0-9\\_\\-\\*]+):first-child", "*[1]/self::$1"),
|
new RegexRule("([a-zA-Z0-9\\_\\-\\*]+):first-child", "*[1]/self::$1"),
|
||||||
@ -275,11 +386,37 @@ private:
|
|||||||
new RegexRule(":root", "/"),
|
new RegexRule(":root", "/"),
|
||||||
|
|
||||||
// use * when tag was omitted
|
// use * when tag was omitted
|
||||||
new RegexRule("^\[", "*["),
|
new RegexRule("^\\[", "*["),
|
||||||
new RegexRule("\\|\\[", "|*[")
|
new RegexRule("\\|\\[", "|*[")
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
NotRule::NotRule(Translator *tt) : t(tt)
|
||||||
|
{
|
||||||
|
currentNotRule = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
NotRule::apply(std::string &selector)
|
||||||
|
{
|
||||||
|
// std::cout << "NotRule: selector=" << selector << "\n";
|
||||||
|
|
||||||
|
std::string pat("([a-zA-Z0-9\\_\\-\\*]+):not\\(([^\\)]*)\\)");
|
||||||
|
return preg_replace_callback(pat, not_rule_callback, selector);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
NotRule::callback(const std::smatch &matches)
|
||||||
|
{
|
||||||
|
std::string m(matches[2].str());
|
||||||
|
std::string pat("^[^\\[]+\\[([^\\]]*)\\].*$");
|
||||||
|
std::string ret(t->translate(m));
|
||||||
|
std::string subresult = preg_replace(pat, "$1", ret);
|
||||||
|
return matches[1].str() + "[not(" + subresult + ")]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
@ -296,8 +433,8 @@ typedef const char *test[2];
|
|||||||
void
|
void
|
||||||
tests()
|
tests()
|
||||||
{
|
{
|
||||||
|
|
||||||
test provider[] = {
|
test provider[] = {
|
||||||
|
#if 1
|
||||||
{"div", "//div"},
|
{"div", "//div"},
|
||||||
{"body div", "//body//div"},
|
{"body div", "//body//div"},
|
||||||
{"div p", "//div//p"},
|
{"div p", "//div//p"},
|
||||||
@ -326,7 +463,6 @@ tests()
|
|||||||
{"div[class|=dialog]", "//div[@class=\"dialog\" or starts-with(@class,concat(\"dialog\",\"-\"))]"},
|
{"div[class|=dialog]", "//div[@class=\"dialog\" or starts-with(@class,concat(\"dialog\",\"-\"))]"},
|
||||||
{"div[class!=made_up]", "//div[not(@class) or @class!=\"made_up\"]"},
|
{"div[class!=made_up]", "//div[not(@class) or @class!=\"made_up\"]"},
|
||||||
{"div[property!=\"made_up\"]", "//div[not(@property) or @property!=\"made_up\"]"},
|
{"div[property!=\"made_up\"]", "//div[not(@property) or @property!=\"made_up\"]"},
|
||||||
|
|
||||||
{"div[class~=example]", "//div[contains(concat(\" \",normalize-space(@class),\" \"),concat(\" \",\"example\",\" \"))]"},
|
{"div[class~=example]", "//div[contains(concat(\" \",normalize-space(@class),\" \"),concat(\" \",\"example\",\" \"))]"},
|
||||||
{"div:not(.example)", "//div[not(contains(concat(\" \",normalize-space(@class),\" \"),\" example \"))]"},
|
{"div:not(.example)", "//div[not(contains(concat(\" \",normalize-space(@class),\" \"),\" example \"))]"},
|
||||||
{"p:contains(selectors)", "//p[contains(string(.),\"selectors\")]"},
|
{"p:contains(selectors)", "//p[contains(string(.),\"selectors\")]"},
|
||||||
@ -336,6 +472,7 @@ tests()
|
|||||||
{"p:nth-child(3n+8)", "//p[(count(preceding-sibling::*)+1)>=8 and ((count(preceding-sibling::*)+1)-8) mod 3=0]"},
|
{"p:nth-child(3n+8)", "//p[(count(preceding-sibling::*)+1)>=8 and ((count(preceding-sibling::*)+1)-8) mod 3=0]"},
|
||||||
{"p:nth-child(2n+1)", "//p[(count(preceding-sibling::*)+1)>=1 and ((count(preceding-sibling::*)+1)-1) mod 2=0]"},
|
{"p:nth-child(2n+1)", "//p[(count(preceding-sibling::*)+1)>=1 and ((count(preceding-sibling::*)+1)-1) mod 2=0]"},
|
||||||
{"p:nth-child(3)", "//*[3]/self::p"},
|
{"p:nth-child(3)", "//*[3]/self::p"},
|
||||||
|
#endif
|
||||||
{"p:nth-child(4n)", "//p[(count(preceding-sibling::*)+1)>=0 and ((count(preceding-sibling::*)+1)-0) mod 4=0]"},
|
{"p:nth-child(4n)", "//p[(count(preceding-sibling::*)+1)>=0 and ((count(preceding-sibling::*)+1)-0) mod 4=0]"},
|
||||||
{"p:only-child", "//*[last()=1]/self::p"},
|
{"p:only-child", "//*[last()=1]/self::p"},
|
||||||
{"p:last-child", "//p[not(following-sibling::*)]"},
|
{"p:last-child", "//p[not(following-sibling::*)]"},
|
||||||
@ -358,8 +495,13 @@ tests()
|
|||||||
std::string expected(t[1]);
|
std::string expected(t[1]);
|
||||||
|
|
||||||
std::string result = translator->translate(selector);
|
std::string result = translator->translate(selector);
|
||||||
std::cout << selector << " " << result << " " << expected << " ";
|
std::cout << t[0] << " ";
|
||||||
std::cout << ((result == expected) ? "\033[32mOK\033[0m" : "\033[31mFAIL\033[0m");
|
std::cout << ((result == expected) ? "\033[32mOK\033[0m" : "\033[31mFAIL\033[0m");
|
||||||
|
|
||||||
|
// if (result != expected)
|
||||||
|
// {
|
||||||
|
// std::cout << " " << result << " " << expected;
|
||||||
|
// }
|
||||||
std::cout << "\n";
|
std::cout << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -367,6 +509,7 @@ tests()
|
|||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
#if 1
|
#if 1
|
||||||
std::vector<std::string> x;
|
std::vector<std::string> x;
|
||||||
|
|
||||||
@ -398,6 +541,16 @@ main(int argc, char **argv)
|
|||||||
std::string pat2 = "(\\d{2}/\\d{2}/)(\\d{4})";
|
std::string pat2 = "(\\d{2}/\\d{2}/)(\\d{4})";
|
||||||
|
|
||||||
std::cout << preg_replace_callback(pat2, next_year, text);
|
std::cout << preg_replace_callback(pat2, next_year, text);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
auto v = explode('+', "4+");
|
||||||
|
|
||||||
|
for (auto e : v)
|
||||||
|
{
|
||||||
|
std::cout << e << "\n";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
tests();
|
tests();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user