1 // Copyright 2011 Google Inc. 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 <string> 40 #include <set> 41 #include <utility> 42 43 #include "utils/fs/path.hpp" 44 #include "utils/optional.ipp" 45 46 47 namespace engine { 48 49 50 /// Filter for test cases. 51 /// 52 /// A filter is one of: the name of a directory containing test cases, the name 53 /// of a test program, or the name of a test program plus the name of a test 54 /// case. 55 class test_filter { 56 public: 57 /// The name of the test program or subdirectory to match. 58 utils::fs::path test_program; 59 60 /// The name of the test case to match; if empty, represents any test case. 61 std::string test_case; 62 63 test_filter(const utils::fs::path&, const std::string&); 64 static test_filter parse(const std::string&); 65 66 std::string str(void) const; 67 68 bool contains(const test_filter&) const; 69 bool matches_test_program(const utils::fs::path&) const; 70 bool matches_test_case(const utils::fs::path&, const std::string&) const; 71 72 bool operator<(const test_filter&) const; 73 bool operator==(const test_filter&) const; 74 bool operator!=(const test_filter&) const; 75 }; 76 77 78 /// Collection of user-provided filters to select test cases. 79 /// 80 /// An empty collection of filters is considered to match any test case. 81 /// 82 /// In general, the filters maintained by this class should be disjoint. If 83 /// they are not, some filters may never have a chance to do a match, which is 84 /// most likely the fault of the user. To check for non-disjoint filters before 85 /// constructing this object, use check_disjoint_filters. 86 class test_filters { 87 /// The user-provided filters. 88 std::set< test_filter > _filters; 89 90 public: 91 explicit test_filters(const std::set< test_filter >&); 92 93 /// Return type of match_test_case. Indicates whether the filters have 94 /// matched a particular test case and, if they have, which filter did the 95 /// match (if any). 96 typedef std::pair< bool, utils::optional< test_filter > > match; 97 98 bool match_test_program(const utils::fs::path&) const; 99 match match_test_case(const utils::fs::path&, const std::string&) const; 100 101 std::set< test_filter > difference(const std::set< test_filter >&) const; 102 }; 103 104 105 void check_disjoint_filters(const std::set< test_filter >&); 106 107 108 /// Tracks state of the filters that have matched tests during execution. 109 class filters_state { 110 /// The user-provided filters. 111 test_filters _filters; 112 113 /// Collection of filters that have matched test cases so far. 114 std::set< test_filter > _used_filters; 115 116 public: 117 explicit filters_state(const std::set< test_filter >&); 118 119 bool match_test_program(const utils::fs::path&) const; 120 bool match_test_case(const utils::fs::path&, const std::string&); 121 122 std::set< test_filter > unused(void) const; 123 }; 124 125 126 } // namespace engine 127 128 #endif // !defined(ENGINE_FILTERS_HPP) 129