mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-22 13:26:10 +01:00
Tags beginning with a non alpha-numeric character are now disallowed.
Added !throws special tag which denotes a test case to be skipped when run with -e (the idea being that the test case is expected to throw an exception which is not caught within a XXX_THROWS assertion).
This commit is contained in:
parent
c5406a25bf
commit
20cad7cb1d
@ -1,6 +1,6 @@
|
||||
![catch logo](catch-logo-small.png)
|
||||
|
||||
*v1.0 build 35 (master branch)*
|
||||
*v1.0 build 36 (master branch)*
|
||||
|
||||
Build status (on Travis CI) [![Build Status](https://travis-ci.org/philsquared/Catch.png)](https://travis-ci.org/philsquared/Catch)
|
||||
|
||||
|
@ -50,14 +50,16 @@ namespace Catch {
|
||||
}
|
||||
return totals;
|
||||
}
|
||||
|
||||
Totals runTestsForGroup( RunContext& context, const TestCaseFilters& filterGroup ) {
|
||||
Totals runTestsForGroup( RunContext& context, TestCaseFilters const& filterGroup ) {
|
||||
Totals totals;
|
||||
std::vector<TestCase>::const_iterator it = getRegistryHub().getTestCaseRegistry().getAllTests().begin();
|
||||
std::vector<TestCase>::const_iterator itEnd = getRegistryHub().getTestCaseRegistry().getAllTests().end();
|
||||
|
||||
std::vector<TestCase> testCases;
|
||||
getRegistryHub().getTestCaseRegistry().getFilteredTests( filterGroup, *m_config, testCases );
|
||||
|
||||
int testsRunForGroup = 0;
|
||||
for(; it != itEnd; ++it ) {
|
||||
if( filterGroup.shouldInclude( *it ) ) {
|
||||
for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();
|
||||
it != itEnd;
|
||||
++it ) {
|
||||
testsRunForGroup++;
|
||||
if( m_testsAlreadyRun.find( *it ) == m_testsAlreadyRun.end() ) {
|
||||
|
||||
@ -68,11 +70,9 @@ namespace Catch {
|
||||
m_testsAlreadyRun.insert( *it );
|
||||
}
|
||||
}
|
||||
}
|
||||
if( testsRunForGroup == 0 && !filterGroup.getName().empty() )
|
||||
m_reporter->noMatchingTestCases( filterGroup.getName() );
|
||||
return totals;
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -58,7 +58,7 @@ namespace Catch {
|
||||
static void use( Code _colourCode );
|
||||
|
||||
private:
|
||||
static Detail::IColourImpl* impl;
|
||||
static Detail::IColourImpl* impl();
|
||||
};
|
||||
|
||||
} // end namespace Catch
|
||||
|
@ -73,7 +73,10 @@ namespace {
|
||||
return true;
|
||||
}
|
||||
|
||||
Win32ColourImpl platformColourImpl;
|
||||
static Detail::IColourImpl* platformColourInstance() {
|
||||
static Win32ColourImpl s_instance;
|
||||
return &s_instance;
|
||||
}
|
||||
|
||||
} // end anon namespace
|
||||
} // end namespace Catch
|
||||
@ -120,7 +123,10 @@ namespace {
|
||||
return isatty(STDOUT_FILENO);
|
||||
}
|
||||
|
||||
PosixColourImpl platformColourImpl;
|
||||
static Detail::IColourImpl* platformColourInstance() {
|
||||
static PosixColourImpl s_instance;
|
||||
return &s_instance;
|
||||
}
|
||||
|
||||
} // end anon namespace
|
||||
} // end namespace Catch
|
||||
@ -132,21 +138,28 @@ namespace Catch {
|
||||
namespace {
|
||||
struct NoColourImpl : Detail::IColourImpl {
|
||||
void use( Colour::Code ) {}
|
||||
|
||||
static IColourImpl* instance() {
|
||||
static NoColourImpl s_instance;
|
||||
return &s_instance;
|
||||
}
|
||||
};
|
||||
NoColourImpl noColourImpl;
|
||||
static const bool shouldUseColour = shouldUseColourForPlatform() &&
|
||||
!isDebuggerActive();
|
||||
static bool shouldUseColour() {
|
||||
return shouldUseColourForPlatform() && !isDebuggerActive();
|
||||
}
|
||||
}
|
||||
|
||||
Colour::Colour( Code _colourCode ){ use( _colourCode ); }
|
||||
Colour::~Colour(){ use( None ); }
|
||||
void Colour::use( Code _colourCode ) {
|
||||
impl->use( _colourCode );
|
||||
impl()->use( _colourCode );
|
||||
}
|
||||
|
||||
Detail::IColourImpl* Colour::impl = shouldUseColour
|
||||
? static_cast<Detail::IColourImpl*>( &platformColourImpl )
|
||||
: static_cast<Detail::IColourImpl*>( &noColourImpl );
|
||||
Detail::IColourImpl* Colour::impl() {
|
||||
return shouldUseColour()
|
||||
? platformColourInstance()
|
||||
: NoColourImpl::instance();
|
||||
}
|
||||
|
||||
} // end namespace Catch
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "catch_ptr.hpp"
|
||||
|
||||
@ -32,6 +33,8 @@ namespace Catch {
|
||||
Never
|
||||
}; };
|
||||
|
||||
class TestCaseFilters;
|
||||
|
||||
struct IConfig : IShared {
|
||||
|
||||
virtual ~IConfig();
|
||||
@ -44,6 +47,7 @@ namespace Catch {
|
||||
virtual bool warnAboutMissingAssertions() const = 0;
|
||||
virtual int abortAfter() const = 0;
|
||||
virtual ShowDurations::OrNot showDurations() const = 0;
|
||||
virtual std::vector<TestCaseFilters> const& filters() const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -23,11 +23,14 @@ namespace Catch {
|
||||
};
|
||||
|
||||
class TestCase;
|
||||
struct IConfig;
|
||||
|
||||
struct ITestCaseRegistry {
|
||||
virtual ~ITestCaseRegistry();
|
||||
virtual std::vector<TestCase> const& getAllTests() const = 0;
|
||||
virtual std::vector<TestCase> getMatchingTestCases( std::string const& rawTestSpec ) 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;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -17,14 +17,6 @@
|
||||
#include <algorithm>
|
||||
|
||||
namespace Catch {
|
||||
inline bool matchesFilters( std::vector<TestCaseFilters> const& filters, TestCase const& testCase ) {
|
||||
std::vector<TestCaseFilters>::const_iterator it = filters.begin();
|
||||
std::vector<TestCaseFilters>::const_iterator itEnd = filters.end();
|
||||
for(; it != itEnd; ++it )
|
||||
if( !it->shouldInclude( testCase ) )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline std::size_t listTests( Config const& config ) {
|
||||
if( config.filters().empty() )
|
||||
@ -37,11 +29,11 @@ namespace Catch {
|
||||
nameAttr.setInitialIndent( 2 ).setIndent( 4 );
|
||||
tagsAttr.setIndent( 6 );
|
||||
|
||||
std::vector<TestCase> const& allTests = getRegistryHub().getTestCaseRegistry().getAllTests();
|
||||
for( std::vector<TestCase>::const_iterator it = allTests.begin(), itEnd = allTests.end();
|
||||
std::vector<TestCase> matchedTestCases;
|
||||
getRegistryHub().getTestCaseRegistry().getFilteredTests( config, matchedTestCases );
|
||||
for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
|
||||
it != itEnd;
|
||||
++it )
|
||||
if( matchesFilters( config.filters(), *it ) ) {
|
||||
++it ) {
|
||||
matchedTests++;
|
||||
TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
|
||||
Colour::Code colour = testCaseInfo.isHidden
|
||||
@ -63,11 +55,11 @@ namespace Catch {
|
||||
|
||||
inline std::size_t listTestsNamesOnly( Config const& config ) {
|
||||
std::size_t matchedTests = 0;
|
||||
std::vector<TestCase> const& allTests = getRegistryHub().getTestCaseRegistry().getAllTests();
|
||||
for( std::vector<TestCase>::const_iterator it = allTests.begin(), itEnd = allTests.end();
|
||||
std::vector<TestCase> matchedTestCases;
|
||||
getRegistryHub().getTestCaseRegistry().getFilteredTests( config, matchedTestCases );
|
||||
for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
|
||||
it != itEnd;
|
||||
++it )
|
||||
if( matchesFilters( config.filters(), *it ) ) {
|
||||
++it ) {
|
||||
matchedTests++;
|
||||
TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
|
||||
std::cout << testCaseInfo.name << std::endl;
|
||||
@ -83,12 +75,11 @@ namespace Catch {
|
||||
|
||||
std::map<std::string, int> tagCounts;
|
||||
|
||||
std::vector<TestCase> const& allTests = getRegistryHub().getTestCaseRegistry().getAllTests();
|
||||
for( std::vector<TestCase>::const_iterator it = allTests.begin(),
|
||||
itEnd = allTests.end();
|
||||
std::vector<TestCase> matchedTestCases;
|
||||
getRegistryHub().getTestCaseRegistry().getFilteredTests( config, matchedTestCases );
|
||||
for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
|
||||
it != itEnd;
|
||||
++it ) {
|
||||
if( matchesFilters( config.filters(), *it ) ) {
|
||||
for( std::set<std::string>::const_iterator tagIt = it->getTestCaseInfo().tags.begin(),
|
||||
tagItEnd = it->getTestCaseInfo().tags.end();
|
||||
tagIt != tagItEnd;
|
||||
@ -101,7 +92,6 @@ namespace Catch {
|
||||
countIt->second++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( std::map<std::string, int>::const_iterator countIt = tagCounts.begin(),
|
||||
countItEnd = tagCounts.end();
|
||||
|
@ -88,23 +88,6 @@ namespace Catch {
|
||||
m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
|
||||
}
|
||||
|
||||
Totals runMatching( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
|
||||
|
||||
std::vector<TestCase> matchingTests = getRegistryHub().getTestCaseRegistry().getMatchingTestCases( testSpec );
|
||||
|
||||
Totals totals;
|
||||
|
||||
testGroupStarting( testSpec, groupIndex, groupsCount );
|
||||
|
||||
std::vector<TestCase>::const_iterator it = matchingTests.begin();
|
||||
std::vector<TestCase>::const_iterator itEnd = matchingTests.end();
|
||||
for(; it != itEnd; ++it )
|
||||
totals += runTest( *it );
|
||||
|
||||
testGroupEnded( testSpec, totals, groupIndex, groupsCount );
|
||||
return totals;
|
||||
}
|
||||
|
||||
Totals runTest( TestCase const& testCase ) {
|
||||
Totals prevTotals = m_totals;
|
||||
|
||||
|
@ -40,6 +40,7 @@ namespace Catch {
|
||||
std::string tagsAsString;
|
||||
SourceLineInfo lineInfo;
|
||||
bool isHidden;
|
||||
bool throws;
|
||||
};
|
||||
|
||||
class TestCase : protected TestCaseInfo {
|
||||
@ -55,6 +56,7 @@ namespace Catch {
|
||||
TestCaseInfo const& getTestCaseInfo() const;
|
||||
|
||||
bool isHidden() const;
|
||||
bool throws() const;
|
||||
bool hasTag( std::string const& tag ) const;
|
||||
bool matchesTags( std::string const& tagPattern ) const;
|
||||
std::set<std::string> const& getTags() const;
|
||||
|
@ -15,6 +15,16 @@
|
||||
|
||||
namespace Catch {
|
||||
|
||||
inline bool isSpecialTag( std::string const& tag ) {
|
||||
return tag == "." ||
|
||||
tag == "hide" ||
|
||||
tag == "!hide" ||
|
||||
tag == "!throws";
|
||||
}
|
||||
inline bool isReservedTag( std::string const& tag ) {
|
||||
return !isSpecialTag( tag ) && tag.size() > 0 && !isalnum( tag[0] );
|
||||
}
|
||||
|
||||
TestCase makeTestCase( ITestCase* _testCase,
|
||||
std::string const& _className,
|
||||
std::string const& _name,
|
||||
@ -25,6 +35,23 @@ namespace Catch {
|
||||
bool isHidden( startsWith( _name, "./" ) ); // Legacy support
|
||||
std::set<std::string> tags;
|
||||
TagExtracter( tags ).parse( desc );
|
||||
for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end();
|
||||
it != itEnd;
|
||||
++it )
|
||||
if( isReservedTag( *it ) ) {
|
||||
{
|
||||
Colour colourGuard( Colour::Red );
|
||||
std::cerr
|
||||
<< "Tag name [" << *it << "] not allowed.\n"
|
||||
<< "Tag names starting with non alpha-numeric characters are reserved\n";
|
||||
}
|
||||
{
|
||||
Colour colourGuard( Colour::FileName );
|
||||
std::cerr << _lineInfo << std::endl;
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if( tags.find( "hide" ) != tags.end() || tags.find( "." ) != tags.end() )
|
||||
isHidden = true;
|
||||
|
||||
@ -47,11 +74,15 @@ namespace Catch {
|
||||
description( _description ),
|
||||
tags( _tags ),
|
||||
lineInfo( _lineInfo ),
|
||||
isHidden( _isHidden )
|
||||
isHidden( _isHidden ),
|
||||
throws( false )
|
||||
{
|
||||
std::ostringstream oss;
|
||||
for( std::set<std::string>::const_iterator it = _tags.begin(), itEnd = _tags.end(); it != itEnd; ++it )
|
||||
for( std::set<std::string>::const_iterator it = _tags.begin(), itEnd = _tags.end(); it != itEnd; ++it ) {
|
||||
oss << "[" << *it << "]";
|
||||
if( *it == "!throws" )
|
||||
throws = true;
|
||||
}
|
||||
tagsAsString = oss.str();
|
||||
}
|
||||
|
||||
@ -62,7 +93,8 @@ namespace Catch {
|
||||
tags( other.tags ),
|
||||
tagsAsString( other.tagsAsString ),
|
||||
lineInfo( other.lineInfo ),
|
||||
isHidden( other.isHidden )
|
||||
isHidden( other.isHidden ),
|
||||
throws( other.throws )
|
||||
{}
|
||||
|
||||
TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
|
||||
@ -85,6 +117,9 @@ namespace Catch {
|
||||
bool TestCase::isHidden() const {
|
||||
return TestCaseInfo::isHidden;
|
||||
}
|
||||
bool TestCase::throws() const {
|
||||
return TestCaseInfo::throws;
|
||||
}
|
||||
|
||||
bool TestCase::hasTag( std::string const& tag ) const {
|
||||
return tags.find( toLower( tag ) ) != tags.end();
|
||||
|
@ -41,9 +41,12 @@ namespace Catch {
|
||||
}
|
||||
else {
|
||||
TestCase const& prev = *m_functions.find( testCase );
|
||||
{
|
||||
Colour colourGuard( Colour::Red );
|
||||
std::cerr << "error: TEST_CASE( \"" << name << "\" ) already defined.\n"
|
||||
<< "\tFirst seen at " << prev.getTestCaseInfo().lineInfo << "\n"
|
||||
<< "\tRedefined at " << testCase.getTestCaseInfo().lineInfo << std::endl;
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@ -56,32 +59,24 @@ namespace Catch {
|
||||
return m_nonHiddenFunctions;
|
||||
}
|
||||
|
||||
// !TBD deprecated
|
||||
virtual std::vector<TestCase> getMatchingTestCases( std::string const& rawTestSpec ) const {
|
||||
std::vector<TestCase> matchingTests;
|
||||
getMatchingTestCases( rawTestSpec, matchingTests );
|
||||
return matchingTests;
|
||||
virtual void getFilteredTests( TestCaseFilters const& filters, 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() ) )
|
||||
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 );
|
||||
|
||||
// !TBD deprecated
|
||||
virtual void getMatchingTestCases( std::string const& rawTestSpec, std::vector<TestCase>& matchingTestsOut ) const {
|
||||
TestCaseFilter filter( rawTestSpec );
|
||||
|
||||
std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin();
|
||||
std::vector<TestCase>::const_iterator itEnd = m_functionsInOrder.end();
|
||||
for(; it != itEnd; ++it ) {
|
||||
if( filter.shouldInclude( *it ) ) {
|
||||
matchingTestsOut.push_back( *it );
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void getMatchingTestCases( TestCaseFilters const& filters, std::vector<TestCase>& matchingTestsOut ) const {
|
||||
std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin();
|
||||
std::vector<TestCase>::const_iterator itEnd = m_functionsInOrder.end();
|
||||
// !TBD: replace with algorithm
|
||||
for(; it != itEnd; ++it )
|
||||
if( filters.shouldInclude( *it ) )
|
||||
matchingTestsOut.push_back( *it );
|
||||
for( std::vector<TestCaseFilters>::const_iterator it = config.filters().begin(),
|
||||
itEnd = config.filters().end();
|
||||
it != itEnd;
|
||||
++it )
|
||||
getFilteredTests( *it, config, matchingTestCases );
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -13,7 +13,7 @@
|
||||
namespace Catch {
|
||||
|
||||
// These numbers are maintained by a script
|
||||
Version libraryVersion( 1, 0, 35, "master" );
|
||||
Version libraryVersion( 1, 0, 36, "master" );
|
||||
}
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED
|
||||
|
@ -774,5 +774,5 @@ with expansion:
|
||||
"first" == "second"
|
||||
|
||||
===============================================================================
|
||||
124 test cases - 38 failed (660 assertions - 93 failed)
|
||||
125 test cases - 38 failed (660 assertions - 93 failed)
|
||||
|
||||
|
@ -3650,6 +3650,15 @@ MiscTests.cpp:<line number>: FAILED:
|
||||
explicitly with message:
|
||||
to infinity and beyond
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
not allowed
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
|
||||
No assertions in test case 'not allowed'
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Process can be configured on command line
|
||||
default - no arguments
|
||||
@ -6982,5 +6991,5 @@ with expansion:
|
||||
true
|
||||
|
||||
===============================================================================
|
||||
124 test cases - 53 failed (679 assertions - 112 failed)
|
||||
125 test cases - 54 failed (680 assertions - 113 failed)
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<testsuites>
|
||||
<testsuite name="~_" errors="12" failures="100" tests="679" hostname="tbd" time="{duration}" timestamp="tbd">
|
||||
<testsuite name="~_" errors="12" failures="101" tests="680" hostname="tbd" time="{duration}" timestamp="tbd">
|
||||
<testcase classname="global" name="Some simple comparisons between doubles" time="{duration}"/>
|
||||
<testcase classname="global" name="Approximate comparisons with different epsilons" time="{duration}"/>
|
||||
<testcase classname="global" name="Approximate comparisons with floats" time="{duration}"/>
|
||||
|
@ -3723,6 +3723,9 @@
|
||||
</Failure>
|
||||
<OverallResult success="false"/>
|
||||
</TestCase>
|
||||
<TestCase name="not allowed">
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Process can be configured on command line">
|
||||
<Section name="default - no arguments">
|
||||
<Expression success="true" filename="/Users/philnash/Dev/OSS/Catch/projects/SelfTest/TestMain.cpp" >
|
||||
@ -7242,7 +7245,7 @@ there"
|
||||
</Section>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<OverallResults successes="567" failures="112"/>
|
||||
<OverallResults successes="567" failures="113"/>
|
||||
</Group>
|
||||
<OverallResults successes="567" failures="112"/>
|
||||
<OverallResults successes="567" failures="113"/>
|
||||
</Catch>
|
||||
|
@ -333,3 +333,9 @@ TEST_CASE("A couple of nested sections followed by a failure", "[failing][.]")
|
||||
|
||||
FAIL("to infinity and beyond");
|
||||
}
|
||||
|
||||
TEST_CASE("not allowed", "[!throws]")
|
||||
{
|
||||
// This test case should not be included if you run with -e on the command line
|
||||
SUCCEED();
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CATCH v1.0 build 35 (master branch)
|
||||
* Generated: 2014-04-12 19:20:39.856403
|
||||
* CATCH v1.0 build 36 (master branch)
|
||||
* Generated: 2014-04-15 18:42:33.686099
|
||||
* ----------------------------------------------------------
|
||||
* This file has been merged from multiple headers. Please don't edit it directly
|
||||
* Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
|
||||
@ -420,11 +420,14 @@ namespace Catch {
|
||||
};
|
||||
|
||||
class TestCase;
|
||||
struct IConfig;
|
||||
|
||||
struct ITestCaseRegistry {
|
||||
virtual ~ITestCaseRegistry();
|
||||
virtual std::vector<TestCase> const& getAllTests() const = 0;
|
||||
virtual std::vector<TestCase> getMatchingTestCases( std::string const& rawTestSpec ) 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;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@ -1497,6 +1500,7 @@ namespace Catch {
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@ -1517,6 +1521,8 @@ namespace Catch {
|
||||
Never
|
||||
}; };
|
||||
|
||||
class TestCaseFilters;
|
||||
|
||||
struct IConfig : IShared {
|
||||
|
||||
virtual ~IConfig();
|
||||
@ -1529,6 +1535,7 @@ namespace Catch {
|
||||
virtual bool warnAboutMissingAssertions() const = 0;
|
||||
virtual int abortAfter() const = 0;
|
||||
virtual ShowDurations::OrNot showDurations() const = 0;
|
||||
virtual std::vector<TestCaseFilters> const& filters() const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
@ -2411,6 +2418,7 @@ namespace Catch {
|
||||
std::string tagsAsString;
|
||||
SourceLineInfo lineInfo;
|
||||
bool isHidden;
|
||||
bool throws;
|
||||
};
|
||||
|
||||
class TestCase : protected TestCaseInfo {
|
||||
@ -2426,6 +2434,7 @@ namespace Catch {
|
||||
TestCaseInfo const& getTestCaseInfo() const;
|
||||
|
||||
bool isHidden() const;
|
||||
bool throws() const;
|
||||
bool hasTag( std::string const& tag ) const;
|
||||
bool matchesTags( std::string const& tagPattern ) const;
|
||||
std::set<std::string> const& getTags() const;
|
||||
@ -4221,7 +4230,7 @@ namespace Catch {
|
||||
static void use( Code _colourCode );
|
||||
|
||||
private:
|
||||
static Detail::IColourImpl* impl;
|
||||
static Detail::IColourImpl* impl();
|
||||
};
|
||||
|
||||
} // end namespace Catch
|
||||
@ -4505,14 +4514,6 @@ namespace Catch
|
||||
#include <algorithm>
|
||||
|
||||
namespace Catch {
|
||||
inline bool matchesFilters( std::vector<TestCaseFilters> const& filters, TestCase const& testCase ) {
|
||||
std::vector<TestCaseFilters>::const_iterator it = filters.begin();
|
||||
std::vector<TestCaseFilters>::const_iterator itEnd = filters.end();
|
||||
for(; it != itEnd; ++it )
|
||||
if( !it->shouldInclude( testCase ) )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline std::size_t listTests( Config const& config ) {
|
||||
if( config.filters().empty() )
|
||||
@ -4525,11 +4526,11 @@ namespace Catch {
|
||||
nameAttr.setInitialIndent( 2 ).setIndent( 4 );
|
||||
tagsAttr.setIndent( 6 );
|
||||
|
||||
std::vector<TestCase> const& allTests = getRegistryHub().getTestCaseRegistry().getAllTests();
|
||||
for( std::vector<TestCase>::const_iterator it = allTests.begin(), itEnd = allTests.end();
|
||||
std::vector<TestCase> matchedTestCases;
|
||||
getRegistryHub().getTestCaseRegistry().getFilteredTests( config, matchedTestCases );
|
||||
for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
|
||||
it != itEnd;
|
||||
++it )
|
||||
if( matchesFilters( config.filters(), *it ) ) {
|
||||
++it ) {
|
||||
matchedTests++;
|
||||
TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
|
||||
Colour::Code colour = testCaseInfo.isHidden
|
||||
@ -4551,11 +4552,11 @@ namespace Catch {
|
||||
|
||||
inline std::size_t listTestsNamesOnly( Config const& config ) {
|
||||
std::size_t matchedTests = 0;
|
||||
std::vector<TestCase> const& allTests = getRegistryHub().getTestCaseRegistry().getAllTests();
|
||||
for( std::vector<TestCase>::const_iterator it = allTests.begin(), itEnd = allTests.end();
|
||||
std::vector<TestCase> matchedTestCases;
|
||||
getRegistryHub().getTestCaseRegistry().getFilteredTests( config, matchedTestCases );
|
||||
for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
|
||||
it != itEnd;
|
||||
++it )
|
||||
if( matchesFilters( config.filters(), *it ) ) {
|
||||
++it ) {
|
||||
matchedTests++;
|
||||
TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
|
||||
std::cout << testCaseInfo.name << std::endl;
|
||||
@ -4571,12 +4572,11 @@ namespace Catch {
|
||||
|
||||
std::map<std::string, int> tagCounts;
|
||||
|
||||
std::vector<TestCase> const& allTests = getRegistryHub().getTestCaseRegistry().getAllTests();
|
||||
for( std::vector<TestCase>::const_iterator it = allTests.begin(),
|
||||
itEnd = allTests.end();
|
||||
std::vector<TestCase> matchedTestCases;
|
||||
getRegistryHub().getTestCaseRegistry().getFilteredTests( config, matchedTestCases );
|
||||
for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
|
||||
it != itEnd;
|
||||
++it ) {
|
||||
if( matchesFilters( config.filters(), *it ) ) {
|
||||
for( std::set<std::string>::const_iterator tagIt = it->getTestCaseInfo().tags.begin(),
|
||||
tagItEnd = it->getTestCaseInfo().tags.end();
|
||||
tagIt != tagItEnd;
|
||||
@ -4589,7 +4589,6 @@ namespace Catch {
|
||||
countIt->second++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( std::map<std::string, int>::const_iterator countIt = tagCounts.begin(),
|
||||
countItEnd = tagCounts.end();
|
||||
@ -4856,23 +4855,6 @@ namespace Catch {
|
||||
m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
|
||||
}
|
||||
|
||||
Totals runMatching( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
|
||||
|
||||
std::vector<TestCase> matchingTests = getRegistryHub().getTestCaseRegistry().getMatchingTestCases( testSpec );
|
||||
|
||||
Totals totals;
|
||||
|
||||
testGroupStarting( testSpec, groupIndex, groupsCount );
|
||||
|
||||
std::vector<TestCase>::const_iterator it = matchingTests.begin();
|
||||
std::vector<TestCase>::const_iterator itEnd = matchingTests.end();
|
||||
for(; it != itEnd; ++it )
|
||||
totals += runTest( *it );
|
||||
|
||||
testGroupEnded( testSpec, totals, groupIndex, groupsCount );
|
||||
return totals;
|
||||
}
|
||||
|
||||
Totals runTest( TestCase const& testCase ) {
|
||||
Totals prevTotals = m_totals;
|
||||
|
||||
@ -5165,14 +5147,16 @@ namespace Catch {
|
||||
}
|
||||
return totals;
|
||||
}
|
||||
|
||||
Totals runTestsForGroup( RunContext& context, const TestCaseFilters& filterGroup ) {
|
||||
Totals runTestsForGroup( RunContext& context, TestCaseFilters const& filterGroup ) {
|
||||
Totals totals;
|
||||
std::vector<TestCase>::const_iterator it = getRegistryHub().getTestCaseRegistry().getAllTests().begin();
|
||||
std::vector<TestCase>::const_iterator itEnd = getRegistryHub().getTestCaseRegistry().getAllTests().end();
|
||||
|
||||
std::vector<TestCase> testCases;
|
||||
getRegistryHub().getTestCaseRegistry().getFilteredTests( filterGroup, *m_config, testCases );
|
||||
|
||||
int testsRunForGroup = 0;
|
||||
for(; it != itEnd; ++it ) {
|
||||
if( filterGroup.shouldInclude( *it ) ) {
|
||||
for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();
|
||||
it != itEnd;
|
||||
++it ) {
|
||||
testsRunForGroup++;
|
||||
if( m_testsAlreadyRun.find( *it ) == m_testsAlreadyRun.end() ) {
|
||||
|
||||
@ -5183,11 +5167,9 @@ namespace Catch {
|
||||
m_testsAlreadyRun.insert( *it );
|
||||
}
|
||||
}
|
||||
}
|
||||
if( testsRunForGroup == 0 && !filterGroup.getName().empty() )
|
||||
m_reporter->noMatchingTestCases( filterGroup.getName() );
|
||||
return totals;
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
@ -5370,9 +5352,12 @@ namespace Catch {
|
||||
}
|
||||
else {
|
||||
TestCase const& prev = *m_functions.find( testCase );
|
||||
{
|
||||
Colour colourGuard( Colour::Red );
|
||||
std::cerr << "error: TEST_CASE( \"" << name << "\" ) already defined.\n"
|
||||
<< "\tFirst seen at " << prev.getTestCaseInfo().lineInfo << "\n"
|
||||
<< "\tRedefined at " << testCase.getTestCaseInfo().lineInfo << std::endl;
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@ -5385,32 +5370,24 @@ namespace Catch {
|
||||
return m_nonHiddenFunctions;
|
||||
}
|
||||
|
||||
// !TBD deprecated
|
||||
virtual std::vector<TestCase> getMatchingTestCases( std::string const& rawTestSpec ) const {
|
||||
std::vector<TestCase> matchingTests;
|
||||
getMatchingTestCases( rawTestSpec, matchingTests );
|
||||
return matchingTests;
|
||||
virtual void getFilteredTests( TestCaseFilters const& filters, 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() ) )
|
||||
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 );
|
||||
|
||||
// !TBD deprecated
|
||||
virtual void getMatchingTestCases( std::string const& rawTestSpec, std::vector<TestCase>& matchingTestsOut ) const {
|
||||
TestCaseFilter filter( rawTestSpec );
|
||||
|
||||
std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin();
|
||||
std::vector<TestCase>::const_iterator itEnd = m_functionsInOrder.end();
|
||||
for(; it != itEnd; ++it ) {
|
||||
if( filter.shouldInclude( *it ) ) {
|
||||
matchingTestsOut.push_back( *it );
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void getMatchingTestCases( TestCaseFilters const& filters, std::vector<TestCase>& matchingTestsOut ) const {
|
||||
std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin();
|
||||
std::vector<TestCase>::const_iterator itEnd = m_functionsInOrder.end();
|
||||
// !TBD: replace with algorithm
|
||||
for(; it != itEnd; ++it )
|
||||
if( filters.shouldInclude( *it ) )
|
||||
matchingTestsOut.push_back( *it );
|
||||
for( std::vector<TestCaseFilters>::const_iterator it = config.filters().begin(),
|
||||
itEnd = config.filters().end();
|
||||
it != itEnd;
|
||||
++it )
|
||||
getFilteredTests( *it, config, matchingTestCases );
|
||||
}
|
||||
|
||||
private:
|
||||
@ -5909,7 +5886,10 @@ namespace {
|
||||
return true;
|
||||
}
|
||||
|
||||
Win32ColourImpl platformColourImpl;
|
||||
static Detail::IColourImpl* platformColourInstance() {
|
||||
static Win32ColourImpl s_instance;
|
||||
return &s_instance;
|
||||
}
|
||||
|
||||
} // end anon namespace
|
||||
} // end namespace Catch
|
||||
@ -5956,7 +5936,10 @@ namespace {
|
||||
return isatty(STDOUT_FILENO);
|
||||
}
|
||||
|
||||
PosixColourImpl platformColourImpl;
|
||||
static Detail::IColourImpl* platformColourInstance() {
|
||||
static PosixColourImpl s_instance;
|
||||
return &s_instance;
|
||||
}
|
||||
|
||||
} // end anon namespace
|
||||
} // end namespace Catch
|
||||
@ -5968,21 +5951,28 @@ namespace Catch {
|
||||
namespace {
|
||||
struct NoColourImpl : Detail::IColourImpl {
|
||||
void use( Colour::Code ) {}
|
||||
|
||||
static IColourImpl* instance() {
|
||||
static NoColourImpl s_instance;
|
||||
return &s_instance;
|
||||
}
|
||||
};
|
||||
NoColourImpl noColourImpl;
|
||||
static const bool shouldUseColour = shouldUseColourForPlatform() &&
|
||||
!isDebuggerActive();
|
||||
static bool shouldUseColour() {
|
||||
return shouldUseColourForPlatform() && !isDebuggerActive();
|
||||
}
|
||||
}
|
||||
|
||||
Colour::Colour( Code _colourCode ){ use( _colourCode ); }
|
||||
Colour::~Colour(){ use( None ); }
|
||||
void Colour::use( Code _colourCode ) {
|
||||
impl->use( _colourCode );
|
||||
impl()->use( _colourCode );
|
||||
}
|
||||
|
||||
Detail::IColourImpl* Colour::impl = shouldUseColour
|
||||
? static_cast<Detail::IColourImpl*>( &platformColourImpl )
|
||||
: static_cast<Detail::IColourImpl*>( &noColourImpl );
|
||||
Detail::IColourImpl* Colour::impl() {
|
||||
return shouldUseColour()
|
||||
? platformColourInstance()
|
||||
: NoColourImpl::instance();
|
||||
}
|
||||
|
||||
} // end namespace Catch
|
||||
|
||||
@ -6233,6 +6223,16 @@ namespace Catch {
|
||||
|
||||
namespace Catch {
|
||||
|
||||
inline bool isSpecialTag( std::string const& tag ) {
|
||||
return tag == "." ||
|
||||
tag == "hide" ||
|
||||
tag == "!hide" ||
|
||||
tag == "!throws";
|
||||
}
|
||||
inline bool isReservedTag( std::string const& tag ) {
|
||||
return !isSpecialTag( tag ) && tag.size() > 0 && !isalnum( tag[0] );
|
||||
}
|
||||
|
||||
TestCase makeTestCase( ITestCase* _testCase,
|
||||
std::string const& _className,
|
||||
std::string const& _name,
|
||||
@ -6243,6 +6243,23 @@ namespace Catch {
|
||||
bool isHidden( startsWith( _name, "./" ) ); // Legacy support
|
||||
std::set<std::string> tags;
|
||||
TagExtracter( tags ).parse( desc );
|
||||
for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end();
|
||||
it != itEnd;
|
||||
++it )
|
||||
if( isReservedTag( *it ) ) {
|
||||
{
|
||||
Colour colourGuard( Colour::Red );
|
||||
std::cerr
|
||||
<< "Tag name [" << *it << "] not allowed.\n"
|
||||
<< "Tag names starting with non alpha-numeric characters are reserved\n";
|
||||
}
|
||||
{
|
||||
Colour colourGuard( Colour::FileName );
|
||||
std::cerr << _lineInfo << std::endl;
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if( tags.find( "hide" ) != tags.end() || tags.find( "." ) != tags.end() )
|
||||
isHidden = true;
|
||||
|
||||
@ -6265,11 +6282,15 @@ namespace Catch {
|
||||
description( _description ),
|
||||
tags( _tags ),
|
||||
lineInfo( _lineInfo ),
|
||||
isHidden( _isHidden )
|
||||
isHidden( _isHidden ),
|
||||
throws( false )
|
||||
{
|
||||
std::ostringstream oss;
|
||||
for( std::set<std::string>::const_iterator it = _tags.begin(), itEnd = _tags.end(); it != itEnd; ++it )
|
||||
for( std::set<std::string>::const_iterator it = _tags.begin(), itEnd = _tags.end(); it != itEnd; ++it ) {
|
||||
oss << "[" << *it << "]";
|
||||
if( *it == "!throws" )
|
||||
throws = true;
|
||||
}
|
||||
tagsAsString = oss.str();
|
||||
}
|
||||
|
||||
@ -6280,7 +6301,8 @@ namespace Catch {
|
||||
tags( other.tags ),
|
||||
tagsAsString( other.tagsAsString ),
|
||||
lineInfo( other.lineInfo ),
|
||||
isHidden( other.isHidden )
|
||||
isHidden( other.isHidden ),
|
||||
throws( other.throws )
|
||||
{}
|
||||
|
||||
TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
|
||||
@ -6303,6 +6325,9 @@ namespace Catch {
|
||||
bool TestCase::isHidden() const {
|
||||
return TestCaseInfo::isHidden;
|
||||
}
|
||||
bool TestCase::throws() const {
|
||||
return TestCaseInfo::throws;
|
||||
}
|
||||
|
||||
bool TestCase::hasTag( std::string const& tag ) const {
|
||||
return tags.find( toLower( tag ) ) != tags.end();
|
||||
@ -6598,7 +6623,7 @@ namespace Catch {
|
||||
namespace Catch {
|
||||
|
||||
// These numbers are maintained by a script
|
||||
Version libraryVersion( 1, 0, 35, "master" );
|
||||
Version libraryVersion( 1, 0, 36, "master" );
|
||||
}
|
||||
|
||||
// #included from: catch_message.hpp
|
||||
|
Loading…
Reference in New Issue
Block a user