aboutsummaryrefslogtreecommitdiff
path: root/filter_test.cc
blob: 2be2bcc8854e74bf63030ff76356a47beb82e2d1 (plain)
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
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// -*- mode: C++ -*-
//
// Copyright 2022 Google LLC
//
// Licensed under the Apache License v2.0 with LLVM Exceptions (the
// "License"); you may not use this file except in compliance with the
// License.  You may obtain a copy of the License at
//
//     https://llvm.org/LICENSE.txt
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: Giuliano Procida

#include "filter.h"

#include <string>
#include <tuple>
#include <vector>

#include <catch2/catch.hpp>

namespace Test {

TEST_CASE("bad syntax cases") {
  const std::vector<std::string> cases = {
    "",
    "\x1B",
    ":",
    "a:",
    "!",
    "a!",
    "(a",
    "(",
    ")",
    "()",
    "(a))",
    "&",
    "&a",
    "a&",
    "|",
    "|a",
    "|&",
    "a||b",
    "a&&b",
  };

  for (const auto& expression : cases) {
    GIVEN("filter: " + expression) {
      CHECK_THROWS(stg::MakeFilter(expression));
    }
  }
}

TEST_CASE("hand-curated cases") {
  const std::string testdata = "testdata";
  const std::vector<
      std::tuple<std::string,
                 std::vector<std::string>,
                 std::vector<std::string>>> cases = {
    {"a",           {"a"}, {"b"}},
    {"! a",         {"b"}, {"a"}},
    {"a | b",       {"a", "b"}, {"c"}},
    {"a & b",       {}, {"a", "b", "c"}},
    {"! a | b",     {"b", "c"}, {"a"}},
    {"! a & b",     {"b"}, {"a", "c"}},
    {" a | ! b",    {"a", "c"}, {"b"}},
    {" a & ! b",    {"a"}, {"b", "c"}},
    {"! a | ! b",   {"a", "b", "c"}, {}},
    {"! a & ! b",   {"c"}, {"a", "b"}},
    {"!(a | b)",    {"c"}, {"a", "b"}},
    {"!(a & b)",    {"a", "b", "c"}, {}},
    {"a & b | c",   {"c"}, {"a", "b"}},
    {"a | b & c",   {"a"}, {"b", "c"}},
    {"!a & b | c",  {"b", "c"}, {"a"}},
    {"!a | b & c",  {"b", "c"}, {"a"}},
    {"a & !b | c",  {"a", "c"}, {"b"}},
    {"a | !b & c",  {"a", "c"}, {"b"}},
    {"a & b | !c",  {"a", "b"}, {"c"}},
    {"a | b & !c",  {"a", "b"}, {"c"}},
    {"!*",          {}, {"", "a", "ab"}},
    {"*",           {"", "a", "ab"}, {}},
    {"a*",          {"a", "ab", "abc"}, {"", "b", "ba"}},
    {"a?",          {"aa", "ab"}, {"", "a", "aaa"}},
    {"*c",          {"c", "ac", "abc"}, {"", "a", "ca"}},
    {"?c",          {"ac"}, {"", "c", "ca", "abc"}},
    {"!(a)",        {"b"}, {"a"}},
    {"!(!(a))",     {"a"}, {"b"}},
    {"!(!(!(a)))",  {"b"}, {"a"}},
    {"!a",          {"b"}, {"a"}},
    {"!!a",         {"a"}, {"b"}},
    {"!!!a",        {"b"}, {"a"}},
    {":/dev/null",  {}, {"", "a"}},
    {"!:/dev/null", {"", "a"}, {}},
    {":" + testdata + "/symbol_list", {"one"}, {"#", "bad"}},
    {"!:" + testdata + "/symbol_list", {"", " "}, {"two"}},
  };

  for (const auto& [expression, ins, outs] : cases) {
    GIVEN("filter: " + expression) {
      auto filter = stg::MakeFilter(expression);
      for (const auto& in : ins) {
        GIVEN("in: " + in) {
          CHECK((*filter)(in));
        }
      }
      for (const auto& out : outs) {
        GIVEN("out: " + out) {
          CHECK(!(*filter)(out));
        }
      }
    }
  }
}

}  // namespace Test