mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-17 11:12:25 +01:00
Update to allow all self tests to be run and to allow running with tags
This commit is contained in:
parent
dd8c13a9e1
commit
36cb967220
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#if (_MANAGED == 1) || (_M_CEE == 1) // detect CLR
|
#if (_MANAGED == 1) || (_M_CEE == 1) // detect CLR
|
||||||
#define INTERNAL_CATCH_VS_MANAGED
|
#define INTERNAL_CATCH_VS_MANAGED
|
||||||
|
#define INTERNAL_CATCH_INLINE inline
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#if defined(_WINDLL)
|
#if defined(_WINDLL)
|
||||||
@ -26,6 +27,7 @@
|
|||||||
// It's possible that this is not enough for someone so allow it to be overridden...
|
// It's possible that this is not enough for someone so allow it to be overridden...
|
||||||
#if !defined( CATCH_CONFIG_MAIN ) && !defined( CATCH_CONFIG_RUNNER )
|
#if !defined( CATCH_CONFIG_MAIN ) && !defined( CATCH_CONFIG_RUNNER )
|
||||||
#define INTERNAL_CATCH_VS_NATIVE
|
#define INTERNAL_CATCH_VS_NATIVE
|
||||||
|
#define INTERNAL_CATCH_INLINE inline
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -52,7 +54,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(INTERNAL_CATCH_VS_MANAGED) || defined(INTERNAL_CATCH_VS_NATIVE)
|
#if defined(INTERNAL_CATCH_VS_MANAGED) || defined(INTERNAL_CATCH_VS_NATIVE)
|
||||||
#define INTERNAL_CATCH_INLINE inline
|
|
||||||
#ifdef INTERNAL_CATCH_VS_MANAGED
|
#ifdef INTERNAL_CATCH_VS_MANAGED
|
||||||
#include "internal/catch_vs_managed_impl.hpp"
|
#include "internal/catch_vs_managed_impl.hpp"
|
||||||
#else // INTERNAL_CATCH_VS_MANAGED
|
#else // INTERNAL_CATCH_VS_MANAGED
|
||||||
@ -203,6 +204,16 @@
|
|||||||
#define THEN( desc ) SECTION( " Then: " desc, "" )
|
#define THEN( desc ) SECTION( " Then: " desc, "" )
|
||||||
#define AND_THEN( desc ) SECTION( " And: " desc, "" )
|
#define AND_THEN( desc ) SECTION( " And: " desc, "" )
|
||||||
|
|
||||||
|
#if defined(INTERNAL_CATCH_VS_MANAGED) || defined(INTERNAL_CATCH_VS_NATIVE)
|
||||||
|
#define CATCH_MAP_CATEGORY_TO_TAG( Category, Tag ) INTERNAL_CATCH_MAP_CATEGORY_TO_TAG( Category, Tag )
|
||||||
|
#define CATCH_CONFIG_SHOW_SUCCESS( v ) CATCH_INTERNAL_CONFIG_SHOW_SUCCESS( v )
|
||||||
|
#define CATCH_CONFIG_WARN_MISSING_ASSERTIONS( v ) CATCH_INTERNAL_CONFIG_WARN_MISSING_ASSERTIONS( v )
|
||||||
|
#else
|
||||||
|
#define CATCH_MAP_CATEGORY_TO_TAG( Category, Tag )
|
||||||
|
#define CATCH_CONFIG_SHOW_SUCCESS( v )
|
||||||
|
#define CATCH_CONFIG_WARN_MISSING_ASSERTIONS( v )
|
||||||
|
#endif
|
||||||
|
|
||||||
using Catch::Detail::Approx;
|
using Catch::Detail::Approx;
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
|
@ -108,6 +108,8 @@ namespace Catch {
|
|||||||
std::set<TestCase> m_testsAlreadyRun;
|
std::set<TestCase> m_testsAlreadyRun;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !defined(INTERNAL_CATCH_VS_MANAGED) && !defined(INTERNAL_CATCH_VS_NATIVE)
|
||||||
|
|
||||||
class Session {
|
class Session {
|
||||||
static bool alreadyInstantiated;
|
static bool alreadyInstantiated;
|
||||||
|
|
||||||
@ -232,6 +234,8 @@ namespace Catch {
|
|||||||
|
|
||||||
bool Session::alreadyInstantiated = false;
|
bool Session::alreadyInstantiated = false;
|
||||||
|
|
||||||
|
#endif // !VS_MANAGED && !VS_NATIVE
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
|
||||||
|
@ -56,11 +56,7 @@ namespace Catch {
|
|||||||
.setResultType( matcher.match( arg ) );
|
.setResultType( matcher.match( arg ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(INTERNAL_CATCH_VS_MANAGED)
|
|
||||||
// TestFailureException not defined for CLR
|
|
||||||
#else // detect CLR
|
|
||||||
struct TestFailureException{};
|
struct TestFailureException{};
|
||||||
#endif
|
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
@ -70,7 +66,6 @@ struct TestFailureException{};
|
|||||||
#if !defined(INTERNAL_CATCH_VS_MANAGED) && !defined(INTERNAL_CATCH_VS_NATIVE)
|
#if !defined(INTERNAL_CATCH_VS_MANAGED) && !defined(INTERNAL_CATCH_VS_NATIVE)
|
||||||
|
|
||||||
// normal Catch
|
// normal Catch
|
||||||
#define INTERNAL_CATCH_TEST_FAILURE_EXCEPTION const Catch::TestFailureException&
|
|
||||||
#define INTERNAL_CATCH_TEST_THROW_FAILURE throw Catch::TestFailureException();
|
#define INTERNAL_CATCH_TEST_THROW_FAILURE throw Catch::TestFailureException();
|
||||||
|
|
||||||
#else // VS integration
|
#else // VS integration
|
||||||
@ -84,10 +79,9 @@ struct TestFailureException{};
|
|||||||
std::stringstream _sf; \
|
std::stringstream _sf; \
|
||||||
_sf << r->getExpressionInMacro().c_str() << ", " << r->getMessage().c_str(); \
|
_sf << r->getExpressionInMacro().c_str() << ", " << r->getMessage().c_str(); \
|
||||||
std::string fail = _sf.str(); \
|
std::string fail = _sf.str(); \
|
||||||
Assert::Fail(Catch::convert_string_to_managed(fail)); \
|
Assert::Fail(Catch::convert_string_for_assert(fail)); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define INTERNAL_CATCH_TEST_FAILURE_EXCEPTION AssertFailedException^
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#if defined(INTERNAL_CATCH_VS_NATIVE)
|
#if defined(INTERNAL_CATCH_VS_NATIVE)
|
||||||
@ -106,8 +100,6 @@ struct TestFailureException{};
|
|||||||
Assert::Fail(ws2.c_str(), &li); \
|
Assert::Fail(ws2.c_str(), &li); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define INTERNAL_CATCH_TEST_FAILURE_EXCEPTION const Catch::TestFailureException&
|
|
||||||
|
|
||||||
#endif // INTERNAL_CATCH_VS_MANAGED
|
#endif // INTERNAL_CATCH_VS_MANAGED
|
||||||
|
|
||||||
#endif // detect CLR
|
#endif // detect CLR
|
||||||
@ -119,7 +111,7 @@ struct TestFailureException{};
|
|||||||
if( Catch::ResultAction::Value internal_catch_action = Catch::getResultCapture().acceptExpression( evaluatedExpr, INTERNAL_CATCH_ASSERTIONINFO_NAME ) ) { \
|
if( Catch::ResultAction::Value internal_catch_action = Catch::getResultCapture().acceptExpression( evaluatedExpr, INTERNAL_CATCH_ASSERTIONINFO_NAME ) ) { \
|
||||||
if( internal_catch_action & Catch::ResultAction::Debug ) BreakIntoDebugger(); \
|
if( internal_catch_action & Catch::ResultAction::Debug ) BreakIntoDebugger(); \
|
||||||
if( internal_catch_action & Catch::ResultAction::Abort ) { INTERNAL_CATCH_TEST_THROW_FAILURE } \
|
if( internal_catch_action & Catch::ResultAction::Abort ) { INTERNAL_CATCH_TEST_THROW_FAILURE } \
|
||||||
if( !Catch::shouldContinueOnFailure( resultDisposition ) ) { INTERNAL_CATCH_TEST_THROW_FAILURE } \
|
if( !Catch::shouldContinueOnFailure( resultDisposition ) ) { throw Catch::TestFailureException(); } \
|
||||||
Catch::isTrue( false && originalExpr ); \
|
Catch::isTrue( false && originalExpr ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +125,7 @@ struct TestFailureException{};
|
|||||||
INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, resultDisposition ); \
|
INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, resultDisposition ); \
|
||||||
try { \
|
try { \
|
||||||
INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionDecomposer()->*expr ).endExpression( resultDisposition ), resultDisposition, expr ); \
|
INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionDecomposer()->*expr ).endExpression( resultDisposition ), resultDisposition, expr ); \
|
||||||
} catch( INTERNAL_CATCH_TEST_FAILURE_EXCEPTION ) { \
|
} catch( const Catch::TestFailureException& ) { \
|
||||||
throw; \
|
throw; \
|
||||||
} catch( ... ) { \
|
} catch( ... ) { \
|
||||||
INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException(), \
|
INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException(), \
|
||||||
@ -172,7 +164,7 @@ struct TestFailureException{};
|
|||||||
INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::DidntThrowException ), resultDisposition, false ); \
|
INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::DidntThrowException ), resultDisposition, false ); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
catch( INTERNAL_CATCH_TEST_FAILURE_EXCEPTION ) { \
|
catch( const Catch::TestFailureException& ) { \
|
||||||
throw; \
|
throw; \
|
||||||
} \
|
} \
|
||||||
catch( exceptionType ) { \
|
catch( exceptionType ) { \
|
||||||
@ -216,7 +208,7 @@ struct TestFailureException{};
|
|||||||
INTERNAL_CATCH_ACCEPT_INFO( #arg " " #matcher, macroName, resultDisposition ); \
|
INTERNAL_CATCH_ACCEPT_INFO( #arg " " #matcher, macroName, resultDisposition ); \
|
||||||
try { \
|
try { \
|
||||||
INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::expressionResultBuilderFromMatcher( ::Catch::Matchers::matcher, arg, #matcher ) ), resultDisposition, false ); \
|
INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::expressionResultBuilderFromMatcher( ::Catch::Matchers::matcher, arg, #matcher ) ), resultDisposition, false ); \
|
||||||
} catch( INTERNAL_CATCH_TEST_FAILURE_EXCEPTION ) { \
|
} catch( const Catch::TestFailureException& ) { \
|
||||||
throw; \
|
throw; \
|
||||||
} catch( ... ) { \
|
} catch( ... ) { \
|
||||||
INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException() ), \
|
INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException() ), \
|
||||||
|
@ -22,6 +22,138 @@
|
|||||||
#define CATCH_CONFIG_CONSOLE_WIDTH 80
|
#define CATCH_CONFIG_CONSOLE_WIDTH 80
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace CatchOverrides {
|
||||||
|
|
||||||
|
class ConfigGuard
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConfigGuard()
|
||||||
|
: origConfig(Catch::getCurrentContext().getConfig())
|
||||||
|
{}
|
||||||
|
~ConfigGuard()
|
||||||
|
{
|
||||||
|
Catch::getCurrentMutableContext().setConfig(origConfig);
|
||||||
|
}
|
||||||
|
const Catch::Ptr<Catch::IConfig const>& value() const {return origConfig;}
|
||||||
|
private:
|
||||||
|
ConfigGuard(const ConfigGuard&);
|
||||||
|
ConfigGuard& operator=(const ConfigGuard&);
|
||||||
|
|
||||||
|
const Catch::Ptr<Catch::IConfig const> origConfig;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class Config
|
||||||
|
{
|
||||||
|
typedef std::map<int, bool> LineData;
|
||||||
|
typedef std::map<std::string, LineData> FileLineData;
|
||||||
|
public:
|
||||||
|
bool includeSuccessfulResults(const std::string& file, int c) const
|
||||||
|
{
|
||||||
|
bool result(false);
|
||||||
|
FileLineData::const_iterator it = showSuccessfulTestsData.find(file);
|
||||||
|
if( it != showSuccessfulTestsData.end() )
|
||||||
|
{
|
||||||
|
for( LineData::const_iterator lineIt = it->second.begin(); lineIt != it->second.end(); ++lineIt )
|
||||||
|
{
|
||||||
|
if( c <= lineIt->first )
|
||||||
|
break;
|
||||||
|
result = lineIt->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
void insertSuccessfulResults(const std::string& file, int c, bool v)
|
||||||
|
{
|
||||||
|
FileLineData::iterator it = showSuccessfulTestsData.find(file);
|
||||||
|
if( it == showSuccessfulTestsData.end() )
|
||||||
|
{
|
||||||
|
LineData tmp;
|
||||||
|
tmp.insert(std::make_pair(c,v));
|
||||||
|
showSuccessfulTestsData.insert(std::make_pair(file, tmp));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
it->second.insert(std::make_pair(c,v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool warnAboutMissingAssertions(const std::string& file, int c) const
|
||||||
|
{
|
||||||
|
bool result(false);
|
||||||
|
FileLineData::const_iterator it = missingAssertionData.find(file);
|
||||||
|
if( it != missingAssertionData.end() )
|
||||||
|
{
|
||||||
|
for( LineData::const_iterator lineIt = it->second.begin(); lineIt != it->second.end(); ++lineIt )
|
||||||
|
{
|
||||||
|
if( c <= lineIt->first )
|
||||||
|
break;
|
||||||
|
result = lineIt->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
void insertMissingAssertions(const std::string& file, int c, bool v)
|
||||||
|
{
|
||||||
|
FileLineData::iterator it = missingAssertionData.find(file);
|
||||||
|
if( it == missingAssertionData.end() )
|
||||||
|
{
|
||||||
|
LineData tmp;
|
||||||
|
tmp.insert(std::make_pair(c,v));
|
||||||
|
missingAssertionData.insert(std::make_pair(file, tmp));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
it->second.insert(std::make_pair(c,v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static Config<T>& instance()
|
||||||
|
{
|
||||||
|
if( !s_instance )
|
||||||
|
{
|
||||||
|
s_instance = new Config<T>();
|
||||||
|
}
|
||||||
|
return *s_instance;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
FileLineData showSuccessfulTestsData;
|
||||||
|
FileLineData missingAssertionData;
|
||||||
|
|
||||||
|
static Config<T>* s_instance;
|
||||||
|
};
|
||||||
|
template <typename T>
|
||||||
|
Config<T>* Config<T>::s_instance = NULL;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct ConfigReset
|
||||||
|
{
|
||||||
|
ConfigReset( const std::string& file, int c )
|
||||||
|
{
|
||||||
|
Config<T>::instance().insertSuccessfulResults(file, c, false);
|
||||||
|
Config<T>::instance().insertMissingAssertions(file, c, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct ConfigShowSuccessfulTests
|
||||||
|
{
|
||||||
|
template <typename U>
|
||||||
|
ConfigShowSuccessfulTests( const std::string& file, int c, U v )
|
||||||
|
{
|
||||||
|
Config<T>::instance().insertSuccessfulResults(file, c, v ? true : false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct ConfigWarnMissingAssertions
|
||||||
|
{
|
||||||
|
template <typename U>
|
||||||
|
ConfigWarnMissingAssertions( const std::string& file, int c, U v )
|
||||||
|
{
|
||||||
|
Config<T>::instance().insertMissingAssertions(file, c, v ? true : false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
struct ConfigData {
|
struct ConfigData {
|
||||||
@ -40,6 +172,21 @@ namespace Catch {
|
|||||||
showDurations( ShowDurations::DefaultForReporter )
|
showDurations( ShowDurations::DefaultForReporter )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
explicit ConfigData(const IConfig* other)
|
||||||
|
: listTests( false ),
|
||||||
|
listTags( false ),
|
||||||
|
listReporters( false ),
|
||||||
|
showSuccessfulTests( other ? other->includeSuccessfulResults() : false ),
|
||||||
|
shouldDebugBreak( false ),
|
||||||
|
noThrow( other ? !other->allowThrows() : false ),
|
||||||
|
showHelp( false ),
|
||||||
|
abortAfter( -1 ),
|
||||||
|
verbosity( Verbosity::Normal ),
|
||||||
|
warnings( other ? (other->warnAboutMissingAssertions() ? WarnAbout::NoAssertions : WarnAbout::Nothing) : WarnAbout::Nothing ),
|
||||||
|
showDurations( other ? other->showDurations() : ShowDurations::DefaultForReporter ),
|
||||||
|
name( other ? other->name() : std::string() )
|
||||||
|
{}
|
||||||
|
|
||||||
bool listTests;
|
bool listTests;
|
||||||
bool listTags;
|
bool listTags;
|
||||||
bool listReporters;
|
bool listReporters;
|
||||||
|
@ -12,10 +12,6 @@
|
|||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
namespace Detail {
|
|
||||||
struct IColourImpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Colour {
|
struct Colour {
|
||||||
enum Code {
|
enum Code {
|
||||||
None = 0,
|
None = 0,
|
||||||
@ -53,12 +49,6 @@ namespace Catch {
|
|||||||
// Use constructed object for RAII guard
|
// Use constructed object for RAII guard
|
||||||
Colour( Code _colourCode );
|
Colour( Code _colourCode );
|
||||||
~Colour();
|
~Colour();
|
||||||
|
|
||||||
// Use static method for one-shot changes
|
|
||||||
static void use( Code _colourCode );
|
|
||||||
|
|
||||||
private:
|
|
||||||
static Detail::IColourImpl* impl;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
@ -10,13 +10,6 @@
|
|||||||
|
|
||||||
#include "catch_console_colour.hpp"
|
#include "catch_console_colour.hpp"
|
||||||
|
|
||||||
namespace Catch { namespace Detail {
|
|
||||||
struct IColourImpl {
|
|
||||||
virtual ~IColourImpl() {}
|
|
||||||
virtual void use( Colour::Code _colourCode ) = 0;
|
|
||||||
};
|
|
||||||
}}
|
|
||||||
|
|
||||||
#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
|
#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
|
||||||
|
|
||||||
#ifndef NOMINMAX
|
#ifndef NOMINMAX
|
||||||
@ -32,7 +25,7 @@ namespace Catch { namespace Detail {
|
|||||||
namespace Catch {
|
namespace Catch {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class Win32ColourImpl : public Detail::IColourImpl {
|
class Win32ColourImpl {
|
||||||
public:
|
public:
|
||||||
Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
|
Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
|
||||||
{
|
{
|
||||||
@ -41,7 +34,7 @@ namespace {
|
|||||||
originalAttributes = csbiInfo.wAttributes;
|
originalAttributes = csbiInfo.wAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void use( Colour::Code _colourCode ) {
|
void use( Colour::Code _colourCode ) {
|
||||||
switch( _colourCode ) {
|
switch( _colourCode ) {
|
||||||
case Colour::None: return setTextAttribute( originalAttributes );
|
case Colour::None: return setTextAttribute( originalAttributes );
|
||||||
case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
|
case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
|
||||||
@ -73,7 +66,7 @@ namespace {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Win32ColourImpl platformColourImpl;
|
typedef Win32ColourImpl PlatformColourImpl;
|
||||||
|
|
||||||
} // end anon namespace
|
} // end anon namespace
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
@ -89,9 +82,9 @@ namespace {
|
|||||||
// Thanks to Adam Strzelecki for original contribution
|
// Thanks to Adam Strzelecki for original contribution
|
||||||
// (http://github.com/nanoant)
|
// (http://github.com/nanoant)
|
||||||
// https://github.com/philsquared/Catch/pull/131
|
// https://github.com/philsquared/Catch/pull/131
|
||||||
class PosixColourImpl : public Detail::IColourImpl {
|
class PosixColourImpl {
|
||||||
public:
|
public:
|
||||||
virtual void use( Colour::Code _colourCode ) {
|
void use( Colour::Code _colourCode ) {
|
||||||
switch( _colourCode ) {
|
switch( _colourCode ) {
|
||||||
case Colour::None:
|
case Colour::None:
|
||||||
case Colour::White: return setColour( "[0m" );
|
case Colour::White: return setColour( "[0m" );
|
||||||
@ -120,7 +113,7 @@ namespace {
|
|||||||
return isatty( fileno(stdout) );
|
return isatty( fileno(stdout) );
|
||||||
}
|
}
|
||||||
|
|
||||||
PosixColourImpl platformColourImpl;
|
typedef PosixColourImpl PlatformColourImpl;
|
||||||
|
|
||||||
} // end anon namespace
|
} // end anon namespace
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
@ -129,24 +122,24 @@ namespace {
|
|||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
namespace {
|
template <typename Impl>
|
||||||
struct NoColourImpl : Detail::IColourImpl {
|
struct ColourChange
|
||||||
void use( Colour::Code ) {}
|
{
|
||||||
|
static Impl impl;
|
||||||
|
static const bool shouldUseColour;
|
||||||
};
|
};
|
||||||
NoColourImpl noColourImpl;
|
template <typename Impl>
|
||||||
static const bool shouldUseColour = shouldUseColourForPlatform() &&
|
Impl ColourChange<Impl>::impl;
|
||||||
!isDebuggerActive();
|
template <typename Impl>
|
||||||
}
|
const bool ColourChange<Impl>::shouldUseColour = shouldUseColourForPlatform() &&
|
||||||
|
!isDebuggerActive();;
|
||||||
|
|
||||||
Colour::Colour( Code _colourCode ){ use( _colourCode ); }
|
INTERNAL_CATCH_INLINE Colour::Colour( Code _colourCode ) {
|
||||||
Colour::~Colour(){ use( None ); }
|
if( ColourChange<PlatformColourImpl>::shouldUseColour ) ColourChange<PlatformColourImpl>::impl.use( _colourCode );
|
||||||
void Colour::use( Code _colourCode ) {
|
}
|
||||||
impl->use( _colourCode );
|
INTERNAL_CATCH_INLINE Colour::~Colour() {
|
||||||
|
if( ColourChange<PlatformColourImpl>::shouldUseColour ) ColourChange<PlatformColourImpl>::impl.use( Colour::None );
|
||||||
}
|
}
|
||||||
|
|
||||||
Detail::IColourImpl* Colour::impl = shouldUseColour
|
|
||||||
? static_cast<Detail::IColourImpl*>( &platformColourImpl )
|
|
||||||
: static_cast<Detail::IColourImpl*>( &noColourImpl );
|
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
|
@ -15,9 +15,10 @@
|
|||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
|
template <typename Runner, typename ResultCapture>
|
||||||
class Context : public IMutableContext {
|
class Context : public IMutableContext {
|
||||||
|
|
||||||
Context() : m_config( NULL ), m_runner( NULL ), m_resultCapture( NULL ) {}
|
Context() : m_config( NULL ), m_runner( &nullRunner ), m_resultCapture( &nullResultCapture ) {}
|
||||||
Context( Context const& );
|
Context( Context const& );
|
||||||
void operator=( Context const& );
|
void operator=( Context const& );
|
||||||
|
|
||||||
@ -81,15 +82,28 @@ namespace Catch {
|
|||||||
IRunner* m_runner;
|
IRunner* m_runner;
|
||||||
IResultCapture* m_resultCapture;
|
IResultCapture* m_resultCapture;
|
||||||
std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
|
std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
|
||||||
|
|
||||||
|
static ResultCapture nullResultCapture;
|
||||||
|
static Runner nullRunner;
|
||||||
|
public:
|
||||||
|
static Context* currentContext;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace {
|
template <typename Runner, typename ResultCapture>
|
||||||
|
ResultCapture Context<Runner, ResultCapture>::nullResultCapture;
|
||||||
|
template <typename Runner, typename ResultCapture>
|
||||||
|
Runner Context<Runner, ResultCapture>::nullRunner;
|
||||||
|
template <typename Runner, typename ResultCapture>
|
||||||
|
Context<Runner,ResultCapture>* Context<Runner, ResultCapture>::currentContext = NULL;
|
||||||
|
|
||||||
|
/*namespace {
|
||||||
Context* currentContext = NULL;
|
Context* currentContext = NULL;
|
||||||
}
|
}*/
|
||||||
|
typedef Context<NullRunner, NullResultCapture> DefaultContext;
|
||||||
INTERNAL_CATCH_INLINE IMutableContext& getCurrentMutableContext() {
|
INTERNAL_CATCH_INLINE IMutableContext& getCurrentMutableContext() {
|
||||||
if( !currentContext )
|
if( !DefaultContext::currentContext )
|
||||||
currentContext = new Context();
|
DefaultContext::currentContext = new DefaultContext();
|
||||||
return *currentContext;
|
return *DefaultContext::currentContext;
|
||||||
}
|
}
|
||||||
INTERNAL_CATCH_INLINE IContext& getCurrentContext() {
|
INTERNAL_CATCH_INLINE IContext& getCurrentContext() {
|
||||||
return getCurrentMutableContext();
|
return getCurrentMutableContext();
|
||||||
@ -104,8 +118,8 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL_CATCH_INLINE void cleanUpContext() {
|
INTERNAL_CATCH_INLINE void cleanUpContext() {
|
||||||
delete currentContext;
|
delete DefaultContext::currentContext;
|
||||||
currentContext = NULL;
|
DefaultContext::currentContext = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,23 @@ namespace Catch {
|
|||||||
virtual std::string getCurrentTestName() const = 0;
|
virtual std::string getCurrentTestName() const = 0;
|
||||||
virtual const AssertionResult* getLastResult() const = 0;
|
virtual const AssertionResult* getLastResult() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct NullResultCapture : public IResultCapture {
|
||||||
|
|
||||||
|
virtual void assertionEnded( AssertionResult const& ) {}
|
||||||
|
virtual bool sectionStarted( SectionInfo const& ,
|
||||||
|
Counts& ) {return false;}
|
||||||
|
virtual void sectionEnded( SectionInfo const& , Counts const& , double ) {}
|
||||||
|
virtual void pushScopedMessage( MessageInfo const& ) {}
|
||||||
|
virtual void popScopedMessage( MessageInfo const& ) {}
|
||||||
|
|
||||||
|
virtual bool shouldDebugBreak() const {return false;}
|
||||||
|
|
||||||
|
virtual ResultAction::Value acceptExpression( ExpressionResultBuilder const& , AssertionInfo const& ) {return ResultAction::Abort;}
|
||||||
|
|
||||||
|
virtual std::string getCurrentTestName() const {return std::string();}
|
||||||
|
virtual const AssertionResult* getLastResult() const {return NULL;}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
|
||||||
|
@ -18,6 +18,10 @@ namespace Catch {
|
|||||||
struct IRunner {
|
struct IRunner {
|
||||||
virtual ~IRunner();
|
virtual ~IRunner();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct NullRunner : public IRunner
|
||||||
|
{
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
|
||||||
|
@ -48,7 +48,6 @@ namespace Catch {
|
|||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class RunContext : public IResultCapture, public IRunner {
|
class RunContext : public IResultCapture, public IRunner {
|
||||||
|
|
||||||
RunContext( RunContext const& );
|
RunContext( RunContext const& );
|
||||||
@ -105,18 +104,16 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Totals runTest( TestCase const& testCase ) {
|
Totals runTest( TestCase const& testCase ) {
|
||||||
Totals prevTotals = m_totals;
|
|
||||||
|
|
||||||
std::string redirectedCout;
|
std::string redirectedCout;
|
||||||
std::string redirectedCerr;
|
std::string redirectedCerr;
|
||||||
|
|
||||||
TestCaseInfo testInfo = testCase.getTestCaseInfo();
|
TestCaseInfo testInfo = testCase.getTestCaseInfo();
|
||||||
|
|
||||||
m_reporter->testCaseStarting( testInfo );
|
UnwindTestCaseOnCompletion finaliser(*this, m_totals, m_reporter, testInfo, redirectedCout, redirectedCerr);
|
||||||
|
|
||||||
m_activeTestCase = &testCase;
|
m_activeTestCase = &testCase;
|
||||||
m_testCaseTracker = TestCaseTracker( testInfo.name );
|
m_testCaseTracker = TestCaseTracker( testInfo.name );
|
||||||
|
|
||||||
do {
|
do {
|
||||||
do {
|
do {
|
||||||
runCurrentTest( redirectedCout, redirectedCerr );
|
runCurrentTest( redirectedCout, redirectedCerr );
|
||||||
@ -125,18 +122,10 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
|
while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
|
||||||
|
|
||||||
Totals deltaTotals = m_totals.delta( prevTotals );
|
|
||||||
m_totals.testCases += deltaTotals.testCases;
|
|
||||||
m_reporter->testCaseEnded( TestCaseStats( testInfo,
|
|
||||||
deltaTotals,
|
|
||||||
redirectedCout,
|
|
||||||
redirectedCerr,
|
|
||||||
aborting() ) );
|
|
||||||
|
|
||||||
m_activeTestCase = NULL;
|
m_activeTestCase = NULL;
|
||||||
m_testCaseTracker.reset();
|
m_testCaseTracker.reset();
|
||||||
|
|
||||||
return deltaTotals;
|
return finaliser.report();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ptr<IConfig const> config() const {
|
Ptr<IConfig const> config() const {
|
||||||
@ -194,12 +183,7 @@ namespace Catch {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void sectionEnded( SectionInfo const& info, Counts const& prevAssertions, double _durationInSeconds ) {
|
void unwindSection(SectionInfo const& info, Counts const& prevAssertions, double _durationInSeconds ) {
|
||||||
if( std::uncaught_exception() ) {
|
|
||||||
m_unfinishedSections.push_back( UnfinishedSections( info, prevAssertions, _durationInSeconds ) );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Counts assertions = m_totals.assertions - prevAssertions;
|
Counts assertions = m_totals.assertions - prevAssertions;
|
||||||
bool missingAssertions = testForMissingAssertions( assertions );
|
bool missingAssertions = testForMissingAssertions( assertions );
|
||||||
|
|
||||||
@ -209,6 +193,15 @@ namespace Catch {
|
|||||||
m_messages.clear();
|
m_messages.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void sectionEnded( SectionInfo const& info, Counts const& prevAssertions, double _durationInSeconds ) {
|
||||||
|
if( std::uncaught_exception() ) {
|
||||||
|
m_unfinishedSections.push_back( UnfinishedSections( info, prevAssertions, _durationInSeconds ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unwindSection(info, prevAssertions, _durationInSeconds);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void pushScopedMessage( MessageInfo const& message ) {
|
virtual void pushScopedMessage( MessageInfo const& message ) {
|
||||||
m_messages.push_back( message );
|
m_messages.push_back( message );
|
||||||
}
|
}
|
||||||
@ -257,16 +250,13 @@ namespace Catch {
|
|||||||
|
|
||||||
void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
|
void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
|
||||||
TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
|
TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
|
||||||
SectionInfo testCaseSection( testCaseInfo.name, testCaseInfo.description, testCaseInfo.lineInfo );
|
|
||||||
m_reporter->sectionStarting( testCaseSection );
|
UnwindSectionOnCompletion finaliser(*this, m_totals, m_reporter, testCaseInfo, m_unfinishedSections, m_messages);
|
||||||
Counts prevAssertions = m_totals.assertions;
|
|
||||||
double duration = 0;
|
|
||||||
try {
|
try {
|
||||||
m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
|
m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
|
||||||
TestCaseTracker::Guard guard( *m_testCaseTracker );
|
TestCaseTracker::Guard guard( *m_testCaseTracker );
|
||||||
|
|
||||||
Timer timer;
|
finaliser.startTimer();
|
||||||
timer.start();
|
|
||||||
if( m_reporter->getPreferences().shouldRedirectStdOut ) {
|
if( m_reporter->getPreferences().shouldRedirectStdOut ) {
|
||||||
StreamRedirect coutRedir( std::cout, redirectedCout );
|
StreamRedirect coutRedir( std::cout, redirectedCout );
|
||||||
StreamRedirect cerrRedir( std::cerr, redirectedCerr );
|
StreamRedirect cerrRedir( std::cerr, redirectedCerr );
|
||||||
@ -275,38 +265,16 @@ namespace Catch {
|
|||||||
else {
|
else {
|
||||||
m_activeTestCase->invoke();
|
m_activeTestCase->invoke();
|
||||||
}
|
}
|
||||||
duration = timer.getElapsedSeconds();
|
finaliser.stopTimer();
|
||||||
}
|
}
|
||||||
#ifdef INTERNAL_CATCH_VS_MANAGED // detect CLR
|
catch( const Catch::TestFailureException& ) {
|
||||||
catch(AssertFailedException^) {
|
|
||||||
if( aborting() )
|
|
||||||
throw; // CLR always rethrows - stop on first assert
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
catch( INTERNAL_CATCH_TEST_FAILURE_EXCEPTION ) {
|
|
||||||
// This just means the test was aborted due to failure
|
// This just means the test was aborted due to failure
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
catch(...) {
|
catch(...) {
|
||||||
ExpressionResultBuilder exResult( ResultWas::ThrewException );
|
ExpressionResultBuilder exResult( ResultWas::ThrewException );
|
||||||
exResult << translateActiveException();
|
exResult << translateActiveException();
|
||||||
actOnCurrentResult( exResult.buildResult( m_lastAssertionInfo ) );
|
actOnCurrentResult( exResult.buildResult( m_lastAssertionInfo ) );
|
||||||
}
|
}
|
||||||
// If sections ended prematurely due to an exception we stored their
|
|
||||||
// infos here so we can tear them down outside the unwind process.
|
|
||||||
for( std::vector<UnfinishedSections>::const_iterator it = m_unfinishedSections.begin(),
|
|
||||||
itEnd = m_unfinishedSections.end();
|
|
||||||
it != itEnd;
|
|
||||||
++it )
|
|
||||||
sectionEnded( it->info, it->prevAssertions, it->durationInSeconds );
|
|
||||||
m_unfinishedSections.clear();
|
|
||||||
m_messages.clear();
|
|
||||||
|
|
||||||
Counts assertions = m_totals.assertions - prevAssertions;
|
|
||||||
bool missingAssertions = testForMissingAssertions( assertions );
|
|
||||||
|
|
||||||
SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
|
|
||||||
m_reporter->sectionEnded( testCaseSectionStats );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -320,6 +288,111 @@ namespace Catch {
|
|||||||
double durationInSeconds;
|
double durationInSeconds;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class UnwindSectionOnCompletion
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UnwindSectionOnCompletion(RunContext& context, Totals& totals, Ptr<IStreamingReporter>& reporter, TestCaseInfo const& testCaseInfo,
|
||||||
|
std::vector<UnfinishedSections>& unfinishedSections, std::vector<MessageInfo>& messages)
|
||||||
|
: m_context(context)
|
||||||
|
, m_totals(totals)
|
||||||
|
, m_reporter(reporter)
|
||||||
|
, m_testCaseSection( testCaseInfo.name, testCaseInfo.description, testCaseInfo.lineInfo )
|
||||||
|
, m_unfinishedSections(unfinishedSections)
|
||||||
|
, m_messages(messages)
|
||||||
|
, m_duration(0.0)
|
||||||
|
{
|
||||||
|
m_prevAssertions = m_totals.assertions;
|
||||||
|
m_reporter->sectionStarting( m_testCaseSection );
|
||||||
|
}
|
||||||
|
~UnwindSectionOnCompletion()
|
||||||
|
{
|
||||||
|
// If sections ended prematurely due to an exception we stored their
|
||||||
|
// infos here so we can tear them down.
|
||||||
|
for( std::vector<UnfinishedSections>::const_iterator it = m_unfinishedSections.begin(),
|
||||||
|
itEnd = m_unfinishedSections.end();
|
||||||
|
it != itEnd;
|
||||||
|
++it ) {
|
||||||
|
m_context.unwindSection( it->info, it->prevAssertions, it->durationInSeconds );
|
||||||
|
}
|
||||||
|
m_unfinishedSections.clear();
|
||||||
|
m_messages.clear();
|
||||||
|
|
||||||
|
Counts assertions = m_totals.assertions - m_prevAssertions;
|
||||||
|
bool missingAssertions = m_context.testForMissingAssertions( assertions );
|
||||||
|
|
||||||
|
SectionStats testCaseSectionStats( m_testCaseSection, assertions, m_duration, missingAssertions );
|
||||||
|
m_reporter->sectionEnded( testCaseSectionStats );
|
||||||
|
}
|
||||||
|
void startTimer()
|
||||||
|
{
|
||||||
|
m_timer.start();
|
||||||
|
}
|
||||||
|
void stopTimer()
|
||||||
|
{
|
||||||
|
m_duration = m_timer.getElapsedSeconds();
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
// non-copyable
|
||||||
|
UnwindSectionOnCompletion(const UnwindSectionOnCompletion&);
|
||||||
|
UnwindSectionOnCompletion& operator=(const UnwindSectionOnCompletion&);
|
||||||
|
|
||||||
|
RunContext& m_context;
|
||||||
|
Totals& m_totals;
|
||||||
|
Ptr<IStreamingReporter>& m_reporter;
|
||||||
|
SectionInfo m_testCaseSection;
|
||||||
|
std::vector<UnfinishedSections>& m_unfinishedSections;
|
||||||
|
std::vector<MessageInfo>& m_messages;
|
||||||
|
Timer m_timer;
|
||||||
|
Counts m_prevAssertions;
|
||||||
|
double m_duration;
|
||||||
|
};
|
||||||
|
|
||||||
|
class UnwindTestCaseOnCompletion
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UnwindTestCaseOnCompletion(RunContext& context, Totals& totals, Ptr<IStreamingReporter>& reporter, TestCaseInfo& testInfo,
|
||||||
|
std::string& redirectedCout, std::string& redirectedCerr)
|
||||||
|
: m_context(context), m_totals(totals), m_reporter(reporter), m_testInfo(testInfo)
|
||||||
|
, m_redirectedCout(redirectedCout), m_redirectedCerr(redirectedCerr)
|
||||||
|
, m_reported(false)
|
||||||
|
{
|
||||||
|
m_prevTotals = m_totals;
|
||||||
|
m_reporter->testCaseStarting( m_testInfo );
|
||||||
|
}
|
||||||
|
~UnwindTestCaseOnCompletion()
|
||||||
|
{
|
||||||
|
if( !m_reported )
|
||||||
|
{
|
||||||
|
report();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Totals report()
|
||||||
|
{
|
||||||
|
m_reported = true;
|
||||||
|
Totals deltaTotals = m_totals.delta( m_prevTotals );
|
||||||
|
m_totals.testCases += deltaTotals.testCases;
|
||||||
|
m_reporter->testCaseEnded( TestCaseStats( m_testInfo,
|
||||||
|
deltaTotals,
|
||||||
|
m_redirectedCout,
|
||||||
|
m_redirectedCerr,
|
||||||
|
m_context.aborting() ) );
|
||||||
|
return deltaTotals;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
// non-copyable
|
||||||
|
UnwindTestCaseOnCompletion(const UnwindTestCaseOnCompletion&);
|
||||||
|
UnwindTestCaseOnCompletion& operator=(const UnwindTestCaseOnCompletion&);
|
||||||
|
|
||||||
|
RunContext& m_context;
|
||||||
|
Totals& m_totals;
|
||||||
|
Ptr<IStreamingReporter>& m_reporter;
|
||||||
|
TestCaseInfo& m_testInfo;
|
||||||
|
std::string& m_redirectedCout;
|
||||||
|
std::string& m_redirectedCerr;
|
||||||
|
bool m_reported;
|
||||||
|
Totals m_prevTotals;
|
||||||
|
};
|
||||||
|
|
||||||
TestRunInfo m_runInfo;
|
TestRunInfo m_runInfo;
|
||||||
IMutableContext& m_context;
|
IMutableContext& m_context;
|
||||||
TestCase const* m_activeTestCase;
|
TestCase const* m_activeTestCase;
|
||||||
|
@ -24,15 +24,25 @@ namespace Catch {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
#ifdef CATCH_PLATFORM_WINDOWS
|
#ifdef CATCH_PLATFORM_WINDOWS
|
||||||
|
template <typename T>
|
||||||
|
struct CounterDefaults
|
||||||
|
{
|
||||||
|
static T hz;
|
||||||
|
static T hzo;
|
||||||
|
};
|
||||||
|
template <typename T>
|
||||||
|
T CounterDefaults<T>::hz = 0;
|
||||||
|
template <typename T>
|
||||||
|
T CounterDefaults<T>::hzo = 0;
|
||||||
|
|
||||||
INTERNAL_CATCH_INLINE uint64_t getCurrentTicks() {
|
INTERNAL_CATCH_INLINE uint64_t getCurrentTicks() {
|
||||||
static uint64_t hz=0, hzo=0;
|
if (!CounterDefaults<uint64_t>::hz) {
|
||||||
if (!hz) {
|
QueryPerformanceFrequency((LARGE_INTEGER*)&CounterDefaults<uint64_t>::hz);
|
||||||
QueryPerformanceFrequency((LARGE_INTEGER*)&hz);
|
QueryPerformanceCounter((LARGE_INTEGER*)&CounterDefaults<uint64_t>::hzo);
|
||||||
QueryPerformanceCounter((LARGE_INTEGER*)&hzo);
|
|
||||||
}
|
}
|
||||||
uint64_t t;
|
uint64_t t;
|
||||||
QueryPerformanceCounter((LARGE_INTEGER*)&t);
|
QueryPerformanceCounter((LARGE_INTEGER*)&t);
|
||||||
return ((t-hzo)*1000000)/hz;
|
return ((t-CounterDefaults<uint64_t>::hzo)*1000000)/CounterDefaults<uint64_t>::hz;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
INTERNAL_CATCH_INLINE uint64_t getCurrentTicks() {
|
INTERNAL_CATCH_INLINE uint64_t getCurrentTicks() {
|
||||||
|
@ -95,7 +95,11 @@ struct StringMaker<T*> {
|
|||||||
if( !p )
|
if( !p )
|
||||||
return INTERNAL_CATCH_STRINGIFY( NULL );
|
return INTERNAL_CATCH_STRINGIFY( NULL );
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
oss << "0x" << p;
|
||||||
|
#else
|
||||||
oss << p;
|
oss << p;
|
||||||
|
#endif
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -18,7 +18,7 @@ using namespace System::Collections::Generic;
|
|||||||
using namespace Microsoft::VisualStudio::TestTools::UnitTesting;
|
using namespace Microsoft::VisualStudio::TestTools::UnitTesting;
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
inline String^ convert_string_to_managed(const std::string& s)
|
inline String^ convert_string_for_assert(const std::string& s)
|
||||||
{
|
{
|
||||||
String^ result = gcnew String(s.c_str());
|
String^ result = gcnew String(s.c_str());
|
||||||
return result;
|
return result;
|
||||||
@ -26,71 +26,12 @@ namespace Catch {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "internal/catch_timer.hpp"
|
|
||||||
#include "internal/catch_reporter_registrars.hpp"
|
#include "internal/catch_reporter_registrars.hpp"
|
||||||
#include "reporters/catch_vs_reporter.hpp"
|
#include "reporters/catch_vs_reporter.hpp"
|
||||||
#include "catch_registry_hub.hpp"
|
#include "catch_registry_hub.hpp"
|
||||||
|
#include "internal/catch_timer.hpp"
|
||||||
//#define OLD (1)
|
#include "internal/catch_console_colour_impl.hpp"
|
||||||
#ifdef OLD
|
#include "catch_runner.hpp"
|
||||||
namespace Catch {
|
|
||||||
|
|
||||||
class ExceptionRegistryHub : public IRegistryHub, public IMutableRegistryHub {
|
|
||||||
|
|
||||||
ExceptionRegistryHub( ExceptionRegistryHub const& );
|
|
||||||
void operator=( ExceptionRegistryHub const& );
|
|
||||||
|
|
||||||
public: // IRegistryHub
|
|
||||||
ExceptionRegistryHub() {
|
|
||||||
}
|
|
||||||
virtual IReporterRegistry const& getReporterRegistry() const {
|
|
||||||
throw std::runtime_error("can't do this for Visual Studio tests!");
|
|
||||||
}
|
|
||||||
virtual ITestCaseRegistry const& getTestCaseRegistry() const {
|
|
||||||
throw std::runtime_error("can't do this for Visual Studio tests!");
|
|
||||||
}
|
|
||||||
virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() {
|
|
||||||
return m_exceptionTranslatorRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
public: // IMutableRegistryHub
|
|
||||||
virtual void registerReporter( std::string const&, IReporterFactory* ) {
|
|
||||||
throw std::runtime_error("can't do this for Visual Studio tests!");
|
|
||||||
}
|
|
||||||
virtual void registerTest( TestCase const& ) {
|
|
||||||
throw std::runtime_error("can't do this for Visual Studio tests!");
|
|
||||||
}
|
|
||||||
virtual void registerTranslator( const IExceptionTranslator* translator ) {
|
|
||||||
m_exceptionTranslatorRegistry.registerTranslator( translator );
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct GlobalRegistryHub
|
|
||||||
{
|
|
||||||
static T*& instance()
|
|
||||||
{
|
|
||||||
if( !theRegistryHub )
|
|
||||||
theRegistryHub = new T();
|
|
||||||
return theRegistryHub;
|
|
||||||
}
|
|
||||||
static T* theRegistryHub;
|
|
||||||
};
|
|
||||||
template <typename T>
|
|
||||||
T* GlobalRegistryHub<T>::theRegistryHub = NULL;
|
|
||||||
|
|
||||||
INTERNAL_CATCH_INLINE IMutableRegistryHub& getMutableRegistryHub() {
|
|
||||||
return *GlobalRegistryHub<ExceptionRegistryHub>::instance();
|
|
||||||
}
|
|
||||||
INTERNAL_CATCH_INLINE std::string translateActiveException() {
|
|
||||||
return GlobalRegistryHub<ExceptionRegistryHub>::instance()->getExceptionTranslatorRegistry().translateActiveException();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif // OLD
|
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
inline NonCopyable::~NonCopyable() {}
|
inline NonCopyable::~NonCopyable() {}
|
||||||
@ -113,16 +54,10 @@ namespace Catch {
|
|||||||
inline TestCaseStats::~TestCaseStats() {}
|
inline TestCaseStats::~TestCaseStats() {}
|
||||||
inline TestGroupStats::~TestGroupStats() {}
|
inline TestGroupStats::~TestGroupStats() {}
|
||||||
inline TestRunStats::~TestRunStats() {}
|
inline TestRunStats::~TestRunStats() {}
|
||||||
//CumulativeReporterBase::SectionNode::~SectionNode() {}
|
|
||||||
//CumulativeReporterBase::~CumulativeReporterBase() {}
|
|
||||||
|
|
||||||
//StreamingReporterBase::~StreamingReporterBase() {}
|
|
||||||
//ConsoleReporter::~ConsoleReporter() {}
|
|
||||||
inline IRunner::~IRunner() {}
|
inline IRunner::~IRunner() {}
|
||||||
inline IMutableContext::~IMutableContext() {}
|
inline IMutableContext::~IMutableContext() {}
|
||||||
inline IConfig::~IConfig() {}
|
inline IConfig::~IConfig() {}
|
||||||
//XmlReporter::~XmlReporter() {}
|
|
||||||
//JunitReporter::~JunitReporter() {}
|
|
||||||
inline TestRegistry::~TestRegistry() {}
|
inline TestRegistry::~TestRegistry() {}
|
||||||
inline FreeFunctionTestCase::~FreeFunctionTestCase() {}
|
inline FreeFunctionTestCase::~FreeFunctionTestCase() {}
|
||||||
inline IGeneratorInfo::~IGeneratorInfo() {}
|
inline IGeneratorInfo::~IGeneratorInfo() {}
|
||||||
@ -137,8 +72,6 @@ namespace Catch {
|
|||||||
inline Matchers::Impl::StdString::EndsWith::~EndsWith() {}
|
inline Matchers::Impl::StdString::EndsWith::~EndsWith() {}
|
||||||
|
|
||||||
inline void Config::dummy() {}
|
inline void Config::dummy() {}
|
||||||
|
|
||||||
//INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( "xml", XmlReporter )
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -16,71 +16,55 @@ using Microsoft::VisualStudio::CppUnitTestFramework::Logger;
|
|||||||
using Microsoft::VisualStudio::CppUnitTestFramework::Assert;
|
using Microsoft::VisualStudio::CppUnitTestFramework::Assert;
|
||||||
using Microsoft::VisualStudio::CppUnitTestFramework::__LineInfo;
|
using Microsoft::VisualStudio::CppUnitTestFramework::__LineInfo;
|
||||||
|
|
||||||
#define INTERNAL_CATCH_INLINE inline
|
|
||||||
|
|
||||||
#include <cvt/wstring>
|
#include <cvt/wstring>
|
||||||
#include <codecvt>
|
#include <codecvt>
|
||||||
|
|
||||||
#include "internal/catch_timer.hpp"
|
#include "internal/catch_reporter_registrars.hpp"
|
||||||
#include "internal/catch_vs_test_registry.hpp"
|
|
||||||
#include "reporters/catch_vs_reporter.hpp"
|
#include "reporters/catch_vs_reporter.hpp"
|
||||||
|
#include "catch_registry_hub.hpp"
|
||||||
|
#include "internal/catch_timer.hpp"
|
||||||
|
#include "internal/catch_console_colour_impl.hpp"
|
||||||
|
#include "catch_runner.hpp"
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
inline NonCopyable::~NonCopyable() {}
|
||||||
|
inline IShared::~IShared() {}
|
||||||
|
inline StreamBufBase::~StreamBufBase() throw() {}
|
||||||
|
inline IContext::~IContext() {}
|
||||||
|
inline IResultCapture::~IResultCapture() {}
|
||||||
|
inline ITestCase::~ITestCase() {}
|
||||||
|
inline ITestCaseRegistry::~ITestCaseRegistry() {}
|
||||||
|
inline IRegistryHub::~IRegistryHub() {}
|
||||||
|
inline IMutableRegistryHub::~IMutableRegistryHub() {}
|
||||||
|
inline IExceptionTranslator::~IExceptionTranslator() {}
|
||||||
|
inline IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
|
||||||
|
inline IReporter::~IReporter() {}
|
||||||
|
inline IReporterFactory::~IReporterFactory() {}
|
||||||
|
inline IReporterRegistry::~IReporterRegistry() {}
|
||||||
|
inline IStreamingReporter::~IStreamingReporter() {}
|
||||||
|
inline AssertionStats::~AssertionStats() {}
|
||||||
|
inline SectionStats::~SectionStats() {}
|
||||||
|
inline TestCaseStats::~TestCaseStats() {}
|
||||||
|
inline TestGroupStats::~TestGroupStats() {}
|
||||||
|
inline TestRunStats::~TestRunStats() {}
|
||||||
|
|
||||||
class ExceptionRegistryHub : public IRegistryHub, public IMutableRegistryHub {
|
inline IRunner::~IRunner() {}
|
||||||
|
inline IMutableContext::~IMutableContext() {}
|
||||||
|
inline IConfig::~IConfig() {}
|
||||||
|
inline TestRegistry::~TestRegistry() {}
|
||||||
|
inline FreeFunctionTestCase::~FreeFunctionTestCase() {}
|
||||||
|
inline IGeneratorInfo::~IGeneratorInfo() {}
|
||||||
|
inline IGeneratorsForTest::~IGeneratorsForTest() {}
|
||||||
|
inline TagParser::~TagParser() {}
|
||||||
|
inline TagExtracter::~TagExtracter() {}
|
||||||
|
inline TagExpressionParser::~TagExpressionParser() {}
|
||||||
|
|
||||||
ExceptionRegistryHub( ExceptionRegistryHub const& );
|
inline Matchers::Impl::StdString::Equals::~Equals() {}
|
||||||
void operator=( ExceptionRegistryHub const& );
|
inline Matchers::Impl::StdString::Contains::~Contains() {}
|
||||||
|
inline Matchers::Impl::StdString::StartsWith::~StartsWith() {}
|
||||||
public: // IRegistryHub
|
inline Matchers::Impl::StdString::EndsWith::~EndsWith() {}
|
||||||
ExceptionRegistryHub() {
|
|
||||||
}
|
|
||||||
virtual IReporterRegistry const& getReporterRegistry() const {
|
|
||||||
throw std::runtime_error("can't do this for Visual Studio tests!");
|
|
||||||
}
|
|
||||||
virtual ITestCaseRegistry const& getTestCaseRegistry() const {
|
|
||||||
throw std::runtime_error("can't do this for Visual Studio tests!");
|
|
||||||
}
|
|
||||||
virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() {
|
|
||||||
return m_exceptionTranslatorRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
public: // IMutableRegistryHub
|
|
||||||
virtual void registerReporter( std::string const&, IReporterFactory* ) {
|
|
||||||
throw std::runtime_error("can't do this for Visual Studio tests!");
|
|
||||||
}
|
|
||||||
virtual void registerTest( TestCase const& ) {
|
|
||||||
throw std::runtime_error("can't do this for Visual Studio tests!");
|
|
||||||
}
|
|
||||||
virtual void registerTranslator( const IExceptionTranslator* translator ) {
|
|
||||||
m_exceptionTranslatorRegistry.registerTranslator( translator );
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct GlobalRegistryHub
|
|
||||||
{
|
|
||||||
static T& instance()
|
|
||||||
{
|
|
||||||
if( !theRegistryHub )
|
|
||||||
theRegistryHub = new T();
|
|
||||||
return *theRegistryHub;
|
|
||||||
}
|
|
||||||
static T* theRegistryHub;
|
|
||||||
};
|
|
||||||
template <typename T>
|
|
||||||
T* GlobalRegistryHub<T>::theRegistryHub = NULL;
|
|
||||||
|
|
||||||
INTERNAL_CATCH_INLINE IMutableRegistryHub& getMutableRegistryHub() {
|
|
||||||
return GlobalRegistryHub<ExceptionRegistryHub>::instance();
|
|
||||||
}
|
|
||||||
INTERNAL_CATCH_INLINE std::string translateActiveException() {
|
|
||||||
return GlobalRegistryHub<ExceptionRegistryHub>::instance().getExceptionTranslatorRegistry().translateActiveException();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
inline void Config::dummy() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // INTERNAL_CATCH_VS_NATIVE
|
#endif // INTERNAL_CATCH_VS_NATIVE
|
||||||
|
@ -63,7 +63,7 @@ private:
|
|||||||
typedef void(*TestFunction)();
|
typedef void(*TestFunction)();
|
||||||
|
|
||||||
struct NameAndDesc {
|
struct NameAndDesc {
|
||||||
#if (_MANAGED == 1) || (_M_CEE == 1) // detect CLR
|
#ifdef INTERNAL_CATCH_VS_MANAGED
|
||||||
NameAndDesc( const char* _name = "", const char* _description= "" )
|
NameAndDesc( const char* _name = "", const char* _description= "" )
|
||||||
: name( _name ), description( _description )
|
: name( _name ), description( _description )
|
||||||
{}
|
{}
|
||||||
@ -74,14 +74,35 @@ struct NameAndDesc {
|
|||||||
NameAndDesc( const wchar_t* _name, const char* _description= "" )
|
NameAndDesc( const wchar_t* _name, const char* _description= "" )
|
||||||
: name(), description( _description )
|
: name(), description( _description )
|
||||||
{
|
{
|
||||||
stdext::cvt::wstring_convert<std::codecvt_utf8<wchar_t> > conv1;
|
assignName(_name);
|
||||||
name = conv1.to_bytes(_name);
|
|
||||||
}
|
}
|
||||||
NameAndDesc( const wchar_t* _name, int )
|
NameAndDesc( const wchar_t* _name, int )
|
||||||
: name(), description( "" )
|
: name(), description( "" )
|
||||||
|
{
|
||||||
|
assignName(_name);
|
||||||
|
}
|
||||||
|
void assignName(const wchar_t* _name)
|
||||||
{
|
{
|
||||||
stdext::cvt::wstring_convert<std::codecvt_utf8<wchar_t> > conv1;
|
stdext::cvt::wstring_convert<std::codecvt_utf8<wchar_t> > conv1;
|
||||||
name = conv1.to_bytes(_name);
|
std::string tmp = conv1.to_bytes(_name);
|
||||||
|
if( tmp.empty() )
|
||||||
|
{
|
||||||
|
name = tmp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::string::iterator startIter = tmp.begin();
|
||||||
|
if(*startIter == '\"')
|
||||||
|
{
|
||||||
|
++startIter;
|
||||||
|
}
|
||||||
|
std::string::reverse_iterator endIter = tmp.rbegin();
|
||||||
|
if(*endIter == '\"')
|
||||||
|
{
|
||||||
|
++endIter;
|
||||||
|
}
|
||||||
|
name.assign(startIter, endIter.base());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -120,7 +141,7 @@ private:
|
|||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
#if (_MANAGED == 1) || (_M_CEE == 1) // detect CLR
|
#ifdef INTERNAL_CATCH_VS_MANAGED
|
||||||
|
|
||||||
#define CATCH_INTERNAL_HANDLE_EMPTY_PARAM2( name ) name##""
|
#define CATCH_INTERNAL_HANDLE_EMPTY_PARAM2( name ) name##""
|
||||||
#define CATCH_INTERNAL_HANDLE_EMPTY_PARAM(...) CATCH_INTERNAL_HANDLE_EMPTY_PARAM2( INTERNAL_CATCH_SPLIT_ARGS_2(__VA_ARGS__) )
|
#define CATCH_INTERNAL_HANDLE_EMPTY_PARAM(...) CATCH_INTERNAL_HANDLE_EMPTY_PARAM2( INTERNAL_CATCH_SPLIT_ARGS_2(__VA_ARGS__) )
|
||||||
@ -147,7 +168,7 @@ private:
|
|||||||
|
|
||||||
#define CATCH_INTERNAL_NAMESPACE( Ext )
|
#define CATCH_INTERNAL_NAMESPACE( Ext )
|
||||||
|
|
||||||
#define INTERNAL_CATCH_TEST_METHOD( Method, UniqueExt, Name, Desc ) \
|
#define INTERNAL_CATCH_TEST_METHOD( Count, UniqueExt, Name, Desc ) \
|
||||||
public: \
|
public: \
|
||||||
[TestMethod] \
|
[TestMethod] \
|
||||||
[Description( CATCH_INTERNAL_HANDLE_EMPTY_PARAM(Name) )] \
|
[Description( CATCH_INTERNAL_HANDLE_EMPTY_PARAM(Name) )] \
|
||||||
@ -155,22 +176,24 @@ private:
|
|||||||
void INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H___M_E_T_H_O_D___, UniqueExt) () \
|
void INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H___M_E_T_H_O_D___, UniqueExt) () \
|
||||||
{ \
|
{ \
|
||||||
Catch::NameAndDesc name_desc( CATCH_INTERNAL_HANDLE_EMPTY_PARAM(Name), Desc ); \
|
Catch::NameAndDesc name_desc( CATCH_INTERNAL_HANDLE_EMPTY_PARAM(Name), Desc ); \
|
||||||
CATCH_INTERNAL_RUN_SINGLE_TEST( Method ); \
|
CATCH_INTERNAL_RUN_SINGLE_TEST(Count); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define INTERNAL_CATCH_TEST_CLASS_METHOD( Method, UniqueExt, Name, Desc ) \
|
#define BEGIN_INTERNAL_CATCH_BATCH_METHOD( Tags, UniqueExt ) \
|
||||||
public: \
|
public: \
|
||||||
[TestMethod] \
|
[TestMethod] \
|
||||||
[Description( CATCH_INTERNAL_HANDLE_EMPTY_PARAM(Name) )] \
|
[TestCategory( CATCH_INTERNAL_HANDLE_EMPTY_PARAM(Tags) )] \
|
||||||
[TestProperty( "Description", CATCH_INTERNAL_HANDLE_EMPTY_PARAM(Name) )] \
|
[Description( CATCH_INTERNAL_HANDLE_EMPTY_PARAM(Tags) )] \
|
||||||
void INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H___M_E_T_H_O_D___, UniqueExt) () \
|
[TestProperty( "Description", CATCH_INTERNAL_HANDLE_EMPTY_PARAM(Tags) )] \
|
||||||
{ \
|
void INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H___M_E_T_H_O_D___, UniqueExt) ()
|
||||||
Catch::NameAndDesc name_desc( CATCH_INTERNAL_HANDLE_EMPTY_PARAM(Name), Desc ); \
|
|
||||||
CATCH_INTERNAL_RUN_SINGLE_CLASS_TEST( Method ); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CHECK_FOR_TEST_CASE_CLASH
|
#define CHECK_FOR_TEST_CASE_CLASH
|
||||||
|
|
||||||
|
#define INTERNAL_CATCH_MAP_CATEGORY_TO_TAG( Category, Tag ) \
|
||||||
|
INTERNAL_CATCH_MAP_CATEGORY_TO_TAG2( #Category, Tag, __COUNTER__ )
|
||||||
|
|
||||||
|
#define FAIL_STRING( str ) _T( str )
|
||||||
|
|
||||||
#else // detect CLR
|
#else // detect CLR
|
||||||
|
|
||||||
// Native tests
|
// Native tests
|
||||||
@ -186,108 +209,161 @@ private:
|
|||||||
#define TEST_IMPL_2(tuple) TEST_IMPL2 tuple
|
#define TEST_IMPL_2(tuple) TEST_IMPL2 tuple
|
||||||
#define TEST_IMPL2( INTERNAL_CATCH_SPLIT_ARG_1,INTERNAL_CATCH_SPLIT_ARG_2,N,...) L#INTERNAL_CATCH_SPLIT_ARG_1
|
#define TEST_IMPL2( INTERNAL_CATCH_SPLIT_ARG_1,INTERNAL_CATCH_SPLIT_ARG_2,N,...) L#INTERNAL_CATCH_SPLIT_ARG_1
|
||||||
|
|
||||||
#define CATCH_INTERNAL_HANDLE_EMPTY_PARAM(...) CATCH_INTERNAL_HANDLE_EMPTY_PARAM_IMPL( (__VA_ARGS__, 2, 1) )
|
#define CATCH_INTERNAL_HANDLE_EMPTY_PARAM(...) CATCH_INTERNAL_HANDLE_EMPTY_PARAM_IMPLW( (__VA_ARGS__, 2, 1) )
|
||||||
#define CATCH_INTERNAL_HANDLE_EMPTY_PARAM_IMPL(tuple) CATCH_INTERNAL_HANDLE_EMPTY_PARAM_IMPL2 tuple
|
|
||||||
#define CATCH_INTERNAL_HANDLE_EMPTY_PARAM_IMPL2( INTERNAL_CATCH_SPLIT_ARG_1,INTERNAL_CATCH_SPLIT_ARG_2,N,...) #INTERNAL_CATCH_SPLIT_ARG_1
|
|
||||||
#define CATCH_INTERNAL_HANDLE_EMPTY_PARAMW(...) CATCH_INTERNAL_HANDLE_EMPTY_PARAM_IMPLW( (__VA_ARGS__, 2, 1) )
|
|
||||||
#define CATCH_INTERNAL_HANDLE_EMPTY_PARAM_IMPLW(tuple) CATCH_INTERNAL_HANDLE_EMPTY_PARAM_IMPL2W tuple
|
#define CATCH_INTERNAL_HANDLE_EMPTY_PARAM_IMPLW(tuple) CATCH_INTERNAL_HANDLE_EMPTY_PARAM_IMPL2W tuple
|
||||||
#define CATCH_INTERNAL_HANDLE_EMPTY_PARAM_IMPL2W( INTERNAL_CATCH_SPLIT_ARG_1,INTERNAL_CATCH_SPLIT_ARG_2,N,...) L#INTERNAL_CATCH_SPLIT_ARG_1
|
#define CATCH_INTERNAL_HANDLE_EMPTY_PARAM_IMPL2W( INTERNAL_CATCH_SPLIT_ARG_1,INTERNAL_CATCH_SPLIT_ARG_2,N,...) L#INTERNAL_CATCH_SPLIT_ARG_1
|
||||||
|
|
||||||
#define INTERNAL_CATCH_TEST_METHOD( Method, UniqueExt, Name, Desc ) \
|
#define INTERNAL_CATCH_TEST_METHOD( Count, UniqueExt, Name, Desc ) \
|
||||||
public: \
|
public: \
|
||||||
BEGIN_TEST_METHOD_ATTRIBUTE( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H___M_E_T_H_O_D___, UniqueExt) ) \
|
BEGIN_TEST_METHOD_ATTRIBUTE( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H___M_E_T_H_O_D___, UniqueExt) ) \
|
||||||
TEST_OWNER( CATCH_INTERNAL_HANDLE_EMPTY_PARAMW(Name) ) \
|
TEST_OWNER( CATCH_INTERNAL_HANDLE_EMPTY_PARAM(Name) ) \
|
||||||
TEST_DESCRIPTION( CATCH_INTERNAL_HANDLE_EMPTY_PARAMW(Name) ) \
|
TEST_DESCRIPTION( CATCH_INTERNAL_HANDLE_EMPTY_PARAM(Name) ) \
|
||||||
END_TEST_METHOD_ATTRIBUTE() \
|
END_TEST_METHOD_ATTRIBUTE() \
|
||||||
TEST_METHOD( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H___M_E_T_H_O_D___, UniqueExt) ) \
|
TEST_METHOD( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H___M_E_T_H_O_D___, UniqueExt) ) \
|
||||||
{ \
|
{ \
|
||||||
Catch::NameAndDesc name_desc(CATCH_INTERNAL_HANDLE_EMPTY_PARAMW(Name), Desc ); \
|
Catch::NameAndDesc name_desc(CATCH_INTERNAL_HANDLE_EMPTY_PARAM(Name), Desc ); \
|
||||||
CATCH_INTERNAL_RUN_SINGLE_TEST( Method ); \
|
CATCH_INTERNAL_RUN_SINGLE_TEST(Count); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define INTERNAL_CATCH_TEST_CLASS_METHOD( Method, UniqueExt, Name, Desc ) \
|
#define BEGIN_INTERNAL_CATCH_BATCH_METHOD( Tags, UniqueExt ) \
|
||||||
public: \
|
public: \
|
||||||
BEGIN_TEST_METHOD_ATTRIBUTE( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H___M_E_T_H_O_D___, UniqueExt) ) \
|
BEGIN_TEST_METHOD_ATTRIBUTE( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H___M_E_T_H_O_D___, UniqueExt) ) \
|
||||||
TEST_OWNER( CATCH_INTERNAL_HANDLE_EMPTY_PARAMW(Name) ) \
|
TEST_OWNER( CATCH_INTERNAL_HANDLE_EMPTY_PARAM(Tags) ) \
|
||||||
TEST_DESCRIPTION( CATCH_INTERNAL_HANDLE_EMPTY_PARAMW(Name) ) \
|
TEST_DESCRIPTION( CATCH_INTERNAL_HANDLE_EMPTY_PARAM(Tags) ) \
|
||||||
END_TEST_METHOD_ATTRIBUTE() \
|
END_TEST_METHOD_ATTRIBUTE() \
|
||||||
TEST_METHOD( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H___M_E_T_H_O_D___, UniqueExt) ) \
|
TEST_METHOD( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H___M_E_T_H_O_D___, UniqueExt) )
|
||||||
{ \
|
|
||||||
Catch::NameAndDesc name_desc( CATCH_INTERNAL_HANDLE_EMPTY_PARAMW(Name), Desc ); \
|
|
||||||
CATCH_INTERNAL_RUN_SINGLE_CLASS_TEST( Method ); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CHECK_FOR_TEST_CASE_CLASH void INTERNAL_CATCH_UNIQUE_NAME_LINE( if_you_get_this_error_you_have_a_test_case_name_clash_please_put_a_namespace_around_the_test_case_at_line_, __LINE__ )() {}
|
#define CHECK_FOR_TEST_CASE_CLASH void INTERNAL_CATCH_UNIQUE_NAME_LINE( if_you_get_this_error_you_have_a_test_case_name_clash_please_put_a_namespace_around_the_test_case_at_line_, __LINE__ )() {}
|
||||||
|
|
||||||
|
#define INTERNAL_CATCH_MAP_CATEGORY_TO_TAG( Category, Tag ) \
|
||||||
|
INTERNAL_CATCH_MAP_CATEGORY_TO_TAG2( Category, Tag, __COUNTER__ )
|
||||||
|
|
||||||
|
#define FAIL_STRING( str ) WIDEN( str )
|
||||||
|
|
||||||
#endif // detect CLR
|
#endif // detect CLR
|
||||||
|
|
||||||
#define INTERNAL_CATCH_CONCAT_LINE_COUNTER INTERNAL_CATCH_UNIQUE_NAME_LINE( INTERNAL_CATCH_UNIQUE_NAME_LINE( __LINE__, _ ), __COUNTER__ )
|
#define INTERNAL_CATCH_CONCAT_LINE_COUNTER( count ) INTERNAL_CATCH_UNIQUE_NAME_LINE( INTERNAL_CATCH_UNIQUE_NAME_LINE( __LINE__, _ ), count )
|
||||||
|
|
||||||
#define CATCH_INTERNAL_RUN_SINGLE_TEST( Method ) \
|
#define CATCH_INTERNAL_CONFIG_SHOW_SUCCESS2( v, Count ) \
|
||||||
{ Catch::ConfigData cd; \
|
namespace { CatchOverrides::ConfigShowSuccessfulTests<Catch::IConfig const*> INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H_____O_V_E_R_R_I_D_E____, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )(__FILE__, Count, v); }
|
||||||
|
|
||||||
|
#define CATCH_INTERNAL_CONFIG_WARN_MISSING_ASSERTIONS2( v, Count ) \
|
||||||
|
namespace { CatchOverrides::ConfigWarnMissingAssertions<Catch::IConfig const*> INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H_____O_V_E_R_R_I_D_E____, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )(__FILE__, Count, v); }
|
||||||
|
|
||||||
|
#define CATCH_INTERNAL_CONFIG_SHOW_SUCCESS( v ) \
|
||||||
|
CATCH_INTERNAL_CONFIG_SHOW_SUCCESS2( v, __COUNTER__)
|
||||||
|
|
||||||
|
#define CATCH_INTERNAL_CONFIG_WARN_MISSING_ASSERTIONS( v ) \
|
||||||
|
CATCH_INTERNAL_CONFIG_WARN_MISSING_ASSERTIONS2( v, __COUNTER__)
|
||||||
|
|
||||||
|
#define CATCH_INTERNAL_RUN_SINGLE_TEST( Count ) \
|
||||||
|
{ CatchOverrides::ConfigGuard cg; \
|
||||||
|
Catch::ConfigData cd(cg.value().get()); \
|
||||||
cd.name = name_desc.name; \
|
cd.name = name_desc.name; \
|
||||||
cd.abortAfter = 1; \
|
cd.abortAfter = 1; \
|
||||||
|
cd.showSuccessfulTests = CatchOverrides::Config<Catch::IConfig const*>::instance().includeSuccessfulResults(__FILE__, Count ); \
|
||||||
|
cd.warnings = (CatchOverrides::Config<Catch::IConfig const*>::instance().warnAboutMissingAssertions(__FILE__, Count ) ? Catch::WarnAbout::NoAssertions : Catch::WarnAbout::Nothing); \
|
||||||
Catch::Ptr<Catch::Config> config(new Catch::Config(cd)); \
|
Catch::Ptr<Catch::Config> config(new Catch::Config(cd)); \
|
||||||
Catch::MSTestReporter* rep = new Catch::MSTestReporter(config.get()); \
|
Catch::MSTestReporter* rep = new Catch::MSTestReporter(config.get()); \
|
||||||
Catch::RunContext tr(config.get(), rep); \
|
Catch::RunContext tr(config.get(), rep); \
|
||||||
std::vector<Catch::TestCase> testCase = Catch::getRegistryHub().getTestCaseRegistry().getMatchingTestCases(name_desc.name); \
|
std::vector<Catch::TestCase> testCase = Catch::getRegistryHub().getTestCaseRegistry().getMatchingTestCases(name_desc.name); \
|
||||||
if( testCase.empty() ) Assert::Fail("No tests match"); \
|
if( testCase.empty() ) Assert::Fail(FAIL_STRING("No tests match")); \
|
||||||
if( testCase.size() > 1 ) Assert::Fail("More than one test with the same name"); \
|
if( testCase.size() > 1 ) Assert::Fail(FAIL_STRING("More than one test with the same name")); \
|
||||||
tr.runTest(*testCase.begin()); \
|
Catch::Totals totals = tr.runTest(*testCase.begin()); \
|
||||||
|
if( totals.assertions.failed > 0 ) { \
|
||||||
|
INTERNAL_CATCH_TEST_THROW_FAILURE \
|
||||||
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CATCH_INTERNAL_RUN_SINGLE_CLASS_TEST( ClassMethod ) \
|
#define INTERNAL_CATCH_TESTCASE2( Count, Name, Desc ) \
|
||||||
{ Catch::ConfigData cd; \
|
|
||||||
cd.name = name_desc.name; \
|
|
||||||
cd.abortAfter = 1; \
|
|
||||||
Catch::Ptr<Catch::Config> config(new Catch::Config(cd)); \
|
|
||||||
Catch::MSTestReporter* rep = new Catch::MSTestReporter(config.get()); \
|
|
||||||
Catch::RunContext tr(config.get(), rep); \
|
|
||||||
std::vector<Catch::TestCase> testCase = Catch::getRegistryHub().getTestCaseRegistry().getMatchingTestCases(name_desc.name); \
|
|
||||||
if( testCase.empty() ) Assert::Fail("No tests match"); \
|
|
||||||
if( testCase.size() > 1 ) Assert::Fail("More than one test with the same name"); \
|
|
||||||
tr.runTest(*testCase.begin()); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define INTERNAL_CATCH_TESTCASE2( UniqueExt, Name, Desc ) \
|
|
||||||
CHECK_FOR_TEST_CASE_CLASH \
|
CHECK_FOR_TEST_CASE_CLASH \
|
||||||
static void INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, UniqueExt )(); \
|
static void INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )(); \
|
||||||
namespace CATCH_INTERNAL_NAMESPACE( UniqueExt ) { \
|
namespace CATCH_INTERNAL_NAMESPACE( INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) { \
|
||||||
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( & INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, UniqueExt ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc(Name, Desc) ); \
|
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( & INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc(CATCH_INTERNAL_HANDLE_EMPTY_PARAM(Name), Desc) ); \
|
||||||
INTERNAL_CATCH_CLASS_DEFINITION( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_L_A_S_S___, UniqueExt ) ) \
|
CatchOverrides::ConfigReset<Catch::IConfig const*> INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_O_N_F_I_G___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )(__FILE__, Count); \
|
||||||
|
INTERNAL_CATCH_CLASS_DEFINITION( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_L_A_S_S___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) ) \
|
||||||
{ \
|
{ \
|
||||||
INTERNAL_CATCH_CLASS_CONTEXT \
|
INTERNAL_CATCH_CLASS_CONTEXT \
|
||||||
INTERNAL_CATCH_TEST_METHOD( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, UniqueExt ), UniqueExt, Name, Desc ) \
|
INTERNAL_CATCH_TEST_METHOD( Count, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ), Name, Desc ) \
|
||||||
}; \
|
}; \
|
||||||
} \
|
} \
|
||||||
void INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, UniqueExt )()
|
void INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )()
|
||||||
|
|
||||||
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE2( QualifiedMethod, UniqueExt, Name, Desc ) \
|
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE2( QualifiedMethod, Count, Name, Desc ) \
|
||||||
CHECK_FOR_TEST_CASE_CLASH \
|
CHECK_FOR_TEST_CASE_CLASH \
|
||||||
namespace CATCH_INTERNAL_NAMESPACE( UniqueExt ) { \
|
namespace CATCH_INTERNAL_NAMESPACE( INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) { \
|
||||||
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( & QualifiedMethod, "&" # QualifiedMethod, Catch::NameAndDesc(Name, Desc), CATCH_INTERNAL_LINEINFO ); \
|
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( & QualifiedMethod, "&" # QualifiedMethod, Catch::NameAndDesc(CATCH_INTERNAL_HANDLE_EMPTY_PARAM(Name), Desc), CATCH_INTERNAL_LINEINFO ); \
|
||||||
INTERNAL_CATCH_CLASS_DEFINITION( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_L_A_S_S___, UniqueExt ) ) \
|
CatchOverrides::ConfigReset<Catch::IConfig const*> INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_O_N_F_I_G___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )(__FILE__, Count); \
|
||||||
|
INTERNAL_CATCH_CLASS_DEFINITION( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_L_A_S_S___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) ) \
|
||||||
{ \
|
{ \
|
||||||
INTERNAL_CATCH_CLASS_CONTEXT \
|
INTERNAL_CATCH_CLASS_CONTEXT \
|
||||||
INTERNAL_CATCH_TEST_CLASS_METHOD( QualifiedMethod, UniqueExt, Name, Desc ) \
|
INTERNAL_CATCH_TEST_METHOD( Count, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ), Name, Desc ) \
|
||||||
}; \
|
}; \
|
||||||
};
|
};
|
||||||
|
|
||||||
#define INTERNAL_CATCH_TEST_CASE_METHOD2( ClassName, UniqueExt, TestName, Desc ) \
|
#define INTERNAL_CATCH_TEST_CASE_METHOD2( ClassName, Count, TestName, Desc ) \
|
||||||
CHECK_FOR_TEST_CASE_CLASH \
|
CHECK_FOR_TEST_CASE_CLASH \
|
||||||
struct INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, UniqueExt ) : ClassName { \
|
struct INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) : ClassName { \
|
||||||
void test(); \
|
void test(); \
|
||||||
static void invoke() { INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, UniqueExt ) tmp; tmp.test(); } \
|
static void invoke() { INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) tmp; tmp.test(); } \
|
||||||
}; \
|
}; \
|
||||||
namespace CATCH_INTERNAL_NAMESPACE( UniqueExt ) { \
|
namespace CATCH_INTERNAL_NAMESPACE( INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) { \
|
||||||
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( & INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, UniqueExt )::invoke, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc(TestName, Desc) ); \
|
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( & INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )::invoke, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc(CATCH_INTERNAL_HANDLE_EMPTY_PARAM(TestName), Desc) ); \
|
||||||
INTERNAL_CATCH_CLASS_DEFINITION( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_L_A_S_S___, UniqueExt ) ) \
|
CatchOverrides::ConfigReset<Catch::IConfig const*> INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_O_N_F_I_G___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )(__FILE__, Count); \
|
||||||
|
INTERNAL_CATCH_CLASS_DEFINITION( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_L_A_S_S___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) ) \
|
||||||
{ \
|
{ \
|
||||||
INTERNAL_CATCH_CLASS_CONTEXT \
|
INTERNAL_CATCH_CLASS_CONTEXT \
|
||||||
INTERNAL_CATCH_TEST_METHOD( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, UniqueExt )::invoke, UniqueExt, TestName, Desc ) \
|
INTERNAL_CATCH_TEST_METHOD( Count, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ), TestName, Desc ) \
|
||||||
}; \
|
}; \
|
||||||
} \
|
} \
|
||||||
void INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, UniqueExt )::test()
|
void INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )::test()
|
||||||
|
|
||||||
|
#if defined(INTERNAL_CATCH_VS_MANAGED)
|
||||||
|
|
||||||
|
#define INTERNAL_CATCH_TEST_REPORT_BATCH_FAILURE( count ) \
|
||||||
|
{ \
|
||||||
|
std::stringstream _sf; \
|
||||||
|
_sf << count << " assertions failed - check output for results."; \
|
||||||
|
std::string fail = _sf.str(); \
|
||||||
|
Assert::Fail(Catch::convert_string_for_assert(fail)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define INTERNAL_CATCH_TEST_REPORT_BATCH_FAILURE( count ) \
|
||||||
|
{ \
|
||||||
|
std::wstringstream _s; \
|
||||||
|
_s << count << " assertions failed - check output for results."; \
|
||||||
|
std::wstring ws = _s.str(); \
|
||||||
|
Assert::Fail(ws.c_str()); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define INTERNAL_CATCH_MAP_CATEGORY_TO_TAG2( Category, Tag, Count ) \
|
||||||
|
CHECK_FOR_TEST_CASE_CLASH \
|
||||||
|
namespace CATCH_INTERNAL_NAMESPACE( INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) { \
|
||||||
|
CatchOverrides::ConfigReset<Catch::IConfig const*> INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_O_N_F_I_G___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )(__FILE__, Count); \
|
||||||
|
INTERNAL_CATCH_CLASS_DEFINITION( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_L_A_S_S___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) ) \
|
||||||
|
{ \
|
||||||
|
INTERNAL_CATCH_CLASS_CONTEXT \
|
||||||
|
BEGIN_INTERNAL_CATCH_BATCH_METHOD( Category, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) \
|
||||||
|
{ \
|
||||||
|
Catch::ConfigData cd; \
|
||||||
|
cd.showSuccessfulTests = CatchOverrides::Config<Catch::IConfig const*>::instance().includeSuccessfulResults(__FILE__, Count ); \
|
||||||
|
cd.warnings = (CatchOverrides::Config<Catch::IConfig const*>::instance().warnAboutMissingAssertions(__FILE__, Count ) ? Catch::WarnAbout::NoAssertions : Catch::WarnAbout::Nothing); \
|
||||||
|
cd.reporterName = "vs_reporter"; \
|
||||||
|
cd.name = "Batch run using tag : " Tag; \
|
||||||
|
cd.testsOrTags.push_back( Tag ); \
|
||||||
|
Catch::Ptr<Catch::Config> config(new Catch::Config(cd)); \
|
||||||
|
Catch::ReporterRegistrar<Catch::MSTestReporter> reporterReg("vs_reporter"); \
|
||||||
|
Catch::Runner runner(config); \
|
||||||
|
Catch::Totals totals = runner.runTests(); \
|
||||||
|
if( totals.assertions.failed > 0 ) { \
|
||||||
|
INTERNAL_CATCH_TEST_REPORT_BATCH_FAILURE(totals.assertions.failed) \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}; \
|
||||||
|
}
|
||||||
|
|
||||||
//#undef CATCH_CONFIG_VARIADIC_MACROS
|
//#undef CATCH_CONFIG_VARIADIC_MACROS
|
||||||
|
|
||||||
@ -301,29 +377,29 @@ private:
|
|||||||
#define INTERNAL_CATCH_SPLIT_TAGS_IMPL_(INTERNAL_CATCH_SPLIT_ARG_1,INTERNAL_CATCH_SPLIT_ARG_2,N,...) INTERNAL_CATCH_SPLIT_ARG_2
|
#define INTERNAL_CATCH_SPLIT_TAGS_IMPL_(INTERNAL_CATCH_SPLIT_ARG_1,INTERNAL_CATCH_SPLIT_ARG_2,N,...) INTERNAL_CATCH_SPLIT_ARG_2
|
||||||
|
|
||||||
#define INTERNAL_CATCH_TESTCASE( ... ) \
|
#define INTERNAL_CATCH_TESTCASE( ... ) \
|
||||||
INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_CONCAT_LINE_COUNTER, INTERNAL_CATCH_SPLIT_ARGS_2(__VA_ARGS__), INTERNAL_CATCH_SPLIT_TAGS(__VA_ARGS__) )
|
INTERNAL_CATCH_TESTCASE2( __COUNTER__ , INTERNAL_CATCH_SPLIT_ARGS_2(__VA_ARGS__), INTERNAL_CATCH_SPLIT_TAGS(__VA_ARGS__) )
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
|
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
|
||||||
INTERNAL_CATCH_METHOD_AS_TEST_CASE2( QualifiedMethod, INTERNAL_CATCH_CONCAT_LINE_COUNTER, INTERNAL_CATCH_SPLIT_ARGS_2(__VA_ARGS__), INTERNAL_CATCH_SPLIT_TAGS(__VA_ARGS__) )
|
INTERNAL_CATCH_METHOD_AS_TEST_CASE2( QualifiedMethod, __COUNTER__, INTERNAL_CATCH_SPLIT_ARGS_2(__VA_ARGS__), INTERNAL_CATCH_SPLIT_TAGS(__VA_ARGS__) )
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... )\
|
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... )\
|
||||||
INTERNAL_CATCH_TEST_CASE_METHOD2(ClassName, INTERNAL_CATCH_CONCAT_LINE_COUNTER, INTERNAL_CATCH_SPLIT_ARGS_2(__VA_ARGS__), INTERNAL_CATCH_SPLIT_TAGS(__VA_ARGS__) )
|
INTERNAL_CATCH_TEST_CASE_METHOD2(ClassName, __COUNTER__, INTERNAL_CATCH_SPLIT_ARGS_2(__VA_ARGS__), INTERNAL_CATCH_SPLIT_TAGS(__VA_ARGS__) )
|
||||||
|
|
||||||
#else
|
#else
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
|
#define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
|
||||||
INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_CONCAT_LINE_COUNTER, Name, Desc )
|
INTERNAL_CATCH_TESTCASE2( __COUNTER__ , Name, Desc )
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
|
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
|
||||||
INTERNAL_CATCH_METHOD_AS_TEST_CASE2( QualifiedMethod, INTERNAL_CATCH_CONCAT_LINE_COUNTER, Name, Desc )
|
INTERNAL_CATCH_METHOD_AS_TEST_CASE2( QualifiedMethod, __COUNTER__, Name, Desc )
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
|
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
|
||||||
INTERNAL_CATCH_TEST_CASE_METHOD2(ClassName, INTERNAL_CATCH_CONCAT_LINE_COUNTER, TestName, Desc )
|
INTERNAL_CATCH_TEST_CASE_METHOD2(ClassName, __COUNTER__, TestName, Desc )
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -49,18 +49,24 @@ namespace Catch {
|
|||||||
MSTestReporter( ReporterConfig const& _config )
|
MSTestReporter( ReporterConfig const& _config )
|
||||||
: m_config( _config.fullConfig() ),
|
: m_config( _config.fullConfig() ),
|
||||||
m_headerPrinted( false ),
|
m_headerPrinted( false ),
|
||||||
m_atLeastOneTestCasePrinted( false )
|
m_atLeastOneTestCasePrinted( false ),
|
||||||
|
m_failed(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
MSTestReporter( Ptr<IConfig> const& _fullConfig )
|
MSTestReporter( Ptr<IConfig> const& _fullConfig )
|
||||||
: m_config( _fullConfig ),
|
: m_config( _fullConfig ),
|
||||||
m_headerPrinted( false ),
|
m_headerPrinted( false ),
|
||||||
m_atLeastOneTestCasePrinted( false )
|
m_atLeastOneTestCasePrinted( false ),
|
||||||
|
m_failed(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual ~MSTestReporter() {
|
virtual ~MSTestReporter() {
|
||||||
if( m_atLeastOneTestCasePrinted ) {
|
if( m_atLeastOneTestCasePrinted ) {
|
||||||
write_output_message(stream.str());
|
write_output_message(stream.str());
|
||||||
|
/*if( m_failed )
|
||||||
|
{
|
||||||
|
Assert::IsTrue(false, L"At least one test failed - examine output for failures.");
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,9 +132,6 @@ namespace Catch {
|
|||||||
write_output_message(_testCaseStats.stdErr);
|
write_output_message(_testCaseStats.stdErr);
|
||||||
write_output_message(getDoubleDashes());
|
write_output_message(getDoubleDashes());
|
||||||
}
|
}
|
||||||
if( _testCaseStats.totals.assertions.failed ) {
|
|
||||||
Assert::IsTrue(false, L"At least one test failed - examine output for CHECK failures.");
|
|
||||||
}
|
|
||||||
m_headerPrinted = false;
|
m_headerPrinted = false;
|
||||||
currentTestCaseInfo.reset();
|
currentTestCaseInfo.reset();
|
||||||
assert( m_sectionStack.empty() );
|
assert( m_sectionStack.empty() );
|
||||||
@ -147,6 +150,7 @@ namespace Catch {
|
|||||||
printTotalsDivider();
|
printTotalsDivider();
|
||||||
printTotals( _testRunStats.totals );
|
printTotals( _testRunStats.totals );
|
||||||
stream << "\r\n" << "\r\n";
|
stream << "\r\n" << "\r\n";
|
||||||
|
m_failed = _testRunStats.totals.testCases.failed;
|
||||||
currentTestCaseInfo.reset();
|
currentTestCaseInfo.reset();
|
||||||
currentGroupInfo.reset();
|
currentGroupInfo.reset();
|
||||||
currentTestRunInfo.reset();
|
currentTestRunInfo.reset();
|
||||||
@ -454,6 +458,7 @@ namespace Catch {
|
|||||||
std::vector<SectionInfo> m_sectionStack;
|
std::vector<SectionInfo> m_sectionStack;
|
||||||
bool m_headerPrinted;
|
bool m_headerPrinted;
|
||||||
bool m_atLeastOneTestCasePrinted;
|
bool m_atLeastOneTestCasePrinted;
|
||||||
|
size_t m_failed;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
187
projects/SelfTest/RunAllTests.cpp
Normal file
187
projects/SelfTest/RunAllTests.cpp
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
/*
|
||||||
|
* Created by Phil on 22/10/2010.
|
||||||
|
* Copyright 2010 Two Blue Cubes Ltd
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "catch.hpp"
|
||||||
|
#include "internal/catch_text.h"
|
||||||
|
#include "internal/catch_console_colour.hpp"
|
||||||
|
|
||||||
|
namespace AllTestsRunner {
|
||||||
|
|
||||||
|
class NullStreamingReporter : public Catch::SharedImpl<Catch::IStreamingReporter> {
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~NullStreamingReporter();
|
||||||
|
|
||||||
|
static std::string getDescription() {
|
||||||
|
return "null reporter";
|
||||||
|
}
|
||||||
|
|
||||||
|
private: // IStreamingReporter
|
||||||
|
|
||||||
|
virtual Catch::ReporterPreferences getPreferences() const {
|
||||||
|
return Catch::ReporterPreferences();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void noMatchingTestCases( std::string const& ) {}
|
||||||
|
virtual void testRunStarting( Catch::TestRunInfo const& ) {}
|
||||||
|
virtual void testGroupStarting( Catch::GroupInfo const& ) {}
|
||||||
|
virtual void testCaseStarting( Catch::TestCaseInfo const& ) {}
|
||||||
|
virtual void sectionStarting( Catch::SectionInfo const& ) {}
|
||||||
|
virtual void assertionStarting( Catch::AssertionInfo const& ) {}
|
||||||
|
virtual bool assertionEnded( Catch::AssertionStats const& ) { return false; }
|
||||||
|
virtual void sectionEnded( Catch::SectionStats const& ) {}
|
||||||
|
virtual void testCaseEnded( Catch::TestCaseStats const& ) {}
|
||||||
|
virtual void testGroupEnded( Catch::TestGroupStats const& ) {}
|
||||||
|
virtual void testRunEnded( Catch::TestRunStats const& ) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class EmbeddedRunner {
|
||||||
|
|
||||||
|
public:
|
||||||
|
EmbeddedRunner() : m_reporter( new NullStreamingReporter() ) {}
|
||||||
|
|
||||||
|
Catch::Totals runMatching( const std::string& rawTestSpec,
|
||||||
|
std::size_t groupIndex,
|
||||||
|
std::size_t groupsCount,
|
||||||
|
const std::string& reporter = "console" );
|
||||||
|
|
||||||
|
private:
|
||||||
|
Catch::Ptr<Catch::IStreamingReporter> m_reporter;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MetaTestRunner {
|
||||||
|
|
||||||
|
public:
|
||||||
|
struct Expected { enum Result {
|
||||||
|
ToSucceed,
|
||||||
|
ToFail
|
||||||
|
}; };
|
||||||
|
|
||||||
|
MetaTestRunner( Expected::Result expectedResult, std::size_t groupIndex, std::size_t groupsCount )
|
||||||
|
: m_expectedResult( expectedResult ),
|
||||||
|
m_groupIndex( groupIndex ),
|
||||||
|
m_groupsCount( groupsCount )
|
||||||
|
{}
|
||||||
|
|
||||||
|
static void runMatching( const std::string& testSpec,
|
||||||
|
Expected::Result expectedResult,
|
||||||
|
std::size_t groupIndex,
|
||||||
|
std::size_t groupsCount ) {
|
||||||
|
forEach( Catch::getRegistryHub().getTestCaseRegistry().getMatchingTestCases( testSpec ),
|
||||||
|
MetaTestRunner( expectedResult, groupIndex, groupsCount ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()( const Catch::TestCase& testCase ) {
|
||||||
|
std::string name;
|
||||||
|
Catch::Totals totals;
|
||||||
|
{
|
||||||
|
EmbeddedRunner runner;
|
||||||
|
name = testCase.getTestCaseInfo().name;
|
||||||
|
totals = runner.runMatching( name, m_groupIndex, m_groupsCount );
|
||||||
|
}
|
||||||
|
switch( m_expectedResult ) {
|
||||||
|
case Expected::ToSucceed:
|
||||||
|
if( totals.assertions.failed > 0 ) {
|
||||||
|
FAIL( "Expected test case '"
|
||||||
|
<< name
|
||||||
|
<< "' to succeed but there was/ were "
|
||||||
|
<< totals.assertions.failed << " failure(s)" );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SUCCEED( "Tests passed, as expected" );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Expected::ToFail:
|
||||||
|
if( totals.assertions.failed == 0 ) {
|
||||||
|
FAIL( "Expected test case '"
|
||||||
|
<< name
|
||||||
|
<< "' to fail but there was/ were "
|
||||||
|
<< totals.assertions.passed << " success(es)" );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SUCCEED( "Tests failed, as expected" );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Expected::Result m_expectedResult;
|
||||||
|
std::size_t m_groupIndex;
|
||||||
|
std::size_t m_groupsCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
NullStreamingReporter::~NullStreamingReporter() {}
|
||||||
|
|
||||||
|
Catch::Totals EmbeddedRunner::runMatching( const std::string& rawTestSpec, std::size_t groupIndex, std::size_t groupsCount, const std::string& ) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
Catch::Ptr<Catch::Config> config = new Catch::Config();
|
||||||
|
config->setStreamBuf( oss.rdbuf() );
|
||||||
|
|
||||||
|
Catch::Totals totals;
|
||||||
|
|
||||||
|
// Scoped because RunContext doesn't report EndTesting until its destructor
|
||||||
|
{
|
||||||
|
Catch::RunContext runner( config.get(), m_reporter.get() );
|
||||||
|
totals = runner.runMatching( rawTestSpec, groupIndex, groupsCount );
|
||||||
|
}
|
||||||
|
return totals;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE( "Run all failing and succeeding tests", "[vsall]" ) {
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
SECTION( "selftest/expected result",
|
||||||
|
"Tests do what they claim" ) {
|
||||||
|
|
||||||
|
#ifdef _UNICODE
|
||||||
|
std::cout << "using Unicode..." << std::endl;
|
||||||
|
#else
|
||||||
|
std::cout << "using Mbcs..." << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SECTION( "selftest/expected result/failing tests",
|
||||||
|
"Tests in the 'failing' branch fail" ) {
|
||||||
|
std::cout << "Tests in the 'failing' branch fail" << std::endl;
|
||||||
|
MetaTestRunner::runMatching( "./failing/*", MetaTestRunner::Expected::ToFail, 0, 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION( "selftest/expected result/succeeding tests",
|
||||||
|
"Tests in the 'succeeding' branch succeed" ) {
|
||||||
|
std::cout << "Tests in the 'succeeding' branch succeed" << std::endl;
|
||||||
|
MetaTestRunner::runMatching( "./succeeding/*", MetaTestRunner::Expected::ToSucceed, 1, 2 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
SECTION( "selftest/test counts",
|
||||||
|
"Number of test cases that run is fixed" ) {
|
||||||
|
EmbeddedRunner runner;
|
||||||
|
|
||||||
|
SECTION( "selftest/test counts/succeeding tests",
|
||||||
|
"Number of 'succeeding' tests is fixed" ) {
|
||||||
|
std::cout << "Number of 'succeeding' tests is fixed" << std::endl;
|
||||||
|
Catch::Totals totals = runner.runMatching( "./succeeding/*", 0, 2 );
|
||||||
|
CHECK( totals.assertions.passed == 298 );
|
||||||
|
CHECK( totals.assertions.failed == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION( "selftest/test counts/failing tests",
|
||||||
|
"Number of 'failing' tests is fixed" ) {
|
||||||
|
std::cout << "Number of 'failing' tests is fixed" << std::endl;
|
||||||
|
Catch::Totals totals = runner.runMatching( "./failing/*", 1, 2 );
|
||||||
|
CHECK( totals.assertions.passed == 2 );
|
||||||
|
CHECK( totals.assertions.failed == 77 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(INTERNAL_CATCH_VS_MANAGED) || defined(INTERNAL_CATCH_VS_NATIVE)
|
||||||
|
CATCH_MAP_CATEGORY_TO_TAG(all, "[vsall]");
|
||||||
|
#endif
|
||||||
|
}
|
@ -13,6 +13,8 @@
|
|||||||
#include "internal/catch_text.h"
|
#include "internal/catch_text.h"
|
||||||
#include "internal/catch_console_colour.hpp"
|
#include "internal/catch_console_colour.hpp"
|
||||||
|
|
||||||
|
namespace TestMain {
|
||||||
|
|
||||||
TEST_CASE( "selftest/main", "Runs all Catch self tests and checks their results" ) {
|
TEST_CASE( "selftest/main", "Runs all Catch self tests and checks their results" ) {
|
||||||
using namespace Catch;
|
using namespace Catch;
|
||||||
|
|
||||||
@ -59,7 +61,7 @@ TEST_CASE( "meta/Misc/Sections", "looped tests" ) {
|
|||||||
CHECK( totals.assertions.passed == 2 );
|
CHECK( totals.assertions.passed == 2 );
|
||||||
CHECK( totals.assertions.failed == 1 );
|
CHECK( totals.assertions.failed == 1 );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
#pragma clang diagnostic ignored "-Wweak-vtables"
|
#pragma clang diagnostic ignored "-Wweak-vtables"
|
||||||
#endif
|
#endif
|
||||||
@ -68,6 +70,8 @@ TEST_CASE( "meta/Misc/Sections", "looped tests" ) {
|
|||||||
#include "../../include/internal/catch_test_spec.h"
|
#include "../../include/internal/catch_test_spec.h"
|
||||||
#include "../../include/reporters/catch_reporter_xml.hpp"
|
#include "../../include/reporters/catch_reporter_xml.hpp"
|
||||||
|
|
||||||
|
namespace TestMain {
|
||||||
|
|
||||||
template<size_t size>
|
template<size_t size>
|
||||||
void parseIntoConfig( const char * (&argv)[size], Catch::ConfigData& config ) {
|
void parseIntoConfig( const char * (&argv)[size], Catch::ConfigData& config ) {
|
||||||
Clara::CommandLine<Catch::ConfigData> parser = Catch::makeCommandLineParser();
|
Clara::CommandLine<Catch::ConfigData> parser = Catch::makeCommandLineParser();
|
||||||
@ -398,35 +402,35 @@ TEST_CASE( "Long strings can be wrapped", "[wrap]" ) {
|
|||||||
std::string testString = "one two three four";
|
std::string testString = "one two three four";
|
||||||
|
|
||||||
SECTION( "No wrapping", "" ) {
|
SECTION( "No wrapping", "" ) {
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString );
|
CHECK( Catch::Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString );
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString );
|
CHECK( Catch::Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString );
|
||||||
}
|
}
|
||||||
SECTION( "Wrapped once", "" ) {
|
SECTION( "Wrapped once", "" ) {
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 17 ) ).toString() == "one two three\nfour" );
|
CHECK( Catch::Text( testString, TextAttributes().setWidth( 17 ) ).toString() == "one two three\nfour" );
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 16 ) ).toString() == "one two three\nfour" );
|
CHECK( Catch::Text( testString, TextAttributes().setWidth( 16 ) ).toString() == "one two three\nfour" );
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 14 ) ).toString() == "one two three\nfour" );
|
CHECK( Catch::Text( testString, TextAttributes().setWidth( 14 ) ).toString() == "one two three\nfour" );
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 13 ) ).toString() == "one two three\nfour" );
|
CHECK( Catch::Text( testString, TextAttributes().setWidth( 13 ) ).toString() == "one two three\nfour" );
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 12 ) ).toString() == "one two\nthree four" );
|
CHECK( Catch::Text( testString, TextAttributes().setWidth( 12 ) ).toString() == "one two\nthree four" );
|
||||||
}
|
}
|
||||||
SECTION( "Wrapped twice", "" ) {
|
SECTION( "Wrapped twice", "" ) {
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" );
|
CHECK( Catch::Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" );
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour" );
|
CHECK( Catch::Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour" );
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour" );
|
CHECK( Catch::Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour" );
|
||||||
}
|
}
|
||||||
SECTION( "Wrapped three times", "" ) {
|
SECTION( "Wrapped three times", "" ) {
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" );
|
CHECK( Catch::Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" );
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 5 ) ).toString() == "one\ntwo\nthree\nfour" );
|
CHECK( Catch::Text( testString, TextAttributes().setWidth( 5 ) ).toString() == "one\ntwo\nthree\nfour" );
|
||||||
}
|
}
|
||||||
SECTION( "Short wrap", "" ) {
|
SECTION( "Short wrap", "" ) {
|
||||||
CHECK( Text( "abcdef", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef" );
|
CHECK( Catch::Text( "abcdef", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef" );
|
||||||
CHECK( Text( "abcdefg", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndefg" );
|
CHECK( Catch::Text( "abcdefg", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndefg" );
|
||||||
CHECK( Text( "abcdefgh", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef-\ngh" );
|
CHECK( Catch::Text( "abcdefgh", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef-\ngh" );
|
||||||
|
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 4 ) ).toString() == "one\ntwo\nthr-\nee\nfour" );
|
CHECK( Catch::Text( testString, TextAttributes().setWidth( 4 ) ).toString() == "one\ntwo\nthr-\nee\nfour" );
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 3 ) ).toString() == "one\ntwo\nth-\nree\nfo-\nur" );
|
CHECK( Catch::Text( testString, TextAttributes().setWidth( 3 ) ).toString() == "one\ntwo\nth-\nree\nfo-\nur" );
|
||||||
}
|
}
|
||||||
SECTION( "As container", "" ) {
|
SECTION( "As container", "" ) {
|
||||||
Text text( testString, TextAttributes().setWidth( 6 ) );
|
Catch::Text text( testString, TextAttributes().setWidth( 6 ) );
|
||||||
REQUIRE( text.size() == 4 );
|
REQUIRE( text.size() == 4 );
|
||||||
CHECK( text[0] == "one" );
|
CHECK( text[0] == "one" );
|
||||||
CHECK( text[1] == "two" );
|
CHECK( text[1] == "two" );
|
||||||
@ -434,7 +438,7 @@ TEST_CASE( "Long strings can be wrapped", "[wrap]" ) {
|
|||||||
CHECK( text[3] == "four" );
|
CHECK( text[3] == "four" );
|
||||||
}
|
}
|
||||||
SECTION( "Indent first line differently", "" ) {
|
SECTION( "Indent first line differently", "" ) {
|
||||||
Text text( testString, TextAttributes()
|
Catch::Text text( testString, TextAttributes()
|
||||||
.setWidth( 10 )
|
.setWidth( 10 )
|
||||||
.setIndent( 4 )
|
.setIndent( 4 )
|
||||||
.setInitialIndent( 1 ) );
|
.setInitialIndent( 1 ) );
|
||||||
@ -449,22 +453,22 @@ TEST_CASE( "Long strings can be wrapped", "[wrap]" ) {
|
|||||||
std::string testString = "one two\nthree four";
|
std::string testString = "one two\nthree four";
|
||||||
|
|
||||||
SECTION( "No wrapping" , "" ) {
|
SECTION( "No wrapping" , "" ) {
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString );
|
CHECK( Catch::Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString );
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString );
|
CHECK( Catch::Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString );
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 10 ) ).toString() == testString );
|
CHECK( Catch::Text( testString, TextAttributes().setWidth( 10 ) ).toString() == testString );
|
||||||
}
|
}
|
||||||
SECTION( "Trailing newline" , "" ) {
|
SECTION( "Trailing newline" , "" ) {
|
||||||
CHECK( Text( "abcdef\n", TextAttributes().setWidth( 10 ) ).toString() == "abcdef\n" );
|
CHECK( Catch::Text( "abcdef\n", TextAttributes().setWidth( 10 ) ).toString() == "abcdef\n" );
|
||||||
CHECK( Text( "abcdef", TextAttributes().setWidth( 6 ) ).toString() == "abcdef" );
|
CHECK( Catch::Text( "abcdef", TextAttributes().setWidth( 6 ) ).toString() == "abcdef" );
|
||||||
CHECK( Text( "abcdef\n", TextAttributes().setWidth( 6 ) ).toString() == "abcdef\n" );
|
CHECK( Catch::Text( "abcdef\n", TextAttributes().setWidth( 6 ) ).toString() == "abcdef\n" );
|
||||||
}
|
}
|
||||||
SECTION( "Wrapped once", "" ) {
|
SECTION( "Wrapped once", "" ) {
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" );
|
CHECK( Catch::Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" );
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour" );
|
CHECK( Catch::Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour" );
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour" );
|
CHECK( Catch::Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour" );
|
||||||
}
|
}
|
||||||
SECTION( "Wrapped twice", "" ) {
|
SECTION( "Wrapped twice", "" ) {
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" );
|
CHECK( Catch::Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,7 +477,7 @@ TEST_CASE( "Long strings can be wrapped", "[wrap]" ) {
|
|||||||
// guide: 1234567890123456789
|
// guide: 1234567890123456789
|
||||||
std::string testString = "one two \tthree four five six";
|
std::string testString = "one two \tthree four five six";
|
||||||
|
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 15 ) ).toString()
|
CHECK( Catch::Text( testString, TextAttributes().setWidth( 15 ) ).toString()
|
||||||
== "one two three\n four\n five\n six" );
|
== "one two three\n four\n five\n six" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -574,12 +578,12 @@ TEST_CASE( "Strings can be rendered with colour", "[colour]" ) {
|
|||||||
|
|
||||||
TEST_CASE( "Text can be formatted using the Text class", "" ) {
|
TEST_CASE( "Text can be formatted using the Text class", "" ) {
|
||||||
|
|
||||||
CHECK( Text( "hi there" ).toString() == "hi there" );
|
CHECK( Catch::Text( "hi there" ).toString() == "hi there" );
|
||||||
|
|
||||||
TextAttributes narrow;
|
TextAttributes narrow;
|
||||||
narrow.setWidth( 6 );
|
narrow.setWidth( 6 );
|
||||||
|
|
||||||
CHECK( Text( "hi there", narrow ).toString() == "hi\nthere" );
|
CHECK( Catch::Text( "hi there", narrow ).toString() == "hi\nthere" );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Long text is truncted", "[Text][Truncated]" ) {
|
TEST_CASE( "Long text is truncted", "[Text][Truncated]" ) {
|
||||||
@ -589,7 +593,8 @@ TEST_CASE( "Long text is truncted", "[Text][Truncated]" ) {
|
|||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
for(int i = 0; i < 600; ++i )
|
for(int i = 0; i < 600; ++i )
|
||||||
oss << longLine << longLine << "\n";
|
oss << longLine << longLine << "\n";
|
||||||
Text t( oss.str() );
|
Catch::Text t( oss.str() );
|
||||||
CHECK_THAT( t.toString(), EndsWith( "... message truncated due to excessive size" ) );
|
CHECK_THAT( t.toString(), EndsWith( "... message truncated due to excessive size" ) );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
110
projects/SelfTest/VisualStudioTests.cpp
Normal file
110
projects/SelfTest/VisualStudioTests.cpp
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* Created by Phil on 22/10/2010.
|
||||||
|
* Copyright 2010 Two Blue Cubes Ltd
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "catch.hpp"
|
||||||
|
|
||||||
|
#if defined(INTERNAL_CATCH_VS_MANAGED) || defined(INTERNAL_CATCH_VS_NATIVE)
|
||||||
|
|
||||||
|
namespace VisualStudioTests
|
||||||
|
{
|
||||||
|
class UniqueTestsFixture {
|
||||||
|
private:
|
||||||
|
static int uniqueID;
|
||||||
|
public:
|
||||||
|
UniqueTestsFixture() { }
|
||||||
|
protected:
|
||||||
|
int getID() {
|
||||||
|
return ++uniqueID;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int UniqueTestsFixture::uniqueID = 0;
|
||||||
|
TEST_CASE("M00", "[m_off]")
|
||||||
|
{
|
||||||
|
bool show = Catch::getCurrentContext().getConfig()->includeSuccessfulResults();
|
||||||
|
REQUIRE(!show);
|
||||||
|
}
|
||||||
|
|
||||||
|
CATCH_CONFIG_SHOW_SUCCESS(true)
|
||||||
|
TEST_CASE("M01", "[m_on]")
|
||||||
|
{
|
||||||
|
bool show = Catch::getCurrentContext().getConfig()->includeSuccessfulResults();
|
||||||
|
REQUIRE(show);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("M02", "[m_off]")
|
||||||
|
{
|
||||||
|
bool show = Catch::getCurrentContext().getConfig()->includeSuccessfulResults();
|
||||||
|
REQUIRE(!show);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE_METHOD(UniqueTestsFixture, "M10", "[m_off]")
|
||||||
|
{
|
||||||
|
bool show = Catch::getCurrentContext().getConfig()->includeSuccessfulResults();
|
||||||
|
REQUIRE(!show);
|
||||||
|
getID();
|
||||||
|
}
|
||||||
|
|
||||||
|
CATCH_CONFIG_WARN_MISSING_ASSERTIONS(true)
|
||||||
|
CATCH_CONFIG_SHOW_SUCCESS(true)
|
||||||
|
TEST_CASE_METHOD(UniqueTestsFixture, "M11", "[m_on]")
|
||||||
|
{
|
||||||
|
bool show = Catch::getCurrentContext().getConfig()->includeSuccessfulResults();
|
||||||
|
REQUIRE(show);
|
||||||
|
getID();
|
||||||
|
}
|
||||||
|
|
||||||
|
CATCH_CONFIG_WARN_MISSING_ASSERTIONS(true)
|
||||||
|
CATCH_CONFIG_SHOW_SUCCESS(true)
|
||||||
|
TEST_CASE_METHOD(UniqueTestsFixture, "M99", "[m_on]")
|
||||||
|
{
|
||||||
|
bool show = Catch::getCurrentContext().getConfig()->includeSuccessfulResults();
|
||||||
|
REQUIRE(show);
|
||||||
|
WARN("Warning message");
|
||||||
|
getID();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE_METHOD(UniqueTestsFixture, "M12", "[m_off]")
|
||||||
|
{
|
||||||
|
bool show = Catch::getCurrentContext().getConfig()->includeSuccessfulResults();
|
||||||
|
REQUIRE(!show);
|
||||||
|
getID();
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConfigTest
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void run1()
|
||||||
|
{
|
||||||
|
bool show = Catch::getCurrentContext().getConfig()->includeSuccessfulResults();
|
||||||
|
REQUIRE(!show);
|
||||||
|
}
|
||||||
|
void run2()
|
||||||
|
{
|
||||||
|
bool show = Catch::getCurrentContext().getConfig()->includeSuccessfulResults();
|
||||||
|
REQUIRE(show);
|
||||||
|
}
|
||||||
|
void run3()
|
||||||
|
{
|
||||||
|
bool show = Catch::getCurrentContext().getConfig()->includeSuccessfulResults();
|
||||||
|
REQUIRE(!show);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
METHOD_AS_TEST_CASE(ConfigTest::run1,"M20", "[m_off]");
|
||||||
|
|
||||||
|
CATCH_CONFIG_SHOW_SUCCESS(true)
|
||||||
|
METHOD_AS_TEST_CASE(ConfigTest::run2,"M21", "[m_on]");
|
||||||
|
|
||||||
|
METHOD_AS_TEST_CASE(ConfigTest::run3,"M22", "[m_off]");
|
||||||
|
|
||||||
|
CATCH_MAP_CATEGORY_TO_TAG(vstestsCheckOutputOff, "[m_off]");
|
||||||
|
CATCH_CONFIG_SHOW_SUCCESS(true)
|
||||||
|
CATCH_MAP_CATEGORY_TO_TAG(vstestsCheckOutputOn, "[m_on]");
|
||||||
|
CATCH_MAP_CATEGORY_TO_TAG(vstestsCheckOutputOff2, "[m_off]");
|
||||||
|
}
|
||||||
|
#endif
|
@ -6,7 +6,9 @@
|
|||||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if !defined(_WINDLL)
|
||||||
#define CATCH_CONFIG_MAIN
|
#define CATCH_CONFIG_MAIN
|
||||||
|
#endif
|
||||||
#include "catch_self_test.hpp"
|
#include "catch_self_test.hpp"
|
||||||
|
|
||||||
namespace Catch{
|
namespace Catch{
|
||||||
|
@ -4,8 +4,6 @@ SOURCES = ApproxTests.cpp \
|
|||||||
ExceptionTests.cpp \
|
ExceptionTests.cpp \
|
||||||
GeneratorTests.cpp \
|
GeneratorTests.cpp \
|
||||||
MessageTests.cpp \
|
MessageTests.cpp \
|
||||||
MessageInstantiationTests1.cpp \
|
|
||||||
MessageInstantiationTests2.cpp \
|
|
||||||
MiscTests.cpp \
|
MiscTests.cpp \
|
||||||
TestMain.cpp \
|
TestMain.cpp \
|
||||||
TrickyTests.cpp \
|
TrickyTests.cpp \
|
||||||
|
Loading…
Reference in New Issue
Block a user