1 // Copyright 2011 The Kyua Authors. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above copyright 11 // notice, this list of conditions and the following disclaimer in the 12 // documentation and/or other materials provided with the distribution. 13 // * Neither the name of Google Inc. nor the names of its contributors 14 // may be used to endorse or promote products derived from this software 15 // without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 /// \file engine/filters.hpp 30 /// Representation and manipulation of filters for test cases. 31 /// 32 /// All the filter classes in this module are supposed to be purely functional: 33 /// they are mere filters that decide whether they match or not the input data 34 /// fed to them. User-interface filter manipulation must go somewhere else. 35 36 #if !defined(ENGINE_FILTERS_HPP) 37 #define ENGINE_FILTERS_HPP 38 39 #include "engine/filters_fwd.hpp" 40 41 #include <ostream> 42 #include <string> 43 #include <set> 44 #include <utility> 45 46 #include "utils/fs/path.hpp" 47 #include "utils/optional.ipp" 48 49 50 namespace engine { 51 52 53 /// Filter for test cases. 54 /// 55 /// A filter is one of: the name of a directory containing test cases, the name 56 /// of a test program, or the name of a test program plus the name of a test 57 /// case. 58 class test_filter { 59 public: 60 /// The name of the test program or subdirectory to match. 61 utils::fs::path test_program; 62 63 /// The name of the test case to match; if empty, represents any test case. 64 std::string test_case; 65 66 test_filter(const utils::fs::path&, const std::string&); 67 static test_filter parse(const std::string&); 68 69 std::string str(void) const; 70 71 bool contains(const test_filter&) const; 72 bool matches_test_program(const utils::fs::path&) const; 73 bool matches_test_case(const utils::fs::path&, const std::string&) const; 74 75 bool operator<(const test_filter&) const; 76 bool operator==(const test_filter&) const; 77 bool operator!=(const test_filter&) const; 78 }; 79 80 81 std::ostream& operator<<(std::ostream&, const test_filter&); 82 83 84 /// Collection of user-provided filters to select test cases. 85 /// 86 /// An empty collection of filters is considered to match any test case. 87 /// 88 /// In general, the filters maintained by this class should be disjoint. If 89 /// they are not, some filters may never have a chance to do a match, which is 90 /// most likely the fault of the user. To check for non-disjoint filters before 91 /// constructing this object, use check_disjoint_filters. 92 class test_filters { 93 /// The user-provided filters. 94 std::set< test_filter > _filters; 95 96 public: 97 explicit test_filters(const std::set< test_filter >&); 98 99 /// Return type of match_test_case. Indicates whether the filters have 100 /// matched a particular test case and, if they have, which filter did the 101 /// match (if any). 102 typedef std::pair< bool, utils::optional< test_filter > > match; 103 104 bool match_test_program(const utils::fs::path&) const; 105 match match_test_case(const utils::fs::path&, const std::string&) const; 106 107 std::set< test_filter > difference(const std::set< test_filter >&) const; 108 }; 109 110 111 void check_disjoint_filters(const std::set< test_filter >&); 112 113 114 /// Tracks state of the filters that have matched tests during execution. 115 class filters_state { 116 /// The user-provided filters. 117 test_filters _filters; 118 119 /// Collection of filters that have matched test cases so far. 120 std::set< test_filter > _used_filters; 121 122 public: 123 explicit filters_state(const std::set< test_filter >&); 124 125 bool match_test_program(const utils::fs::path&) const; 126 bool match_test_case(const utils::fs::path&, const std::string&); 127 128 std::set< test_filter > unused(void) const; 129 }; 130 131 132 } // namespace engine 133 134 #endif // !defined(ENGINE_FILTERS_HPP) 135