reapack

Package manager for REAPER
Log | Files | Refs | Submodules | README | LICENSE

filter.cpp (8183B)


      1 #include "helper.hpp"
      2 
      3 #include <filter.hpp>
      4 
      5 static const char *M = "[filter]";
      6 
      7 TEST_CASE("basic matching", M) {
      8   Filter f;
      9   REQUIRE(f.match({}));
     10   REQUIRE(f.match({"world"}));
     11 
     12   f.set("hello");
     13   REQUIRE(f.match({"hello"}));
     14   REQUIRE(f.match({"HELLO"}));
     15   REQUIRE_FALSE(f.match({"world"}));
     16 }
     17 
     18 TEST_CASE("word matching", M) {
     19   Filter f;
     20   f.set("hello world");
     21 
     22   REQUIRE_FALSE(f.match({"hello"}));
     23   REQUIRE(f.match({"hello world"}));
     24   REQUIRE(f.match({"helloworld"}));
     25   REQUIRE(f.match({"hello test world"}));
     26 }
     27 
     28 TEST_CASE("quote phrase matching", M) {
     29   Filter f;
     30 
     31   SECTION("double quotes")
     32     f.set("\"foo bar\" baz");
     33   SECTION("single quotes")
     34     f.set("'foo bar' baz");
     35 
     36   REQUIRE(f.match({"baz foo bar"}));
     37   REQUIRE(f.match({"BEFOREfoo barAFTER baz"}));
     38   REQUIRE_FALSE(f.match({"foobarbaz"}));
     39   REQUIRE_FALSE(f.match({"foo test bar baz"}));
     40 }
     41 
     42 TEST_CASE("full word matching", M) {
     43   Filter f;
     44 
     45   SECTION("double quotes")
     46     f.set("\"hello\" world");
     47   SECTION("single quotes")
     48     f.set("'hello' world");
     49 
     50   REQUIRE(f.match({"BEFORE hello AFTER world"}));
     51   REQUIRE(f.match({"_hello_ world"}));
     52   REQUIRE_FALSE(f.match({"BEFOREhello world"}));
     53   REQUIRE_FALSE(f.match({"helloAFTER world"}));
     54   REQUIRE_FALSE(f.match({"BEFOREhelloAFTER world"}));
     55 }
     56 
     57 TEST_CASE("late opening quote", M) {
     58   Filter f;
     59   f.set("foo'bar'");
     60 
     61   REQUIRE(f.match({"foo'bar'"}));
     62   REQUIRE_FALSE(f.match({"foo bar"}));
     63 }
     64 
     65 TEST_CASE("early closing quote", M) {
     66   Filter f;
     67   f.set("'foo'bar");
     68 
     69   REQUIRE(f.match({"foo bar"}));
     70   REQUIRE_FALSE(f.match({"foobar"}));
     71   REQUIRE_FALSE(f.match({"foo ar"}));
     72 }
     73 
     74 TEST_CASE("mixing quotes", M) {
     75   Filter f;
     76 
     77   SECTION("double in single") {
     78     f.set("'hello \"world\"'");
     79 
     80     REQUIRE(f.match({"hello \"world\""}));
     81     REQUIRE_FALSE(f.match({"hello world"}));
     82   }
     83 
     84   SECTION("single in double") {
     85     f.set("\"hello 'world'\"");
     86 
     87     REQUIRE(f.match({"hello 'world'"}));
     88     REQUIRE_FALSE(f.match({"hello world"}));
     89   }
     90 }
     91 
     92 TEST_CASE("start of string", M) {
     93   Filter f;
     94 
     95   SECTION("normal") {
     96     f.set("^hello");
     97 
     98     REQUIRE(f.match({"hello world"}));
     99     REQUIRE_FALSE(f.match({"puts 'hello world'"}));
    100   }
    101 
    102   SECTION("middle") {
    103     f.set("hel^lo");
    104 
    105     REQUIRE(f.match({"hel^lo world"}));
    106     REQUIRE_FALSE(f.match({"hello world"}));
    107   }
    108 
    109   SECTION("single") {
    110     f.set("^");
    111     REQUIRE(f.match({"hello world"}));
    112   }
    113 
    114   SECTION("literal ^") {
    115     f.set("'^hello'");
    116     REQUIRE(f.match({"^hello world"}));
    117     REQUIRE_FALSE(f.match({"world hello"}));
    118   }
    119 
    120   SECTION("full word") {
    121     f.set("^'hello");
    122     REQUIRE(f.match({"hello world"}));
    123     REQUIRE_FALSE(f.match({"world hello"}));
    124   }
    125 }
    126 
    127 TEST_CASE("end of string", M) {
    128   Filter f;
    129 
    130   SECTION("normal") {
    131     f.set("world$");
    132 
    133     REQUIRE(f.match({"hello world"}));
    134     REQUIRE_FALSE(f.match({"'hello world'.upcase"}));
    135   }
    136 
    137   SECTION("middle") {
    138     f.set("hel$lo");
    139 
    140     REQUIRE(f.match({"hel$lo world"}));
    141     REQUIRE_FALSE(f.match({"hello world"}));
    142   }
    143 
    144   SECTION("single") {
    145     f.set("$");
    146     REQUIRE(f.match({"hello world"}));
    147   }
    148 
    149   SECTION("full word") {
    150     f.set("'hello'$");
    151     REQUIRE(f.match({"hello"}));
    152     REQUIRE_FALSE(f.match({"hello world"}));
    153   }
    154 
    155   SECTION("literal $") {
    156     f.set("'hello$'");
    157     REQUIRE(f.match({"hello$"}));
    158     REQUIRE_FALSE(f.match({"hello world"}));
    159   }
    160 }
    161 
    162 TEST_CASE("both anchors", M) {
    163   Filter f;
    164   f.set("^word$");
    165 
    166   REQUIRE(f.match({"word"}));
    167   REQUIRE_FALSE(f.match({"word after"}));
    168   REQUIRE_FALSE(f.match({"before word"}));
    169 }
    170 
    171 TEST_CASE("row matching", M) {
    172   Filter f;
    173   f.set("hello world");
    174 
    175   REQUIRE_FALSE(f.match({"hello"}));
    176   REQUIRE(f.match({"hello", "world"}));
    177   REQUIRE(f.match({"hello", "test", "world"}));
    178 }
    179 
    180 TEST_CASE("OR operator", M) {
    181   Filter f;
    182 
    183   SECTION("normal") {
    184     f.set("hello OR bacon");
    185 
    186     REQUIRE(f.match({"hello world"}));
    187     REQUIRE(f.match({"chunky bacon"}));
    188     REQUIRE_FALSE(f.match({"not matching"}));
    189     REQUIRE_FALSE(f.match({"OR"}));
    190   }
    191 
    192   SECTION("anchor") {
    193     f.set("world OR ^bacon");
    194 
    195     REQUIRE(f.match({"hello world"}));
    196     REQUIRE_FALSE(f.match({"chunky bacon"}));
    197     REQUIRE(f.match({"bacon"}));
    198   }
    199 
    200   SECTION("reset") {
    201     f.set("hello OR bacon world");
    202 
    203     REQUIRE_FALSE(f.match({"world"}));
    204     REQUIRE(f.match({"hello world"}));
    205     REQUIRE(f.match({"bacon world"}));
    206   }
    207 
    208   SECTION("single") {
    209     f.set("OR");
    210     REQUIRE(f.match({"anything"}));
    211   }
    212 
    213   SECTION("literal OR") {
    214     f.set("'OR'");
    215     REQUIRE(f.match({"OR"}));
    216     REQUIRE_FALSE(f.match({"foo"}));
    217   }
    218 }
    219 
    220 TEST_CASE("NOT operator", M) {
    221   Filter f;
    222 
    223   SECTION("normal") {
    224     f.set("hello NOT bacon");
    225 
    226     REQUIRE(f.match({"hello world"}));
    227     REQUIRE_FALSE(f.match({"chunky bacon"}));
    228     REQUIRE_FALSE(f.match({"hello NOT bacon"}));
    229   }
    230 
    231   SECTION("row matching") {
    232     f.set("NOT bacon");
    233 
    234     REQUIRE_FALSE(f.match({"hello", "bacon", "world"}));
    235     REQUIRE(f.match({"hello", "world"}));
    236   }
    237 
    238   SECTION("preceded by OR") {
    239     f.set("hello OR NOT bacon");
    240     REQUIRE(f.match({"hello bacon"}));
    241     REQUIRE(f.match({"hello", "bacon"}));
    242   }
    243 
    244   SECTION("followed by OR") {
    245     f.set("NOT bacon OR hello");
    246     REQUIRE(f.match({"hello bacon"}));
    247     REQUIRE(f.match({"hello", "bacon"}));
    248   }
    249 
    250   SECTION("full word matching") {
    251     f.set("NOT 'hello'");
    252     REQUIRE(f.match({"hellobacon"}));
    253   }
    254 
    255   SECTION("NOT NOT") {
    256     f.set("NOT NOT hello");
    257     REQUIRE(f.match({"hello"}));
    258     REQUIRE_FALSE(f.match({"world"}));
    259   }
    260 
    261   SECTION("literal NOT") {
    262     f.set("'NOT'");
    263     REQUIRE(f.match({"NOT"}));
    264     REQUIRE_FALSE(f.match({"foo"}));
    265   }
    266 }
    267 
    268 TEST_CASE("AND grouping", M) {
    269   Filter f;
    270 
    271   SECTION("normal") {
    272     f.set("( hello world ) OR ( NOT hello bacon )");
    273 
    274     REQUIRE(f.match({"hello world"}));
    275     REQUIRE(f.match({"chunky bacon"}));
    276     REQUIRE_FALSE(f.match({"hello chunky bacon"}));
    277   }
    278 
    279   SECTION("close without opening") {
    280     f.set(") test");
    281   }
    282 
    283   SECTION("NOT + AND grouping") {
    284     f.set("NOT ( apple orange ) bacon");
    285 
    286     REQUIRE(f.match({"bacon"}));
    287     REQUIRE(f.match({"apple bacon"}));
    288     REQUIRE(f.match({"orange bacon"}));
    289     REQUIRE_FALSE(f.match({"apple bacon orange"}));
    290   }
    291 
    292   SECTION("NOT + AND + OR grouping") {
    293     f.set("NOT ( apple OR orange ) OR bacon");
    294 
    295     REQUIRE_FALSE(f.match({"apple"}));
    296     REQUIRE_FALSE(f.match({"orange"}));
    297     REQUIRE(f.match({"test"}));
    298     REQUIRE(f.match({"apple bacon"}));
    299     REQUIRE(f.match({"bacon"}));
    300   }
    301 
    302   SECTION("nested groups") {
    303     f.set("NOT ( ( apple OR orange ) OR bacon )");
    304 
    305     REQUIRE_FALSE(f.match({"apple"}));
    306     REQUIRE_FALSE(f.match({"orange"}));
    307     REQUIRE(f.match({"test"}));
    308     REQUIRE_FALSE(f.match({"apple bacon"}));
    309     REQUIRE_FALSE(f.match({"bacon"}));
    310   }
    311 
    312   SECTION("literal parentheses") {
    313     f.set("'('");
    314     REQUIRE(f.match({"("}));
    315     REQUIRE_FALSE(f.match({"foo"}));
    316   }
    317 
    318   SECTION("closing a subgroup rewinds to the AND parent") {
    319     f.set("a OR ( b ) c");
    320 
    321     REQUIRE_FALSE(f.match({"c"}));
    322     REQUIRE(f.match({"a c"}));
    323     REQUIRE(f.match({"b c"}));
    324   }
    325 
    326   SECTION("closing a subgroup doesn't rewind too far") {
    327     f.set("NOT ( a OR ( b ) c ) OR d");
    328 
    329     REQUIRE_FALSE(f.match({"a c"}));
    330     REQUIRE(f.match({"a z"}));
    331     REQUIRE(f.match({"d"}));
    332   }
    333 }
    334 
    335 TEST_CASE("synonymous words", M) {
    336   Filter f;
    337 
    338   SECTION("basic") {
    339     f.set("open");
    340     REQUIRE(f.match({"open"}));
    341     REQUIRE(f.match({"display"}));
    342     REQUIRE_FALSE(f.match({"door"}));
    343   }
    344 
    345   SECTION("case-insensitive") {
    346     f.set("OPEN");
    347     REQUIRE(f.match({"opening"}));
    348     REQUIRE(f.match({"display"}));
    349   }
    350 
    351   SECTION("full-word synonyms") {
    352     f.set("unselect");
    353     REQUIRE(f.match({"unselect"}));
    354     REQUIRE(f.match({"unselected"}));
    355     REQUIRE(f.match({"deselect"}));
    356     REQUIRE_FALSE(f.match({"deselected"}));
    357   }
    358 
    359   SECTION("preserve anchor flags") {
    360     f.set("^insert");
    361     REQUIRE(f.match({"add"}));
    362     REQUIRE_FALSE(f.match({"don't add"}));
    363     REQUIRE_FALSE(f.match({"not inserting things"}));
    364   }
    365 
    366   SECTION("NOT applies to all synonyms") {
    367     f.set("NOT open");
    368     REQUIRE(f.match({"foo bar"}));
    369     REQUIRE_FALSE(f.match({"open display"}));
    370   }
    371 
    372   SECTION("clear flags for the next token") {
    373     f.set("^open bar");
    374     REQUIRE(f.match({"open bar"}));
    375   }
    376 }