diff --git a/include/catch_runner.hpp b/include/catch_runner.hpp index 98f160a0..2cc883f3 100644 --- a/include/catch_runner.hpp +++ b/include/catch_runner.hpp @@ -33,28 +33,18 @@ namespace Catch { Totals runTests() { - std::vector filterGroups = m_config->filters(); - if( filterGroups.empty() ) { - TestCaseFilters filterGroup( "" ); - filterGroups.push_back( filterGroup ); - } - RunContext context( m_config.get(), m_reporter ); Totals totals; - for( std::size_t i=0; i < filterGroups.size() && !context.aborting(); ++i ) { - context.testGroupStarting( filterGroups[i].getName(), i, filterGroups.size() ); - totals += runTestsForGroup( context, filterGroups[i] ); - context.testGroupEnded( filterGroups[i].getName(), totals, i, filterGroups.size() ); - } - return totals; - } - Totals runTestsForGroup( RunContext& context, TestCaseFilters const& filterGroup ) { - Totals totals; + context.testGroupStarting( "", 1, 1 ); // deprecated? + + TestSpec testSpec = m_config->testSpec(); + if( !testSpec.hasFilters() ) + testSpec = TestSpecParser().parse( "~[.]" ).testSpec(); // All not hidden tests std::vector testCases; - getRegistryHub().getTestCaseRegistry().getFilteredTests( filterGroup, *m_config, testCases ); + getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, *m_config, testCases ); int testsRunForGroup = 0; for( std::vector::const_iterator it = testCases.begin(), itEnd = testCases.end(); @@ -70,8 +60,7 @@ namespace Catch { m_testsAlreadyRun.insert( *it ); } } - if( testsRunForGroup == 0 && !filterGroup.getName().empty() ) - m_reporter->noMatchingTestCases( filterGroup.getName() ); + context.testGroupEnded( "", totals, 1, 1 ); return totals; } diff --git a/include/internal/catch_config.hpp b/include/internal/catch_config.hpp index dccec273..ab1d2aa8 100644 --- a/include/internal/catch_config.hpp +++ b/include/internal/catch_config.hpp @@ -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 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 m_filterSets; + TestSpec m_testSpec; }; diff --git a/include/internal/catch_interfaces_config.h b/include/internal/catch_interfaces_config.h index 32936591..c7610d99 100644 --- a/include/internal/catch_interfaces_config.h +++ b/include/internal/catch_interfaces_config.h @@ -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 const& filters() const = 0; + virtual TestSpec const& testSpec() const = 0; }; } diff --git a/include/internal/catch_interfaces_testcase.h b/include/internal/catch_interfaces_testcase.h index 47f15204..21ed3c3a 100644 --- a/include/internal/catch_interfaces_testcase.h +++ b/include/internal/catch_interfaces_testcase.h @@ -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 const& getAllTests() const = 0; - virtual void getFilteredTests( TestCaseFilters const& filters, IConfig const& config, std::vector& matchingTestCases ) const = 0; - virtual void getFilteredTests( IConfig const& config, std::vector& matchingTestCases ) const = 0; + virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector& matchingTestCases ) const = 0; }; } diff --git a/include/internal/catch_list.hpp b/include/internal/catch_list.hpp index 76a963f0..f05d58c1 100644 --- a/include/internal/catch_list.hpp +++ b/include/internal/catch_list.hpp @@ -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 #include @@ -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 matchedTestCases; - getRegistryHub().getTestCaseRegistry().getFilteredTests( config, matchedTestCases ); + getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases ); for( std::vector::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 matchedTestCases; - getRegistryHub().getTestCaseRegistry().getFilteredTests( config, matchedTestCases ); + getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases ); for( std::vector::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 tagCounts; std::vector matchedTestCases; - getRegistryHub().getTestCaseRegistry().getFilteredTests( config, matchedTestCases ); + getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases ); for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); it != itEnd; ++it ) { diff --git a/include/internal/catch_test_case_info.hpp b/include/internal/catch_test_case_info.hpp index 84bf6a33..c3cb6a53 100644 --- a/include/internal/catch_test_case_info.hpp +++ b/include/internal/catch_test_case_info.hpp @@ -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 { diff --git a/include/internal/catch_test_case_registry_impl.hpp b/include/internal/catch_test_case_registry_impl.hpp index 25f210ef..a0a478ff 100644 --- a/include/internal/catch_test_case_registry_impl.hpp +++ b/include/internal/catch_test_case_registry_impl.hpp @@ -59,25 +59,15 @@ namespace Catch { return m_nonHiddenFunctions; } - virtual void getFilteredTests( TestCaseFilters const& filters, IConfig const& config, std::vector& matchingTestCases ) const { + virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector& matchingTestCases ) const { for( std::vector::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& matchingTestCases ) const { - if( config.filters().empty() ) - return getFilteredTests( TestCaseFilters( "empty" ), config, matchingTestCases ); - - for( std::vector::const_iterator it = config.filters().begin(), - itEnd = config.filters().end(); - it != itEnd; - ++it ) - getFilteredTests( *it, config, matchingTestCases ); - } private: diff --git a/include/internal/catch_test_spec.h b/include/internal/catch_test_spec.h index 1b58d4e8..7af4a89e 100644 --- a/include/internal/catch_test_spec.h +++ b/include/internal/catch_test_spec.h @@ -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 #include @@ -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 m_tagExpressions; - std::vector m_inclusionFilters; - std::vector m_exclusionFilters; - std::string m_name; - }; - } +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + #endif // TWOBLUECUBES_CATCH_TEST_SPEC_H_INCLUDED diff --git a/include/internal/catch_test_spec.hpp b/include/internal/catch_test_spec.hpp index 6df01bc7..0827a938 100644 --- a/include/internal/catch_test_spec.hpp +++ b/include/internal/catch_test_spec.hpp @@ -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::const_iterator it = m_tagExpressions.begin(); - std::vector::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::const_iterator it = m_inclusionFilters.begin(); - std::vector::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::const_iterator it = m_exclusionFilters.begin(); - std::vector::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 diff --git a/include/internal/catch_test_spec_parser.hpp b/include/internal/catch_test_spec_parser.hpp index fbf06247..fd566813 100644 --- a/include/internal/catch_test_spec_parser.hpp +++ b/include/internal/catch_test_spec_parser.hpp @@ -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(); + 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 diff --git a/projects/SelfTest/CmdLineTests.cpp b/projects/SelfTest/CmdLineTests.cpp index f0b79861..36b8df94 100644 --- a/projects/SelfTest/CmdLineTests.cpp +++ b/projects/SelfTest/CmdLineTests.cpp @@ -216,5 +216,13 @@ TEST_CASE( "Parse test names and tags", "" ) { CHECK( spec.matches( tcC ) == false ); CHECK( spec.matches( tcD ) == false ); } + SECTION( "quoted string followed by tag exclusion" ) { + TestSpec spec = parseTestSpec( "\"*name*\"~[.]" ); + CHECK( spec.hasFilters() == true ); + CHECK( spec.matches( tcA ) == false ); + CHECK( spec.matches( tcB ) == false ); + CHECK( spec.matches( tcC ) == false ); + CHECK( spec.matches( tcD ) == true ); + } } diff --git a/projects/SelfTest/SurrogateCpps/catch_test_spec.cpp b/projects/SelfTest/SurrogateCpps/catch_test_spec.cpp new file mode 100644 index 00000000..7a708e64 --- /dev/null +++ b/projects/SelfTest/SurrogateCpps/catch_test_spec.cpp @@ -0,0 +1,2 @@ +// This file is only here to verify (to the extent possible) the self sufficiency of the header +#include "catch_test_spec.h" diff --git a/projects/SelfTest/TestMain.cpp b/projects/SelfTest/TestMain.cpp index 461f965d..5046cafc 100644 --- a/projects/SelfTest/TestMain.cpp +++ b/projects/SelfTest/TestMain.cpp @@ -54,18 +54,16 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]" CHECK_NOTHROW( parseIntoConfig( argv, config ) ); Catch::Config cfg( config ); - REQUIRE( cfg.filters().size() == 1 ); - REQUIRE( cfg.filters()[0].shouldInclude( fakeTestCase( "notIncluded" ) ) == false ); - REQUIRE( cfg.filters()[0].shouldInclude( fakeTestCase( "test1" ) ) ); + REQUIRE( cfg.testSpec().matches( fakeTestCase( "notIncluded" ) ) == false ); + REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) ); } SECTION( "Specify one test case exclusion using exclude:", "" ) { const char* argv[] = { "test", "exclude:test1" }; CHECK_NOTHROW( parseIntoConfig( argv, config ) ); Catch::Config cfg( config ); - REQUIRE( cfg.filters().size() == 1 ); - REQUIRE( cfg.filters()[0].shouldInclude( fakeTestCase( "test1" ) ) == false ); - REQUIRE( cfg.filters()[0].shouldInclude( fakeTestCase( "alwaysIncluded" ) ) ); + REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) == false ); + REQUIRE( cfg.testSpec().matches( fakeTestCase( "alwaysIncluded" ) ) ); } SECTION( "Specify one test case exclusion using ~", "" ) { @@ -73,21 +71,10 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]" CHECK_NOTHROW( parseIntoConfig( argv, config ) ); Catch::Config cfg( config ); - REQUIRE( cfg.filters().size() == 1 ); - REQUIRE( cfg.filters()[0].shouldInclude( fakeTestCase( "test1" ) ) == false ); - REQUIRE( cfg.filters()[0].shouldInclude( fakeTestCase( "alwaysIncluded" ) ) ); + REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) == false ); + REQUIRE( cfg.testSpec().matches( fakeTestCase( "alwaysIncluded" ) ) ); } - - SECTION( "Specify two test cases using -t", "" ) { - const char* argv[] = { "test", "-t", "test1", "test2" }; - CHECK_NOTHROW( parseIntoConfig( argv, config ) ); - Catch::Config cfg( config ); - REQUIRE( cfg.filters().size() == 1 ); - REQUIRE( cfg.filters()[0].shouldInclude( fakeTestCase( "notIncluded" ) ) == false ); - REQUIRE( cfg.filters()[0].shouldInclude( fakeTestCase( "test1" ) ) ); - REQUIRE( cfg.filters()[0].shouldInclude( fakeTestCase( "test2" ) ) ); - } } SECTION( "reporter", "" ) { @@ -191,156 +178,6 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]" } } -TEST_CASE( "selftest/test filter", "Individual filters" ) { - - Catch::TestCaseFilter matchAny( "*" ); - Catch::TestCaseFilter matchNone( "*", Catch::IfFilterMatches::ExcludeTests ); - CHECK( matchAny.shouldInclude( fakeTestCase( "any" ) )); - CHECK( matchNone.shouldInclude( fakeTestCase( "any" ) ) == false ); - - Catch::TestCaseFilter matchHidden( "./*" ); - Catch::TestCaseFilter matchNonHidden( "./*", Catch::IfFilterMatches::ExcludeTests ); - - CHECK( matchHidden.shouldInclude( fakeTestCase( "any" ) ) == false ); - CHECK( matchNonHidden.shouldInclude( fakeTestCase( "any" ) ) ); - - CHECK( matchHidden.shouldInclude( fakeTestCase( "./any" ) ) ); - CHECK( matchNonHidden.shouldInclude( fakeTestCase( "./any" ) ) == false ); -} - -TEST_CASE( "selftest/test filters", "Sets of filters" ) { - - Catch::TestCaseFilter matchHidden( "./*" ); - Catch::TestCaseFilter dontMatchA( "./a*", Catch::IfFilterMatches::ExcludeTests ); - Catch::TestCaseFilters filters( "" ); - filters.addFilter( matchHidden ); - filters.addFilter( dontMatchA ); - - CHECK( matchHidden.shouldInclude( fakeTestCase( "./something" ) ) ); - - CHECK( filters.shouldInclude( fakeTestCase( "any" ) ) == false ); - CHECK( filters.shouldInclude( fakeTestCase( "./something" ) ) ); - CHECK( filters.shouldInclude( fakeTestCase( "./anything" ) ) == false ); -} - -TEST_CASE( "selftest/filter/prefix wildcard", "Individual filters with wildcards at the start" ) { - Catch::TestCaseFilter matchBadgers( "*badger" ); - - CHECK( matchBadgers.shouldInclude( fakeTestCase( "big badger" ) )); - CHECK( matchBadgers.shouldInclude( fakeTestCase( "little badgers" ) ) == false ); -} -TEST_CASE( "selftest/filter/wildcard at both ends", "Individual filters with wildcards at both ends" ) { - Catch::TestCaseFilter matchBadgers( "*badger*" ); - - CHECK( matchBadgers.shouldInclude( fakeTestCase( "big badger" ) )); - CHECK( matchBadgers.shouldInclude( fakeTestCase( "little badgers" ) ) ); - CHECK( matchBadgers.shouldInclude( fakeTestCase( "badgers are big" ) ) ); - CHECK( matchBadgers.shouldInclude( fakeTestCase( "hedgehogs" ) ) == false ); -} - - -template -int getArgc( const char * (&)[size] ) { - return size; -} - -TEST_CASE( "selftest/tags", "[tags]" ) { - - std::string p1 = "[one]"; - std::string p2 = "[one],[two]"; - std::string p3 = "[one][two]"; - std::string p4 = "[one][two],[three]"; - std::string p5 = "[one][two]~[.],[three]"; - std::string p6 = "[one][two]exclude:[.],[three]"; - - SECTION( "single [one] tag", "" ) { - Catch::TestCase oneTag = makeTestCase( NULL, "", "test", "[one]", CATCH_INTERNAL_LINEINFO ); - - CHECK( oneTag.getTestCaseInfo().description == "" ); - CHECK( oneTag.hasTag( "one" ) ); - CHECK( oneTag.getTags().size() == 1 ); - - CHECK( oneTag.matchesTags( p1 ) == true ); - CHECK( oneTag.matchesTags( p2 ) == true ); - CHECK( oneTag.matchesTags( p3 ) == false ); - CHECK( oneTag.matchesTags( p4 ) == false ); - CHECK( oneTag.matchesTags( p5 ) == false ); - CHECK( oneTag.matchesTags( p6 ) == false ); - } - - SECTION( "single [two] tag", "" ) { - Catch::TestCase oneTag = makeTestCase( NULL, "", "test", "[two]", CATCH_INTERNAL_LINEINFO ); - - CHECK( oneTag.getTestCaseInfo().description == "" ); - CHECK( oneTag.hasTag( "two" ) ); - CHECK( oneTag.getTags().size() == 1 ); - - CHECK( oneTag.matchesTags( p1 ) == false ); - CHECK( oneTag.matchesTags( p2 ) == true ); - CHECK( oneTag.matchesTags( p3 ) == false ); - CHECK( oneTag.matchesTags( p4 ) == false ); - CHECK( oneTag.matchesTags( p5 ) == false ); - CHECK( oneTag.matchesTags( p6 ) == false ); - } - - SECTION( "two tags", "" ) { - Catch::TestCase twoTags= makeTestCase( NULL, "", "test", "[one][two]", CATCH_INTERNAL_LINEINFO ); - - CHECK( twoTags.getTestCaseInfo().description == "" ); - CHECK( twoTags.hasTag( "one" ) ); - CHECK( twoTags.hasTag( "two" ) ); - CHECK( twoTags.hasTag( "Two" ) ); - CHECK( twoTags.hasTag( "three" ) == false ); - CHECK( twoTags.getTags().size() == 2 ); - - CHECK( twoTags.matchesTags( p1 ) == true ); - CHECK( twoTags.matchesTags( p2 ) == true ); - CHECK( twoTags.matchesTags( p3 ) == true ); - CHECK( twoTags.matchesTags( p4 ) == true ); - CHECK( twoTags.matchesTags( p5 ) == true ); - CHECK( twoTags.matchesTags( p6 ) == true ); - } - SECTION( "complex", "" ) { - CHECK( fakeTestCase( "test", "[one][.]" ).matchesTags( p1 ) ); - CHECK_FALSE( fakeTestCase( "test", "[one][.]" ).matchesTags( p5 ) ); - CHECK( fakeTestCase( "test", "[three]" ).matchesTags( p4 ) ); - CHECK( fakeTestCase( "test", "[three]" ).matchesTags( p5 ) ); - CHECK( fakeTestCase( "test", "[three]" ).matchesTags( "[three]~[one]" ) ); - CHECK( fakeTestCase( "test", "[three]" ).matchesTags( "[three]exclude:[one]" ) ); - CHECK( fakeTestCase( "test", "[unit][not_apple]" ).matchesTags( "[unit]" ) ); - CHECK_FALSE( fakeTestCase( "test", "[unit][not_apple]" ).matchesTags( "[unit]~[not_apple]" ) ); - CHECK_FALSE( fakeTestCase( "test", "[unit][not_apple]" ).matchesTags( "[unit]exclude:[not_apple]" ) ); - } - - SECTION( "one tag with characters either side", "" ) { - - Catch::TestCase oneTagWithExtras = makeTestCase( NULL, "", "test", "12[one]34", CATCH_INTERNAL_LINEINFO ); - CHECK( oneTagWithExtras.getTestCaseInfo().description == "1234" ); - CHECK( oneTagWithExtras.hasTag( "one" ) ); - CHECK( oneTagWithExtras.hasTag( "two" ) == false ); - CHECK( oneTagWithExtras.getTags().size() == 1 ); - } - - SECTION( "start of a tag, but not closed", "" ) { - - Catch::TestCase oneTagOpen = makeTestCase( NULL, "", "test", "[one", CATCH_INTERNAL_LINEINFO ); - - CHECK( oneTagOpen.getTestCaseInfo().description == "[one" ); - CHECK( oneTagOpen.hasTag( "one" ) == false ); - CHECK( oneTagOpen.getTags().size() == 0 ); - } - - SECTION( "hidden", "" ) { - Catch::TestCase oneTag = makeTestCase( NULL, "", "test", "[.]", CATCH_INTERNAL_LINEINFO ); - - CHECK( oneTag.getTestCaseInfo().description == "" ); - CHECK( oneTag.hasTag( "." ) ); - CHECK( oneTag.isHidden() ); - - CHECK( oneTag.matchesTags( "~[.]" ) == false ); - - } -} TEST_CASE( "Long strings can be wrapped", "[wrap]" ) { diff --git a/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj b/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj index b939b522..bab0b763 100644 --- a/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj +++ b/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 2656C2211925E7330040DB02 /* catch_test_spec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2656C2201925E7330040DB02 /* catch_test_spec.cpp */; }; + 2656C2251925EC870040DB02 /* catch_tags.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2656C2241925EC870040DB02 /* catch_tags.cpp */; }; 266B06B816F3A60A004ED264 /* VariadicMacrosTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266B06B616F3A60A004ED264 /* VariadicMacrosTests.cpp */; }; 266ECD74170F3C620030D735 /* BDDTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266ECD73170F3C620030D735 /* BDDTests.cpp */; }; 26847E5F16BBADB40043B9C1 /* catch_message.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26847E5D16BBADB40043B9C1 /* catch_message.cpp */; }; @@ -31,7 +33,6 @@ 4A6D0C3D149B3D9E00DB3EAA /* MiscTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A6D0C34149B3D9E00DB3EAA /* MiscTests.cpp */; }; 4A6D0C3E149B3D9E00DB3EAA /* TestMain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A6D0C35149B3D9E00DB3EAA /* TestMain.cpp */; }; 4A6D0C3F149B3D9E00DB3EAA /* TrickyTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A6D0C36149B3D9E00DB3EAA /* TrickyTests.cpp */; }; - 4A8E4DD2160A352200194CBD /* catch_tags.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A8E4DD0160A352200194CBD /* catch_tags.cpp */; }; 4AB3D99D1616216500C9A0F8 /* catch_interfaces_testcase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AB3D99C1616216500C9A0F8 /* catch_interfaces_testcase.cpp */; }; 4AB3D9A01616219100C9A0F8 /* catch_interfaces_config.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AB3D99F1616219100C9A0F8 /* catch_interfaces_config.cpp */; }; 4AB3D9A2161621B500C9A0F8 /* catch_interfaces_generators.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AB3D9A1161621B500C9A0F8 /* catch_interfaces_generators.cpp */; }; @@ -57,7 +58,6 @@ /* Begin PBXFileReference section */ 261488FA184C81130041FBEB /* catch_test_spec.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_test_spec.hpp; sourceTree = ""; }; - 261488FB184C83EA0041FBEB /* catch_tags.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_tags.h; sourceTree = ""; }; 261488FC184D1DC10041FBEB /* catch_stream.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_stream.h; sourceTree = ""; }; 261488FD184D21290041FBEB /* catch_section_info.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_section_info.h; sourceTree = ""; }; 261488FE184DC32F0041FBEB /* catch_section.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_section.h; sourceTree = ""; }; @@ -67,6 +67,10 @@ 263FD06017AF8DF200988A20 /* catch_timer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_timer.hpp; sourceTree = ""; }; 263FD06117AF8DF200988A20 /* catch_timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_timer.h; sourceTree = ""; }; 2656C21F1925E5100040DB02 /* catch_test_spec_parser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_test_spec_parser.hpp; sourceTree = ""; }; + 2656C2201925E7330040DB02 /* catch_test_spec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_test_spec.cpp; path = ../../../SelfTest/SurrogateCpps/catch_test_spec.cpp; sourceTree = ""; }; + 2656C2221925EC6F0040DB02 /* catch_tags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_tags.h; sourceTree = ""; }; + 2656C2231925EC6F0040DB02 /* catch_tags.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_tags.hpp; sourceTree = ""; }; + 2656C2241925EC870040DB02 /* catch_tags.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_tags.cpp; path = ../../../SelfTest/SurrogateCpps/catch_tags.cpp; sourceTree = ""; }; 266B06B616F3A60A004ED264 /* VariadicMacrosTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VariadicMacrosTests.cpp; path = ../../../SelfTest/VariadicMacrosTests.cpp; sourceTree = ""; }; 266ECD73170F3C620030D735 /* BDDTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BDDTests.cpp; path = ../../../SelfTest/BDDTests.cpp; sourceTree = ""; }; 266ECD8C1713614B0030D735 /* catch_legacy_reporter_adapter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_legacy_reporter_adapter.hpp; sourceTree = ""; }; @@ -153,8 +157,6 @@ 4A6D0C68149B3E3D00DB3EAA /* catch_reporter_xml.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_reporter_xml.hpp; sourceTree = ""; }; 4A7ADB4314F631E10094FE10 /* catch_totals.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_totals.hpp; sourceTree = ""; }; 4A7DB2CD1652FE4B00FA6523 /* catch_version.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = catch_version.h; path = ../../../../include/internal/catch_version.h; sourceTree = ""; }; - 4A8E4DCC160A344100194CBD /* catch_tags.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_tags.hpp; sourceTree = ""; }; - 4A8E4DD0160A352200194CBD /* catch_tags.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_tags.cpp; path = ../../../SelfTest/SurrogateCpps/catch_tags.cpp; sourceTree = ""; }; 4A90B59B15D0F61A00EF71BC /* catch_interfaces_generators.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_interfaces_generators.h; sourceTree = ""; }; 4A90B59D15D24FE900EF71BC /* catch_assertionresult.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; path = catch_assertionresult.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; 4A90B59E15D2521E00EF71BC /* catch_expressionresult_builder.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; path = catch_expressionresult_builder.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; @@ -303,7 +305,8 @@ 4A8E4DCF160A34E200194CBD /* SurrogateCpps */ = { isa = PBXGroup; children = ( - 4A8E4DD0160A352200194CBD /* catch_tags.cpp */, + 2656C2241925EC870040DB02 /* catch_tags.cpp */, + 2656C2201925E7330040DB02 /* catch_test_spec.cpp */, 4AEE031F16142F910071E950 /* catch_common.cpp */, 4AEE032216142FC70071E950 /* catch_debugger.cpp */, 4AEE032416142FF10071E950 /* catch_stream.cpp */, @@ -385,6 +388,8 @@ 4AC91CBF155C381600DC5117 /* Test execution */ = { isa = PBXGroup; children = ( + 2656C2221925EC6F0040DB02 /* catch_tags.h */, + 2656C2231925EC6F0040DB02 /* catch_tags.hpp */, 2656C21F1925E5100040DB02 /* catch_test_spec_parser.hpp */, 4A6D0C4A149B3E3D00DB3EAA /* catch_config.hpp */, 4A6D0C51149B3E3D00DB3EAA /* catch_context.h */, @@ -392,9 +397,7 @@ 4A7ADB4314F631E10094FE10 /* catch_totals.hpp */, 4AB77CB71553B72B00857BF0 /* catch_section_info.hpp */, 4A084F1D15DAD15F0027E631 /* catch_test_spec.h */, - 4A8E4DCC160A344100194CBD /* catch_tags.hpp */, 26948287179EF7F900ED166E /* catch_test_case_tracker.hpp */, - 261488FB184C83EA0041FBEB /* catch_tags.h */, ); name = "Test execution"; sourceTree = ""; @@ -518,14 +521,15 @@ 4A6D0C3D149B3D9E00DB3EAA /* MiscTests.cpp in Sources */, 4A6D0C3E149B3D9E00DB3EAA /* TestMain.cpp in Sources */, 4A6D0C3F149B3D9E00DB3EAA /* TrickyTests.cpp in Sources */, - 4A8E4DD2160A352200194CBD /* catch_tags.cpp in Sources */, 4AEE032016142F910071E950 /* catch_common.cpp in Sources */, 4AEE032316142FC70071E950 /* catch_debugger.cpp in Sources */, + 2656C2251925EC870040DB02 /* catch_tags.cpp in Sources */, 4AEE032516142FF10071E950 /* catch_stream.cpp in Sources */, 4AEE0328161434FD0071E950 /* catch_xmlwriter.cpp in Sources */, 4A45DA2416161EF9004F8D6B /* catch_console_colour.cpp in Sources */, 4A45DA2716161F1F004F8D6B /* catch_ptr.cpp in Sources */, 26E1B7D319213BC900812682 /* CmdLineTests.cpp in Sources */, + 2656C2211925E7330040DB02 /* catch_test_spec.cpp in Sources */, 4A45DA2916161F3D004F8D6B /* catch_streambuf.cpp in Sources */, 4A45DA2B16161F79004F8D6B /* catch_interfaces_registry_hub.cpp in Sources */, 4A45DA2D16161FA2004F8D6B /* catch_interfaces_capture.cpp in Sources */,