11 #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED 12 #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED 14 #define TWOBLUECUBES_CATCH_HPP_INCLUDED 17 # pragma clang system_header 18 #elif defined __GNUC__ 19 # pragma GCC system_header 24 #define TWOBLUECUBES_CATCH_SUPPRESS_WARNINGS_H_INCLUDED 27 # ifdef __ICC // icpc defines the __clang__ macro 28 # pragma warning(push) 29 # pragma warning(disable: 161 1682) 31 # pragma clang diagnostic ignored "-Wglobal-constructors" 32 # pragma clang diagnostic ignored "-Wvariadic-macros" 33 # pragma clang diagnostic ignored "-Wc99-extensions" 34 # pragma clang diagnostic ignored "-Wunused-variable" 35 # pragma clang diagnostic push 36 # pragma clang diagnostic ignored "-Wpadded" 37 # pragma clang diagnostic ignored "-Wc++98-compat" 38 # pragma clang diagnostic ignored "-Wc++98-compat-pedantic" 39 # pragma clang diagnostic ignored "-Wswitch-enum" 41 #elif defined __GNUC__ 42 # pragma GCC diagnostic ignored "-Wvariadic-macros" 43 # pragma GCC diagnostic ignored "-Wunused-variable" 44 # pragma GCC diagnostic push 45 # pragma GCC diagnostic ignored "-Wpadded" 48 #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) 53 # ifndef CLARA_CONFIG_MAIN 54 # define CLARA_CONFIG_MAIN_NOT_DEFINED 55 # define CLARA_CONFIG_MAIN 60 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED 63 #define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED 65 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line 66 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) 67 #define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) 69 #define INTERNAL_CATCH_STRINGIFY2( expr ) #expr 70 #define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr ) 77 #define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED 101 # if __has_feature(cxx_nullptr) 102 # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR 105 # if __has_feature(cxx_noexcept) 106 # define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT 115 #endif // __BORLANDC__ 119 #ifdef __EDG_VERSION__ 121 #endif // __EDG_VERSION__ 133 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) ) 134 # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR 143 #if (_MSC_VER >= 1600) 144 # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR 147 #if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015)) 148 #define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT 149 #define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS 155 #if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \ 156 ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \ 157 ( defined __GNUC__ && __GNUC__ >= 3 ) || \ 158 ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L ) 160 #define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS 168 #if (__cplusplus >= 201103L) 170 # define CATCH_CPP11_OR_GREATER 172 # if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) 173 # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR 176 # ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT 177 # define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT 180 # ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS 181 # define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS 184 # ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM 185 # define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM 188 # ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE 189 # define CATCH_INTERNAL_CONFIG_CPP11_TUPLE 192 # ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS 193 # define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS 196 #endif // __cplusplus >= 201103L 199 #if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11) 200 # define CATCH_CONFIG_CPP11_NULLPTR 202 #if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11) 203 # define CATCH_CONFIG_CPP11_NOEXCEPT 205 #if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11) 206 # define CATCH_CONFIG_CPP11_GENERATED_METHODS 208 #if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11) 209 # define CATCH_CONFIG_CPP11_IS_ENUM 211 #if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11) 212 # define CATCH_CONFIG_CPP11_TUPLE 214 #if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS) 215 #define CATCH_CONFIG_VARIADIC_MACROS 219 #if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT) 220 # define CATCH_NOEXCEPT noexcept 221 # define CATCH_NOEXCEPT_IS(x) noexcept(x) 223 # define CATCH_NOEXCEPT throw() 224 # define CATCH_NOEXCEPT_IS(x) 230 #ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS 256 template<
typename ContainerT>
258 typename ContainerT::const_iterator it = container.begin();
259 typename ContainerT::const_iterator itEnd = container.end();
260 for(; it != itEnd; ++it )
263 template<
typename AssociativeContainerT>
265 typename AssociativeContainerT::const_iterator it = container.begin();
266 typename AssociativeContainerT::const_iterator itEnd = container.end();
267 for(; it != itEnd; ++it )
293 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS 330 #define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) ) 331 #define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO ); 355 #define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO ) 358 #define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED 361 #define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED 369 virtual bool moveNext() = 0;
370 virtual std::size_t getCurrentIndex()
const = 0;
377 virtual bool moveNext() = 0;
385 #define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED 388 #pragma clang diagnostic push 389 #pragma clang diagnostic ignored "-Wpadded" 405 Ptr(
Ptr const& other ) : m_p( other.m_p ){
429 T*
get() {
return m_p; }
430 const T*
get()
const{
return m_p; }
433 bool operator !()
const {
return m_p == NULL; }
442 virtual void addRef()
const = 0;
443 virtual void release()
const = 0;
446 template<
typename T = IShared>
465 #pragma clang diagnostic pop 486 virtual IRunner* getRunner() = 0;
487 virtual size_t getGeneratorIndex(
std::string const& fileInfo,
size_t totalSize ) = 0;
488 virtual bool advanceGeneratorsForCurrentTest() = 0;
495 virtual void setResultCapture(
IResultCapture* resultCapture ) = 0;
496 virtual void setRunner(
IRunner* runner ) = 0;
508 #define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED 511 #define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED 520 virtual void invoke ()
const = 0;
530 virtual std::vector<TestCase>
const& getAllTests()
const = 0;
531 virtual void getFilteredTests( TestSpec
const& testSpec, IConfig
const&
config, std::vector<TestCase>& matchingTestCases,
bool negated =
false )
const = 0;
558 NameAndDesc(
const char* _name =
"",
const char* _description=
"" )
559 :
name( _name ), description( _description )
574 char const* className,
583 void registerTestCase(
ITestCase* testCase,
584 char const* className,
597 #ifdef CATCH_CONFIG_VARIADIC_MACROS 598 #define INTERNAL_CATCH_TESTCASE( ... ) \ 600 static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \ 601 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\ 602 static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )() 605 #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ 606 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); } 609 #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... )\ 611 struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \ 614 Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \ 616 void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test() 619 #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \ 621 static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \ 622 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\ 623 static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )() 626 #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \ 627 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); } 630 #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\ 632 struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \ 635 Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \ 637 void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test() 642 #define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED 645 #define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED 648 #define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED 661 ExpressionFailed = FailureBit | 1,
662 ExplicitFailure = FailureBit | 2,
664 Exception = 0x100 | FailureBit,
666 ThrewException = Exception | 1,
667 DidntThrowException = Exception | 2,
669 FatalErrorCondition = 0x200 | FailureBit
684 ContinueOnFailure = 0x02,
700 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED 734 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS 742 bool succeeded()
const;
744 bool hasExpression()
const;
745 bool hasMessage()
const;
748 bool hasExpandedExpression()
const;
767 struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
772 oss << other.
oss.str();
776 oss << other.
oss.str();
786 char const* capturedExpression,
795 m_stream.oss <<
value;
799 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT
const& );
800 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT
const& );
808 void endExpression();
815 void captureExpression();
817 bool shouldDebugBreak()
const;
818 bool allowThrows()
const;
838 #define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED 841 #define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED 844 #pragma warning(push) 845 #pragma warning(disable:4389) // '==' : signed/unsigned mismatch 871 inline T&
opCast(T
const&
t) {
return const_cast<T&
>(
t); }
874 #ifdef CATCH_CONFIG_CPP11_NULLPTR 875 inline std::nullptr_t
opCast(std::nullptr_t) {
return nullptr; }
876 #endif // CATCH_CONFIG_CPP11_NULLPTR 880 template<
typename T1,
typename T2, Operator Op>
883 template<
typename T1,
typename T2>
885 static bool evaluate( T1
const& lhs, T2
const& rhs) {
889 template<
typename T1,
typename T2>
891 static bool evaluate( T1
const& lhs, T2
const& rhs ) {
895 template<
typename T1,
typename T2>
897 static bool evaluate( T1
const& lhs, T2
const& rhs ) {
901 template<
typename T1,
typename T2>
903 static bool evaluate( T1
const& lhs, T2
const& rhs ) {
907 template<
typename T1,
typename T2>
909 static bool evaluate( T1
const& lhs, T2
const& rhs ) {
913 template<
typename T1,
typename T2>
915 static bool evaluate( T1
const& lhs, T2
const& rhs ) {
920 template<Operator Op,
typename T1,
typename T2>
929 template<Operator Op,
typename T1,
typename T2>
930 bool compare( T1
const& lhs, T2
const& rhs ) {
935 template<Operator Op>
bool compare(
unsigned int lhs,
int rhs ) {
936 return applyEvaluator<Op>( lhs,
static_cast<unsigned int>( rhs ) );
938 template<Operator Op>
bool compare(
unsigned long lhs,
int rhs ) {
939 return applyEvaluator<Op>( lhs,
static_cast<unsigned int>( rhs ) );
941 template<Operator Op>
bool compare(
unsigned char lhs,
int rhs ) {
942 return applyEvaluator<Op>( lhs,
static_cast<unsigned int>( rhs ) );
946 template<Operator Op>
bool compare(
unsigned int lhs,
long rhs ) {
947 return applyEvaluator<Op>( lhs,
static_cast<unsigned long>( rhs ) );
949 template<Operator Op>
bool compare(
unsigned long lhs,
long rhs ) {
950 return applyEvaluator<Op>( lhs,
static_cast<unsigned long>( rhs ) );
952 template<Operator Op>
bool compare(
unsigned char lhs,
long rhs ) {
953 return applyEvaluator<Op>( lhs,
static_cast<unsigned long>( rhs ) );
957 template<Operator Op>
bool compare(
int lhs,
unsigned int rhs ) {
958 return applyEvaluator<Op>(
static_cast<unsigned int>( lhs ), rhs );
960 template<Operator Op>
bool compare(
int lhs,
unsigned long rhs ) {
961 return applyEvaluator<Op>(
static_cast<unsigned int>( lhs ), rhs );
963 template<Operator Op>
bool compare(
int lhs,
unsigned char rhs ) {
964 return applyEvaluator<Op>(
static_cast<unsigned int>( lhs ), rhs );
968 template<Operator Op>
bool compare(
long lhs,
unsigned int rhs ) {
969 return applyEvaluator<Op>(
static_cast<unsigned long>( lhs ), rhs );
971 template<Operator Op>
bool compare(
long lhs,
unsigned long rhs ) {
972 return applyEvaluator<Op>(
static_cast<unsigned long>( lhs ), rhs );
974 template<Operator Op>
bool compare(
long lhs,
unsigned char rhs ) {
975 return applyEvaluator<Op>(
static_cast<unsigned long>( lhs ), rhs );
979 template<Operator Op,
typename T>
bool compare(
long lhs, T* rhs ) {
982 template<Operator Op,
typename T>
bool compare( T* lhs,
long rhs ) {
987 template<Operator Op,
typename T>
bool compare(
int lhs, T* rhs ) {
990 template<Operator Op,
typename T>
bool compare( T* lhs,
int rhs ) {
994 #ifdef CATCH_CONFIG_CPP11_NULLPTR 996 template<Operator Op,
typename T>
bool compare( std::nullptr_t, T* rhs ) {
999 template<Operator Op,
typename T>
bool compare( T* lhs, std::nullptr_t ) {
1002 #endif // CATCH_CONFIG_CPP11_NULLPTR 1008 #pragma warning(pop) 1012 #define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED 1022 #define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED 1024 #import <Foundation/Foundation.h> 1026 #ifdef __has_feature 1027 #define CATCH_ARC_ENABLED __has_feature(objc_arc) 1029 #define CATCH_ARC_ENABLED 0 1032 void arcSafeRelease( NSObject*
obj );
1033 id performOptionalSelector(
id obj,
SEL sel );
1035 #if !CATCH_ARC_ENABLED 1036 inline void arcSafeRelease( NSObject*
obj ) {
1039 inline id performOptionalSelector(
id obj,
SEL sel ) {
1040 if( [obj respondsToSelector: sel] )
1041 return [obj performSelector: sel];
1044 #define CATCH_UNSAFE_UNRETAINED 1045 #define CATCH_ARC_STRONG 1047 inline void arcSafeRelease( NSObject* ){}
1048 inline id performOptionalSelector(
id obj,
SEL sel ) {
1050 #pragma clang diagnostic push 1051 #pragma clang diagnostic ignored "-Warc-performSelector-leaks" 1053 if( [obj respondsToSelector: sel] )
1054 return [obj performSelector: sel];
1056 #pragma clang diagnostic pop 1060 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained 1061 #define CATCH_ARC_STRONG __strong 1066 #ifdef CATCH_CONFIG_CPP11_TUPLE 1070 #ifdef CATCH_CONFIG_CPP11_IS_ENUM 1071 #include <type_traits> 1077 template<
typename T>
1098 #ifdef CATCH_CONFIG_CPP11_NULLPTR 1113 template<
typename T>
BorgType( T
const& );
1124 template<
typename T>
1126 static std::ostream &
s;
1131 #if defined(CATCH_CONFIG_CPP11_IS_ENUM) 1132 template<
typename T,
1135 struct EnumStringMaker
1140 template<
typename T>
1141 struct EnumStringMaker<T,true>
1153 #if defined(CATCH_CONFIG_CPP11_IS_ENUM) 1154 template<
typename T>
1157 return EnumStringMaker<T>::convert( v );
1160 template<
typename T>
1167 template<
typename T>
1169 std::ostringstream oss;
1177 template<
typename T>
1184 template<
typename T>
1188 template<
typename T>
1190 template<
typename U>
1199 template<
typename R,
typename C>
1210 template<
typename InputIterator>
1221 template<
typename T,
typename Allocator>
1226 #ifdef CATCH_CONFIG_CPP11_TUPLE 1229 namespace TupleDetail {
1235 struct ElementPrinter {
1236 static void print(
const Tuple& tuple, std::ostream& os )
1238 os << ( N ?
", " :
" " )
1240 ElementPrinter<Tuple,N+1>::print(tuple,os);
1248 struct ElementPrinter<Tuple,N,false> {
1249 static void print(
const Tuple&, std::ostream& ) {}
1254 template<
typename ...Types>
1257 static std::string convert(
const std::tuple<Types...>& tuple )
1259 std::ostringstream os;
1261 TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );
1266 #endif // CATCH_CONFIG_CPP11_TUPLE 1269 template<
typename T>
1282 template<
typename T>
1288 template<
typename InputIterator>
1290 std::ostringstream oss;
1292 if( first != last ) {
1294 for( ++first ; first != last ; ++
first )
1295 oss <<
", " << Catch::toString( *first );
1308 template<
typename T>
1311 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS 1317 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS 1322 template<
typename RhsT>
1324 return captureExpression<Internal::IsEqualTo>( rhs );
1327 template<
typename RhsT>
1329 return captureExpression<Internal::IsNotEqualTo>( rhs );
1332 template<
typename RhsT>
1334 return captureExpression<Internal::IsLessThan>( rhs );
1337 template<
typename RhsT>
1339 return captureExpression<Internal::IsGreaterThan>( rhs );
1342 template<
typename RhsT>
1344 return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
1347 template<
typename RhsT>
1349 return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
1353 return captureExpression<Internal::IsEqualTo>( rhs );
1357 return captureExpression<Internal::IsNotEqualTo>( rhs );
1361 bool value = m_lhs ?
true :
false;
1364 .setResultType( value )
1370 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison&
operator + ( RhsT
const& );
1371 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT
const& );
1372 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT
const& );
1373 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison&
operator * ( RhsT
const& );
1374 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT
const& );
1375 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT
const& );
1378 template<Internal::Operator Op,
typename RhsT>
1397 template<
typename T>
1409 #define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED 1440 : m_info( macroName, lineInfo, type )
1443 template<
typename T>
1465 #define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED 1472 class AssertionResult;
1473 struct AssertionInfo;
1476 class ScopedMessageBuilder;
1484 virtual bool sectionStarted(
SectionInfo const& sectionInfo,
1485 Counts& assertions ) = 0;
1486 virtual void sectionEnded(
SectionInfo const&
name,
Counts const& assertions,
double _durationInSeconds ) = 0;
1488 virtual void popScopedMessage(
MessageInfo const& message ) = 0;
1490 virtual std::string getCurrentTestName()
const = 0;
1493 virtual void handleFatalErrorCondition(
std::string const& message ) = 0;
1500 #define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED 1503 #define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED 1505 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) 1506 #define CATCH_PLATFORM_MAC 1507 #elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) 1508 #define CATCH_PLATFORM_IPHONE 1509 #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) 1510 #define CATCH_PLATFORM_WINDOWS 1521 #ifdef CATCH_PLATFORM_MAC 1526 #if defined(__ppc64__) || defined(__ppc__) 1527 #define CATCH_BREAK_INTO_DEBUGGER() \ 1528 if( Catch::isDebuggerActive() ) { \ 1529 __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \ 1530 : : : "memory","r0","r3","r4" ); \ 1533 #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );} 1537 #elif defined(_MSC_VER) 1538 #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); } 1539 #elif defined(__MINGW32__) 1540 extern "C" __declspec(dllimport)
void __stdcall DebugBreak();
1541 #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); } 1544 #ifndef CATCH_BREAK_INTO_DEBUGGER 1545 #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue(); 1549 #define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED 1556 virtual bool aborting()
const = 0;
1565 #define INTERNAL_CATCH_REACT( resultBuilder ) \ 1566 if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \ 1567 resultBuilder.react(); 1570 #define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \ 1572 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ 1574 ( __catchResult <= expr ).endExpression(); \ 1577 __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \ 1579 INTERNAL_CATCH_REACT( __catchResult ) \ 1580 } while( Catch::isTrue( false && (expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look 1583 #define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \ 1584 INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \ 1585 if( Catch::getResultCapture().getLastResult()->succeeded() ) 1588 #define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \ 1589 INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \ 1590 if( !Catch::getResultCapture().getLastResult()->succeeded() ) 1593 #define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \ 1595 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ 1598 __catchResult.captureResult( Catch::ResultWas::Ok ); \ 1601 __catchResult.useActiveException( resultDisposition ); \ 1603 INTERNAL_CATCH_REACT( __catchResult ) \ 1604 } while( Catch::alwaysFalse() ) 1607 #define INTERNAL_CATCH_THROWS( expr, resultDisposition, macroName ) \ 1609 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ 1610 if( __catchResult.allowThrows() ) \ 1613 __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ 1616 __catchResult.captureResult( Catch::ResultWas::Ok ); \ 1619 __catchResult.captureResult( Catch::ResultWas::Ok ); \ 1620 INTERNAL_CATCH_REACT( __catchResult ) \ 1621 } while( Catch::alwaysFalse() ) 1624 #define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \ 1626 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ 1627 if( __catchResult.allowThrows() ) \ 1630 __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ 1632 catch( exceptionType ) { \ 1633 __catchResult.captureResult( Catch::ResultWas::Ok ); \ 1636 __catchResult.useActiveException( resultDisposition ); \ 1639 __catchResult.captureResult( Catch::ResultWas::Ok ); \ 1640 INTERNAL_CATCH_REACT( __catchResult ) \ 1641 } while( Catch::alwaysFalse() ) 1644 #ifdef CATCH_CONFIG_VARIADIC_MACROS 1645 #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \ 1647 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ 1648 __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \ 1649 __catchResult.captureResult( messageType ); \ 1650 INTERNAL_CATCH_REACT( __catchResult ) \ 1651 } while( Catch::alwaysFalse() ) 1653 #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \ 1655 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ 1656 __catchResult << log + ::Catch::StreamEndStop(); \ 1657 __catchResult.captureResult( messageType ); \ 1658 INTERNAL_CATCH_REACT( __catchResult ) \ 1659 } while( Catch::alwaysFalse() ) 1663 #define INTERNAL_CATCH_INFO( log, macroName ) \ 1664 Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log; 1667 #define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \ 1669 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg " " #matcher, resultDisposition ); \ 1671 std::string matcherAsString = ::Catch::Matchers::matcher.toString(); \ 1673 .setLhs( Catch::toString( arg ) ) \ 1674 .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \ 1675 .setOp( "matches" ) \ 1676 .setResultType( ::Catch::Matchers::matcher.match( arg ) ); \ 1677 __catchResult.captureExpression(); \ 1679 __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \ 1681 INTERNAL_CATCH_REACT( __catchResult ) \ 1682 } while( Catch::alwaysFalse() ) 1685 #define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED 1688 #define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED 1706 #define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED 1713 Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}
1730 return passed + failed + failedButOk;
1733 return failed == 0 && failedButOk == 0;
1754 Totals diff = *
this - prevTotals;
1776 #define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED 1778 #ifdef CATCH_PLATFORM_WINDOWS 1779 typedef unsigned long long uint64_t;
1790 unsigned int getElapsedMicroseconds()
const;
1791 unsigned int getElapsedMilliseconds()
const;
1792 double getElapsedSeconds()
const;
1810 operator bool()
const;
1823 #ifdef CATCH_CONFIG_VARIADIC_MACROS 1824 #define INTERNAL_CATCH_SECTION( ... ) \ 1825 if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) 1827 #define INTERNAL_CATCH_SECTION( name, desc ) \ 1828 if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) ) 1832 #define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED 1841 template<
typename T>
1844 virtual T getValue( std::size_t
index )
const = 0;
1845 virtual std::size_t
size ()
const = 0;
1848 template<
typename T>
1854 return m_from+
static_cast<int>(
index );
1858 return static_cast<std::size_t
>( 1+m_to-m_from );
1867 template<
typename T>
1873 m_values.push_back( value );
1877 return m_values[
index];
1881 return m_values.size();
1888 template<
typename T>
1895 : m_fileInfo( other.m_fileInfo ),
1902 m_fileInfo = fileInfo;
1910 operator T ()
const {
1913 typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
1914 typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
1915 for(
size_t index = 0; it != itEnd; ++it )
1918 if( overallIndex >=
index && overallIndex < index + generator->
size() )
1929 m_totalSize += generator->
size();
1930 m_composed.push_back( generator );
1940 valuesGen->
add( value );
1948 std::copy( other.
m_composed.begin(), other.
m_composed.end(), std::back_inserter( m_composed ) );
1958 namespace Generators
1960 template<
typename T>
1967 template<
typename T>
1971 valuesGen->
add( val1 );
1972 valuesGen->
add( val2 );
1973 generators.
add( valuesGen );
1977 template<
typename T>
1981 valuesGen->
add( val1 );
1982 valuesGen->
add( val2 );
1983 valuesGen->
add( val3 );
1984 generators.
add( valuesGen );
1988 template<
typename T>
1992 valuesGen->
add( val1 );
1993 valuesGen->
add( val2 );
1994 valuesGen->
add( val3 );
1995 valuesGen->
add( val4 );
1996 generators.
add( valuesGen );
2002 using namespace Generators;
2006 #define INTERNAL_CATCH_LINESTR2( line ) #line 2007 #define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line ) 2009 #define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" ) 2012 #define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED 2016 #define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED 2023 struct ITestCaseRegistry;
2024 struct IExceptionTranslatorRegistry;
2025 struct IExceptionTranslator;
2026 struct IReporterRegistry;
2027 struct IReporterFactory;
2032 virtual IReporterRegistry
const& getReporterRegistry()
const = 0;
2039 virtual void registerReporter(
std::string const&
name, IReporterFactory* factory ) = 0;
2040 virtual void registerTest(
TestCase const& testInfo ) = 0;
2068 template<
typename T>
2073 : m_translateFunction( translateFunction )
2081 return m_translateFunction( ex );
2090 template<
typename T>
2099 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) \ 2100 static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ); \ 2101 namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ) ); }\ 2102 static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ) 2105 #define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED 2116 : m_epsilon(
std::numeric_limits<float>::epsilon()*100 ),
2122 : m_epsilon( other.m_epsilon ),
2123 m_scale( other.m_scale ),
2124 m_value( other.m_value )
2134 approx.
scale( m_scale );
2147 friend bool operator != (
double lhs,
Approx const& rhs ) {
2151 friend bool operator != (
Approx const& lhs,
double rhs ) {
2156 m_epsilon = newEpsilon;
2166 std::ostringstream oss;
2180 return value.toString();
2186 #define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED 2189 namespace Matchers {
2192 template<
typename ExpressionT>
2199 virtual bool match( ExpressionT
const& expr )
const = 0;
2203 template<
typename DerivedT,
typename ExpressionT>
2213 template<
typename ExpressionT>
2221 m_matchers.push_back( matcher.
clone() );
2224 virtual bool match( ExpressionT
const& expr )
const 2226 for( std::size_t i = 0; i < m_matchers.size(); ++i )
2227 if( !m_matchers[i]->match( expr ) )
2232 std::ostringstream oss;
2234 for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
2237 oss << m_matchers[i]->toString();
2247 template<
typename ExpressionT>
2255 m_matchers.push_back( matcher.
clone() );
2258 virtual bool match( ExpressionT
const& expr )
const 2260 for( std::size_t i = 0; i < m_matchers.size(); ++i )
2261 if( m_matchers[i]->match( expr ) )
2266 std::ostringstream oss;
2268 for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
2271 oss << m_matchers[i]->toString();
2283 namespace StdString {
2295 return m_str == expr;
2298 return "equals: \"" + m_str +
"\"";
2311 return expr.find( m_substr ) != std::string::npos;
2314 return "contains: \"" + m_substr +
"\"";
2327 return expr.find( m_substr ) == 0;
2330 return "starts with: \"" + m_substr +
"\"";
2343 return expr.find( m_substr ) == expr.size() - m_substr.size();
2346 return "ends with: \"" + m_substr +
"\"";
2356 template<
typename ExpressionT>
2361 template<
typename ExpressionT>
2367 template<
typename ExpressionT>
2372 template<
typename ExpressionT>
2406 using namespace Matchers;
2411 #define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED 2414 #define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED 2433 #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } 2435 #define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED 2440 template<
typename T>
2445 : nullableValue( new( storage ) T( _value ) )
2448 : nullableValue( _other ? new( storage ) T( *_other ) : NULL )
2456 if( &_other !=
this ) {
2459 nullableValue =
new( storage ) T( *_other );
2465 nullableValue =
new( storage ) T( _value );
2471 nullableValue->~T();
2472 nullableValue = NULL;
2481 return nullableValue ? *nullableValue : defaultValue;
2484 bool some()
const {
return nullableValue != NULL; }
2485 bool none()
const {
return nullableValue == NULL; }
2487 bool operator !()
const {
return nullableValue == NULL; }
2494 char storage[
sizeof(T)];
2514 #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED 2520 #pragma clang diagnostic push 2521 #pragma clang diagnostic ignored "-Wpadded" 2532 ShouldFail = 1 << 2,
2540 std::set<std::string>
const& _tags,
2545 bool isHidden()
const;
2546 bool throws()
const;
2547 bool okToFail()
const;
2548 bool expectedToFail()
const;
2568 void invoke()
const;
2574 bool operator < (
TestCase const& other )
const;
2589 #pragma clang diagnostic pop 2595 #define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED 2597 #import <objc/runtime.h> 2619 class OcMethod :
public SharedImpl<ITestCase> {
2622 OcMethod( Class cls,
SEL sel ) : m_cls( cls ), m_sel( sel ) {}
2624 virtual void invoke()
const {
2625 id obj = [[m_cls alloc] init];
2627 performOptionalSelector( obj,
@selector(setUp) );
2628 performOptionalSelector( obj, m_sel );
2629 performOptionalSelector( obj,
@selector(tearDown) );
2631 arcSafeRelease( obj );
2634 virtual ~OcMethod() {}
2645 NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
2646 SEL sel = NSSelectorFromString( selStr );
2647 arcSafeRelease( selStr );
2648 id value = performOptionalSelector( cls, sel );
2650 return [(NSString*)value UTF8String];
2655 inline size_t registerTestMethods() {
2656 size_t noTestMethods = 0;
2657 int noClasses = objc_getClassList( NULL, 0 );
2659 Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc(
sizeof(Class) * noClasses);
2660 objc_getClassList( classes, noClasses );
2662 for(
int c = 0;
c < noClasses;
c++ ) {
2663 Class cls = classes[c];
2666 Method* methods = class_copyMethodList( cls, &count );
2667 for( u_int
m = 0;
m <
count ;
m++ ) {
2668 SEL selector = method_getName(methods[
m]);
2670 if(
startsWith( methodName,
"Catch_TestCase_" ) ) {
2671 std::string testCaseName = methodName.substr( 15 );
2672 std::string name = Detail::getAnnotation( cls,
"Name", testCaseName );
2673 std::string desc = Detail::getAnnotation( cls,
"Description", testCaseName );
2674 const char* className = class_getName( cls );
2683 return noTestMethods;
2686 namespace Matchers {
2688 namespace NSStringMatchers {
2690 template<
typename MatcherT>
2691 struct StringHolder : MatcherImpl<MatcherT, NSString*>{
2692 StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
2693 StringHolder( StringHolder
const& other ) : m_substr( [other.m_substr copy] ){}
2695 arcSafeRelease( m_substr );
2702 Equals( NSString* substr ) : StringHolder( substr ){}
2704 virtual bool match( ExpressionType
const& str )
const {
2705 return (str != nil || m_substr == nil ) &&
2706 [str isEqualToString:m_substr];
2710 return "equals string: " +
Catch::toString( m_substr );
2715 Contains( NSString* substr ) : StringHolder( substr ){}
2717 virtual bool match( ExpressionType
const& str )
const {
2718 return (str != nil || m_substr == nil ) &&
2719 [str rangeOfString:m_substr].location != NSNotFound;
2723 return "contains string: " +
Catch::toString( m_substr );
2728 StartsWith( NSString* substr ) : StringHolder( substr ){}
2730 virtual bool match( ExpressionType
const& str )
const {
2731 return (str != nil || m_substr == nil ) &&
2732 [str rangeOfString:m_substr].location == 0;
2736 return "starts with: " +
Catch::toString( m_substr );
2740 EndsWith( NSString* substr ) : StringHolder( substr ){}
2742 virtual bool match( ExpressionType
const& str )
const {
2743 return (str != nil || m_substr == nil ) &&
2744 [str rangeOfString:m_substr].location == [str length] - [m_substr
length];
2748 return "ends with: " +
Catch::toString( m_substr );
2769 using namespace Matchers;
2774 #define OC_TEST_CASE( name, desc )\ 2775 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \ 2779 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \ 2783 -(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test ) 2789 #define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED 2795 #pragma clang diagnostic push 2796 #pragma clang diagnostic ignored "-Wweak-vtables" 2800 #define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED 2803 #define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED 2806 #define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED 2809 #define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED 2812 #pragma clang diagnostic push 2813 #pragma clang diagnostic ignored "-Wpadded" 2817 #define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED 2820 #pragma clang diagnostic push 2821 #pragma clang diagnostic ignored "-Wpadded" 2832 virtual bool matches(
TestCaseInfo const& testCase )
const = 0;
2834 class NamePattern :
public Pattern {
2835 enum WildcardPosition {
2837 WildcardAtStart = 1,
2839 WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
2845 m_name = m_name.substr( 1 );
2846 m_wildcard = WildcardAtStart;
2849 m_name = m_name.substr( 0, m_name.size()-1 );
2850 m_wildcard =
static_cast<WildcardPosition
>( m_wildcard | WildcardAtEnd );
2853 virtual ~NamePattern();
2854 virtual bool matches(
TestCaseInfo const& testCase )
const {
2855 switch( m_wildcard ) {
2858 case WildcardAtStart:
2862 case WildcardAtBothEnds:
2867 #pragma clang diagnostic push 2868 #pragma clang diagnostic ignored "-Wunreachable-code" 2870 throw std::logic_error(
"Unknown enum" );
2872 #pragma clang diagnostic pop 2877 WildcardPosition m_wildcard;
2879 class TagPattern :
public Pattern {
2882 virtual ~TagPattern();
2883 virtual bool matches(
TestCaseInfo const& testCase )
const {
2889 class ExcludedPattern :
public Pattern {
2891 ExcludedPattern(
Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
2892 virtual ~ExcludedPattern();
2893 virtual bool matches(
TestCaseInfo const& testCase )
const {
return !m_underlyingPattern->matches( testCase ); }
2899 std::vector<Ptr<Pattern> > m_patterns;
2903 for( std::vector<
Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it )
2904 if( !(*it)->matches( testCase ) )
2911 bool hasFilters()
const {
2912 return !m_filters.empty();
2916 for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )
2917 if( it->matches( testCase ) )
2923 std::vector<Filter> m_filters;
2925 friend class TestSpecParser;
2930 #pragma clang diagnostic pop 2935 class TestSpecParser {
2936 enum Mode{ None, Name, QuotedName, Tag };
2939 std::size_t m_start, m_pos;
2941 TestSpec::Filter m_currentFilter;
2942 TestSpec m_testSpec;
2946 TestSpecParser(
ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
2950 m_exclusion =
false;
2951 m_start = std::string::npos;
2953 for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
2954 visitChar( m_arg[m_pos] );
2955 if( m_mode == Name )
2956 addPattern<TestSpec::NamePattern>();
2959 TestSpec testSpec() {
2964 void visitChar(
char c ) {
2965 if( m_mode == None ) {
2968 case '~': m_exclusion =
true;
return;
2969 case '[':
return startNewMode( Tag, ++m_pos );
2970 case '"':
return startNewMode( QuotedName, ++m_pos );
2971 default: startNewMode( Name, m_pos );
break;
2974 if( m_mode == Name ) {
2976 addPattern<TestSpec::NamePattern>();
2979 else if( c ==
'[' ) {
2980 if( subString() ==
"exclude:" )
2983 addPattern<TestSpec::NamePattern>();
2984 startNewMode( Tag, ++m_pos );
2987 else if( m_mode == QuotedName && c ==
'"' )
2988 addPattern<TestSpec::NamePattern>();
2989 else if( m_mode == Tag && c ==
']' )
2990 addPattern<TestSpec::TagPattern>();
2992 void startNewMode( Mode
mode, std::size_t
start ) {
2996 std::string subString()
const {
return m_arg.substr( m_start, m_pos - m_start ); }
2997 template<
typename T>
3002 token = token.substr( 8 );
3004 if( !token.empty() ) {
3007 pattern =
new TestSpec::ExcludedPattern( pattern );
3008 m_currentFilter.m_patterns.push_back( pattern );
3010 m_exclusion =
false;
3014 if( !m_currentFilter.m_patterns.empty() ) {
3015 m_testSpec.m_filters.push_back( m_currentFilter );
3016 m_currentFilter = TestSpec::Filter();
3020 inline TestSpec parseTestSpec(
std::string const& arg ) {
3027 #pragma clang diagnostic pop 3031 #define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED 3039 struct Verbosity {
enum Level {
3045 struct WarnAbout {
enum What {
3050 struct ShowDurations {
enum OrNot {
3055 struct RunTests {
enum InWhatOrder {
3057 InLexicographicalOrder,
3067 virtual bool allowThrows()
const = 0;
3068 virtual std::ostream&
stream()
const = 0;
3070 virtual bool includeSuccessfulResults()
const = 0;
3071 virtual bool shouldDebugBreak()
const = 0;
3072 virtual bool warnAboutMissingAssertions()
const = 0;
3073 virtual int abortAfter()
const = 0;
3074 virtual bool showInvisibles()
const = 0;
3075 virtual ShowDurations::OrNot showDurations()
const = 0;
3076 virtual TestSpec
const& testSpec()
const = 0;
3077 virtual RunTests::InWhatOrder runOrder()
const = 0;
3078 virtual unsigned int rngSeed()
const = 0;
3079 virtual bool forceColour()
const = 0;
3084 #define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED 3086 #include <streambuf> 3089 #pragma clang diagnostic ignored "-Wpadded" 3097 Stream( std::streambuf* _streamBuf,
bool _isOwned );
3100 std::streambuf* streamBuf;
3106 std::ostream& cout();
3107 std::ostream& cerr();
3116 #ifndef CATCH_CONFIG_CONSOLE_WIDTH 3117 #define CATCH_CONFIG_CONSOLE_WIDTH 80 3125 : listTests( false ),
3127 listReporters( false ),
3128 listTestNamesOnly( false ),
3129 showSuccessfulTests( false ),
3130 shouldDebugBreak( false ),
3133 showInvisibles( false ),
3134 forceColour( false ),
3137 verbosity( Verbosity::Normal ),
3138 warnings( WarnAbout::Nothing ),
3139 showDurations( ShowDurations::DefaultForReporter ),
3140 runOrder( RunTests::InDeclarationOrder )
3146 bool listTestNamesOnly;
3148 bool showSuccessfulTests;
3149 bool shouldDebugBreak;
3152 bool showInvisibles;
3156 unsigned int rngSeed;
3158 Verbosity::Level verbosity;
3159 WarnAbout::What warnings;
3160 ShowDurations::OrNot showDurations;
3161 RunTests::InWhatOrder runOrder;
3168 std::vector<std::string> testsOrTags;
3173 Config( Config
const& other );
3175 virtual void dummy();
3179 : m_os(
Catch::cout().rdbuf() )
3182 Config( ConfigData
const&
data )
3184 m_os(
Catch::cout().rdbuf() )
3186 if( !data.testsOrTags.empty() ) {
3188 for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
3189 parser.parse( data.testsOrTags[i] );
3190 m_testSpec = parser.testSpec();
3195 m_os.rdbuf( Catch::cout().rdbuf() );
3200 m_data.outputFilename = filename;
3204 return m_data.outputFilename ;
3207 bool listTests()
const {
return m_data.listTests; }
3208 bool listTestNamesOnly()
const {
return m_data.listTestNamesOnly; }
3209 bool listTags()
const {
return m_data.listTags; }
3210 bool listReporters()
const {
return m_data.listReporters; }
3212 std::string getProcessName()
const {
return m_data.processName; }
3214 bool shouldDebugBreak()
const {
return m_data.shouldDebugBreak; }
3216 void setStreamBuf( std::streambuf*
buf ) {
3217 m_os.rdbuf( buf ? buf : Catch::cout().rdbuf() );
3222 setStreamBuf( stream.streamBuf );
3227 std::string getReporterName()
const {
return m_data.reporterName; }
3229 int abortAfter()
const {
return m_data.abortAfter; }
3231 TestSpec
const& testSpec()
const {
return m_testSpec; }
3233 bool showHelp()
const {
return m_data.showHelp; }
3234 bool showInvisibles()
const {
return m_data.showInvisibles; }
3237 virtual bool allowThrows()
const {
return !m_data.noThrow; }
3238 virtual std::ostream&
stream()
const {
return m_os; }
3239 virtual std::string name()
const {
return m_data.name.empty() ? m_data.processName : m_data.name; }
3240 virtual bool includeSuccessfulResults()
const {
return m_data.showSuccessfulTests; }
3241 virtual bool warnAboutMissingAssertions()
const {
return m_data.warnings & WarnAbout::NoAssertions; }
3242 virtual ShowDurations::OrNot showDurations()
const {
return m_data.showDurations; }
3243 virtual RunTests::InWhatOrder runOrder()
const {
return m_data.runOrder; }
3244 virtual unsigned int rngSeed()
const {
return m_data.rngSeed; }
3245 virtual bool forceColour()
const {
return m_data.forceColour; }
3251 mutable std::ostream m_os;
3252 TestSpec m_testSpec;
3258 #define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED 3261 #ifdef CLARA_CONFIG_CONSOLE_WIDTH 3262 #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH 3263 #undef CLARA_CONFIG_CONSOLE_WIDTH 3265 #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH 3268 #define STITCH_CLARA_OPEN_NAMESPACE namespace Catch { 3272 #if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE) 3274 #ifndef STITCH_CLARA_OPEN_NAMESPACE 3275 #define TWOBLUECUBES_CLARA_H_INCLUDED 3276 #define STITCH_CLARA_OPEN_NAMESPACE 3277 #define STITCH_CLARA_CLOSE_NAMESPACE 3279 #define STITCH_CLARA_CLOSE_NAMESPACE } 3282 #define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE 3287 #if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE) 3288 #ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE 3289 #define TBC_TEXT_FORMAT_H_INCLUDED 3297 #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE 3298 namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
3303 #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH 3304 const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
3306 const unsigned int consoleWidth = 80;
3309 struct TextAttributes {
3313 width( consoleWidth-1 ),
3317 TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value;
return *
this; }
3318 TextAttributes& setIndent( std::size_t _value ) { indent = _value;
return *
this; }
3319 TextAttributes& setWidth( std::size_t _value ) {
width = _value;
return *
this; }
3320 TextAttributes& setTabChar(
char _value ) { tabChar = _value;
return *
this; }
3322 std::size_t initialIndent;
3330 Text(
std::string const& _str, TextAttributes
const& _attr = TextAttributes() )
3334 std::size_t indent = _attr.initialIndent != std::string::npos
3335 ? _attr.initialIndent
3339 while( !remainder.empty() ) {
3340 if( lines.size() >= 1000 ) {
3341 lines.push_back(
"... message truncated due to excessive size" );
3344 std::size_t tabPos = std::string::npos;
3345 std::size_t
width = (std::min)( remainder.size(), _attr.width - indent );
3346 std::size_t pos = remainder.find_first_of(
'\n' );
3347 if( pos <= width ) {
3350 pos = remainder.find_last_of( _attr.tabChar, width );
3351 if( pos != std::string::npos ) {
3353 if( remainder[width] ==
'\n' )
3355 remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
3358 if( width == remainder.size() ) {
3359 spliceLine( indent, remainder, width );
3361 else if( remainder[width] ==
'\n' ) {
3362 spliceLine( indent, remainder, width );
3363 if( width <= 1 || remainder.size() != 1 )
3364 remainder = remainder.substr( 1 );
3365 indent = _attr.indent;
3368 pos = remainder.find_last_of( wrappableChars, width );
3369 if( pos != std::string::npos && pos > 0 ) {
3370 spliceLine( indent, remainder, pos );
3371 if( remainder[0] ==
' ' )
3372 remainder = remainder.substr( 1 );
3375 spliceLine( indent, remainder, width-1 );
3376 lines.back() += "-";
3378 if( lines.size() == 1 )
3379 indent = _attr.indent;
3380 if( tabPos != std::string::npos )
3386 void spliceLine( std::size_t _indent,
std::string& _remainder, std::size_t _pos ) {
3387 lines.push_back(
std::string( _indent,
' ' ) + _remainder.substr( 0, _pos ) );
3388 _remainder = _remainder.substr( _pos );
3391 typedef std::vector<std::string>::const_iterator const_iterator;
3393 const_iterator begin()
const {
return lines.begin(); }
3394 const_iterator
end()
const {
return lines.end(); }
3395 std::string const& last()
const {
return lines.back(); }
3396 std::size_t
size()
const {
return lines.size(); }
3397 std::string const& operator[]( std::size_t _index )
const {
return lines[_index]; }
3399 std::ostringstream oss;
3404 inline friend std::ostream&
operator << ( std::ostream& _stream, Text
const& _text ) {
3405 for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
3406 it != itEnd; ++it ) {
3407 if( it != _text.begin() )
3416 TextAttributes attr;
3417 std::vector<std::string> lines;
3422 #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE 3426 #endif // TBC_TEXT_FORMAT_H_INCLUDED 3431 #undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE 3434 #include <algorithm> 3435 #include <stdexcept> 3439 #ifdef STITCH_CLARA_OPEN_NAMESPACE 3440 STITCH_CLARA_OPEN_NAMESPACE
3445 struct UnpositionalTag {};
3447 extern UnpositionalTag _;
3449 #ifdef CLARA_CONFIG_MAIN 3455 #ifdef CLARA_CONSOLE_WIDTH 3456 const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
3458 const unsigned int consoleWidth = 80;
3461 using namespace Tbc;
3464 return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
3467 template<
typename T>
struct RemoveConstRef{
typedef T
type; };
3468 template<
typename T>
struct RemoveConstRef<T&>{
typedef T
type; };
3469 template<
typename T>
struct RemoveConstRef<T const&>{
typedef T
type; };
3470 template<
typename T>
struct RemoveConstRef<T const>{
typedef T
type; };
3472 template<
typename T>
struct IsBool {
static const bool value =
false; };
3473 template<>
struct IsBool<bool> {
static const bool value =
true; };
3475 template<
typename T>
3476 void convertInto(
std::string const& _source, T& _dest ) {
3477 std::stringstream ss;
3481 throw std::runtime_error(
"Unable to convert " + _source +
" to destination type" );
3486 inline void convertInto(
std::string const& _source,
bool& _dest ) {
3488 std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower );
3489 if( sourceLC ==
"y" || sourceLC ==
"1" || sourceLC ==
"true" || sourceLC ==
"yes" || sourceLC ==
"on" )
3491 else if( sourceLC ==
"n" || sourceLC ==
"0" || sourceLC ==
"false" || sourceLC ==
"no" || sourceLC ==
"off" )
3494 throw std::runtime_error(
"Expected a boolean value but did not recognise:\n '" + _source +
"'" );
3496 inline void convertInto(
bool _source,
bool& _dest ) {
3499 template<
typename T>
3500 inline void convertInto(
bool, T& ) {
3501 throw std::runtime_error(
"Invalid conversion" );
3504 template<
typename ConfigT>
3505 struct IArgFunction {
3506 virtual ~IArgFunction() {}
3507 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS 3508 IArgFunction() =
default;
3509 IArgFunction( IArgFunction
const& ) =
default;
3512 virtual void setFlag( ConfigT& config )
const = 0;
3513 virtual bool takesArg()
const = 0;
3514 virtual IArgFunction* clone()
const = 0;
3517 template<
typename ConfigT>
3518 class BoundArgFunction {
3520 BoundArgFunction() : functionObj( NULL ) {}
3521 BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
3522 BoundArgFunction( BoundArgFunction
const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : NULL ) {}
3523 BoundArgFunction&
operator = ( BoundArgFunction
const& other ) {
3524 IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : NULL;
3526 functionObj = newFunctionObj;
3529 ~BoundArgFunction() {
delete functionObj; }
3532 functionObj->set( config,
value );
3534 void setFlag( ConfigT& config )
const {
3535 functionObj->setFlag( config );
3537 bool takesArg()
const {
return functionObj->takesArg(); }
3539 bool isSet()
const {
3540 return functionObj != NULL;
3543 IArgFunction<ConfigT>* functionObj;
3546 template<
typename C>
3547 struct NullBinder : IArgFunction<C>{
3548 virtual void set( C&,
std::string const& )
const {}
3549 virtual void setFlag( C& )
const {}
3550 virtual bool takesArg()
const {
return true; }
3551 virtual IArgFunction<C>* clone()
const {
return new NullBinder( *
this ); }
3554 template<
typename C,
typename M>
3555 struct BoundDataMember : IArgFunction<C>{
3556 BoundDataMember( M C::* _member ) : member( _member ) {}
3557 virtual void set( C&
p,
std::string const& stringValue )
const {
3558 convertInto( stringValue, p.*member );
3560 virtual void setFlag( C& p )
const {
3561 convertInto(
true, p.*member );
3564 virtual IArgFunction<C>* clone()
const {
return new BoundDataMember( *
this ); }
3567 template<
typename C,
typename M>
3568 struct BoundUnaryMethod : IArgFunction<C>{
3569 BoundUnaryMethod(
void (C::*_member)( M ) ) : member( _member ) {}
3570 virtual void set( C&
p,
std::string const& stringValue )
const {
3572 convertInto( stringValue, value );
3573 (p.*member)( value );
3575 virtual void setFlag( C& p )
const {
3577 convertInto(
true, value );
3578 (p.*member)( value );
3581 virtual IArgFunction<C>* clone()
const {
return new BoundUnaryMethod( *
this ); }
3582 void (C::*member)( M );
3584 template<
typename C>
3585 struct BoundNullaryMethod : IArgFunction<C>{
3586 BoundNullaryMethod(
void (C::*_member)() ) : member( _member ) {}
3587 virtual void set( C&
p,
std::string const& stringValue )
const {
3589 convertInto( stringValue, value );
3593 virtual void setFlag( C& p )
const {
3596 virtual bool takesArg()
const {
return false; }
3597 virtual IArgFunction<C>* clone()
const {
return new BoundNullaryMethod( *
this ); }
3598 void (C::*member)();
3601 template<
typename C>
3602 struct BoundUnaryFunction : IArgFunction<C>{
3603 BoundUnaryFunction(
void (*_function)( C& ) ) : function( _function ) {}
3604 virtual void set( C&
obj,
std::string const& stringValue )
const {
3606 convertInto( stringValue, value );
3610 virtual void setFlag( C& p )
const {
3613 virtual bool takesArg()
const {
return false; }
3614 virtual IArgFunction<C>* clone()
const {
return new BoundUnaryFunction( *
this ); }
3615 void (*
function)( C& );
3618 template<
typename C,
typename T>
3619 struct BoundBinaryFunction : IArgFunction<C>{
3620 BoundBinaryFunction(
void (*_function)( C&, T ) ) : function( _function ) {}
3621 virtual void set( C&
obj,
std::string const& stringValue )
const {
3623 convertInto( stringValue, value );
3626 virtual void setFlag( C& obj )
const {
3628 convertInto(
true, value );
3632 virtual IArgFunction<C>* clone()
const {
return new BoundBinaryFunction( *
this ); }
3633 void (*
function)( C&, T );
3639 Parser() : separators(
" \t=:" ) {}
3642 enum Type { Positional, ShortOpt, LongOpt };
3643 Token( Type _type,
std::string const& _data ) :
type( _type ), data( _data ) {}
3648 void parseIntoTokens(
int argc,
char const *
const * argv, std::vector<Parser::Token>& tokens )
const {
3650 for(
int i = 1; i < argc && argv[i] != doubleDash; ++i )
3651 parseIntoTokens( argv[i] , tokens);
3653 void parseIntoTokens(
std::string arg, std::vector<Parser::Token>& tokens )
const {
3654 while( !arg.empty() ) {
3655 Parser::Token token( Parser::Token::Positional, arg );
3657 if( token.data[0] ==
'-' ) {
3658 if( token.data.size() > 1 && token.data[1] ==
'-' ) {
3659 token = Parser::Token( Parser::Token::LongOpt, token.data.substr( 2 ) );
3662 token = Parser::Token( Parser::Token::ShortOpt, token.data.substr( 1 ) );
3663 if( token.data.size() > 1 && separators.find( token.data[1] ) == std::string::npos ) {
3664 arg =
"-" + token.data.substr( 1 );
3665 token.data = token.data.substr( 0, 1 );
3669 if( token.type != Parser::Token::Positional ) {
3670 std::size_t pos = token.data.find_first_of( separators );
3671 if( pos != std::string::npos ) {
3672 arg = token.data.substr( pos+1 );
3673 token.data = token.data.substr( 0, pos );
3676 tokens.push_back( token );
3682 template<
typename ConfigT>
3683 struct CommonArgProperties {
3684 CommonArgProperties() {}
3685 CommonArgProperties( Detail::BoundArgFunction<ConfigT>
const& _boundField ) : boundField( _boundField ) {}
3687 Detail::BoundArgFunction<ConfigT> boundField;
3692 bool takesArg()
const {
3693 return !placeholder.empty();
3695 void validate()
const {
3696 if( !boundField.isSet() )
3697 throw std::logic_error(
"option not bound" );
3700 struct OptionArgProperties {
3701 std::vector<std::string> shortNames;
3704 bool hasShortName(
std::string const& shortName )
const {
3705 return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end();
3707 bool hasLongName(
std::string const& _longName )
const {
3708 return _longName == longName;
3711 struct PositionalArgProperties {
3712 PositionalArgProperties() : position( -1 ) {}
3715 bool isFixedPositional()
const {
3716 return position != -1;
3720 template<
typename ConfigT>
3723 struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties {
3725 Arg( Detail::BoundArgFunction<ConfigT>
const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {}
3727 using CommonArgProperties<ConfigT>::placeholder;
3730 if( !longName.empty() )
3731 return "--" + longName;
3732 if( !shortNames.empty() )
3733 return "-" + shortNames[0];
3734 return "positional args";
3737 std::ostringstream oss;
3739 std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
3740 for(; it != itEnd; ++it ) {
3747 if( !longName.empty() ) {
3750 oss <<
"--" << longName;
3752 if( !placeholder.empty() )
3753 oss <<
" <" << placeholder <<
">";
3759 #if defined(__cplusplus) && __cplusplus > 199711L 3760 typedef std::unique_ptr<Arg> ArgAutoPtr;
3762 typedef std::auto_ptr<Arg> ArgAutoPtr;
3765 friend void addOptName( Arg& arg,
std::string const& optName )
3767 if( optName.empty() )
3770 if( !arg.longName.empty() )
3771 throw std::logic_error(
"Only one long opt may be specified. '" 3773 +
"' already specified, now attempting to add '" 3775 arg.longName = optName.substr( 2 );
3778 arg.shortNames.push_back( optName.substr( 1 ) );
3780 throw std::logic_error(
"option must begin with - or --. Option was: '" + optName +
"'" );
3782 friend void setPositionalArg( Arg& arg,
int position )
3784 arg.position = position;
3789 ArgBuilder( Arg* arg ) : m_arg( arg ) {}
3792 template<
typename C,
typename M>
3793 void bind( M C::* field,
std::string const& placeholder ) {
3794 m_arg->boundField =
new Detail::BoundDataMember<C,M>( field );
3795 m_arg->placeholder = placeholder;
3798 template<
typename C>
3799 void bind(
bool C::* field ) {
3800 m_arg->boundField =
new Detail::BoundDataMember<C,bool>( field );
3804 template<
typename C,
typename M>
3805 void bind(
void (C::* unaryMethod)( M ),
std::string const& placeholder ) {
3806 m_arg->boundField =
new Detail::BoundUnaryMethod<C,M>( unaryMethod );
3807 m_arg->placeholder = placeholder;
3811 template<
typename C>
3812 void bind(
void (C::* unaryMethod)(
bool ) ) {
3813 m_arg->boundField =
new Detail::BoundUnaryMethod<C,bool>( unaryMethod );
3817 template<
typename C>
3818 void bind(
void (C::* nullaryMethod)() ) {
3819 m_arg->boundField =
new Detail::BoundNullaryMethod<C>( nullaryMethod );
3823 template<
typename C>
3824 void bind(
void (* unaryFunction)( C& ) ) {
3825 m_arg->boundField =
new Detail::BoundUnaryFunction<C>( unaryFunction );
3829 template<
typename C,
typename T>
3830 void bind(
void (* binaryFunction)( C&, T ),
std::string const& placeholder ) {
3831 m_arg->boundField =
new Detail::BoundBinaryFunction<C, T>( binaryFunction );
3832 m_arg->placeholder = placeholder;
3835 ArgBuilder& describe(
std::string const& description ) {
3836 m_arg->description = description;
3840 m_arg->detail = detail;
3848 class OptBuilder :
public ArgBuilder {
3850 OptBuilder( Arg* arg ) : ArgBuilder( arg ) {}
3851 OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}
3853 OptBuilder& operator[](
std::string const& optName ) {
3854 addOptName( *ArgBuilder::m_arg, optName );
3862 : m_boundProcessName( new Detail::NullBinder<ConfigT>() ),
3863 m_highestSpecifiedArgPosition( 0 ),
3864 m_throwOnUnrecognisedTokens( false )
3866 CommandLine( CommandLine
const& other )
3867 : m_boundProcessName( other.m_boundProcessName ),
3868 m_options ( other.m_options ),
3869 m_positionalArgs( other.m_positionalArgs ),
3870 m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),
3871 m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )
3873 if( other.m_floatingArg.get() )
3874 m_floatingArg.reset(
new Arg( *other.m_floatingArg ) );
3877 CommandLine& setThrowOnUnrecognisedTokens(
bool shouldThrow =
true ) {
3878 m_throwOnUnrecognisedTokens = shouldThrow;
3882 OptBuilder operator[](
std::string const& optName ) {
3883 m_options.push_back( Arg() );
3884 addOptName( m_options.back(), optName );
3885 OptBuilder builder( &m_options.back() );
3889 ArgBuilder operator[](
int position ) {
3890 m_positionalArgs.insert( std::make_pair( position, Arg() ) );
3891 if( position > m_highestSpecifiedArgPosition )
3892 m_highestSpecifiedArgPosition = position;
3893 setPositionalArg( m_positionalArgs[position], position );
3894 ArgBuilder builder( &m_positionalArgs[position] );
3899 ArgBuilder operator[]( UnpositionalTag ) {
3900 if( m_floatingArg.get() )
3901 throw std::logic_error(
"Only one unpositional argument can be added" );
3902 m_floatingArg.reset(
new Arg() );
3903 ArgBuilder builder( m_floatingArg.get() );
3907 template<
typename C,
typename M>
3908 void bindProcessName( M C::* field ) {
3909 m_boundProcessName =
new Detail::BoundDataMember<C,M>( field );
3911 template<
typename C,
typename M>
3912 void bindProcessName(
void (C::*_unaryMethod)( M ) ) {
3913 m_boundProcessName =
new Detail::BoundUnaryMethod<C,M>( _unaryMethod );
3916 void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth )
const {
3917 typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
3918 std::size_t maxWidth = 0;
3919 for( it = itBegin; it != itEnd; ++it )
3920 maxWidth = (
std::max)( maxWidth, it->
commands().size() );
3922 for( it = itBegin; it != itEnd; ++it ) {
3923 Detail::Text
usage( it->commands(), Detail::TextAttributes()
3924 .setWidth( maxWidth+indent )
3925 .setIndent( indent ) );
3926 Detail::Text desc( it->description, Detail::TextAttributes()
3927 .setWidth( width - maxWidth - 3 ) );
3929 for( std::size_t i = 0; i < (std::max)(
usage.size(), desc.size() ); ++i ) {
3933 if( i < desc.size() && !desc[i].empty() )
3934 os <<
std::string( indent + 2 + maxWidth - usageCol.size(),
' ' )
3941 std::ostringstream oss;
3946 void argSynopsis( std::ostream& os )
const {
3947 for(
int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
3950 typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
3951 if( it != m_positionalArgs.end() )
3952 os <<
"<" << it->second.placeholder <<
">";
3953 else if( m_floatingArg.get() )
3954 os <<
"<" << m_floatingArg->placeholder <<
">";
3956 throw std::logic_error(
"non consecutive positional arguments with no floating args" );
3959 if( m_floatingArg.get() ) {
3960 if( m_highestSpecifiedArgPosition > 1 )
3962 os <<
"[<" << m_floatingArg->placeholder <<
"> ...]";
3966 std::ostringstream oss;
3973 os <<
"usage:\n " << procName <<
" ";
3975 if( !m_options.empty() ) {
3976 os <<
" [options]\n\nwhere options are: \n";
3982 std::ostringstream oss;
3983 usage( oss, procName );
3987 ConfigT parse(
int argc,
char const *
const * argv )
const {
3989 parseInto( argc, argv, config );
3993 std::vector<Parser::Token> parseInto(
int argc,
char const *
const * argv, ConfigT& config )
const {
3995 std::size_t lastSlash = processName.find_last_of(
"/\\" );
3996 if( lastSlash != std::string::npos )
3997 processName = processName.substr( lastSlash+1 );
3998 m_boundProcessName.set( config, processName );
3999 std::vector<Parser::Token> tokens;
4001 parser.parseIntoTokens( argc, argv, tokens );
4002 return populate( tokens, config );
4005 std::vector<Parser::Token> populate( std::vector<Parser::Token>
const& tokens, ConfigT& config )
const {
4007 std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );
4008 unusedTokens = populateFixedArgs( unusedTokens, config );
4009 unusedTokens = populateFloatingArgs( unusedTokens, config );
4010 return unusedTokens;
4013 std::vector<Parser::Token> populateOptions( std::vector<Parser::Token>
const& tokens, ConfigT& config )
const {
4014 std::vector<Parser::Token> unusedTokens;
4015 std::vector<std::string> errors;
4016 for( std::size_t i = 0; i < tokens.size(); ++i ) {
4017 Parser::Token
const& token = tokens[i];
4018 typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
4019 for(; it != itEnd; ++it ) {
4020 Arg
const& arg = *it;
4023 if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
4024 ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
4025 if( arg.takesArg() ) {
4026 if( i == tokens.size()-1 || tokens[i+1].
type != Parser::Token::Positional )
4027 errors.push_back( "Expected argument to
option: " + token.data );
4029 arg.boundField.set( config, tokens[++i].data );
4032 arg.boundField.setFlag( config );
4037 catch( std::exception& ex ) {
4038 errors.push_back(
std::string( ex.what() ) +
"\n- while parsing: (" + arg.commands() + ")" );
4042 if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )
4043 unusedTokens.push_back( token );
4044 else if( errors.empty() && m_throwOnUnrecognisedTokens )
4045 errors.push_back(
"unrecognised option: " + token.data );
4048 if( !errors.empty() ) {
4049 std::ostringstream oss;
4050 for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();
4053 if( it != errors.begin() )
4057 throw std::runtime_error( oss.str() );
4059 return unusedTokens;
4061 std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token>
const& tokens, ConfigT& config )
const {
4062 std::vector<Parser::Token> unusedTokens;
4064 for( std::size_t i = 0; i < tokens.size(); ++i ) {
4065 Parser::Token
const& token = tokens[i];
4066 typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
4067 if( it != m_positionalArgs.end() )
4068 it->second.boundField.set( config, token.data );
4070 unusedTokens.push_back( token );
4071 if( token.type == Parser::Token::Positional )
4074 return unusedTokens;
4076 std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token>
const& tokens, ConfigT& config )
const {
4077 if( !m_floatingArg.get() )
4079 std::vector<Parser::Token> unusedTokens;
4080 for( std::size_t i = 0; i < tokens.size(); ++i ) {
4081 Parser::Token
const& token = tokens[i];
4082 if( token.type == Parser::Token::Positional )
4083 m_floatingArg->boundField.set( config, token.data );
4085 unusedTokens.push_back( token );
4087 return unusedTokens;
4090 void validate()
const 4092 if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() )
4093 throw std::logic_error(
"No options or arguments specified" );
4095 for(
typename std::vector<Arg>::const_iterator it = m_options.begin(),
4096 itEnd = m_options.end();
4102 Detail::BoundArgFunction<ConfigT> m_boundProcessName;
4103 std::vector<Arg> m_options;
4104 std::map<int, Arg> m_positionalArgs;
4105 ArgAutoPtr m_floatingArg;
4106 int m_highestSpecifiedArgPosition;
4107 bool m_throwOnUnrecognisedTokens;
4112 STITCH_CLARA_CLOSE_NAMESPACE
4113 #undef STITCH_CLARA_OPEN_NAMESPACE 4114 #undef STITCH_CLARA_CLOSE_NAMESPACE 4116 #endif // TWOBLUECUBES_CLARA_H_INCLUDED 4117 #undef STITCH_CLARA_OPEN_NAMESPACE 4120 #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH 4121 #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH 4122 #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH 4129 inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
4130 inline void abortAfterX( ConfigData& config,
int x ) {
4132 throw std::runtime_error(
"Value after -x or --abortAfter must be greater than zero" );
4133 config.abortAfter =
x;
4135 inline void addTestOrTags( ConfigData& config,
std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
4137 inline void addWarning( ConfigData& config,
std::string const& _warning ) {
4138 if( _warning ==
"NoAssertions" )
4139 config.warnings =
static_cast<WarnAbout::What
>( config.warnings | WarnAbout::NoAssertions );
4141 throw std::runtime_error(
"Unrecognised warning: '" + _warning +
"'" );
4145 config.runOrder = RunTests::InDeclarationOrder;
4147 config.runOrder = RunTests::InLexicographicalOrder;
4149 config.runOrder = RunTests::InRandomOrder;
4151 throw std::runtime_error(
"Unrecognised ordering: '" + order +
"'" );
4153 inline void setRngSeed( ConfigData& config,
std::string const& seed ) {
4154 if( seed ==
"time" ) {
4155 config.rngSeed =
static_cast<unsigned int>( std::time(0) );
4158 std::stringstream ss;
4160 ss >> config.rngSeed;
4162 throw std::runtime_error(
"Argment to --rng-seed should be the word 'time' or a number" );
4165 inline void setVerbosity( ConfigData& config,
int level ) {
4167 config.verbosity =
static_cast<Verbosity::Level
>(
level );
4169 inline void setShowDurations( ConfigData& config,
bool _showDurations ) {
4170 config.showDurations = _showDurations
4171 ? ShowDurations::Always
4172 : ShowDurations::Never;
4174 inline void loadTestNamesFromFile( ConfigData& config,
std::string const& _filename ) {
4175 std::ifstream
f( _filename.c_str() );
4177 throw std::domain_error(
"Unable to load input file: " + _filename );
4180 while( std::getline(
f, line ) ) {
4182 if( !line.empty() && !
startsWith( line,
"#" ) )
4183 addTestOrTags( config,
"\"" + line +
"\"," );
4187 inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
4189 using namespace Clara;
4190 CommandLine<ConfigData> cli;
4192 cli.bindProcessName( &ConfigData::processName );
4194 cli["-?"]["-h"]["--help"]
4195 .describe(
"display usage information" )
4196 .bind( &ConfigData::showHelp );
4198 cli["-l"]["--list-tests"]
4199 .describe(
"list all/matching test cases" )
4200 .bind( &ConfigData::listTests );
4202 cli["-t"]["--list-tags"]
4203 .describe(
"list all/matching tags" )
4204 .bind( &ConfigData::listTags );
4206 cli["-s"]["--success"]
4207 .describe(
"include successful tests in output" )
4208 .bind( &ConfigData::showSuccessfulTests );
4210 cli["-b"]["--break"]
4211 .describe(
"break into debugger on failure" )
4212 .bind( &ConfigData::shouldDebugBreak );
4214 cli["-e"]["--nothrow"]
4215 .describe(
"skip exception tests" )
4216 .bind( &ConfigData::noThrow );
4218 cli["-i"]["--invisibles"]
4219 .describe(
"show invisibles (tabs, newlines)" )
4220 .bind( &ConfigData::showInvisibles );
4223 .describe(
"output filename" )
4224 .bind( &ConfigData::outputFilename,
"filename" );
4226 cli["-r"]["--reporter"]
4228 .describe(
"reporter to use (defaults to console)" )
4229 .bind( &ConfigData::reporterName,
"name" );
4232 .describe(
"suite name" )
4235 cli["-a"]["--abort"]
4236 .describe(
"abort at first failure" )
4237 .bind( &abortAfterFirst );
4239 cli["-x"]["--abortx"]
4240 .describe(
"abort after x failures" )
4241 .bind( &abortAfterX,
"no. failures" );
4244 .describe(
"enable warnings" )
4245 .bind( &addWarning,
"warning name" );
4255 .describe(
"which test or tests to use" )
4256 .bind( &addTestOrTags,
"test name, pattern or tags" );
4258 cli["-d"]["--durations"]
4259 .describe(
"show test durations" )
4260 .bind( &setShowDurations,
"yes/no" );
4262 cli["-f"]["--input-file"]
4263 .describe(
"load test names to run from a file" )
4264 .bind( &loadTestNamesFromFile,
"filename" );
4267 cli["--list-test-names-only"]
4268 .describe(
"list all/matching test cases names only" )
4269 .bind( &ConfigData::listTestNamesOnly );
4271 cli["--list-reporters"]
4272 .describe(
"list all reporters" )
4273 .bind( &ConfigData::listReporters );
4276 .describe(
"test case order (defaults to decl)" )
4277 .bind( &setOrder,
"decl|lex|rand" );
4280 .describe(
"set a specific seed for random numbers" )
4281 .bind( &setRngSeed,
"'time'|number" );
4283 cli["--force-colour"]
4284 .describe(
"force colourised output" )
4285 .bind( &ConfigData::forceColour );
4293 #define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED 4296 #define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED 4298 #define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH 4300 #define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch 4303 #ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE 4304 # ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED 4305 # ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED 4306 # define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED 4309 # define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED 4312 #ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED 4318 #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE 4319 namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
4324 #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH 4325 const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
4327 const unsigned int consoleWidth = 80;
4330 struct TextAttributes {
4334 width( consoleWidth-1 ),
4338 TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value;
return *
this; }
4339 TextAttributes& setIndent( std::size_t _value ) { indent = _value;
return *
this; }
4340 TextAttributes& setWidth( std::size_t _value ) { width = _value;
return *
this; }
4341 TextAttributes& setTabChar(
char _value ) { tabChar = _value;
return *
this; }
4343 std::size_t initialIndent;
4351 Text(
std::string const& _str, TextAttributes
const& _attr = TextAttributes() )
4355 std::size_t indent = _attr.initialIndent != std::string::npos
4356 ? _attr.initialIndent
4360 while( !remainder.empty() ) {
4361 if( lines.size() >= 1000 ) {
4362 lines.push_back(
"... message truncated due to excessive size" );
4365 std::size_t tabPos = std::string::npos;
4366 std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
4367 std::size_t pos = remainder.find_first_of(
'\n' );
4368 if( pos <= width ) {
4371 pos = remainder.find_last_of( _attr.tabChar, width );
4372 if( pos != std::string::npos ) {
4374 if( remainder[width] ==
'\n' )
4376 remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
4379 if( width == remainder.size() ) {
4380 spliceLine( indent, remainder, width );
4382 else if( remainder[width] ==
'\n' ) {
4383 spliceLine( indent, remainder, width );
4384 if( width <= 1 || remainder.size() != 1 )
4385 remainder = remainder.substr( 1 );
4386 indent = _attr.indent;
4389 pos = remainder.find_last_of( wrappableChars, width );
4390 if( pos != std::string::npos && pos > 0 ) {
4391 spliceLine( indent, remainder, pos );
4392 if( remainder[0] ==
' ' )
4393 remainder = remainder.substr( 1 );
4396 spliceLine( indent, remainder, width-1 );
4397 lines.back() += "-";
4399 if( lines.size() == 1 )
4400 indent = _attr.indent;
4401 if( tabPos != std::string::npos )
4407 void spliceLine( std::size_t _indent,
std::string& _remainder, std::size_t _pos ) {
4408 lines.push_back(
std::string( _indent,
' ' ) + _remainder.substr( 0, _pos ) );
4409 _remainder = _remainder.substr( _pos );
4412 typedef std::vector<std::string>::const_iterator const_iterator;
4414 const_iterator begin()
const {
return lines.begin(); }
4415 const_iterator
end()
const {
return lines.end(); }
4416 std::string const& last()
const {
return lines.back(); }
4417 std::size_t
size()
const {
return lines.size(); }
4418 std::string const& operator[]( std::size_t _index )
const {
return lines[_index]; }
4420 std::ostringstream oss;
4425 inline friend std::ostream&
operator << ( std::ostream& _stream, Text
const& _text ) {
4426 for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
4427 it != itEnd; ++it ) {
4428 if( it != _text.begin() )
4437 TextAttributes attr;
4438 std::vector<std::string> lines;
4443 #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE 4447 #endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED 4448 #undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE 4452 using Tbc::TextAttributes;
4456 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED 4474 BrightRed = Bright | Red,
4475 BrightGreen = Bright | Green,
4476 LightGrey = Bright | Grey,
4477 BrightWhite = Bright | White,
4480 FileName = LightGrey,
4482 ResultError = BrightRed,
4483 ResultSuccess = BrightGreen,
4484 ResultExpectedFailure = Warning,
4489 OriginalExpression = Cyan,
4490 ReconstructedExpression = Yellow,
4492 SecondaryText = LightGrey,
4497 Colour( Code _colourCode );
4498 Colour( Colour
const& other );
4502 static void use( Code _colourCode );
4508 inline std::ostream&
operator << ( std::ostream& os, Colour
const& ) {
return os; }
4513 #define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED 4522 struct ReporterConfig {
4523 explicit ReporterConfig(
Ptr<IConfig> const& _fullConfig )
4524 : m_stream( &_fullConfig->
stream() ), m_fullConfig( _fullConfig ) {}
4526 ReporterConfig(
Ptr<IConfig> const& _fullConfig, std::ostream& _stream )
4527 : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
4529 std::ostream&
stream()
const {
return *m_stream; }
4530 Ptr<IConfig> fullConfig()
const {
return m_fullConfig; }
4533 std::ostream* m_stream;
4537 struct ReporterPreferences {
4538 ReporterPreferences()
4539 : shouldRedirectStdOut( false )
4542 bool shouldRedirectStdOut;
4545 template<
typename T>
4546 struct LazyStat :
Option<T> {
4547 LazyStat() : used( false ) {}
4548 LazyStat&
operator=( T
const& _value ) {
4560 struct TestRunInfo {
4561 TestRunInfo(
std::string const& _name ) : name( _name ) {}
4566 std::size_t _groupIndex,
4567 std::size_t _groupsCount )
4569 groupIndex( _groupIndex ),
4570 groupsCounts( _groupsCount )
4574 std::size_t groupIndex;
4575 std::size_t groupsCounts;
4578 struct AssertionStats {
4580 std::vector<MessageInfo>
const& _infoMessages,
4582 : assertionResult( _assertionResult ),
4583 infoMessages( _infoMessages ),
4586 if( assertionResult.hasMessage() ) {
4589 MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
4590 builder << assertionResult.getMessage();
4593 infoMessages.push_back( builder.m_info );
4596 virtual ~AssertionStats();
4598 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS 4599 AssertionStats( AssertionStats
const& ) =
default;
4600 AssertionStats( AssertionStats && ) =
default;
4601 AssertionStats&
operator = ( AssertionStats
const& ) =
default;
4602 AssertionStats&
operator = ( AssertionStats && ) =
default;
4606 std::vector<MessageInfo> infoMessages;
4610 struct SectionStats {
4612 Counts const& _assertions,
4613 double _durationInSeconds,
4614 bool _missingAssertions )
4615 : sectionInfo( _sectionInfo ),
4616 assertions( _assertions ),
4617 durationInSeconds( _durationInSeconds ),
4618 missingAssertions( _missingAssertions )
4620 virtual ~SectionStats();
4621 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS 4622 SectionStats( SectionStats
const& ) =
default;
4623 SectionStats( SectionStats && ) =
default;
4624 SectionStats&
operator = ( SectionStats
const& ) =
default;
4625 SectionStats&
operator = ( SectionStats && ) =
default;
4630 double durationInSeconds;
4631 bool missingAssertions;
4634 struct TestCaseStats {
4640 : testInfo( _testInfo ),
4644 aborting( _aborting )
4646 virtual ~TestCaseStats();
4648 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS 4649 TestCaseStats( TestCaseStats
const& ) =
default;
4650 TestCaseStats( TestCaseStats && ) =
default;
4651 TestCaseStats&
operator = ( TestCaseStats
const& ) =
default;
4652 TestCaseStats&
operator = ( TestCaseStats && ) =
default;
4662 struct TestGroupStats {
4663 TestGroupStats( GroupInfo
const& _groupInfo,
4666 : groupInfo( _groupInfo ),
4668 aborting( _aborting )
4670 TestGroupStats( GroupInfo
const& _groupInfo )
4671 : groupInfo( _groupInfo ),
4674 virtual ~TestGroupStats();
4676 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS 4677 TestGroupStats( TestGroupStats
const& ) =
default;
4678 TestGroupStats( TestGroupStats && ) =
default;
4679 TestGroupStats&
operator = ( TestGroupStats
const& ) =
default;
4680 TestGroupStats&
operator = ( TestGroupStats && ) =
default;
4683 GroupInfo groupInfo;
4688 struct TestRunStats {
4689 TestRunStats( TestRunInfo
const& _runInfo,
4692 : runInfo( _runInfo ),
4694 aborting( _aborting )
4696 virtual ~TestRunStats();
4698 # ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS 4699 TestRunStats( TestRunStats
const& _other )
4700 : runInfo( _other.runInfo ),
4701 totals( _other.totals ),
4702 aborting( _other.aborting )
4705 TestRunStats( TestRunStats
const& ) =
default;
4706 TestRunStats( TestRunStats && ) =
default;
4707 TestRunStats&
operator = ( TestRunStats
const& ) =
default;
4708 TestRunStats&
operator = ( TestRunStats && ) =
default;
4711 TestRunInfo runInfo;
4716 struct IStreamingReporter :
IShared {
4717 virtual ~IStreamingReporter();
4722 virtual ReporterPreferences getPreferences()
const = 0;
4724 virtual void noMatchingTestCases(
std::string const& spec ) = 0;
4726 virtual void testRunStarting( TestRunInfo
const& testRunInfo ) = 0;
4727 virtual void testGroupStarting( GroupInfo
const& groupInfo ) = 0;
4729 virtual void testCaseStarting(
TestCaseInfo const& testInfo ) = 0;
4730 virtual void sectionStarting(
SectionInfo const& sectionInfo ) = 0;
4732 virtual void assertionStarting(
AssertionInfo const& assertionInfo ) = 0;
4735 virtual bool assertionEnded( AssertionStats
const& assertionStats ) = 0;
4736 virtual void sectionEnded( SectionStats
const& sectionStats ) = 0;
4737 virtual void testCaseEnded( TestCaseStats
const& testCaseStats ) = 0;
4738 virtual void testGroupEnded( TestGroupStats
const& testGroupStats ) = 0;
4739 virtual void testRunEnded( TestRunStats
const& testRunStats ) = 0;
4741 virtual void skipTest(
TestCaseInfo const& testInfo ) = 0;
4744 struct IReporterFactory {
4745 virtual ~IReporterFactory();
4746 virtual IStreamingReporter* create( ReporterConfig
const& config )
const = 0;
4750 struct IReporterRegistry {
4751 typedef std::map<std::string, IReporterFactory*> FactoryMap;
4753 virtual ~IReporterRegistry();
4755 virtual FactoryMap
const& getFactories()
const = 0;
4761 #include <algorithm> 4765 inline std::size_t listTests( Config
const& config ) {
4767 TestSpec testSpec = config.testSpec();
4768 if( config.testSpec().hasFilters() )
4769 Catch::cout() <<
"Matching test cases:\n";
4771 Catch::cout() <<
"All available test cases:\n";
4775 std::size_t matchedTests = 0;
4776 TextAttributes nameAttr, tagsAttr;
4777 nameAttr.setInitialIndent( 2 ).setIndent( 4 );
4778 tagsAttr.setIndent( 6 );
4780 std::vector<TestCase> matchedTestCases;
4782 for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
4786 TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
4787 Colour::Code colour = testCaseInfo.
isHidden()
4788 ? Colour::SecondaryText
4790 Colour colourGuard( colour );
4792 Catch::cout() << Text( testCaseInfo.
name, nameAttr ) << std::endl;
4793 if( !testCaseInfo.
tags.empty() )
4794 Catch::cout() << Text( testCaseInfo.
tagsAsString, tagsAttr ) << std::endl;
4797 if( !config.testSpec().hasFilters() )
4798 Catch::cout() <<
pluralise( matchedTests,
"test case" ) <<
"\n" << std::endl;
4800 Catch::cout() <<
pluralise( matchedTests,
"matching test case" ) <<
"\n" << std::endl;
4801 return matchedTests;
4804 inline std::size_t listTestsNamesOnly( Config
const& config ) {
4805 TestSpec testSpec = config.testSpec();
4806 if( !config.testSpec().hasFilters() )
4808 std::size_t matchedTests = 0;
4809 std::vector<TestCase> matchedTestCases;
4811 for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
4815 TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
4816 Catch::cout() << testCaseInfo.
name << std::endl;
4818 return matchedTests;
4822 TagInfo() : count ( 0 ) {}
4825 spellings.insert( spelling );
4829 for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end();
4832 out += "[" + *it + "]";
4835 std::set<std::string> spellings;
4839 inline std::size_t listTags( Config
const& config ) {
4840 TestSpec testSpec = config.testSpec();
4841 if( config.testSpec().hasFilters() )
4842 Catch::cout() <<
"Tags for matching test cases:\n";
4844 Catch::cout() <<
"All available tags:\n";
4848 std::map<std::string, TagInfo> tagCounts;
4850 std::vector<TestCase> matchedTestCases;
4852 for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
4855 for( std::set<std::string>::const_iterator tagIt = it->getTestCaseInfo().tags.begin(),
4856 tagItEnd = it->getTestCaseInfo().tags.end();
4861 std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName );
4862 if( countIt == tagCounts.end() )
4863 countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
4864 countIt->second.add( tagName );
4868 for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(),
4869 countItEnd = tagCounts.end();
4870 countIt != countItEnd;
4872 std::ostringstream oss;
4873 oss <<
" " << std::setw(2) << countIt->second.count <<
" ";
4874 Text wrapper( countIt->second.all(), TextAttributes()
4875 .setInitialIndent( 0 )
4876 .setIndent( oss.str().size() )
4877 .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );
4878 Catch::cout() << oss.str() << wrapper <<
"\n";
4880 Catch::cout() <<
pluralise( tagCounts.size(),
"tag" ) <<
"\n" << std::endl;
4881 return tagCounts.size();
4884 inline std::size_t listReporters( Config
const& ) {
4885 Catch::cout() <<
"Available reporters:\n";
4887 IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
4888 std::size_t maxNameLen = 0;
4889 for(it = itBegin; it != itEnd; ++it )
4890 maxNameLen = (
std::max)( maxNameLen, it->first.size() );
4892 for(it = itBegin; it != itEnd; ++it ) {
4893 Text wrapper( it->second->getDescription(), TextAttributes()
4894 .setInitialIndent( 0 )
4895 .setIndent( 7+maxNameLen )
4896 .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
4897 Catch::cout() <<
" " 4900 <<
std::string( maxNameLen - it->first.size() + 2, ' ' )
4903 Catch::cout() << std::endl;
4904 return factories.size();
4909 if( config.listTests() )
4910 listedCount = listedCount.
valueOr(0) + listTests( config );
4911 if( config.listTestNamesOnly() )
4912 listedCount = listedCount.
valueOr(0) + listTestsNamesOnly( config );
4913 if( config.listTags() )
4914 listedCount = listedCount.
valueOr(0) + listTags( config );
4915 if( config.listReporters() )
4916 listedCount = listedCount.
valueOr(0) + listReporters( config );
4923 #define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED 4926 #define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED 4933 namespace SectionTracking {
4935 class TrackedSection {
4937 typedef std::map<std::string, TrackedSection> TrackedSections;
4947 TrackedSection(
std::string const& name, TrackedSection* parent )
4948 : m_name( name ), m_runState( NotStarted ), m_parent( parent )
4951 RunState runState()
const {
return m_runState; }
4953 TrackedSection* findChild(
std::string const& childName );
4954 TrackedSection* acquireChild(
std::string const& childName );
4957 if( m_runState == NotStarted )
4958 m_runState = Executing;
4962 TrackedSection* getParent() {
4965 bool hasChildren()
const {
4966 return !m_children.empty();
4971 RunState m_runState;
4972 TrackedSections m_children;
4973 TrackedSection* m_parent;
4976 inline TrackedSection* TrackedSection::findChild(
std::string const& childName ) {
4977 TrackedSections::iterator it = m_children.find( childName );
4978 return it != m_children.end()
4982 inline TrackedSection* TrackedSection::acquireChild(
std::string const& childName ) {
4983 if( TrackedSection* child = findChild( childName ) )
4985 m_children.insert( std::make_pair( childName, TrackedSection( childName,
this ) ) );
4986 return findChild( childName );
4988 inline void TrackedSection::leave() {
4989 for( TrackedSections::const_iterator it = m_children.begin(), itEnd = m_children.end();
4992 if( it->second.runState() != Completed ) {
4993 m_runState = ExecutingChildren;
4996 m_runState = Completed;
4999 class TestCaseTracker {
5001 TestCaseTracker(
std::string const& testCaseName )
5002 : m_testCase( testCaseName, NULL ),
5003 m_currentSection( &m_testCase ),
5004 m_completedASectionThisRun( false )
5008 TrackedSection* child = m_currentSection->acquireChild( name );
5009 if( m_completedASectionThisRun || child->runState() == TrackedSection::Completed )
5012 m_currentSection = child;
5013 m_currentSection->enter();
5016 void leaveSection() {
5017 m_currentSection->leave();
5018 m_currentSection = m_currentSection->getParent();
5019 assert( m_currentSection != NULL );
5020 m_completedASectionThisRun =
true;
5023 bool currentSectionHasChildren()
const {
5024 return m_currentSection->hasChildren();
5026 bool isCompleted()
const {
5027 return m_testCase.runState() == TrackedSection::Completed;
5032 Guard( TestCaseTracker& tracker ) : m_tracker( tracker ) {
5033 m_tracker.enterTestCase();
5036 m_tracker.leaveTestCase();
5039 Guard( Guard
const& );
5041 TestCaseTracker& m_tracker;
5045 void enterTestCase() {
5046 m_currentSection = &m_testCase;
5047 m_completedASectionThisRun =
false;
5050 void leaveTestCase() {
5054 TrackedSection m_testCase;
5055 TrackedSection* m_currentSection;
5056 bool m_completedASectionThisRun;
5061 using SectionTracking::TestCaseTracker;
5066 #define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED 5082 #if defined ( CATCH_PLATFORM_WINDOWS ) 5086 struct FatalConditionHandler {
5092 #else // Not Windows - assumed to be POSIX compatible 5098 struct SignalDefs {
int id;
const char*
name; };
5099 extern SignalDefs signalDefs[];
5100 SignalDefs signalDefs[] = {
5101 { SIGINT,
"SIGINT - Terminal interrupt signal" },
5102 { SIGILL,
"SIGILL - Illegal instruction signal" },
5103 { SIGFPE,
"SIGFPE - Floating point error signal" },
5104 { SIGSEGV,
"SIGSEGV - Segmentation violation signal" },
5105 { SIGTERM,
"SIGTERM - Termination request signal" },
5106 { SIGABRT,
"SIGABRT - Abort (abnormal termination) signal" }
5109 struct FatalConditionHandler {
5111 static void handleSignal(
int sig ) {
5112 for( std::size_t i = 0; i <
sizeof(signalDefs)/
sizeof(SignalDefs); ++i )
5113 if( sig == signalDefs[i].
id )
5114 fatal( signalDefs[i].name, -sig );
5115 fatal(
"<unknown signal>", -sig );
5118 FatalConditionHandler() : m_isSet( true ) {
5119 for( std::size_t i = 0; i <
sizeof(signalDefs)/
sizeof(SignalDefs); ++i )
5120 signal( signalDefs[i].
id, handleSignal );
5122 ~FatalConditionHandler() {
5127 for( std::size_t i = 0; i <
sizeof(signalDefs)/
sizeof(SignalDefs); ++i )
5128 signal( signalDefs[i].
id, SIG_DFL );
5138 #endif // not Windows 5145 class StreamRedirect {
5149 : m_stream( stream ),
5150 m_prevBuf( stream.rdbuf() ),
5151 m_targetString( targetString )
5153 stream.rdbuf( m_oss.rdbuf() );
5157 m_targetString += m_oss.str();
5158 m_stream.rdbuf( m_prevBuf );
5162 std::ostream& m_stream;
5163 std::streambuf* m_prevBuf;
5164 std::ostringstream m_oss;
5172 RunContext( RunContext
const& );
5178 : m_runInfo( config->name() ),
5180 m_activeTestCase( NULL ),
5182 m_reporter( reporter ),
5183 m_prevRunner( m_context.getRunner() ),
5185 m_prevConfig( m_context.getConfig() )
5187 m_context.setRunner(
this );
5188 m_context.setConfig( m_config );
5189 m_context.setResultCapture(
this );
5190 m_reporter->testRunStarting( m_runInfo );
5193 virtual ~RunContext() {
5194 m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
5195 m_context.setRunner( m_prevRunner );
5196 m_context.setConfig( NULL );
5197 m_context.setResultCapture( m_prevResultCapture );
5198 m_context.setConfig( m_prevConfig );
5201 void testGroupStarting(
std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
5202 m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );
5204 void testGroupEnded(
std::string const& testSpec,
Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {
5205 m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
5209 Totals prevTotals = m_totals;
5216 m_reporter->testCaseStarting( testInfo );
5218 m_activeTestCase = &testCase;
5219 m_testCaseTracker = TestCaseTracker( testInfo.
name );
5223 runCurrentTest( redirectedCout, redirectedCerr );
5225 while( !m_testCaseTracker->isCompleted() && !aborting() );
5229 Totals deltaTotals = m_totals.
delta( prevTotals );
5230 m_totals.
testCases += deltaTotals.testCases;
5231 m_reporter->testCaseEnded( TestCaseStats( testInfo,
5237 m_activeTestCase = NULL;
5238 m_testCaseTracker.reset();
5251 m_totals.assertions.passed++;
5253 else if( !result.
isOk() ) {
5254 m_totals.assertions.failed++;
5257 if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) )
5261 m_lastAssertionInfo =
AssertionInfo(
"", m_lastAssertionInfo.lineInfo,
"{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
5265 virtual bool sectionStarted (
5270 std::ostringstream oss;
5271 oss << sectionInfo.
name <<
"@" << sectionInfo.
lineInfo;
5273 if( !m_testCaseTracker->enterSection( oss.str() ) )
5276 m_lastAssertionInfo.lineInfo = sectionInfo.
lineInfo;
5278 m_reporter->sectionStarting( sectionInfo );
5280 assertions = m_totals.assertions;
5284 bool testForMissingAssertions(
Counts& assertions ) {
5285 if( assertions.
total() != 0 ||
5286 !m_config->warnAboutMissingAssertions() ||
5287 m_testCaseTracker->currentSectionHasChildren() )
5289 m_totals.assertions.
failed++;
5294 virtual void sectionEnded(
SectionInfo const& info,
Counts const& prevAssertions,
double _durationInSeconds ) {
5295 if( std::uncaught_exception() ) {
5296 m_unfinishedSections.push_back( UnfinishedSections( info, prevAssertions, _durationInSeconds ) );
5300 Counts assertions = m_totals.assertions - prevAssertions;
5301 bool missingAssertions = testForMissingAssertions( assertions );
5303 m_testCaseTracker->leaveSection();
5305 m_reporter->sectionEnded( SectionStats( info, assertions, _durationInSeconds, missingAssertions ) );
5309 virtual void pushScopedMessage(
MessageInfo const& message ) {
5310 m_messages.push_back( message );
5313 virtual void popScopedMessage(
MessageInfo const& message ) {
5314 m_messages.erase( std::remove( m_messages.begin(), m_messages.end(),
message ), m_messages.end() );
5318 return m_activeTestCase
5319 ? m_activeTestCase->getTestCaseInfo().name
5324 return &m_lastResult;
5327 virtual void handleFatalErrorCondition(
std::string const& message ) {
5328 ResultBuilder resultBuilder = makeUnexpectedResultBuilder();
5333 handleUnfinishedSections();
5336 TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
5341 SectionStats testCaseSectionStats( testCaseSection, assertions, 0,
false );
5342 m_reporter->sectionEnded( testCaseSectionStats );
5344 TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo();
5348 m_reporter->testCaseEnded( TestCaseStats( testInfo,
5353 m_totals.testCases.failed++;
5354 testGroupEnded(
"", m_totals, 1, 1 );
5355 m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals,
false ) );
5360 bool aborting()
const {
5361 return m_totals.assertions.failed ==
static_cast<std::size_t
>( m_config->abortAfter() );
5367 TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
5369 m_reporter->sectionStarting( testCaseSection );
5370 Counts prevAssertions = m_totals.assertions;
5371 double duration = 0;
5374 TestCaseTracker::Guard guard( *m_testCaseTracker );
5378 if( m_reporter->getPreferences().shouldRedirectStdOut ) {
5379 StreamRedirect coutRedir( Catch::cout(), redirectedCout );
5380 StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr );
5381 invokeActiveTestCase();
5384 invokeActiveTestCase();
5392 makeUnexpectedResultBuilder().useActiveException();
5394 handleUnfinishedSections();
5397 Counts assertions = m_totals.assertions - prevAssertions;
5398 bool missingAssertions = testForMissingAssertions( assertions );
5402 m_totals.assertions.failed -= assertions.failedButOk;
5403 m_totals.assertions.
failedButOk += assertions.failedButOk;
5406 SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
5407 m_reporter->sectionEnded( testCaseSectionStats );
5410 void invokeActiveTestCase() {
5411 FatalConditionHandler fatalConditionHandler;
5412 m_activeTestCase->invoke();
5413 fatalConditionHandler.reset();
5419 return ResultBuilder( m_lastAssertionInfo.macroName.c_str(),
5420 m_lastAssertionInfo.lineInfo,
5421 m_lastAssertionInfo.capturedExpression.c_str(),
5422 m_lastAssertionInfo.resultDisposition );
5425 void handleUnfinishedSections() {
5428 for( std::vector<UnfinishedSections>::const_reverse_iterator it = m_unfinishedSections.rbegin(),
5429 itEnd = m_unfinishedSections.rend();
5432 sectionEnded( it->info, it->prevAssertions, it->durationInSeconds );
5433 m_unfinishedSections.clear();
5436 struct UnfinishedSections {
5437 UnfinishedSections(
SectionInfo const& _info,
Counts const& _prevAssertions,
double _durationInSeconds )
5438 : info( _info ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
5443 double durationInSeconds;
5446 TestRunInfo m_runInfo;
5455 std::vector<MessageInfo> m_messages;
5460 std::vector<UnfinishedSections> m_unfinishedSections;
5467 throw std::logic_error(
"No result capture instance" );
5473 #define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED 5479 Version(
unsigned int _majorVersion,
5480 unsigned int _minorVersion,
5481 unsigned int _patchNumber,
5483 unsigned int _buildNumber );
5485 unsigned int const majorVersion;
5486 unsigned int const minorVersion;
5487 unsigned int const patchNumber;
5491 unsigned int const buildNumber;
5493 friend std::ostream&
operator << ( std::ostream& os, Version
const& version );
5499 extern Version libraryVersion;
5512 : m_config( config )
5520 RunContext context( m_config.get(), m_reporter );
5524 context.testGroupStarting(
"all tests", 1, 1 );
5526 TestSpec testSpec = m_config->testSpec();
5527 if( !testSpec.hasFilters() )
5530 std::vector<TestCase> testCases;
5533 int testsRunForGroup = 0;
5534 for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();
5538 if( m_testsAlreadyRun.find( *it ) == m_testsAlreadyRun.end() ) {
5540 if( context.aborting() )
5543 totals += context.runTest( *it );
5544 m_testsAlreadyRun.insert( *it );
5547 std::vector<TestCase> skippedTestCases;
5550 for( std::vector<TestCase>::const_iterator it = skippedTestCases.begin(), itEnd = skippedTestCases.end();
5553 m_reporter->skipTest( *it );
5555 context.testGroupEnded(
"all tests", totals, 1, 1 );
5562 if( !m_config->getFilename().empty() ) {
5563 m_ofs.open( m_config->getFilename().c_str() );
5564 if( m_ofs.fail() ) {
5565 std::ostringstream oss;
5566 oss <<
"Unable to open file: '" << m_config->getFilename() <<
"'";
5567 throw std::domain_error( oss.str() );
5569 m_config->setStreamBuf( m_ofs.rdbuf() );
5572 void makeReporter() {
5573 std::string reporterName = m_config->getReporterName().empty()
5575 : m_config->getReporterName();
5579 std::ostringstream oss;
5580 oss <<
"No reporter registered with name: '" << reporterName <<
"'";
5581 throw std::domain_error( oss.str() );
5587 std::ofstream m_ofs;
5589 std::set<TestCase> m_testsAlreadyRun;
5593 static bool alreadyInstantiated;
5597 struct OnUnusedOptions {
enum DoWhat { Ignore, Fail }; };
5600 : m_cli( makeCommandLineParser() ) {
5601 if( alreadyInstantiated ) {
5602 std::string msg =
"Only one instance of Catch::Session can ever be used";
5603 Catch::cerr() << msg << std::endl;
5604 throw std::logic_error( msg );
5606 alreadyInstantiated =
true;
5613 Catch::cout() <<
"\nCatch v" << libraryVersion <<
"\n";
5615 m_cli.usage( Catch::cout(), processName );
5616 Catch::cout() <<
"For more detail usage please see the project docs\n" << std::endl;
5619 int applyCommandLine(
int argc,
char*
const argv[], OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
5621 m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
5622 m_unusedTokens = m_cli.parseInto( argc, argv, m_configData );
5623 if( m_configData.showHelp )
5624 showHelp( m_configData.processName );
5627 catch( std::exception& ex ) {
5629 Colour colourGuard( Colour::Red );
5631 <<
"\nError(s) in input:\n" 5632 << Text( ex.what(), TextAttributes().setIndent(2) )
5635 m_cli.usage( Catch::cout(), m_configData.processName );
5636 return (std::numeric_limits<int>::max)();
5641 void useConfigData( ConfigData
const& _configData ) {
5642 m_configData = _configData;
5646 int run(
int argc,
char*
const argv[] ) {
5648 int returnCode = applyCommandLine( argc, argv );
5649 if( returnCode == 0 )
5655 if( m_configData.showHelp )
5662 std::srand( m_configData.rngSeed );
5664 Runner runner( m_config );
5668 return static_cast<int>( *listed );
5670 return static_cast<int>( runner.runTests().assertions.failed );
5672 catch( std::exception& ex ) {
5673 Catch::cerr() << ex.what() << std::endl;
5674 return (std::numeric_limits<int>::max)();
5678 Clara::CommandLine<ConfigData>
const& cli()
const {
5681 std::vector<Clara::Parser::Token>
const& unusedTokens()
const {
5682 return m_unusedTokens;
5684 ConfigData& configData() {
5685 return m_configData;
5689 m_config =
new Config( m_configData );
5694 Clara::CommandLine<ConfigData> m_cli;
5695 std::vector<Clara::Parser::Token> m_unusedTokens;
5696 ConfigData m_configData;
5700 bool Session::alreadyInstantiated =
false;
5705 #define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED 5708 #define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED 5714 #include <algorithm> 5722 struct RandomNumberGenerator {
5723 int operator()(
int n )
const {
return std::rand() %
n; }
5727 TestRegistry() : m_unnamedCount( 0 ) {}
5728 virtual ~TestRegistry();
5730 virtual void registerTest(
TestCase const& testCase ) {
5733 std::ostringstream oss;
5734 oss <<
"Anonymous test case " << ++m_unnamedCount;
5735 return registerTest( testCase.
withName( oss.str() ) );
5738 if( m_functions.find( testCase ) == m_functions.end() ) {
5739 m_functions.insert( testCase );
5740 m_functionsInOrder.push_back( testCase );
5742 m_nonHiddenFunctions.push_back( testCase );
5745 TestCase const& prev = *m_functions.find( testCase );
5747 Colour colourGuard( Colour::Red );
5748 Catch::cerr() <<
"error: TEST_CASE( \"" << name <<
"\" ) already defined.\n" 5756 virtual std::vector<TestCase>
const& getAllTests()
const {
5757 return m_functionsInOrder;
5760 virtual std::vector<TestCase>
const& getAllNonHiddenTests()
const {
5761 return m_nonHiddenFunctions;
5764 virtual void getFilteredTests( TestSpec
const& testSpec, IConfig
const& config, std::vector<TestCase>& matchingTestCases,
bool negated =
false )
const {
5766 for( std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin(),
5767 itEnd = m_functionsInOrder.end();
5770 bool includeTest = testSpec.matches( *it ) && ( config.allowThrows() || !it->throws() );
5771 if( includeTest != negated )
5772 matchingTestCases.push_back( *it );
5774 sortTests( config, matchingTestCases );
5779 static void sortTests( IConfig
const& config, std::vector<TestCase>& matchingTestCases ) {
5781 switch( config.runOrder() ) {
5782 case RunTests::InLexicographicalOrder:
5783 std::sort( matchingTestCases.begin(), matchingTestCases.end(), LexSort() );
5785 case RunTests::InRandomOrder:
5787 RandomNumberGenerator rng;
5788 std::random_shuffle( matchingTestCases.begin(), matchingTestCases.end(), rng );
5791 case RunTests::InDeclarationOrder:
5796 std::set<TestCase> m_functions;
5797 std::vector<TestCase> m_functionsInOrder;
5798 std::vector<TestCase> m_nonHiddenFunctions;
5799 size_t m_unnamedCount;
5804 class FreeFunctionTestCase :
public SharedImpl<ITestCase> {
5807 FreeFunctionTestCase(
TestFunction fun ) : m_fun( fun ) {}
5809 virtual void invoke()
const {
5814 virtual ~FreeFunctionTestCase();
5820 std::string className = classOrQualifiedMethodName;
5823 std::size_t lastColons = className.rfind(
"::" );
5824 std::size_t penultimateColons = className.rfind(
"::", lastColons-1 );
5825 if( penultimateColons == std::string::npos )
5826 penultimateColons = 1;
5827 className = className.substr( penultimateColons, lastColons-penultimateColons );
5837 registerTestCase(
new FreeFunctionTestCase(
function ),
"", nameAndDesc, lineInfo );
5843 char const* classOrQualifiedMethodName,
5849 extractClassName( classOrQualifiedMethodName ),
5858 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED 5864 class ReporterRegistry :
public IReporterRegistry {
5868 virtual ~ReporterRegistry() {
5873 FactoryMap::const_iterator it = m_factories.find( name );
5874 if( it == m_factories.end() )
5876 return it->second->create( ReporterConfig( config ) );
5879 void registerReporter(
std::string const& name, IReporterFactory* factory ) {
5880 m_factories.insert( std::make_pair( name, factory ) );
5883 FactoryMap
const& getFactories()
const {
5888 FactoryMap m_factories;
5893 #define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED 5896 #import "Foundation/Foundation.h" 5903 ~ExceptionTranslatorRegistry() {
5908 m_translators.push_back( translator );
5918 @catch (NSException *exception) {
5928 catch( std::exception& ex ) {
5934 catch(
const char* msg ) {
5938 return tryTranslators( m_translators.begin() );
5942 std::string tryTranslators( std::vector<const IExceptionTranslator*>::const_iterator it )
const {
5943 if( it == m_translators.end() )
5944 return "Unknown exception";
5947 return (*it)->translate();
5950 return tryTranslators( it+1 );
5955 std::vector<const IExceptionTranslator*> m_translators;
5965 RegistryHub( RegistryHub
const& );
5971 virtual IReporterRegistry
const& getReporterRegistry()
const {
5972 return m_reporterRegistry;
5975 return m_testCaseRegistry;
5978 return m_exceptionTranslatorRegistry;
5982 virtual void registerReporter(
std::string const& name, IReporterFactory* factory ) {
5983 m_reporterRegistry.registerReporter( name, factory );
5985 virtual void registerTest(
TestCase const& testInfo ) {
5986 m_testCaseRegistry.registerTest( testInfo );
5989 m_exceptionTranslatorRegistry.registerTranslator( translator );
5993 TestRegistry m_testCaseRegistry;
5994 ReporterRegistry m_reporterRegistry;
5995 ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
5999 inline RegistryHub*& getTheRegistryHub() {
6000 static RegistryHub* theRegistryHub = NULL;
6001 if( !theRegistryHub )
6002 theRegistryHub =
new RegistryHub();
6003 return theRegistryHub;
6008 return *getTheRegistryHub();
6011 return *getTheRegistryHub();
6014 delete getTheRegistryHub();
6015 getTheRegistryHub() = NULL;
6025 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED 6032 : m_lineInfo( lineInfo ) {
6033 std::ostringstream oss;
6034 oss << lineInfo <<
": function ";
6035 oss <<
"not implemented";
6040 return m_what.c_str();
6046 #define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED 6049 #define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED 6052 #define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED 6054 #include <streambuf> 6058 class StreamBufBase :
public std::streambuf {
6064 #include <stdexcept> 6070 template<
typename WriterF,
size_t bufferSize=256>
6071 class StreamBufImpl :
public StreamBufBase {
6072 char data[bufferSize];
6077 setp( data, data +
sizeof(data) );
6085 int overflow(
int c ) {
6089 if( pbase() == epptr() )
6090 m_writer(
std::string( 1, static_cast<char>( c ) ) );
6092 sputc( static_cast<char>( c ) );
6098 if( pbase() != pptr() ) {
6099 m_writer(
std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
6100 setp( pbase(), epptr() );
6108 struct OutputDebugWriter {
6116 : streamBuf( NULL ), isOwned( false )
6119 Stream::Stream( std::streambuf* _streamBuf,
bool _isOwned )
6120 : streamBuf( _streamBuf ), isOwned( _isOwned )
6123 void Stream::release() {
6131 #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement this functions 6132 std::ostream& cout() {
6135 std::ostream& cerr() {
6145 Context() : m_config( NULL ), m_runner( NULL ), m_resultCapture( NULL ) {}
6146 Context( Context
const& );
6151 return m_resultCapture;
6153 virtual IRunner* getRunner() {
6156 virtual size_t getGeneratorIndex(
std::string const& fileInfo,
size_t totalSize ) {
6157 return getGeneratorsForCurrentTest()
6158 .getGeneratorInfo( fileInfo, totalSize )
6161 virtual bool advanceGeneratorsForCurrentTest() {
6163 return generators && generators->
moveNext();
6172 m_resultCapture = resultCapture;
6174 virtual void setRunner(
IRunner* runner ) {
6187 std::map<std::string, IGeneratorsForTest*>::const_iterator it =
6188 m_generatorsByTestName.find( testName );
6189 return it != m_generatorsByTestName.end()
6199 m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
6208 std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
6212 Context* currentContext = NULL;
6215 if( !currentContext )
6216 currentContext =
new Context();
6217 return *currentContext;
6224 if( streamName ==
"stdout" )
return Stream( Catch::cout().rdbuf(),
false );
6225 if( streamName ==
"stderr" )
return Stream( Catch::cerr().rdbuf(),
false );
6226 if( streamName ==
"debug" )
return Stream(
new StreamBufImpl<OutputDebugWriter>,
true );
6228 throw std::domain_error(
"Unknown stream: " + streamName );
6232 delete currentContext;
6233 currentContext = NULL;
6238 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED 6243 struct IColourImpl {
6244 virtual ~IColourImpl() {}
6245 virtual void use( Colour::Code _colourCode ) = 0;
6248 struct NoColourImpl : IColourImpl {
6249 void use( Colour::Code ) {}
6251 static IColourImpl* instance() {
6252 static NoColourImpl s_instance;
6260 #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI ) 6261 # ifdef CATCH_PLATFORM_WINDOWS 6262 # define CATCH_CONFIG_COLOUR_WINDOWS 6264 # define CATCH_CONFIG_COLOUR_ANSI 6268 #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) 6277 #include <windows.h> 6283 class Win32ColourImpl :
public IColourImpl {
6285 Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
6287 CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
6288 GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
6289 originalAttributes = csbiInfo.wAttributes;
6292 virtual void use( Colour::Code _colourCode ) {
6293 switch( _colourCode ) {
6294 case Colour::None:
return setTextAttribute( originalAttributes );
6295 case Colour::White:
return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
6296 case Colour::Red:
return setTextAttribute( FOREGROUND_RED );
6297 case Colour::Green:
return setTextAttribute( FOREGROUND_GREEN );
6298 case Colour::Blue:
return setTextAttribute( FOREGROUND_BLUE );
6299 case Colour::Cyan:
return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
6300 case Colour::Yellow:
return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
6301 case Colour::Grey:
return setTextAttribute( 0 );
6303 case Colour::LightGrey:
return setTextAttribute( FOREGROUND_INTENSITY );
6304 case Colour::BrightRed:
return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
6305 case Colour::BrightGreen:
return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
6306 case Colour::BrightWhite:
return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
6308 case Colour::Bright:
throw std::logic_error(
"not a colour" );
6313 void setTextAttribute( WORD _textAttribute ) {
6314 SetConsoleTextAttribute( stdoutHandle, _textAttribute );
6317 WORD originalAttributes;
6320 IColourImpl* platformColourInstance() {
6321 static Win32ColourImpl s_instance;
6328 #elif defined( CATCH_CONFIG_COLOUR_ANSI ) 6339 class PosixColourImpl :
public IColourImpl {
6341 virtual void use( Colour::Code _colourCode ) {
6342 switch( _colourCode ) {
6344 case Colour::White:
return setColour(
"[0m" );
6345 case Colour::Red:
return setColour(
"[0;31m" );
6346 case Colour::Green:
return setColour(
"[0;32m" );
6347 case Colour::Blue:
return setColour(
"[0:34m" );
6348 case Colour::Cyan:
return setColour(
"[0;36m" );
6349 case Colour::Yellow:
return setColour(
"[0;33m" );
6350 case Colour::Grey:
return setColour(
"[1;30m" );
6352 case Colour::LightGrey:
return setColour(
"[0;37m" );
6353 case Colour::BrightRed:
return setColour(
"[1;31m" );
6354 case Colour::BrightGreen:
return setColour(
"[1;32m" );
6355 case Colour::BrightWhite:
return setColour(
"[1;37m" );
6357 case Colour::Bright:
throw std::logic_error(
"not a colour" );
6360 static IColourImpl* instance() {
6361 static PosixColourImpl s_instance;
6366 void setColour(
const char* _escapeCode ) {
6367 Catch::cout() <<
'\033' << _escapeCode;
6371 IColourImpl* platformColourInstance() {
6373 return (config && config->forceColour()) || isatty(STDOUT_FILENO)
6374 ? PosixColourImpl::instance()
6375 : NoColourImpl::instance();
6381 #else // not Windows or ANSI 6385 static IColourImpl* platformColourInstance() {
return NoColourImpl::instance(); }
6389 #endif // Windows/ ANSI/ None 6393 Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); }
6394 Colour::Colour( Colour
const& _other ) : m_moved( false ) {
const_cast<Colour&
>( _other ).m_moved =
true; }
6395 Colour::~Colour(){
if( !m_moved ) use(
None ); }
6397 void Colour::use( Code _colourCode ) {
6399 ? NoColourImpl::instance()
6400 : platformColourInstance();
6401 impl->use( _colourCode );
6407 #define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED 6417 GeneratorInfo( std::size_t size )
6423 if( ++m_currentIndex == m_size ) {
6430 std::size_t getCurrentIndex()
const {
6431 return m_currentIndex;
6435 std::size_t m_currentIndex;
6443 ~GeneratorsForTest() {
6448 std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
6449 if( it == m_generatorsByName.end() ) {
6451 m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
6452 m_generatorsInOrder.push_back( info );
6459 std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
6460 std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
6461 for(; it != itEnd; ++it ) {
6462 if( (*it)->moveNext() )
6469 std::map<std::string, IGeneratorInfo*> m_generatorsByName;
6470 std::vector<IGeneratorInfo*> m_generatorsInOrder;
6475 return new GeneratorsForTest();
6481 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED 6489 : macroName( _macroName ),
6490 lineInfo( _lineInfo ),
6491 capturedExpression( _capturedExpression ),
6492 resultDisposition( _resultDisposition )
6499 m_resultData( data )
6515 return m_resultData.resultType;
6519 return !m_info.capturedExpression.empty();
6523 return !m_resultData.message.empty();
6528 return "!" + m_info.capturedExpression;
6530 return m_info.capturedExpression;
6533 if( m_info.macroName.empty() )
6534 return m_info.capturedExpression;
6536 return m_info.macroName +
"( " + m_info.capturedExpression +
" )";
6540 return hasExpression() && getExpandedExpression() != getExpression();
6544 return m_resultData.reconstructedExpression;
6548 return m_resultData.message;
6551 return m_info.lineInfo;
6555 return m_info.macroName;
6561 #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED 6570 else if( tag ==
"!throws" )
6572 else if( tag ==
"!shouldfail" )
6574 else if( tag ==
"!mayfail" )
6579 inline bool isReservedTag(
std::string const& tag ) {
6580 return parseSpecialTag( tag ) ==
TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] );
6583 if( isReservedTag( tag ) ) {
6585 Colour colourGuard( Colour::Red );
6587 <<
"Tag name [" << tag <<
"] not allowed.\n" 6588 <<
"Tag names starting with non alpha-numeric characters are reserved\n";
6591 Colour colourGuard( Colour::FileName );
6592 Catch::cerr() << _lineInfo << std::endl;
6607 std::set<std::string>
tags;
6610 for( std::size_t i = 0; i < _descOrTags.size(); ++i ) {
6611 char c = _descOrTags[i];
6624 enforceNotReservedTag( tag, _lineInfo );
6635 tags.insert(
"hide" );
6639 TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
6640 return TestCase( _testCase, info );
6646 std::set<std::string>
const& _tags,
6649 className( _className ),
6650 description( _description ),
6652 lineInfo( _lineInfo ),
6655 std::ostringstream oss;
6656 for( std::set<std::string>::const_iterator it = _tags.begin(), itEnd = _tags.end(); it != itEnd; ++it ) {
6657 oss <<
"[" << *it <<
"]";
6666 : name( other.name ),
6667 className( other.className ),
6668 description( other.description ),
6672 lineInfo( other.lineInfo ),
6698 other.name = _newName;
6704 name.swap( other.
name );
6707 tags.swap( other.
tags );
6711 std::swap( lineInfo, other.
lineInfo );
6719 return test.get() == other.
test.get() &&
6720 name == other.
name &&
6725 return name < other.
name;
6741 #define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED 6746 (
unsigned int _majorVersion,
6747 unsigned int _minorVersion,
6748 unsigned int _patchNumber,
6750 unsigned int _buildNumber )
6751 : majorVersion( _majorVersion ),
6752 minorVersion( _minorVersion ),
6753 patchNumber( _patchNumber ),
6754 branchName( _branchName ),
6755 buildNumber( _buildNumber )
6758 std::ostream&
operator << ( std::ostream& os, Version
const& version ) {
6759 os << version.majorVersion <<
"." 6760 << version.minorVersion <<
"." 6761 << version.patchNumber;
6763 if( !version.branchName.empty() ) {
6764 os <<
"-" << version.branchName
6765 <<
"." << version.buildNumber;
6770 Version libraryVersion( 1, 2, 1,
"", 0 );
6775 #define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED 6782 : macroName( _macroName ),
6783 lineInfo( _lineInfo ),
6785 sequence( ++globalCount )
6794 : m_info( builder.m_info )
6796 m_info.message = builder.
m_stream.str();
6800 : m_info( other.m_info )
6810 #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED 6813 #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED 6819 virtual ~IReporter();
6821 virtual bool shouldRedirectStdout()
const = 0;
6823 virtual void StartTesting() = 0;
6824 virtual void EndTesting(
Totals const& totals ) = 0;
6825 virtual void StartGroup(
std::string const& groupName ) = 0;
6826 virtual void EndGroup(
std::string const& groupName,
Totals const& totals ) = 0;
6827 virtual void StartTestCase(
TestCaseInfo const& testInfo ) = 0;
6830 virtual void EndSection(
std::string const& sectionName,
Counts const& assertions ) = 0;
6831 virtual void NoAssertionsInSection(
std::string const& sectionName ) = 0;
6832 virtual void NoAssertionsInTestCase(
std::string const& testName ) = 0;
6833 virtual void Aborted() = 0;
6837 class LegacyReporterAdapter :
public SharedImpl<IStreamingReporter>
6841 virtual ~LegacyReporterAdapter();
6843 virtual ReporterPreferences getPreferences()
const;
6844 virtual void noMatchingTestCases(
std::string const& );
6845 virtual void testRunStarting( TestRunInfo
const& );
6846 virtual void testGroupStarting( GroupInfo
const& groupInfo );
6847 virtual void testCaseStarting(
TestCaseInfo const& testInfo );
6848 virtual void sectionStarting(
SectionInfo const& sectionInfo );
6850 virtual bool assertionEnded( AssertionStats
const& assertionStats );
6851 virtual void sectionEnded( SectionStats
const& sectionStats );
6852 virtual void testCaseEnded( TestCaseStats
const& testCaseStats );
6853 virtual void testGroupEnded( TestGroupStats
const& testGroupStats );
6854 virtual void testRunEnded( TestRunStats
const& testRunStats );
6864 LegacyReporterAdapter::LegacyReporterAdapter(
Ptr<IReporter> const& legacyReporter )
6865 : m_legacyReporter( legacyReporter )
6867 LegacyReporterAdapter::~LegacyReporterAdapter() {}
6869 ReporterPreferences LegacyReporterAdapter::getPreferences()
const {
6870 ReporterPreferences prefs;
6871 prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();
6875 void LegacyReporterAdapter::noMatchingTestCases(
std::string const& ) {}
6876 void LegacyReporterAdapter::testRunStarting( TestRunInfo
const& ) {
6877 m_legacyReporter->StartTesting();
6879 void LegacyReporterAdapter::testGroupStarting( GroupInfo
const& groupInfo ) {
6880 m_legacyReporter->StartGroup( groupInfo.name );
6882 void LegacyReporterAdapter::testCaseStarting(
TestCaseInfo const& testInfo ) {
6883 m_legacyReporter->StartTestCase( testInfo );
6885 void LegacyReporterAdapter::sectionStarting(
SectionInfo const& sectionInfo ) {
6886 m_legacyReporter->StartSection( sectionInfo.
name, sectionInfo.
description );
6888 void LegacyReporterAdapter::assertionStarting(
AssertionInfo const& ) {
6892 bool LegacyReporterAdapter::assertionEnded( AssertionStats
const& assertionStats ) {
6893 if( assertionStats.assertionResult.getResultType() !=
ResultWas::Ok ) {
6894 for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
6902 m_legacyReporter->Result( result );
6906 m_legacyReporter->Result( assertionStats.assertionResult );
6909 void LegacyReporterAdapter::sectionEnded( SectionStats
const& sectionStats ) {
6910 if( sectionStats.missingAssertions )
6911 m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );
6912 m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );
6914 void LegacyReporterAdapter::testCaseEnded( TestCaseStats
const& testCaseStats ) {
6915 m_legacyReporter->EndTestCase
6916 ( testCaseStats.testInfo,
6917 testCaseStats.totals,
6918 testCaseStats.stdOut,
6919 testCaseStats.stdErr );
6921 void LegacyReporterAdapter::testGroupEnded( TestGroupStats
const& testGroupStats ) {
6922 if( testGroupStats.aborting )
6923 m_legacyReporter->Aborted();
6924 m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );
6926 void LegacyReporterAdapter::testRunEnded( TestRunStats
const& testRunStats ) {
6927 m_legacyReporter->EndTesting( testRunStats.totals );
6929 void LegacyReporterAdapter::skipTest(
TestCaseInfo const& ) {
6936 #pragma clang diagnostic push 6937 #pragma clang diagnostic ignored "-Wc++11-long-long" 6940 #ifdef CATCH_PLATFORM_WINDOWS 6941 #include <windows.h> 6943 #include <sys/time.h> 6949 #ifdef CATCH_PLATFORM_WINDOWS 6950 uint64_t getCurrentTicks() {
6951 static uint64_t hz=0, hzo=0;
6953 QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );
6954 QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );
6957 QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );
6958 return ((t-hzo)*1000000)/hz;
6961 uint64_t getCurrentTicks() {
6963 gettimeofday(&t,NULL);
6964 return static_cast<uint64_t
>( t.tv_sec ) * 1000000ull + static_cast<uint64_t>( t.tv_usec );
6970 m_ticks = getCurrentTicks();
6973 return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
6976 return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
6979 return getElapsedMicroseconds()/1000000.0;
6985 #pragma clang diagnostic pop 6988 #define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED 6993 return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
6996 return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
6999 return s.find( infix ) != std::string::npos;
7010 static char const* whitespaceChars =
"\n\r\t ";
7011 std::string::size_type
start = str.find_first_not_of( whitespaceChars );
7012 std::string::size_type
end = str.find_last_not_of( whitespaceChars );
7014 return start != std::string::npos ? str.substr( start, 1+end-start ) :
"";
7018 bool replaced =
false;
7019 std::size_t i = str.find( replaceThis );
7020 while( i != std::string::npos ) {
7022 str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
7023 if( i < str.size()-withThis.size() )
7024 i = str.find( replaceThis, i+withThis.size() );
7026 i = std::string::npos;
7049 : file( other.file ),
7053 return file.empty();
7056 return line == other.
line && file == other.
file;
7059 return line < other.
line || ( line == other.
line && file < other.
file );
7064 os << info.
file <<
"(" << info.
line <<
")";
7066 os << info.
file <<
":" << info.
line;
7072 std::ostringstream oss;
7073 oss << locationInfo <<
": Internal Catch error: '" << message <<
"'";
7075 throw std::logic_error( oss.str() );
7080 #define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED 7089 description( _description ),
7090 lineInfo( _lineInfo )
7095 m_sectionIncluded(
getResultCapture().sectionStarted( m_info, m_assertions ) )
7101 if( m_sectionIncluded )
7106 Section::operator bool()
const {
7107 return m_sectionIncluded;
7113 #define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED 7117 #ifdef CATCH_PLATFORM_MAC 7120 #include <stdbool.h> 7121 #include <sys/types.h> 7123 #include <sys/sysctl.h> 7135 struct kinfo_proc info;
7141 info.kp_proc.p_flag = 0;
7148 mib[2] = KERN_PROC_PID;
7153 size =
sizeof(info);
7154 if( sysctl(mib,
sizeof(mib) /
sizeof(*mib), &info, &size, NULL, 0) != 0 ) {
7155 Catch::cerr() <<
"\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
7161 return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
7165 #elif defined(_MSC_VER) 7166 extern "C" __declspec(dllimport)
int __stdcall IsDebuggerPresent();
7169 return IsDebuggerPresent() != 0;
7172 #elif defined(__MINGW32__) 7173 extern "C" __declspec(dllimport)
int __stdcall IsDebuggerPresent();
7176 return IsDebuggerPresent() != 0;
7185 #ifdef CATCH_PLATFORM_WINDOWS 7186 extern "C" __declspec(dllimport)
void __stdcall OutputDebugStringA( const
char* );
7189 ::OutputDebugStringA( text.c_str() );
7196 Catch::cout() << text;
7202 #define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED 7212 enum Arch { Big, Little };
7214 static Arch which() {
7217 char asChar[sizeof (int)];
7221 return ( u.asChar[
sizeof(
int)-1] == 1 ) ? Big : Little;
7229 int i = 0, end =
static_cast<int>(
size ), inc = 1;
7230 if( Endianness::which() == Endianness::Little ) {
7235 unsigned char const *bytes =
static_cast<unsigned char const *
>(
object);
7236 std::ostringstream os;
7237 os <<
"0x" << std::setfill(
'0') << std::hex;
7238 for( ; i !=
end; i += inc )
7239 os <<
std::setw(2) << static_cast<unsigned>(bytes[i]);
7247 for(
size_t i = 0; i < s.size(); ++i ) {
7250 case '\n': subs =
"\\n";
break;
7251 case '\t': subs =
"\\t";
break;
7254 if( !subs.empty() ) {
7255 s = s.substr( 0, i ) + subs + s.substr( i+1 );
7260 return "\"" + s + "\"";
7265 s.reserve( value.size() );
7266 for(
size_t i = 0; i < value.size(); ++i )
7267 s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?';
7290 std::ostringstream oss;
7293 oss <<
" (0x" << std::hex << value <<
")";
7298 std::ostringstream oss;
7301 oss <<
" (0x" << std::hex << value <<
")";
7309 template<
typename T>
7311 std::ostringstream oss;
7312 oss << std::setprecision( precision )
7316 std::size_t i = d.find_last_not_of(
'0' );
7317 if( i != std::string::npos && i != d.size()-1 ) {
7320 d = d.substr( 0, i+1 );
7326 return fpToString( value, 10 );
7329 return fpToString( value, 5 ) + "
f";
7333 return value ?
"true" :
"false";
7338 ?
toString( static_cast<unsigned int>( value ) )
7343 return toString( static_cast<char>( value ) );
7347 return toString( static_cast<char>( value ) );
7350 #ifdef CATCH_CONFIG_CPP11_NULLPTR 7360 return "@" +
toString([nsstring UTF8String]);
7365 return "@" +
toString([nsstring UTF8String]);
7368 return toString( [nsObject description] );
7375 #define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED 7381 char const* capturedExpression,
7383 : m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition ),
7384 m_shouldDebugBreak( false ),
7385 m_shouldThrow( false )
7389 m_data.resultType =
result;
7397 m_exprComponents.lhs = lhs;
7401 m_exprComponents.rhs = rhs;
7405 m_exprComponents.op = op;
7410 m_exprComponents.testFalse =
isFalseTest( m_assertionInfo.resultDisposition );
7411 captureExpression();
7415 m_assertionInfo.resultDisposition = resultDisposition;
7421 setResultType( resultType );
7422 captureExpression();
7429 if( !result.
isOk() ) {
7431 m_shouldDebugBreak =
true;
7433 m_shouldThrow =
true;
7451 if( m_exprComponents.testFalse ) {
7458 data.
message = m_stream.oss.str();
7460 if( m_exprComponents.testFalse ) {
7461 if( m_exprComponents.op ==
"" )
7469 if( m_exprComponents.op ==
"" )
7470 return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.op + m_exprComponents.lhs;
7471 else if( m_exprComponents.op ==
"matches" )
7472 return m_exprComponents.lhs + " " + m_exprComponents.rhs;
7473 else if( m_exprComponents.op !=
"!" ) {
7474 if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 &&
7475 m_exprComponents.lhs.find("\
n") ==
std::string::npos &&
7476 m_exprComponents.rhs.find("\
n") == std::string::npos )
7477 return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs;
7479 return m_exprComponents.lhs + "\
n" + m_exprComponents.op + "\
n" + m_exprComponents.rhs;
7482 return "{can't expand - use " + m_assertionInfo.macroName + "_FALSE( " + m_assertionInfo.capturedExpression.substr(1) + " ) instead of " + m_assertionInfo.macroName + "( " + m_assertionInfo.capturedExpression + " ) for better diagnostics}";
7488 #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED 7491 #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED 7499 virtual ~TagAliasRegistry();
7502 void add(
char const* alias,
char const* tag,
SourceLineInfo const& lineInfo );
7503 static TagAliasRegistry&
get();
7506 std::map<std::string, TagAlias> m_registry;
7516 TagAliasRegistry::~TagAliasRegistry() {}
7519 std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias );
7520 if( it != m_registry.end() )
7527 std::string expandedTestSpec = unexpandedTestSpec;
7528 for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end();
7531 std::size_t pos = expandedTestSpec.find( it->first );
7532 if( pos != std::string::npos ) {
7533 expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
7535 expandedTestSpec.substr( pos + it->first.size() );
7538 return expandedTestSpec;
7541 void TagAliasRegistry::add(
char const* alias,
char const* tag,
SourceLineInfo const& lineInfo ) {
7544 std::ostringstream oss;
7545 oss <<
"error: tag alias, \"" << alias <<
"\" is not of the form [@alias name].\n" <<
lineInfo;
7546 throw std::domain_error( oss.str().c_str() );
7548 if( !m_registry.insert( std::make_pair( alias,
TagAlias( tag, lineInfo ) ) ).second ) {
7549 std::ostringstream oss;
7550 oss <<
"error: tag alias, \"" << alias <<
"\" already registered.\n" 7551 <<
"\tFirst seen at " << find(alias)->lineInfo <<
"\n" 7553 throw std::domain_error( oss.str().c_str() );
7557 TagAliasRegistry& TagAliasRegistry::get() {
7558 static TagAliasRegistry instance;
7568 TagAliasRegistry::get().add( alias, tag, lineInfo );
7570 catch( std::exception& ex ) {
7571 Colour colourGuard( Colour::Red );
7572 Catch::cerr() << ex.what() << std::endl;
7580 #define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED 7583 #define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED 7589 struct StreamingReporterBase :
SharedImpl<IStreamingReporter> {
7591 StreamingReporterBase( ReporterConfig
const& _config )
7592 : m_config( _config.fullConfig() ),
7593 stream( _config.stream() )
7596 virtual ~StreamingReporterBase();
7598 virtual void noMatchingTestCases(
std::string const& ) {}
7600 virtual void testRunStarting( TestRunInfo
const& _testRunInfo ) {
7601 currentTestRunInfo = _testRunInfo;
7603 virtual void testGroupStarting( GroupInfo
const& _groupInfo ) {
7604 currentGroupInfo = _groupInfo;
7607 virtual void testCaseStarting(
TestCaseInfo const& _testInfo ) {
7608 currentTestCaseInfo = _testInfo;
7610 virtual void sectionStarting(
SectionInfo const& _sectionInfo ) {
7611 m_sectionStack.push_back( _sectionInfo );
7614 virtual void sectionEnded( SectionStats
const& ) {
7615 m_sectionStack.pop_back();
7617 virtual void testCaseEnded( TestCaseStats
const& ) {
7618 currentTestCaseInfo.reset();
7620 virtual void testGroupEnded( TestGroupStats
const& ) {
7621 currentGroupInfo.reset();
7623 virtual void testRunEnded( TestRunStats
const& ) {
7624 currentTestCaseInfo.reset();
7625 currentGroupInfo.reset();
7626 currentTestRunInfo.reset();
7637 LazyStat<TestRunInfo> currentTestRunInfo;
7638 LazyStat<GroupInfo> currentGroupInfo;
7639 LazyStat<TestCaseInfo> currentTestCaseInfo;
7641 std::vector<SectionInfo> m_sectionStack;
7644 struct CumulativeReporterBase :
SharedImpl<IStreamingReporter> {
7645 template<
typename T,
typename ChildNodeT>
7647 explicit Node( T
const& _value ) : value( _value ) {}
7650 typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
7652 ChildNodes children;
7655 explicit SectionNode( SectionStats
const& _stats ) : stats( _stats ) {}
7656 virtual ~SectionNode();
7658 bool operator == ( SectionNode
const& other )
const {
7659 return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
7666 typedef std::vector<Ptr<SectionNode> > ChildSections;
7667 typedef std::vector<AssertionStats> Assertions;
7668 ChildSections childSections;
7669 Assertions assertions;
7674 struct BySectionInfo {
7675 BySectionInfo(
SectionInfo const& other ) : m_other( other ) {}
7676 BySectionInfo( BySectionInfo
const& other ) : m_other( other.m_other ) {}
7678 return node->stats.sectionInfo.lineInfo == m_other.lineInfo;
7685 typedef Node<TestCaseStats, SectionNode> TestCaseNode;
7686 typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;
7687 typedef Node<TestRunStats, TestGroupNode> TestRunNode;
7689 CumulativeReporterBase( ReporterConfig
const& _config )
7690 : m_config( _config.fullConfig() ),
7691 stream( _config.stream() )
7693 ~CumulativeReporterBase();
7695 virtual void testRunStarting( TestRunInfo
const& ) {}
7696 virtual void testGroupStarting( GroupInfo
const& ) {}
7698 virtual void testCaseStarting(
TestCaseInfo const& ) {}
7700 virtual void sectionStarting(
SectionInfo const& sectionInfo ) {
7701 SectionStats incompleteStats( sectionInfo,
Counts(), 0,
false );
7703 if( m_sectionStack.empty() ) {
7704 if( !m_rootSection )
7705 m_rootSection =
new SectionNode( incompleteStats );
7706 node = m_rootSection;
7709 SectionNode& parentNode = *m_sectionStack.back();
7710 SectionNode::ChildSections::const_iterator it =
7711 std::find_if( parentNode.childSections.begin(),
7712 parentNode.childSections.end(),
7713 BySectionInfo( sectionInfo ) );
7714 if( it == parentNode.childSections.end() ) {
7715 node =
new SectionNode( incompleteStats );
7716 parentNode.childSections.push_back( node );
7721 m_sectionStack.push_back( node );
7722 m_deepestSection = node;
7727 virtual bool assertionEnded( AssertionStats
const& assertionStats ) {
7728 assert( !m_sectionStack.empty() );
7729 SectionNode& sectionNode = *m_sectionStack.back();
7730 sectionNode.assertions.push_back( assertionStats );
7733 virtual void sectionEnded( SectionStats
const& sectionStats ) {
7734 assert( !m_sectionStack.empty() );
7735 SectionNode& node = *m_sectionStack.back();
7736 node.stats = sectionStats;
7737 m_sectionStack.pop_back();
7739 virtual void testCaseEnded( TestCaseStats
const& testCaseStats ) {
7741 assert( m_sectionStack.size() == 0 );
7742 node->children.push_back( m_rootSection );
7743 m_testCases.push_back( node );
7744 m_rootSection.
reset();
7746 assert( m_deepestSection );
7747 m_deepestSection->stdOut = testCaseStats.stdOut;
7748 m_deepestSection->stdErr = testCaseStats.stdErr;
7750 virtual void testGroupEnded( TestGroupStats
const& testGroupStats ) {
7752 node->children.
swap( m_testCases );
7753 m_testGroups.push_back( node );
7755 virtual void testRunEnded( TestRunStats
const& testRunStats ) {
7757 node->children.
swap( m_testGroups );
7758 m_testRuns.push_back( node );
7759 testRunEndedCumulative();
7761 virtual void testRunEndedCumulative() = 0;
7767 std::vector<AssertionStats> m_assertions;
7768 std::vector<std::vector<Ptr<SectionNode> > > m_sections;
7769 std::vector<Ptr<TestCaseNode> > m_testCases;
7770 std::vector<Ptr<TestGroupNode> > m_testGroups;
7772 std::vector<Ptr<TestRunNode> > m_testRuns;
7776 std::vector<Ptr<SectionNode> > m_sectionStack;
7781 char const* getLineOfChars() {
7782 static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
7784 memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
7785 line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
7793 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED 7797 template<
typename T>
7798 class LegacyReporterRegistrar {
7800 class ReporterFactory :
public IReporterFactory {
7801 virtual IStreamingReporter* create( ReporterConfig
const& config )
const {
7802 return new LegacyReporterAdapter(
new T( config ) );
7806 return T::getDescription();
7812 LegacyReporterRegistrar(
std::string const& name ) {
7817 template<
typename T>
7818 class ReporterRegistrar {
7820 class ReporterFactory :
public IReporterFactory {
7833 virtual IStreamingReporter* create( ReporterConfig
const& config )
const {
7834 return new T( config );
7838 return T::getDescription();
7850 #define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \ 7851 namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } 7852 #define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \ 7853 namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } 7856 #define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED 7867 class ScopedElement {
7869 ScopedElement( XmlWriter* writer )
7870 : m_writer( writer )
7873 ScopedElement( ScopedElement
const& other )
7874 : m_writer( other.m_writer ){
7875 other.m_writer = NULL;
7880 m_writer->endElement();
7883 ScopedElement& writeText(
std::string const& text,
bool indent =
true ) {
7884 m_writer->writeText( text, indent );
7888 template<
typename T>
7889 ScopedElement& writeAttribute(
std::string const& name, T
const& attribute ) {
7890 m_writer->writeAttribute( name, attribute );
7895 mutable XmlWriter* m_writer;
7899 : m_tagIsOpen( false ),
7900 m_needsNewline( false ),
7901 m_os( &Catch::cout() )
7904 XmlWriter( std::ostream& os )
7905 : m_tagIsOpen( false ),
7906 m_needsNewline( false ),
7911 while( !m_tags.empty() )
7915 XmlWriter& startElement(
std::string const& name ) {
7917 newlineIfNecessary();
7919 m_tags.push_back( name );
7925 ScopedElement scopedElement(
std::string const& name ) {
7926 ScopedElement scoped(
this );
7927 startElement( name );
7931 XmlWriter& endElement() {
7932 newlineIfNecessary();
7933 m_indent = m_indent.substr( 0, m_indent.size()-2 );
7936 m_tagIsOpen =
false;
7939 stream() << m_indent <<
"</" << m_tags.back() <<
">\n";
7946 if( !name.empty() && !attribute.empty() ) {
7947 stream() <<
" " << name <<
"=\"";
7948 writeEncodedText( attribute );
7954 XmlWriter& writeAttribute(
std::string const& name,
bool attribute ) {
7955 stream() <<
" " << name <<
"=\"" << ( attribute ?
"true" :
"false" ) <<
"\"";
7959 template<
typename T>
7960 XmlWriter& writeAttribute(
std::string const& name, T
const& attribute ) {
7962 stream() <<
" " << name <<
"=\"" << attribute <<
"\"";
7966 XmlWriter& writeText(
std::string const& text,
bool indent =
true ) {
7967 if( !text.empty() ){
7968 bool tagWasOpen = m_tagIsOpen;
7970 if( tagWasOpen && indent )
7972 writeEncodedText( text );
7973 m_needsNewline =
true;
7978 XmlWriter& writeComment(
std::string const& text ) {
7980 stream() << m_indent <<
"<!--" << text <<
"-->";
7981 m_needsNewline =
true;
7985 XmlWriter& writeBlankLine() {
7991 void setStream( std::ostream& os ) {
7996 XmlWriter( XmlWriter
const& );
8003 void ensureTagClosed() {
8006 m_tagIsOpen =
false;
8010 void newlineIfNecessary() {
8011 if( m_needsNewline ) {
8013 m_needsNewline =
false;
8017 void writeEncodedText(
std::string const& text ) {
8018 static const char* charsToEncode =
"<&\"";
8020 std::string::size_type pos = mtext.find_first_of( charsToEncode );
8021 while( pos != std::string::npos ) {
8022 stream() << mtext.substr( 0, pos );
8024 switch( mtext[pos] ) {
8035 mtext = mtext.substr( pos+1 );
8036 pos = mtext.find_first_of( charsToEncode );
8042 bool m_needsNewline;
8043 std::vector<std::string> m_tags;
8050 class XmlReporter :
public StreamingReporterBase {
8052 XmlReporter( ReporterConfig
const& _config )
8053 : StreamingReporterBase( _config ),
8057 virtual ~XmlReporter();
8060 return "Reports test results as an XML document";
8064 virtual ReporterPreferences getPreferences()
const {
8065 ReporterPreferences prefs;
8066 prefs.shouldRedirectStdOut =
true;
8070 virtual void noMatchingTestCases(
std::string const& s ) {
8071 StreamingReporterBase::noMatchingTestCases( s );
8074 virtual void testRunStarting( TestRunInfo
const& testInfo ) {
8075 StreamingReporterBase::testRunStarting( testInfo );
8076 m_xml.setStream( stream );
8077 m_xml.startElement(
"Catch" );
8078 if( !m_config->name().empty() )
8079 m_xml.writeAttribute(
"name", m_config->name() );
8082 virtual void testGroupStarting( GroupInfo
const& groupInfo ) {
8083 StreamingReporterBase::testGroupStarting( groupInfo );
8084 m_xml.startElement(
"Group" )
8085 .writeAttribute(
"name", groupInfo.name );
8088 virtual void testCaseStarting(
TestCaseInfo const& testInfo ) {
8089 StreamingReporterBase::testCaseStarting(testInfo);
8090 m_xml.startElement(
"TestCase" ).writeAttribute(
"name",
trim( testInfo.
name ) );
8092 if ( m_config->showDurations() == ShowDurations::Always )
8093 m_testCaseTimer.start();
8096 virtual void sectionStarting(
SectionInfo const& sectionInfo ) {
8097 StreamingReporterBase::sectionStarting( sectionInfo );
8098 if( m_sectionDepth++ > 0 ) {
8099 m_xml.startElement(
"Section" )
8100 .writeAttribute(
"name",
trim( sectionInfo.
name ) )
8101 .writeAttribute(
"description", sectionInfo.
description );
8107 virtual bool assertionEnded( AssertionStats
const& assertionStats ) {
8108 const AssertionResult& assertionResult = assertionStats.assertionResult;
8111 if( assertionStats.assertionResult.getResultType() !=
ResultWas::Ok ) {
8112 for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
8116 m_xml.scopedElement(
"Info" )
8117 .writeText( it->message );
8119 m_xml.scopedElement(
"Warning" )
8120 .writeText( it->message );
8126 if( !m_config->includeSuccessfulResults() &&
isOk(assertionResult.
getResultType()) )
8131 m_xml.startElement(
"Expression" )
8132 .writeAttribute(
"success", assertionResult.
succeeded() )
8137 m_xml.scopedElement(
"Original" )
8139 m_xml.scopedElement(
"Expanded" )
8146 m_xml.scopedElement(
"Exception" )
8152 m_xml.scopedElement(
"Fatal Error Condition" )
8158 m_xml.scopedElement(
"Info" )
8165 m_xml.scopedElement(
"Failure" )
8178 virtual void sectionEnded( SectionStats
const& sectionStats ) {
8179 StreamingReporterBase::sectionEnded( sectionStats );
8180 if( --m_sectionDepth > 0 ) {
8181 XmlWriter::ScopedElement
e = m_xml.scopedElement(
"OverallResults" );
8182 e.writeAttribute(
"successes", sectionStats.assertions.passed );
8183 e.writeAttribute(
"failures", sectionStats.assertions.failed );
8184 e.writeAttribute(
"expectedFailures", sectionStats.assertions.failedButOk );
8186 if ( m_config->showDurations() == ShowDurations::Always )
8187 e.writeAttribute(
"durationInSeconds", sectionStats.durationInSeconds );
8193 virtual void testCaseEnded( TestCaseStats
const& testCaseStats ) {
8194 StreamingReporterBase::testCaseEnded( testCaseStats );
8195 XmlWriter::ScopedElement e = m_xml.scopedElement(
"OverallResult" );
8196 e.writeAttribute(
"success", testCaseStats.totals.assertions.allOk() );
8198 if ( m_config->showDurations() == ShowDurations::Always )
8199 e.writeAttribute(
"durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
8204 virtual void testGroupEnded( TestGroupStats
const& testGroupStats ) {
8205 StreamingReporterBase::testGroupEnded( testGroupStats );
8207 m_xml.scopedElement(
"OverallResults" )
8208 .writeAttribute(
"successes", testGroupStats.totals.assertions.passed )
8209 .writeAttribute(
"failures", testGroupStats.totals.assertions.failed )
8210 .writeAttribute(
"expectedFailures", testGroupStats.totals.assertions.failedButOk );
8214 virtual void testRunEnded( TestRunStats
const& testRunStats ) {
8215 StreamingReporterBase::testRunEnded( testRunStats );
8216 m_xml.scopedElement(
"OverallResults" )
8217 .writeAttribute(
"successes", testRunStats.totals.assertions.passed )
8218 .writeAttribute(
"failures", testRunStats.totals.assertions.failed )
8219 .writeAttribute(
"expectedFailures", testRunStats.totals.assertions.failedButOk );
8224 Timer m_testCaseTimer;
8229 INTERNAL_CATCH_REGISTER_REPORTER(
"xml", XmlReporter )
8234 #define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED 8240 class JunitReporter :
public CumulativeReporterBase {
8242 JunitReporter( ReporterConfig
const& _config )
8243 : CumulativeReporterBase( _config ),
8244 xml( _config.stream() )
8250 return "Reports test results in an XML format that looks like Ant's junitreport target";
8253 virtual void noMatchingTestCases(
std::string const& ) {}
8255 virtual ReporterPreferences getPreferences()
const {
8256 ReporterPreferences prefs;
8257 prefs.shouldRedirectStdOut =
true;
8261 virtual void testRunStarting( TestRunInfo
const& runInfo ) {
8262 CumulativeReporterBase::testRunStarting( runInfo );
8263 xml.startElement(
"testsuites" );
8266 virtual void testGroupStarting( GroupInfo
const& groupInfo ) {
8268 stdOutForSuite.str(
"");
8269 stdErrForSuite.str(
"");
8270 unexpectedExceptions = 0;
8271 CumulativeReporterBase::testGroupStarting( groupInfo );
8274 virtual bool assertionEnded( AssertionStats
const& assertionStats ) {
8276 unexpectedExceptions++;
8277 return CumulativeReporterBase::assertionEnded( assertionStats );
8280 virtual void testCaseEnded( TestCaseStats
const& testCaseStats ) {
8281 stdOutForSuite << testCaseStats.stdOut;
8282 stdErrForSuite << testCaseStats.stdErr;
8283 CumulativeReporterBase::testCaseEnded( testCaseStats );
8286 virtual void testGroupEnded( TestGroupStats
const& testGroupStats ) {
8287 double suiteTime = suiteTimer.getElapsedSeconds();
8288 CumulativeReporterBase::testGroupEnded( testGroupStats );
8289 writeGroup( *m_testGroups.back(), suiteTime );
8292 virtual void testRunEndedCumulative() {
8296 void writeGroup( TestGroupNode
const& groupNode,
double suiteTime ) {
8297 XmlWriter::ScopedElement e = xml.scopedElement(
"testsuite" );
8298 TestGroupStats
const& stats = groupNode.value;
8299 xml.writeAttribute(
"name", stats.groupInfo.name );
8300 xml.writeAttribute(
"errors", unexpectedExceptions );
8301 xml.writeAttribute(
"failures", stats.totals.assertions.failed-unexpectedExceptions );
8302 xml.writeAttribute(
"tests", stats.totals.assertions.total() );
8303 xml.writeAttribute(
"hostname",
"tbd" );
8304 if( m_config->showDurations() == ShowDurations::Never )
8305 xml.writeAttribute(
"time",
"" );
8307 xml.writeAttribute(
"time", suiteTime );
8308 xml.writeAttribute(
"timestamp",
"tbd" );
8311 for( TestGroupNode::ChildNodes::const_iterator
8312 it = groupNode.children.begin(), itEnd = groupNode.children.end();
8315 writeTestCase( **it );
8317 xml.scopedElement(
"system-out" ).writeText(
trim( stdOutForSuite.str() ),
false );
8318 xml.scopedElement(
"system-err" ).writeText(
trim( stdErrForSuite.str() ),
false );
8321 void writeTestCase( TestCaseNode
const& testCaseNode ) {
8322 TestCaseStats
const& stats = testCaseNode.value;
8326 assert( testCaseNode.children.size() == 1 );
8327 SectionNode
const& rootSection = *testCaseNode.children.front();
8331 if( className.empty() ) {
8332 if( rootSection.childSections.empty() )
8333 className =
"global";
8335 writeSection( className,
"", rootSection );
8340 SectionNode
const& sectionNode ) {
8342 if( !rootName.empty() )
8343 name = rootName +
"/" + name;
8345 if( !sectionNode.assertions.empty() ||
8346 !sectionNode.stdOut.empty() ||
8347 !sectionNode.stdErr.empty() ) {
8348 XmlWriter::ScopedElement e = xml.scopedElement(
"testcase" );
8349 if( className.empty() ) {
8350 xml.writeAttribute(
"classname", name );
8351 xml.writeAttribute(
"name",
"root" );
8354 xml.writeAttribute(
"classname", className );
8355 xml.writeAttribute(
"name", name );
8357 xml.writeAttribute(
"time",
Catch::toString( sectionNode.stats.durationInSeconds ) );
8359 writeAssertions( sectionNode );
8361 if( !sectionNode.stdOut.empty() )
8362 xml.scopedElement(
"system-out" ).writeText(
trim( sectionNode.stdOut ),
false );
8363 if( !sectionNode.stdErr.empty() )
8364 xml.scopedElement(
"system-err" ).writeText(
trim( sectionNode.stdErr ),
false );
8366 for( SectionNode::ChildSections::const_iterator
8367 it = sectionNode.childSections.begin(),
8368 itEnd = sectionNode.childSections.end();
8371 if( className.empty() )
8372 writeSection( name, "", **it );
8374 writeSection( className, name, **it );
8377 void writeAssertions( SectionNode
const& sectionNode ) {
8378 for( SectionNode::Assertions::const_iterator
8379 it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();
8382 writeAssertion( *it );
8384 void writeAssertion( AssertionStats
const& stats ) {
8386 if( !result.
isOk() ) {
8391 elementName =
"error";
8394 elementName =
"failure";
8397 elementName =
"failure";
8400 elementName =
"failure";
8410 elementName =
"internalError";
8414 XmlWriter::ScopedElement e = xml.scopedElement( elementName );
8419 std::ostringstream oss;
8422 for( std::vector<MessageInfo>::const_iterator
8423 it = stats.infoMessages.begin(),
8424 itEnd = stats.infoMessages.end();
8428 oss << it->message << "\n";
8431 xml.writeText( oss.str(), false );
8437 std::ostringstream stdOutForSuite;
8438 std::ostringstream stdErrForSuite;
8439 unsigned int unexpectedExceptions;
8442 INTERNAL_CATCH_REGISTER_REPORTER(
"junit", JunitReporter )
8447 #define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED 8451 struct ConsoleReporter : StreamingReporterBase {
8452 ConsoleReporter( ReporterConfig
const& _config )
8453 : StreamingReporterBase( _config ),
8454 m_headerPrinted( false )
8457 virtual ~ConsoleReporter();
8459 return "Reports test results as plain lines of text";
8461 virtual ReporterPreferences getPreferences()
const {
8462 ReporterPreferences prefs;
8463 prefs.shouldRedirectStdOut =
false;
8467 virtual void noMatchingTestCases(
std::string const& spec ) {
8468 stream <<
"No test cases matched '" << spec <<
"'" << std::endl;
8474 virtual bool assertionEnded( AssertionStats
const& _assertionStats ) {
8477 bool printInfoMessages =
true;
8480 if( !m_config->includeSuccessfulResults() && result.
isOk() ) {
8483 printInfoMessages =
false;
8488 AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
8490 stream << std::endl;
8494 virtual void sectionStarting(
SectionInfo const& _sectionInfo ) {
8495 m_headerPrinted =
false;
8496 StreamingReporterBase::sectionStarting( _sectionInfo );
8498 virtual void sectionEnded( SectionStats
const& _sectionStats ) {
8499 if( _sectionStats.missingAssertions ) {
8501 Colour colour( Colour::ResultError );
8502 if( m_sectionStack.size() > 1 )
8503 stream <<
"\nNo assertions in section";
8505 stream <<
"\nNo assertions in test case";
8506 stream <<
" '" << _sectionStats.sectionInfo.name <<
"'\n" << std::endl;
8508 if( m_headerPrinted ) {
8509 if( m_config->showDurations() == ShowDurations::Always )
8510 stream <<
"Completed in " << _sectionStats.durationInSeconds <<
"s" << std::endl;
8511 m_headerPrinted =
false;
8514 if( m_config->showDurations() == ShowDurations::Always )
8515 stream << _sectionStats.sectionInfo.name <<
" completed in " << _sectionStats.durationInSeconds <<
"s" << std::endl;
8517 StreamingReporterBase::sectionEnded( _sectionStats );
8520 virtual void testCaseEnded( TestCaseStats
const& _testCaseStats ) {
8521 StreamingReporterBase::testCaseEnded( _testCaseStats );
8522 m_headerPrinted =
false;
8524 virtual void testGroupEnded( TestGroupStats
const& _testGroupStats ) {
8525 if( currentGroupInfo.used ) {
8526 printSummaryDivider();
8527 stream <<
"Summary for group '" << _testGroupStats.groupInfo.name <<
"':\n";
8528 printTotals( _testGroupStats.totals );
8529 stream <<
"\n" << std::endl;
8531 StreamingReporterBase::testGroupEnded( _testGroupStats );
8533 virtual void testRunEnded( TestRunStats
const& _testRunStats ) {
8534 printTotalsDivider( _testRunStats.totals );
8535 printTotals( _testRunStats.totals );
8536 stream << std::endl;
8537 StreamingReporterBase::testRunEnded( _testRunStats );
8542 class AssertionPrinter {
8543 void operator= ( AssertionPrinter
const& );
8545 AssertionPrinter( std::ostream& _stream, AssertionStats
const& _stats,
bool _printInfoMessages )
8546 : stream( _stream ),
8548 result( _stats.assertionResult ),
8549 colour( Colour::
None ),
8550 message( result.getMessage() ),
8551 messages( _stats.infoMessages ),
8552 printInfoMessages( _printInfoMessages )
8556 colour = Colour::Success;
8557 passOrFail =
"PASSED";
8559 if( _stats.infoMessages.size() == 1 )
8560 messageLabel =
"with message";
8561 if( _stats.infoMessages.size() > 1 )
8562 messageLabel =
"with messages";
8565 if( result.
isOk() ) {
8566 colour = Colour::Success;
8567 passOrFail =
"FAILED - but was ok";
8570 colour = Colour::Error;
8571 passOrFail =
"FAILED";
8573 if( _stats.infoMessages.size() == 1 )
8574 messageLabel =
"with message";
8575 if( _stats.infoMessages.size() > 1 )
8576 messageLabel =
"with messages";
8579 colour = Colour::Error;
8580 passOrFail =
"FAILED";
8581 messageLabel =
"due to unexpected exception with message";
8584 colour = Colour::Error;
8585 passOrFail =
"FAILED";
8586 messageLabel =
"due to a fatal error condition";
8589 colour = Colour::Error;
8590 passOrFail =
"FAILED";
8591 messageLabel =
"because no exception was thrown where one was expected";
8594 messageLabel =
"info";
8597 messageLabel =
"warning";
8600 passOrFail =
"FAILED";
8601 colour = Colour::Error;
8602 if( _stats.infoMessages.size() == 1 )
8603 messageLabel =
"explicitly with message";
8604 if( _stats.infoMessages.size() > 1 )
8605 messageLabel =
"explicitly with messages";
8611 passOrFail =
"** internal error **";
8612 colour = Colour::Error;
8617 void print()
const {
8619 if( stats.totals.assertions.total() > 0 ) {
8623 printOriginalExpression();
8624 printReconstructedExpression();
8633 void printResultType()
const {
8634 if( !passOrFail.empty() ) {
8635 Colour colourGuard( colour );
8636 stream << passOrFail <<
":\n";
8639 void printOriginalExpression()
const {
8641 Colour colourGuard( Colour::OriginalExpression );
8647 void printReconstructedExpression()
const {
8649 stream <<
"with expansion:\n";
8650 Colour colourGuard( Colour::ReconstructedExpression );
8654 void printMessage()
const {
8655 if( !messageLabel.empty() )
8656 stream << messageLabel <<
":" <<
"\n";
8657 for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
8662 stream << Text( it->message, TextAttributes().setIndent(2) ) <<
"\n";
8665 void printSourceInfo()
const {
8666 Colour colourGuard( Colour::FileName );
8671 AssertionStats
const& stats;
8672 AssertionResult
const&
result;
8673 Colour::Code colour;
8677 std::vector<MessageInfo> messages;
8678 bool printInfoMessages;
8683 if( !currentTestRunInfo.used )
8685 if( !currentGroupInfo.used )
8686 lazyPrintGroupInfo();
8688 if( !m_headerPrinted ) {
8689 printTestCaseAndSectionHeader();
8690 m_headerPrinted =
true;
8693 void lazyPrintRunInfo() {
8694 stream <<
"\n" << getLineOfChars<'~'>() <<
"\n";
8695 Colour colour( Colour::SecondaryText );
8696 stream << currentTestRunInfo->name
8697 <<
" is a Catch v" << libraryVersion <<
" host application.\n" 8698 <<
"Run with -? for options\n\n";
8700 if( m_config->rngSeed() != 0 )
8701 stream <<
"Randomness seeded to: " << m_config->rngSeed() <<
"\n\n";
8703 currentTestRunInfo.used =
true;
8705 void lazyPrintGroupInfo() {
8706 if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
8707 printClosedHeader(
"Group: " + currentGroupInfo->name );
8708 currentGroupInfo.used =
true;
8711 void printTestCaseAndSectionHeader() {
8712 assert( !m_sectionStack.empty() );
8713 printOpenHeader( currentTestCaseInfo->name );
8715 if( m_sectionStack.size() > 1 ) {
8716 Colour colourGuard( Colour::Headers );
8718 std::vector<SectionInfo>::const_iterator
8719 it = m_sectionStack.begin()+1,
8720 itEnd = m_sectionStack.end();
8721 for( ; it != itEnd; ++it )
8722 printHeaderString( it->name, 2 );
8725 SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
8727 if( !lineInfo.empty() ){
8728 stream << getLineOfChars<
'-'>() <<
"\n";
8729 Colour colourGuard( Colour::FileName );
8730 stream << lineInfo <<
"\n";
8732 stream << getLineOfChars<
'.'>() <<
"\n" << std::endl;
8735 void printClosedHeader(
std::string const& _name ) {
8736 printOpenHeader( _name );
8737 stream << getLineOfChars<
'.'>() <<
"\n";
8739 void printOpenHeader(
std::string const& _name ) {
8740 stream << getLineOfChars<
'-'>() <<
"\n";
8742 Colour colourGuard( Colour::Headers );
8743 printHeaderString( _name );
8749 void printHeaderString(
std::string const& _string, std::size_t indent = 0 ) {
8750 std::size_t i = _string.find(
": " );
8751 if( i != std::string::npos )
8755 stream << Text( _string, TextAttributes()
8756 .setIndent( indent+i)
8757 .setInitialIndent( indent ) ) <<
"\n";
8760 struct SummaryColumn {
8762 SummaryColumn(
std::string const& _label, Colour::Code _colour )
8766 SummaryColumn addRow( std::size_t count ) {
8767 std::ostringstream oss;
8770 for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {
8771 while( it->size() < row.size() )
8773 while( it->size() > row.size() )
8776 rows.push_back( row );
8781 Colour::Code colour;
8782 std::vector<std::string> rows;
8786 void printTotals( Totals
const& totals ) {
8787 if( totals.testCases.total() == 0 ) {
8788 stream << Colour( Colour::Warning ) <<
"No tests ran\n";
8790 else if( totals.assertions.total() > 0 && totals.assertions.allPassed() ) {
8791 stream << Colour( Colour::ResultSuccess ) <<
"All tests passed";
8793 << pluralise( totals.assertions.passed,
"assertion" ) <<
" in " 8794 << pluralise( totals.testCases.passed,
"test case" ) <<
")" 8799 std::vector<SummaryColumn> columns;
8800 columns.push_back( SummaryColumn(
"", Colour::None )
8801 .addRow( totals.testCases.total() )
8802 .addRow( totals.assertions.total() ) );
8803 columns.push_back( SummaryColumn(
"passed", Colour::Success )
8804 .addRow( totals.testCases.passed )
8805 .addRow( totals.assertions.passed ) );
8806 columns.push_back( SummaryColumn(
"failed", Colour::ResultError )
8807 .addRow( totals.testCases.failed )
8808 .addRow( totals.assertions.failed ) );
8809 columns.push_back( SummaryColumn(
"failed as expected", Colour::ResultExpectedFailure )
8810 .addRow( totals.testCases.failedButOk )
8811 .addRow( totals.assertions.failedButOk ) );
8813 printSummaryRow(
"test cases", columns, 0 );
8814 printSummaryRow(
"assertions", columns, 1 );
8817 void printSummaryRow(
std::string const&
label, std::vector<SummaryColumn>
const& cols, std::size_t row ) {
8818 for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) {
8820 if( it->label.empty() ) {
8821 stream << label <<
": ";
8825 stream << Colour( Colour::Warning ) <<
"- none -";
8827 else if( value !=
"0" ) {
8828 stream << Colour( Colour::LightGrey ) <<
" | ";
8829 stream << Colour( it->colour )
8830 << value <<
" " << it->label;
8836 static std::size_t makeRatio( std::size_t number, std::size_t total ) {
8837 std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0;
8838 return ( ratio == 0 && number > 0 ) ? 1 : ratio;
8840 static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
8841 if( i > j && i > k )
8849 void printTotalsDivider( Totals
const& totals ) {
8850 if( totals.testCases.total() > 0 ) {
8851 std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );
8852 std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );
8853 std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );
8854 while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 )
8855 findMax( failedRatio, failedButOkRatio, passedRatio )++;
8856 while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 )
8857 findMax( failedRatio, failedButOkRatio, passedRatio )--;
8859 stream << Colour( Colour::Error ) <<
std::string( failedRatio,
'=' );
8860 stream << Colour( Colour::ResultExpectedFailure ) <<
std::string( failedButOkRatio,
'=' );
8861 if( totals.testCases.allPassed() )
8862 stream << Colour( Colour::ResultSuccess ) <<
std::string( passedRatio,
'=' );
8864 stream << Colour( Colour::Success ) <<
std::string( passedRatio,
'=' );
8867 stream << Colour( Colour::Warning ) <<
std::string( CATCH_CONFIG_CONSOLE_WIDTH-1,
'=' );
8871 void printSummaryDivider() {
8872 stream << getLineOfChars<
'-'>() <<
"\n";
8876 bool m_headerPrinted;
8879 INTERNAL_CATCH_REGISTER_REPORTER(
"console", ConsoleReporter )
8884 #define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED 8888 struct CompactReporter : StreamingReporterBase {
8890 CompactReporter( ReporterConfig
const& _config )
8891 : StreamingReporterBase( _config )
8894 virtual ~CompactReporter();
8897 return "Reports test results on a single line, suitable for IDEs";
8900 virtual ReporterPreferences getPreferences()
const {
8901 ReporterPreferences prefs;
8902 prefs.shouldRedirectStdOut =
false;
8906 virtual void noMatchingTestCases(
std::string const& spec ) {
8907 stream <<
"No test cases matched '" << spec <<
"'" << std::endl;
8910 virtual void assertionStarting( AssertionInfo
const& ) {
8913 virtual bool assertionEnded( AssertionStats
const& _assertionStats ) {
8914 AssertionResult
const& result = _assertionStats.assertionResult;
8916 bool printInfoMessages =
true;
8919 if( !m_config->includeSuccessfulResults() && result.isOk() ) {
8922 printInfoMessages =
false;
8925 AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
8928 stream << std::endl;
8932 virtual void testRunEnded( TestRunStats
const& _testRunStats ) {
8933 printTotals( _testRunStats.totals );
8934 stream <<
"\n" << std::endl;
8935 StreamingReporterBase::testRunEnded( _testRunStats );
8939 class AssertionPrinter {
8940 void operator= ( AssertionPrinter
const& );
8942 AssertionPrinter( std::ostream& _stream, AssertionStats
const& _stats,
bool _printInfoMessages )
8945 , result( _stats.assertionResult )
8946 , messages( _stats.infoMessages )
8947 , itMessage( _stats.infoMessages.begin() )
8948 , printInfoMessages( _printInfoMessages )
8954 itMessage = messages.begin();
8956 switch( result.getResultType() ) {
8958 printResultType( Colour::ResultSuccess, passedString() );
8959 printOriginalExpression();
8960 printReconstructedExpression();
8961 if ( ! result.hasExpression() )
8962 printRemainingMessages( Colour::None );
8964 printRemainingMessages();
8968 printResultType( Colour::ResultSuccess, failedString() +
std::string( " - but was ok" ) );
8970 printResultType( Colour::Error, failedString() );
8971 printOriginalExpression();
8972 printReconstructedExpression();
8973 printRemainingMessages();
8976 printResultType( Colour::Error, failedString() );
8977 printIssue(
"unexpected exception with message:" );
8979 printExpressionWas();
8980 printRemainingMessages();
8983 printResultType( Colour::Error, failedString() );
8984 printIssue(
"fatal error condition with message:" );
8986 printExpressionWas();
8987 printRemainingMessages();
8990 printResultType( Colour::Error, failedString() );
8991 printIssue(
"expected exception, got none" );
8992 printExpressionWas();
8993 printRemainingMessages();
8996 printResultType( Colour::None,
"info" );
8998 printRemainingMessages();
9001 printResultType( Colour::None,
"warning" );
9003 printRemainingMessages();
9006 printResultType( Colour::Error, failedString() );
9007 printIssue(
"explicitly" );
9008 printRemainingMessages( Colour::None );
9014 printResultType( Colour::Error,
"** internal error **" );
9022 static Colour::Code dimColour() {
return Colour::FileName; }
9024 #ifdef CATCH_PLATFORM_MAC 9025 static const char* failedString() {
return "FAILED"; }
9026 static const char* passedString() {
return "PASSED"; }
9028 static const char* failedString() {
return "failed"; }
9029 static const char* passedString() {
return "passed"; }
9032 void printSourceInfo()
const {
9033 Colour colourGuard( Colour::FileName );
9034 stream << result.getSourceInfo() <<
":";
9037 void printResultType( Colour::Code colour,
std::string passOrFail )
const {
9038 if( !passOrFail.empty() ) {
9040 Colour colourGuard( colour );
9041 stream <<
" " << passOrFail;
9048 stream <<
" " << issue;
9051 void printExpressionWas() {
9052 if( result.hasExpression() ) {
9055 Colour colour( dimColour() );
9056 stream <<
" expression was:";
9058 printOriginalExpression();
9062 void printOriginalExpression()
const {
9063 if( result.hasExpression() ) {
9064 stream <<
" " << result.getExpression();
9068 void printReconstructedExpression()
const {
9069 if( result.hasExpandedExpression() ) {
9071 Colour colour( dimColour() );
9074 stream << result.getExpandedExpression();
9078 void printMessage() {
9079 if ( itMessage != messages.end() ) {
9080 stream <<
" '" << itMessage->message <<
"'";
9085 void printRemainingMessages( Colour::Code colour = dimColour() ) {
9086 if ( itMessage == messages.end() )
9090 std::vector<MessageInfo>::const_iterator itEnd = messages.end();
9091 const std::size_t N =
static_cast<std::size_t
>(
std::distance( itMessage, itEnd ) );
9094 Colour colourGuard( colour );
9095 stream <<
" with " << pluralise( N,
"message" ) <<
":";
9098 for(; itMessage != itEnd; ) {
9101 stream <<
" '" << itMessage->message <<
"'";
9102 if ( ++itMessage != itEnd ) {
9103 Colour colourGuard( dimColour() );
9112 AssertionStats
const& stats;
9113 AssertionResult
const&
result;
9114 std::vector<MessageInfo> messages;
9115 std::vector<MessageInfo>::const_iterator itMessage;
9116 bool printInfoMessages;
9126 std::string bothOrAll( std::size_t count )
const {
9127 return count == 1 ?
"" : count == 2 ?
"both " :
"all " ;
9130 void printTotals(
const Totals& totals )
const {
9131 if( totals.testCases.total() == 0 ) {
9132 stream <<
"No tests ran.";
9134 else if( totals.testCases.failed == totals.testCases.total() ) {
9135 Colour colour( Colour::ResultError );
9137 totals.assertions.failed == totals.assertions.total() ?
9138 bothOrAll( totals.assertions.failed ) :
"";
9140 "Failed " << bothOrAll( totals.testCases.failed )
9141 << pluralise( totals.testCases.failed,
"test case" ) <<
", " 9142 "failed " << qualify_assertions_failed <<
9143 pluralise( totals.assertions.failed,
"assertion" ) <<
".";
9145 else if( totals.assertions.total() == 0 ) {
9147 "Passed " << bothOrAll( totals.testCases.total() )
9148 << pluralise( totals.testCases.total(),
"test case" )
9149 <<
" (no assertions).";
9151 else if( totals.assertions.failed ) {
9152 Colour colour( Colour::ResultError );
9154 "Failed " << pluralise( totals.testCases.failed,
"test case" ) <<
", " 9155 "failed " << pluralise( totals.assertions.failed,
"assertion" ) <<
".";
9158 Colour colour( Colour::ResultSuccess );
9160 "Passed " << bothOrAll( totals.testCases.passed )
9161 << pluralise( totals.testCases.passed,
"test case" ) <<
9162 " with " << pluralise( totals.assertions.passed,
"assertion" ) <<
".";
9167 INTERNAL_CATCH_REGISTER_REPORTER(
"compact", CompactReporter )
9183 IReporter::~IReporter() {}
9184 IReporterFactory::~IReporterFactory() {}
9185 IReporterRegistry::~IReporterRegistry() {}
9186 IStreamingReporter::~IStreamingReporter() {}
9187 AssertionStats::~AssertionStats() {}
9188 SectionStats::~SectionStats() {}
9189 TestCaseStats::~TestCaseStats() {}
9190 TestGroupStats::~TestGroupStats() {}
9191 TestRunStats::~TestRunStats() {}
9192 CumulativeReporterBase::SectionNode::~SectionNode() {}
9193 CumulativeReporterBase::~CumulativeReporterBase() {}
9195 StreamingReporterBase::~StreamingReporterBase() {}
9196 ConsoleReporter::~ConsoleReporter() {}
9197 CompactReporter::~CompactReporter() {}
9200 IConfig::~IConfig() {}
9201 XmlReporter::~XmlReporter() {}
9202 JunitReporter::~JunitReporter() {}
9203 TestRegistry::~TestRegistry() {}
9204 FreeFunctionTestCase::~FreeFunctionTestCase() {}
9207 TestSpec::Pattern::~Pattern() {}
9208 TestSpec::NamePattern::~NamePattern() {}
9209 TestSpec::TagPattern::~TagPattern() {}
9210 TestSpec::ExcludedPattern::~ExcludedPattern() {}
9217 void Config::dummy() {}
9221 #pragma clang diagnostic pop 9226 #ifdef CATCH_CONFIG_MAIN 9228 #define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED 9233 int main (
int argc,
char *
const argv[]) {
9234 return Catch::Session().run( argc, argv );
9240 int main (
int argc,
char *
const argv[]) {
9241 #if !CATCH_ARC_ENABLED 9242 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
9245 Catch::registerTestMethods();
9246 int result = Catch::Session().run( argc, (
char*
const*)argv );
9248 #if !CATCH_ARC_ENABLED 9259 #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED 9260 # undef CLARA_CONFIG_MAIN 9266 #ifdef CATCH_CONFIG_PREFIX_ALL 9268 #define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" ) 9269 #define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" ) 9271 #define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS" ) 9272 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" ) 9273 #define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" ) 9275 #define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" ) 9276 #define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" ) 9277 #define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" ) 9278 #define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" ) 9279 #define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" ) 9281 #define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS" ) 9282 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" ) 9283 #define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" ) 9285 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" ) 9286 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" ) 9288 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" ) 9289 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg ) 9290 #define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" ) 9291 #define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" ) 9292 #define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" ) 9294 #ifdef CATCH_CONFIG_VARIADIC_MACROS 9295 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) 9296 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) 9297 #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) 9298 #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) 9299 #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ ) 9300 #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ ) 9302 #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) 9303 #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) 9304 #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) 9305 #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) 9306 #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg ) 9307 #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg ) 9309 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) 9311 #define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) 9312 #define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) 9314 #define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) 9317 #ifdef CATCH_CONFIG_VARIADIC_MACROS 9318 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ ) 9319 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) 9321 #define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags ) 9322 #define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) 9324 #define CATCH_GIVEN( desc ) CATCH_SECTION( "Given: " desc, "" ) 9325 #define CATCH_WHEN( desc ) CATCH_SECTION( " When: " desc, "" ) 9326 #define CATCH_AND_WHEN( desc ) CATCH_SECTION( " And: " desc, "" ) 9327 #define CATCH_THEN( desc ) CATCH_SECTION( " Then: " desc, "" ) 9328 #define CATCH_AND_THEN( desc ) CATCH_SECTION( " And: " desc, "" ) 9333 #define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" ) 9334 #define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" ) 9336 #define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "REQUIRE_THROWS" ) 9337 #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" ) 9338 #define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" ) 9340 #define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" ) 9341 #define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" ) 9342 #define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" ) 9343 #define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" ) 9344 #define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" ) 9346 #define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS" ) 9347 #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" ) 9348 #define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" ) 9350 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" ) 9351 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" ) 9353 #define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" ) 9354 #define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg ) 9355 #define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" ) 9356 #define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" ) 9357 #define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" ) 9359 #ifdef CATCH_CONFIG_VARIADIC_MACROS 9360 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) 9361 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) 9362 #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) 9363 #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) 9364 #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ ) 9365 #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ ) 9367 #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) 9368 #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) 9369 #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) 9370 #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) 9371 #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg ) 9372 #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg ) 9374 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) 9376 #define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) 9377 #define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) 9379 #define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) 9383 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) 9386 #ifdef CATCH_CONFIG_VARIADIC_MACROS 9387 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ ) 9388 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) 9390 #define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags ) 9391 #define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) 9393 #define GIVEN( desc ) SECTION( " Given: " desc, "" ) 9394 #define WHEN( desc ) SECTION( " When: " desc, "" ) 9395 #define AND_WHEN( desc ) SECTION( "And when: " desc, "" ) 9396 #define THEN( desc ) SECTION( " Then: " desc, "" ) 9397 #define AND_THEN( desc ) SECTION( " And: " desc, "" ) 9403 #define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED 9406 # ifdef __ICC // icpc defines the __clang__ macro 9407 # pragma warning(pop) 9409 # pragma clang diagnostic pop 9411 #elif defined __GNUC__ 9412 # pragma GCC diagnostic pop 9415 #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
virtual std::string getCurrentTestName() const =0
virtual std::size_t size() const
std::vector< Ptr< Matcher< ExpressionT > > > m_matchers
virtual std::string toString() const
Equals(std::string const &str)
AnyOf(AnyOf const &other)
Approx operator()(double value)
virtual std::string toString() const
GLfixed GLfixed GLint GLint order
Option(Option const &_other)
std::vector< T > m_values
std::string toString(std::vector< T, Allocator > const &v)
std::string rawMemoryToString(const T &object)
bool isFalseTest(int flags)
ExceptionTranslatorRegistrar(std::string(*translateFunction)(T &))
NameAndDesc(const char *_name="", const char *_description="")
std::string getMessage() const
Impl::StdString::StartsWith StartsWith(const char *substr)
ExpressionT ExpressionType
bool operator<(TestCase const &other) const
CopyableStream & operator=(CopyableStream const &other)
virtual void registerTest(TestCase const &testInfo)=0
Approx & scale(double newScale)
Option & operator=(Option const &_other)
std::string toString() const
void toLowerInPlace(std::string &s)
virtual Ptr< Matcher > clone() const =0
std::string getExpressionInMacro() const
std::string reconstructedExpression
INT64 INT64 INT64 remainder
ResultDisposition::Flags operator|(ResultDisposition::Flags lhs, ResultDisposition::Flags rhs)
std::string rawMemoryToString(const void *object, std::size_t size)
std::ostream & operator<<(std::ostream &os, SourceLineInfo const &info)
bool contains(std::string const &s, std::string const &infix)
double getElapsedSeconds() const
bool expectedToFail() const
ExpressionLhs< T const & > operator<=(T const &operand)
void writeToDebugConsole(std::string const &text)
std::set< std::string > lcaseTags
T const & operator+(T const &value, StreamEndStop)
EndsWith(std::string const &substr)
float3 operator*(const float3 &a, float b)
virtual T getValue(std::size_t index) const
SpecialProperties properties
GLuint GLsizei const GLchar * message
std::string(* exceptionTranslateFunction)()
T valueOr(T const &defaultValue) const
virtual ~NotImplementedException() CATCH_NOEXCEPT
BetweenGenerator(T from, T to)
void deleteAll(ContainerT &container)
virtual void popScopedMessage(MessageInfo const &message)=0
virtual bool advanceGeneratorsForCurrentTest()=0
typedef HANDLE(WINAPI *PFNWGLCREATEBUFFERREGIONARBPROC)(HDC hDC
IResultCapture & getResultCapture()
GLsizei const GLchar *const * string
std::vector< Ptr< Matcher< ExpressionT > > > m_matchers
T const & operator*() const
GLenum GLuint GLenum GLsizei const GLchar * buf
static bool evaluate(T1 const &lhs, T2 const &rhs)
unsigned int getElapsedMilliseconds() const
static const char * getName()
bool replaceInPlace(std::string &str, std::string const &replaceThis, std::string const &withThis)
std::string getExpandedExpression() const
IGeneratorsForTest * createGeneratorsForTest()
virtual void registerReporter(std::string const &name, IReporterFactory *factory)=0
AssertionResultData m_data
virtual void invoke() const
#define CATCH_INTERNAL_ERROR(msg)
IMutableRegistryHub & getMutableRegistryHub()
GLsizei GLsizei GLfloat distance
GLsizei const GLubyte * commands
ScopedMessage(MessageBuilder const &builder)
virtual void handleFatalErrorCondition(std::string const &message)=0
void config(uvc::device &device, uint8_t gyro_bw, uint8_t gyro_range, uint8_t accel_bw, uint8_t accel_range, uint32_t time_seed)
bool operator==(TestCase const &other) const
CompositeGenerator(CompositeGenerator &other)
static std::string convert(U *p)
TestCase makeTestCase(ITestCase *testCase, std::string const &className, std::string const &name, std::string const &description, SourceLineInfo const &lineInfo)
virtual void pushScopedMessage(MessageInfo const &message)=0
virtual ~ITestCaseRegistry()
virtual bool aborting() const =0
ResultDisposition::Flags resultDisposition
ExceptionTranslator(std::string(*translateFunction)(T &))
static bool evaluate(T1 const &lhs, T2 const &rhs)
Impl::Generic::AllOf< ExpressionT > AllOf(Impl::Matcher< ExpressionT > const &m1, Impl::Matcher< ExpressionT > const &m2, Impl::Matcher< ExpressionT > const &m3)
static bool evaluate(T1 const &lhs, T2 const &rhs)
IRegistryHub & getRegistryHub()
virtual std::string toString() const
bool shouldContinueOnFailure(int flags)
virtual std::size_t size() const
std::string getTestMacroName() const
Contains(std::string const &substr)
ResultBuilder & setLhs(std::string const &lhs)
ResultWas::OfType resultType
bool isJustInfo(int flags)
void add(const IGenerator< T > *generator)
AssertionResult build() const
GLsizeiptr const void GLenum usage
static type makeSafe(bool value)
virtual T getValue(std::size_t index) const
virtual bool match(std::string const &expr) const
std::string reconstructExpression() const
static ITagAliasRegistry const & get()
Totals delta(Totals const &prevTotals) const
static std::string convert(R C::*p)
static const char * getName()
SourceLineInfo getSourceInfo() const
AllOf(AllOf const &other)
EndsWith(EndsWith const &other)
virtual std::string translate() const
bool operator<(SourceLineInfo const &other) const
GLuint GLuint GLsizei count
Impl::StdString::Contains Contains(const char *substr)
TestCase(ITestCase *testCase, TestCaseInfo const &info)
bool shouldSuppressFailure(int flags)
virtual void assertionEnded(AssertionResult const &result)=0
ResultWas::OfType getResultType() const
GLenum GLint GLint * precision
virtual ~IExceptionTranslatorRegistry()
bool isOk(ResultWas::OfType resultType)
virtual void registerTranslator(const IExceptionTranslator *translator)=0
ResultBuilder & setResultType(ResultWas::OfType result)
virtual bool match(std::string const &expr) const
static bool evaluate(T1 const &lhs, T2 const &rhs)
static bool evaluate(T1 const &lhs, T2 const &rhs)
GLenum GLenum GLsizei void * row
TestCase & operator=(TestCase const &other)
MethodTestCase(void(C::*method)())
bool operator==(SourceLineInfo const &other) const
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
MessageInfo(std::string const &_macroName, SourceLineInfo const &_lineInfo, ResultWas::OfType _type)
virtual std::string translateActiveException() const =0
virtual bool match(std::string const &expr) const
static const char * getName()
void throwLogicError(std::string const &message, SourceLineInfo const &locationInfo)
NotImplementedException(SourceLineInfo const &lineInfo)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * data
virtual ~ITagAliasRegistry()
std::string trim(std::string const &str)
bool endsWith(std::string const &s, std::string const &suffix)
AutoReg(TestFunction function, SourceLineInfo const &lineInfo, NameAndDesc const &nameAndDesc)
GLuint GLsizei const GLchar * label
std::string makeString(const char *str)
std::string toLower(std::string const &s)
void swap(TestCase &other)
static const char * getName()
ResultBuilder & captureExpression(RhsT const &rhs)
std::string translateActiveException()
MessageBuilder(std::string const ¯oName, SourceLineInfo const &lineInfo, ResultWas::OfType type)
void(SafeBool::* type)() const
virtual ~IMutableContext()
TestCaseInfo(std::string const &_name, std::string const &_className, std::string const &_description, std::set< std::string > const &_tags, SourceLineInfo const &_lineInfo)
std::set< std::string > tags
TestCase withName(std::string const &_newName) const
NonCopyable & operator=(NonCopyable const &)
virtual size_t getGeneratorIndex(std::string const &fileInfo, size_t totalSize)=0
SourceLineInfo m_lineInfo
TagAlias(std::string _tag, SourceLineInfo _lineInfo)
virtual ITestCaseRegistry const & getTestCaseRegistry() const =0
CopyableStream(CopyableStream const &other)
std::ostringstream m_stream
void registerTestCase(ITestCase *testCase, char const *className, NameAndDesc const &nameAndDesc, SourceLineInfo const &lineInfo)
GLsizei const GLfloat * value
virtual T getValue(std::size_t index) const =0
std::size_t total() const
bool hasExpandedExpression() const
IContext & getCurrentContext()
virtual bool match(ExpressionT const &expr) const
AssertionResultData m_resultData
#define INTERNAL_CATCH_STRINGIFY(expr)
virtual bool match(std::string const &expr) const
static const char * getName()
RegistrarForTagAliases(char const *alias, char const *tag, SourceLineInfo const &lineInfo)
virtual ~IMutableRegistryHub()
bool applyEvaluator(T1 const &lhs, T2 const &rhs)
virtual Ptr< Matcher< ExpressionT > > clone() const
FalseType testStreamable(FalseType)
static unsigned int globalCount
void deleteAllValues(AssociativeContainerT &container)
void captureResult(ResultWas::OfType resultType)
typedef void(APIENTRYP PFNGLDRAWRANGEELEMENTSPROC)(GLenum mode
virtual bool moveNext()=0
virtual std::string toString() const
StartsWith(std::string const &substr)
TestCaseInfo const & getTestCaseInfo() const
static const char * getName()
AssertionInfo m_assertionInfo
ExpressionLhs(ResultBuilder &rb, T lhs)
AllOf & add(Matcher< ExpressionT > const &matcher)
std::string toString(T const &value)
converts any type to a string
CompositeGenerator & then(CompositeGenerator &other)
CompositeGenerator & setFileInfo(const char *fileInfo)
AnyOf & add(Matcher< ExpressionT > const &matcher)
GLenum GLsizei GLsizei GLint * values
virtual ~IGeneratorsForTest()
virtual std::size_t size() const =0
bool compare(T *lhs, int rhs)
Stream createStream(std::string const &streamName)
virtual std::string toString() const
virtual void release() const
GLint GLint GLsizei width
Section(SectionInfo const &info)
SectionInfo(SourceLineInfo const &_lineInfo, std::string const &_name, std::string const &_description=std::string())
GLuint const GLchar * name
virtual IReporterRegistry const & getReporterRegistry() const =0
ResultBuilder & setOp(std::string const &op)
virtual IResultCapture * getResultCapture()=0
static bool evaluate(T1 const &lhs, T2 const &rhs)
CompositeGenerator< T > between(T from, T to)
Impl::StdString::EndsWith EndsWith(const char *substr)
GLuint GLsizei GLsizei * length
void useActiveException(ResultDisposition::Flags resultDisposition=ResultDisposition::Normal)
const T * operator->() const
std::string unprintableString
static std::string convert(T const &_value)
Equals(Equals const &other)
bool shouldDebugBreak() const
virtual ~IGeneratorInfo()
Contains(Contains const &other)
virtual const char * what() const CATCH_NOEXCEPT
void move(CompositeGenerator &other)
Approx(Approx const &other)
std::string rangeToString(InputIterator first, InputIterator last)
ResultBuilder & setRhs(std::string const &rhs)
Impl::Generic::AnyOf< ExpressionT > AnyOf(Impl::Matcher< ExpressionT > const &m1, Impl::Matcher< ExpressionT > const &m2, Impl::Matcher< ExpressionT > const &m3)
virtual void addRef() const
IMutableContext & getCurrentMutableContext()
virtual bool match(ExpressionT const &expr) const
virtual ~IExceptionTranslator()
GLuint GLenum GLenum transform
bool operator==(const float3 &a, const float3 &b)
virtual IExceptionTranslatorRegistry & getExceptionTranslatorRegistry()=0
virtual std::string toString() const
static const char * getName()
virtual void sectionEnded(SectionInfo const &name, Counts const &assertions, double _durationInSeconds)=0
virtual ~MethodTestCase()
StartsWith(StartsWith const &other)
virtual ~IResultCapture()
NotImplementedException(NotImplementedException const &)
std::string getExpression() const
AutoReg(void(C::*method)(), char const *className, NameAndDesc const &nameAndDesc, SourceLineInfo const &lineInfo)
GLint GLint GLint GLint GLint x
virtual void getFilteredTests(TestSpec const &testSpec, IConfig const &config, std::vector< TestCase > &matchingTestCases, bool negated=false) const =0
static std::string convert(T const &)
virtual std::string expandAliases(std::string const &unexpandedTestSpec) const =0
ResultBuilder(char const *macroName, SourceLineInfo const &lineInfo, char const *capturedExpression, ResultDisposition::Flags resultDisposition)
bool hasExpression() const
unsigned int getElapsedMicroseconds() const
CompositeGenerator & then(T value)
Approx & epsilon(double newEpsilon)
pluralise(std::size_t count, std::string const &label)
std::string capturedExpression
virtual Ptr< IConfig const > getConfig() const =0
std::vector< const IGenerator< T > * > m_composed
GLuint GLuint GLsizei GLenum type
bool startsWith(std::string const &s, std::string const &prefix)
virtual IRunner * getRunner()=0
Impl::StdString::Equals Equals(const char *str)