1 /*
2  *  Created by Phil on 14/8/2012.
3  *  Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
4  *
5  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
6  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  */
8 #ifndef TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
9 #define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
10 
11 #ifdef __clang__
12 #pragma clang diagnostic push
13 #pragma clang diagnostic ignored "-Wpadded"
14 #endif
15 
16 #include "catch_wildcard_pattern.hpp"
17 #include "catch_test_case_info.h"
18 
19 #include <string>
20 #include <vector>
21 
22 namespace Catch {
23 
24     class TestSpec {
25         struct Pattern : SharedImpl<> {
26             virtual ~Pattern();
27             virtual bool matches( TestCaseInfo const& testCase ) const = 0;
28         };
29         class NamePattern : public Pattern {
30         public:
NamePattern(std::string const & name)31             NamePattern( std::string const& name )
32             : m_wildcardPattern( toLower( name ), CaseSensitive::No )
33             {}
34             virtual ~NamePattern();
matches(TestCaseInfo const & testCase) const35             virtual bool matches( TestCaseInfo const& testCase ) const {
36                 return m_wildcardPattern.matches( toLower( testCase.name ) );
37             }
38         private:
39             WildcardPattern m_wildcardPattern;
40         };
41 
42         class TagPattern : public Pattern {
43         public:
TagPattern(std::string const & tag)44             TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
45             virtual ~TagPattern();
matches(TestCaseInfo const & testCase) const46             virtual bool matches( TestCaseInfo const& testCase ) const {
47                 return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();
48             }
49         private:
50             std::string m_tag;
51         };
52 
53         class ExcludedPattern : public Pattern {
54         public:
ExcludedPattern(Ptr<Pattern> const & underlyingPattern)55             ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
56             virtual ~ExcludedPattern();
matches(TestCaseInfo const & testCase) const57             virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
58         private:
59             Ptr<Pattern> m_underlyingPattern;
60         };
61 
62         struct Filter {
63             std::vector<Ptr<Pattern> > m_patterns;
64 
matchesCatch::TestSpec::Filter65             bool matches( TestCaseInfo const& testCase ) const {
66                 // All patterns in a filter must match for the filter to be a match
67                 for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) {
68                     if( !(*it)->matches( testCase ) )
69                         return false;
70                 }
71                 return true;
72             }
73         };
74 
75     public:
hasFilters() const76         bool hasFilters() const {
77             return !m_filters.empty();
78         }
matches(TestCaseInfo const & testCase) const79         bool matches( TestCaseInfo const& testCase ) const {
80             // A TestSpec matches if any filter matches
81             for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )
82                 if( it->matches( testCase ) )
83                     return true;
84             return false;
85         }
86 
87     private:
88         std::vector<Filter> m_filters;
89 
90         friend class TestSpecParser;
91     };
92 }
93 
94 #ifdef __clang__
95 #pragma clang diagnostic pop
96 #endif
97 
98 #endif // TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
99