Compare commits

...

24 Commits

Author SHA1 Message Date
Phil Nash
ebf9f3bb9d v1.5.3 2016-05-10 19:09:59 +01:00
Phil Nash
1ebebd4ab8 Merge branch 'rcdailey-throw-on-duplicate-tests' 2016-05-10 19:07:07 +01:00
Phil Nash
b57e734eb4 Merge branch 'throw-on-duplicate-tests' of git://github.com/rcdailey/Catch into rcdailey-throw-on-duplicate-tests 2016-05-10 19:06:47 +01:00
Phil Nash
5aa2b82b17 Merge pull request #656 from daniel-j-h/better_travis
Pins LLVM 3.8 (stable) instead of tracking the nightly repository
2016-05-07 23:19:26 +01:00
Phil Nash
5c198d85e6 v1.5.2 2016-05-07 23:14:04 +01:00
Phil Nash
5a6b291878 Using Clara 0.0.2.4 - fixes issue with spaces in quoted arguments 2016-05-07 23:12:46 +01:00
Daniel J. Hofmann
1706dd4f11 Pins LLVM 3.8 (stable) instead of tracking the nightly repository 2016-05-07 18:55:12 +02:00
Phil Nash
92b141ee53 v1.5.1 2016-04-28 08:13:00 +01:00
Phil Nash
4f1263d6b4 Removed use of dynamic_cast from test_case_tracker.
(Thanks to #631 and #648)
2016-04-28 08:11:12 +01:00
Phil Nash
3b19458fed Removed use of dynamic_cast for MultipleReporters
(Thanks to #630, #636 and #648)
2016-04-28 08:11:12 +01:00
Phil Nash
e5537842d0 Regenerated single include
(forgot for previously tagged release)
2016-04-25 18:56:50 +01:00
Phil Nash
0fe303b6b7 v1.5.0 (due to new embedded Clara) 2016-04-23 13:25:51 +01:00
Phil Nash
1c47fe023a Updated embedded Clara to 0.0.2.3
- has all new, more robust, token parsing.
- eliminates issue with unreachable code
- allows use of forward slashes to introduce short args on Windows
2016-04-23 13:21:29 +01:00
Phil Nash
6f3bc629be Merge branch 'AzCopey-hotfix/override-warning' 2016-04-23 13:14:08 +01:00
Phil Nash
6de7142d1f Merge pull request #634 from rafaeleyng/patch-1
Update tutorial.md
2016-04-05 18:23:22 +01:00
Rafael Eyng
7544644bb4 Update tutorial.md
Closes #633
2016-04-04 23:04:45 -03:00
Robert Dailey
86c0ea2999 [#608] Don't use exit() on duplicate test descriptions
Instead of `exit(1)`, it now throws `std::runtime_error` with the details
of the failure. This exception is handled in `run()` at a higher level where
the log is printed to cerr and the test gracefully exits.
2016-04-01 11:56:51 -05:00
Ian Copland
7075b7defb Added missing CATCH_OVERRIDE to CumulativeReporterBase::assertionEnded(). This fixes a warning when building in Xcode 7.2+ with default warning settings. 2016-03-29 17:03:09 +01:00
Phil Nash
c984fc3ecd v1.4.0
- use __COUNTER__ for unique IDS instead of __LINE__ (where possible)
+ bug fixes
2016-03-15 07:24:26 +00:00
Phil Nash
447f53e9e3 Fixed !shouldfail 2016-03-14 19:13:34 +00:00
Phil Nash
13a887ad24 Use __COUNTER__ when generating unique names instead of __LINE__, if available.
Based on PR #351
2016-03-14 07:55:00 +00:00
Phil Nash
02af70ed0b build v1.3.6 (include's David Grayson's fix for the gcc pragma) 2016-03-11 18:31:52 +00:00
Phil Nash
c362894565 Merge branch 'DavidEGrayson-pr_gcc_pragma_typo' 2016-03-11 07:59:20 +00:00
David Grayson
97e335437e Fix CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS: GCC needs to be capitalized.
Fixes issue #600.
2016-03-04 19:24:10 -08:00
26 changed files with 532 additions and 246 deletions

View File

@@ -64,7 +64,7 @@ matrix:
compiler: clang
addons: &clang38
apt:
sources: ['llvm-toolchain-precise', 'ubuntu-toolchain-r-test']
sources: ['llvm-toolchain-precise-3.8', 'ubuntu-toolchain-r-test']
packages: ['clang-3.8']
env: COMPILER='ccache clang++-3.8' BUILD_TYPE='Release'

View File

@@ -1,6 +1,6 @@
![catch logo](catch-logo-small.png)
*v1.3.5*
*v1.5.3*
Build status (on Travis CI) [![Build Status](https://travis-ci.org/philsquared/Catch.png)](https://travis-ci.org/philsquared/Catch)

View File

@@ -1,6 +1,6 @@
# Getting Catch
The simplest way to get Catch is to download the single header version from [http://builds.catch-lib.net](http://builds.catch-lib.net). Don't be put off by the word "builds" there. The single header is generated by merging a set of individual headers but it is still just normal source code in a header file.
The simplest way to get Catch is to download the latest [single header version](https://raw.githubusercontent.com/philsquared/Catch/master/single_include/catch.hpp). The single header is generated by merging a set of individual headers but it is still just normal source code in a header file.
The full source for Catch, including test projects, documentation, and other things, is hosted on GitHub. [http://catch-lib.net](http://catch-lib.net) will redirect you there.

View File

@@ -131,10 +131,10 @@ namespace Catch {
Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
}
int applyCommandLine( int argc, char const* argv[], OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
int applyCommandLine( int argc, char const* const* const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
try {
m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
m_unusedTokens = m_cli.parseInto( argc, argv, m_configData );
m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData );
if( m_configData.showHelp )
showHelp( m_configData.processName );
m_config.reset();
@@ -158,16 +158,13 @@ namespace Catch {
m_config.reset();
}
int run( int argc, char const* argv[] ) {
int run( int argc, char const* const* const argv ) {
int returnCode = applyCommandLine( argc, argv );
if( returnCode == 0 )
returnCode = run();
return returnCode;
}
int run( int argc, char* argv[] ) {
return run( argc, const_cast<char const**>( argv ) );
}
int run() {
if( m_configData.showHelp )

View File

@@ -6,7 +6,7 @@
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
// Version 0.0.1.1
// Version 0.0.2.4
// Only use header guard if we are not using an outer namespace
#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
@@ -343,6 +343,11 @@ namespace Tbc {
#include <stdexcept>
#include <memory>
#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
#define CLARA_PLATFORM_WINDOWS
#endif
// Use optional outer namespace
#ifdef STITCH_CLARA_OPEN_NAMESPACE
STITCH_CLARA_OPEN_NAMESPACE
@@ -366,9 +371,6 @@ namespace Clara {
const unsigned int consoleWidth = 80;
#endif
// Use this to try and stop compiler from warning about unreachable code
inline bool isTrue( bool value ) { return value; }
using namespace Tbc;
inline bool startsWith( std::string const& str, std::string const& prefix ) {
@@ -404,14 +406,7 @@ namespace Clara {
else
throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" );
}
inline void convertInto( bool _source, bool& _dest ) {
_dest = _source;
}
template<typename T>
inline void convertInto( bool, T& ) {
if( isTrue( true ) )
throw std::runtime_error( "Invalid conversion" );
}
template<typename ConfigT>
struct IArgFunction {
@@ -421,7 +416,6 @@ namespace Clara {
IArgFunction( IArgFunction const& ) = default;
#endif
virtual void set( ConfigT& config, std::string const& value ) const = 0;
virtual void setFlag( ConfigT& config ) const = 0;
virtual bool takesArg() const = 0;
virtual IArgFunction* clone() const = 0;
};
@@ -443,9 +437,6 @@ namespace Clara {
void set( ConfigT& config, std::string const& value ) const {
functionObj->set( config, value );
}
void setFlag( ConfigT& config ) const {
functionObj->setFlag( config );
}
bool takesArg() const { return functionObj->takesArg(); }
bool isSet() const {
@@ -459,7 +450,6 @@ namespace Clara {
template<typename C>
struct NullBinder : IArgFunction<C>{
virtual void set( C&, std::string const& ) const {}
virtual void setFlag( C& ) const {}
virtual bool takesArg() const { return true; }
virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
};
@@ -470,9 +460,6 @@ namespace Clara {
virtual void set( C& p, std::string const& stringValue ) const {
convertInto( stringValue, p.*member );
}
virtual void setFlag( C& p ) const {
convertInto( true, p.*member );
}
virtual bool takesArg() const { return !IsBool<M>::value; }
virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
M C::* member;
@@ -485,11 +472,6 @@ namespace Clara {
convertInto( stringValue, value );
(p.*member)( value );
}
virtual void setFlag( C& p ) const {
typename RemoveConstRef<M>::type value;
convertInto( true, value );
(p.*member)( value );
}
virtual bool takesArg() const { return !IsBool<M>::value; }
virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
void (C::*member)( M );
@@ -503,9 +485,6 @@ namespace Clara {
if( value )
(p.*member)();
}
virtual void setFlag( C& p ) const {
(p.*member)();
}
virtual bool takesArg() const { return false; }
virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
void (C::*member)();
@@ -520,9 +499,6 @@ namespace Clara {
if( value )
function( obj );
}
virtual void setFlag( C& p ) const {
function( p );
}
virtual bool takesArg() const { return false; }
virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
void (*function)( C& );
@@ -536,11 +512,6 @@ namespace Clara {
convertInto( stringValue, value );
function( obj, value );
}
virtual void setFlag( C& obj ) const {
typename RemoveConstRef<T>::type value;
convertInto( true, value );
function( obj, value );
}
virtual bool takesArg() const { return !IsBool<T>::value; }
virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
void (*function)( C&, T );
@@ -548,8 +519,20 @@ namespace Clara {
} // namespace Detail
struct Parser {
Parser() : separators( " \t=:" ) {}
inline std::vector<std::string> argsToVector( int argc, char const* const* const argv ) {
std::vector<std::string> args( static_cast<std::size_t>( argc ) );
for( std::size_t i = 0; i < static_cast<std::size_t>( argc ); ++i )
args[i] = argv[i];
return args;
}
class Parser {
enum Mode { None, MaybeShortOpt, SlashOpt, ShortOpt, LongOpt, Positional };
Mode mode;
std::size_t from;
bool inQuotes;
public:
struct Token {
enum Type { Positional, ShortOpt, LongOpt };
@@ -558,38 +541,75 @@ namespace Clara {
std::string data;
};
void parseIntoTokens( int argc, char const* const argv[], std::vector<Parser::Token>& tokens ) const {
Parser() : mode( None ), from( 0 ), inQuotes( false ){}
void parseIntoTokens( std::vector<std::string> const& args, std::vector<Token>& tokens ) {
const std::string doubleDash = "--";
for( int i = 1; i < argc && argv[i] != doubleDash; ++i )
parseIntoTokens( argv[i] , tokens);
for( std::size_t i = 1; i < args.size() && args[i] != doubleDash; ++i )
parseIntoTokens( args[i], tokens);
}
void parseIntoTokens( std::string arg, std::vector<Parser::Token>& tokens ) const {
while( !arg.empty() ) {
Parser::Token token( Parser::Token::Positional, arg );
arg = "";
if( token.data[0] == '-' ) {
if( token.data.size() > 1 && token.data[1] == '-' ) {
token = Parser::Token( Parser::Token::LongOpt, token.data.substr( 2 ) );
}
else {
token = Parser::Token( Parser::Token::ShortOpt, token.data.substr( 1 ) );
if( token.data.size() > 1 && separators.find( token.data[1] ) == std::string::npos ) {
arg = "-" + token.data.substr( 1 );
token.data = token.data.substr( 0, 1 );
}
}
}
if( token.type != Parser::Token::Positional ) {
std::size_t pos = token.data.find_first_of( separators );
if( pos != std::string::npos ) {
arg = token.data.substr( pos+1 );
token.data = token.data.substr( 0, pos );
}
}
tokens.push_back( token );
void parseIntoTokens( std::string const& arg, std::vector<Token>& tokens ) {
for( std::size_t i = 0; i <= arg.size(); ++i ) {
char c = arg[i];
if( c == '"' )
inQuotes = !inQuotes;
mode = handleMode( i, c, arg, tokens );
}
}
std::string separators;
Mode handleMode( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
switch( mode ) {
case None: return handleNone( i, c );
case MaybeShortOpt: return handleMaybeShortOpt( i, c );
case ShortOpt:
case LongOpt:
case SlashOpt: return handleOpt( i, c, arg, tokens );
case Positional: return handlePositional( i, c, arg, tokens );
default: throw std::logic_error( "Unknown mode" );
}
}
Mode handleNone( std::size_t i, char c ) {
if( inQuotes ) {
from = i;
return Positional;
}
switch( c ) {
case '-': return MaybeShortOpt;
#ifdef CLARA_PLATFORM_WINDOWS
case '/': from = i+1; return SlashOpt;
#endif
default: from = i; return Positional;
}
}
Mode handleMaybeShortOpt( std::size_t i, char c ) {
switch( c ) {
case '-': from = i+1; return LongOpt;
default: from = i; return ShortOpt;
}
}
Mode handleOpt( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
if( std::string( ":=\0", 5 ).find( c ) == std::string::npos )
return mode;
std::string optName = arg.substr( from, i-from );
if( mode == ShortOpt )
for( std::size_t j = 0; j < optName.size(); ++j )
tokens.push_back( Token( Token::ShortOpt, optName.substr( j, 1 ) ) );
else if( mode == SlashOpt && optName.size() == 1 )
tokens.push_back( Token( Token::ShortOpt, optName ) );
else
tokens.push_back( Token( Token::LongOpt, optName ) );
return None;
}
Mode handlePositional( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
if( inQuotes || std::string( "\0", 3 ).find( c ) == std::string::npos )
return mode;
std::string data = arg.substr( from, i-from );
tokens.push_back( Token( Token::Positional, data ) );
return None;
}
};
template<typename ConfigT>
@@ -894,21 +914,21 @@ namespace Clara {
return oss.str();
}
ConfigT parse( int argc, char const* const argv[] ) const {
ConfigT parse( std::vector<std::string> const& args ) const {
ConfigT config;
parseInto( argc, argv, config );
parseInto( args, config );
return config;
}
std::vector<Parser::Token> parseInto( int argc, char const* argv[], ConfigT& config ) const {
std::string processName = argv[0];
std::vector<Parser::Token> parseInto( std::vector<std::string> const& args, ConfigT& config ) const {
std::string processName = args[0];
std::size_t lastSlash = processName.find_last_of( "/\\" );
if( lastSlash != std::string::npos )
processName = processName.substr( lastSlash+1 );
m_boundProcessName.set( config, processName );
std::vector<Parser::Token> tokens;
Parser parser;
parser.parseIntoTokens( argc, argv, tokens );
parser.parseIntoTokens( args, tokens );
return populate( tokens, config );
}
@@ -939,7 +959,7 @@ namespace Clara {
arg.boundField.set( config, tokens[++i].data );
}
else {
arg.boundField.setFlag( config );
arg.boundField.set( config, "true" );
}
break;
}

View File

@@ -10,7 +10,11 @@
#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
#define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
#ifdef CATCH_CONFIG_COUNTER
# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
#else
# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
#endif
#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )

View File

@@ -23,7 +23,7 @@
// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
// ****************
// Note to maintainers: if new toggles are added please document them
// in configuration.md, too
@@ -86,7 +86,7 @@
# endif
# if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) && defined(CATCH_CPP11_OR_GREATER)
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "gcc diagnostic ignored \"-Wparentheses\"" )
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "GCC diagnostic ignored \"-Wparentheses\"" )
# endif
// - otherwise more recent versions define __cplusplus >= 201103L
@@ -123,6 +123,14 @@
#endif
// Use __COUNTER__ if the compiler supports it
#if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \
( defined __GNUC__ && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 ) || \
( defined __clang__ && __clang_major__ >= 3 )
#define CATCH_INTERNAL_CONFIG_COUNTER
#endif
////////////////////////////////////////////////////////////////////////////////
// C++ language feature support
@@ -196,6 +204,9 @@
#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)
# define CATCH_CONFIG_CPP11_UNIQUE_PTR
#endif
#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
# define CATCH_CONFIG_COUNTER
#endif
#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS

View File

@@ -66,9 +66,11 @@ namespace Catch {
}
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) \
static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ); \
namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ) ); }\
static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature )
#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
static std::string translatorName( signature ); \
namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\
static std::string translatorName( signature )
#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
#endif // TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED

View File

@@ -219,6 +219,7 @@ namespace Catch
bool aborting;
};
class MultipleReporters;
struct IStreamingReporter : IShared {
virtual ~IStreamingReporter();
@@ -247,6 +248,8 @@ namespace Catch
virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; }
};

View File

@@ -109,6 +109,11 @@ namespace Catch {
while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
Totals deltaTotals = m_totals.delta( prevTotals );
if( testInfo.expectedToFail() && deltaTotals.testCases.passed > 0 ) {
deltaTotals.assertions.failed++;
deltaTotals.testCases.passed--;
deltaTotals.testCases.failed++;
}
m_totals.testCases += deltaTotals.testCases;
m_reporter->testCaseEnded( TestCaseStats( testInfo,
deltaTotals,

View File

@@ -60,13 +60,15 @@ namespace Catch {
it != itEnd;
++it ) {
std::pair<std::set<TestCase>::const_iterator, bool> prev = seenFunctions.insert( *it );
if( !prev.second ){
Catch::cerr()
<< Colour( Colour::Red )
<< "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n"
<< "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
<< "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl;
exit(1);
if( !prev.second ) {
std::ostringstream ss;
ss << Colour( Colour::Red )
<< "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n"
<< "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
<< "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl;
throw std::runtime_error(ss.str());
}
}
}

View File

@@ -41,6 +41,10 @@ namespace TestCaseTracking {
virtual void addChild( Ptr<ITracker> const& child ) = 0;
virtual ITracker* findChild( std::string const& name ) = 0;
virtual void openChild() = 0;
// Debug/ checking
virtual bool isSectionTracker() const = 0;
virtual bool isIndexTracker() const = 0;
};
class TrackerContext {
@@ -167,6 +171,10 @@ namespace TestCaseTracking {
m_parent->openChild();
}
}
virtual bool isSectionTracker() const CATCH_OVERRIDE { return false; }
virtual bool isIndexTracker() const CATCH_OVERRIDE { return false; }
void open() {
m_runState = Executing;
moveToThis();
@@ -230,13 +238,16 @@ namespace TestCaseTracking {
{}
virtual ~SectionTracker();
virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; }
static SectionTracker& acquire( TrackerContext& ctx, std::string const& name ) {
SectionTracker* section = CATCH_NULL;
ITracker& currentTracker = ctx.currentTracker();
if( ITracker* childTracker = currentTracker.findChild( name ) ) {
section = dynamic_cast<SectionTracker*>( childTracker );
assert( section );
assert( childTracker );
assert( childTracker->isSectionTracker() );
section = static_cast<SectionTracker*>( childTracker );
}
else {
section = new SectionTracker( name, ctx, &currentTracker );
@@ -261,13 +272,16 @@ namespace TestCaseTracking {
{}
virtual ~IndexTracker();
virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; }
static IndexTracker& acquire( TrackerContext& ctx, std::string const& name, int size ) {
IndexTracker* tracker = CATCH_NULL;
ITracker& currentTracker = ctx.currentTracker();
if( ITracker* childTracker = currentTracker.findChild( name ) ) {
tracker = dynamic_cast<IndexTracker*>( childTracker );
assert( tracker );
assert( childTracker );
assert( childTracker->isIndexTracker() );
tracker = static_cast<IndexTracker*>( childTracker );
}
else {
tracker = new IndexTracker( name, ctx, &currentTracker, size );

View File

@@ -85,24 +85,28 @@ void registerTestCaseFunction
#ifdef CATCH_CONFIG_VARIADIC_MACROS
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
static void TestName(); \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
static void TestName()
#define INTERNAL_CATCH_TESTCASE( ... ) \
static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... )\
#define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
namespace{ \
struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
struct TestName : ClassName{ \
void test(); \
}; \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
} \
void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
void TestName::test()
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
@@ -110,24 +114,28 @@ void registerTestCaseFunction
#else
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \
static void TestName(); \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
static void TestName()
#define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
#define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\
namespace{ \
struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
struct TestCaseName : ClassName{ \
void test(); \
}; \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
} \
void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
void TestCaseName::test()
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \

View File

@@ -37,7 +37,7 @@ namespace Catch {
return os;
}
Version libraryVersion( 1, 3, 5, "", 0 );
Version libraryVersion( 1, 5, 3, "", 0 );
}

View File

@@ -166,7 +166,7 @@ namespace Catch {
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
virtual bool assertionEnded( AssertionStats const& assertionStats ) {
virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
assert( !m_sectionStack.empty() );
SectionNode& sectionNode = *m_sectionStack.back();
sectionNode.assertions.push_back( assertionStats );

View File

@@ -349,7 +349,7 @@ namespace Catch {
if( totals.testCases.total() == 0 ) {
stream << Colour( Colour::Warning ) << "No tests ran\n";
}
else if( totals.assertions.total() > 0 && totals.assertions.allPassed() ) {
else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) {
stream << Colour( Colour::ResultSuccess ) << "All tests passed";
stream << " ("
<< pluralise( totals.assertions.passed, "assertion" ) << " in "

View File

@@ -118,13 +118,18 @@ public: // IStreamingReporter
++it )
(*it)->skipTest( testInfo );
}
virtual MultipleReporters* tryAsMulti() CATCH_OVERRIDE {
return this;
}
};
Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter ) {
Ptr<IStreamingReporter> resultingReporter;
if( existingReporter ) {
MultipleReporters* multi = dynamic_cast<MultipleReporters*>( existingReporter.get() );
MultipleReporters* multi = existingReporter->tryAsMulti();
if( !multi ) {
multi = new MultipleReporters;
resultingReporter = Ptr<IStreamingReporter>( multi );

View File

@@ -830,6 +830,6 @@ with expansion:
"first" == "second"
===============================================================================
test cases: 167 | 124 passed | 42 failed | 1 failed as expected
assertions: 919 | 823 passed | 83 failed | 13 failed as expected
test cases: 168 | 124 passed | 42 failed | 2 failed as expected
assertions: 920 | 824 passed | 78 failed | 18 failed as expected

View File

@@ -3951,6 +3951,17 @@ with expansion:
==
9223372036854775807 (0x<hex digits>)
-------------------------------------------------------------------------------
This test 'should' fail but doesn't
-------------------------------------------------------------------------------
MiscTests.cpp:<line number>
...............................................................................
MiscTests.cpp:<line number>:
PASSED:
with message:
oops!
-------------------------------------------------------------------------------
Process can be configured on command line
default - no arguments
@@ -9093,6 +9104,6 @@ with expansion:
1 > 0
===============================================================================
test cases: 167 | 123 passed | 43 failed | 1 failed as expected
assertions: 921 | 823 passed | 85 failed | 13 failed as expected
test cases: 168 | 123 passed | 43 failed | 2 failed as expected
assertions: 922 | 824 passed | 80 failed | 18 failed as expected

View File

@@ -485,7 +485,131 @@ ConditionTests.cpp:<line number>: FAILED:
with expansion:
9.1f != Approx( 9.1000003815 )
===============================================================================
test cases: 19 | 15 passed | 3 failed | 1 failed as expected
assertions: 62 | 56 passed | 4 failed | 2 failed as expected
-------------------------------------------------------------------------------
Ordering comparison checks that should succeed
-------------------------------------------------------------------------------
ConditionTests.cpp:<line number>
...............................................................................
ConditionTests.cpp:<line number>:
PASSED:
REQUIRE( data.int_seven < 8 )
with expansion:
7 < 8
ConditionTests.cpp:<line number>:
PASSED:
REQUIRE( data.int_seven > 6 )
with expansion:
7 > 6
ConditionTests.cpp:<line number>:
PASSED:
REQUIRE( data.int_seven > 0 )
with expansion:
7 > 0
ConditionTests.cpp:<line number>:
PASSED:
REQUIRE( data.int_seven > -1 )
with expansion:
7 > -1
ConditionTests.cpp:<line number>:
PASSED:
REQUIRE( data.int_seven >= 7 )
with expansion:
7 >= 7
ConditionTests.cpp:<line number>:
PASSED:
REQUIRE( data.int_seven >= 6 )
with expansion:
7 >= 6
ConditionTests.cpp:<line number>:
PASSED:
REQUIRE( data.int_seven <= 7 )
with expansion:
7 <= 7
ConditionTests.cpp:<line number>:
PASSED:
REQUIRE( data.int_seven <= 8 )
with expansion:
7 <= 8
ConditionTests.cpp:<line number>:
PASSED:
REQUIRE( data.float_nine_point_one > 9 )
with expansion:
9.1f > 9
ConditionTests.cpp:<line number>:
PASSED:
REQUIRE( data.float_nine_point_one < 10 )
with expansion:
9.1f < 10
ConditionTests.cpp:<line number>:
PASSED:
REQUIRE( data.float_nine_point_one < 9.2 )
with expansion:
9.1f < 9.2
ConditionTests.cpp:<line number>:
PASSED:
REQUIRE( data.str_hello <= "hello" )
with expansion:
"hello" <= "hello"
ConditionTests.cpp:<line number>:
PASSED:
REQUIRE( data.str_hello >= "hello" )
with expansion:
"hello" >= "hello"
ConditionTests.cpp:<line number>:
PASSED:
REQUIRE( data.str_hello < "hellp" )
with expansion:
"hello" < "hellp"
ConditionTests.cpp:<line number>:
PASSED:
REQUIRE( data.str_hello < "zebra" )
with expansion:
"hello" < "zebra"
ConditionTests.cpp:<line number>:
PASSED:
REQUIRE( data.str_hello > "hellm" )
with expansion:
"hello" > "hellm"
ConditionTests.cpp:<line number>:
PASSED:
REQUIRE( data.str_hello > "a" )
with expansion:
"hello" > "a"
-------------------------------------------------------------------------------
Ordering comparison checks that should fail
-------------------------------------------------------------------------------
ConditionTests.cpp:<line number>
...............................................................................
ConditionTests.cpp:<line number>: FAILED:
CHECK( data.int_seven > 7 )
with expansion:
7 > 7
ConditionTests.cpp:<line number>: FAILED:
CHECK( data.int_seven < 7 )
with expansion:
7 < 7
===============================================================================
test cases: 21 | 16 passed | 3 failed | 2 failed as expected
assertions: 81 | 73 passed | 4 failed | 4 failed as expected

View File

@@ -1,5 +1,5 @@
<testsuites>
<testsuite name="CatchSelfTest" errors="13" failures="72" tests="921" hostname="tbd" time="{duration}" timestamp="tbd">
<testsuite name="CatchSelfTest" errors="13" failures="68" tests="923" hostname="tbd" time="{duration}" timestamp="tbd">
<testcase classname="global" name="toString(enum)" time="{duration}"/>
<testcase classname="global" name="toString(enum w/operator&lt;&lt;)" time="{duration}"/>
<testcase classname="global" name="toString(enum class)" time="{duration}"/>
@@ -499,6 +499,7 @@ MiscTests.cpp:<line number>
<testcase classname="XmlEncode" name="string with control char (1)" time="{duration}"/>
<testcase classname="XmlEncode" name="string with control char (x7F)" time="{duration}"/>
<testcase classname="global" name="long long" time="{duration}"/>
<testcase classname="global" name="This test 'should' fail but doesn't" time="{duration}"/>
<testcase classname="Process can be configured on command line" name="default - no arguments" time="{duration}"/>
<testcase classname="Process can be configured on command line" name="test lists/1 test" time="{duration}"/>
<testcase classname="Process can be configured on command line" name="test lists/Specify one test case exclusion using exclude:" time="{duration}"/>

View File

@@ -665,7 +665,7 @@
5 != 5
</Expanded>
</Expression>
<OverallResult success="false"/>
<OverallResult success="true"/>
</TestCase>
<TestCase name="Ordering comparison checks that should succeed">
<Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
@@ -4085,6 +4085,9 @@
</Expression>
<OverallResult success="true"/>
</TestCase>
<TestCase name="This test 'should' fail but doesn't">
<OverallResult success="false"/>
</TestCase>
<TestCase name="Process can be configured on command line">
<Section name="default - no arguments">
<Expression success="true" type="CHECK_NOTHROW" filename="projects/SelfTest/TestMain.cpp" >
@@ -9563,7 +9566,7 @@ there"
</Section>
<OverallResult success="true"/>
</TestCase>
<OverallResults successes="823" failures="85" expectedFailures="13"/>
<OverallResults successes="824" failures="81" expectedFailures="18"/>
</Group>
<OverallResults successes="823" failures="85" expectedFailures="13"/>
<OverallResults successes="824" failures="80" expectedFailures="18"/>
</Catch>

View File

@@ -101,7 +101,7 @@ TEST_CASE( "Inequality checks that should succeed", "" )
REQUIRE( data.str_hello.size() != 6 );
}
TEST_CASE( "Inequality checks that should fail", "[.][failing]" )
TEST_CASE( "Inequality checks that should fail", "[.][failing][!shouldfail]" )
{
TestData data;

View File

@@ -478,3 +478,8 @@ TEST_CASE( "long long" ) {
// int x = 10/i; // This should cause the signal to fire
// CHECK( x == 0 );
//}
TEST_CASE( "This test 'should' fail but doesn't", "[.][failing][!shouldfail]" )
{
SUCCEED( "oops!" );
}

View File

@@ -25,7 +25,7 @@ CATCH_REGISTER_TAG_ALIAS( "[@tricky]", "[tricky]~[.]" )
template<size_t size>
void parseIntoConfig( const char * (&argv)[size], Catch::ConfigData& config ) {
Catch::Clara::CommandLine<Catch::ConfigData> parser = Catch::makeCommandLineParser();
parser.parseInto( size, argv, config );
parser.parseInto( Catch::Clara::argsToVector( size, argv ), config );
}
template<size_t size>

View File

@@ -1,6 +1,6 @@
/*
* Catch v1.3.5
* Generated: 2016-02-29 08:16:42.342094
* Catch v1.5.3
* Generated: 2016-05-10 19:09:28.805441
* ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly
* Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
@@ -62,7 +62,11 @@
#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
#define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
#ifdef CATCH_CONFIG_COUNTER
# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
#else
# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
#endif
#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
@@ -89,7 +93,7 @@
// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
// ****************
// Note to maintainers: if new toggles are added please document them
// in configuration.md, too
@@ -149,7 +153,7 @@
# endif
# if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) && defined(CATCH_CPP11_OR_GREATER)
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "gcc diagnostic ignored \"-Wparentheses\"" )
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "GCC diagnostic ignored \"-Wparentheses\"" )
# endif
// - otherwise more recent versions define __cplusplus >= 201103L
@@ -185,6 +189,15 @@
#endif
// Use __COUNTER__ if the compiler supports it
#if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \
( defined __GNUC__ && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 ) || \
( defined __clang__ && __clang_major__ >= 3 )
#define CATCH_INTERNAL_CONFIG_COUNTER
#endif
////////////////////////////////////////////////////////////////////////////////
// C++ language feature support
@@ -256,6 +269,9 @@
#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)
# define CATCH_CONFIG_CPP11_UNIQUE_PTR
#endif
#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
# define CATCH_CONFIG_COUNTER
#endif
#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
@@ -686,24 +702,28 @@ void registerTestCaseFunction
#ifdef CATCH_CONFIG_VARIADIC_MACROS
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
static void TestName(); \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
static void TestName()
#define INTERNAL_CATCH_TESTCASE( ... ) \
static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... )\
#define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
namespace{ \
struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
struct TestName : ClassName{ \
void test(); \
}; \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
} \
void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
void TestName::test()
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
@@ -711,24 +731,28 @@ void registerTestCaseFunction
#else
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \
static void TestName(); \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
static void TestName()
#define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
#define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\
namespace{ \
struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
struct TestCaseName : ClassName{ \
void test(); \
}; \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
} \
void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
void TestCaseName::test()
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \
@@ -2578,10 +2602,12 @@ namespace Catch {
}
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) \
static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ); \
namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ) ); }\
static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature )
#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
static std::string translatorName( signature ); \
namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\
static std::string translatorName( signature )
#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
// #included from: internal/catch_approx.hpp
#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
@@ -3592,7 +3618,7 @@ namespace Catch {
#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
// #included from: ../external/clara.h
// Version 0.0.1.1
// Version 0.0.2.4
// Only use header guard if we are not using an outer namespace
#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
@@ -3908,6 +3934,10 @@ namespace Tbc {
#include <stdexcept>
#include <memory>
#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
#define CLARA_PLATFORM_WINDOWS
#endif
// Use optional outer namespace
#ifdef STITCH_CLARA_OPEN_NAMESPACE
STITCH_CLARA_OPEN_NAMESPACE
@@ -3931,9 +3961,6 @@ namespace Clara {
const unsigned int consoleWidth = 80;
#endif
// Use this to try and stop compiler from warning about unreachable code
inline bool isTrue( bool value ) { return value; }
using namespace Tbc;
inline bool startsWith( std::string const& str, std::string const& prefix ) {
@@ -3969,14 +3996,6 @@ namespace Clara {
else
throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" );
}
inline void convertInto( bool _source, bool& _dest ) {
_dest = _source;
}
template<typename T>
inline void convertInto( bool, T& ) {
if( isTrue( true ) )
throw std::runtime_error( "Invalid conversion" );
}
template<typename ConfigT>
struct IArgFunction {
@@ -3986,7 +4005,6 @@ namespace Clara {
IArgFunction( IArgFunction const& ) = default;
#endif
virtual void set( ConfigT& config, std::string const& value ) const = 0;
virtual void setFlag( ConfigT& config ) const = 0;
virtual bool takesArg() const = 0;
virtual IArgFunction* clone() const = 0;
};
@@ -4008,9 +4026,6 @@ namespace Clara {
void set( ConfigT& config, std::string const& value ) const {
functionObj->set( config, value );
}
void setFlag( ConfigT& config ) const {
functionObj->setFlag( config );
}
bool takesArg() const { return functionObj->takesArg(); }
bool isSet() const {
@@ -4023,7 +4038,6 @@ namespace Clara {
template<typename C>
struct NullBinder : IArgFunction<C>{
virtual void set( C&, std::string const& ) const {}
virtual void setFlag( C& ) const {}
virtual bool takesArg() const { return true; }
virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
};
@@ -4034,9 +4048,6 @@ namespace Clara {
virtual void set( C& p, std::string const& stringValue ) const {
convertInto( stringValue, p.*member );
}
virtual void setFlag( C& p ) const {
convertInto( true, p.*member );
}
virtual bool takesArg() const { return !IsBool<M>::value; }
virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
M C::* member;
@@ -4049,11 +4060,6 @@ namespace Clara {
convertInto( stringValue, value );
(p.*member)( value );
}
virtual void setFlag( C& p ) const {
typename RemoveConstRef<M>::type value;
convertInto( true, value );
(p.*member)( value );
}
virtual bool takesArg() const { return !IsBool<M>::value; }
virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
void (C::*member)( M );
@@ -4067,9 +4073,6 @@ namespace Clara {
if( value )
(p.*member)();
}
virtual void setFlag( C& p ) const {
(p.*member)();
}
virtual bool takesArg() const { return false; }
virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
void (C::*member)();
@@ -4084,9 +4087,6 @@ namespace Clara {
if( value )
function( obj );
}
virtual void setFlag( C& p ) const {
function( p );
}
virtual bool takesArg() const { return false; }
virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
void (*function)( C& );
@@ -4100,11 +4100,6 @@ namespace Clara {
convertInto( stringValue, value );
function( obj, value );
}
virtual void setFlag( C& obj ) const {
typename RemoveConstRef<T>::type value;
convertInto( true, value );
function( obj, value );
}
virtual bool takesArg() const { return !IsBool<T>::value; }
virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
void (*function)( C&, T );
@@ -4112,8 +4107,20 @@ namespace Clara {
} // namespace Detail
struct Parser {
Parser() : separators( " \t=:" ) {}
inline std::vector<std::string> argsToVector( int argc, char const* const* const argv ) {
std::vector<std::string> args( static_cast<std::size_t>( argc ) );
for( std::size_t i = 0; i < static_cast<std::size_t>( argc ); ++i )
args[i] = argv[i];
return args;
}
class Parser {
enum Mode { None, MaybeShortOpt, SlashOpt, ShortOpt, LongOpt, Positional };
Mode mode;
std::size_t from;
bool inQuotes;
public:
struct Token {
enum Type { Positional, ShortOpt, LongOpt };
@@ -4122,38 +4129,75 @@ namespace Clara {
std::string data;
};
void parseIntoTokens( int argc, char const* const argv[], std::vector<Parser::Token>& tokens ) const {
Parser() : mode( None ), from( 0 ), inQuotes( false ){}
void parseIntoTokens( std::vector<std::string> const& args, std::vector<Token>& tokens ) {
const std::string doubleDash = "--";
for( int i = 1; i < argc && argv[i] != doubleDash; ++i )
parseIntoTokens( argv[i] , tokens);
for( std::size_t i = 1; i < args.size() && args[i] != doubleDash; ++i )
parseIntoTokens( args[i], tokens);
}
void parseIntoTokens( std::string arg, std::vector<Parser::Token>& tokens ) const {
while( !arg.empty() ) {
Parser::Token token( Parser::Token::Positional, arg );
arg = "";
if( token.data[0] == '-' ) {
if( token.data.size() > 1 && token.data[1] == '-' ) {
token = Parser::Token( Parser::Token::LongOpt, token.data.substr( 2 ) );
}
else {
token = Parser::Token( Parser::Token::ShortOpt, token.data.substr( 1 ) );
if( token.data.size() > 1 && separators.find( token.data[1] ) == std::string::npos ) {
arg = "-" + token.data.substr( 1 );
token.data = token.data.substr( 0, 1 );
}
}
}
if( token.type != Parser::Token::Positional ) {
std::size_t pos = token.data.find_first_of( separators );
if( pos != std::string::npos ) {
arg = token.data.substr( pos+1 );
token.data = token.data.substr( 0, pos );
}
}
tokens.push_back( token );
void parseIntoTokens( std::string const& arg, std::vector<Token>& tokens ) {
for( std::size_t i = 0; i <= arg.size(); ++i ) {
char c = arg[i];
if( c == '"' )
inQuotes = !inQuotes;
mode = handleMode( i, c, arg, tokens );
}
}
std::string separators;
Mode handleMode( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
switch( mode ) {
case None: return handleNone( i, c );
case MaybeShortOpt: return handleMaybeShortOpt( i, c );
case ShortOpt:
case LongOpt:
case SlashOpt: return handleOpt( i, c, arg, tokens );
case Positional: return handlePositional( i, c, arg, tokens );
default: throw std::logic_error( "Unknown mode" );
}
}
Mode handleNone( std::size_t i, char c ) {
if( inQuotes ) {
from = i;
return Positional;
}
switch( c ) {
case '-': return MaybeShortOpt;
#ifdef CLARA_PLATFORM_WINDOWS
case '/': from = i+1; return SlashOpt;
#endif
default: from = i; return Positional;
}
}
Mode handleMaybeShortOpt( std::size_t i, char c ) {
switch( c ) {
case '-': from = i+1; return LongOpt;
default: from = i; return ShortOpt;
}
}
Mode handleOpt( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
if( std::string( ":=\0", 5 ).find( c ) == std::string::npos )
return mode;
std::string optName = arg.substr( from, i-from );
if( mode == ShortOpt )
for( std::size_t j = 0; j < optName.size(); ++j )
tokens.push_back( Token( Token::ShortOpt, optName.substr( j, 1 ) ) );
else if( mode == SlashOpt && optName.size() == 1 )
tokens.push_back( Token( Token::ShortOpt, optName ) );
else
tokens.push_back( Token( Token::LongOpt, optName ) );
return None;
}
Mode handlePositional( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
if( inQuotes || std::string( "\0", 3 ).find( c ) == std::string::npos )
return mode;
std::string data = arg.substr( from, i-from );
tokens.push_back( Token( Token::Positional, data ) );
return None;
}
};
template<typename ConfigT>
@@ -4456,21 +4500,21 @@ namespace Clara {
return oss.str();
}
ConfigT parse( int argc, char const* const argv[] ) const {
ConfigT parse( std::vector<std::string> const& args ) const {
ConfigT config;
parseInto( argc, argv, config );
parseInto( args, config );
return config;
}
std::vector<Parser::Token> parseInto( int argc, char const* argv[], ConfigT& config ) const {
std::string processName = argv[0];
std::vector<Parser::Token> parseInto( std::vector<std::string> const& args, ConfigT& config ) const {
std::string processName = args[0];
std::size_t lastSlash = processName.find_last_of( "/\\" );
if( lastSlash != std::string::npos )
processName = processName.substr( lastSlash+1 );
m_boundProcessName.set( config, processName );
std::vector<Parser::Token> tokens;
Parser parser;
parser.parseIntoTokens( argc, argv, tokens );
parser.parseIntoTokens( args, tokens );
return populate( tokens, config );
}
@@ -4501,7 +4545,7 @@ namespace Clara {
arg.boundField.set( config, tokens[++i].data );
}
else {
arg.boundField.setFlag( config );
arg.boundField.set( config, "true" );
}
break;
}
@@ -5209,6 +5253,8 @@ namespace Catch
bool aborting;
};
class MultipleReporters;
struct IStreamingReporter : IShared {
virtual ~IStreamingReporter();
@@ -5236,6 +5282,8 @@ namespace Catch
virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; }
};
struct IReporterFactory : IShared {
@@ -5453,6 +5501,10 @@ namespace TestCaseTracking {
virtual void addChild( Ptr<ITracker> const& child ) = 0;
virtual ITracker* findChild( std::string const& name ) = 0;
virtual void openChild() = 0;
// Debug/ checking
virtual bool isSectionTracker() const = 0;
virtual bool isIndexTracker() const = 0;
};
class TrackerContext {
@@ -5577,6 +5629,10 @@ namespace TestCaseTracking {
m_parent->openChild();
}
}
virtual bool isSectionTracker() const CATCH_OVERRIDE { return false; }
virtual bool isIndexTracker() const CATCH_OVERRIDE { return false; }
void open() {
m_runState = Executing;
moveToThis();
@@ -5640,13 +5696,16 @@ namespace TestCaseTracking {
{}
virtual ~SectionTracker();
virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; }
static SectionTracker& acquire( TrackerContext& ctx, std::string const& name ) {
SectionTracker* section = CATCH_NULL;
ITracker& currentTracker = ctx.currentTracker();
if( ITracker* childTracker = currentTracker.findChild( name ) ) {
section = dynamic_cast<SectionTracker*>( childTracker );
assert( section );
assert( childTracker );
assert( childTracker->isSectionTracker() );
section = static_cast<SectionTracker*>( childTracker );
}
else {
section = new SectionTracker( name, ctx, &currentTracker );
@@ -5671,13 +5730,16 @@ namespace TestCaseTracking {
{}
virtual ~IndexTracker();
virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; }
static IndexTracker& acquire( TrackerContext& ctx, std::string const& name, int size ) {
IndexTracker* tracker = CATCH_NULL;
ITracker& currentTracker = ctx.currentTracker();
if( ITracker* childTracker = currentTracker.findChild( name ) ) {
tracker = dynamic_cast<IndexTracker*>( childTracker );
assert( tracker );
assert( childTracker );
assert( childTracker->isIndexTracker() );
tracker = static_cast<IndexTracker*>( childTracker );
}
else {
tracker = new IndexTracker( name, ctx, &currentTracker, size );
@@ -5884,6 +5946,11 @@ namespace Catch {
while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
Totals deltaTotals = m_totals.delta( prevTotals );
if( testInfo.expectedToFail() && deltaTotals.testCases.passed > 0 ) {
deltaTotals.assertions.failed++;
deltaTotals.testCases.passed--;
deltaTotals.testCases.failed++;
}
m_totals.testCases += deltaTotals.testCases;
m_reporter->testCaseEnded( TestCaseStats( testInfo,
deltaTotals,
@@ -6275,10 +6342,10 @@ namespace Catch {
Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
}
int applyCommandLine( int argc, char const* argv[], OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
int applyCommandLine( int argc, char const* const* const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
try {
m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
m_unusedTokens = m_cli.parseInto( argc, argv, m_configData );
m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData );
if( m_configData.showHelp )
showHelp( m_configData.processName );
m_config.reset();
@@ -6302,16 +6369,13 @@ namespace Catch {
m_config.reset();
}
int run( int argc, char const* argv[] ) {
int run( int argc, char const* const* const argv ) {
int returnCode = applyCommandLine( argc, argv );
if( returnCode == 0 )
returnCode = run();
return returnCode;
}
int run( int argc, char* argv[] ) {
return run( argc, const_cast<char const**>( argv ) );
}
int run() {
if( m_configData.showHelp )
@@ -6416,13 +6480,15 @@ namespace Catch {
it != itEnd;
++it ) {
std::pair<std::set<TestCase>::const_iterator, bool> prev = seenFunctions.insert( *it );
if( !prev.second ){
Catch::cerr()
<< Colour( Colour::Red )
<< "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n"
<< "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
<< "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl;
exit(1);
if( !prev.second ) {
std::ostringstream ss;
ss << Colour( Colour::Red )
<< "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n"
<< "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
<< "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl;
throw std::runtime_error(ss.str());
}
}
}
@@ -7481,7 +7547,7 @@ namespace Catch {
return os;
}
Version libraryVersion( 1, 3, 5, "", 0 );
Version libraryVersion( 1, 5, 3, "", 0 );
}
@@ -8460,13 +8526,18 @@ public: // IStreamingReporter
++it )
(*it)->skipTest( testInfo );
}
virtual MultipleReporters* tryAsMulti() CATCH_OVERRIDE {
return this;
}
};
Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter ) {
Ptr<IStreamingReporter> resultingReporter;
if( existingReporter ) {
MultipleReporters* multi = dynamic_cast<MultipleReporters*>( existingReporter.get() );
MultipleReporters* multi = existingReporter->tryAsMulti();
if( !multi ) {
multi = new MultipleReporters;
resultingReporter = Ptr<IStreamingReporter>( multi );
@@ -8646,7 +8717,7 @@ namespace Catch {
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
virtual bool assertionEnded( AssertionStats const& assertionStats ) {
virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
assert( !m_sectionStack.empty() );
SectionNode& sectionNode = *m_sectionStack.back();
sectionNode.assertions.push_back( assertionStats );
@@ -9777,7 +9848,7 @@ namespace Catch {
if( totals.testCases.total() == 0 ) {
stream << Colour( Colour::Warning ) << "No tests ran\n";
}
else if( totals.assertions.total() > 0 && totals.assertions.allPassed() ) {
else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) {
stream << Colour( Colour::ResultSuccess ) << "All tests passed";
stream << " ("
<< pluralise( totals.assertions.passed, "assertion" ) << " in "