Always debug-break non-inline

This commit is contained in:
Phil Nash 2017-11-23 19:14:26 +00:00
parent 8141a7836f
commit 9329d97a43
4 changed files with 22 additions and 38 deletions

View File

@ -61,7 +61,7 @@ namespace Catch {
getCurrentContext().getResultCapture()->assertionStarting( m_assertionInfo ); getCurrentContext().getResultCapture()->assertionStarting( m_assertionInfo );
} }
AssertionHandler::~AssertionHandler() { AssertionHandler::~AssertionHandler() {
if ( !m_handled ) { if ( !m_completed ) {
handle( ResultWas::ThrewException, "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE" ); handle( ResultWas::ThrewException, "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE" );
getCurrentContext().getResultCapture()->exceptionEarlyReported(); getCurrentContext().getResultCapture()->exceptionEarlyReported();
} }
@ -76,7 +76,6 @@ namespace Catch {
{ {
getCurrentContext().getResultCapture()->assertionRun(); getCurrentContext().getResultCapture()->assertionRun();
getCurrentContext().getResultCapture()->assertionPassed(); getCurrentContext().getResultCapture()->assertionPassed();
m_handled = true;
return; return;
} }
@ -96,7 +95,6 @@ namespace Catch {
} }
void AssertionHandler::handle( AssertionResultData const& resultData, ITransientExpression const* expr ) { void AssertionHandler::handle( AssertionResultData const& resultData, ITransientExpression const* expr ) {
m_handled = true;
getResultCapture().assertionRun(); getResultCapture().assertionRun();
AssertionResult assertionResult{ m_assertionInfo, resultData }; AssertionResult assertionResult{ m_assertionInfo, resultData };
@ -116,20 +114,22 @@ namespace Catch {
return getCurrentContext().getConfig()->allowThrows(); return getCurrentContext().getConfig()->allowThrows();
} }
void AssertionHandler::reactWithDebugBreak() const { void AssertionHandler::complete() {
setCompleted();
if( m_shouldDebugBreak ) { if( m_shouldDebugBreak ) {
///////////////////////////////////////////////////////////////////
// To inspect the state during test, you need to go one level up the callstack // If you find your debugger stopping you here then go one level up on the
// To go back to the test and change execution, jump over the reactWithoutDebugBreak() call // call-stack for the code that caused it (typically a failed assertion)
///////////////////////////////////////////////////////////////////
// (To go back to the test and change execution, jump over the throw, next)
CATCH_BREAK_INTO_DEBUGGER(); CATCH_BREAK_INTO_DEBUGGER();
} }
reactWithoutDebugBreak();
}
void AssertionHandler::reactWithoutDebugBreak() const {
if( m_shouldThrow ) if( m_shouldThrow )
throw Catch::TestFailureException(); throw Catch::TestFailureException();
} }
void AssertionHandler::setCompleted() {
m_completed = true;
}
void AssertionHandler::useActiveException() { void AssertionHandler::useActiveException() {
handle( ResultWas::ThrewException, Catch::translateActiveException() ); handle( ResultWas::ThrewException, Catch::translateActiveException() );

View File

@ -36,7 +36,7 @@ namespace Catch {
AssertionInfo m_assertionInfo; AssertionInfo m_assertionInfo;
bool m_shouldDebugBreak = false; bool m_shouldDebugBreak = false;
bool m_shouldThrow = false; bool m_shouldThrow = false;
bool m_handled = false; bool m_completed = false;
public: public:
AssertionHandler AssertionHandler
@ -57,11 +57,9 @@ namespace Catch {
void handle( ResultWas::OfType resultType, ITransientExpression const* expr, bool negated ); void handle( ResultWas::OfType resultType, ITransientExpression const* expr, bool negated );
void handle( AssertionResultData const& resultData, ITransientExpression const* expr ); void handle( AssertionResultData const& resultData, ITransientExpression const* expr );
auto shouldDebugBreak() const -> bool { return m_shouldDebugBreak; }
auto allowThrows() const -> bool; auto allowThrows() const -> bool;
void reactWithDebugBreak() const; void complete();
void reactWithoutDebugBreak() const; void setCompleted();
void useActiveException(); void useActiveException();
}; };

View File

@ -11,7 +11,6 @@
#include "catch_assertionhandler.h" #include "catch_assertionhandler.h"
#include "catch_message.h" #include "catch_message.h"
#include "catch_interfaces_capture.h" #include "catch_interfaces_capture.h"
#include "catch_debugger.h"
#if !defined(CATCH_CONFIG_DISABLE) #if !defined(CATCH_CONFIG_DISABLE)
@ -22,37 +21,22 @@
#endif #endif
#if defined(CATCH_CONFIG_FAST_COMPILE) #if defined(CATCH_CONFIG_FAST_COMPILE)
///////////////////////////////////////////////////////////////////////////////
// We can speedup compilation significantly by breaking into debugger lower in
// the callstack, because then we don't have to expand CATCH_BREAK_INTO_DEBUGGER
// macro in each assertion
#define INTERNAL_CATCH_REACT( handler ) \
handler.reactWithDebugBreak();
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Another way to speed-up compilation is to omit local try-catch for REQUIRE* // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
// macros. // macros.
// This can potentially cause false negative, if the test code catches
// the exception before it propagates back up to the runner.
#define INTERNAL_CATCH_TRY #define INTERNAL_CATCH_TRY
#define INTERNAL_CATCH_CATCH( capturer ) #define INTERNAL_CATCH_CATCH( capturer )
#else // CATCH_CONFIG_FAST_COMPILE #else // CATCH_CONFIG_FAST_COMPILE
///////////////////////////////////////////////////////////////////////////////
// In the event of a failure works out if the debugger needs to be invoked
// and/or an exception thrown and takes appropriate action.
// This needs to be done as a macro so the debugger will stop in the user
// source code rather than in Catch library code
#define INTERNAL_CATCH_REACT( handler ) \
if( handler.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
handler.reactWithoutDebugBreak();
#define INTERNAL_CATCH_TRY try #define INTERNAL_CATCH_TRY try
#define INTERNAL_CATCH_CATCH( capturer ) catch(...) { capturer.useActiveException(); } #define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.useActiveException(); }
#endif #endif
#define INTERNAL_CATCH_REACT( handler ) handler.complete();
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \ #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
do { \ do { \

View File

@ -297,11 +297,13 @@ namespace Catch {
// Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
// are reported without translation at the point of origin. // are reported without translation at the point of origin.
if (m_shouldReportUnexpected) { if (m_shouldReportUnexpected) {
AssertionHandler AssertionHandler handler
( m_lastAssertionInfo.macroName, ( m_lastAssertionInfo.macroName,
m_lastAssertionInfo.lineInfo, m_lastAssertionInfo.lineInfo,
m_lastAssertionInfo.capturedExpression, m_lastAssertionInfo.capturedExpression,
m_lastAssertionInfo.resultDisposition ).useActiveException(); m_lastAssertionInfo.resultDisposition );
handler.useActiveException();
handler.setCompleted();
} }
} }
m_testCaseTracker->close(); m_testCaseTracker->close();