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 47namespace 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. 55class test_filter { 56public: 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. 86class test_filters { 87 /// The user-provided filters. 88 std::set< test_filter > _filters; 89 90public: 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 105void check_disjoint_filters(const std::set< test_filter >&); 106 107 108/// Tracks state of the filters that have matched tests during execution. 109class 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 116public: 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