2012-08-14 20:35:30 +02:00
|
|
|
/*
|
|
|
|
* Created by Phil on 14/8/2012.
|
|
|
|
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
|
|
|
|
*
|
|
|
|
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
|
|
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
*/
|
2012-09-17 07:42:29 +02:00
|
|
|
#ifndef TWOBLUECUBES_CATCH_TEST_SPEC_H_INCLUDED
|
|
|
|
#define TWOBLUECUBES_CATCH_TEST_SPEC_H_INCLUDED
|
2012-08-14 20:35:30 +02:00
|
|
|
|
2012-08-28 09:20:18 +02:00
|
|
|
#include "catch_test_case_info.h"
|
2012-09-26 19:38:26 +02:00
|
|
|
#include "catch_tags.hpp"
|
2013-03-12 19:47:53 +01:00
|
|
|
#include "catch_common.h"
|
2012-08-28 09:20:18 +02:00
|
|
|
|
2012-08-14 20:35:30 +02:00
|
|
|
#include <string>
|
2012-08-28 09:20:18 +02:00
|
|
|
#include <vector>
|
2012-08-14 20:35:30 +02:00
|
|
|
|
|
|
|
namespace Catch {
|
2013-07-03 20:14:59 +02:00
|
|
|
|
2012-08-23 21:08:50 +02:00
|
|
|
struct IfFilterMatches{ enum DoWhat {
|
2012-09-07 18:52:15 +02:00
|
|
|
AutoDetectBehaviour,
|
2012-08-23 21:08:50 +02:00
|
|
|
IncludeTests,
|
|
|
|
ExcludeTests
|
|
|
|
}; };
|
2012-08-14 20:35:30 +02:00
|
|
|
|
2012-08-23 21:08:50 +02:00
|
|
|
class TestCaseFilter {
|
2012-08-24 09:23:50 +02:00
|
|
|
enum WildcardPosition {
|
|
|
|
NoWildcard = 0,
|
|
|
|
WildcardAtStart = 1,
|
|
|
|
WildcardAtEnd = 2,
|
|
|
|
WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
|
|
|
|
};
|
2013-03-25 09:46:48 +01:00
|
|
|
|
2012-08-14 20:35:30 +02:00
|
|
|
public:
|
2013-04-23 19:58:56 +02:00
|
|
|
TestCaseFilter( std::string const& testSpec, IfFilterMatches::DoWhat matchBehaviour = IfFilterMatches::AutoDetectBehaviour )
|
2013-03-22 20:00:42 +01:00
|
|
|
: m_stringToMatch( toLower( testSpec ) ),
|
2012-08-23 21:08:50 +02:00
|
|
|
m_filterType( matchBehaviour ),
|
2012-08-24 09:23:50 +02:00
|
|
|
m_wildcardPosition( NoWildcard )
|
2012-08-23 21:08:50 +02:00
|
|
|
{
|
2012-09-07 18:52:15 +02:00
|
|
|
if( m_filterType == IfFilterMatches::AutoDetectBehaviour ) {
|
|
|
|
if( startsWith( m_stringToMatch, "exclude:" ) ) {
|
|
|
|
m_stringToMatch = m_stringToMatch.substr( 8 );
|
|
|
|
m_filterType = IfFilterMatches::ExcludeTests;
|
|
|
|
}
|
|
|
|
else if( startsWith( m_stringToMatch, "~" ) ) {
|
|
|
|
m_stringToMatch = m_stringToMatch.substr( 1 );
|
|
|
|
m_filterType = IfFilterMatches::ExcludeTests;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
m_filterType = IfFilterMatches::IncludeTests;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-21 09:58:22 +01:00
|
|
|
if( startsWith( m_stringToMatch, "*" ) ) {
|
2012-08-24 09:23:50 +02:00
|
|
|
m_stringToMatch = m_stringToMatch.substr( 1 );
|
2013-07-12 14:41:41 +02:00
|
|
|
m_wildcardPosition = static_cast<WildcardPosition>( m_wildcardPosition | WildcardAtStart );
|
2012-08-24 09:23:50 +02:00
|
|
|
}
|
2013-03-21 09:58:22 +01:00
|
|
|
if( endsWith( m_stringToMatch, "*" ) ) {
|
2012-08-24 09:23:50 +02:00
|
|
|
m_stringToMatch = m_stringToMatch.substr( 0, m_stringToMatch.size()-1 );
|
2013-07-12 14:41:41 +02:00
|
|
|
m_wildcardPosition = static_cast<WildcardPosition>( m_wildcardPosition | WildcardAtEnd );
|
2012-08-14 20:35:30 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-23 21:08:50 +02:00
|
|
|
IfFilterMatches::DoWhat getFilterType() const {
|
|
|
|
return m_filterType;
|
|
|
|
}
|
2013-07-03 20:14:59 +02:00
|
|
|
|
2013-04-23 19:58:56 +02:00
|
|
|
bool shouldInclude( TestCase const& testCase ) const {
|
2012-08-23 21:08:50 +02:00
|
|
|
return isMatch( testCase ) == (m_filterType == IfFilterMatches::IncludeTests);
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
|
2012-08-27 22:48:15 +02:00
|
|
|
#ifdef __clang__
|
|
|
|
#pragma clang diagnostic push
|
|
|
|
#pragma clang diagnostic ignored "-Wunreachable-code"
|
|
|
|
#endif
|
|
|
|
|
2013-04-23 19:58:56 +02:00
|
|
|
bool isMatch( TestCase const& testCase ) const {
|
2013-03-12 19:47:53 +01:00
|
|
|
std::string name = testCase.getTestCaseInfo().name;
|
2013-03-22 20:00:42 +01:00
|
|
|
toLowerInPlace( name );
|
2012-08-24 09:23:50 +02:00
|
|
|
|
|
|
|
switch( m_wildcardPosition ) {
|
|
|
|
case NoWildcard:
|
|
|
|
return m_stringToMatch == name;
|
|
|
|
case WildcardAtStart:
|
|
|
|
return endsWith( name, m_stringToMatch );
|
|
|
|
case WildcardAtEnd:
|
|
|
|
return startsWith( name, m_stringToMatch );
|
|
|
|
case WildcardAtBothEnds:
|
|
|
|
return contains( name, m_stringToMatch );
|
|
|
|
}
|
2012-08-27 22:48:15 +02:00
|
|
|
throw std::logic_error( "Unhandled wildcard type" );
|
2012-08-14 20:35:30 +02:00
|
|
|
}
|
|
|
|
|
2012-08-27 22:48:15 +02:00
|
|
|
#ifdef __clang__
|
|
|
|
#pragma clang diagnostic pop
|
|
|
|
#endif
|
|
|
|
|
2012-08-24 09:23:50 +02:00
|
|
|
std::string m_stringToMatch;
|
2012-08-23 21:08:50 +02:00
|
|
|
IfFilterMatches::DoWhat m_filterType;
|
2012-08-24 09:23:50 +02:00
|
|
|
WildcardPosition m_wildcardPosition;
|
2012-08-14 20:35:30 +02:00
|
|
|
};
|
2012-08-23 21:08:50 +02:00
|
|
|
|
|
|
|
class TestCaseFilters {
|
|
|
|
public:
|
2013-04-23 19:58:56 +02:00
|
|
|
TestCaseFilters( std::string const& name ) : m_name( name ) {}
|
2012-08-23 21:08:50 +02:00
|
|
|
|
|
|
|
std::string getName() const {
|
|
|
|
return m_name;
|
|
|
|
}
|
2013-07-03 20:14:59 +02:00
|
|
|
|
2013-04-23 19:58:56 +02:00
|
|
|
void addFilter( TestCaseFilter const& filter ) {
|
2012-08-23 21:08:50 +02:00
|
|
|
if( filter.getFilterType() == IfFilterMatches::ExcludeTests )
|
|
|
|
m_exclusionFilters.push_back( filter );
|
|
|
|
else
|
|
|
|
m_inclusionFilters.push_back( filter );
|
|
|
|
}
|
|
|
|
|
2013-04-23 19:58:56 +02:00
|
|
|
void addTags( std::string const& tagPattern ) {
|
2012-09-26 19:38:26 +02:00
|
|
|
TagExpression exp;
|
|
|
|
TagExpressionParser( exp ).parse( tagPattern );
|
|
|
|
|
|
|
|
m_tagExpressions.push_back( exp );
|
|
|
|
}
|
|
|
|
|
2013-04-23 19:58:56 +02:00
|
|
|
bool shouldInclude( TestCase const& testCase ) const {
|
2012-09-26 19:38:26 +02:00
|
|
|
if( !m_tagExpressions.empty() ) {
|
|
|
|
std::vector<TagExpression>::const_iterator it = m_tagExpressions.begin();
|
|
|
|
std::vector<TagExpression>::const_iterator itEnd = m_tagExpressions.end();
|
|
|
|
for(; it != itEnd; ++it )
|
|
|
|
if( it->matches( testCase.getTags() ) )
|
|
|
|
break;
|
|
|
|
if( it == itEnd )
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-08-23 21:08:50 +02:00
|
|
|
if( !m_inclusionFilters.empty() ) {
|
|
|
|
std::vector<TestCaseFilter>::const_iterator it = m_inclusionFilters.begin();
|
|
|
|
std::vector<TestCaseFilter>::const_iterator itEnd = m_inclusionFilters.end();
|
|
|
|
for(; it != itEnd; ++it )
|
|
|
|
if( it->shouldInclude( testCase ) )
|
|
|
|
break;
|
|
|
|
if( it == itEnd )
|
|
|
|
return false;
|
|
|
|
}
|
2012-09-26 19:38:26 +02:00
|
|
|
else if( m_exclusionFilters.empty() && m_tagExpressions.empty() ) {
|
2012-09-15 18:53:27 +02:00
|
|
|
return !testCase.isHidden();
|
|
|
|
}
|
2013-07-03 20:14:59 +02:00
|
|
|
|
2012-08-23 21:08:50 +02:00
|
|
|
std::vector<TestCaseFilter>::const_iterator it = m_exclusionFilters.begin();
|
|
|
|
std::vector<TestCaseFilter>::const_iterator itEnd = m_exclusionFilters.end();
|
|
|
|
for(; it != itEnd; ++it )
|
|
|
|
if( !it->shouldInclude( testCase ) )
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
private:
|
2012-09-26 19:38:26 +02:00
|
|
|
std::vector<TagExpression> m_tagExpressions;
|
2012-08-23 21:08:50 +02:00
|
|
|
std::vector<TestCaseFilter> m_inclusionFilters;
|
|
|
|
std::vector<TestCaseFilter> m_exclusionFilters;
|
|
|
|
std::string m_name;
|
|
|
|
};
|
|
|
|
|
2012-08-14 20:35:30 +02:00
|
|
|
}
|
|
|
|
|
2012-09-17 07:42:29 +02:00
|
|
|
#endif // TWOBLUECUBES_CATCH_TEST_SPEC_H_INCLUDED
|