1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
#include "FilterParser.h"
#include "3rd-party/catch.hpp"
TEST_CASE(
"FilterParser doesn't crash parsing expression with invalid character "
"in operator",
"[FilterParser]")
{
FilterParser fp;
REQUIRE_FALSE(fp.parse_string("title =¯ \"foo\""));
}
TEST_CASE("FilterParser raises errors on invalid queries", "[FilterParser]")
{
FilterParser fp;
SECTION("incorrect string quoting") {
REQUIRE_FALSE(fp.parse_string("a = \"b"));
}
SECTION("non-value to the right of equality check operator") {
REQUIRE_FALSE(fp.parse_string("a = b"));
}
SECTION("unbalanced parentheses") {
REQUIRE_FALSE(fp.parse_string("((a=\"b\")))"));
}
SECTION("non-existent operator") {
REQUIRE_FALSE(fp.parse_string("a !! \"b\""));
}
SECTION("incorrect syntax for range") {
REQUIRE_FALSE(fp.parse_string("AAAA between 0:15:30"));
}
SECTION("no whitespace after the `and` operator") {
REQUIRE_FALSE(fp.parse_string("x = 42andy=0"));
REQUIRE_FALSE(fp.parse_string("x = 42 andy=0"));
}
SECTION("operator without arguments") {
REQUIRE_FALSE(fp.parse_string("=!"));
}
}
TEST_CASE("FilterParser doesn't raise errors on valid queries",
"[FilterParser]")
{
FilterParser fp;
SECTION("test parser") {
REQUIRE(fp.parse_string("a = \"b\""));
REQUIRE(fp.parse_string("(a=\"b\")"));
REQUIRE(fp.parse_string("((a=\"b\"))"));
}
SECTION("test operators") {
REQUIRE(fp.parse_string("a != \"b\""));
REQUIRE(fp.parse_string("a =~ \"b\""));
REQUIRE(fp.parse_string("a !~ \"b\""));
}
SECTION("Parse string of complex query") {
REQUIRE(fp.parse_string(
"( a = \"b\") and ( b = \"c\" ) or ( ( c != \"d\" ) "
"and ( c !~ \"asdf\" )) or c != \"xx\""));
}
}
TEST_CASE("Both = and == are accepted", "[FilterParser]")
{
FilterParser fp;
REQUIRE(fp.parse_string("a = \"abc\""));
REQUIRE(fp.parse_string("a == \"abc\""));
}
TEST_CASE("FilterParser disallows NUL byte inside filter expressions",
"[FilterParser]")
{
FilterParser fp;
REQUIRE_FALSE(fp.parse_string(std::string("attri\0bute = 0", 14)));
REQUIRE_FALSE(fp.parse_string(std::string("attribute\0= 0", 13)));
REQUIRE_FALSE(fp.parse_string(std::string("attribute = \0", 13)));
REQUIRE_FALSE(fp.parse_string(std::string("attribute = \\\"\0\\\"", 17)));
// The following shouldn't pass, but it does. Further REQUIREs explain why:
// the NUL byte silently terminates parsing.
REQUIRE(fp.parse_string(std::string("attribute = \"hello\0world\"", 25)));
REQUIRE(fp.get_root()->op == MATCHOP_EQ);
REQUIRE(fp.get_root()->name == "attribute");
REQUIRE(fp.get_root()->literal == "\"hello");
}
TEST_CASE("FilterParser parses empty string literals", "[FilterParser]")
{
FilterParser fp;
REQUIRE(fp.parse_string("title==\"\""));
REQUIRE(fp.get_root()->op == MATCHOP_EQ);
REQUIRE(fp.get_root()->name == "title");
REQUIRE(fp.get_root()->literal == "");
}
TEST_CASE("Logical operators require space or paren after them",
"[FilterParser]")
{
FilterParser fp;
const auto verify_tree = [&fp](int op) {
REQUIRE(fp.get_root()->op == op);
REQUIRE(fp.get_root()->l->op == MATCHOP_EQ);
REQUIRE(fp.get_root()->l->name == "a");
REQUIRE(fp.get_root()->l->literal == "42");
REQUIRE(fp.get_root()->r->op == MATCHOP_EQ);
REQUIRE(fp.get_root()->r->name == "y");
REQUIRE(fp.get_root()->r->literal == "0");
};
SECTION("`and`") {
REQUIRE_FALSE(fp.parse_string("a=42andy=0"));
REQUIRE_FALSE(fp.parse_string("(a=42)andy=0"));
REQUIRE_FALSE(fp.parse_string("a=42 andy=0"));
REQUIRE(fp.parse_string("a=42and(y=0)"));
verify_tree(LOGOP_AND);
REQUIRE(fp.parse_string("(a=42)and(y=0)"));
verify_tree(LOGOP_AND);
REQUIRE(fp.parse_string("a=42and y=0"));
verify_tree(LOGOP_AND);
}
SECTION("`or`") {
REQUIRE_FALSE(fp.parse_string("a=42ory=0"));
REQUIRE_FALSE(fp.parse_string("(a=42)ory=0"));
REQUIRE_FALSE(fp.parse_string("a=42 ory=0"));
REQUIRE(fp.parse_string("a=42or(y=0)"));
verify_tree(LOGOP_OR);
REQUIRE(fp.parse_string("(a=42)or(y=0)"));
verify_tree(LOGOP_OR);
REQUIRE(fp.parse_string("a=42or y=0"));
verify_tree(LOGOP_OR);
}
}
|