2010-11-10 00:24:00 +01:00
/*
* Created by Phil on 18 / 10 / 2010.
* Copyright 2010 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)
*/
# ifndef TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
# define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
2017-08-08 18:53:01 +02:00
# include "catch_assertionhandler.h"
2014-05-28 19:53:01 +02:00
# include "catch_result_builder.h"
2013-02-02 20:58:04 +01:00
# include "catch_message.h"
2011-01-11 10:13:31 +01:00
# include "catch_interfaces_capture.h"
2013-12-03 19:52:41 +01:00
# include "catch_debugger.h"
2011-04-28 09:03:28 +02:00
# include "catch_common.h"
2014-04-23 07:51:58 +02:00
# include "catch_tostring.h"
2014-05-28 19:53:01 +02:00
# include "catch_interfaces_runner.h"
2015-03-04 08:08:53 +01:00
# include "catch_compiler_capabilities.h"
2013-04-22 09:19:17 +02:00
2012-10-29 20:55:13 +01:00
2017-02-14 15:35:12 +01:00
# 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( resultBuilder ) \
resultBuilder . react ( ) ;
2017-03-17 13:21:40 +01:00
///////////////////////////////////////////////////////////////////////////////
// Another way to speed-up compilation is to omit local try-catch for REQUIRE*
// macros.
// This can potentially cause false negative, if the test code catches
// the exception before it propagates back up to the runner.
2017-08-07 01:09:54 +02:00
# define INTERNAL_CATCH_TRY
# define INTERNAL_CATCH_CATCH( capturer, disposition )
# else // CATCH_CONFIG_FAST_COMPILE
2011-02-03 21:00:46 +01:00
///////////////////////////////////////////////////////////////////////////////
2014-05-28 19:53:01 +02:00
// 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( resultBuilder ) \
if ( resultBuilder . shouldDebugBreak ( ) ) CATCH_BREAK_INTO_DEBUGGER ( ) ; \
2017-08-08 18:53:01 +02:00
resultBuilder . react ( ) ;
# define INTERNAL_CATCH_REACT2( handler ) \
if ( handler . shouldDebugBreak ( ) ) CATCH_BREAK_INTO_DEBUGGER ( ) ; \
handler . reactWithDebugBreak ( ) ;
2014-05-28 19:53:01 +02:00
2017-08-07 01:09:54 +02:00
# define INTERNAL_CATCH_TRY try
# define INTERNAL_CATCH_CATCH( capturer, disposition ) catch(...) { capturer.useActiveException( disposition ); }
2017-08-08 20:36:18 +02:00
# define INTERNAL_CATCH_CATCH2( capturer ) catch(...) { capturer.useActiveException(); }
2017-08-07 01:09:54 +02:00
# endif
2010-12-27 21:49:19 +01:00
2012-10-24 22:59:47 +02:00
///////////////////////////////////////////////////////////////////////////////
2017-04-26 17:10:18 +02:00
# define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
2012-10-29 20:55:13 +01:00
do { \
2017-08-08 18:53:01 +02:00
Catch : : AssertionHandler catchAssertionHandler ( macroName , CATCH_INTERNAL_LINEINFO , # __VA_ARGS__ , resultDisposition ) ; \
2017-08-07 01:09:54 +02:00
INTERNAL_CATCH_TRY { \
2016-02-29 09:01:06 +01:00
CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
2017-08-08 18:53:01 +02:00
catchAssertionHandler . handle ( Catch : : Decomposer ( ) < = __VA_ARGS__ ) ; \
2017-02-15 10:38:38 +01:00
CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
2017-08-08 20:36:18 +02:00
} INTERNAL_CATCH_CATCH2 ( catchAssertionHandler ) \
2017-08-08 18:53:01 +02:00
INTERNAL_CATCH_REACT2 ( catchAssertionHandler ) \
2017-04-26 17:10:18 +02:00
} while ( Catch : : isTrue ( false & & static_cast < bool > ( ! ! ( __VA_ARGS__ ) ) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look
2017-01-30 11:56:29 +01:00
// The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
2010-11-10 00:24:00 +01:00
2012-02-10 09:30:13 +01:00
///////////////////////////////////////////////////////////////////////////////
2017-05-03 19:10:27 +02:00
# define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
INTERNAL_CATCH_TEST ( macroName , resultDisposition , __VA_ARGS__ ) ; \
2017-06-26 21:30:23 +02:00
if ( Catch : : getResultCapture ( ) . lastAssertionPassed ( ) )
2012-02-10 09:30:13 +01:00
///////////////////////////////////////////////////////////////////////////////
2017-05-03 19:10:27 +02:00
# define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
INTERNAL_CATCH_TEST ( macroName , resultDisposition , __VA_ARGS__ ) ; \
2017-06-26 21:30:23 +02:00
if ( ! Catch : : getResultCapture ( ) . lastAssertionPassed ( ) )
2012-02-10 09:30:13 +01:00
2011-03-14 09:45:55 +01:00
///////////////////////////////////////////////////////////////////////////////
2017-05-03 19:10:27 +02:00
# define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
2012-10-29 20:55:13 +01:00
do { \
2017-08-08 20:36:18 +02:00
Catch : : AssertionHandler catchAssertionHandler ( macroName , CATCH_INTERNAL_LINEINFO , # __VA_ARGS__ , resultDisposition ) ; \
2012-10-29 20:55:13 +01:00
try { \
2017-05-03 19:10:27 +02:00
static_cast < void > ( __VA_ARGS__ ) ; \
2017-08-08 20:36:18 +02:00
catchAssertionHandler . handle ( Catch : : ResultWas : : Ok ) ; \
2012-10-29 20:55:13 +01:00
} \
catch ( . . . ) { \
2017-08-08 20:36:18 +02:00
catchAssertionHandler . useActiveException ( ) ; \
2012-10-29 20:55:13 +01:00
} \
2017-08-08 20:36:18 +02:00
INTERNAL_CATCH_REACT2 ( catchAssertionHandler ) \
2014-05-28 19:53:01 +02:00
} while ( Catch : : alwaysFalse ( ) )
2011-03-14 09:45:55 +01:00
2011-02-03 21:00:46 +01:00
///////////////////////////////////////////////////////////////////////////////
2017-06-26 20:48:41 +02:00
# define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
2012-10-29 20:55:13 +01:00
do { \
2017-06-26 20:48:41 +02:00
Catch : : ResultBuilder __catchResult ( macroName , CATCH_INTERNAL_LINEINFO , # __VA_ARGS__ , resultDisposition ) ; \
2014-06-05 19:11:31 +02:00
if ( __catchResult . allowThrows ( ) ) \
try { \
2017-05-03 19:10:27 +02:00
static_cast < void > ( __VA_ARGS__ ) ; \
2014-06-05 19:11:31 +02:00
__catchResult . captureResult ( Catch : : ResultWas : : DidntThrowException ) ; \
} \
catch ( . . . ) { \
2017-06-26 20:48:41 +02:00
__catchResult . captureExpectedException ( " " ) ; \
2014-06-05 19:11:31 +02:00
} \
else \
2014-05-28 19:53:01 +02:00
__catchResult . captureResult ( Catch : : ResultWas : : Ok ) ; \
INTERNAL_CATCH_REACT ( __catchResult ) \
} while ( Catch : : alwaysFalse ( ) )
2012-10-29 20:55:13 +01:00
2011-02-03 21:00:46 +01:00
///////////////////////////////////////////////////////////////////////////////
2017-03-21 14:22:39 +01:00
# define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
2012-10-29 20:55:13 +01:00
do { \
2017-08-08 20:43:07 +02:00
Catch : : AssertionHandler catchAssertionHandler ( macroName , CATCH_INTERNAL_LINEINFO , # expr " , " # exceptionType , resultDisposition ) ; \
if ( catchAssertionHandler . allowThrows ( ) ) \
2014-06-05 19:11:31 +02:00
try { \
2017-01-31 18:02:11 +01:00
static_cast < void > ( expr ) ; \
2017-08-08 20:43:07 +02:00
catchAssertionHandler . handle ( Catch : : ResultWas : : DidntThrowException ) ; \
2014-06-05 19:11:31 +02:00
} \
2017-07-19 21:30:00 +02:00
catch ( exceptionType const & ) { \
2017-08-08 20:43:07 +02:00
catchAssertionHandler . handle ( Catch : : ResultWas : : Ok ) ; \
2014-06-05 19:11:31 +02:00
} \
catch ( . . . ) { \
2017-08-08 20:43:07 +02:00
catchAssertionHandler . useActiveException ( ) ; \
2014-06-05 19:11:31 +02:00
} \
else \
2017-08-08 20:43:07 +02:00
catchAssertionHandler . handle ( Catch : : ResultWas : : Ok ) ; \
INTERNAL_CATCH_REACT2 ( catchAssertionHandler ) \
2014-05-28 19:53:01 +02:00
} while ( Catch : : alwaysFalse ( ) )
2010-11-10 00:24:00 +01:00
2013-02-02 20:58:04 +01:00
///////////////////////////////////////////////////////////////////////////////
2017-06-26 17:47:40 +02:00
# define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
do { \
2017-08-08 21:17:09 +02:00
Catch : : AssertionHandler catchAssertionHandler ( macroName , CATCH_INTERNAL_LINEINFO , " " , resultDisposition ) ; \
catchAssertionHandler . handle ( messageType , ( Catch : : MessageStream ( ) < < __VA_ARGS__ + : : Catch : : StreamEndStop ( ) ) . m_stream . str ( ) . c_str ( ) ) ; \
INTERNAL_CATCH_REACT2 ( catchAssertionHandler ) \
2017-06-26 17:47:40 +02:00
} while ( Catch : : alwaysFalse ( ) )
2010-11-10 00:24:00 +01:00
2011-02-03 21:00:46 +01:00
///////////////////////////////////////////////////////////////////////////////
2017-03-21 14:22:39 +01:00
# define INTERNAL_CATCH_INFO( macroName, log ) \
2013-06-28 18:09:57 +02:00
Catch : : ScopedMessage INTERNAL_CATCH_UNIQUE_NAME ( scopedMessage ) = Catch : : MessageBuilder ( macroName , CATCH_INTERNAL_LINEINFO , Catch : : ResultWas : : Info ) < < log ;
2013-02-02 20:58:04 +01:00
2017-07-29 08:43:32 +02:00
# if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
2012-03-04 12:14:21 +01:00
///////////////////////////////////////////////////////////////////////////////
2017-03-21 14:22:39 +01:00
# define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
2012-10-29 20:55:13 +01:00
do { \
2015-08-08 00:15:58 +02:00
Catch : : ResultBuilder __catchResult ( macroName , CATCH_INTERNAL_LINEINFO , # arg " , " # matcher , resultDisposition ) ; \
2017-08-07 01:09:54 +02:00
INTERNAL_CATCH_TRY { \
2017-01-09 13:23:10 +01:00
__catchResult . captureMatch ( arg , matcher , # matcher ) ; \
2017-08-07 01:09:54 +02:00
} INTERNAL_CATCH_CATCH ( __catchResult , resultDisposition ) \
2014-05-28 19:53:01 +02:00
INTERNAL_CATCH_REACT ( __catchResult ) \
} while ( Catch : : alwaysFalse ( ) )
2012-03-04 12:14:21 +01:00
2017-06-26 20:48:41 +02:00
///////////////////////////////////////////////////////////////////////////////
# define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
do { \
Catch : : ResultBuilder __catchResult ( macroName , CATCH_INTERNAL_LINEINFO , # __VA_ARGS__ " , " # matcher , resultDisposition ) ; \
if ( __catchResult . allowThrows ( ) ) \
try { \
static_cast < void > ( __VA_ARGS__ ) ; \
__catchResult . captureResult ( Catch : : ResultWas : : DidntThrowException ) ; \
} \
catch ( . . . ) { \
__catchResult . captureExpectedException ( matcher ) ; \
} \
else \
__catchResult . captureResult ( Catch : : ResultWas : : Ok ) ; \
INTERNAL_CATCH_REACT ( __catchResult ) \
} while ( Catch : : alwaysFalse ( ) )
2017-06-05 18:40:50 +02:00
///////////////////////////////////////////////////////////////////////////////
# define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, expr ) \
do { \
2017-06-26 20:48:41 +02:00
Catch : : ResultBuilder __catchResult ( macroName , CATCH_INTERNAL_LINEINFO , # expr " , " # exceptionType " , " # matcher , resultDisposition ) ; \
2017-06-05 18:40:50 +02:00
if ( __catchResult . allowThrows ( ) ) \
try { \
static_cast < void > ( expr ) ; \
__catchResult . captureResult ( Catch : : ResultWas : : DidntThrowException ) ; \
} \
2017-07-19 21:30:00 +02:00
catch ( exceptionType const & ex ) { \
2017-06-05 18:40:50 +02:00
__catchResult . captureMatch ( ex , matcher , # matcher ) ; \
} \
catch ( . . . ) { \
__catchResult . useActiveException ( resultDisposition ) ; \
} \
else \
__catchResult . captureResult ( Catch : : ResultWas : : Ok ) ; \
INTERNAL_CATCH_REACT ( __catchResult ) \
} while ( Catch : : alwaysFalse ( ) )
2017-07-28 21:34:34 +02:00
# endif // CATCH_CONFIG_DISABLE_MATCHERS
2017-06-05 18:40:50 +02:00
2010-11-10 00:24:00 +01:00
# endif // TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED