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 diagnostic ignored "-Wglobal-constructors" 18 #pragma clang diagnostic ignored "-Wvariadic-macros" 20 #pragma clang diagnostic push 21 #pragma clang diagnostic ignored "-Wpadded" 25 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED 28 #define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED 30 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line 31 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) 32 #define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) 34 #define INTERNAL_CATCH_STRINGIFY2( expr ) #expr 35 #define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr ) 42 #define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED 50 #if (__BORLANDC__ > 0x582 ) 54 #endif // __BORLANDC__ 58 #ifdef __EDG_VERSION__ 60 #if (__EDG_VERSION__ > 238 ) 64 #endif // __EDG_VERSION__ 70 #if (__DMC__ > 0x840 ) 82 #if (__GNUC_MINOR__ >= 96 ) 90 #endif // __GNUC__ < 3 98 #if (_MSC_VER >= 1310 ) // (VC++ 7.0+) 105 #if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \ 106 ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \ 107 ( defined __GNUC__ && __GNUC__ >= 3 ) || \ 108 ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L ) 110 #ifndef CATCH_CONFIG_NO_VARIADIC_MACROS 111 #define CATCH_CONFIG_VARIADIC_MACROS 131 return value ? &SafeBool::trueValue : 0;
134 void trueValue()
const {}
137 template<
typename ContainerT>
139 typename ContainerT::const_iterator it = container.begin();
140 typename ContainerT::const_iterator itEnd = container.end();
141 for(; it != itEnd; ++it )
144 template<
typename AssociativeContainerT>
146 typename AssociativeContainerT::const_iterator it = container.begin();
147 typename AssociativeContainerT::const_iterator itEnd = container.end();
148 for(; it != itEnd; ++it )
152 template<
typename ContainerT,
typename Function>
153 inline void forEach( ContainerT& container, Function
function ) {
154 std::for_each( container.begin(), container.end(), function );
157 template<
typename ContainerT,
typename Function>
158 inline void forEach( ContainerT
const& container, Function
function ) {
159 std::for_each( container.begin(), container.end(), function );
162 inline bool startsWith( std::string
const& s, std::string
const& prefix ) {
163 return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
165 inline bool endsWith( std::string
const& s, std::string
const& suffix ) {
166 return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
168 inline bool contains( std::string
const& s, std::string
const& infix ) {
169 return s.find( infix ) != std::string::npos;
174 inline std::string
toLower( std::string
const& s ) {
181 pluralise( std::size_t count, std::string
const& label )
205 : file( other.file ),
212 return line == other.
line && file == other.
file;
220 os << info.
file <<
"(" << info.
line <<
")";
222 os << info.
file <<
":" << info.
line;
228 inline bool isTrue(
bool value ){
return value; }
231 std::ostringstream oss;
232 oss << locationInfo <<
": Internal Catch error: '" << message <<
"'";
234 throw std::logic_error( oss.str() );
238 #define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) ) 239 #define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO ); 252 virtual const char* what()
const throw();
262 #define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO ) 265 #define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED 268 #define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED 276 virtual bool moveNext() = 0;
277 virtual std::size_t getCurrentIndex()
const = 0;
283 virtual IGeneratorInfo& getGeneratorInfo( std::string
const& fileInfo, std::size_t size ) = 0;
284 virtual bool moveNext() = 0;
292 #define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED 295 #pragma clang diagnostic push 296 #pragma clang diagnostic ignored "-Wpadded" 312 Ptr(
Ptr const& other ) : m_p( other.m_p ){
335 void swap(
Ptr& other ) { std::swap( m_p, other.m_p ); }
336 T*
get() {
return m_p; }
337 const T*
get()
const{
return m_p; }
340 bool operator !()
const {
return m_p == NULL; }
349 virtual void addRef()
const = 0;
350 virtual void release()
const = 0;
353 template<
typename T = IShared>
372 #pragma clang diagnostic pop 393 virtual IRunner& getRunner() = 0;
394 virtual size_t getGeneratorIndex( std::string
const& fileInfo,
size_t totalSize ) = 0;
395 virtual bool advanceGeneratorsForCurrentTest() = 0;
402 virtual void setResultCapture(
IResultCapture* resultCapture ) = 0;
403 virtual void setRunner(
IRunner* runner ) = 0;
415 #define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED 418 #define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED 424 class TestCaseFilters;
427 virtual void invoke ()
const = 0;
436 virtual std::vector<TestCase>
const& getAllTests()
const = 0;
437 virtual std::vector<TestCase> getMatchingTestCases( std::string
const& rawTestSpec )
const = 0;
457 void (C::*m_method)();
463 NameAndDesc(
const char* _name =
"",
const char* _description=
"" )
464 : name( _name ), description( _description )
479 char const* className,
488 void registerTestCase(
ITestCase* testCase,
489 char const* className,
497 void operator= (
AutoReg const& );
502 #ifdef CATCH_CONFIG_VARIADIC_MACROS 503 #define INTERNAL_CATCH_TESTCASE( ... ) \ 505 static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \ 506 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__ ) ); }\ 507 static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )() 510 #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ 511 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); } 514 #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... )\ 516 struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \ 519 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 ); \ 521 void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test() 524 #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \ 526 static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \ 527 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 ) ); }\ 528 static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )() 531 #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \ 532 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); } 535 #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\ 537 struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \ 540 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 ); \ 542 void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test() 547 #define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED 550 #define TWOBLUECUBES_CATCH_EXPRESSION_DECOMPOSER_HPP_INCLUDED 553 #define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED 556 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_BUILDER_H_INCLUDED 559 #define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED 562 #define TWOBLUECUBES_CATCH_SFINAE_HPP_INCLUDED 569 static const bool value =
true;
574 static const bool value =
false;
579 #ifdef CATCH_CONFIG_SFINAE 581 template<
bool>
struct NotABooleanExpression;
583 template<
bool c>
struct If : NotABooleanExpression<c> {};
584 template<>
struct If<true> :
TrueType {};
585 template<>
struct If<false> :
FalseType {};
587 template<
int size>
struct SizedIf;
591 #endif // CATCH_CONFIG_SFINAE 601 #define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED 603 #import <Foundation/Foundation.h> 606 #define CATCH_ARC_ENABLED __has_feature(objc_arc) 608 #define CATCH_ARC_ENABLED 0 611 void arcSafeRelease( NSObject* obj );
612 id performOptionalSelector(
id obj,
SEL sel );
614 #if !CATCH_ARC_ENABLED 615 inline void arcSafeRelease( NSObject* obj ) {
618 inline id performOptionalSelector(
id obj,
SEL sel ) {
619 if( [obj respondsToSelector: sel] )
620 return [obj performSelector: sel];
623 #define CATCH_UNSAFE_UNRETAINED 624 #define CATCH_ARC_STRONG 626 inline void arcSafeRelease( NSObject* ){}
627 inline id performOptionalSelector(
id obj,
SEL sel ) {
629 #pragma clang diagnostic push 630 #pragma clang diagnostic ignored "-Warc-performSelector-leaks" 632 if( [obj respondsToSelector: sel] )
633 return [obj performSelector: sel];
635 #pragma clang diagnostic pop 639 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained 640 #define CATCH_ARC_STRONG __strong 651 #ifdef CATCH_CONFIG_SFINAE 654 class IsStreamInsertableHelper {
655 template<
int N>
struct TrueIfSizeable :
TrueType {};
657 template<
typename T2>
658 static TrueIfSizeable<sizeof((*(std::ostream*)0) << *((T2 const*)0))> dummy(T2*);
662 typedef SizedIf<sizeof(dummy((T*)0))> type;
671 template<
typename T>
BorgType( T
const& );
681 static std::ostream &
s;
691 static std::string
convert( T
const& ) {
return "{?}"; }
697 static std::string
convert( T
const& _value ) {
698 std::ostringstream oss;
707 std::string
toString( T
const& value );
719 std::ostringstream oss;
727 static std::string
convert( std::vector<T>
const& v ) {
728 std::ostringstream oss;
730 for( std::size_t i = 0; i < v.size(); ++ i ) {
732 if( i < v.size() - 1 )
761 inline std::string
toString( std::string
const& value ) {
762 return "\"" + value +
"\"";
765 inline std::string
toString( std::wstring
const& value ) {
766 std::ostringstream oss;
768 for(
size_t i = 0; i < value.size(); ++i )
769 oss << static_cast<char>( value[i] <= 0xff ? value[i] :
'?');
774 inline std::string
toString(
const char*
const value ) {
775 return value ?
Catch::toString( std::string( value ) ) : std::string(
"{null string}" );
783 std::ostringstream oss;
788 inline std::string
toString(
unsigned long value ) {
789 std::ostringstream oss;
791 oss <<
"0x" << std::hex << value;
797 inline std::string
toString(
unsigned int value ) {
798 return toString( static_cast<unsigned long>( value ) );
801 inline std::string
toString(
const double value ) {
802 std::ostringstream oss;
803 oss << std::setprecision( 10 )
806 std::string d = oss.str();
807 std::size_t i = d.find_last_not_of(
'0' );
808 if( i != std::string::npos && i != d.size()-1 ) {
811 d = d.substr( 0, i+1 );
817 return value ?
"true" :
"false";
822 ?
toString( static_cast<unsigned int>( value ) )
827 return toString( static_cast<char>( value ) );
830 inline std::string
toString(
unsigned char value ) {
831 return toString( static_cast<char>( value ) );
834 #ifdef CATCH_CONFIG_CPP11_NULLPTR 835 inline std::string
toString( std::nullptr_t ) {
841 inline std::string
toString( NSString
const *
const& nsstring ) {
844 return std::string(
"@\"" ) + [nsstring UTF8String] +
"\"";
846 inline std::string
toString( NSString * CATCH_ARC_STRONG
const& nsstring ) {
849 return std::string(
"@\"" ) + [nsstring UTF8String] +
"\"";
851 inline std::string
toString( NSObject*
const& nsObject ) {
852 return toString( [nsObject description] );
859 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED 863 #define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED 876 ExpressionFailed = FailureBit | 1,
877 ExplicitFailure = FailureBit | 2,
879 Exception = 0x100 | FailureBit,
881 ThrewException = Exception | 1,
882 DidntThrowException = Exception | 2
905 ContinueOnFailure = 0x01,
928 std::string
const& _capturedExpression,
953 bool succeeded()
const;
955 bool hasExpression()
const;
956 bool hasMessage()
const;
957 std::string getExpression()
const;
958 std::string getExpressionInMacro()
const;
959 bool hasExpandedExpression()
const;
960 std::string getExpandedExpression()
const;
961 std::string getMessage()
const;
963 std::string getTestMacroName()
const;
973 #define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED 976 #pragma warning(push) 977 #pragma warning(disable:4389) // '==' : signed/unsigned mismatch 1000 template<
typename T>
1001 inline T&
opCast(T
const& t) {
return const_cast<T&
>(t); }
1004 #ifdef CATCH_CONFIG_CPP11_NULLPTR 1005 inline std::nullptr_t
opCast(std::nullptr_t) {
return nullptr; }
1006 #endif // CATCH_CONFIG_CPP11_NULLPTR 1010 template<
typename T1,
typename T2, Operator Op>
1013 template<
typename T1,
typename T2>
1019 template<
typename T1,
typename T2>
1025 template<
typename T1,
typename T2>
1031 template<
typename T1,
typename T2>
1037 template<
typename T1,
typename T2>
1043 template<
typename T1,
typename T2>
1050 template<Operator Op,
typename T1,
typename T2>
1059 template<Operator Op,
typename T1,
typename T2>
1065 template<Operator Op>
bool compare(
unsigned int lhs,
int rhs ) {
1066 return applyEvaluator<Op>( lhs,
static_cast<unsigned int>( rhs ) );
1068 template<Operator Op>
bool compare(
unsigned long lhs,
int rhs ) {
1069 return applyEvaluator<Op>( lhs,
static_cast<unsigned int>( rhs ) );
1071 template<Operator Op>
bool compare(
unsigned char lhs,
int rhs ) {
1072 return applyEvaluator<Op>( lhs,
static_cast<unsigned int>( rhs ) );
1076 template<Operator Op>
bool compare(
unsigned int lhs,
long rhs ) {
1077 return applyEvaluator<Op>( lhs,
static_cast<unsigned long>( rhs ) );
1079 template<Operator Op>
bool compare(
unsigned long lhs,
long rhs ) {
1080 return applyEvaluator<Op>( lhs,
static_cast<unsigned long>( rhs ) );
1082 template<Operator Op>
bool compare(
unsigned char lhs,
long rhs ) {
1083 return applyEvaluator<Op>( lhs,
static_cast<unsigned long>( rhs ) );
1087 template<Operator Op>
bool compare(
int lhs,
unsigned int rhs ) {
1088 return applyEvaluator<Op>(
static_cast<unsigned int>( lhs ), rhs );
1090 template<Operator Op>
bool compare(
int lhs,
unsigned long rhs ) {
1091 return applyEvaluator<Op>(
static_cast<unsigned int>( lhs ), rhs );
1093 template<Operator Op>
bool compare(
int lhs,
unsigned char rhs ) {
1094 return applyEvaluator<Op>(
static_cast<unsigned int>( lhs ), rhs );
1098 template<Operator Op>
bool compare(
long lhs,
unsigned int rhs ) {
1099 return applyEvaluator<Op>(
static_cast<unsigned long>( lhs ), rhs );
1101 template<Operator Op>
bool compare(
long lhs,
unsigned long rhs ) {
1102 return applyEvaluator<Op>(
static_cast<unsigned long>( lhs ), rhs );
1104 template<Operator Op>
bool compare(
long lhs,
unsigned char rhs ) {
1105 return applyEvaluator<Op>(
static_cast<unsigned long>( lhs ), rhs );
1109 template<Operator Op,
typename T>
bool compare(
long lhs, T* rhs ) {
1112 template<Operator Op,
typename T>
bool compare( T* lhs,
long rhs ) {
1117 template<Operator Op,
typename T>
bool compare(
int lhs, T* rhs ) {
1120 template<Operator Op,
typename T>
bool compare( T* lhs,
int rhs ) {
1124 #ifdef CATCH_CONFIG_CPP11_NULLPTR 1126 template<Operator Op,
typename T>
bool compare( std::nullptr_t, T* rhs ) {
1129 template<Operator Op,
typename T>
bool compare( T* lhs, std::nullptr_t ) {
1132 #endif // CATCH_CONFIG_CPP11_NULLPTR 1138 #pragma warning(pop) 1143 struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
1162 template<
typename T>
1168 std::string reconstructExpression(
AssertionInfo const& info )
const;
1172 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT
const& );
1173 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT
const& );
1177 struct ExprComponents {
1180 std::string lhs, rhs, op;
1182 std::ostringstream m_stream;
1191 template<
typename T>
1198 template<
typename RhsT>
1200 return captureExpression<Internal::IsEqualTo>( rhs );
1203 template<
typename RhsT>
1205 return captureExpression<Internal::IsNotEqualTo>( rhs );
1208 template<
typename RhsT>
1210 return captureExpression<Internal::IsLessThan>( rhs );
1213 template<
typename RhsT>
1215 return captureExpression<Internal::IsGreaterThan>( rhs );
1218 template<
typename RhsT>
1220 return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
1223 template<
typename RhsT>
1225 return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
1229 return captureExpression<Internal::IsEqualTo>( rhs );
1233 return captureExpression<Internal::IsNotEqualTo>( rhs );
1237 bool value = m_lhs ?
true :
false;
1246 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT
const& );
1247 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT
const& );
1248 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT
const& );
1249 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT
const& );
1250 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT
const& );
1251 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT
const& );
1254 template<Internal::Operator Op,
typename RhsT>
1276 template<
typename T>
1289 #define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED 1313 static unsigned int globalCount;
1320 : m_info( macroName, lineInfo, type )
1323 template<
typename T>
1344 #define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED 1348 #define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED 1370 return passed + failed;
1387 Totals diff = *
this - prevTotals;
1415 class ScopedMessageBuilder;
1422 virtual bool sectionStarted(
SectionInfo const& sectionInfo,
1423 Counts& assertions ) = 0;
1424 virtual void sectionEnded(
SectionInfo const& name,
Counts const& assertions,
double _durationInSeconds ) = 0;
1425 virtual void pushScopedMessage(
MessageInfo const& message ) = 0;
1426 virtual void popScopedMessage(
MessageInfo const& message ) = 0;
1428 virtual bool shouldDebugBreak()
const = 0;
1432 virtual std::string getCurrentTestName()
const = 0;
1438 #define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED 1443 #define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED 1445 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) 1446 #define CATCH_PLATFORM_MAC 1447 #elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) 1448 #define CATCH_PLATFORM_IPHONE 1449 #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) 1450 #define CATCH_PLATFORM_WINDOWS 1453 #ifdef CATCH_PLATFORM_MAC 1456 #include <stdbool.h> 1457 #include <sys/types.h> 1459 #include <sys/sysctl.h> 1472 struct kinfo_proc info;
1478 info.kp_proc.p_flag = 0;
1485 mib[2] = KERN_PROC_PID;
1490 size =
sizeof(info);
1491 junk = sysctl(mib,
sizeof(mib) /
sizeof(*mib), &info, &size, NULL, 0);
1496 return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
1503 #if defined(__ppc64__) || defined(__ppc__) 1504 #define BreakIntoDebugger() \ 1505 if( Catch::isDebuggerActive() ) { \ 1506 __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \ 1507 : : : "memory","r0","r3","r4" ); \ 1510 #define BreakIntoDebugger() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );} 1516 #elif defined(_MSC_VER) 1517 extern "C" __declspec(dllimport)
int __stdcall IsDebuggerPresent();
1518 #define BreakIntoDebugger() if (IsDebuggerPresent() ) { __debugbreak(); } 1520 return IsDebuggerPresent() != 0;
1522 #elif defined(__MINGW32__) 1523 extern "C" __declspec(dllimport)
int __stdcall IsDebuggerPresent();
1524 extern "C" __declspec(dllimport)
void __stdcall DebugBreak();
1525 #define BreakIntoDebugger() if (IsDebuggerPresent() ) { DebugBreak(); } 1527 return IsDebuggerPresent() != 0;
1534 #ifdef CATCH_PLATFORM_WINDOWS 1535 extern "C" __declspec(dllimport)
void __stdcall OutputDebugStringA(
const char* );
1537 ::OutputDebugStringA( text.c_str() );
1544 #endif // CATCH_PLATFORM_WINDOWS 1547 #define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED 1550 #define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED 1553 #define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED 1556 #define TWOBLUECUBES_CATCH_TEST_SPEC_H_INCLUDED 1559 #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED 1565 #pragma clang diagnostic push 1566 #pragma clang diagnostic ignored "-Wpadded" 1575 std::string
const& _className,
1576 std::string
const& _description,
1577 std::set<std::string>
const& _tags,
1598 TestCase withName( std::string
const& _newName )
const;
1600 void invoke()
const;
1604 bool isHidden()
const;
1605 bool hasTag( std::string
const& tag )
const;
1606 bool matchesTags( std::string
const& tagPattern )
const;
1607 std::set<std::string>
const& getTags()
const;
1619 std::string
const& className,
1620 std::string
const& name,
1621 std::string
const& description,
1626 #pragma clang diagnostic pop 1630 #define TWOBLUECUBES_CATCH_TAGS_HPP_INCLUDED 1638 #pragma clang diagnostic ignored "-Wpadded" 1647 std::size_t pos = 0;
1648 while( pos < str.size() ) {
1651 std::size_t
end = str.find_first_of(
']', pos );
1652 if( end != std::string::npos ) {
1653 acceptTag( str.substr( pos+1, end-pos-1 ) );
1670 virtual void acceptTag( std::string
const& tag ) = 0;
1671 virtual void acceptChar(
char c ) = 0;
1685 void parse( std::string& description ) {
1687 description = m_remainder;
1691 virtual void acceptTag( std::string
const& tag ) {
1692 m_tags.insert(
toLower( tag ) );
1694 virtual void acceptChar(
char c ) {
1700 std::set<std::string>& m_tags;
1701 std::string m_remainder;
1707 : m_isNegated( false )
1710 Tag( std::string
const& name,
bool isNegated )
1712 m_isNegated( isNegated )
1722 bool operator ! ()
const {
1723 return m_name.empty();
1732 typedef std::map<std::string, Tag> TagMap;
1735 m_tags.insert( std::make_pair(
toLower( tag.
getName() ), tag ) );
1739 return m_tags.empty();
1742 bool matches( std::set<std::string>
const& tags )
const {
1743 TagMap::const_iterator it = m_tags.begin();
1744 TagMap::const_iterator itEnd = m_tags.end();
1745 for(; it != itEnd; ++it ) {
1746 bool found = tags.find( it->first ) != tags.end();
1747 if( found == it->second.isNegated() )
1759 bool matches( std::set<std::string>
const& tags )
const {
1760 std::vector<TagSet>::const_iterator it = m_tagSets.begin();
1761 std::vector<TagSet>::const_iterator itEnd = m_tagSets.end();
1762 for(; it != itEnd; ++it )
1763 if( it->matches( tags ) )
1771 std::vector<TagSet> m_tagSets;
1777 : m_isNegated( false ),
1784 virtual void acceptTag( std::string
const& tag ) {
1785 m_currentTagSet.add(
Tag( tag, m_isNegated ) );
1786 m_isNegated =
false;
1788 virtual void acceptChar(
char c ) {
1794 m_exp.m_tagSets.push_back( m_currentTagSet );
1798 virtual void endParse() {
1799 if( !m_currentTagSet.empty() )
1800 m_exp.m_tagSets.push_back( m_currentTagSet );
1824 enum WildcardPosition {
1826 WildcardAtStart = 1,
1828 WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
1833 : m_stringToMatch(
toLower( testSpec ) ),
1834 m_filterType( matchBehaviour ),
1835 m_wildcardPosition( NoWildcard )
1838 if(
startsWith( m_stringToMatch,
"exclude:" ) ) {
1839 m_stringToMatch = m_stringToMatch.substr( 8 );
1842 else if(
startsWith( m_stringToMatch,
"~" ) ) {
1843 m_stringToMatch = m_stringToMatch.substr( 1 );
1852 m_stringToMatch = m_stringToMatch.substr( 1 );
1853 m_wildcardPosition = (WildcardPosition)( m_wildcardPosition | WildcardAtStart );
1855 if(
endsWith( m_stringToMatch,
"*" ) ) {
1856 m_stringToMatch = m_stringToMatch.substr( 0, m_stringToMatch.size()-1 );
1857 m_wildcardPosition = (WildcardPosition)( m_wildcardPosition | WildcardAtEnd );
1862 return m_filterType;
1871 #pragma clang diagnostic push 1872 #pragma clang diagnostic ignored "-Wunreachable-code" 1875 bool isMatch(
TestCase const& testCase )
const {
1879 switch( m_wildcardPosition ) {
1881 return m_stringToMatch == name;
1882 case WildcardAtStart:
1883 return endsWith( name, m_stringToMatch );
1886 case WildcardAtBothEnds:
1887 return contains( name, m_stringToMatch );
1889 throw std::logic_error(
"Unhandled wildcard type" );
1893 #pragma clang diagnostic pop 1896 std::string m_stringToMatch;
1898 WildcardPosition m_wildcardPosition;
1911 m_exclusionFilters.push_back( filter );
1913 m_inclusionFilters.push_back( filter );
1920 m_tagExpressions.push_back( exp );
1924 if( !m_tagExpressions.empty() ) {
1925 std::vector<TagExpression>::const_iterator it = m_tagExpressions.begin();
1926 std::vector<TagExpression>::const_iterator itEnd = m_tagExpressions.end();
1927 for(; it != itEnd; ++it )
1928 if( it->matches( testCase.
getTags() ) )
1934 if( !m_inclusionFilters.empty() ) {
1935 std::vector<TestCaseFilter>::const_iterator it = m_inclusionFilters.begin();
1936 std::vector<TestCaseFilter>::const_iterator itEnd = m_inclusionFilters.end();
1937 for(; it != itEnd; ++it )
1938 if( it->shouldInclude( testCase ) )
1943 else if( m_exclusionFilters.empty() && m_tagExpressions.empty() ) {
1947 std::vector<TestCaseFilter>::const_iterator it = m_exclusionFilters.begin();
1948 std::vector<TestCaseFilter>::const_iterator itEnd = m_exclusionFilters.end();
1949 for(; it != itEnd; ++it )
1950 if( !it->shouldInclude( testCase ) )
1955 std::vector<TagExpression> m_tagExpressions;
1956 std::vector<TestCaseFilter> m_inclusionFilters;
1957 std::vector<TestCaseFilter> m_exclusionFilters;
1964 #define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED 1992 virtual bool allowThrows()
const = 0;
1993 virtual std::ostream& stream()
const = 0;
1994 virtual std::string name()
const = 0;
1995 virtual bool includeSuccessfulResults()
const = 0;
1996 virtual bool shouldDebugBreak()
const = 0;
1997 virtual bool warnAboutMissingAssertions()
const = 0;
1998 virtual int abortAfter()
const = 0;
2004 #define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED 2007 #define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED 2009 #include <streambuf> 2019 #include <stdexcept> 2024 template<
typename WriterF,
size_t bufferSize=256>
2026 char data[bufferSize];
2031 setp( data, data +
sizeof(data) );
2039 int overflow(
int c ) {
2043 if( pbase() == epptr() )
2044 m_writer( std::string( 1, static_cast<char>( c ) ) );
2046 sputc( static_cast<char>( c ) );
2052 if( pbase() != pptr() ) {
2053 m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
2054 setp( pbase(), epptr() );
2072 : streamBuf( NULL ), isOwned( false )
2075 Stream( std::streambuf* _streamBuf,
bool _isOwned )
2076 : streamBuf( _streamBuf ), isOwned( _isOwned )
2099 #ifndef CATCH_CONFIG_CONSOLE_WIDTH 2100 #define CATCH_CONFIG_CONSOLE_WIDTH 80 2108 : listTests( false ),
2110 listReporters( false ),
2111 showSuccessfulTests( false ),
2112 shouldDebugBreak( false ),
2148 virtual void dummy();
2152 : m_os(
std::cout.rdbuf() )
2157 m_os(
std::cout.rdbuf() )
2160 std::string groupName;
2161 for( std::size_t i = 0; i < data.
testsOrTags.size(); ++i ) {
2167 for( std::size_t i = 0; i < data.
testsOrTags.size(); ++i ) {
2174 m_filterSets.push_back( filters );
2179 m_os.rdbuf( std::cout.rdbuf() );
2184 m_data.outputFilename = filename;
2188 return m_data.outputFilename ;
2196 return m_data.processName;
2200 return m_data.shouldDebugBreak;
2204 m_os.rdbuf( buf ? buf : std::cout.rdbuf() );
2219 m_filterSets.push_back( filters );
2223 return m_data.abortAfter;
2226 std::vector<TestCaseFilters>
const&
filters()
const {
2227 return m_filterSets;
2234 virtual std::ostream&
stream()
const {
return m_os; }
2235 virtual std::string
name()
const {
return m_data.name.empty() ? m_data.processName : m_data.name; }
2244 mutable std::ostream m_os;
2245 std::vector<TestCaseFilters> m_filterSets;
2251 #define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED 2256 template<
typename T>
2261 : nullableValue( new( storage ) T( _value ) )
2264 : nullableValue( _other ? new( storage ) T( *_other ) : NULL )
2274 nullableValue =
new( storage ) T( *_other );
2279 nullableValue =
new( storage ) T( _value );
2285 nullableValue->~T();
2286 nullableValue = NULL;
2295 return nullableValue ? *nullableValue : defaultValue;
2298 bool some()
const {
return nullableValue != NULL; }
2299 bool none()
const {
return nullableValue == NULL; }
2301 bool operator !()
const {
return nullableValue == NULL; }
2308 char storage[
sizeof(T)];
2322 : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
2325 : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
2327 std::ostream&
stream()
const {
return *m_stream; }
2331 std::ostream* m_stream;
2337 : shouldRedirectStdOut( false )
2343 template<
typename T>
2364 std::size_t _groupIndex,
2365 std::size_t _groupsCount )
2367 groupIndex( _groupIndex ),
2368 groupsCounts( _groupsCount )
2378 std::string
const& _description,
2381 description( _description ),
2382 lineInfo( _lineInfo )
2392 std::vector<MessageInfo>
const& _infoMessages,
2394 : assertionResult( _assertionResult ),
2395 infoMessages( _infoMessages ),
2398 if( assertionResult.hasMessage() ) {
2401 MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
2402 builder << assertionResult.getMessage();
2405 infoMessages.push_back( builder.m_info );
2417 Counts const& _assertions,
2418 double _durationInSeconds,
2419 bool _missingAssertions )
2420 : sectionInfo( _sectionInfo ),
2421 assertions( _assertions ),
2422 durationInSeconds( _durationInSeconds ),
2423 missingAssertions( _missingAssertions )
2436 std::string
const& _stdOut,
2437 std::string
const& _stdErr,
2439 : testInfo( _testInfo ),
2443 aborting( _aborting )
2458 : groupInfo( _groupInfo ),
2460 aborting( _aborting )
2463 : groupInfo( _groupInfo ),
2477 : runInfo( _runInfo ),
2479 aborting( _aborting )
2482 : runInfo( _other.runInfo ),
2483 totals( _other.totals ),
2484 aborting( _other.aborting )
2501 virtual void noMatchingTestCases( std::string
const& spec ) = 0;
2503 virtual void testRunStarting(
TestRunInfo const& testRunInfo ) = 0;
2504 virtual void testGroupStarting(
GroupInfo const& groupInfo ) = 0;
2506 virtual void testCaseStarting(
TestCaseInfo const& testInfo ) = 0;
2507 virtual void sectionStarting(
SectionInfo const& sectionInfo ) = 0;
2509 virtual void assertionStarting(
AssertionInfo const& assertionInfo ) = 0;
2511 virtual bool assertionEnded(
AssertionStats const& assertionStats ) = 0;
2512 virtual void sectionEnded(
SectionStats const& sectionStats ) = 0;
2513 virtual void testCaseEnded(
TestCaseStats const& testCaseStats ) = 0;
2514 virtual void testGroupEnded(
TestGroupStats const& testGroupStats ) = 0;
2515 virtual void testRunEnded(
TestRunStats const& testRunStats ) = 0;
2521 : m_config( _config.fullConfig() ),
2522 stream( _config.stream() )
2530 currentTestRunInfo = _testRunInfo;
2533 currentGroupInfo = _groupInfo;
2537 currentTestCaseInfo = _testInfo;
2540 m_sectionStack.push_back( _sectionInfo );
2544 m_sectionStack.pop_back();
2547 currentTestCaseInfo.reset();
2548 assert( m_sectionStack.empty() );
2551 currentGroupInfo.reset();
2554 currentTestCaseInfo.reset();
2555 currentGroupInfo.reset();
2556 currentTestRunInfo.reset();
2570 template<
typename T,
typename ChildNodeT>
2572 explicit Node( T
const& _value ) : value( _value ) {}
2599 return node->stats.sectionInfo.lineInfo == other.
lineInfo;
2607 : m_config( _config.fullConfig() ),
2608 stream( _config.stream() )
2620 if( m_sectionStack.empty() ) {
2621 if( !m_rootSection )
2622 m_rootSection =
new SectionNode( incompleteStats );
2623 node = m_rootSection;
2627 SectionNode::ChildSections::const_iterator it =
2636 m_sectionStack.push_back( node );
2637 m_deepestSection = node;
2643 assert( !m_sectionStack.empty() );
2644 SectionNode& sectionNode = *m_sectionStack.back();
2645 sectionNode.
assertions.push_back( assertionStats );
2649 assert( !m_sectionStack.empty() );
2651 node.
stats = sectionStats;
2652 m_sectionStack.pop_back();
2656 assert( m_sectionStack.size() == 0 );
2657 node->children.push_back( m_rootSection );
2658 m_testCases.push_back( node );
2659 m_rootSection.
reset();
2661 assert( m_deepestSection );
2662 m_deepestSection->stdOut = testCaseStats.
stdOut;
2663 m_deepestSection->stdErr = testCaseStats.
stdErr;
2667 node->children.
swap( m_testCases );
2668 m_testGroups.push_back( node );
2672 node->children.
swap( m_testGroups );
2673 m_testRuns.push_back( node );
2676 virtual void testRunEnded() = 0;
2697 virtual bool shouldRedirectStdout()
const = 0;
2699 virtual void StartTesting() = 0;
2700 virtual void EndTesting(
Totals const& totals ) = 0;
2701 virtual void StartGroup( std::string
const& groupName ) = 0;
2702 virtual void EndGroup( std::string
const& groupName,
Totals const& totals ) = 0;
2703 virtual void StartTestCase(
TestCaseInfo const& testInfo ) = 0;
2704 virtual void EndTestCase(
TestCaseInfo const& testInfo,
Totals const& totals, std::string
const& stdOut, std::string
const& stdErr ) = 0;
2705 virtual void StartSection( std::string
const& sectionName, std::string
const& description ) = 0;
2706 virtual void EndSection( std::string
const& sectionName,
Counts const& assertions ) = 0;
2707 virtual void NoAssertionsInSection( std::string
const& sectionName ) = 0;
2708 virtual void NoAssertionsInTestCase( std::string
const& testName ) = 0;
2709 virtual void Aborted() = 0;
2716 virtual std::string getDescription()
const = 0;
2724 virtual FactoryMap
const& getFactories()
const = 0;
2727 inline std::string
trim( std::string
const& str ) {
2728 static char const* whitespaceChars =
"\n\r\t ";
2729 std::string::size_type start = str.find_first_not_of( whitespaceChars );
2730 std::string::size_type
end = str.find_last_not_of( whitespaceChars );
2732 return start != std::string::npos ? str.substr( start, 1+end-start ) :
"";
2755 virtual void registerReporter( std::string
const& name,
IReporterFactory* factory ) = 0;
2756 virtual void registerTest(
TestCase const& testInfo ) = 0;
2775 template<
typename MatcherT>
2777 std::string
const& matcherCallAsString ) {
2778 std::string matcherAsString = matcher.toString();
2779 if( matcherAsString ==
"{?}" )
2780 matcherAsString = matcherCallAsString;
2782 .
setRhs( matcherAsString )
2783 .
setOp(
"matches" );
2786 template<
typename MatcherT,
typename ArgT>
2789 std::string
const& matcherCallAsString ) {
2795 template<
typename MatcherT,
typename ArgT>
2798 std::string
const& matcherCallAsString ) {
2809 #define INTERNAL_CATCH_ASSERTIONINFO_NAME INTERNAL_CATCH_UNIQUE_NAME( __assertionInfo ) 2812 #define INTERNAL_CATCH_ACCEPT_EXPR( evaluatedExpr, resultDisposition, originalExpr ) \ 2813 if( Catch::ResultAction::Value internal_catch_action = Catch::getResultCapture().acceptExpression( evaluatedExpr, INTERNAL_CATCH_ASSERTIONINFO_NAME ) ) { \ 2814 if( internal_catch_action & Catch::ResultAction::Debug ) BreakIntoDebugger(); \ 2815 if( internal_catch_action & Catch::ResultAction::Abort ) throw Catch::TestFailureException(); \ 2816 if( !Catch::shouldContinueOnFailure( resultDisposition ) ) throw Catch::TestFailureException(); \ 2817 Catch::isTrue( false && originalExpr ); \ 2821 #define INTERNAL_CATCH_ACCEPT_INFO( expr, macroName, resultDisposition ) \ 2822 Catch::AssertionInfo INTERNAL_CATCH_ASSERTIONINFO_NAME( macroName, CATCH_INTERNAL_LINEINFO, expr, resultDisposition ); 2825 #define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \ 2827 INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, resultDisposition ); \ 2829 INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionDecomposer()->*expr ).endExpression( resultDisposition ), resultDisposition, expr ); \ 2830 } catch( Catch::TestFailureException& ) { \ 2833 INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException(), \ 2834 resultDisposition | Catch::ResultDisposition::ContinueOnFailure, expr ); \ 2836 } while( Catch::isTrue( false ) ) 2839 #define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \ 2840 INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \ 2841 if( Catch::getResultCapture().getLastResult()->succeeded() ) 2844 #define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \ 2845 INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \ 2846 if( !Catch::getResultCapture().getLastResult()->succeeded() ) 2849 #define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \ 2851 INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, resultDisposition ); \ 2854 INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::Ok ), resultDisposition, false ); \ 2857 INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException(), resultDisposition, false ); \ 2859 } while( Catch::isTrue( false ) ) 2862 #define INTERNAL_CATCH_THROWS_IMPL( expr, exceptionType, resultDisposition ) \ 2864 if( Catch::getCurrentContext().getConfig()->allowThrows() ) { \ 2866 INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::DidntThrowException ), resultDisposition, false ); \ 2869 catch( Catch::TestFailureException& ) { \ 2872 catch( exceptionType ) { \ 2873 INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::Ok ), resultDisposition, false ); \ 2877 #define INTERNAL_CATCH_THROWS( expr, exceptionType, resultDisposition, macroName ) \ 2879 INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, resultDisposition ); \ 2880 INTERNAL_CATCH_THROWS_IMPL( expr, exceptionType, resultDisposition ) \ 2881 } while( Catch::isTrue( false ) ) 2884 #define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \ 2886 INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, resultDisposition ); \ 2887 INTERNAL_CATCH_THROWS_IMPL( expr, exceptionType, resultDisposition ) \ 2889 INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException() ), \ 2890 resultDisposition | Catch::ResultDisposition::ContinueOnFailure, false ); \ 2892 } while( Catch::isTrue( false ) ) 2895 #define INTERNAL_CATCH_MSG( log, messageType, resultDisposition, macroName ) \ 2897 INTERNAL_CATCH_ACCEPT_INFO( "", macroName, resultDisposition ); \ 2898 INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( messageType ) << log, resultDisposition, true ) \ 2899 } while( Catch::isTrue( false ) ) 2902 #define INTERNAL_CATCH_INFO( log, macroName ) \ 2903 Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log; 2906 #define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \ 2908 INTERNAL_CATCH_ACCEPT_INFO( #arg " " #matcher, macroName, resultDisposition ); \ 2910 INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::expressionResultBuilderFromMatcher( ::Catch::Matchers::matcher, arg, #matcher ) ), resultDisposition, false ); \ 2911 } catch( Catch::TestFailureException& ) { \ 2914 INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException() ), \ 2915 resultDisposition | Catch::ResultDisposition::ContinueOnFailure, false ); \ 2917 } while( Catch::isTrue( false ) ) 2920 #define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED 2923 #define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED 2925 #ifdef CATCH_PLATFORM_WINDOWS 2926 typedef unsigned long long uint64_t;
2937 unsigned int getElapsedNanoseconds()
const;
2938 unsigned int getElapsedMilliseconds()
const;
2939 double getElapsedSeconds()
const;
2954 std::string
const& name,
2955 std::string
const& description =
"" )
2956 : m_info( name, description, lineInfo ),
2963 if( m_sectionIncluded )
2969 return m_sectionIncluded;
2977 bool m_sectionIncluded;
2983 #ifdef CATCH_CONFIG_VARIADIC_MACROS 2984 #define INTERNAL_CATCH_SECTION( ... ) \ 2985 if( Catch::Section INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::Section( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) 2987 #define INTERNAL_CATCH_SECTION( name, desc ) \ 2988 if( Catch::Section INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::Section( CATCH_INTERNAL_LINEINFO, name, desc ) ) 2992 #define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED 3001 template<
typename T>
3004 virtual T getValue( std::size_t index )
const = 0;
3005 virtual std::size_t size ()
const = 0;
3008 template<
typename T>
3014 return m_from+
static_cast<int>( index );
3018 return static_cast<std::size_t
>( 1+m_to-m_from );
3027 template<
typename T>
3033 m_values.push_back( value );
3037 return m_values[index];
3041 return m_values.size();
3045 std::vector<T> m_values;
3048 template<
typename T>
3055 : m_fileInfo( other.m_fileInfo ),
3062 m_fileInfo = fileInfo;
3070 operator T ()
const {
3073 typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
3074 typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
3075 for(
size_t index = 0; it != itEnd; ++it )
3078 if( overallIndex >= index && overallIndex < index + generator->size() )
3080 return generator->
getValue( overallIndex-index );
3082 index += generator->
size();
3089 m_totalSize += generator->
size();
3090 m_composed.push_back( generator );
3100 valuesGen->
add( value );
3108 std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
3109 m_totalSize += other.m_totalSize;
3110 other.m_composed.clear();
3113 std::vector<const IGenerator<T>*> m_composed;
3114 std::string m_fileInfo;
3118 namespace Generators
3120 template<
typename T>
3127 template<
typename T>
3131 valuesGen->
add( val1 );
3132 valuesGen->
add( val2 );
3133 generators.
add( valuesGen );
3137 template<
typename T>
3141 valuesGen->
add( val1 );
3142 valuesGen->
add( val2 );
3143 valuesGen->
add( val3 );
3144 generators.
add( valuesGen );
3148 template<
typename T>
3152 valuesGen->
add( val1 );
3153 valuesGen->
add( val2 );
3154 valuesGen->
add( val3 );
3155 valuesGen->
add( val4 );
3156 generators.
add( valuesGen );
3162 using namespace Generators;
3166 #define INTERNAL_CATCH_LINESTR2( line ) #line 3167 #define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line ) 3169 #define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" ) 3172 #define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED 3182 virtual std::string translate()
const = 0;
3192 template<
typename T>
3196 ExceptionTranslator( std::string(*translateFunction)( T& ) )
3197 : m_translateFunction( translateFunction )
3200 virtual std::string translate()
const {
3205 return m_translateFunction( ex );
3210 std::string(*m_translateFunction)( T& );
3214 template<
typename T>
3217 (
new ExceptionTranslator<T>( translateFunction ) );
3223 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) \ 3224 static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ); \ 3225 namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ) ); }\ 3226 static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ) 3229 #define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED 3240 : m_epsilon(
std::numeric_limits<float>::epsilon()*100 ),
3246 : m_epsilon( other.m_epsilon ),
3247 m_scale( other.m_scale ),
3248 m_value( other.m_value )
3258 approx.
scale( m_scale );
3264 return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
3271 friend bool operator != (
double lhs,
Approx const& rhs ) {
3275 friend bool operator != (
Approx const& lhs,
double rhs ) {
3280 m_epsilon = newEpsilon;
3290 std::ostringstream oss;
3291 oss <<
"Approx( " << m_value <<
" )";
3304 return value.toString();
3310 #define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED 3313 namespace Matchers {
3316 template<
typename ExpressionT>
3323 virtual bool match( ExpressionT
const& expr )
const = 0;
3324 virtual std::string
toString()
const = 0;
3327 template<
typename DerivedT,
typename ExpressionT>
3337 template<
typename ExpressionT>
3345 m_matchers.push_back( matcher.
clone() );
3348 virtual bool match( ExpressionT
const& expr )
const 3350 for( std::size_t i = 0; i < m_matchers.size(); ++i )
3351 if( !m_matchers[i]->match( expr ) )
3356 std::ostringstream oss;
3358 for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
3361 oss << m_matchers[i]->toString();
3368 std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
3371 template<
typename ExpressionT>
3379 m_matchers.push_back( matcher.
clone() );
3382 virtual bool match( ExpressionT
const& expr )
const 3384 for( std::size_t i = 0; i < m_matchers.size(); ++i )
3385 if( m_matchers[i]->match( expr ) )
3390 std::ostringstream oss;
3392 for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
3395 oss << m_matchers[i]->toString();
3402 std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
3407 namespace StdString {
3409 inline std::string
makeString( std::string
const& str ) {
return str; }
3410 inline std::string
makeString(
const char* str ) {
return str ? std::string( str ) : std::string(); }
3413 Equals( std::string
const& str ) : m_str( str ){}
3418 virtual bool match( std::string
const& expr )
const {
3419 return m_str == expr;
3422 return "equals: \"" + m_str +
"\"";
3429 Contains( std::string
const& substr ) : m_substr( substr ){}
3434 virtual bool match( std::string
const& expr )
const {
3435 return expr.find( m_substr ) != std::string::npos;
3438 return "contains: \"" + m_substr +
"\"";
3450 virtual bool match( std::string
const& expr )
const {
3451 return expr.find( m_substr ) == 0;
3454 return "starts with: \"" + m_substr +
"\"";
3461 EndsWith( std::string
const& substr ) : m_substr( substr ){}
3466 virtual bool match( std::string
const& expr )
const {
3467 return expr.find( m_substr ) == expr.size() - m_substr.size();
3470 return "ends with: \"" + m_substr +
"\"";
3480 template<
typename ExpressionT>
3485 template<
typename ExpressionT>
3491 template<
typename ExpressionT>
3496 template<
typename ExpressionT>
3530 using namespace Matchers;
3537 #define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED 3552 #define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED 3554 #import <objc/runtime.h> 3576 class OcMethod :
public SharedImpl<ITestCase> {
3579 OcMethod( Class cls,
SEL sel ) : m_cls( cls ), m_sel( sel ) {}
3581 virtual void invoke()
const {
3582 id obj = [[m_cls alloc] init];
3584 performOptionalSelector( obj,
@selector(setUp) );
3585 performOptionalSelector( obj, m_sel );
3586 performOptionalSelector( obj,
@selector(tearDown) );
3588 arcSafeRelease( obj );
3591 virtual ~OcMethod() {}
3599 inline bool startsWith( std::string
const& str, std::string
const& sub ) {
3600 return str.length() > sub.length() && str.substr( 0, sub.length() ) == sub;
3603 inline std::string getAnnotation( Class cls,
3604 std::string
const& annotationName,
3605 std::string
const& testCaseName ) {
3606 NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
3607 SEL sel = NSSelectorFromString( selStr );
3608 arcSafeRelease( selStr );
3609 id value = performOptionalSelector( cls, sel );
3611 return [(NSString*)value UTF8String];
3616 inline size_t registerTestMethods() {
3617 size_t noTestMethods = 0;
3618 int noClasses = objc_getClassList( NULL, 0 );
3620 Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc(
sizeof(Class) * noClasses);
3621 objc_getClassList( classes, noClasses );
3623 for(
int c = 0; c < noClasses; c++ ) {
3624 Class cls = classes[c];
3627 Method* methods = class_copyMethodList( cls, &count );
3628 for( u_int m = 0; m < count ; m++ ) {
3629 SEL selector = method_getName(methods[m]);
3630 std::string methodName = sel_getName(selector);
3632 std::string testCaseName = methodName.substr( 15 );
3633 std::string name = Detail::getAnnotation( cls,
"Name", testCaseName );
3634 std::string desc = Detail::getAnnotation( cls,
"Description", testCaseName );
3635 const char* className = class_getName( cls );
3644 return noTestMethods;
3647 namespace Matchers {
3649 namespace NSStringMatchers {
3651 template<
typename MatcherT>
3652 struct StringHolder : MatcherImpl<MatcherT, NSString*>{
3653 StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
3654 StringHolder( StringHolder
const& other ) : m_substr( [other.m_substr copy] ){}
3656 arcSafeRelease( m_substr );
3663 Equals( NSString* substr ) : StringHolder( substr ){}
3665 virtual bool match( ExpressionType
const& str )
const {
3666 return (str != nil || m_substr == nil ) &&
3667 [str isEqualToString:m_substr];
3670 virtual std::string
toString()
const {
3676 Contains( NSString* substr ) : StringHolder( substr ){}
3678 virtual bool match( ExpressionType
const& str )
const {
3679 return (str != nil || m_substr == nil ) &&
3680 [str rangeOfString:m_substr].location != NSNotFound;
3683 virtual std::string
toString()
const {
3689 StartsWith( NSString* substr ) : StringHolder( substr ){}
3691 virtual bool match( ExpressionType
const& str )
const {
3692 return (str != nil || m_substr == nil ) &&
3693 [str rangeOfString:m_substr].location == 0;
3696 virtual std::string
toString()
const {
3701 EndsWith( NSString* substr ) : StringHolder( substr ){}
3703 virtual bool match( ExpressionType
const& str )
const {
3704 return (str != nil || m_substr == nil ) &&
3705 [str rangeOfString:m_substr].location == [str length] - [m_substr length];
3708 virtual std::string
toString()
const {
3730 using namespace Matchers;
3735 #define OC_TEST_CASE( name, desc )\ 3736 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \ 3740 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \ 3744 -(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test ) 3748 #if defined( CATCH_CONFIG_MAIN ) || defined( CATCH_CONFIG_RUNNER ) 3750 #define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED 3756 #pragma clang diagnostic push 3757 #pragma clang diagnostic ignored "-Wweak-vtables" 3761 #define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED 3764 #define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED 3767 #define TWOBLUECUBES_CLARA_H_INCLUDED 3770 #define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED 3777 struct TextAttributes {
3779 : initialIndent( std::string::npos ),
3785 TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value;
return *
this; }
3786 TextAttributes& setIndent( std::size_t _value ) { indent = _value;
return *
this; }
3787 TextAttributes& setWidth( std::size_t _value ) { width = _value;
return *
this; }
3788 TextAttributes& setTabChar(
char _value ) { tabChar = _value;
return *
this; }
3790 std::size_t initialIndent;
3798 Text( std::string
const& _str, TextAttributes
const& _attr = TextAttributes() );
3799 void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos );
3801 typedef std::vector<std::string>::const_iterator const_iterator;
3803 const_iterator
begin()
const {
return lines.begin(); }
3804 const_iterator
end()
const {
return lines.end(); }
3805 std::string
const& last()
const {
return lines.back(); }
3806 std::size_t size()
const {
return lines.size(); }
3807 std::string
const& operator[]( std::size_t _index )
const {
return lines[_index]; }
3810 friend std::ostream&
operator << ( std::ostream& _stream, Text
const& _text );
3814 TextAttributes attr;
3815 std::vector<std::string> lines;
3822 template<
typename T>
struct RemoveConstRef{
typedef T type; };
3823 template<
typename T>
struct RemoveConstRef<T&>{
typedef T type; };
3824 template<
typename T>
struct RemoveConstRef<T const&>{
typedef T type; };
3825 template<
typename T>
struct RemoveConstRef<T const>{
typedef T type; };
3827 template<
typename T>
struct IsBool {
static const bool value =
false; };
3828 template<>
struct IsBool<bool> {
static const bool value =
true; };
3830 template<
typename T>
3831 void convertInto( std::string
const& _source, T& _dest ) {
3832 std::stringstream ss;
3836 throw std::runtime_error(
"Unable to convert " + _source +
" to destination type" );
3838 inline void convertInto( std::string
const& _source, std::string& _dest ) {
3841 inline void convertInto( std::string
const& _source,
bool& _dest ) {
3842 std::string sourceLC = _source;
3843 std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower );
3844 if( sourceLC ==
"y" || sourceLC ==
"1" || sourceLC ==
"true" || sourceLC ==
"yes" || sourceLC ==
"on" )
3846 else if( sourceLC ==
"n" || sourceLC ==
"0" || sourceLC ==
"false" || sourceLC ==
"no" || sourceLC ==
"off" )
3849 throw std::runtime_error(
"Expected a boolean value but did not recognise:\n '" + _source +
"'" );
3851 inline void convertInto(
bool _source,
bool& _dest ) {
3854 template<
typename T>
3855 inline void convertInto(
bool, T& ) {
3856 throw std::runtime_error(
"Invalid conversion" );
3859 template<
typename ConfigT>
3860 struct IArgFunction {
3861 virtual ~IArgFunction() {}
3862 virtual void set( ConfigT& config, std::string
const& value )
const = 0;
3863 virtual void setFlag( ConfigT& config )
const = 0;
3864 virtual bool takesArg()
const = 0;
3865 virtual IArgFunction* clone()
const = 0;
3868 template<
typename ConfigT>
3869 class BoundArgFunction {
3871 BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
3872 BoundArgFunction( BoundArgFunction
const& other ) : functionObj( other.functionObj->clone() ) {}
3873 BoundArgFunction& operator = ( BoundArgFunction
const& other ) {
3874 IArgFunction<ConfigT>* newFunctionObj = other.functionObj->clone();
3876 functionObj = newFunctionObj;
3879 ~BoundArgFunction() {
delete functionObj; }
3881 void set( ConfigT& config, std::string
const& value )
const {
3882 functionObj->set( config, value );
3884 void setFlag( ConfigT& config )
const {
3885 functionObj->setFlag( config );
3887 bool takesArg()
const {
return functionObj->takesArg(); }
3889 IArgFunction<ConfigT>* functionObj;
3892 template<
typename C>
3893 struct NullBinder : IArgFunction<C>{
3894 virtual void set( C&, std::string
const& )
const {}
3895 virtual void setFlag( C& )
const {}
3896 virtual bool takesArg()
const {
return true; }
3897 virtual IArgFunction<C>* clone()
const {
return new NullBinder( *
this ); }
3900 template<
typename C,
typename M>
3901 struct BoundDataMember : IArgFunction<C>{
3902 BoundDataMember( M C::* _member ) : member( _member ) {}
3903 virtual void set( C& p, std::string
const& stringValue )
const {
3904 convertInto( stringValue, p.*member );
3906 virtual void setFlag( C& p )
const {
3907 convertInto(
true, p.*member );
3909 virtual bool takesArg()
const {
return !IsBool<M>::value; }
3910 virtual IArgFunction<C>* clone()
const {
return new BoundDataMember( *
this ); }
3913 template<
typename C,
typename M>
3914 struct BoundUnaryMethod : IArgFunction<C>{
3915 BoundUnaryMethod(
void (C::*_member)( M ) ) : member( _member ) {}
3916 virtual void set( C& p, std::string
const& stringValue )
const {
3917 typename RemoveConstRef<M>::type value;
3918 convertInto( stringValue, value );
3919 (p.*member)( value );
3921 virtual void setFlag( C& p )
const {
3922 typename RemoveConstRef<M>::type value;
3923 convertInto(
true, value );
3924 (p.*member)( value );
3926 virtual bool takesArg()
const {
return !IsBool<M>::value; }
3927 virtual IArgFunction<C>* clone()
const {
return new BoundUnaryMethod( *
this ); }
3928 void (C::*member)( M );
3930 template<
typename C>
3931 struct BoundNullaryMethod : IArgFunction<C>{
3932 BoundNullaryMethod(
void (C::*_member)() ) : member( _member ) {}
3933 virtual void set( C& p, std::string
const& stringValue )
const {
3935 convertInto( stringValue, value );
3939 virtual void setFlag( C& p )
const {
3942 virtual bool takesArg()
const {
return false; }
3943 virtual IArgFunction<C>* clone()
const {
return new BoundNullaryMethod( *
this ); }
3944 void (C::*member)();
3947 template<
typename C>
3948 struct BoundUnaryFunction : IArgFunction<C>{
3949 BoundUnaryFunction(
void (*_function)( C& ) ) :
function( _function ) {}
3950 virtual void set( C& obj, std::string
const& stringValue )
const {
3952 convertInto( stringValue, value );
3956 virtual void setFlag( C& p )
const {
3959 virtual bool takesArg()
const {
return false; }
3960 virtual IArgFunction<C>* clone()
const {
return new BoundUnaryFunction( *
this ); }
3961 void (*
function)( C& );
3964 template<
typename C,
typename T>
3965 struct BoundBinaryFunction : IArgFunction<C>{
3966 BoundBinaryFunction(
void (*_function)( C&, T ) ) :
function( _function ) {}
3967 virtual void set( C& obj, std::string
const& stringValue )
const {
3968 typename RemoveConstRef<T>::type value;
3969 convertInto( stringValue, value );
3970 function( obj, value );
3972 virtual void setFlag( C& obj )
const {
3973 typename RemoveConstRef<T>::type value;
3974 convertInto(
true, value );
3975 function( obj, value );
3977 virtual bool takesArg()
const {
return !IsBool<T>::value; }
3978 virtual IArgFunction<C>* clone()
const {
return new BoundBinaryFunction( *
this ); }
3979 void (*
function)( C&, T );
3982 template<
typename C,
typename M>
3983 BoundArgFunction<C> makeBoundField( M C::* _member ) {
3984 return BoundArgFunction<C>(
new BoundDataMember<C,M>( _member ) );
3986 template<
typename C,
typename M>
3987 BoundArgFunction<C> makeBoundField(
void (C::*_member)( M ) ) {
3988 return BoundArgFunction<C>(
new BoundUnaryMethod<C,M>( _member ) );
3990 template<
typename C>
3991 BoundArgFunction<C> makeBoundField(
void (C::*_member)() ) {
3992 return BoundArgFunction<C>(
new BoundNullaryMethod<C>( _member ) );
3994 template<
typename C>
3995 BoundArgFunction<C> makeBoundField(
void (*_function)( C& ) ) {
3996 return BoundArgFunction<C>(
new BoundUnaryFunction<C>( _function ) );
3998 template<
typename C,
typename T>
3999 BoundArgFunction<C> makeBoundField(
void (*_function)( C&, T ) ) {
4000 return BoundArgFunction<C>(
new BoundBinaryFunction<C, T>( _function ) );
4005 Parser() : separators(
" \t=:" ) {}
4008 enum Type { Positional, ShortOpt, LongOpt };
4009 Token( Type _type, std::string
const& _data ) : type( _type ), data( _data ) {}
4014 void parseIntoTokens(
int argc,
char const *
const * argv, std::vector<Parser::Token>& tokens )
const {
4015 for(
int i = 1; i < argc; ++i )
4016 parseIntoTokens( argv[i] , tokens);
4018 void parseIntoTokens( std::string arg, std::vector<Parser::Token>& tokens )
const {
4019 while( !arg.empty() ) {
4020 Parser::Token token( Parser::Token::Positional, arg );
4022 if( token.data[0] ==
'-' ) {
4023 if( token.data.size() > 1 && token.data[1] ==
'-' ) {
4024 token = Parser::Token( Parser::Token::LongOpt, token.data.substr( 2 ) );
4027 token = Parser::Token( Parser::Token::ShortOpt, token.data.substr( 1 ) );
4028 if( token.data.size() > 1 && separators.find( token.data[1] ) == std::string::npos ) {
4029 arg =
"-" + token.data.substr( 1 );
4030 token.data = token.data.substr( 0, 1 );
4034 if( token.type != Parser::Token::Positional ) {
4035 std::size_t pos = token.data.find_first_of( separators );
4036 if( pos != std::string::npos ) {
4037 arg = token.data.substr( pos+1 );
4038 token.data = token.data.substr( 0, pos );
4041 tokens.push_back( token );
4044 std::string separators;
4047 template<
typename ConfigT>
4051 Arg( Detail::BoundArgFunction<ConfigT>
const& _boundField ) : boundField( _boundField ), position( -1 ) {}
4053 bool hasShortName( std::string
const& shortName )
const {
4054 for( std::vector<std::string>::const_iterator
4055 it = shortNames.begin(), itEnd = shortNames.end();
4058 if( *it == shortName )
4062 bool hasLongName( std::string
const& _longName )
const {
4063 return _longName == longName;
4065 bool takesArg()
const {
4066 return !hint.empty();
4068 bool isFixedPositional()
const {
4069 return position != -1;
4071 bool isAnyPositional()
const {
4072 return position == -1 && shortNames.empty() && longName.empty();
4074 std::string dbgName()
const {
4075 if( !longName.empty() )
4076 return "--" + longName;
4077 if( !shortNames.empty() )
4078 return "-" + shortNames[0];
4079 return "positional args";
4081 void validate()
const {
4082 if( boundField.takesArg() && !takesArg() )
4083 throw std::logic_error( dbgName() +
" must specify an arg name" );
4085 std::string commands()
const {
4086 std::ostringstream oss;
4088 std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
4089 for(; it != itEnd; ++it ) {
4096 if( !longName.empty() ) {
4099 oss <<
"--" << longName;
4102 oss <<
" <" << hint <<
">";
4106 Detail::BoundArgFunction<ConfigT> boundField;
4107 std::vector<std::string> shortNames;
4108 std::string longName;
4109 std::string description;
4116 template<
typename F>
4117 ArgBinder( CommandLine* cl, F f )
4119 m_arg( Detail::makeBoundField( f ) )
4121 ArgBinder( ArgBinder& other )
4122 : m_cl( other.m_cl ),
4123 m_arg( other.m_arg )
4130 if( m_arg.isFixedPositional() ) {
4131 m_cl->m_positionalArgs.insert( std::make_pair( m_arg.position, m_arg ) );
4132 if( m_arg.position > m_cl->m_highestSpecifiedArgPosition )
4133 m_cl->m_highestSpecifiedArgPosition = m_arg.position;
4135 else if( m_arg.isAnyPositional() ) {
4136 if( m_cl->m_arg.get() )
4137 throw std::logic_error(
"Only one unpositional argument can be added" );
4138 m_cl->m_arg = std::auto_ptr<Arg>(
new Arg( m_arg ) );
4141 m_cl->m_options.push_back( m_arg );
4144 ArgBinder& shortOpt( std::string
const& name ) {
4145 m_arg.shortNames.push_back( name );
4148 ArgBinder& longOpt( std::string
const& name ) {
4149 m_arg.longName = name;
4152 ArgBinder& describe( std::string
const& description ) {
4153 m_arg.description = description;
4156 ArgBinder& hint( std::string
const& hint ) {
4160 ArgBinder& position(
int position ) {
4161 m_arg.position = position;
4172 : m_boundProcessName(
new Detail::NullBinder<ConfigT>() ),
4173 m_highestSpecifiedArgPosition( 0 )
4175 CommandLine( CommandLine
const& other )
4176 : m_boundProcessName( other.m_boundProcessName ),
4177 m_options ( other.m_options ),
4178 m_positionalArgs( other.m_positionalArgs ),
4179 m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition )
4181 if( other.m_arg.get() )
4182 m_arg = std::auto_ptr<Arg>(
new Arg( *other.m_arg ) );
4185 template<
typename F>
4186 ArgBinder bind( F f ) {
4187 ArgBinder binder(
this, f );
4190 template<
typename F>
4191 void bindProcessName( F f ) {
4192 m_boundProcessName = Detail::makeBoundField( f );
4196 typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
4197 std::size_t maxWidth = 0;
4198 for( it = itBegin; it != itEnd; ++it )
4199 maxWidth = (std::max)( maxWidth, it->commands().size() );
4201 for( it = itBegin; it != itEnd; ++it ) {
4202 Catch::Text usage( it->commands(), Catch::TextAttributes()
4203 .setWidth( maxWidth+indent )
4204 .setIndent( indent ) );
4206 Catch::Text desc( it->description, Catch::TextAttributes()
4207 .setWidth( width - maxWidth -3 ) );
4209 for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {
4210 std::string usageCol = i < usage.size() ? usage[i] :
"";
4213 if( i < desc.size() && !desc[i].empty() )
4214 os << std::string( indent + 2 + maxWidth - usageCol.size(),
' ' )
4220 std::string optUsage()
const {
4221 std::ostringstream oss;
4226 void argSynopsis( std::ostream& os )
const {
4227 for(
int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
4230 typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
4231 if( it != m_positionalArgs.end() )
4232 os <<
"<" << it->second.hint <<
">";
4233 else if( m_arg.get() )
4234 os <<
"<" << m_arg->hint <<
">";
4236 throw std::logic_error(
"non consecutive positional arguments with no floating args" );
4240 if( m_highestSpecifiedArgPosition > 1 )
4242 os <<
"[<" << m_arg->hint <<
"> ...]";
4245 std::string argSynopsis()
const {
4246 std::ostringstream oss;
4251 void usage( std::ostream& os, std::string
const& procName )
const {
4252 os <<
"usage:\n " << procName <<
" ";
4254 if( !m_options.empty() ) {
4255 os <<
" [options]\n\nwhere options are: \n";
4260 std::string usage( std::string
const& procName )
const {
4261 std::ostringstream oss;
4262 usage( oss, procName );
4266 std::vector<Parser::Token> parseInto(
int argc,
char const *
const * argv, ConfigT& config )
const {
4267 std::string processName = argv[0];
4268 std::size_t lastSlash = processName.find_last_of(
"/\\" );
4269 if( lastSlash != std::string::npos )
4270 processName = processName.substr( lastSlash+1 );
4271 m_boundProcessName.set( config, processName );
4272 std::vector<Parser::Token> tokens;
4274 parser.parseIntoTokens( argc, argv, tokens );
4275 return populate( tokens, config );
4278 std::vector<Parser::Token> populate( std::vector<Parser::Token>
const& tokens, ConfigT& config )
const {
4279 if( m_options.empty() && m_positionalArgs.empty() )
4280 throw std::logic_error(
"No options or arguments specified" );
4282 std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );
4283 unusedTokens = populateFixedArgs( unusedTokens, config );
4284 unusedTokens = populateFloatingArgs( unusedTokens, config );
4285 return unusedTokens;
4288 std::vector<Parser::Token> populateOptions( std::vector<Parser::Token>
const& tokens, ConfigT& config )
const {
4289 std::vector<Parser::Token> unusedTokens;
4290 for( std::size_t i = 0; i < tokens.size(); ++i ) {
4291 Parser::Token
const& token = tokens[i];
4292 typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
4293 for(; it != itEnd; ++it ) {
4294 Arg
const& arg = *it;
4297 if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
4298 ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
4299 if( arg.takesArg() ) {
4300 if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )
4301 throw std::domain_error(
"Expected argument to option " + token.data );
4302 arg.boundField.set( config, tokens[++i].data );
4305 arg.boundField.setFlag( config );
4310 catch( std::exception& ex ) {
4311 throw std::runtime_error( std::string( ex.what() ) +
"\n- while parsing: (" + arg.commands() +
")" );
4315 unusedTokens.push_back( token );
4317 return unusedTokens;
4319 std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token>
const& tokens, ConfigT& config )
const {
4320 std::vector<Parser::Token> unusedTokens;
4322 for( std::size_t i = 0; i < tokens.size(); ++i ) {
4323 Parser::Token
const& token = tokens[i];
4324 typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
4325 if( it != m_positionalArgs.end() )
4326 it->second.boundField.set( config, token.data );
4328 unusedTokens.push_back( token );
4329 if( token.type == Parser::Token::Positional )
4332 return unusedTokens;
4334 std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token>
const& tokens, ConfigT& config )
const {
4337 std::vector<Parser::Token> unusedTokens;
4338 for( std::size_t i = 0; i < tokens.size(); ++i ) {
4339 Parser::Token
const& token = tokens[i];
4340 if( token.type == Parser::Token::Positional )
4341 m_arg->boundField.set( config, token.data );
4343 unusedTokens.push_back( token );
4345 return unusedTokens;
4349 Detail::BoundArgFunction<ConfigT> m_boundProcessName;
4350 std::vector<Arg> m_options;
4351 std::map<int, Arg> m_positionalArgs;
4352 std::auto_ptr<Arg> m_arg;
4353 int m_highestSpecifiedArgPosition;
4361 inline void abortAfterX(
ConfigData& config,
int x ) {
4363 throw std::runtime_error(
"Value after -x or --abortAfter must be greater than zero" );
4366 inline void addTestOrTags(
ConfigData& config, std::string
const& _testSpec ) { config.
testsOrTags.push_back( _testSpec ); }
4368 inline void addWarning(
ConfigData& config, std::string
const& _warning ) {
4369 if( _warning ==
"NoAssertions" )
4372 throw std::runtime_error(
"Unrecognised warning: '" + _warning +
"'" );
4375 inline void setVerbosity(
ConfigData& config,
int level ) {
4379 inline void setShowDurations(
ConfigData& config,
bool _showDurations ) {
4385 inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
4387 Clara::CommandLine<ConfigData> cli;
4392 .describe(
"display usage information" )
4398 .describe(
"list all (or matching) test cases" )
4400 .longOpt(
"list-tests" );
4403 .describe(
"list all (or matching) tags" )
4405 .longOpt(
"list-tags" );
4408 .describe(
"list all reporters" )
4409 .longOpt(
"list-reporters" );
4412 .describe(
"include successful tests in output" )
4414 .longOpt(
"success" );
4417 .describe(
"break into debugger on failure" )
4419 .longOpt(
"break" );
4422 .describe(
"skip exception tests" )
4424 .longOpt(
"nothrow" );
4427 .describe(
"output filename" )
4430 .hint(
"filename" );
4433 .describe(
"reporter to use - defaults to console" )
4435 .longOpt(
"reporter" )
4440 .describe(
"suite name" )
4445 cli.bind( &abortAfterFirst )
4446 .describe(
"abort at first failure" )
4448 .longOpt(
"abort" );
4450 cli.bind( &abortAfterX )
4451 .describe(
"abort after x failures" )
4453 .longOpt(
"abortx" )
4454 .hint(
"number of failures" );
4456 cli.bind( &addWarning )
4457 .describe(
"enable warnings" )
4460 .hint(
"warning name" );
4468 cli.bind( &addTestOrTags )
4469 .describe(
"which test or tests to use" )
4470 .hint(
"test name, pattern or tags" );
4472 cli.bind( &setShowDurations )
4473 .describe(
"show test durations" )
4475 .longOpt(
"durations" )
4484 #define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED 4487 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED 4509 BrightRed = Bright | Red,
4510 BrightGreen = Bright | Green,
4511 LightGrey = Bright | Grey,
4512 BrightWhite = Bright | White,
4515 FileName = LightGrey,
4516 ResultError = BrightRed,
4517 ResultSuccess = BrightGreen,
4522 OriginalExpression = Cyan,
4523 ReconstructedExpression = Yellow,
4525 SecondaryText = LightGrey,
4530 Colour( Code _colourCode );
4534 static void use( Code _colourCode );
4537 static Detail::IColourImpl* impl;
4543 #include <algorithm> 4546 inline bool matchesFilters( std::vector<TestCaseFilters>
const& filters,
TestCase const& testCase ) {
4547 std::vector<TestCaseFilters>::const_iterator it = filters.begin();
4548 std::vector<TestCaseFilters>::const_iterator itEnd = filters.end();
4549 for(; it != itEnd; ++it )
4550 if( !it->shouldInclude( testCase ) )
4555 inline std::size_t listTests(
Config const& config ) {
4556 if( config.
filters().empty() )
4557 std::cout <<
"All available test cases:\n";
4559 std::cout <<
"Matching test cases:\n";
4561 std::vector<TestCase>::const_iterator it = allTests.begin(), itEnd = allTests.end();
4564 std::size_t maxTagLen = 0;
4565 std::size_t maxNameLen = 0;
4566 for(; it != itEnd; ++it ) {
4567 if( matchesFilters( config.
filters(), *it ) ) {
4568 maxTagLen = (std::max)( it->getTestCaseInfo().tagsAsString.size(), maxTagLen );
4569 maxNameLen = (std::max)( it->getTestCaseInfo().name.size(), maxNameLen );
4576 if( maxTagLen > 30 )
4582 std::size_t matchedTests = 0;
4583 for( it = allTests.begin(); it != itEnd; ++it ) {
4584 if( matchesFilters( config.
filters(), *it ) ) {
4586 Text nameWrapper( it->getTestCaseInfo().name,
4588 .setWidth( maxNameLen )
4589 .setInitialIndent(2)
4592 Text tagsWrapper( it->getTestCaseInfo().tagsAsString,
4594 .setWidth( maxTagLen )
4595 .setInitialIndent(0)
4598 for( std::size_t i = 0; i < (std::max)( nameWrapper.size(), tagsWrapper.size() ); ++i ) {
4599 Colour::Code colour = Colour::None;
4600 if( it->getTestCaseInfo().isHidden )
4601 colour = Colour::SecondaryText;
4602 std::string nameCol;
4603 if( i < nameWrapper.size() ) {
4604 nameCol = nameWrapper[i];
4608 colour = Colour::SecondaryText;
4612 Colour colourGuard( colour );
4613 std::cout << nameCol;
4615 if( i < tagsWrapper.size() && !tagsWrapper[i].empty() ) {
4617 Colour colourGuard( Colour::SecondaryText );
4618 std::cout <<
" " << std::string( maxNameLen - nameCol.size(),
'.' ) <<
" ";
4621 std::cout << std::string( maxNameLen - nameCol.size(),
' ' ) <<
" ";
4623 std::cout << tagsWrapper[i];
4629 if( config.
filters().empty() )
4630 std::cout <<
pluralise( matchedTests,
"test case" ) <<
"\n" << std::endl;
4632 std::cout <<
pluralise( matchedTests,
"matching test case" ) <<
"\n" << std::endl;
4633 return matchedTests;
4636 inline std::size_t listTags(
Config const& config ) {
4637 if( config.
filters().empty() )
4638 std::cout <<
"All available tags:\n";
4640 std::cout <<
"Matching tags:\n";
4642 std::vector<TestCase>::const_iterator it = allTests.begin(), itEnd = allTests.end();
4644 std::map<std::string, int> tagCounts;
4646 std::size_t maxTagLen = 0;
4648 for(; it != itEnd; ++it ) {
4649 if( matchesFilters( config.
filters(), *it ) ) {
4650 for( std::set<std::string>::const_iterator tagIt = it->getTestCaseInfo().tags.begin(),
4651 tagItEnd = it->getTestCaseInfo().tags.end();
4654 std::string tagName = *tagIt;
4655 maxTagLen = (std::max)( maxTagLen, tagName.size() );
4656 std::map<std::string, int>::iterator countIt = tagCounts.find( tagName );
4657 if( countIt == tagCounts.end() )
4658 tagCounts.insert( std::make_pair( tagName, 1 ) );
4668 for( std::map<std::string, int>::const_iterator countIt = tagCounts.begin(), countItEnd = tagCounts.end();
4669 countIt != countItEnd;
4671 Text wrapper(
"[" + countIt->first +
"]", TextAttributes()
4673 .setWidth( maxTagLen ) );
4674 std::cout << wrapper;
4675 std::size_t dots = 2;
4676 if( maxTagLen > wrapper.last().size() )
4677 dots += maxTagLen - wrapper.last().size();
4679 Colour colourGuard( Colour::SecondaryText );
4680 std::cout << std::string( dots,
'.' );
4682 std::cout << countIt->second
4685 std::cout <<
pluralise( tagCounts.size(),
"tag" ) <<
"\n" << std::endl;
4686 return tagCounts.size();
4689 inline std::size_t listReporters(
Config const& ) {
4690 std::cout <<
"Available reports:\n";
4692 IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
4693 std::size_t maxNameLen = 0;
4694 for(it = itBegin; it != itEnd; ++it )
4695 maxNameLen = (std::max)( maxNameLen, it->first.size() );
4697 for(it = itBegin; it != itEnd; ++it ) {
4698 Text wrapper( it->second->getDescription(), TextAttributes()
4699 .setInitialIndent( 0 )
4700 .setIndent( 7+maxNameLen )
4705 << std::string( maxNameLen - it->first.size() + 2,
' ' )
4708 std::cout << std::endl;
4709 return factories.size();
4715 listedCount = listedCount.
valueOr(0) + listTests( config );
4717 listedCount = listedCount.
valueOr(0) + listTags( config );
4719 listedCount = listedCount.
valueOr(0) + listReporters( config );
4726 #define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED 4729 #define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED 4736 namespace SectionTracking {
4738 class TrackedSection {
4740 typedef std::map<std::string, TrackedSection> TrackedSections;
4750 TrackedSection( std::string
const& name, TrackedSection* parent )
4751 : m_name( name ), m_runState( NotStarted ), m_parent( parent )
4754 RunState runState()
const {
return m_runState; }
4756 void addChild( std::string
const& childName ) {
4757 m_children.insert( std::make_pair( childName, TrackedSection( childName,
this ) ) );
4759 TrackedSection* getChild( std::string
const& childName ) {
4760 return &m_children.find( childName )->second;
4764 if( m_runState == NotStarted )
4765 m_runState = Executing;
4768 for( TrackedSections::const_iterator it = m_children.begin(), itEnd = m_children.end();
4771 if( it->second.runState() != Completed ) {
4772 m_runState = ExecutingChildren;
4775 m_runState = Completed;
4777 TrackedSection* getParent() {
4780 bool hasChildren()
const {
4781 return !m_children.empty();
4786 RunState m_runState;
4787 TrackedSections m_children;
4788 TrackedSection* m_parent;
4792 class TestCaseTracker {
4794 TestCaseTracker( std::string
const& testCaseName )
4795 : m_testCase( testCaseName, NULL ),
4796 m_currentSection( &m_testCase ),
4797 m_completedASectionThisRun(
false )
4800 bool enterSection( std::string
const& name ) {
4801 if( m_completedASectionThisRun )
4803 if( m_currentSection->runState() == TrackedSection::Executing ) {
4804 m_currentSection->addChild( name );
4808 TrackedSection* child = m_currentSection->getChild( name );
4809 if( child->runState() != TrackedSection::Completed ) {
4810 m_currentSection = child;
4811 m_currentSection->enter();
4817 void leaveSection() {
4818 m_currentSection->leave();
4819 m_currentSection = m_currentSection->getParent();
4820 assert( m_currentSection != NULL );
4821 m_completedASectionThisRun =
true;
4824 bool currentSectionHasChildren()
const {
4825 return m_currentSection->hasChildren();
4827 bool isCompleted()
const {
4828 return m_testCase.runState() == TrackedSection::Completed;
4833 Guard( TestCaseTracker& tracker )
4834 : m_tracker( tracker )
4836 m_tracker.enterTestCase();
4839 m_tracker.leaveTestCase();
4842 Guard( Guard
const& );
4843 void operator = ( Guard
const& );
4844 TestCaseTracker& m_tracker;
4848 void enterTestCase() {
4849 m_currentSection = &m_testCase;
4850 m_completedASectionThisRun =
false;
4853 void leaveTestCase() {
4857 TrackedSection m_testCase;
4858 TrackedSection* m_currentSection;
4859 bool m_completedASectionThisRun;
4864 using SectionTracking::TestCaseTracker;
4873 class StreamRedirect {
4876 StreamRedirect( std::ostream& stream, std::string& targetString )
4877 : m_stream( stream ),
4878 m_prevBuf( stream.rdbuf() ),
4879 m_targetString( targetString )
4881 stream.rdbuf( m_oss.rdbuf() );
4885 m_targetString += m_oss.str();
4886 m_stream.rdbuf( m_prevBuf );
4890 std::ostream& m_stream;
4891 std::streambuf* m_prevBuf;
4892 std::ostringstream m_oss;
4893 std::string& m_targetString;
4900 RunContext( RunContext
const& );
4901 void operator =( RunContext
const& );
4906 : m_runInfo( config->name() ),
4908 m_activeTestCase( NULL ),
4910 m_reporter( reporter ),
4911 m_prevRunner( &m_context.getRunner() ),
4912 m_prevResultCapture( &m_context.getResultCapture() ),
4913 m_prevConfig( m_context.getConfig() )
4915 m_context.setRunner(
this );
4916 m_context.setConfig( m_config );
4917 m_context.setResultCapture(
this );
4918 m_reporter->testRunStarting( m_runInfo );
4921 virtual ~RunContext() {
4922 m_reporter->testRunEnded(
TestRunStats( m_runInfo, m_totals, aborting() ) );
4923 m_context.setRunner( m_prevRunner );
4924 m_context.setConfig( NULL );
4925 m_context.setResultCapture( m_prevResultCapture );
4926 m_context.setConfig( m_prevConfig );
4929 void testGroupStarting( std::string
const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
4930 m_reporter->testGroupStarting(
GroupInfo( testSpec, groupIndex, groupsCount ) );
4932 void testGroupEnded( std::string
const& testSpec,
Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {
4933 m_reporter->testGroupEnded(
TestGroupStats(
GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
4936 Totals runMatching( std::string
const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
4942 testGroupStarting( testSpec, groupIndex, groupsCount );
4944 std::vector<TestCase>::const_iterator it = matchingTests.begin();
4945 std::vector<TestCase>::const_iterator itEnd = matchingTests.end();
4946 for(; it != itEnd; ++it )
4947 totals += runTest( *it );
4949 testGroupEnded( testSpec, totals, groupIndex, groupsCount );
4954 Totals prevTotals = m_totals;
4956 std::string redirectedCout;
4957 std::string redirectedCerr;
4961 m_reporter->testCaseStarting( testInfo );
4963 m_activeTestCase = &testCase;
4964 m_testCaseTracker = TestCaseTracker( testInfo.
name );
4968 runCurrentTest( redirectedCout, redirectedCerr );
4970 while( !m_testCaseTracker->isCompleted() && !aborting() );
4974 Totals deltaTotals = m_totals.
delta( prevTotals );
4982 m_activeTestCase = NULL;
4983 m_testCaseTracker.reset();
4995 m_lastAssertionInfo = assertionInfo;
4996 return actOnCurrentResult( assertionResult.
buildResult( assertionInfo ) );
5001 m_totals.assertions.passed++;
5003 else if( !result.
isOk() ) {
5004 m_totals.assertions.failed++;
5007 if( m_reporter->assertionEnded(
AssertionStats( result, m_messages, m_totals ) ) )
5011 m_lastAssertionInfo =
AssertionInfo(
"", m_lastAssertionInfo.lineInfo,
"{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
5014 virtual bool sectionStarted (
5019 std::ostringstream oss;
5020 oss << sectionInfo.
name <<
"@" << sectionInfo.
lineInfo;
5022 if( !m_testCaseTracker->enterSection( oss.str() ) )
5025 m_lastAssertionInfo.lineInfo = sectionInfo.
lineInfo;
5027 m_reporter->sectionStarting( sectionInfo );
5029 assertions = m_totals.assertions;
5033 bool testForMissingAssertions(
Counts& assertions ) {
5034 if( assertions.
total() != 0 ||
5035 !m_config->warnAboutMissingAssertions() ||
5036 m_testCaseTracker->currentSectionHasChildren() )
5038 m_totals.assertions.
failed++;
5043 virtual void sectionEnded(
SectionInfo const& info,
Counts const& prevAssertions,
double _durationInSeconds ) {
5044 if( std::uncaught_exception() ) {
5045 m_unfinishedSections.push_back( UnfinishedSections( info, prevAssertions, _durationInSeconds ) );
5049 Counts assertions = m_totals.assertions - prevAssertions;
5050 bool missingAssertions = testForMissingAssertions( assertions );
5052 m_testCaseTracker->leaveSection();
5054 m_reporter->sectionEnded(
SectionStats( info, assertions, _durationInSeconds, missingAssertions ) );
5058 virtual void pushScopedMessage(
MessageInfo const& message ) {
5059 m_messages.push_back( message );
5062 virtual void popScopedMessage(
MessageInfo const& message ) {
5063 m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );
5066 virtual bool shouldDebugBreak()
const {
5067 return m_config->shouldDebugBreak();
5070 virtual std::string getCurrentTestName()
const {
5071 return m_activeTestCase
5072 ? m_activeTestCase->getTestCaseInfo().name
5077 return &m_lastResult;
5082 bool aborting()
const {
5083 return m_totals.assertions.failed ==
static_cast<std::size_t
>( m_config->abortAfter() );
5089 m_lastResult = result;
5090 assertionEnded( m_lastResult );
5094 if( !m_lastResult.isOk() ) {
5096 if( shouldDebugBreak() )
5104 void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
5105 TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
5107 m_reporter->sectionStarting( testCaseSection );
5108 Counts prevAssertions = m_totals.assertions;
5109 double duration = 0;
5112 TestCaseTracker::Guard guard( *m_testCaseTracker );
5116 if( m_reporter->getPreferences().shouldRedirectStdOut ) {
5117 StreamRedirect coutRedir( std::cout, redirectedCout );
5118 StreamRedirect cerrRedir( std::cerr, redirectedCerr );
5119 m_activeTestCase->invoke();
5122 m_activeTestCase->invoke();
5132 actOnCurrentResult( exResult.
buildResult( m_lastAssertionInfo ) );
5136 for( std::vector<UnfinishedSections>::const_iterator it = m_unfinishedSections.begin(),
5137 itEnd = m_unfinishedSections.end();
5140 sectionEnded( it->info, it->prevAssertions, it->durationInSeconds );
5141 m_unfinishedSections.clear();
5144 Counts assertions = m_totals.assertions - prevAssertions;
5145 bool missingAssertions = testForMissingAssertions( assertions );
5147 SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
5148 m_reporter->sectionEnded( testCaseSectionStats );
5152 struct UnfinishedSections {
5153 UnfinishedSections(
SectionInfo const& _info,
Counts const& _prevAssertions,
double _durationInSeconds )
5154 : info( _info ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
5159 double durationInSeconds;
5171 std::vector<MessageInfo> m_messages;
5176 std::vector<UnfinishedSections> m_unfinishedSections;
5182 #define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED 5188 Version(
unsigned int _majorVersion,
5189 unsigned int _minorVersion,
5190 unsigned int _buildNumber,
5191 std::string
const& _branchName )
5192 : majorVersion( _majorVersion ),
5193 minorVersion( _minorVersion ),
5194 buildNumber( _buildNumber ),
5195 branchName( _branchName )
5198 const unsigned int majorVersion;
5199 const unsigned int minorVersion;
5200 const unsigned int buildNumber;
5201 const std::string branchName;
5204 void operator=( Version
const& );
5207 extern Version libraryVersion;
5220 : m_config( config )
5228 std::vector<TestCaseFilters> filterGroups = m_config->filters();
5229 if( filterGroups.empty() ) {
5231 filterGroups.push_back( filterGroup );
5234 RunContext context( m_config.get(), m_reporter );
5238 for( std::size_t i=0; i < filterGroups.size() && !context.aborting(); ++i ) {
5239 context.testGroupStarting( filterGroups[i].getName(), i, filterGroups.size() );
5240 totals += runTestsForGroup( context, filterGroups[i] );
5241 context.testGroupEnded( filterGroups[i].getName(), totals, i, filterGroups.size() );
5250 int testsRunForGroup = 0;
5251 for(; it != itEnd; ++it ) {
5254 if( m_testsAlreadyRun.find( *it ) == m_testsAlreadyRun.end() ) {
5256 if( context.aborting() )
5259 totals += context.runTest( *it );
5260 m_testsAlreadyRun.insert( *it );
5264 if( testsRunForGroup == 0 && !filterGroup.
getName().empty() )
5265 m_reporter->noMatchingTestCases( filterGroup.
getName() );
5273 if( !m_config->getFilename().empty() ) {
5274 m_ofs.open( m_config->getFilename().c_str() );
5275 if( m_ofs.fail() ) {
5276 std::ostringstream oss;
5277 oss <<
"Unable to open file: '" << m_config->getFilename() <<
"'";
5278 throw std::domain_error( oss.str() );
5280 m_config->setStreamBuf( m_ofs.rdbuf() );
5283 void makeReporter() {
5284 std::string reporterName = m_config->getReporterName().empty()
5286 : m_config->getReporterName();
5290 std::ostringstream oss;
5291 oss <<
"No reporter registered with name: '" << reporterName <<
"'";
5292 throw std::domain_error( oss.str() );
5298 std::ofstream m_ofs;
5300 std::set<TestCase> m_testsAlreadyRun;
5304 static bool alreadyInstantiated;
5308 struct OnUnusedOptions {
enum DoWhat { Ignore, Fail }; };
5311 : m_cli( makeCommandLineParser() ) {
5312 if( alreadyInstantiated ) {
5313 std::string msg =
"Only one instance of Catch::Session can ever be used";
5314 std::cerr << msg << std::endl;
5315 throw std::logic_error( msg );
5317 alreadyInstantiated =
true;
5323 void showHelp( std::string
const& processName ) {
5324 std::cout <<
"\nCatch v" << libraryVersion.majorVersion <<
"." 5325 << libraryVersion.minorVersion <<
" build " 5326 << libraryVersion.buildNumber;
5327 if( libraryVersion.branchName !=
"master" )
5328 std::cout <<
" (" << libraryVersion.branchName <<
" branch)";
5331 m_cli.usage( std::cout, processName );
5332 std::cout <<
"For more detail usage please see the project docs\n" << std::endl;
5335 int applyCommandLine(
int argc,
char*
const argv[], OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
5337 m_unusedTokens = m_cli.parseInto( argc, argv, m_configData );
5338 if( unusedOptionBehaviour == OnUnusedOptions::Fail )
5339 enforceNoUsedTokens();
5340 if( m_configData.showHelp )
5341 showHelp( m_configData.processName );
5344 catch( std::exception& ex ) {
5346 Colour colourGuard( Colour::Red );
5347 std::cerr <<
"\nError in input:\n" 5348 << Text( ex.what(), TextAttributes().setIndent(2) )
5351 m_cli.usage( std::cout, m_configData.processName );
5352 return (std::numeric_limits<int>::max)();
5357 void useConfigData(
ConfigData const& _configData ) {
5358 m_configData = _configData;
5362 void enforceNoUsedTokens()
const {
5363 if( !m_unusedTokens.empty() ) {
5364 std::vector<Clara::Parser::Token>::const_iterator
5365 it = m_unusedTokens.begin(),
5366 itEnd = m_unusedTokens.end();
5368 for(; it != itEnd; ++it )
5369 msg +=
" unrecognised option: " + it->data +
"\n";
5370 throw std::runtime_error( msg.substr( 0, msg.size()-1 ) );
5374 int run(
int argc,
char*
const argv[] ) {
5376 int returnCode = applyCommandLine( argc, argv );
5377 if( returnCode == 0 )
5383 if( m_configData.showHelp )
5389 Runner runner( m_config );
5393 return static_cast<int>( *listed );
5395 return static_cast<int>( runner.runTests().assertions.failed );
5397 catch( std::exception& ex ) {
5398 std::cerr << ex.what() << std::endl;
5399 return (std::numeric_limits<int>::max)();
5403 Clara::CommandLine<ConfigData>
const& cli()
const {
5406 std::vector<Clara::Parser::Token>
const& unusedTokens()
const {
5407 return m_unusedTokens;
5410 return m_configData;
5414 m_config =
new Config( m_configData );
5419 Clara::CommandLine<ConfigData> m_cli;
5420 std::vector<Clara::Parser::Token> m_unusedTokens;
5425 bool Session::alreadyInstantiated =
false;
5430 #define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED 5433 #define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED 5444 TestRegistry() : m_unnamedCount( 0 ) {}
5445 virtual ~TestRegistry();
5447 virtual void registerTest(
TestCase const& testCase ) {
5450 std::ostringstream oss;
5451 oss <<
"Anonymous test case " << ++m_unnamedCount;
5452 return registerTest( testCase.
withName( oss.str() ) );
5455 if( m_functions.find( testCase ) == m_functions.end() ) {
5456 m_functions.insert( testCase );
5457 m_functionsInOrder.push_back( testCase );
5459 m_nonHiddenFunctions.push_back( testCase );
5462 TestCase const& prev = *m_functions.find( testCase );
5463 std::cerr <<
"error: TEST_CASE( \"" << name <<
"\" ) already defined.\n" 5470 virtual std::vector<TestCase>
const& getAllTests()
const {
5471 return m_functionsInOrder;
5474 virtual std::vector<TestCase>
const& getAllNonHiddenTests()
const {
5475 return m_nonHiddenFunctions;
5479 virtual std::vector<TestCase> getMatchingTestCases( std::string
const& rawTestSpec )
const {
5480 std::vector<TestCase> matchingTests;
5481 getMatchingTestCases( rawTestSpec, matchingTests );
5482 return matchingTests;
5486 virtual void getMatchingTestCases( std::string
const& rawTestSpec, std::vector<TestCase>& matchingTestsOut )
const {
5489 std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin();
5490 std::vector<TestCase>::const_iterator itEnd = m_functionsInOrder.end();
5491 for(; it != itEnd; ++it ) {
5493 matchingTestsOut.push_back( *it );
5497 virtual void getMatchingTestCases(
TestCaseFilters const& filters, std::vector<TestCase>& matchingTestsOut )
const {
5498 std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin();
5499 std::vector<TestCase>::const_iterator itEnd = m_functionsInOrder.end();
5501 for(; it != itEnd; ++it )
5503 matchingTestsOut.push_back( *it );
5508 std::set<TestCase> m_functions;
5509 std::vector<TestCase> m_functionsInOrder;
5510 std::vector<TestCase> m_nonHiddenFunctions;
5511 size_t m_unnamedCount;
5516 class FreeFunctionTestCase :
public SharedImpl<ITestCase> {
5519 FreeFunctionTestCase(
TestFunction fun ) : m_fun( fun ) {}
5521 virtual void invoke()
const {
5526 virtual ~FreeFunctionTestCase();
5531 inline std::string extractClassName( std::string
const& classOrQualifiedMethodName ) {
5532 std::string className = classOrQualifiedMethodName;
5535 std::size_t lastColons = className.rfind(
"::" );
5536 std::size_t penultimateColons = className.rfind(
"::", lastColons-1 );
5537 if( penultimateColons == std::string::npos )
5538 penultimateColons = 1;
5539 className = className.substr( penultimateColons, lastColons-penultimateColons );
5549 registerTestCase(
new FreeFunctionTestCase(
function ),
"", nameAndDesc, lineInfo );
5555 char const* classOrQualifiedMethodName,
5561 extractClassName( classOrQualifiedMethodName ),
5570 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED 5580 virtual ~ReporterRegistry() {
5585 FactoryMap::const_iterator it = m_factories.find( name );
5586 if( it == m_factories.end() )
5591 void registerReporter( std::string
const& name,
IReporterFactory* factory ) {
5592 m_factories.insert( std::make_pair( name, factory ) );
5595 FactoryMap
const& getFactories()
const {
5600 FactoryMap m_factories;
5605 #define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED 5608 #import "Foundation/Foundation.h" 5615 ~ExceptionTranslatorRegistry() {
5620 m_translators.push_back( translator );
5630 @catch (NSException *exception) {
5631 return toString( [exception description] );
5637 catch( std::exception& ex ) {
5640 catch( std::string& msg ) {
5643 catch(
const char* msg ) {
5647 return tryTranslators( m_translators.begin() );
5651 std::string tryTranslators( std::vector<const IExceptionTranslator*>::const_iterator it )
const {
5652 if( it == m_translators.end() )
5653 return "Unknown exception";
5656 return (*it)->translate();
5659 return tryTranslators( it+1 );
5664 std::vector<const IExceptionTranslator*> m_translators;
5674 RegistryHub( RegistryHub
const& );
5675 void operator=( RegistryHub
const& );
5681 return m_reporterRegistry;
5684 return m_testCaseRegistry;
5687 return m_exceptionTranslatorRegistry;
5691 virtual void registerReporter( std::string
const& name,
IReporterFactory* factory ) {
5692 m_reporterRegistry.registerReporter( name, factory );
5694 virtual void registerTest(
TestCase const& testInfo ) {
5695 m_testCaseRegistry.registerTest( testInfo );
5698 m_exceptionTranslatorRegistry.registerTranslator( translator );
5702 TestRegistry m_testCaseRegistry;
5703 ReporterRegistry m_reporterRegistry;
5704 ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
5708 inline RegistryHub*& getTheRegistryHub() {
5709 static RegistryHub* theRegistryHub = NULL;
5710 if( !theRegistryHub )
5711 theRegistryHub =
new RegistryHub();
5712 return theRegistryHub;
5717 return *getTheRegistryHub();
5720 return *getTheRegistryHub();
5723 delete getTheRegistryHub();
5724 getTheRegistryHub() = NULL;
5734 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED 5741 : m_lineInfo( lineInfo ) {
5742 std::ostringstream oss;
5743 oss << lineInfo <<
": function ";
5744 oss <<
"not implemented";
5749 return m_what.c_str();
5755 #define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED 5761 Context() : m_config( NULL ) {}
5762 Context( Context
const& );
5763 void operator=( Context
const& );
5767 return *m_resultCapture;
5769 virtual IRunner& getRunner() {
5772 virtual size_t getGeneratorIndex( std::string
const& fileInfo,
size_t totalSize ) {
5773 return getGeneratorsForCurrentTest()
5774 .getGeneratorInfo( fileInfo, totalSize )
5777 virtual bool advanceGeneratorsForCurrentTest() {
5779 return generators && generators->
moveNext();
5788 m_resultCapture = resultCapture;
5790 virtual void setRunner(
IRunner* runner ) {
5803 std::map<std::string, IGeneratorsForTest*>::const_iterator it =
5804 m_generatorsByTestName.find( testName );
5805 return it != m_generatorsByTestName.end()
5815 m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
5824 std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
5828 Context* currentContext = NULL;
5831 if( !currentContext )
5832 currentContext =
new Context();
5833 return *currentContext;
5840 if( streamName ==
"stdout" )
return Stream( std::cout.rdbuf(),
false );
5841 if( streamName ==
"stderr" )
return Stream( std::cerr.rdbuf(),
false );
5844 throw std::domain_error(
"Unknown stream: " + streamName );
5848 delete currentContext;
5849 currentContext = NULL;
5854 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED 5856 namespace Catch {
namespace Detail {
5857 struct IColourImpl {
5858 virtual ~IColourImpl() {}
5859 virtual void use( Colour::Code _colourCode ) = 0;
5863 #if defined ( CATCH_PLATFORM_WINDOWS ) 5872 #include <windows.h> 5878 class Win32ColourImpl :
public Detail::IColourImpl {
5880 Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
5882 CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
5883 GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
5884 originalAttributes = csbiInfo.wAttributes;
5887 virtual void use( Colour::Code _colourCode ) {
5888 switch( _colourCode ) {
5889 case Colour::None:
return setTextAttribute( originalAttributes );
5890 case Colour::White:
return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
5891 case Colour::Red:
return setTextAttribute( FOREGROUND_RED );
5892 case Colour::Green:
return setTextAttribute( FOREGROUND_GREEN );
5893 case Colour::Blue:
return setTextAttribute( FOREGROUND_BLUE );
5894 case Colour::Cyan:
return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
5895 case Colour::Yellow:
return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
5896 case Colour::Grey:
return setTextAttribute( 0 );
5898 case Colour::LightGrey:
return setTextAttribute( FOREGROUND_INTENSITY );
5899 case Colour::BrightRed:
return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
5900 case Colour::BrightGreen:
return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
5901 case Colour::BrightWhite:
return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
5903 case Colour::Bright:
throw std::logic_error(
"not a colour" );
5908 void setTextAttribute( WORD _textAttribute ) {
5909 SetConsoleTextAttribute( stdoutHandle, _textAttribute );
5911 HANDLE stdoutHandle;
5912 WORD originalAttributes;
5915 inline bool shouldUseColourForPlatform() {
5919 Win32ColourImpl platformColourImpl;
5924 #else // Not Windows - assumed to be POSIX compatible 5935 class PosixColourImpl :
public Detail::IColourImpl {
5937 virtual void use( Colour::Code _colourCode ) {
5938 switch( _colourCode ) {
5940 case Colour::White:
return setColour(
"[0m" );
5941 case Colour::Red:
return setColour(
"[0;31m" );
5942 case Colour::Green:
return setColour(
"[0;32m" );
5943 case Colour::Blue:
return setColour(
"[0:34m" );
5944 case Colour::Cyan:
return setColour(
"[0;36m" );
5945 case Colour::Yellow:
return setColour(
"[0;33m" );
5946 case Colour::Grey:
return setColour(
"[1;30m" );
5948 case Colour::LightGrey:
return setColour(
"[0;37m" );
5949 case Colour::BrightRed:
return setColour(
"[1;31m" );
5950 case Colour::BrightGreen:
return setColour(
"[1;32m" );
5951 case Colour::BrightWhite:
return setColour(
"[1;37m" );
5953 case Colour::Bright:
throw std::logic_error(
"not a colour" );
5957 void setColour(
const char* _escapeCode ) {
5958 std::cout <<
'\033' << _escapeCode;
5962 inline bool shouldUseColourForPlatform() {
5963 return isatty( fileno(stdout) );
5966 PosixColourImpl platformColourImpl;
5971 #endif // not Windows 5976 struct NoColourImpl : Detail::IColourImpl {
5977 void use( Colour::Code ) {}
5979 NoColourImpl noColourImpl;
5980 static const bool shouldUseColour = shouldUseColourForPlatform() &&
5984 Colour::Colour( Code _colourCode ){ use( _colourCode ); }
5985 Colour::~Colour(){ use( None ); }
5986 void Colour::use( Code _colourCode ) {
5987 impl->use( _colourCode );
5990 Detail::IColourImpl* Colour::impl = shouldUseColour
5991 ?
static_cast<Detail::IColourImpl*
>( &platformColourImpl )
5992 : static_cast<Detail::IColourImpl*>( &noColourImpl );
5997 #define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED 6007 GeneratorInfo( std::size_t size )
6013 if( ++m_currentIndex == m_size ) {
6020 std::size_t getCurrentIndex()
const {
6021 return m_currentIndex;
6025 std::size_t m_currentIndex;
6033 ~GeneratorsForTest() {
6037 IGeneratorInfo& getGeneratorInfo( std::string
const& fileInfo, std::size_t size ) {
6038 std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
6039 if( it == m_generatorsByName.end() ) {
6041 m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
6042 m_generatorsInOrder.push_back( info );
6049 std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
6050 std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
6051 for(; it != itEnd; ++it ) {
6052 if( (*it)->moveNext() )
6059 std::map<std::string, IGeneratorInfo*> m_generatorsByName;
6060 std::vector<IGeneratorInfo*> m_generatorsInOrder;
6065 return new GeneratorsForTest();
6071 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED 6077 std::string
const& _capturedExpression,
6079 : macroName( _macroName ),
6080 lineInfo( _lineInfo ),
6081 capturedExpression( _capturedExpression ),
6082 resultDisposition( _resultDisposition )
6089 m_resultData( data )
6105 return m_resultData.resultType;
6109 return !m_info.capturedExpression.empty();
6113 return !m_resultData.message.empty();
6118 return "!" + m_info.capturedExpression;
6120 return m_info.capturedExpression;
6123 if( m_info.macroName.empty() )
6124 return m_info.capturedExpression;
6126 return m_info.macroName +
"( " + m_info.capturedExpression +
" )";
6130 return hasExpression() && getExpandedExpression() != getExpression();
6134 return m_resultData.reconstructedExpression;
6138 return m_resultData.message;
6141 return m_info.lineInfo;
6145 return m_info.macroName;
6151 #define TWOBLUECUBES_CATCH_EXPRESSIONRESULT_BUILDER_HPP_INCLUDED 6158 m_data.resultType = resultType;
6161 : m_data( other.m_data ),
6162 m_exprComponents( other.m_exprComponents )
6164 m_stream << other.m_stream.str();
6167 m_data = other.m_data;
6168 m_exprComponents = other.m_exprComponents;
6170 m_stream << other.m_stream.str();
6174 m_data.resultType = result;
6182 m_exprComponents.shouldNegate =
shouldNegate( resultDisposition );
6186 m_exprComponents.lhs = lhs;
6190 m_exprComponents.rhs = rhs;
6194 m_exprComponents.op = op;
6209 data.
message = m_stream.str();
6211 if( m_exprComponents.shouldNegate ) {
6212 if( m_exprComponents.op ==
"" )
6220 if( m_exprComponents.op ==
"" )
6221 return m_exprComponents.lhs.empty() ? info.
capturedExpression : m_exprComponents.op + m_exprComponents.lhs;
6222 else if( m_exprComponents.op ==
"matches" )
6223 return m_exprComponents.lhs +
" " + m_exprComponents.rhs;
6224 else if( m_exprComponents.op !=
"!" ) {
6225 if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 &&
6226 m_exprComponents.lhs.find(
"\n") == std::string::npos &&
6227 m_exprComponents.rhs.find(
"\n") == std::string::npos )
6228 return m_exprComponents.lhs +
" " + m_exprComponents.op +
" " + m_exprComponents.rhs;
6230 return m_exprComponents.lhs +
"\n" + m_exprComponents.op +
"\n" + m_exprComponents.rhs;
6239 #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED 6244 std::string
const& _className,
6245 std::string
const& _name,
6246 std::string
const& _descOrTags,
6249 std::string desc = _descOrTags;
6251 std::set<std::string> tags;
6253 if( tags.find(
"hide" ) != tags.end() || tags.find(
"." ) != tags.end() )
6256 TestCaseInfo info( _name, _className, desc, tags, isHidden, _lineInfo );
6257 return TestCase( _testCase, info );
6261 std::string
const& _className,
6262 std::string
const& _description,
6263 std::set<std::string>
const& _tags,
6267 className( _className ),
6268 description( _description ),
6270 lineInfo( _lineInfo ),
6271 isHidden( _isHidden )
6273 std::ostringstream oss;
6274 for( std::set<std::string>::const_iterator it = _tags.begin(), itEnd = _tags.end(); it != itEnd; ++it )
6275 oss <<
"[" << *it <<
"]";
6276 tagsAsString = oss.str();
6280 : name( other.
name ),
6298 other.
name = _newName;
6311 return tags.find(
toLower( tag ) ) != tags.end();
6323 test.swap( other.test );
6325 name.swap( other.
name );
6327 std::swap( lineInfo, other.
lineInfo );
6331 return test.get() == other.test.get() &&
6332 name == other.
name &&
6337 return name < other.
name;
6353 #define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED 6358 Version libraryVersion( 1, 0, 10,
"master" );
6362 #define TWOBLUECUBES_CATCH_TEXT_HPP_INCLUDED 6369 Text::Text( std::string
const& _str, TextAttributes
const& _attr )
6372 std::string wrappableChars =
" [({.,/|\\-";
6373 std::size_t indent = _attr.initialIndent != std::string::npos
6374 ? _attr.initialIndent
6376 std::string remainder = _str;
6378 while( !remainder.empty() ) {
6379 assert( lines.size() < 1000 );
6380 std::size_t tabPos = std::string::npos;
6381 std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
6382 std::size_t pos = remainder.find_first_of(
'\n' );
6383 if( pos <= width ) {
6386 pos = remainder.find_last_of( _attr.tabChar, width );
6387 if( pos != std::string::npos ) {
6389 if( remainder[width] ==
'\n' )
6391 remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
6394 if( width == remainder.size() ) {
6395 spliceLine( indent, remainder, width );
6397 else if( remainder[width] ==
'\n' ) {
6398 spliceLine( indent, remainder, width );
6399 if( width <= 1 || remainder.size() != 1 )
6400 remainder = remainder.substr( 1 );
6401 indent = _attr.indent;
6404 pos = remainder.find_last_of( wrappableChars, width );
6405 if( pos != std::string::npos && pos > 0 ) {
6406 spliceLine( indent, remainder, pos );
6407 if( remainder[0] ==
' ' )
6408 remainder = remainder.substr( 1 );
6411 spliceLine( indent, remainder, width-1 );
6412 lines.back() +=
"-";
6414 if( lines.size() == 1 )
6415 indent = _attr.indent;
6416 if( tabPos != std::string::npos )
6422 void Text::spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
6423 lines.push_back( std::string( _indent,
' ' ) + _remainder.substr( 0, _pos ) );
6424 _remainder = _remainder.substr( _pos );
6428 std::ostringstream oss;
6433 std::ostream&
operator << ( std::ostream& _stream, Text
const& _text ) {
6434 for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
6435 it != itEnd; ++it ) {
6436 if( it != _text.begin() )
6446 #define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED 6453 : macroName( _macroName ),
6454 lineInfo( _lineInfo ),
6456 sequence( ++globalCount )
6460 unsigned int MessageInfo::globalCount = 0;
6465 : m_info( builder.
m_info )
6467 m_info.message = builder.
m_stream.str();
6477 #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED 6480 #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED 6484 class LegacyReporterAdapter :
public SharedImpl<IStreamingReporter>
6488 virtual ~LegacyReporterAdapter();
6491 virtual void noMatchingTestCases( std::string
const& );
6492 virtual void testRunStarting(
TestRunInfo const& );
6493 virtual void testGroupStarting(
GroupInfo const& groupInfo );
6494 virtual void testCaseStarting(
TestCaseInfo const& testInfo );
6495 virtual void sectionStarting(
SectionInfo const& sectionInfo );
6497 virtual bool assertionEnded(
AssertionStats const& assertionStats );
6498 virtual void sectionEnded(
SectionStats const& sectionStats );
6499 virtual void testCaseEnded(
TestCaseStats const& testCaseStats );
6500 virtual void testGroupEnded(
TestGroupStats const& testGroupStats );
6501 virtual void testRunEnded(
TestRunStats const& testRunStats );
6510 LegacyReporterAdapter::LegacyReporterAdapter(
Ptr<IReporter> const& legacyReporter )
6511 : m_legacyReporter( legacyReporter )
6513 LegacyReporterAdapter::~LegacyReporterAdapter() {}
6521 void LegacyReporterAdapter::noMatchingTestCases( std::string
const& ) {}
6522 void LegacyReporterAdapter::testRunStarting(
TestRunInfo const& ) {
6523 m_legacyReporter->StartTesting();
6525 void LegacyReporterAdapter::testGroupStarting(
GroupInfo const& groupInfo ) {
6526 m_legacyReporter->StartGroup( groupInfo.
name );
6528 void LegacyReporterAdapter::testCaseStarting(
TestCaseInfo const& testInfo ) {
6529 m_legacyReporter->StartTestCase( testInfo );
6531 void LegacyReporterAdapter::sectionStarting(
SectionInfo const& sectionInfo ) {
6532 m_legacyReporter->StartSection( sectionInfo.
name, sectionInfo.
description );
6534 void LegacyReporterAdapter::assertionStarting(
AssertionInfo const& ) {
6538 bool LegacyReporterAdapter::assertionEnded(
AssertionStats const& assertionStats ) {
6540 for( std::vector<MessageInfo>::const_iterator it = assertionStats.
infoMessages.begin(), itEnd = assertionStats.
infoMessages.end();
6545 expressionBuilder << it->message;
6548 m_legacyReporter->Result( result );
6555 void LegacyReporterAdapter::sectionEnded(
SectionStats const& sectionStats ) {
6557 m_legacyReporter->NoAssertionsInSection( sectionStats.
sectionInfo.
name );
6560 void LegacyReporterAdapter::testCaseEnded(
TestCaseStats const& testCaseStats ) {
6561 m_legacyReporter->EndTestCase
6567 void LegacyReporterAdapter::testGroupEnded(
TestGroupStats const& testGroupStats ) {
6569 m_legacyReporter->Aborted();
6572 void LegacyReporterAdapter::testRunEnded(
TestRunStats const& testRunStats ) {
6573 m_legacyReporter->EndTesting( testRunStats.
totals );
6580 #pragma clang diagnostic push 6581 #pragma clang diagnostic ignored "-Wc++11-long-long" 6584 #ifdef CATCH_PLATFORM_WINDOWS 6585 #include <windows.h> 6587 #include <sys/time.h> 6593 #ifdef CATCH_PLATFORM_WINDOWS 6594 uint64_t getCurrentTicks() {
6595 static uint64_t hz=0, hzo=0;
6597 QueryPerformanceFrequency((LARGE_INTEGER*)&hz);
6598 QueryPerformanceCounter((LARGE_INTEGER*)&hzo);
6601 QueryPerformanceCounter((LARGE_INTEGER*)&t);
6602 return ((t-hzo)*1000000)/hz;
6605 uint64_t getCurrentTicks() {
6607 gettimeofday(&t,NULL);
6608 return (uint64_t)t.tv_sec * 1000000ull + (uint64_t)t.tv_usec;
6614 m_ticks = getCurrentTicks();
6617 return (
unsigned int)(getCurrentTicks() - m_ticks);
6620 return (
unsigned int)((getCurrentTicks() - m_ticks)/1000);
6623 return (getCurrentTicks() - m_ticks)/1000000.0;
6629 #pragma clang diagnostic pop 6632 #define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED 6635 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED 6639 template<
typename T>
6640 class LegacyReporterRegistrar {
6644 return new LegacyReporterAdapter(
new T( config ) );
6647 virtual std::string getDescription()
const {
6648 return T::getDescription();
6654 LegacyReporterRegistrar( std::string
const& name ) {
6659 template<
typename T>
6660 class ReporterRegistrar {
6676 return new T( config );
6679 virtual std::string getDescription()
const {
6680 return T::getDescription();
6686 ReporterRegistrar( std::string
const& name ) {
6692 #define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \ 6693 Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); 6694 #define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \ 6695 Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); 6698 #define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED 6710 class ScopedElement {
6712 ScopedElement( XmlWriter* writer )
6713 : m_writer( writer )
6716 ScopedElement( ScopedElement
const& other )
6717 : m_writer( other.m_writer ){
6718 other.m_writer = NULL;
6723 m_writer->endElement();
6726 ScopedElement& writeText( std::string
const& text,
bool indent =
true ) {
6727 m_writer->writeText( text, indent );
6731 template<
typename T>
6732 ScopedElement& writeAttribute( std::string
const& name, T
const& attribute ) {
6733 m_writer->writeAttribute( name, attribute );
6738 mutable XmlWriter* m_writer;
6742 : m_tagIsOpen(
false ),
6743 m_needsNewline(
false ),
6747 XmlWriter( std::ostream& os )
6748 : m_tagIsOpen(
false ),
6749 m_needsNewline(
false ),
6754 while( !m_tags.empty() )
6758 XmlWriter& operator = ( XmlWriter
const& other ) {
6759 XmlWriter temp( other );
6764 void swap( XmlWriter& other ) {
6765 std::swap( m_tagIsOpen, other.m_tagIsOpen );
6766 std::swap( m_needsNewline, other.m_needsNewline );
6767 std::swap( m_tags, other.m_tags );
6768 std::swap( m_indent, other.m_indent );
6769 std::swap( m_os, other.m_os );
6772 XmlWriter& startElement( std::string
const& name ) {
6774 newlineIfNecessary();
6775 stream() << m_indent <<
"<" << name;
6776 m_tags.push_back( name );
6782 ScopedElement scopedElement( std::string
const& name ) {
6783 ScopedElement scoped(
this );
6784 startElement( name );
6788 XmlWriter& endElement() {
6789 newlineIfNecessary();
6790 m_indent = m_indent.substr( 0, m_indent.size()-2 );
6793 m_tagIsOpen =
false;
6796 stream() << m_indent <<
"</" << m_tags.back() <<
">\n";
6802 XmlWriter& writeAttribute( std::string
const& name, std::string
const& attribute ) {
6803 if( !name.empty() && !attribute.empty() ) {
6804 stream() <<
" " << name <<
"=\"";
6805 writeEncodedText( attribute );
6811 XmlWriter& writeAttribute( std::string
const& name,
bool attribute ) {
6812 stream() <<
" " << name <<
"=\"" << ( attribute ?
"true" :
"false" ) <<
"\"";
6816 template<
typename T>
6817 XmlWriter& writeAttribute( std::string
const& name, T
const& attribute ) {
6819 stream() <<
" " << name <<
"=\"" << attribute <<
"\"";
6823 XmlWriter& writeText( std::string
const& text,
bool indent =
true ) {
6824 if( !text.empty() ){
6825 bool tagWasOpen = m_tagIsOpen;
6827 if( tagWasOpen && indent )
6828 stream() << m_indent;
6829 writeEncodedText( text );
6830 m_needsNewline =
true;
6835 XmlWriter& writeComment( std::string
const& text ) {
6837 stream() << m_indent <<
"<!--" << text <<
"-->";
6838 m_needsNewline =
true;
6842 XmlWriter& writeBlankLine() {
6850 std::ostream& stream() {
6854 void ensureTagClosed() {
6857 m_tagIsOpen =
false;
6861 void newlineIfNecessary() {
6862 if( m_needsNewline ) {
6864 m_needsNewline =
false;
6868 void writeEncodedText( std::string
const& text ) {
6869 static const char* charsToEncode =
"<&\"";
6870 std::string mtext = text;
6871 std::string::size_type pos = mtext.find_first_of( charsToEncode );
6872 while( pos != std::string::npos ) {
6873 stream() << mtext.substr( 0, pos );
6875 switch( mtext[pos] ) {
6880 stream() <<
"&";
6883 stream() <<
""";
6886 mtext = mtext.substr( pos+1 );
6887 pos = mtext.find_first_of( charsToEncode );
6893 bool m_needsNewline;
6894 std::vector<std::string> m_tags;
6895 std::string m_indent;
6901 class XmlReporter :
public SharedImpl<IReporter> {
6903 XmlReporter(
ReporterConfig const& config ) : m_config( config ), m_sectionDepth( 0 ) {}
6905 static std::string getDescription() {
6906 return "Reports test results as an XML document";
6908 virtual ~XmlReporter();
6912 virtual bool shouldRedirectStdout()
const {
6916 virtual void StartTesting() {
6917 m_xml = XmlWriter( m_config.stream() );
6918 m_xml.startElement(
"Catch" );
6919 if( !m_config.fullConfig()->name().empty() )
6920 m_xml.writeAttribute(
"name", m_config.fullConfig()->name() );
6923 virtual void EndTesting(
const Totals& totals ) {
6924 m_xml.scopedElement(
"OverallResults" )
6930 virtual void StartGroup(
const std::string& groupName ) {
6931 m_xml.startElement(
"Group" )
6932 .writeAttribute(
"name", groupName );
6935 virtual void EndGroup(
const std::string&,
const Totals& totals ) {
6936 m_xml.scopedElement(
"OverallResults" )
6942 virtual void StartSection(
const std::string& sectionName,
const std::string& description ) {
6943 if( m_sectionDepth++ > 0 ) {
6944 m_xml.startElement(
"Section" )
6945 .writeAttribute(
"name", sectionName )
6946 .writeAttribute(
"description", description );
6949 virtual void NoAssertionsInSection(
const std::string& ) {}
6950 virtual void NoAssertionsInTestCase(
const std::string& ) {}
6952 virtual void EndSection(
const std::string& ,
const Counts& assertions ) {
6953 if( --m_sectionDepth > 0 ) {
6954 m_xml.scopedElement(
"OverallResults" )
6955 .writeAttribute(
"successes", assertions.
passed )
6956 .writeAttribute(
"failures", assertions.
failed );
6962 m_xml.startElement(
"TestCase" ).writeAttribute(
"name", testInfo.
name );
6963 m_currentTestSuccess =
true;
6971 m_xml.startElement(
"Expression" )
6972 .writeAttribute(
"success", assertionResult.
succeeded() )
6976 m_xml.scopedElement(
"Original" )
6978 m_xml.scopedElement(
"Expanded" )
6980 m_currentTestSuccess &= assertionResult.
succeeded();
6985 m_xml.scopedElement(
"Exception" )
6989 m_currentTestSuccess =
false;
6992 m_xml.scopedElement(
"Info" )
6996 m_xml.scopedElement(
"Warning" )
7000 m_xml.scopedElement(
"Failure" )
7002 m_currentTestSuccess =
false;
7016 virtual void Aborted() {
7021 m_xml.scopedElement(
"OverallResult" ).writeAttribute(
"success", m_currentTestSuccess );
7027 bool m_currentTestSuccess;
7035 #define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED 7050 static std::string getDescription() {
7051 return "Reports test results in an XML format that looks like Ant's junitreport target";
7054 virtual void noMatchingTestCases( std::string
const& ) {}
7062 virtual void testRunStarting(
TestRunInfo const& runInfo ) {
7064 xml.startElement(
"testsuites" );
7067 virtual void testGroupStarting(
GroupInfo const& groupInfo ) {
7069 stdOutForSuite.str(
"");
7070 stdErrForSuite.str(
"");
7071 unexpectedExceptions = 0;
7075 virtual bool assertionEnded(
AssertionStats const& assertionStats ) {
7077 unexpectedExceptions++;
7081 virtual void testCaseEnded(
TestCaseStats const& testCaseStats ) {
7082 stdOutForSuite << testCaseStats.
stdOut;
7083 stdErrForSuite << testCaseStats.
stdErr;
7087 virtual void testGroupEnded(
TestGroupStats const& testGroupStats ) {
7088 double suiteTime = suiteTimer.getElapsedSeconds();
7090 writeGroup( *m_testGroups.back(), suiteTime );
7093 virtual void testRunEnded() {
7097 void writeGroup( TestGroupNode
const& groupNode,
double suiteTime ) {
7098 XmlWriter::ScopedElement e = xml.scopedElement(
"testsuite" );
7101 xml.writeAttribute(
"errors", unexpectedExceptions );
7104 xml.writeAttribute(
"hostname",
"tbd" );
7106 xml.writeAttribute(
"time",
"" );
7108 xml.writeAttribute(
"time", suiteTime );
7109 xml.writeAttribute(
"timestamp",
"tbd" );
7112 for( TestGroupNode::ChildNodes::const_iterator
7113 it = groupNode.children.begin(), itEnd = groupNode.children.end();
7116 writeTestCase( **it );
7118 xml.scopedElement(
"system-out" ).writeText(
trim( stdOutForSuite.str() ),
false );
7119 xml.scopedElement(
"system-err" ).writeText(
trim( stdErrForSuite.str() ),
false );
7122 void writeTestCase( TestCaseNode
const& testCaseNode ) {
7127 assert( testCaseNode.children.size() == 1 );
7128 SectionNode
const& rootSection = *testCaseNode.children.front();
7132 if( className.empty() ) {
7133 if( rootSection.childSections.empty() )
7134 className =
"global";
7136 writeSection( className,
"", rootSection );
7139 void writeSection( std::string
const& className,
7140 std::string
const& rootName,
7141 SectionNode
const& sectionNode ) {
7142 std::string name =
trim( sectionNode.stats.sectionInfo.name );
7143 if( !rootName.empty() )
7144 name = rootName +
"/" + name;
7146 if( !sectionNode.assertions.empty() ||
7147 !sectionNode.stdOut.empty() ||
7148 !sectionNode.stdErr.empty() ) {
7149 XmlWriter::ScopedElement e = xml.scopedElement(
"testcase" );
7150 if( className.empty() ) {
7151 xml.writeAttribute(
"classname", name );
7152 xml.writeAttribute(
"name",
"root" );
7155 xml.writeAttribute(
"classname", className );
7156 xml.writeAttribute(
"name", name );
7158 xml.writeAttribute(
"time",
toString( sectionNode.stats.durationInSeconds ) );
7160 writeAssertions( sectionNode );
7162 if( !sectionNode.stdOut.empty() )
7163 xml.scopedElement(
"system-out" ).writeText(
trim( sectionNode.stdOut ),
false );
7164 if( !sectionNode.stdErr.empty() )
7165 xml.scopedElement(
"system-err" ).writeText(
trim( sectionNode.stdErr ),
false );
7167 for( SectionNode::ChildSections::const_iterator
7168 it = sectionNode.childSections.begin(),
7169 itEnd = sectionNode.childSections.end();
7172 if( className.empty() )
7173 writeSection( name,
"", **it );
7175 writeSection( className, name, **it );
7178 void writeAssertions( SectionNode
const& sectionNode ) {
7179 for( SectionNode::Assertions::const_iterator
7180 it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();
7183 writeAssertion( *it );
7187 if( !result.
isOk() ) {
7188 std::string elementName;
7191 elementName =
"error";
7194 elementName =
"failure";
7197 elementName =
"failure";
7200 elementName =
"failure";
7210 elementName =
"internalError";
7214 XmlWriter::ScopedElement e = xml.scopedElement( elementName );
7219 std::ostringstream oss;
7222 for( std::vector<MessageInfo>::const_iterator
7228 oss << it->message <<
"\n";
7231 xml.writeText( oss.str(), false );
7237 std::ostringstream stdOutForSuite;
7238 std::ostringstream stdErrForSuite;
7239 unsigned int unexpectedExceptions;
7242 INTERNAL_CATCH_REGISTER_REPORTER(
"junit", JunitReporter )
7247 #define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED 7254 m_headerPrinted(
false ),
7255 m_atLeastOneTestCasePrinted(
false )
7258 virtual ~ConsoleReporter();
7259 static std::string getDescription() {
7260 return "Reports test results as plain lines of text";
7268 virtual void noMatchingTestCases( std::string
const& spec ) {
7269 stream <<
"No test cases matched '" << spec <<
"'" << std::endl;
7275 virtual bool assertionEnded(
AssertionStats const& _assertionStats ) {
7279 if( !m_config->includeSuccessfulResults() && result.
isOk() )
7284 AssertionPrinter printer( stream, _assertionStats );
7286 stream << std::endl;
7290 virtual void sectionStarting(
SectionInfo const& _sectionInfo ) {
7291 m_headerPrinted =
false;
7294 virtual void sectionEnded(
SectionStats const& _sectionStats ) {
7297 Colour colour( Colour::ResultError );
7298 if( m_sectionStack.size() > 1 )
7299 stream <<
"\nNo assertions in section";
7301 stream <<
"\nNo assertions in test case";
7302 stream <<
" '" << _sectionStats.
sectionInfo.
name <<
"'\n" << std::endl;
7304 if( m_headerPrinted ) {
7306 stream <<
"Completed in " << _sectionStats.
durationInSeconds <<
"s" << std::endl;
7307 m_headerPrinted =
false;
7316 virtual void testCaseEnded(
TestCaseStats const& _testCaseStats ) {
7318 m_headerPrinted =
false;
7320 virtual void testGroupEnded(
TestGroupStats const& _testGroupStats ) {
7321 if( currentGroupInfo.used ) {
7322 printSummaryDivider();
7323 stream <<
"Summary for group '" << _testGroupStats.
groupInfo.
name <<
"':\n";
7324 printTotals( _testGroupStats.
totals );
7325 stream <<
"\n" << std::endl;
7329 virtual void testRunEnded(
TestRunStats const& _testRunStats ) {
7330 if( m_atLeastOneTestCasePrinted )
7331 printTotalsDivider();
7332 printTotals( _testRunStats.
totals );
7333 stream <<
"\n" << std::endl;
7339 class AssertionPrinter {
7340 void operator= ( AssertionPrinter
const& );
7342 AssertionPrinter( std::ostream& _stream,
AssertionStats const& _stats )
7343 : stream( _stream ),
7346 colour( Colour::None ),
7347 message( result.getMessage() ),
7350 switch( result.getResultType() ) {
7352 colour = Colour::Success;
7353 passOrFail =
"PASSED";
7356 messageLabel =
"with message";
7358 messageLabel =
"with messages";
7361 if( result.isOk() ) {
7362 colour = Colour::Success;
7363 passOrFail =
"FAILED - but was ok";
7366 colour = Colour::Error;
7367 passOrFail =
"FAILED";
7370 messageLabel =
"with message";
7372 messageLabel =
"with messages";
7375 colour = Colour::Error;
7376 passOrFail =
"FAILED";
7377 messageLabel =
"due to unexpected exception with message";
7380 colour = Colour::Error;
7381 passOrFail =
"FAILED";
7382 messageLabel =
"because no exception was thrown where one was expected";
7385 messageLabel =
"info";
7388 messageLabel =
"warning";
7391 passOrFail =
"FAILED";
7392 colour = Colour::Error;
7394 messageLabel =
"explicitly with message";
7396 messageLabel =
"explicitly with messages";
7402 passOrFail =
"** internal error **";
7403 colour = Colour::Error;
7408 void print()
const {
7410 if( stats.totals.assertions.total() > 0 ) {
7414 printOriginalExpression();
7415 printReconstructedExpression();
7424 void printResultType()
const {
7425 if( !passOrFail.empty() ) {
7426 Colour colourGuard( colour );
7427 stream << passOrFail <<
":\n";
7430 void printOriginalExpression()
const {
7431 if( result.hasExpression() ) {
7432 Colour colourGuard( Colour::OriginalExpression );
7434 stream << result.getExpressionInMacro();
7438 void printReconstructedExpression()
const {
7439 if( result.hasExpandedExpression() ) {
7440 stream <<
"with expansion:\n";
7441 Colour colourGuard( Colour::ReconstructedExpression );
7442 stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) <<
"\n";
7445 void printMessage()
const {
7446 if( !messageLabel.empty() )
7447 stream << messageLabel <<
":" <<
"\n";
7448 for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
7451 stream << Text( it->message, TextAttributes().setIndent(2) ) <<
"\n";
7454 void printSourceInfo()
const {
7455 Colour colourGuard( Colour::FileName );
7456 stream << result.getSourceInfo() <<
": ";
7459 std::ostream& stream;
7462 Colour::Code colour;
7463 std::string passOrFail;
7464 std::string messageLabel;
7465 std::string message;
7466 std::vector<MessageInfo> messages;
7471 if( !currentTestRunInfo.used )
7473 if( !currentGroupInfo.used )
7474 lazyPrintGroupInfo();
7476 if( !m_headerPrinted ) {
7477 printTestCaseAndSectionHeader();
7478 m_headerPrinted =
true;
7480 m_atLeastOneTestCasePrinted =
true;
7482 void lazyPrintRunInfo() {
7483 stream <<
"\n" << getTildes() <<
"\n";
7484 Colour colour( Colour::SecondaryText );
7485 stream << currentTestRunInfo->name
7486 <<
" is a Catch v" << libraryVersion.majorVersion <<
"." 7487 << libraryVersion.minorVersion <<
" b" 7488 << libraryVersion.buildNumber;
7489 if( libraryVersion.branchName !=
"master" )
7490 stream <<
" (" << libraryVersion.branchName <<
")";
7491 stream <<
" host application.\n" 7492 <<
"Run with -? for options\n\n";
7494 currentTestRunInfo.used =
true;
7496 void lazyPrintGroupInfo() {
7497 if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
7498 printClosedHeader(
"Group: " + currentGroupInfo->name );
7499 currentGroupInfo.used =
true;
7502 void printTestCaseAndSectionHeader() {
7503 assert( !m_sectionStack.empty() );
7504 printOpenHeader( currentTestCaseInfo->name );
7506 if( m_sectionStack.size() > 1 ) {
7507 Colour colourGuard( Colour::Headers );
7509 std::vector<SectionInfo>::const_iterator
7510 it = m_sectionStack.begin()+1,
7511 itEnd = m_sectionStack.end();
7512 for( ; it != itEnd; ++it )
7513 printHeaderString( it->name, 2 );
7518 if( !lineInfo.
empty() ){
7519 stream << getDashes() <<
"\n";
7520 Colour colourGuard( Colour::FileName );
7521 stream << lineInfo <<
"\n";
7523 stream << getDots() <<
"\n" << std::endl;
7526 void printClosedHeader( std::string
const& _name ) {
7527 printOpenHeader( _name );
7528 stream << getDots() <<
"\n";
7530 void printOpenHeader( std::string
const& _name ) {
7531 stream << getDashes() <<
"\n";
7533 Colour colourGuard( Colour::Headers );
7534 printHeaderString( _name );
7540 void printHeaderString( std::string
const& _string, std::size_t indent = 0 ) {
7541 std::size_t i = _string.find(
": " );
7542 if( i != std::string::npos )
7546 stream << Text( _string, TextAttributes()
7547 .setIndent( indent+i)
7548 .setInitialIndent( indent ) ) <<
"\n";
7551 void printTotals(
const Totals& totals ) {
7553 stream <<
"No tests ran";
7556 Colour colour( Colour::ResultError );
7557 printCounts(
"test case", totals.
testCases );
7560 printCounts(
"assertion", totals.
assertions );
7565 Colour colour( Colour::ResultSuccess );
7566 stream <<
"All tests passed (" 7571 void printCounts( std::string
const& label,
Counts const& counts ) {
7572 if( counts.
total() == 1 ) {
7573 stream <<
"1 " << label <<
" - ";
7580 stream << counts.
total() <<
" " << label <<
"s ";
7583 stream <<
"- " << counts.
failed <<
" failed";
7584 else if( counts.
passed == 2 )
7585 stream <<
"- both passed";
7587 stream <<
"- all passed";
7591 stream <<
"- both failed";
7593 stream <<
"- all failed";
7598 void printTotalsDivider() {
7599 stream << getDoubleDashes() <<
"\n";
7601 void printSummaryDivider() {
7602 stream << getDashes() <<
"\n";
7604 static std::string
const& getDashes() {
7608 static std::string
const& getDots() {
7612 static std::string
const& getDoubleDashes() {
7614 return doubleDashes;
7616 static std::string
const& getTildes() {
7622 bool m_headerPrinted;
7623 bool m_atLeastOneTestCasePrinted;
7626 INTERNAL_CATCH_REGISTER_REPORTER(
"console", ConsoleReporter )
7655 ConsoleReporter::~ConsoleReporter() {}
7659 XmlReporter::~XmlReporter() {}
7660 JunitReporter::~JunitReporter() {}
7661 TestRegistry::~TestRegistry() {}
7662 FreeFunctionTestCase::~FreeFunctionTestCase() {}
7674 void Config::dummy() {}
7676 INTERNAL_CATCH_REGISTER_LEGACY_REPORTER(
"xml", XmlReporter )
7680 #pragma clang diagnostic pop 7685 #ifdef CATCH_CONFIG_MAIN 7687 #define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED 7692 int main (
int argc,
char *
const argv[]) {
7693 return Catch::Session().run( argc, argv );
7699 int main (
int argc,
char *
const argv[]) {
7700 #if !CATCH_ARC_ENABLED 7701 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
7704 Catch::registerTestMethods();
7705 int result = Catch::Session().run( argc, (
char*
const*)argv );
7707 #if !CATCH_ARC_ENABLED 7721 #ifdef CATCH_CONFIG_PREFIX_ALL 7723 #define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" ) 7724 #define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::NegateResult, "CATCH_REQUIRE_FALSE" ) 7726 #define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, ..., Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS" ) 7727 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" ) 7728 #define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" ) 7730 #define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" ) 7731 #define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::NegateResult, "CATCH_CHECK_FALSE" ) 7732 #define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" ) 7733 #define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" ) 7734 #define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" ) 7736 #define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, ..., Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS" ) 7737 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" ) 7738 #define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" ) 7740 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" ) 7741 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" ) 7743 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" ) 7744 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN" ) 7745 #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL" ) 7746 #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED" ) 7747 #define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" ) 7748 #define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" ) 7749 #define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" ) 7751 #ifdef CATCH_CONFIG_VARIADIC_MACROS 7752 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) 7753 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) 7754 #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) 7755 #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) 7757 #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) 7758 #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) 7759 #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) 7760 #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) 7762 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) 7764 #define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) 7765 #define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) 7767 #define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) 7770 #ifdef CATCH_CONFIG_VARIADIC_MACROS 7771 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ ) 7773 #define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags ) 7775 #define CATCH_GIVEN( desc ) CATCH_SECTION( "Given: " desc, "" ) 7776 #define CATCH_WHEN( desc ) CATCH_SECTION( " When: " desc, "" ) 7777 #define CATCH_AND_WHEN( desc ) CATCH_SECTION( " And: " desc, "" ) 7778 #define CATCH_THEN( desc ) CATCH_SECTION( " Then: " desc, "" ) 7779 #define CATCH_AND_THEN( desc ) CATCH_SECTION( " And: " desc, "" ) 7784 #define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" ) 7785 #define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::NegateResult, "REQUIRE_FALSE" ) 7787 #define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, ..., Catch::ResultDisposition::Normal, "REQUIRE_THROWS" ) 7788 #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" ) 7789 #define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" ) 7791 #define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" ) 7792 #define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::NegateResult, "CHECK_FALSE" ) 7793 #define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" ) 7794 #define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" ) 7795 #define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" ) 7797 #define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, ..., Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS" ) 7798 #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" ) 7799 #define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" ) 7801 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" ) 7802 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" ) 7804 #define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" ) 7805 #define WARN( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN" ) 7806 #define FAIL( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL" ) 7807 #define SUCCEED( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED" ) 7808 #define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" ) 7809 #define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" ) 7810 #define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" ) 7812 #ifdef CATCH_CONFIG_VARIADIC_MACROS 7813 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) 7814 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) 7815 #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) 7816 #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) 7818 #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) 7819 #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) 7820 #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) 7821 #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) 7823 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) 7825 #define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) 7826 #define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) 7828 #define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) 7832 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) 7835 #ifdef CATCH_CONFIG_VARIADIC_MACROS 7836 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ ) 7838 #define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags ) 7840 #define GIVEN( desc ) SECTION( " Given: " desc, "" ) 7841 #define WHEN( desc ) SECTION( " When: " desc, "" ) 7842 #define AND_WHEN( desc ) SECTION( "And when: " desc, "" ) 7843 #define THEN( desc ) SECTION( " Then: " desc, "" ) 7844 #define AND_THEN( desc ) SECTION( " And: " desc, "" ) 7849 #pragma clang diagnostic pop 7852 #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED ShowDurations::OrNot showDurations
virtual void testGroupStarting(GroupInfo const &)
void setStreamBuf(std::streambuf *buf)
Ptr< SectionNode > m_rootSection
int main(int argc, char *argv[])
std::string getExpandedExpression() const
TestRunInfo(std::string const &_name)
CompositeGenerator< T > between(T from, T to)
bool operator<(const Landmark &lhs, const Landmark &rhs)
std::vector< Ptr< TestCaseNode > > m_testCases
Approx operator()(double value)
virtual ~TestGroupStats()
StartsWith(std::string const &substr)
virtual void sectionEnded(SectionStats const &)
GroupInfo(std::string const &_name, std::size_t _groupIndex, std::size_t _groupsCount)
EndsWith(std::string const &substr)
ReporterConfig(Ptr< IConfig > const &_fullConfig, std::ostream &_stream)
virtual bool match(ExpressionT const &expr) const
std::string getName() const
virtual std::size_t size() const
ExpressionResultBuilder & setRhs(std::string const &rhs)
std::vector< Ptr< TestGroupNode > > m_testGroups
virtual void noMatchingTestCases(std::string const &)
SectionNode(SectionStats const &_stats)
ExpressionResultBuilder & setResultType(ResultWas::OfType result)
SourceLineInfo getSourceInfo() const
static bool evaluate(T1 const &lhs, T2 const &rhs)
virtual bool match(ExpressionT const &expr) const
std::vector< TestCaseFilters > const & filters() const
virtual void testCaseEnded(TestCaseStats const &)
std::vector< Ptr< ChildNodeT > > ChildNodes
bool hasExpandedExpression() const
void throwLogicError(std::string const &message, SourceLineInfo const &locationInfo)
virtual ~StreamingReporterBase()
CompositeGenerator & then(CompositeGenerator &other)
MethodTestCase(void(C::*method)())
const T * operator->() const
virtual void testRunStarting(TestRunInfo const &_testRunInfo)
static std::string convert(T const &_value)
bool listReporters() const
ResultDisposition::Flags operator|(ResultDisposition::Flags lhs, ResultDisposition::Flags rhs)
ExpressionResultBuilder & endExpression(ResultDisposition::Flags resultDisposition)
AssertionStats(AssertionResult const &_assertionResult, std::vector< MessageInfo > const &_infoMessages, Totals const &_totals)
Equals(std::string const &str)
virtual T getValue(std::size_t index) const
virtual ~IExceptionTranslatorRegistry()
CompositeGenerator< T > values(T val1, T val2, T val3, T val4)
Section(SourceLineInfo const &lineInfo, std::string const &name, std::string const &description="")
Ptr< SectionNode > m_deepestSection
std::string getExpression() const
MessageBuilder(std::string const ¯oName, SourceLineInfo const &lineInfo, ResultWas::OfType type)
std::string toString(T const &value)
converts any type to a string
TestGroupStats(GroupInfo const &_groupInfo)
bool shouldNegate(int flags)
virtual IResultCapture & getResultCapture()=0
static std::string convert(U *p)
std::string(* exceptionTranslateFunction)()
std::string toString(unsigned char value)
Node< TestGroupStats, TestCaseNode > TestGroupNode
AssertionResult buildResult(AssertionInfo const &info) const
virtual void testGroupEnded(TestGroupStats const &testGroupStats)
ExceptionTranslatorRegistrar(std::string(*translateFunction)(T &))
void setFilename(std::string const &filename)
std::vector< std::vector< Ptr< SectionNode > > > m_sections
std::string capturedExpression
std::string toString() const
std::string trim(std::string const &str)
ExpressionResultBuilder expressionResultBuilderFromMatcher(MatcherT const &matcher, std::string const &matcherCallAsString)
std::vector< Ptr< SectionNode > > ChildSections
virtual std::string toString() const
#define CATCH_CONFIG_CONSOLE_WIDTH
SectionInfo(std::string const &_name, std::string const &_description, SourceLineInfo const &_lineInfo)
bool hasExpression() const
std::string reconstructedExpression
std::string outputFilename
TestCaseInfo const & getTestCaseInfo() const
virtual ~IResultCapture()
Node< TestCaseStats, SectionNode > TestCaseNode
void deleteAllValues(AssociativeContainerT &container)
Totals delta(Totals const &prevTotals) const
void swap(TestCase &other)
IContext & getCurrentContext()
CumulativeReporterBase(ReporterConfig const &_config)
Contains(std::string const &substr)
void(SafeBool::* type)() const
AutoReg(TestFunction function, SourceLineInfo const &lineInfo, NameAndDesc const &nameAndDesc)
virtual T getValue(std::size_t index) const
std::set< std::string > tags
std::string getTestMacroName() const
static const char * getName()
LazyStat< TestCaseInfo > currentTestCaseInfo
IGeneratorsForTest * createGeneratorsForTest()
virtual Ptr< Matcher< ExpressionT > > clone() const
Ptr< IConfig > fullConfig() const
NotImplementedException(SourceLineInfo const &lineInfo)
bool hasTag(std::string const &tag) const
static const char * getName()
virtual ~IExceptionTranslator()
AssertionResult assertionResult
Option & operator=(Option const &_other)
ResultDisposition::Flags resultDisposition
#define CATCH_INTERNAL_ERROR(msg)
virtual void popScopedMessage(MessageInfo const &message)=0
bool matches(std::set< std::string > const &tags) const
static const char * getName()
LazyStat< GroupInfo > currentGroupInfo
LazyStat & operator=(T const &_value)
virtual IExceptionTranslatorRegistry & getExceptionTranslatorRegistry()=0
virtual void registerTest(TestCase const &testInfo)=0
void writeToDebugConsole(std::string const &text)
virtual ShowDurations::OrNot showDurations() const
AllOf & add(Matcher< ExpressionT > const &matcher)
TestCaseInfo(std::string const &_name, std::string const &_className, std::string const &_description, std::set< std::string > const &_tags, bool _isHidden, SourceLineInfo const &_lineInfo)
virtual ~IMutableContext()
virtual void invoke() const
Stream(std::streambuf *_streamBuf, bool _isOwned)
AnyOf & add(Matcher< ExpressionT > const &matcher)
std::map< std::string, IReporterFactory * > FactoryMap
pluralise(std::size_t count, std::string const &label)
std::vector< std::string > testsOrTags
std::size_t total() const
virtual void testRunEnded(TestRunStats const &testRunStats)
virtual void testCaseStarting(TestCaseInfo const &_testInfo)
bool applyEvaluator(T1 const &lhs, T2 const &rhs)
bool isJustInfo(int flags)
static std::string convert(std::vector< T > const &v)
static const char * getName()
ReporterConfig(Ptr< IConfig > const &_fullConfig)
virtual ~IStreamingReporter()
ScopedMessage(MessageBuilder const &builder)
void addFilter(TestCaseFilter const &filter)
TestCaseStats(TestCaseInfo const &_testInfo, Totals const &_totals, std::string const &_stdOut, std::string const &_stdErr, bool _aborting)
std::string getExpressionInMacro() const
std::string getProcessName() const
void addTags(std::string const &tagPattern)
Stream createStream(std::string const &streamName)
std::string const & getFilename() const
virtual void testGroupEnded(TestGroupStats const &)
Approx & scale(double newScale)
virtual void registerTranslator(const IExceptionTranslator *translator)=0
NameAndDesc(const char *_name="", const char *_description="")
bool operator==(TestCase const &other) const
virtual std::string toString() const
static bool evaluate(T1 const &lhs, T2 const &rhs)
Node< TestRunStats, TestGroupNode > TestRunNode
virtual bool warnAboutMissingAssertions() const
static const char * getName()
IRegistryHub & getRegistryHub()
Tag(std::string const &name, bool isNegated)
MessageInfo(std::string const &_macroName, SourceLineInfo const &_lineInfo, ResultWas::OfType _type)
virtual T getValue(std::size_t index) const =0
bool compare(T *lhs, int rhs)
void add(const IGenerator< T > *generator)
Approx(Approx const &other)
void registerTestCase(ITestCase *testCase, char const *className, NameAndDesc const &nameAndDesc, SourceLineInfo const &lineInfo)
std::string getReporterName() const
IMutableRegistryHub & getMutableRegistryHub()
virtual FactoryMap const & getFactories() const =0
virtual bool match(std::string const &expr) const
ExpressionResultBuilder & setOp(std::string const &op)
FalseType testStreamable(FalseType)
StreamingReporterBase(ReporterConfig const &_config)
~CumulativeReporterBase()
CompositeGenerator(CompositeGenerator &other)
virtual std::string toString() const
virtual std::string getCurrentTestName() const =0
bool shouldContinueOnFailure(int flags)
static std::string convert(T const &)
TestRunStats(TestRunStats const &_other)
std::vector< Ptr< TestRunNode > > m_testRuns
TestCaseFilters(std::string const &name)
virtual void sectionStarting(SectionInfo const &_sectionInfo)
std::string reconstructExpression(AssertionInfo const &info) const
TestCase withName(std::string const &_newName) const
std::string getName() const
virtual void testGroupStarting(GroupInfo const &_groupInfo)
std::vector< SectionInfo > m_sectionStack
static bool evaluate(T1 const &lhs, T2 const &rhs)
ExpressionResultBuilder & endExpression(ResultDisposition::Flags resultDisposition)
virtual void sectionEnded(SectionStats const §ionStats)
ChildSections childSections
virtual Ptr< Matcher > clone() const =0
virtual ~IReporterRegistry()
virtual std::string toString() const
virtual bool includeSuccessfulResults() const
virtual std::string toString() const
std::string makeString(const char *str)
virtual ITestCaseRegistry const & getTestCaseRegistry() const =0
IfFilterMatches::DoWhat getFilterType() const
ResultWas::OfType getResultType() const
virtual std::ostream & stream() const
virtual bool match(std::string const &expr) const
void toLowerInPlace(std::string &s)
SectionStats(SectionInfo const &_sectionInfo, Counts const &_assertions, double _durationInSeconds, bool _missingAssertions)
ExpressionT ExpressionType
virtual IReporterRegistry const & getReporterRegistry() const =0
virtual ~IReporterFactory()
AnyOf(AnyOf const &other)
#define INTERNAL_CATCH_STRINGIFY(expr)
virtual bool match(std::string const &expr) const
TestRunStats(TestRunInfo const &_runInfo, Totals const &_totals, bool _aborting)
virtual bool moveNext()=0
T valueOr(T const &defaultValue) const
virtual IStreamingReporter * create(std::string const &name, Ptr< IConfig > const &config) const =0
bool shouldRedirectStdOut
double getElapsedSeconds() const
IResultCapture & getResultCapture()
virtual bool assertionEnded(AssertionStats const &assertionStats)
virtual ~IMutableRegistryHub()
std::string toLower(std::string const &s)
Impl::StdString::StartsWith StartsWith(const char *substr)
Impl::StdString::EndsWith EndsWith(const char *substr)
std::string getMessage() const
virtual std::string toString() const
Equals(Equals const &other)
virtual const char * what() const
bool operator<(TestCase const &other) const
ResultWas::OfType resultType
virtual ~ITestCaseRegistry()
unsigned int getElapsedNanoseconds() const
Impl::StdString::Equals Equals(const char *str)
bool operator==(const RegistrationTransform &lhs, const RegistrationTransform &rhs)
virtual void addRef() const
bool startsWith(std::string const &s, std::string const &prefix)
Option(Option const &_other)
virtual std::vector< TestCase > getMatchingTestCases(std::string const &rawTestSpec) const =0
bool matches(std::set< std::string > const &tags) const
static bool evaluate(T1 const &lhs, T2 const &rhs)
std::vector< AssertionStats > m_assertions
virtual size_t getGeneratorIndex(std::string const &fileInfo, size_t totalSize)=0
bool shouldInclude(TestCase const &testCase) const
virtual ~AssertionStats()
virtual void testCaseStarting(TestCaseInfo const &)
std::set< std::string > const & getTags() const
static const char * getName()
TestCaseFilter(std::string const &testSpec, IfFilterMatches::DoWhat matchBehaviour=IfFilterMatches::AutoDetectBehaviour)
virtual void release() const
BetweenGenerator(T from, T to)
Contains(Contains const &other)
bool matchesTags(std::string const &tagPattern) const
CompositeGenerator & then(T value)
CompositeGenerator & setFileInfo(const char *fileInfo)
virtual ~IGeneratorsForTest()
virtual std::vector< TestCase > const & getAllTests() const =0
TestCase makeTestCase(ITestCase *testCase, std::string const &className, std::string const &name, std::string const &description, SourceLineInfo const &lineInfo)
std::string makeString(T const &value)
static bool evaluate(T1 const &lhs, T2 const &rhs)
AllOf(AllOf const &other)
void useStream(std::string const &streamName)
bool shouldInclude(TestCase const &testCase) const
IMutableContext & getCurrentMutableContext()
Impl::StdString::Contains Contains(const char *substr)
virtual bool match(std::string const &expr) const
virtual bool allowThrows() const
virtual void sectionStarting(SectionInfo const §ionInfo)
bool endsWith(std::string const &s, std::string const &suffix)
bool contains(std::string const &s, std::string const &infix)
TestCase(ITestCase *testCase, TestCaseInfo const &info)
ExpressionResultBuilder & setLhs(std::string const &lhs)
T const & operator*() const
Config(ConfigData const &data)
virtual void testRunStarting(TestRunInfo const &)
virtual ~IGeneratorInfo()
ExpressionResultBuilder & operator=(ExpressionResultBuilder const &other)
SourceLineInfo(std::string const &_file, std::size_t _line)
unsigned int getElapsedMilliseconds() const
TestGroupStats(GroupInfo const &_groupInfo, Totals const &_totals, bool _aborting)
Impl::Generic::AnyOf< ExpressionT > AnyOf(Impl::Matcher< ExpressionT > const &m1, Impl::Matcher< ExpressionT > const &m2, Impl::Matcher< ExpressionT > const &m3)
std::vector< Ptr< SectionNode > > m_sectionStack
ExpressionResultBuilder(ResultWas::OfType resultType=ResultWas::Unknown)
std::string translateActiveException()
virtual void testCaseEnded(TestCaseStats const &testCaseStats)
std::ostream & stream() const
static bool evaluate(T1 const &lhs, T2 const &rhs)
StartsWith(StartsWith const &other)
SourceLineInfo(SourceLineInfo const &other)
AssertionResultData m_resultData
Approx & epsilon(double newEpsilon)
std::streambuf * streamBuf
void addTestSpec(std::string const &testSpec)
bool shouldDebugBreak() const
virtual std::size_t size() const =0
void print(QString header, QRect r)
bool shouldSuppressFailure(int flags)
void forEach(ContainerT &container, Function function)
virtual void sectionEnded(SectionInfo const &name, Counts const &assertions, double _durationInSeconds)=0
virtual bool advanceGeneratorsForCurrentTest()=0
Impl::Generic::AllOf< ExpressionT > AllOf(Impl::Matcher< ExpressionT > const &m1, Impl::Matcher< ExpressionT > const &m2, Impl::Matcher< ExpressionT > const &m3)
void parse(std::string const &str)
std::vector< MessageInfo > infoMessages
virtual std::string name() const
TestCase & operator=(TestCase const &other)
std::ostringstream m_stream
void operator()(std::string const &str)
std::ostream & operator<<(std::ostream &os, SourceLineInfo const &info)
static const char * getName()
virtual void pushScopedMessage(MessageInfo const &message)=0
static type makeSafe(bool value)
Verbosity::Level verbosity
float4 transform(float16 matrix, float4 voxel)
AutoReg(void(C::*method)(), char const *className, NameAndDesc const &nameAndDesc, SourceLineInfo const &lineInfo)
virtual std::size_t size() const
void deleteAll(ContainerT &container)
virtual void testRunEnded(TestRunStats const &)
bool isOk(ResultWas::OfType resultType)
LazyStat< TestRunInfo > currentTestRunInfo
virtual ~NotImplementedException()
TagExpressionParser(TagExpression &exp)
virtual std::string translateActiveException() const =0
virtual void assertionStarting(AssertionInfo const &)
EndsWith(EndsWith const &other)
std::vector< AssertionStats > Assertions
virtual void registerReporter(std::string const &name, IReporterFactory *factory)=0