First step to refactoring ResultsCapture into pure calls onto IResultListener interface

This commit is contained in:
Phil Nash 2010-12-31 20:49:58 +00:00
parent 245be004fe
commit 6ea8f298a4
3 changed files with 67 additions and 75 deletions

View File

@ -190,9 +190,19 @@ private:
}; };
struct ResultAction
{
enum Value
{
None,
Failed = 1, // Failure - but no debug break if Debug bit not set
DebugFailed = 3 // Indicates that the debugger should break, if possible
};
};
class TestCaseInfo; class TestCaseInfo;
class ScopedInfo; class ScopedInfo;
struct IResultListener struct IResultListener
{ {
virtual ~IResultListener(){} virtual ~IResultListener(){}
@ -202,18 +212,14 @@ struct IResultListener
virtual void pushScopedInfo( ScopedInfo* scopedInfo ) = 0; virtual void pushScopedInfo( ScopedInfo* scopedInfo ) = 0;
virtual void popScopedInfo( ScopedInfo* scopedInfo ) = 0; virtual void popScopedInfo( ScopedInfo* scopedInfo ) = 0;
virtual bool shouldDebugBreak() const = 0; virtual bool shouldDebugBreak() const = 0;
virtual ResultAction::Value acceptResult( bool result ) = 0;
virtual ResultAction::Value acceptResult( ResultWas::OfType result ) = 0;
virtual void acceptExpression( const MutableResultInfo& resultInfo ) = 0;
virtual void acceptMessage( const std::string& msg ) = 0;
}; };
struct ResultAction
{
enum Value
{
None,
Failed = 1, // Failure - but no debug break if Debug bit not set
DebugFailed = 3 // Indicates that the debugger should break, if possible
};
};
class ResultsCapture class ResultsCapture
{ {
@ -237,60 +243,11 @@ public:
instance().m_listener = listener; instance().m_listener = listener;
return prevListener; return prevListener;
} }
static IResultListener& getListener()
static void acceptExpression( const MutableResultInfo& resultInfo )
{ {
instance().currentResult = resultInfo; return *instance().m_listener;
} }
static ResultAction::Value acceptResult( bool result )
{
return acceptResult( result ? ResultWas::Ok : ResultWas::ExpressionFailed );
}
static ResultAction::Value acceptResult( ResultWas::OfType result )
{
MutableResultInfo& currentResult = instance().currentResult;
currentResult.setResultType( result );
if( instance().m_listener )
{
instance().m_listener->testEnded( currentResult );
}
bool ok = currentResult.ok();
instance().currentResult = MutableResultInfo();
if( ok )
return ResultAction::None;
else if( instance().m_listener->shouldDebugBreak() )
return ResultAction::DebugFailed;
else
return ResultAction::Failed;
}
static void acceptMessage( const std::string& msg )
{
instance().currentResult.setMessage( msg );
}
static bool acceptSectionStart( const std::string& name, const std::string& description, std::size_t& successes, std::size_t& failures )
{
return instance().m_listener->sectionStarted( name, description, successes, failures );
}
static void acceptSectionEnd( const std::string& name, std::size_t successes, std::size_t failures )
{
instance().m_listener->sectionEnded( name, successes, failures );
}
static void pushScopedInfo( ScopedInfo* scopedInfo )
{
instance().m_listener->pushScopedInfo( scopedInfo );
}
static void popScopedInfo( ScopedInfo* scopedInfo )
{
instance().m_listener->popScopedInfo( scopedInfo );
}
private: private:
MutableResultInfo currentResult; MutableResultInfo currentResult;
IResultListener* m_listener; IResultListener* m_listener;
@ -302,12 +259,12 @@ class ScopedInfo
public: public:
ScopedInfo() ScopedInfo()
{ {
ResultsCapture::pushScopedInfo( this ); ResultsCapture::getListener().pushScopedInfo( this );
} }
~ScopedInfo() ~ScopedInfo()
{ {
ResultsCapture::popScopedInfo( this ); ResultsCapture::getListener().popScopedInfo( this );
} }
ScopedInfo& operator << ( const char* str ) ScopedInfo& operator << ( const char* str )
@ -378,7 +335,7 @@ inline bool isTrue( bool value )
} // end namespace Catch } // end namespace Catch
#define INTERNAL_CATCH_ACCEPT_RESULT( result, stopOnFailure ) \ #define INTERNAL_CATCH_ACCEPT_RESULT( result, stopOnFailure ) \
if( Catch::ResultAction::Value action = Catch::ResultsCapture::acceptResult( result ) ) \ if( Catch::ResultAction::Value action = Catch::ResultsCapture::getListener().acceptResult( result ) ) \
{ \ { \
if( action == Catch::ResultAction::DebugFailed ) DebugBreak(); \ if( action == Catch::ResultAction::DebugFailed ) DebugBreak(); \
if( Catch::isTrue( stopOnFailure ) ) throw Catch::TestFailureException(); \ if( Catch::isTrue( stopOnFailure ) ) throw Catch::TestFailureException(); \
@ -386,12 +343,12 @@ inline bool isTrue( bool value )
#define INTERNAL_CATCH_TEST( expr, isNot, stopOnFailure, macroName ) \ #define INTERNAL_CATCH_TEST( expr, isNot, stopOnFailure, macroName ) \
{ \ { \
Catch::ResultsCapture::acceptExpression( Catch::ResultBuilder( #expr, isNot, __FILE__, __LINE__, macroName )->*expr ); \ Catch::ResultsCapture::getListener().acceptExpression( Catch::ResultBuilder( #expr, isNot, __FILE__, __LINE__, macroName )->*expr ); \
INTERNAL_CATCH_ACCEPT_RESULT( expr, stopOnFailure ) \ INTERNAL_CATCH_ACCEPT_RESULT( expr, stopOnFailure ) \
} }
#define INTERNAL_CATCH_THROWS( expr, exceptionType, nothrow, stopOnFailure, macroName ) \ #define INTERNAL_CATCH_THROWS( expr, exceptionType, nothrow, stopOnFailure, macroName ) \
Catch::ResultsCapture::acceptExpression( Catch::ResultBuilder( #expr, false, __FILE__, __LINE__, macroName ) ); \ Catch::ResultsCapture::getListener().acceptExpression( Catch::ResultBuilder( #expr, false, __FILE__, __LINE__, macroName ) ); \
try \ try \
{ \ { \
expr; \ expr; \
@ -413,8 +370,8 @@ catch( ... ) \
{ \ { \
std::ostringstream INTERNAL_CATCH_UNIQUE_NAME( strm ); \ std::ostringstream INTERNAL_CATCH_UNIQUE_NAME( strm ); \
INTERNAL_CATCH_UNIQUE_NAME( strm ) << reason; \ INTERNAL_CATCH_UNIQUE_NAME( strm ) << reason; \
Catch::ResultsCapture::acceptExpression( Catch::MutableResultInfo( "", false, __FILE__, __LINE__, macroName ) ); \ Catch::ResultsCapture::getListener().acceptExpression( Catch::MutableResultInfo( "", false, __FILE__, __LINE__, macroName ) ); \
Catch::ResultsCapture::acceptMessage( INTERNAL_CATCH_UNIQUE_NAME( strm ).str() ); \ Catch::ResultsCapture::getListener().acceptMessage( INTERNAL_CATCH_UNIQUE_NAME( strm ).str() ); \
INTERNAL_CATCH_ACCEPT_RESULT( resultType, stopOnFailure ) \ INTERNAL_CATCH_ACCEPT_RESULT( resultType, stopOnFailure ) \
} }

View File

@ -136,13 +136,13 @@ namespace Catch
} }
catch( std::exception& ex ) catch( std::exception& ex )
{ {
ResultsCapture::acceptMessage( ex.what() ); acceptMessage( ex.what() );
ResultsCapture::acceptResult( ResultWas::ThrewException ); acceptResult( ResultWas::ThrewException );
} }
catch(...) catch(...)
{ {
ResultsCapture::acceptMessage( "unknown exception" ); acceptMessage( "unknown exception" );
ResultsCapture::acceptResult( ResultWas::ThrewException ); acceptResult( ResultWas::ThrewException );
} }
m_info.clear(); m_info.clear();
m_reporter->EndTestCase( testInfo, redirectedCout, redirectedCerr ); m_reporter->EndTestCase( testInfo, redirectedCout, redirectedCerr );
@ -159,6 +159,39 @@ namespace Catch
} }
private: // IResultListener private: // IResultListener
virtual ResultAction::Value acceptResult( bool result )
{
return acceptResult( result ? ResultWas::Ok : ResultWas::ExpressionFailed );
}
virtual ResultAction::Value acceptResult( ResultWas::OfType result )
{
m_currentResult.setResultType( result );
testEnded( m_currentResult );
bool ok = m_currentResult.ok();
m_currentResult = MutableResultInfo();
if( ok )
return ResultAction::None;
else if( shouldDebugBreak() )
return ResultAction::DebugFailed;
else
return ResultAction::Failed;
}
virtual void acceptExpression( const MutableResultInfo& resultInfo )
{
m_currentResult = resultInfo;
}
virtual void acceptMessage( const std::string& msg )
{
m_currentResult.setMessage( msg );
}
///
virtual void testEnded( const ResultInfo& result ) virtual void testEnded( const ResultInfo& result )
{ {
@ -213,6 +246,8 @@ namespace Catch
} }
private: private:
MutableResultInfo m_currentResult;
const RunnerConfig& m_config; const RunnerConfig& m_config;
std::size_t m_successes; std::size_t m_successes;
std::size_t m_failures; std::size_t m_failures;

View File

@ -24,13 +24,13 @@ namespace Catch
public: public:
Section( const std::string& name, const std::string& description ) Section( const std::string& name, const std::string& description )
: m_name( name ), : m_name( name ),
m_sectionIncluded( ResultsCapture::acceptSectionStart( name, description, m_successes, m_failures ) ) m_sectionIncluded( ResultsCapture::getListener().sectionStarted( name, description, m_successes, m_failures ) )
{ {
} }
~Section() ~Section()
{ {
ResultsCapture::acceptSectionEnd( m_name, m_successes, m_failures ); ResultsCapture::getListener().sectionEnded( m_name, m_successes, m_failures );
} }
// This indicates whether the section should be executed or not // This indicates whether the section should be executed or not