• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- mode: C++ -*-
3 //
4 // Copyright 2022 Google LLC
5 //
6 // Licensed under the Apache License v2.0 with LLVM Exceptions (the
7 // "License"); you may not use this file except in compliance with the
8 // License.  You may obtain a copy of the License at
9 //
10 //     https://llvm.org/LICENSE.txt
11 //
12 // Unless required by applicable law or agreed to in writing, software
13 // distributed under the License is distributed on an "AS IS" BASIS,
14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 // See the License for the specific language governing permissions and
16 // limitations under the License.
17 //
18 // Author: Giuliano Procida
19 
20 #include "filter.h"
21 
22 #include <string>
23 #include <tuple>
24 #include <vector>
25 
26 #include <catch2/catch.hpp>
27 
28 namespace Test {
29 
30 TEST_CASE("bad syntax cases") {
31   const std::vector<std::string> cases = {
32     "",
33     "\x1B",
34     ":",
35     "a:",
36     "!",
37     "a!",
38     "(a",
39     "(",
40     ")",
41     "()",
42     "(a))",
43     "&",
44     "&a",
45     "a&",
46     "|",
47     "|a",
48     "|&",
49     "a||b",
50     "a&&b",
51   };
52 
53   for (const auto& expression : cases) {
54     GIVEN("filter: " + expression) {
55       CHECK_THROWS(stg::MakeFilter(expression));
56     }
57   }
58 }
59 
60 TEST_CASE("hand-curated cases") {
61   const std::string testdata = "testdata";
62   const std::vector<
63       std::tuple<std::string,
64                  std::vector<std::string>,
65                  std::vector<std::string>>> cases = {
66     {"a",           {"a"}, {"b"}},
67     {"! a",         {"b"}, {"a"}},
68     {"a | b",       {"a", "b"}, {"c"}},
69     {"a & b",       {}, {"a", "b", "c"}},
70     {"! a | b",     {"b", "c"}, {"a"}},
71     {"! a & b",     {"b"}, {"a", "c"}},
72     {" a | ! b",    {"a", "c"}, {"b"}},
73     {" a & ! b",    {"a"}, {"b", "c"}},
74     {"! a | ! b",   {"a", "b", "c"}, {}},
75     {"! a & ! b",   {"c"}, {"a", "b"}},
76     {"!(a | b)",    {"c"}, {"a", "b"}},
77     {"!(a & b)",    {"a", "b", "c"}, {}},
78     {"a & b | c",   {"c"}, {"a", "b"}},
79     {"a | b & c",   {"a"}, {"b", "c"}},
80     {"!a & b | c",  {"b", "c"}, {"a"}},
81     {"!a | b & c",  {"b", "c"}, {"a"}},
82     {"a & !b | c",  {"a", "c"}, {"b"}},
83     {"a | !b & c",  {"a", "c"}, {"b"}},
84     {"a & b | !c",  {"a", "b"}, {"c"}},
85     {"a | b & !c",  {"a", "b"}, {"c"}},
86     {"!*",          {}, {"", "a", "ab"}},
87     {"*",           {"", "a", "ab"}, {}},
88     {"a*",          {"a", "ab", "abc"}, {"", "b", "ba"}},
89     {"a?",          {"aa", "ab"}, {"", "a", "aaa"}},
90     {"*c",          {"c", "ac", "abc"}, {"", "a", "ca"}},
91     {"?c",          {"ac"}, {"", "c", "ca", "abc"}},
92     {"!(a)",        {"b"}, {"a"}},
93     {"!(!(a))",     {"a"}, {"b"}},
94     {"!(!(!(a)))",  {"b"}, {"a"}},
95     {"!a",          {"b"}, {"a"}},
96     {"!!a",         {"a"}, {"b"}},
97     {"!!!a",        {"b"}, {"a"}},
98     {":/dev/null",  {}, {"", "a"}},
99     {"!:/dev/null", {"", "a"}, {}},
100     {":" + testdata + "/symbol_list", {"one"}, {"#", "bad"}},
101     {"!:" + testdata + "/symbol_list", {"", " "}, {"two"}},
102   };
103 
104   for (const auto& [expression, ins, outs] : cases) {
105     GIVEN("filter: " + expression) {
106       auto filter = stg::MakeFilter(expression);
107       for (const auto& in : ins) {
108         GIVEN("in: " + in) {
109           CHECK((*filter)(in));
110         }
111       }
112       for (const auto& out : outs) {
113         GIVEN("out: " + out) {
114           CHECK(!(*filter)(out));
115         }
116       }
117     }
118   }
119 }
120 
121 }  // namespace Test
122