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 #include "catch_enforce.h" 19 20 namespace Catch { 21 22 namespace { operator <<(std::ostream & os,ITransientExpression const & expr)23 auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& { 24 expr.streamReconstructedExpression( os ); 25 return os; 26 } 27 } 28 LazyExpression(bool isNegated)29 LazyExpression::LazyExpression( bool isNegated ) 30 : m_isNegated( isNegated ) 31 {} 32 LazyExpression(LazyExpression const & other)33 LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {} 34 operator bool() const35 LazyExpression::operator bool() const { 36 return m_transientExpression != nullptr; 37 } 38 operator <<(std::ostream & os,LazyExpression const & lazyExpr)39 auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& { 40 if( lazyExpr.m_isNegated ) 41 os << "!"; 42 43 if( lazyExpr ) { 44 if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() ) 45 os << "(" << *lazyExpr.m_transientExpression << ")"; 46 else 47 os << *lazyExpr.m_transientExpression; 48 } 49 else { 50 os << "{** error - unchecked empty expression requested **}"; 51 } 52 return os; 53 } 54 AssertionHandler(StringRef const & macroName,SourceLineInfo const & lineInfo,StringRef capturedExpression,ResultDisposition::Flags resultDisposition)55 AssertionHandler::AssertionHandler 56 ( StringRef const& macroName, 57 SourceLineInfo const& lineInfo, 58 StringRef capturedExpression, 59 ResultDisposition::Flags resultDisposition ) 60 : m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition }, 61 m_resultCapture( getResultCapture() ) 62 {} 63 handleExpr(ITransientExpression const & expr)64 void AssertionHandler::handleExpr( ITransientExpression const& expr ) { 65 m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction ); 66 } handleMessage(ResultWas::OfType resultType,StringRef const & message)67 void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) { 68 m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction ); 69 } 70 allowThrows() const71 auto AssertionHandler::allowThrows() const -> bool { 72 return getCurrentContext().getConfig()->allowThrows(); 73 } 74 complete()75 void AssertionHandler::complete() { 76 setCompleted(); 77 if( m_reaction.shouldDebugBreak ) { 78 79 // If you find your debugger stopping you here then go one level up on the 80 // call-stack for the code that caused it (typically a failed assertion) 81 82 // (To go back to the test and change execution, jump over the throw, next) 83 CATCH_BREAK_INTO_DEBUGGER(); 84 } 85 if (m_reaction.shouldThrow) { 86 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) 87 throw Catch::TestFailureException(); 88 #else 89 CATCH_ERROR( "Test failure requires aborting test!" ); 90 #endif 91 } 92 } setCompleted()93 void AssertionHandler::setCompleted() { 94 m_completed = true; 95 } 96 handleUnexpectedInflightException()97 void AssertionHandler::handleUnexpectedInflightException() { 98 m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction ); 99 } 100 handleExceptionThrownAsExpected()101 void AssertionHandler::handleExceptionThrownAsExpected() { 102 m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction); 103 } handleExceptionNotThrownAsExpected()104 void AssertionHandler::handleExceptionNotThrownAsExpected() { 105 m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction); 106 } 107 handleUnexpectedExceptionNotThrown()108 void AssertionHandler::handleUnexpectedExceptionNotThrown() { 109 m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction ); 110 } 111 handleThrowingCallSkipped()112 void AssertionHandler::handleThrowingCallSkipped() { 113 m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction); 114 } 115 116 // This is the overload that takes a string and infers the Equals matcher from it 117 // 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)118 void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString ) { 119 handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString ); 120 } 121 122 } // namespace Catch 123