mirror of https://github.com/catchorg/Catch2.git
136 lines
4.8 KiB
C++
136 lines
4.8 KiB
C++
![]() |
/*
|
||
|
* Created by Phil on 8/8/2017.
|
||
|
* Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
|
||
|
*
|
||
|
* 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_assertionhandler.h"
|
||
|
#include "catch_assertionresult.h"
|
||
|
#include "catch_interfaces_capture.h"
|
||
|
#include "catch_interfaces_runner.h"
|
||
|
#include "catch_context.h"
|
||
|
#include "catch_debugger.h"
|
||
|
#include "catch_interfaces_registry_hub.h"
|
||
|
|
||
|
#include <iostream> // !TBD
|
||
|
|
||
|
namespace Catch {
|
||
|
|
||
|
auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
|
||
|
expr.streamReconstructedExpression( os );
|
||
|
return os;
|
||
|
}
|
||
|
|
||
|
LazyExpression::LazyExpression( bool isNegated )
|
||
|
: m_isNegated( isNegated )
|
||
|
{}
|
||
|
|
||
|
LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {}
|
||
|
|
||
|
LazyExpression::operator bool() const {
|
||
|
return m_transientExpression != nullptr;
|
||
|
}
|
||
|
|
||
|
auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& {
|
||
|
if( lazyExpr.m_isNegated )
|
||
|
os << "!";
|
||
|
|
||
|
if( lazyExpr ) {
|
||
|
if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )
|
||
|
os << "(" << *lazyExpr.m_transientExpression << ")";
|
||
|
else
|
||
|
os << *lazyExpr.m_transientExpression;
|
||
|
}
|
||
|
else {
|
||
|
os << "{** error - unchecked empty expression requested **}";
|
||
|
}
|
||
|
return os;
|
||
|
}
|
||
|
|
||
|
AssertionHandler::AssertionHandler
|
||
|
( StringRef macroName,
|
||
|
SourceLineInfo const& lineInfo,
|
||
|
StringRef capturedExpression,
|
||
|
ResultDisposition::Flags resultDisposition )
|
||
|
: m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition }
|
||
|
{
|
||
|
getCurrentContext().getResultCapture()->assertionStarting( m_assertionInfo );
|
||
|
}
|
||
|
|
||
|
void AssertionHandler::handle( ITransientExpression const& expr ) {
|
||
|
|
||
|
bool negated = isFalseTest( m_assertionInfo.resultDisposition );
|
||
|
bool result = expr.getResult() != negated;
|
||
|
|
||
|
AssertionResultData data( result ? ResultWas::Ok : ResultWas::ExpressionFailed, LazyExpression( negated ) );
|
||
|
|
||
|
// Deprecated
|
||
|
// data.negated = negated;
|
||
|
// data.parenthesized = negated && expr.isBinaryExpression(); // !TBD: needed?
|
||
|
// data.decomposedExpression = nullptr; // !TBD
|
||
|
// data.reconstructedExpression = ""; // !TBD
|
||
|
|
||
|
|
||
|
getResultCapture().assertionRun();
|
||
|
|
||
|
AssertionResult assertionResult{ m_assertionInfo, data };
|
||
|
assertionResult.m_resultData.lazyExpression.m_transientExpression = &expr;
|
||
|
|
||
|
getResultCapture().assertionEnded( assertionResult );
|
||
|
|
||
|
if( !assertionResult.isOk() ) {
|
||
|
m_shouldDebugBreak = getCurrentContext().getConfig()->shouldDebugBreak();
|
||
|
m_shouldThrow =
|
||
|
getCurrentContext().getRunner()->aborting() ||
|
||
|
(m_assertionInfo.resultDisposition & ResultDisposition::Normal);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
auto AssertionHandler::shouldDebugBreak() const -> bool {
|
||
|
return m_shouldDebugBreak;
|
||
|
}
|
||
|
void AssertionHandler::reactWithDebugBreak() const {
|
||
|
if (m_shouldDebugBreak) {
|
||
|
///////////////////////////////////////////////////////////////////
|
||
|
// To inspect the state during test, you need to go one level up the callstack
|
||
|
// To go back to the test and change execution, jump over the reactWithoutDebugBreak() call
|
||
|
///////////////////////////////////////////////////////////////////
|
||
|
CATCH_BREAK_INTO_DEBUGGER();
|
||
|
}
|
||
|
reactWithoutDebugBreak();
|
||
|
}
|
||
|
void AssertionHandler::reactWithoutDebugBreak() const {
|
||
|
if( m_shouldThrow )
|
||
|
throw Catch::TestFailureException();
|
||
|
}
|
||
|
|
||
|
void AssertionHandler::useActiveException( ResultDisposition::Flags resultDisposition ) {
|
||
|
m_assertionInfo.resultDisposition = resultDisposition;
|
||
|
useActiveException();
|
||
|
}
|
||
|
void AssertionHandler::useActiveException() {
|
||
|
bool negated = isFalseTest( m_assertionInfo.resultDisposition );
|
||
|
|
||
|
AssertionResultData data( ResultWas::ThrewException, LazyExpression( negated ) );
|
||
|
data.message = Catch::translateActiveException();
|
||
|
|
||
|
//data.decomposedExpression = &expr; // for lazy reconstruction
|
||
|
|
||
|
AssertionResult result( m_assertionInfo, data );
|
||
|
|
||
|
getResultCapture().assertionEnded( result );
|
||
|
|
||
|
// !TBD: factor this out? handleResult()?
|
||
|
if( !result.isOk() ) {
|
||
|
if( getCurrentContext().getConfig()->shouldDebugBreak() )
|
||
|
m_shouldDebugBreak = true;
|
||
|
if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) )
|
||
|
m_shouldThrow = true;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
} // namespace Catch
|