mirror of
https://github.com/catchorg/Catch2.git
synced 2025-08-01 12:55:40 +02:00
Switched over to new name/ tag parser
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
#ifndef TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
|
||||
|
||||
#include "catch_test_spec.h"
|
||||
#include "catch_test_spec_parser.hpp"
|
||||
#include "catch_context.h"
|
||||
#include "catch_interfaces_config.h"
|
||||
#include "catch_stream.h"
|
||||
@@ -84,21 +84,10 @@ namespace Catch {
|
||||
m_os( std::cout.rdbuf() )
|
||||
{
|
||||
if( !data.testsOrTags.empty() ) {
|
||||
std::string groupName;
|
||||
for( std::size_t i = 0; i < data.testsOrTags.size(); ++i ) {
|
||||
if( i != 0 )
|
||||
groupName += " ";
|
||||
groupName += data.testsOrTags[i];
|
||||
}
|
||||
TestCaseFilters filters( groupName );
|
||||
for( std::size_t i = 0; i < data.testsOrTags.size(); ++i ) {
|
||||
std::string filter = data.testsOrTags[i];
|
||||
if( startsWith( filter, "[" ) || startsWith( filter, "~[" ) )
|
||||
filters.addTags( filter );
|
||||
else
|
||||
filters.addFilter( TestCaseFilter( filter ) );
|
||||
}
|
||||
m_filterSets.push_back( filters );
|
||||
TestSpecParser parser;
|
||||
for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
|
||||
parser.parse( data.testsOrTags[i] );
|
||||
m_testSpec = parser.testSpec();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,13 +109,9 @@ namespace Catch {
|
||||
bool listTags() const { return m_data.listTags; }
|
||||
bool listReporters() const { return m_data.listReporters; }
|
||||
|
||||
std::string getProcessName() const {
|
||||
return m_data.processName;
|
||||
}
|
||||
std::string getProcessName() const { return m_data.processName; }
|
||||
|
||||
bool shouldDebugBreak() const {
|
||||
return m_data.shouldDebugBreak;
|
||||
}
|
||||
bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
|
||||
|
||||
void setStreamBuf( std::streambuf* buf ) {
|
||||
m_os.rdbuf( buf ? buf : std::cout.rdbuf() );
|
||||
@@ -141,19 +126,10 @@ namespace Catch {
|
||||
|
||||
std::string getReporterName() const { return m_data.reporterName; }
|
||||
|
||||
void addTestSpec( std::string const& testSpec ) {
|
||||
TestCaseFilters filters( testSpec );
|
||||
filters.addFilter( TestCaseFilter( testSpec ) );
|
||||
m_filterSets.push_back( filters );
|
||||
}
|
||||
|
||||
int abortAfter() const {
|
||||
return m_data.abortAfter;
|
||||
}
|
||||
int abortAfter() const { return m_data.abortAfter; }
|
||||
|
||||
std::vector<TestCaseFilters> const& filters() const {
|
||||
return m_filterSets;
|
||||
}
|
||||
TestSpec const& testSpec() const { return m_testSpec; }
|
||||
|
||||
bool showHelp() const { return m_data.showHelp; }
|
||||
bool showInvisibles() const { return m_data.showInvisibles; }
|
||||
@@ -172,7 +148,7 @@ namespace Catch {
|
||||
|
||||
Stream m_stream;
|
||||
mutable std::ostream m_os;
|
||||
std::vector<TestCaseFilters> m_filterSets;
|
||||
TestSpec m_testSpec;
|
||||
};
|
||||
|
||||
|
||||
|
@@ -33,7 +33,7 @@ namespace Catch {
|
||||
Never
|
||||
}; };
|
||||
|
||||
class TestCaseFilters;
|
||||
class TestSpec;
|
||||
|
||||
struct IConfig : IShared {
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace Catch {
|
||||
virtual int abortAfter() const = 0;
|
||||
virtual bool showInvisibles() const = 0;
|
||||
virtual ShowDurations::OrNot showDurations() const = 0;
|
||||
virtual std::vector<TestCaseFilters> const& filters() const = 0;
|
||||
virtual TestSpec const& testSpec() const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -14,7 +14,7 @@
|
||||
|
||||
namespace Catch {
|
||||
|
||||
class TestCaseFilters;
|
||||
class TestSpec;
|
||||
|
||||
struct ITestCase : IShared {
|
||||
virtual void invoke () const = 0;
|
||||
@@ -28,8 +28,7 @@ namespace Catch {
|
||||
struct ITestCaseRegistry {
|
||||
virtual ~ITestCaseRegistry();
|
||||
virtual std::vector<TestCase> const& getAllTests() const = 0;
|
||||
virtual void getFilteredTests( TestCaseFilters const& filters, IConfig const& config, std::vector<TestCase>& matchingTestCases ) const = 0;
|
||||
virtual void getFilteredTests( IConfig const& config, std::vector<TestCase>& matchingTestCases ) const = 0;
|
||||
virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector<TestCase>& matchingTestCases ) const = 0;
|
||||
|
||||
};
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@
|
||||
#include "catch_text.h"
|
||||
#include "catch_console_colour.hpp"
|
||||
#include "catch_interfaces_reporter.h"
|
||||
#include "catch_test_spec_parser.hpp"
|
||||
|
||||
#include <limits>
|
||||
#include <algorithm>
|
||||
@@ -19,10 +20,14 @@
|
||||
namespace Catch {
|
||||
|
||||
inline std::size_t listTests( Config const& config ) {
|
||||
if( config.filters().empty() )
|
||||
std::cout << "All available test cases:\n";
|
||||
else
|
||||
|
||||
TestSpec testSpec = config.testSpec();
|
||||
if( config.testSpec().hasFilters() )
|
||||
std::cout << "Matching test cases:\n";
|
||||
else {
|
||||
std::cout << "All available test cases:\n";
|
||||
testSpec = TestSpecParser().parse( "*" ).testSpec();
|
||||
}
|
||||
|
||||
std::size_t matchedTests = 0;
|
||||
TextAttributes nameAttr, tagsAttr;
|
||||
@@ -30,7 +35,7 @@ namespace Catch {
|
||||
tagsAttr.setIndent( 6 );
|
||||
|
||||
std::vector<TestCase> matchedTestCases;
|
||||
getRegistryHub().getTestCaseRegistry().getFilteredTests( config, matchedTestCases );
|
||||
getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
|
||||
for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
|
||||
it != itEnd;
|
||||
++it ) {
|
||||
@@ -46,7 +51,7 @@ namespace Catch {
|
||||
std::cout << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;
|
||||
}
|
||||
|
||||
if( config.filters().empty() )
|
||||
if( !config.testSpec().hasFilters() )
|
||||
std::cout << pluralise( matchedTests, "test case" ) << "\n" << std::endl;
|
||||
else
|
||||
std::cout << pluralise( matchedTests, "matching test case" ) << "\n" << std::endl;
|
||||
@@ -54,9 +59,12 @@ namespace Catch {
|
||||
}
|
||||
|
||||
inline std::size_t listTestsNamesOnly( Config const& config ) {
|
||||
TestSpec testSpec = config.testSpec();
|
||||
if( !config.testSpec().hasFilters() )
|
||||
testSpec = TestSpecParser().parse( "*" ).testSpec();
|
||||
std::size_t matchedTests = 0;
|
||||
std::vector<TestCase> matchedTestCases;
|
||||
getRegistryHub().getTestCaseRegistry().getFilteredTests( config, matchedTestCases );
|
||||
getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
|
||||
for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
|
||||
it != itEnd;
|
||||
++it ) {
|
||||
@@ -68,15 +76,18 @@ namespace Catch {
|
||||
}
|
||||
|
||||
inline std::size_t listTags( Config const& config ) {
|
||||
if( config.filters().empty() )
|
||||
TestSpec testSpec = config.testSpec();
|
||||
if( config.testSpec().hasFilters() )
|
||||
std::cout << "Tags for matching test cases:\n";
|
||||
else {
|
||||
std::cout << "All available tags:\n";
|
||||
else
|
||||
std::cout << "Matching tags:\n";
|
||||
testSpec = TestSpecParser().parse( "*" ).testSpec();
|
||||
}
|
||||
|
||||
std::map<std::string, int> tagCounts;
|
||||
|
||||
std::vector<TestCase> matchedTestCases;
|
||||
getRegistryHub().getTestCaseRegistry().getFilteredTests( config, matchedTestCases );
|
||||
getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
|
||||
for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
|
||||
it != itEnd;
|
||||
++it ) {
|
||||
|
@@ -8,9 +8,10 @@
|
||||
#ifndef TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
|
||||
|
||||
#include "catch_tags.h"
|
||||
#include "catch_test_spec.h"
|
||||
#include "catch_test_case_info.h"
|
||||
#include "catch_interfaces_testcase.h"
|
||||
#include "catch_tags.h"
|
||||
#include "catch_common.h"
|
||||
|
||||
namespace Catch {
|
||||
|
@@ -59,25 +59,15 @@ namespace Catch {
|
||||
return m_nonHiddenFunctions;
|
||||
}
|
||||
|
||||
virtual void getFilteredTests( TestCaseFilters const& filters, IConfig const& config, std::vector<TestCase>& matchingTestCases ) const {
|
||||
virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector<TestCase>& matchingTestCases ) const {
|
||||
for( std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin(),
|
||||
itEnd = m_functionsInOrder.end();
|
||||
it != itEnd;
|
||||
++it ) {
|
||||
if( filters.shouldInclude( *it ) && ( config.allowThrows() || !it->throws() ) )
|
||||
if( testSpec.matches( *it ) && ( config.allowThrows() || !it->throws() ) )
|
||||
matchingTestCases.push_back( *it );
|
||||
}
|
||||
}
|
||||
virtual void getFilteredTests( IConfig const& config, std::vector<TestCase>& matchingTestCases ) const {
|
||||
if( config.filters().empty() )
|
||||
return getFilteredTests( TestCaseFilters( "empty" ), config, matchingTestCases );
|
||||
|
||||
for( std::vector<TestCaseFilters>::const_iterator it = config.filters().begin(),
|
||||
itEnd = config.filters().end();
|
||||
it != itEnd;
|
||||
++it )
|
||||
getFilteredTests( *it, config, matchingTestCases );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
|
@@ -8,8 +8,12 @@
|
||||
#ifndef TWOBLUECUBES_CATCH_TEST_SPEC_H_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_TEST_SPEC_H_INCLUDED
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpadded"
|
||||
#endif
|
||||
|
||||
#include "catch_test_case_info.h"
|
||||
#include "catch_tags.h" // deprecated
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -105,55 +109,10 @@ namespace Catch {
|
||||
|
||||
friend class TestSpecParser;
|
||||
};
|
||||
|
||||
|
||||
// -------- deprecated -------
|
||||
|
||||
class TestCase;
|
||||
|
||||
struct IfFilterMatches{ enum DoWhat {
|
||||
AutoDetectBehaviour,
|
||||
IncludeTests,
|
||||
ExcludeTests
|
||||
}; };
|
||||
|
||||
class TestCaseFilter {
|
||||
enum WildcardPosition {
|
||||
NoWildcard = 0,
|
||||
WildcardAtStart = 1,
|
||||
WildcardAtEnd = 2,
|
||||
WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
|
||||
};
|
||||
|
||||
public:
|
||||
TestCaseFilter( std::string const& testSpec, IfFilterMatches::DoWhat matchBehaviour = IfFilterMatches::AutoDetectBehaviour );
|
||||
|
||||
IfFilterMatches::DoWhat getFilterType() const;
|
||||
bool shouldInclude( TestCase const& testCase ) const;
|
||||
|
||||
private:
|
||||
bool isMatch( TestCase const& testCase ) const;
|
||||
|
||||
std::string m_stringToMatch;
|
||||
IfFilterMatches::DoWhat m_filterType;
|
||||
WildcardPosition m_wildcardPosition;
|
||||
};
|
||||
|
||||
class TestCaseFilters {
|
||||
public:
|
||||
TestCaseFilters( std::string const& name );
|
||||
std::string getName() const;
|
||||
void addFilter( TestCaseFilter const& filter );
|
||||
void addTags( std::string const& tagPattern );
|
||||
bool shouldInclude( TestCase const& testCase ) const;
|
||||
|
||||
private:
|
||||
std::vector<TagExpression> m_tagExpressions;
|
||||
std::vector<TestCaseFilter> m_inclusionFilters;
|
||||
std::vector<TestCaseFilter> m_exclusionFilters;
|
||||
std::string m_name;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_TEST_SPEC_H_INCLUDED
|
||||
|
@@ -9,125 +9,7 @@
|
||||
#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
|
||||
|
||||
#include "catch_test_spec.hpp"
|
||||
#include "catch_test_case_info.h"
|
||||
#include "catch_common.h"
|
||||
|
||||
namespace Catch {
|
||||
|
||||
TestCaseFilter::TestCaseFilter( std::string const& testSpec, IfFilterMatches::DoWhat matchBehaviour )
|
||||
: m_stringToMatch( toLower( testSpec ) ),
|
||||
m_filterType( matchBehaviour ),
|
||||
m_wildcardPosition( NoWildcard )
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if( startsWith( m_stringToMatch, "*" ) ) {
|
||||
m_stringToMatch = m_stringToMatch.substr( 1 );
|
||||
m_wildcardPosition = (WildcardPosition)( m_wildcardPosition | WildcardAtStart );
|
||||
}
|
||||
if( endsWith( m_stringToMatch, "*" ) ) {
|
||||
m_stringToMatch = m_stringToMatch.substr( 0, m_stringToMatch.size()-1 );
|
||||
m_wildcardPosition = (WildcardPosition)( m_wildcardPosition | WildcardAtEnd );
|
||||
}
|
||||
}
|
||||
|
||||
IfFilterMatches::DoWhat TestCaseFilter::getFilterType() const {
|
||||
return m_filterType;
|
||||
}
|
||||
|
||||
bool TestCaseFilter::shouldInclude( TestCase const& testCase ) const {
|
||||
return isMatch( testCase ) == (m_filterType == IfFilterMatches::IncludeTests);
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunreachable-code"
|
||||
#endif
|
||||
|
||||
bool TestCaseFilter::isMatch( TestCase const& testCase ) const {
|
||||
std::string name = testCase.getTestCaseInfo().name;
|
||||
toLowerInPlace( name );
|
||||
|
||||
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 );
|
||||
}
|
||||
throw std::logic_error( "Unhandled wildcard type" );
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
TestCaseFilters::TestCaseFilters( std::string const& name ) : m_name( name ) {}
|
||||
|
||||
std::string TestCaseFilters::getName() const {
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void TestCaseFilters::addFilter( TestCaseFilter const& filter ) {
|
||||
if( filter.getFilterType() == IfFilterMatches::ExcludeTests )
|
||||
m_exclusionFilters.push_back( filter );
|
||||
else
|
||||
m_inclusionFilters.push_back( filter );
|
||||
}
|
||||
|
||||
void TestCaseFilters::addTags( std::string const& tagPattern ) {
|
||||
TagExpression exp;
|
||||
TagExpressionParser( exp ).parse( tagPattern );
|
||||
|
||||
m_tagExpressions.push_back( exp );
|
||||
}
|
||||
|
||||
bool TestCaseFilters::shouldInclude( TestCase const& testCase ) const {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
else if( m_exclusionFilters.empty() && m_tagExpressions.empty() ) {
|
||||
return !testCase.isHidden();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
// deprecated
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
|
||||
|
@@ -8,6 +8,11 @@
|
||||
#ifndef TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpadded"
|
||||
#endif
|
||||
|
||||
#include "catch_test_spec.h"
|
||||
|
||||
namespace Catch {
|
||||
@@ -19,15 +24,23 @@ namespace Catch {
|
||||
std::size_t m_start, m_pos;
|
||||
std::string m_arg;
|
||||
TestSpec::Filter m_currentFilter;
|
||||
TestSpec m_testSpec;
|
||||
|
||||
public:
|
||||
TestSpec testSpec;
|
||||
|
||||
public:
|
||||
TestSpecParser( std::string const& arg ) : m_mode( None ), m_exclusion( false ), m_start( std::string::npos ), m_arg( arg ) {
|
||||
TestSpecParser parse( std::string const& arg ) {
|
||||
m_mode = None;
|
||||
m_exclusion = false;
|
||||
m_start = std::string::npos;
|
||||
m_arg = arg;
|
||||
for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
|
||||
visitChar( m_arg[m_pos] );
|
||||
visitChar( ',' );
|
||||
if( m_mode == Name )
|
||||
addPattern<TestSpec::NamePattern>();
|
||||
return *this;
|
||||
}
|
||||
TestSpec testSpec() {
|
||||
addFilter();
|
||||
return m_testSpec;
|
||||
}
|
||||
private:
|
||||
void visitChar( char c ) {
|
||||
@@ -81,15 +94,19 @@ namespace Catch {
|
||||
}
|
||||
void addFilter() {
|
||||
if( !m_currentFilter.m_patterns.empty() ) {
|
||||
testSpec.m_filters.push_back( m_currentFilter );
|
||||
m_testSpec.m_filters.push_back( m_currentFilter );
|
||||
m_currentFilter = TestSpec::Filter();
|
||||
}
|
||||
}
|
||||
};
|
||||
inline TestSpec parseTestSpec( std::string const& arg ) {
|
||||
return TestSpecParser( arg ).testSpec;
|
||||
return TestSpecParser().parse( arg ).testSpec();
|
||||
}
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
|
||||
|
Reference in New Issue
Block a user