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