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"
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"
2017-08-30 18:07:29 +02:00
# include "catch_debugger.h"
2013-04-22 09:19:17 +02:00
2017-08-27 17:03:32 +02:00
# if !defined(CATCH_CONFIG_DISABLE)
2017-08-26 15:14:27 +02:00
# if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
# define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
# else
# define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
# endif
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
2017-08-09 12:36:33 +02:00
# define INTERNAL_CATCH_REACT( handler ) \
2017-08-08 22:07:30 +02:00
handler . reactWithDebugBreak ( ) ;
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-08 22:07:30 +02:00
# define INTERNAL_CATCH_TRY( capturer ) capturer.setExceptionGuard();
2017-08-09 12:36:33 +02:00
# define INTERNAL_CATCH_CATCH( capturer ) capturer.unsetExceptionGuard();
2017-08-07 01:09:54 +02:00
# 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
2017-08-09 12:36:33 +02:00
# define INTERNAL_CATCH_REACT( handler ) \
2017-08-08 18:53:01 +02:00
if ( handler . shouldDebugBreak ( ) ) CATCH_BREAK_INTO_DEBUGGER ( ) ; \
2017-08-08 22:07:30 +02:00
handler . reactWithoutDebugBreak ( ) ;
2014-05-28 19:53:01 +02:00
2017-08-08 22:07:30 +02:00
# define INTERNAL_CATCH_TRY( capturer ) try
2017-08-09 12:36:33 +02:00
# define INTERNAL_CATCH_CATCH( 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-26 15:14:27 +02:00
Catch : : AssertionHandler catchAssertionHandler ( macroName , CATCH_INTERNAL_LINEINFO , CATCH_INTERNAL_STRINGIFY ( __VA_ARGS__ ) , resultDisposition ) ; \
2017-08-08 22:07:30 +02:00
INTERNAL_CATCH_TRY ( catchAssertionHandler ) { \
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-09 12:36:33 +02:00
} INTERNAL_CATCH_CATCH ( catchAssertionHandler ) \
INTERNAL_CATCH_REACT ( catchAssertionHandler ) \
2017-11-21 14:12:22 +01: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-26 15:14:27 +02:00
Catch : : AssertionHandler catchAssertionHandler ( macroName , CATCH_INTERNAL_LINEINFO , CATCH_INTERNAL_STRINGIFY ( __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-09 12:36:33 +02:00
INTERNAL_CATCH_REACT ( 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-08-26 15:14:27 +02:00
Catch : : AssertionHandler catchAssertionHandler ( macroName , CATCH_INTERNAL_LINEINFO , CATCH_INTERNAL_STRINGIFY ( __VA_ARGS__ ) , resultDisposition ) ; \
2017-08-09 01:52:20 +02:00
if ( catchAssertionHandler . allowThrows ( ) ) \
2014-06-05 19:11:31 +02:00
try { \
2017-05-03 19:10:27 +02:00
static_cast < void > ( __VA_ARGS__ ) ; \
2017-08-09 01:52:20 +02:00
catchAssertionHandler . handle ( Catch : : ResultWas : : DidntThrowException ) ; \
2014-06-05 19:11:31 +02:00
} \
catch ( . . . ) { \
2017-08-09 01:52:20 +02:00
catchAssertionHandler . handle ( Catch : : ResultWas : : Ok ) ; \
2014-06-05 19:11:31 +02:00
} \
else \
2017-08-09 01:52:20 +02:00
catchAssertionHandler . handle ( Catch : : ResultWas : : Ok ) ; \
2017-08-09 12:36:33 +02:00
INTERNAL_CATCH_REACT ( catchAssertionHandler ) \
2014-05-28 19:53:01 +02:00
} 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-26 15:14:27 +02:00
Catch : : AssertionHandler catchAssertionHandler ( macroName , CATCH_INTERNAL_LINEINFO , CATCH_INTERNAL_STRINGIFY ( expr ) " , " CATCH_INTERNAL_STRINGIFY ( exceptionType ) , resultDisposition ) ; \
2017-08-08 20:43:07 +02:00
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 ) ; \
2017-08-09 12:36:33 +02:00
INTERNAL_CATCH_REACT ( 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 ) ; \
2017-08-14 09:54:57 +02:00
catchAssertionHandler . handle ( messageType , ( Catch : : MessageStream ( ) < < __VA_ARGS__ + : : Catch : : StreamEndStop ( ) ) . m_stream . str ( ) ) ; \
2017-08-09 12:36:33 +02:00
INTERNAL_CATCH_REACT ( 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-06-26 20:48:41 +02:00
///////////////////////////////////////////////////////////////////////////////
2017-08-09 13:10:14 +02:00
// Although this is matcher-based, it can be used with just a string
2017-06-26 20:48:41 +02:00
# define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
do { \
2017-08-26 15:14:27 +02:00
Catch : : AssertionHandler catchAssertionHandler ( macroName , CATCH_INTERNAL_LINEINFO , CATCH_INTERNAL_STRINGIFY ( __VA_ARGS__ ) " , " CATCH_INTERNAL_STRINGIFY ( matcher ) , resultDisposition ) ; \
2017-08-09 01:44:30 +02:00
if ( catchAssertionHandler . allowThrows ( ) ) \
2017-06-26 20:48:41 +02:00
try { \
static_cast < void > ( __VA_ARGS__ ) ; \
2017-08-09 01:44:30 +02:00
catchAssertionHandler . handle ( Catch : : ResultWas : : DidntThrowException ) ; \
2017-06-26 20:48:41 +02:00
} \
catch ( . . . ) { \
2017-08-09 01:44:30 +02:00
handleExceptionMatchExpr ( catchAssertionHandler , matcher , # matcher ) ; \
2017-06-26 20:48:41 +02:00
} \
else \
2017-08-09 01:44:30 +02:00
catchAssertionHandler . handle ( Catch : : ResultWas : : Ok ) ; \
2017-08-09 12:36:33 +02:00
INTERNAL_CATCH_REACT ( catchAssertionHandler ) \
2017-06-26 20:48:41 +02:00
} while ( Catch : : alwaysFalse ( ) )
2017-08-27 17:03:32 +02:00
# endif // CATCH_CONFIG_DISABLE
2017-06-26 20:48:41 +02:00
2010-11-10 00:24:00 +01:00
# endif // TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED