1 /* 2 * Created by Phil on 8/8/2017. 3 * Copyright 2017 Two Blue Cubes Ltd. All rights reserved. 4 * 5 * Distributed under the Boost Software License, Version 1.0. (See accompanying 6 * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 */ 8 9 #include "catch_assertionhandler.h" 10 #include "catch_assertionresult.h" 11 #include "catch_interfaces_runner.h" 12 #include "catch_interfaces_config.h" 13 #include "catch_context.h" 14 #include "catch_debugger.h" 15 #include "catch_interfaces_registry_hub.h" 16 #include "catch_capture_matchers.h" 17 #include "catch_run_context.h" 18 19 namespace Catch { 20 21 namespace { operator <<(std::ostream & os,ITransientExpression const & expr)22 auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& { 23 expr.streamReconstructedExpression( os ); 24 return os; 25 } 26 } 27 LazyExpression(bool isNegated)28 LazyExpression::LazyExpression( bool isNegated ) 29 : m_isNegated( isNegated ) 30 {} 31 LazyExpression(LazyExpression const & other)32 LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {} 33 operator bool() const34 LazyExpression::operator bool() const { 35 return m_transientExpression != nullptr; 36 } 37 operator <<(std::ostream & os,LazyExpression const & lazyExpr)38 auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& { 39 if( lazyExpr.m_isNegated ) 40 os << "!"; 41 42 if( lazyExpr ) { 43 if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() ) 44 os << "(" << *lazyExpr.m_transientExpression << ")"; 45 else 46 os << *lazyExpr.m_transientExpression; 47 } 48 else { 49 os << "{** error - unchecked empty expression requested **}"; 50 } 51 return os; 52 } 53 AssertionHandler(StringRef const & macroName,SourceLineInfo const & lineInfo,StringRef capturedExpression,ResultDisposition::Flags resultDisposition)54 AssertionHandler::AssertionHandler 55 ( StringRef const& macroName, 56 SourceLineInfo const& lineInfo, 57 StringRef capturedExpression, 58 ResultDisposition::Flags resultDisposition ) 59 : m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition }, 60 m_resultCapture( getResultCapture() ) 61 {} 62 handleExpr(ITransientExpression const & expr)63 void AssertionHandler::handleExpr( ITransientExpression const& expr ) { 64 m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction ); 65 } handleMessage(ResultWas::OfType resultType,StringRef const & message)66 void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) { 67 m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction ); 68 } 69 allowThrows() const70 auto AssertionHandler::allowThrows() const -> bool { 71 return getCurrentContext().getConfig()->allowThrows(); 72 } 73 complete()74 void AssertionHandler::complete() { 75 setCompleted(); 76 if( m_reaction.shouldDebugBreak ) { 77 78 // If you find your debugger stopping you here then go one level up on the 79 // call-stack for the code that caused it (typically a failed assertion) 80 81 // (To go back to the test and change execution, jump over the throw, next) 82 CATCH_BREAK_INTO_DEBUGGER(); 83 } 84 if (m_reaction.shouldThrow) { 85 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) 86 throw Catch::TestFailureException(); 87 #else 88 CATCH_ERROR( "Test failure requires aborting test!" ); 89 #endif 90 } 91 } setCompleted()92 void AssertionHandler::setCompleted() { 93 m_completed = true; 94 } 95 handleUnexpectedInflightException()96 void AssertionHandler::handleUnexpectedInflightException() { 97 m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction ); 98 } 99 handleExceptionThrownAsExpected()100 void AssertionHandler::handleExceptionThrownAsExpected() { 101 m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction); 102 } handleExceptionNotThrownAsExpected()103 void AssertionHandler::handleExceptionNotThrownAsExpected() { 104 m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction); 105 } 106 handleUnexpectedExceptionNotThrown()107 void AssertionHandler::handleUnexpectedExceptionNotThrown() { 108 m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction ); 109 } 110 handleThrowingCallSkipped()111 void AssertionHandler::handleThrowingCallSkipped() { 112 m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction); 113 } 114 115 // This is the overload that takes a string and infers the Equals matcher from it 116 // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp handleExceptionMatchExpr(AssertionHandler & handler,std::string const & str,StringRef const & matcherString)117 void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString ) { 118 handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString ); 119 } 120 121 } // namespace Catch 122