11 #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED 12 #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED 14 #define TWOBLUECUBES_CATCH_HPP_INCLUDED 17 # pragma clang system_header 18 #elif defined __GNUC__ 19 # pragma GCC system_header 25 # ifdef __ICC // icpc defines the __clang__ macro 26 # pragma warning(push) 27 # pragma warning(disable: 161 1682) 29 # pragma clang diagnostic ignored "-Wglobal-constructors" 30 # pragma clang diagnostic ignored "-Wvariadic-macros" 31 # pragma clang diagnostic ignored "-Wc99-extensions" 32 # pragma clang diagnostic ignored "-Wunused-variable" 33 # pragma clang diagnostic push 34 # pragma clang diagnostic ignored "-Wpadded" 35 # pragma clang diagnostic ignored "-Wc++98-compat" 36 # pragma clang diagnostic ignored "-Wc++98-compat-pedantic" 37 # pragma clang diagnostic ignored "-Wswitch-enum" 38 # pragma clang diagnostic ignored "-Wcovered-switch-default" 40 #elif defined __GNUC__ 41 # pragma GCC diagnostic ignored "-Wvariadic-macros" 42 # pragma GCC diagnostic ignored "-Wunused-variable" 43 # pragma GCC diagnostic push 44 # pragma GCC diagnostic ignored "-Wpadded" 46 #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) 51 # ifndef CLARA_CONFIG_MAIN 52 # define CLARA_CONFIG_MAIN_NOT_DEFINED 53 # define CLARA_CONFIG_MAIN 58 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED 61 #define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED 63 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line 64 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) 65 #ifdef CATCH_CONFIG_COUNTER 66 # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) 68 # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) 71 #define INTERNAL_CATCH_STRINGIFY2( expr ) #expr 72 #define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr ) 79 #define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED 111 # if __cplusplus >= 201103L 112 # define CATCH_CPP11_OR_GREATER 115 # if __cplusplus >= 201402L 116 # define CATCH_CPP14_OR_GREATER 123 # if __has_feature(cxx_nullptr) 124 # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR 127 # if __has_feature(cxx_noexcept) 128 # define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT 131 # if defined(CATCH_CPP11_OR_GREATER) 132 # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) 141 #endif // __BORLANDC__ 145 #ifdef __EDG_VERSION__ 147 #endif // __EDG_VERSION__ 159 # if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) 160 # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR 163 # if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) && defined(CATCH_CPP11_OR_GREATER) 164 # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "GCC diagnostic ignored \"-Wparentheses\"" ) 176 #if (_MSC_VER >= 1600) 177 # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR 178 # define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR 181 #if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015)) 182 #define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT 183 #define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS 191 #if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \ 192 ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \ 193 ( defined __GNUC__ && __GNUC__ >= 3 ) || \ 194 ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L ) 196 #define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS 201 #if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \ 202 ( defined __GNUC__ && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 ) || \ 203 ( defined __clang__ && __clang_major__ >= 3 ) 205 #define CATCH_INTERNAL_CONFIG_COUNTER 213 #if defined(CATCH_CPP11_OR_GREATER) 215 # if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) 216 # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR 219 # ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT 220 # define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT 223 # ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS 224 # define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS 227 # ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM 228 # define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM 231 # ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE 232 # define CATCH_INTERNAL_CONFIG_CPP11_TUPLE 235 # ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS 236 # define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS 239 # if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) 240 # define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG 243 # if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) 244 # define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE 246 # if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) 247 # define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR 250 #endif // __cplusplus >= 201103L 253 #if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11) 254 # define CATCH_CONFIG_CPP11_NULLPTR 256 #if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11) 257 # define CATCH_CONFIG_CPP11_NOEXCEPT 259 #if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11) 260 # define CATCH_CONFIG_CPP11_GENERATED_METHODS 262 #if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11) 263 # define CATCH_CONFIG_CPP11_IS_ENUM 265 #if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11) 266 # define CATCH_CONFIG_CPP11_TUPLE 268 #if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS) 269 # define CATCH_CONFIG_VARIADIC_MACROS 271 #if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11) 272 # define CATCH_CONFIG_CPP11_LONG_LONG 274 #if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11) 275 # define CATCH_CONFIG_CPP11_OVERRIDE 277 #if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11) 278 # define CATCH_CONFIG_CPP11_UNIQUE_PTR 280 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) 281 # define CATCH_CONFIG_COUNTER 284 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) 285 # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS 289 #if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT) 290 # define CATCH_NOEXCEPT noexcept 291 # define CATCH_NOEXCEPT_IS(x) noexcept(x) 293 # define CATCH_NOEXCEPT throw() 294 # define CATCH_NOEXCEPT_IS(x) 298 #ifdef CATCH_CONFIG_CPP11_NULLPTR 299 # define CATCH_NULL nullptr 301 # define CATCH_NULL NULL 305 #ifdef CATCH_CONFIG_CPP11_OVERRIDE 306 # define CATCH_OVERRIDE override 308 # define CATCH_OVERRIDE 312 #ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR 313 # define CATCH_AUTO_PTR( T ) std::unique_ptr<T> 315 # define CATCH_AUTO_PTR( T ) std::auto_ptr<T> 328 #ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS 345 typedef void (
SafeBool::*type)()
const;
347 static type makeSafe(
bool value ) {
348 return value ? &SafeBool::trueValue : 0;
351 void trueValue()
const {}
354 template<
typename ContainerT>
355 inline void deleteAll( ContainerT&
container ) {
356 typename ContainerT::const_iterator it = container.begin();
357 typename ContainerT::const_iterator itEnd = container.end();
358 for(; it != itEnd; ++it )
361 template<
typename AssociativeContainerT>
362 inline void deleteAllValues( AssociativeContainerT& container ) {
363 typename AssociativeContainerT::const_iterator it = container.begin();
364 typename AssociativeContainerT::const_iterator itEnd = container.end();
365 for(; it != itEnd; ++it )
369 bool startsWith( std::string
const& s, std::string
const& prefix );
370 bool endsWith( std::string
const& s, std::string
const& suffix );
371 bool contains( std::string
const& s, std::string
const& infix );
372 void toLowerInPlace( std::string& s );
373 std::string toLower( std::string
const& s );
374 std::string trim( std::string
const& str );
375 bool replaceInPlace( std::string& str, std::string
const& replaceThis, std::string
const& withThis );
378 pluralise( std::size_t count, std::string
const& label );
380 friend std::ostream& operator << ( std::ostream& os,
pluralise const& pluraliser );
391 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS 404 std::ostream& operator << ( std::ostream& os,
SourceLineInfo const& info );
407 inline bool isTrue(
bool value ){
return value; }
408 inline bool alwaysTrue() {
return true; }
409 inline bool alwaysFalse() {
return false; }
411 void throwLogicError( std::string
const& message,
SourceLineInfo const& locationInfo );
413 void seedRng( IConfig
const& config );
414 unsigned int rngSeed();
422 return std::string();
431 #define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) ) 432 #define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO ); 446 virtual const char* what()
const CATCH_NOEXCEPT;
456 #define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO ) 459 #define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED 462 #define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED 470 virtual bool moveNext() = 0;
471 virtual std::size_t getCurrentIndex()
const = 0;
477 virtual IGeneratorInfo& getGeneratorInfo( std::string
const& fileInfo, std::size_t
size ) = 0;
478 virtual bool moveNext() = 0;
486 #define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED 489 #pragma clang diagnostic push 490 #pragma clang diagnostic ignored "-Wpadded" 501 Ptr() : m_p( CATCH_NULL ){}
502 Ptr(
T* p ) : m_p( p ){
506 Ptr(
Ptr const& other ) : m_p( other.m_p ){
519 Ptr& operator = (
T* p ){
524 Ptr& operator = (
Ptr const& other ){
529 void swap(
Ptr& other ) { std::swap( m_p, other.m_p ); }
530 T*
get()
const{
return m_p; }
531 T& operator*()
const {
return *m_p; }
532 T* operator->()
const {
return m_p; }
533 bool operator !()
const {
return m_p == CATCH_NULL; }
534 operator SafeBool::type()
const {
return SafeBool::makeSafe( m_p != CATCH_NULL ); }
542 virtual void addRef()
const = 0;
543 virtual void release()
const = 0;
546 template<
typename T = IShared>
551 virtual void addRef()
const {
554 virtual void release()
const {
559 mutable unsigned int m_rc;
565 #pragma clang diagnostic pop 586 virtual IRunner* getRunner() = 0;
587 virtual size_t getGeneratorIndex( std::string
const& fileInfo,
size_t totalSize ) = 0;
588 virtual bool advanceGeneratorsForCurrentTest() = 0;
595 virtual void setResultCapture(
IResultCapture* resultCapture ) = 0;
596 virtual void setRunner(
IRunner* runner ) = 0;
602 void cleanUpContext();
603 Stream createStream( std::string
const& streamName );
608 #define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED 611 #define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED 620 virtual void invoke ()
const = 0;
630 virtual std::vector<TestCase>
const& getAllTests()
const = 0;
631 virtual std::vector<TestCase>
const& getAllTestsSorted( IConfig
const& config )
const = 0;
634 bool matchTest(
TestCase const& testCase, TestSpec
const& testSpec, IConfig
const& config );
635 std::vector<TestCase> filterTests( std::vector<TestCase>
const& testCases, TestSpec
const& testSpec, IConfig
const& config );
636 std::vector<TestCase>
const& getAllTestCasesSorted( IConfig
const& config );
648 virtual void invoke()
const {
656 void (C::*m_method)();
659 typedef void(*TestFunction)();
662 NameAndDesc(
const char* _name =
"",
const char* _description=
"" )
663 : name( _name ), description( _description )
667 const char* description;
670 void registerTestCase
672 char const* className,
679 ( TestFunction
function,
685 (
void (C::*method)(),
686 char const* className,
701 void operator= (
AutoReg const& );
704 void registerTestCaseFunction
705 ( TestFunction
function,
711 #ifdef CATCH_CONFIG_VARIADIC_MACROS 712 #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \ 714 static void TestName(); \ 715 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\ 716 static void TestName() 717 #define INTERNAL_CATCH_TESTCASE( ... ) \ 718 INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ ) 721 #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ 722 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); } 725 #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\ 727 struct TestName : ClassName{ \ 730 Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \ 732 void TestName::test() 733 #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \ 734 INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ ) 737 #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \ 738 Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); 741 #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \ 743 static void TestName(); \ 744 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\ 745 static void TestName() 746 #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \ 747 INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc ) 750 #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \ 751 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); } 754 #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\ 756 struct TestCaseName : ClassName{ \ 759 Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \ 761 void TestCaseName::test() 762 #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\ 763 INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc ) 766 #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \ 767 Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); 771 #define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED 774 #define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED 777 #define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED 790 ExpressionFailed = FailureBit | 1,
791 ExplicitFailure = FailureBit | 2,
793 Exception = 0x100 | FailureBit,
795 ThrewException = Exception | 1,
796 DidntThrowException = Exception | 2,
798 FatalErrorCondition = 0x200 | FailureBit
802 inline bool isOk( ResultWas::OfType resultType ) {
803 return ( resultType & ResultWas::FailureBit ) == 0;
805 inline bool isJustInfo(
int flags ) {
806 return flags == ResultWas::Info;
813 ContinueOnFailure = 0x02,
818 inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
819 return static_cast<ResultDisposition::Flags
>(
static_cast<int>( lhs ) | static_cast<int>( rhs ) );
822 inline bool shouldContinueOnFailure(
int flags ) {
return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
823 inline bool isFalseTest(
int flags ) {
return ( flags & ResultDisposition::FalseTest ) != 0; }
824 inline bool shouldSuppressFailure(
int flags ) {
return ( flags & ResultDisposition::SuppressFail ) != 0; }
829 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED 840 std::string
const& _capturedExpression,
841 ResultDisposition::Flags _resultDisposition );
843 std::string macroName;
845 std::string capturedExpression;
846 ResultDisposition::Flags resultDisposition;
853 std::string reconstructedExpression;
855 ResultWas::OfType resultType;
863 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS 871 bool succeeded()
const;
872 ResultWas::OfType getResultType()
const;
873 bool hasExpression()
const;
874 bool hasMessage()
const;
875 std::string getExpression()
const;
876 std::string getExpressionInMacro()
const;
877 bool hasExpandedExpression()
const;
878 std::string getExpandedExpression()
const;
879 std::string getMessage()
const;
881 std::string getTestMacroName()
const;
891 #define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED 898 template<
typename ExpressionT>
class AllOf;
899 template<
typename ExpressionT>
class AnyOf;
900 template<
typename ExpressionT>
class Not;
903 template<
typename ExpressionT>
906 typedef ExpressionT ExpressionType;
910 virtual bool match( ExpressionT
const& expr )
const = 0;
911 virtual std::string toString()
const = 0;
918 template<
typename DerivedT,
typename ExpressionT>
927 template<
typename ExpressionT>
928 class Not :
public MatcherImpl<Not<ExpressionT>, ExpressionT> {
931 Not( Not
const& other ) : m_matcher( other.m_matcher ) {}
933 virtual bool match( ExpressionT
const& expr )
const CATCH_OVERRIDE {
934 return !m_matcher->match( expr );
937 virtual std::string toString()
const CATCH_OVERRIDE {
938 return "not " + m_matcher->toString();
944 template<
typename ExpressionT>
945 class AllOf :
public MatcherImpl<AllOf<ExpressionT>, ExpressionT> {
949 AllOf( AllOf
const& other ) : m_matchers( other.m_matchers ) {}
952 m_matchers.push_back( matcher.clone() );
955 virtual bool match( ExpressionT
const& expr )
const 957 for( std::size_t i = 0; i < m_matchers.size(); ++i )
958 if( !m_matchers[i]->match( expr ) )
962 virtual std::string toString()
const {
963 std::ostringstream oss;
965 for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
968 oss << m_matchers[i]->toString();
975 AllOf allOfExpr( *
this );
976 allOfExpr.add( other );
981 std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
984 template<
typename ExpressionT>
985 class AnyOf :
public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> {
989 AnyOf( AnyOf
const& other ) : m_matchers( other.m_matchers ) {}
992 m_matchers.push_back( matcher.clone() );
995 virtual bool match( ExpressionT
const& expr )
const 997 for( std::size_t i = 0; i < m_matchers.size(); ++i )
998 if( m_matchers[i]->match( expr ) )
1002 virtual std::string toString()
const {
1003 std::ostringstream oss;
1005 for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
1008 oss << m_matchers[i]->toString();
1015 AnyOf anyOfExpr( *
this );
1016 anyOfExpr.add( other );
1021 std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
1026 template<
typename ExpressionT>
1029 allOfExpr.add( *
this );
1030 allOfExpr.add( other );
1034 template<
typename ExpressionT>
1037 anyOfExpr.add( *
this );
1038 anyOfExpr.add( other );
1042 template<
typename ExpressionT>
1047 namespace StdString {
1049 inline std::string
makeString( std::string
const& str ) {
return str; }
1050 inline std::string
makeString(
const char* str ) {
return str ? std::string( str ) : std::string(); }
1054 CasedString( std::string
const& str, CaseSensitive::Choice caseSensitivity )
1055 : m_caseSensitivity( caseSensitivity ),
1056 m_str( adjustString( str ) )
1058 std::string adjustString( std::string
const& str )
const {
1059 return m_caseSensitivity == CaseSensitive::No
1064 std::string toStringSuffix()
const 1066 return m_caseSensitivity == CaseSensitive::No
1067 ?
" (case insensitive)" 1070 CaseSensitive::Choice m_caseSensitivity;
1075 Equals( std::string
const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
1076 : m_data( str, caseSensitivity )
1078 Equals(
Equals const& other ) : m_data( other.m_data ){}
1082 virtual bool match( std::string
const& expr )
const {
1083 return m_data.m_str == m_data.adjustString( expr );;
1085 virtual std::string toString()
const {
1086 return "equals: \"" + m_data.m_str +
"\"" + m_data.toStringSuffix();
1093 Contains( std::string
const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
1094 : m_data( substr, caseSensitivity ){}
1099 virtual bool match( std::string
const& expr )
const {
1100 return m_data.adjustString( expr ).find( m_data.m_str ) != std::string::npos;
1102 virtual std::string toString()
const {
1103 return "contains: \"" + m_data.m_str +
"\"" + m_data.toStringSuffix();
1110 StartsWith( std::string
const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
1111 : m_data( substr, caseSensitivity ){}
1117 virtual bool match( std::string
const& expr )
const {
1118 return startsWith( m_data.adjustString( expr ), m_data.m_str );
1120 virtual std::string toString()
const {
1121 return "starts with: \"" + m_data.m_str +
"\"" + m_data.toStringSuffix();
1128 EndsWith( std::string
const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
1129 : m_data( substr, caseSensitivity ){}
1134 virtual bool match( std::string
const& expr )
const {
1135 return endsWith( m_data.adjustString( expr ), m_data.m_str );
1137 virtual std::string toString()
const {
1138 return "ends with: \"" + m_data.m_str +
"\"" + m_data.toStringSuffix();
1148 template<
typename ExpressionT>
1153 template<
typename ExpressionT>
1158 template<
typename ExpressionT>
1164 template<
typename ExpressionT>
1169 template<
typename ExpressionT>
1203 using namespace Matchers;
1213 struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
1218 oss << other.oss.str();
1222 oss << other.oss.str();
1225 std::ostringstream oss;
1232 char const* capturedExpression,
1233 ResultDisposition::Flags resultDisposition,
1234 char const* secondArg =
"" );
1236 template<
typename T>
1240 template<
typename T>
1242 m_stream.oss << value;
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& );
1255 void endExpression();
1257 std::string reconstructExpression()
const;
1260 void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
1261 void captureResult( ResultWas::OfType resultType );
1262 void captureExpression();
1263 void captureExpectedException( std::string
const& expectedMessage );
1267 bool shouldDebugBreak()
const;
1268 bool allowThrows()
const;
1273 struct ExprComponents {
1274 ExprComponents() : testFalse(
false ) {}
1276 std::string lhs, rhs, op;
1280 bool m_shouldDebugBreak;
1288 #define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED 1291 #define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED 1294 #pragma warning(push) 1295 #pragma warning(disable:4389) // '==' : signed/unsigned mismatch 1301 namespace Internal {
1308 IsLessThanOrEqualTo,
1309 IsGreaterThanOrEqualTo
1312 template<Operator Op>
struct OperatorTraits {
static const char* getName(){
return "*error*"; } };
1313 template<>
struct OperatorTraits<IsEqualTo> {
static const char* getName(){
return "=="; } };
1314 template<>
struct OperatorTraits<IsNotEqualTo> {
static const char* getName(){
return "!="; } };
1315 template<>
struct OperatorTraits<IsLessThan> {
static const char* getName(){
return "<"; } };
1316 template<>
struct OperatorTraits<IsGreaterThan> {
static const char* getName(){
return ">"; } };
1317 template<>
struct OperatorTraits<IsLessThanOrEqualTo> {
static const char* getName(){
return "<="; } };
1318 template<>
struct OperatorTraits<IsGreaterThanOrEqualTo>{
static const char* getName(){
return ">="; } };
1320 template<
typename T>
1321 inline T& opCast(
T const& t) {
return const_cast<T&
>(t); }
1324 #ifdef CATCH_CONFIG_CPP11_NULLPTR 1325 inline std::nullptr_t opCast(std::nullptr_t) {
return nullptr; }
1326 #endif // CATCH_CONFIG_CPP11_NULLPTR 1330 template<
typename T1,
typename T2, Operator Op>
1333 template<
typename T1,
typename T2>
1335 static bool evaluate( T1
const& lhs, T2
const& rhs) {
1336 return bool( opCast( lhs ) == opCast( rhs ) );
1339 template<
typename T1,
typename T2>
1341 static bool evaluate( T1
const& lhs, T2
const& rhs ) {
1342 return bool( opCast( lhs ) != opCast( rhs ) );
1345 template<
typename T1,
typename T2>
1347 static bool evaluate( T1
const& lhs, T2
const& rhs ) {
1348 return bool( opCast( lhs ) < opCast( rhs ) );
1351 template<
typename T1,
typename T2>
1353 static bool evaluate( T1
const& lhs, T2
const& rhs ) {
1354 return bool( opCast( lhs ) > opCast( rhs ) );
1357 template<
typename T1,
typename T2>
1359 static bool evaluate( T1
const& lhs, T2
const& rhs ) {
1360 return bool( opCast( lhs ) >= opCast( rhs ) );
1363 template<
typename T1,
typename T2>
1365 static bool evaluate( T1
const& lhs, T2
const& rhs ) {
1366 return bool( opCast( lhs ) <= opCast( rhs ) );
1370 template<Operator Op,
typename T1,
typename T2>
1371 bool applyEvaluator( T1
const& lhs, T2
const& rhs ) {
1379 template<Operator Op,
typename T1,
typename T2>
1380 bool compare( T1
const& lhs, T2
const& rhs ) {
1385 template<Operator Op>
bool compare(
unsigned int lhs,
int rhs ) {
1386 return applyEvaluator<Op>( lhs,
static_cast<unsigned int>( rhs ) );
1388 template<Operator Op>
bool compare(
unsigned long lhs,
int rhs ) {
1389 return applyEvaluator<Op>( lhs,
static_cast<unsigned int>( rhs ) );
1391 template<Operator Op>
bool compare(
unsigned char lhs,
int rhs ) {
1392 return applyEvaluator<Op>( lhs,
static_cast<unsigned int>( rhs ) );
1396 template<Operator Op>
bool compare(
unsigned int lhs,
long rhs ) {
1397 return applyEvaluator<Op>( lhs,
static_cast<unsigned long>( rhs ) );
1399 template<Operator Op>
bool compare(
unsigned long lhs,
long rhs ) {
1400 return applyEvaluator<Op>( lhs,
static_cast<unsigned long>( rhs ) );
1402 template<Operator Op>
bool compare(
unsigned char lhs,
long rhs ) {
1403 return applyEvaluator<Op>( lhs,
static_cast<unsigned long>( rhs ) );
1407 template<Operator Op>
bool compare(
int lhs,
unsigned int rhs ) {
1408 return applyEvaluator<Op>(
static_cast<unsigned int>( lhs ), rhs );
1410 template<Operator Op>
bool compare(
int lhs,
unsigned long rhs ) {
1411 return applyEvaluator<Op>(
static_cast<unsigned int>( lhs ), rhs );
1413 template<Operator Op>
bool compare(
int lhs,
unsigned char rhs ) {
1414 return applyEvaluator<Op>(
static_cast<unsigned int>( lhs ), rhs );
1418 template<Operator Op>
bool compare(
long lhs,
unsigned int rhs ) {
1419 return applyEvaluator<Op>(
static_cast<unsigned long>( lhs ), rhs );
1421 template<Operator Op>
bool compare(
long lhs,
unsigned long rhs ) {
1422 return applyEvaluator<Op>(
static_cast<unsigned long>( lhs ), rhs );
1424 template<Operator Op>
bool compare(
long lhs,
unsigned char rhs ) {
1425 return applyEvaluator<Op>(
static_cast<unsigned long>( lhs ), rhs );
1429 template<Operator Op,
typename T>
bool compare(
long lhs,
T* rhs ) {
1432 template<Operator Op,
typename T>
bool compare(
T* lhs,
long rhs ) {
1437 template<Operator Op,
typename T>
bool compare(
int lhs,
T* rhs ) {
1440 template<Operator Op,
typename T>
bool compare(
T* lhs,
int rhs ) {
1444 #ifdef CATCH_CONFIG_CPP11_LONG_LONG 1446 template<Operator Op>
bool compare(
long long lhs,
unsigned int rhs ) {
1447 return applyEvaluator<Op>(
static_cast<unsigned long>( lhs ), rhs );
1449 template<Operator Op>
bool compare(
long long lhs,
unsigned long rhs ) {
1450 return applyEvaluator<Op>(
static_cast<unsigned long>( lhs ), rhs );
1452 template<Operator Op>
bool compare(
long long lhs,
unsigned long long rhs ) {
1453 return applyEvaluator<Op>(
static_cast<unsigned long>( lhs ), rhs );
1455 template<Operator Op>
bool compare(
long long lhs,
unsigned char rhs ) {
1456 return applyEvaluator<Op>(
static_cast<unsigned long>( lhs ), rhs );
1460 template<Operator Op>
bool compare(
unsigned long long lhs,
int rhs ) {
1461 return applyEvaluator<Op>(
static_cast<long>( lhs ), rhs );
1463 template<Operator Op>
bool compare(
unsigned long long lhs,
long rhs ) {
1464 return applyEvaluator<Op>(
static_cast<long>( lhs ), rhs );
1466 template<Operator Op>
bool compare(
unsigned long long lhs,
long long rhs ) {
1467 return applyEvaluator<Op>(
static_cast<long>( lhs ), rhs );
1469 template<Operator Op>
bool compare(
unsigned long long lhs,
char rhs ) {
1470 return applyEvaluator<Op>(
static_cast<long>( lhs ), rhs );
1474 template<Operator Op,
typename T>
bool compare(
long long lhs,
T* rhs ) {
1477 template<Operator Op,
typename T>
bool compare(
T* lhs,
long long rhs ) {
1480 #endif // CATCH_CONFIG_CPP11_LONG_LONG 1482 #ifdef CATCH_CONFIG_CPP11_NULLPTR 1484 template<Operator Op,
typename T>
bool compare( std::nullptr_t,
T* rhs ) {
1487 template<Operator Op,
typename T>
bool compare(
T* lhs, std::nullptr_t ) {
1490 #endif // CATCH_CONFIG_CPP11_NULLPTR 1496 #pragma warning(pop) 1500 #define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED 1510 #define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED 1512 #import <Foundation/Foundation.h> 1514 #ifdef __has_feature 1515 #define CATCH_ARC_ENABLED __has_feature(objc_arc) 1517 #define CATCH_ARC_ENABLED 0 1520 void arcSafeRelease( NSObject* obj );
1521 id performOptionalSelector(
id obj,
SEL sel );
1523 #if !CATCH_ARC_ENABLED 1524 inline void arcSafeRelease( NSObject* obj ) {
1527 inline id performOptionalSelector(
id obj,
SEL sel ) {
1528 if( [obj respondsToSelector: sel] )
1529 return [obj performSelector: sel];
1532 #define CATCH_UNSAFE_UNRETAINED 1533 #define CATCH_ARC_STRONG 1535 inline void arcSafeRelease( NSObject* ){}
1536 inline id performOptionalSelector(
id obj,
SEL sel ) {
1538 #pragma clang diagnostic push 1539 #pragma clang diagnostic ignored "-Warc-performSelector-leaks" 1541 if( [obj respondsToSelector: sel] )
1542 return [obj performSelector: sel];
1544 #pragma clang diagnostic pop 1548 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained 1549 #define CATCH_ARC_STRONG __strong 1554 #ifdef CATCH_CONFIG_CPP11_TUPLE 1558 #ifdef CATCH_CONFIG_CPP11_IS_ENUM 1559 #include <type_traits> 1565 template<
typename T>
1566 std::string toString(
T const& value );
1570 std::string toString( std::string
const& value );
1571 std::string toString( std::wstring
const& value );
1572 std::string toString(
const char*
const value );
1573 std::string toString(
char*
const value );
1574 std::string toString(
const wchar_t*
const value );
1575 std::string toString(
wchar_t*
const value );
1576 std::string toString(
int value );
1577 std::string toString(
unsigned long value );
1578 std::string toString(
unsigned int value );
1579 std::string toString(
const double value );
1580 std::string toString(
const float value );
1581 std::string toString(
bool value );
1582 std::string toString(
char value );
1583 std::string toString(
signed char value );
1584 std::string toString(
unsigned char value );
1586 #ifdef CATCH_CONFIG_CPP11_LONG_LONG 1587 std::string toString(
long long value );
1588 std::string toString(
unsigned long long value );
1591 #ifdef CATCH_CONFIG_CPP11_NULLPTR 1592 std::string toString( std::nullptr_t );
1596 std::string toString( NSString
const *
const& nsstring );
1597 std::string toString( NSString * CATCH_ARC_STRONG
const& nsstring );
1598 std::string toString( NSObject*
const& nsObject );
1603 extern const std::string unprintableString;
1606 template<
typename T>
BorgType(
T const& );
1612 TrueType& testStreamable( std::ostream& );
1617 template<
typename T>
1619 static std::ostream &s;
1621 enum { value =
sizeof( testStreamable(s << t) ) ==
sizeof(
TrueType ) };
1624 #if defined(CATCH_CONFIG_CPP11_IS_ENUM) 1625 template<
typename T,
1626 bool IsEnum = std::is_enum<T>::value
1628 struct EnumStringMaker
1630 static std::string convert(
T const& ) {
return unprintableString; }
1633 template<
typename T>
1634 struct EnumStringMaker<T,true>
1636 static std::string convert( T
const& v )
1638 return ::Catch::toString(
1639 static_cast<typename std::underlying_type<T>::type
>(v)
1646 #if defined(CATCH_CONFIG_CPP11_IS_ENUM) 1647 template<
typename T>
1648 static std::string convert( T
const& v )
1650 return EnumStringMaker<T>::convert( v );
1653 template<
typename T>
1654 static std::string convert( T
const& ) {
return unprintableString; }
1660 template<
typename T>
1661 static std::string convert( T
const& _value ) {
1662 std::ostringstream oss;
1668 std::string rawMemoryToString(
const void *
object, std::size_t
size );
1670 template<
typename T>
1671 inline std::string rawMemoryToString(
const T&
object ) {
1672 return rawMemoryToString( &
object,
sizeof(
object) );
1677 template<
typename T>
1681 template<
typename T>
1683 template<
typename U>
1684 static std::string convert( U* p ) {
1688 return Detail::rawMemoryToString( p );
1692 template<
typename R,
typename C>
1694 static std::string convert( R C::* p ) {
1698 return Detail::rawMemoryToString( p );
1703 template<
typename InputIterator>
1704 std::string rangeToString( InputIterator first, InputIterator last );
1714 template<
typename T,
typename Allocator>
1715 std::string toString( std::vector<T,Allocator>
const& v ) {
1716 return Detail::rangeToString( v.begin(), v.end() );
1719 #ifdef CATCH_CONFIG_CPP11_TUPLE 1722 namespace TupleDetail {
1726 bool = (N < std::tuple_size<Tuple>::value)
1728 struct ElementPrinter {
1729 static void print(
const Tuple& tuple, std::ostream& os )
1731 os << ( N ?
", " :
" " )
1732 << Catch::toString(std::get<N>(tuple));
1733 ElementPrinter<Tuple,N+1>::print(tuple,os);
1741 struct ElementPrinter<Tuple,N,false> {
1742 static void print(
const Tuple&, std::ostream& ) {}
1747 template<
typename ...Types>
1750 static std::string convert(
const std::tuple<Types...>& tuple )
1752 std::ostringstream os;
1754 TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );
1759 #endif // CATCH_CONFIG_CPP11_TUPLE 1762 template<
typename T>
1775 template<
typename T>
1776 std::string toString(
T const& value ) {
1781 template<
typename InputIterator>
1782 std::string rangeToString( InputIterator first, InputIterator last ) {
1783 std::ostringstream oss;
1785 if( first != last ) {
1786 oss << Catch::toString( *first );
1787 for( ++first ; first != last ; ++first )
1788 oss <<
", " << Catch::toString( *first );
1801 template<
typename T>
1804 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS 1810 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS 1815 template<
typename RhsT>
1817 return captureExpression<Internal::IsEqualTo>( rhs );
1820 template<
typename RhsT>
1822 return captureExpression<Internal::IsNotEqualTo>( rhs );
1825 template<
typename RhsT>
1827 return captureExpression<Internal::IsLessThan>( rhs );
1830 template<
typename RhsT>
1832 return captureExpression<Internal::IsGreaterThan>( rhs );
1835 template<
typename RhsT>
1837 return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
1840 template<
typename RhsT>
1842 return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
1846 return captureExpression<Internal::IsEqualTo>( rhs );
1850 return captureExpression<Internal::IsNotEqualTo>( rhs );
1853 void endExpression() {
1854 bool value = m_lhs ?
true :
false;
1856 .setLhs( Catch::toString( value ) )
1857 .setResultType( value )
1863 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison&
operator + ( RhsT
const& );
1864 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison&
operator - ( RhsT
const& );
1865 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT
const& );
1866 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT
const& );
1867 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT
const& );
1868 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT
const& );
1871 template<Internal::Operator Op,
typename RhsT>
1874 .setResultType( Internal::compare<Op>( m_lhs, rhs ) )
1875 .setLhs( Catch::toString( m_lhs ) )
1876 .setRhs( Catch::toString( rhs ) )
1890 template<
typename T>
1902 #define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED 1911 ResultWas::OfType _type );
1913 std::string macroName;
1915 ResultWas::OfType type;
1916 std::string message;
1917 unsigned int sequence;
1919 bool operator == (
MessageInfo const& other )
const {
1920 return sequence == other.sequence;
1922 bool operator < (
MessageInfo const& other )
const {
1923 return sequence < other.sequence;
1926 static unsigned int globalCount;
1932 ResultWas::OfType type )
1933 : m_info( macroName, lineInfo, type )
1936 template<
typename T>
1943 std::ostringstream m_stream;
1958 #define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED 1970 class ScopedMessageBuilder;
1978 virtual bool sectionStarted(
SectionInfo const& sectionInfo,
1979 Counts& assertions ) = 0;
1981 virtual void sectionEndedEarly(
SectionEndInfo const& endInfo ) = 0;
1982 virtual void pushScopedMessage(
MessageInfo const& message ) = 0;
1983 virtual void popScopedMessage(
MessageInfo const& message ) = 0;
1985 virtual std::string getCurrentTestName()
const = 0;
1988 virtual void handleFatalErrorCondition( std::string
const& message ) = 0;
1995 #define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED 1998 #define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED 2000 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) 2001 #define CATCH_PLATFORM_MAC 2002 #elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) 2003 #define CATCH_PLATFORM_IPHONE 2004 #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) 2005 #define CATCH_PLATFORM_WINDOWS 2012 bool isDebuggerActive();
2013 void writeToDebugConsole( std::string
const& text );
2016 #ifdef CATCH_PLATFORM_MAC 2021 #if defined(__ppc64__) || defined(__ppc__) 2022 #define CATCH_BREAK_INTO_DEBUGGER() \ 2023 if( Catch::isDebuggerActive() ) { \ 2024 __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \ 2025 : : : "memory","r0","r3","r4" ); \ 2028 #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );} 2032 #elif defined(_MSC_VER) 2033 #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); } 2034 #elif defined(__MINGW32__) 2035 extern "C" __declspec(dllimport)
void __stdcall DebugBreak();
2036 #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); } 2039 #ifndef CATCH_BREAK_INTO_DEBUGGER 2040 #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue(); 2044 #define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED 2051 virtual bool aborting()
const = 0;
2060 #define INTERNAL_CATCH_REACT( resultBuilder ) \ 2061 if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \ 2062 resultBuilder.react(); 2065 #define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \ 2067 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ 2069 CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ 2070 ( __catchResult <= expr ).endExpression(); \ 2073 __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \ 2075 INTERNAL_CATCH_REACT( __catchResult ) \ 2076 } while( Catch::isTrue( false && !!(expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look 2079 #define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \ 2080 INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \ 2081 if( Catch::getResultCapture().getLastResult()->succeeded() ) 2084 #define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \ 2085 INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \ 2086 if( !Catch::getResultCapture().getLastResult()->succeeded() ) 2089 #define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \ 2091 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ 2094 __catchResult.captureResult( Catch::ResultWas::Ok ); \ 2097 __catchResult.useActiveException( resultDisposition ); \ 2099 INTERNAL_CATCH_REACT( __catchResult ) \ 2100 } while( Catch::alwaysFalse() ) 2103 #define INTERNAL_CATCH_THROWS( expr, resultDisposition, matcher, macroName ) \ 2105 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \ 2106 if( __catchResult.allowThrows() ) \ 2109 __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ 2112 __catchResult.captureExpectedException( matcher ); \ 2115 __catchResult.captureResult( Catch::ResultWas::Ok ); \ 2116 INTERNAL_CATCH_REACT( __catchResult ) \ 2117 } while( Catch::alwaysFalse() ) 2120 #define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \ 2122 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ 2123 if( __catchResult.allowThrows() ) \ 2126 __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ 2128 catch( exceptionType ) { \ 2129 __catchResult.captureResult( Catch::ResultWas::Ok ); \ 2132 __catchResult.useActiveException( resultDisposition ); \ 2135 __catchResult.captureResult( Catch::ResultWas::Ok ); \ 2136 INTERNAL_CATCH_REACT( __catchResult ) \ 2137 } while( Catch::alwaysFalse() ) 2140 #ifdef CATCH_CONFIG_VARIADIC_MACROS 2141 #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \ 2143 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ 2144 __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \ 2145 __catchResult.captureResult( messageType ); \ 2146 INTERNAL_CATCH_REACT( __catchResult ) \ 2147 } while( Catch::alwaysFalse() ) 2149 #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \ 2151 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ 2152 __catchResult << log + ::Catch::StreamEndStop(); \ 2153 __catchResult.captureResult( messageType ); \ 2154 INTERNAL_CATCH_REACT( __catchResult ) \ 2155 } while( Catch::alwaysFalse() ) 2159 #define INTERNAL_CATCH_INFO( log, macroName ) \ 2160 Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log; 2163 #define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \ 2165 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \ 2167 std::string matcherAsString = (matcher).toString(); \ 2169 .setLhs( Catch::toString( arg ) ) \ 2170 .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \ 2171 .setOp( "matches" ) \ 2172 .setResultType( (matcher).match( arg ) ); \ 2173 __catchResult.captureExpression(); \ 2175 __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \ 2177 INTERNAL_CATCH_REACT( __catchResult ) \ 2178 } while( Catch::alwaysFalse() ) 2181 #define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED 2184 #define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED 2187 #define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED 2194 Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}
2198 diff.passed = passed - other.passed;
2199 diff.failed = failed - other.failed;
2200 diff.failedButOk = failedButOk - other.failedButOk;
2204 passed += other.passed;
2205 failed += other.failed;
2206 failedButOk += other.failedButOk;
2210 std::size_t total()
const {
2211 return passed + failed + failedButOk;
2213 bool allPassed()
const {
2214 return failed == 0 && failedButOk == 0;
2216 bool allOk()
const {
2222 std::size_t failedButOk;
2229 diff.assertions = assertions - other.assertions;
2230 diff.testCases = testCases - other.testCases;
2235 Totals diff = *
this - prevTotals;
2236 if( diff.assertions.failed > 0 )
2237 ++diff.testCases.failed;
2238 else if( diff.assertions.failedButOk > 0 )
2239 ++diff.testCases.failedButOk;
2241 ++diff.testCases.passed;
2246 assertions += other.assertions;
2247 testCases += other.testCases;
2261 std::string
const& _name,
2262 std::string
const& _description = std::string() );
2265 std::string description;
2271 : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
2276 double durationInSeconds;
2282 #define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED 2284 #ifdef CATCH_PLATFORM_WINDOWS 2285 typedef unsigned long long uint64_t;
2294 Timer() : m_ticks( 0 ) {}
2296 unsigned int getElapsedMicroseconds()
const;
2297 unsigned int getElapsedMilliseconds()
const;
2298 double getElapsedSeconds()
const;
2316 operator bool()
const;
2323 bool m_sectionIncluded;
2329 #ifdef CATCH_CONFIG_VARIADIC_MACROS 2330 #define INTERNAL_CATCH_SECTION( ... ) \ 2331 if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) 2333 #define INTERNAL_CATCH_SECTION( name, desc ) \ 2334 if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) ) 2338 #define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED 2347 template<
typename T>
2350 virtual T getValue( std::size_t index )
const = 0;
2351 virtual std::size_t
size ()
const = 0;
2354 template<
typename T>
2359 virtual T getValue( std::size_t index )
const {
2360 return m_from+
static_cast<int>( index );
2363 virtual std::size_t
size()
const {
2364 return static_cast<std::size_t
>( 1+m_to-m_from );
2373 template<
typename T>
2378 void add(
T value ) {
2379 m_values.push_back( value );
2382 virtual T getValue( std::size_t index )
const {
2383 return m_values[index];
2386 virtual std::size_t
size()
const {
2387 return m_values.size();
2391 std::vector<T> m_values;
2394 template<
typename T>
2401 : m_fileInfo( other.m_fileInfo ),
2408 m_fileInfo = fileInfo;
2413 deleteAll( m_composed );
2416 operator T ()
const {
2417 size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
2419 typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
2420 typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
2421 for(
size_t index = 0; it != itEnd; ++it )
2424 if( overallIndex >= index && overallIndex < index + generator->
size() )
2426 return generator->getValue( overallIndex-index );
2428 index += generator->size();
2430 CATCH_INTERNAL_ERROR(
"Indexed past end of generated range" );
2435 m_totalSize += generator->size();
2436 m_composed.push_back( generator );
2446 valuesGen->add( value );
2454 std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
2455 m_totalSize += other.m_totalSize;
2456 other.m_composed.clear();
2459 std::vector<const IGenerator<T>*> m_composed;
2460 std::string m_fileInfo;
2464 namespace Generators
2466 template<
typename T>
2473 template<
typename T>
2477 valuesGen->add( val1 );
2478 valuesGen->add( val2 );
2479 generators.add( valuesGen );
2483 template<
typename T>
2487 valuesGen->add( val1 );
2488 valuesGen->add( val2 );
2489 valuesGen->add( val3 );
2490 generators.add( valuesGen );
2494 template<
typename T>
2498 valuesGen->add( val1 );
2499 valuesGen->add( val2 );
2500 valuesGen->add( val3 );
2501 valuesGen->add( val4 );
2502 generators.add( valuesGen );
2508 using namespace Generators;
2512 #define INTERNAL_CATCH_LINESTR2( line ) #line 2513 #define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line ) 2515 #define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" ) 2518 #define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED 2524 #define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED 2534 struct IReporterRegistry;
2535 struct IReporterFactory;
2540 virtual IReporterRegistry
const& getReporterRegistry()
const = 0;
2549 virtual void registerTest(
TestCase const& testInfo ) = 0;
2556 std::string translateActiveException();
2562 typedef std::string(*exceptionTranslateFunction)();
2565 typedef std::vector<const IExceptionTranslator*> ExceptionTranslators;
2569 virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd )
const = 0;
2575 virtual std::string translateActiveException()
const = 0;
2579 template<
typename T>
2583 ExceptionTranslator( std::string(*translateFunction)(
T& ) )
2584 : m_translateFunction( translateFunction )
2587 virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd )
const CATCH_OVERRIDE {
2592 return (*it)->translate( it+1, itEnd );
2595 return m_translateFunction( ex );
2600 std::string(*m_translateFunction)(
T& );
2604 template<
typename T>
2606 getMutableRegistryHub().registerTranslator
2607 (
new ExceptionTranslator<T>( translateFunction ) );
2613 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \ 2614 static std::string translatorName( signature ); \ 2615 namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\ 2616 static std::string translatorName( signature ) 2618 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) 2621 #define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED 2631 explicit Approx (
double value )
2632 : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
2638 : m_epsilon( other.m_epsilon ),
2639 m_scale( other.m_scale ),
2640 m_value( other.m_value )
2647 Approx operator()(
double value ) {
2649 approx.epsilon( m_epsilon );
2650 approx.scale( m_scale );
2654 friend bool operator == (
double lhs,
Approx const& rhs ) {
2656 return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
2659 friend bool operator == (
Approx const& lhs,
double rhs ) {
2660 return operator==( rhs, lhs );
2663 friend bool operator != (
double lhs,
Approx const& rhs ) {
2664 return !operator==( lhs, rhs );
2667 friend bool operator != (
Approx const& lhs,
double rhs ) {
2668 return !operator==( rhs, lhs );
2671 Approx& epsilon(
double newEpsilon ) {
2672 m_epsilon = newEpsilon;
2676 Approx& scale(
double newScale ) {
2681 std::string toString()
const {
2682 std::ostringstream oss;
2683 oss <<
"Approx( " << Catch::toString( m_value ) <<
" )";
2695 inline std::string toString<Detail::Approx>(
Detail::Approx const& value ) {
2696 return value.toString();
2702 #define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED 2705 #define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED 2724 #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } 2726 #define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED 2731 template<
typename T>
2734 Option() : nullableValue( CATCH_NULL ) {}
2736 : nullableValue(
new( storage )
T( _value ) )
2739 : nullableValue( _other ?
new( storage )
T( *_other ) : CATCH_NULL )
2747 if( &_other !=
this ) {
2750 nullableValue =
new( storage )
T( *_other );
2754 Option& operator = (
T const& _value ) {
2756 nullableValue =
new( storage )
T( _value );
2762 nullableValue->~T();
2763 nullableValue = CATCH_NULL;
2766 T& operator*() {
return *nullableValue; }
2767 T const& operator*()
const {
return *nullableValue; }
2768 T* operator->() {
return nullableValue; }
2769 const T* operator->()
const {
return nullableValue; }
2771 T valueOr(
T const& defaultValue )
const {
2772 return nullableValue ? *nullableValue : defaultValue;
2775 bool some()
const {
return nullableValue != CATCH_NULL; }
2776 bool none()
const {
return nullableValue == CATCH_NULL; }
2778 bool operator !()
const {
return nullableValue == CATCH_NULL; }
2779 operator SafeBool::type()
const {
2780 return SafeBool::makeSafe( some() );
2785 char storage[
sizeof(
T)];
2795 virtual std::string expandAliases( std::string
const& unexpandedTestSpec )
const = 0;
2805 #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED 2811 #pragma clang diagnostic push 2812 #pragma clang diagnostic ignored "-Wpadded" 2820 enum SpecialProperties{
2823 ShouldFail = 1 << 2,
2829 std::string
const& _className,
2830 std::string
const& _description,
2831 std::set<std::string>
const& _tags,
2836 friend void setTags(
TestCaseInfo& testCaseInfo, std::set<std::string>
const& tags );
2838 bool isHidden()
const;
2839 bool throws()
const;
2840 bool okToFail()
const;
2841 bool expectedToFail()
const;
2844 std::string className;
2845 std::string description;
2846 std::set<std::string> tags;
2847 std::set<std::string> lcaseTags;
2848 std::string tagsAsString;
2850 SpecialProperties properties;
2859 TestCase withName( std::string
const& _newName )
const;
2861 void invoke()
const;
2866 bool operator == (
TestCase const& other )
const;
2867 bool operator < (
TestCase const& other )
const;
2875 std::string
const& className,
2876 std::string
const& name,
2877 std::string
const& description,
2882 #pragma clang diagnostic pop 2888 #define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED 2890 #import <objc/runtime.h> 2912 class OcMethod :
public SharedImpl<ITestCase> {
2915 OcMethod( Class cls,
SEL sel ) : m_cls( cls ), m_sel( sel ) {}
2917 virtual void invoke()
const {
2918 id obj = [[m_cls alloc] init];
2920 performOptionalSelector( obj,
@selector(setUp) );
2921 performOptionalSelector( obj, m_sel );
2922 performOptionalSelector( obj,
@selector(tearDown) );
2924 arcSafeRelease( obj );
2927 virtual ~OcMethod() {}
2935 inline std::string getAnnotation( Class cls,
2936 std::string
const& annotationName,
2937 std::string
const& testCaseName ) {
2938 NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
2939 SEL sel = NSSelectorFromString( selStr );
2940 arcSafeRelease( selStr );
2941 id value = performOptionalSelector( cls, sel );
2943 return [(NSString*)value UTF8String];
2948 inline size_t registerTestMethods() {
2949 size_t noTestMethods = 0;
2950 int noClasses = objc_getClassList( CATCH_NULL, 0 );
2952 Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc(
sizeof(Class) * noClasses);
2953 objc_getClassList( classes, noClasses );
2955 for(
int c = 0; c < noClasses; c++ ) {
2956 Class cls = classes[c];
2959 Method* methods = class_copyMethodList( cls, &count );
2960 for( u_int m = 0; m < count ; m++ ) {
2961 SEL selector = method_getName(methods[m]);
2962 std::string methodName = sel_getName(selector);
2963 if( startsWith( methodName,
"Catch_TestCase_" ) ) {
2964 std::string testCaseName = methodName.substr( 15 );
2965 std::string name = Detail::getAnnotation( cls,
"Name", testCaseName );
2966 std::string desc = Detail::getAnnotation( cls,
"Description", testCaseName );
2967 const char* className = class_getName( cls );
2969 getMutableRegistryHub().registerTest( makeTestCase(
new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(),
SourceLineInfo() ) );
2976 return noTestMethods;
2979 namespace Matchers {
2981 namespace NSStringMatchers {
2983 template<
typename MatcherT>
2984 struct StringHolder : MatcherImpl<MatcherT, NSString*>{
2985 StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
2986 StringHolder( StringHolder
const& other ) : m_substr( [other.m_substr copy] ){}
2988 arcSafeRelease( m_substr );
2994 struct Equals : StringHolder<Equals> {
2995 Equals( NSString* substr ) : StringHolder( substr ){}
2997 virtual bool match( ExpressionType
const& str )
const {
2998 return (str != nil || m_substr == nil ) &&
2999 [str isEqualToString:m_substr];
3002 virtual std::string toString()
const {
3003 return "equals string: " + Catch::toString( m_substr );
3007 struct Contains : StringHolder<Contains> {
3008 Contains( NSString* substr ) : StringHolder( substr ){}
3010 virtual bool match( ExpressionType
const& str )
const {
3011 return (str != nil || m_substr == nil ) &&
3012 [str rangeOfString:m_substr].location != NSNotFound;
3015 virtual std::string toString()
const {
3016 return "contains string: " + Catch::toString( m_substr );
3020 struct StartsWith : StringHolder<StartsWith> {
3021 StartsWith( NSString* substr ) : StringHolder( substr ){}
3023 virtual bool match( ExpressionType
const& str )
const {
3024 return (str != nil || m_substr == nil ) &&
3025 [str rangeOfString:m_substr].location == 0;
3028 virtual std::string toString()
const {
3029 return "starts with: " + Catch::toString( m_substr );
3032 struct EndsWith : StringHolder<EndsWith> {
3033 EndsWith( NSString* substr ) : StringHolder( substr ){}
3035 virtual bool match( ExpressionType
const& str )
const {
3036 return (str != nil || m_substr == nil ) &&
3037 [str rangeOfString:m_substr].location == [str length] - [m_substr length];
3040 virtual std::string toString()
const {
3041 return "ends with: " + Catch::toString( m_substr );
3048 inline Impl::NSStringMatchers::Equals
3049 Equals( NSString* substr ){
return Impl::NSStringMatchers::Equals( substr ); }
3051 inline Impl::NSStringMatchers::Contains
3052 Contains( NSString* substr ){
return Impl::NSStringMatchers::Contains( substr ); }
3054 inline Impl::NSStringMatchers::StartsWith
3055 StartsWith( NSString* substr ){
return Impl::NSStringMatchers::StartsWith( substr ); }
3057 inline Impl::NSStringMatchers::EndsWith
3058 EndsWith( NSString* substr ){
return Impl::NSStringMatchers::EndsWith( substr ); }
3062 using namespace Matchers;
3067 #define OC_TEST_CASE( name, desc )\ 3068 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \ 3072 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \ 3076 -(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test ) 3082 #define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED 3088 #pragma clang diagnostic push 3089 #pragma clang diagnostic ignored "-Wweak-vtables" 3093 #define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED 3096 #define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED 3099 #define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED 3102 #define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED 3105 #pragma clang diagnostic push 3106 #pragma clang diagnostic ignored "-Wpadded" 3110 #define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED 3113 #pragma clang diagnostic push 3114 #pragma clang diagnostic ignored "-Wpadded" 3118 #define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED 3122 class WildcardPattern {
3123 enum WildcardPosition {
3125 WildcardAtStart = 1,
3127 WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
3132 WildcardPattern( std::string
const& pattern, CaseSensitive::Choice caseSensitivity )
3133 : m_caseSensitivity( caseSensitivity ),
3134 m_wildcard( NoWildcard ),
3135 m_pattern( adjustCase( pattern ) )
3137 if( startsWith( m_pattern,
"*" ) ) {
3138 m_pattern = m_pattern.substr( 1 );
3139 m_wildcard = WildcardAtStart;
3141 if( endsWith( m_pattern,
"*" ) ) {
3142 m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
3143 m_wildcard =
static_cast<WildcardPosition
>( m_wildcard | WildcardAtEnd );
3146 virtual ~WildcardPattern();
3147 virtual bool matches( std::string
const& str )
const {
3148 switch( m_wildcard ) {
3150 return m_pattern == adjustCase( str );
3151 case WildcardAtStart:
3152 return endsWith( adjustCase( str ), m_pattern );
3154 return startsWith( adjustCase( str ), m_pattern );
3155 case WildcardAtBothEnds:
3156 return contains( adjustCase( str ), m_pattern );
3160 #pragma clang diagnostic push 3161 #pragma clang diagnostic ignored "-Wunreachable-code" 3163 throw std::logic_error(
"Unknown enum" );
3165 #pragma clang diagnostic pop 3169 std::string adjustCase( std::string
const& str )
const {
3170 return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
3172 CaseSensitive::Choice m_caseSensitivity;
3173 WildcardPosition m_wildcard;
3174 std::string m_pattern;
3186 virtual bool matches(
TestCaseInfo const& testCase )
const = 0;
3188 class NamePattern :
public Pattern {
3190 NamePattern( std::string
const& name )
3191 : m_wildcardPattern( toLower( name ), CaseSensitive::No )
3193 virtual ~NamePattern();
3194 virtual bool matches(
TestCaseInfo const& testCase )
const {
3195 return m_wildcardPattern.matches( toLower( testCase.name ) );
3198 WildcardPattern m_wildcardPattern;
3201 class TagPattern :
public Pattern {
3203 TagPattern( std::string
const& tag ) : m_tag( toLower( tag ) ) {}
3204 virtual ~TagPattern();
3205 virtual bool matches(
TestCaseInfo const& testCase )
const {
3206 return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();
3212 class ExcludedPattern :
public Pattern {
3214 ExcludedPattern(
Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
3215 virtual ~ExcludedPattern();
3216 virtual bool matches(
TestCaseInfo const& testCase )
const {
return !m_underlyingPattern->matches( testCase ); }
3222 std::vector<Ptr<Pattern> > m_patterns;
3226 for( std::vector<
Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) {
3227 if( !(*it)->matches( testCase ) )
3235 bool hasFilters()
const {
3236 return !m_filters.empty();
3240 for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )
3241 if( it->matches( testCase ) )
3247 std::vector<Filter> m_filters;
3249 friend class TestSpecParser;
3254 #pragma clang diagnostic pop 3259 class TestSpecParser {
3260 enum Mode{ None, Name, QuotedName, Tag };
3263 std::size_t m_start, m_pos;
3265 TestSpec::Filter m_currentFilter;
3266 TestSpec m_testSpec;
3270 TestSpecParser(
ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
3272 TestSpecParser& parse( std::string
const& arg ) {
3274 m_exclusion =
false;
3275 m_start = std::string::npos;
3276 m_arg = m_tagAliases->expandAliases( arg );
3277 for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
3278 visitChar( m_arg[m_pos] );
3279 if( m_mode == Name )
3280 addPattern<TestSpec::NamePattern>();
3283 TestSpec testSpec() {
3288 void visitChar(
char c ) {
3289 if( m_mode == None ) {
3292 case '~': m_exclusion =
true;
return;
3293 case '[':
return startNewMode( Tag, ++m_pos );
3294 case '"':
return startNewMode( QuotedName, ++m_pos );
3295 default: startNewMode( Name, m_pos );
break;
3298 if( m_mode == Name ) {
3300 addPattern<TestSpec::NamePattern>();
3303 else if( c ==
'[' ) {
3304 if( subString() ==
"exclude:" )
3307 addPattern<TestSpec::NamePattern>();
3308 startNewMode( Tag, ++m_pos );
3311 else if( m_mode == QuotedName && c ==
'"' )
3312 addPattern<TestSpec::NamePattern>();
3313 else if( m_mode == Tag && c ==
']' )
3314 addPattern<TestSpec::TagPattern>();
3316 void startNewMode( Mode mode, std::size_t start ) {
3320 std::string subString()
const {
return m_arg.substr( m_start, m_pos - m_start ); }
3321 template<
typename T>
3323 std::string token = subString();
3324 if( startsWith( token,
"exclude:" ) ) {
3326 token = token.substr( 8 );
3328 if( !token.empty() ) {
3331 pattern =
new TestSpec::ExcludedPattern( pattern );
3332 m_currentFilter.m_patterns.push_back( pattern );
3334 m_exclusion =
false;
3338 if( !m_currentFilter.m_patterns.empty() ) {
3339 m_testSpec.m_filters.push_back( m_currentFilter );
3340 m_currentFilter = TestSpec::Filter();
3344 inline TestSpec parseTestSpec( std::string
const& arg ) {
3345 return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
3351 #pragma clang diagnostic pop 3355 #define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED 3363 struct Verbosity {
enum Level {
3369 struct WarnAbout {
enum What {
3374 struct ShowDurations {
enum OrNot {
3379 struct RunTests {
enum InWhatOrder {
3381 InLexicographicalOrder,
3384 struct UseColour {
enum YesOrNo {
3396 virtual bool allowThrows()
const = 0;
3397 virtual std::ostream& stream()
const = 0;
3398 virtual std::string name()
const = 0;
3399 virtual bool includeSuccessfulResults()
const = 0;
3400 virtual bool shouldDebugBreak()
const = 0;
3401 virtual bool warnAboutMissingAssertions()
const = 0;
3402 virtual int abortAfter()
const = 0;
3403 virtual bool showInvisibles()
const = 0;
3404 virtual ShowDurations::OrNot showDurations()
const = 0;
3405 virtual TestSpec
const& testSpec()
const = 0;
3406 virtual RunTests::InWhatOrder runOrder()
const = 0;
3407 virtual unsigned int rngSeed()
const = 0;
3408 virtual UseColour::YesOrNo useColour()
const = 0;
3413 #define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED 3416 #define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED 3418 #include <streambuf> 3422 class StreamBufBase :
public std::streambuf {
3424 virtual ~StreamBufBase() CATCH_NOEXCEPT;
3428 #include <streambuf> 3434 std::ostream& cout();
3435 std::ostream& cerr();
3438 virtual ~IStream() CATCH_NOEXCEPT;
3439 virtual std::ostream& stream()
const = 0;
3442 class FileStream :
public IStream {
3443 mutable std::ofstream m_ofs;
3445 FileStream( std::string
const& filename );
3446 virtual ~FileStream() CATCH_NOEXCEPT;
3448 virtual std::ostream& stream()
const CATCH_OVERRIDE;
3451 class CoutStream :
public IStream {
3452 mutable std::ostream m_os;
3455 virtual ~CoutStream() CATCH_NOEXCEPT;
3458 virtual std::ostream& stream()
const CATCH_OVERRIDE;
3461 class DebugOutStream :
public IStream {
3462 CATCH_AUTO_PTR( StreamBufBase ) m_streamBuf;
3463 mutable std::ostream m_os;
3466 virtual ~DebugOutStream() CATCH_NOEXCEPT;
3469 virtual std::ostream& stream()
const CATCH_OVERRIDE;
3479 #ifndef CATCH_CONFIG_CONSOLE_WIDTH 3480 #define CATCH_CONFIG_CONSOLE_WIDTH 80 3488 : listTests(
false ),
3490 listReporters(
false ),
3491 listTestNamesOnly(
false ),
3492 showSuccessfulTests(
false ),
3493 shouldDebugBreak(
false ),
3496 showInvisibles(
false ),
3497 filenamesAsTags(
false ),
3500 verbosity( Verbosity::Normal ),
3501 warnings( WarnAbout::Nothing ),
3502 showDurations( ShowDurations::DefaultForReporter ),
3503 runOrder( RunTests::InDeclarationOrder ),
3504 useColour( UseColour::Auto )
3510 bool listTestNamesOnly;
3512 bool showSuccessfulTests;
3513 bool shouldDebugBreak;
3516 bool showInvisibles;
3517 bool filenamesAsTags;
3520 unsigned int rngSeed;
3522 Verbosity::Level verbosity;
3523 WarnAbout::What warnings;
3524 ShowDurations::OrNot showDurations;
3525 RunTests::InWhatOrder runOrder;
3526 UseColour::YesOrNo useColour;
3528 std::string outputFilename;
3530 std::string processName;
3532 std::vector<std::string> reporterNames;
3533 std::vector<std::string> testsOrTags;
3540 virtual void dummy();
3546 Config( ConfigData
const& data )
3548 m_stream( openStream() )
3550 if( !data.testsOrTags.empty() ) {
3551 TestSpecParser parser( ITagAliasRegistry::get() );
3552 for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
3553 parser.parse( data.testsOrTags[i] );
3554 m_testSpec = parser.testSpec();
3561 std::string
const& getFilename()
const {
3562 return m_data.outputFilename ;
3565 bool listTests()
const {
return m_data.listTests; }
3566 bool listTestNamesOnly()
const {
return m_data.listTestNamesOnly; }
3567 bool listTags()
const {
return m_data.listTags; }
3568 bool listReporters()
const {
return m_data.listReporters; }
3570 std::string getProcessName()
const {
return m_data.processName; }
3572 bool shouldDebugBreak()
const {
return m_data.shouldDebugBreak; }
3574 std::vector<std::string> getReporterNames()
const {
return m_data.reporterNames; }
3576 int abortAfter()
const {
return m_data.abortAfter; }
3578 TestSpec
const& testSpec()
const {
return m_testSpec; }
3580 bool showHelp()
const {
return m_data.showHelp; }
3581 bool showInvisibles()
const {
return m_data.showInvisibles; }
3584 virtual bool allowThrows()
const {
return !m_data.noThrow; }
3585 virtual std::ostream& stream()
const {
return m_stream->stream(); }
3586 virtual std::string name()
const {
return m_data.name.empty() ? m_data.processName : m_data.name; }
3587 virtual bool includeSuccessfulResults()
const {
return m_data.showSuccessfulTests; }
3588 virtual bool warnAboutMissingAssertions()
const {
return m_data.warnings & WarnAbout::NoAssertions; }
3589 virtual ShowDurations::OrNot showDurations()
const {
return m_data.showDurations; }
3590 virtual RunTests::InWhatOrder runOrder()
const {
return m_data.runOrder; }
3591 virtual unsigned int rngSeed()
const {
return m_data.rngSeed; }
3592 virtual UseColour::YesOrNo useColour()
const {
return m_data.useColour; }
3596 IStream
const* openStream() {
3597 if( m_data.outputFilename.empty() )
3598 return new CoutStream();
3599 else if( m_data.outputFilename[0] ==
'%' ) {
3600 if( m_data.outputFilename ==
"%debug" )
3601 return new DebugOutStream();
3603 throw std::domain_error(
"Unrecognised stream: " + m_data.outputFilename );
3606 return new FileStream( m_data.outputFilename );
3610 CATCH_AUTO_PTR( IStream
const ) m_stream;
3611 TestSpec m_testSpec;
3617 #define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED 3620 #ifdef CLARA_CONFIG_CONSOLE_WIDTH 3621 #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH 3622 #undef CLARA_CONFIG_CONSOLE_WIDTH 3624 #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH 3627 #define STITCH_CLARA_OPEN_NAMESPACE namespace Catch { 3633 #if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE) 3635 #ifndef STITCH_CLARA_OPEN_NAMESPACE 3636 #define TWOBLUECUBES_CLARA_H_INCLUDED 3637 #define STITCH_CLARA_OPEN_NAMESPACE 3638 #define STITCH_CLARA_CLOSE_NAMESPACE 3640 #define STITCH_CLARA_CLOSE_NAMESPACE } 3643 #define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE 3648 #if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE) 3649 #ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE 3650 #define TBC_TEXT_FORMAT_H_INCLUDED 3656 #include <algorithm> 3659 #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE 3660 namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
3665 #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH 3666 const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
3668 const unsigned int consoleWidth = 80;
3671 struct TextAttributes {
3673 : initialIndent( std::string::npos ),
3675 width( consoleWidth-1 ),
3679 TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value;
return *
this; }
3680 TextAttributes& setIndent( std::size_t _value ) { indent = _value;
return *
this; }
3681 TextAttributes& setWidth( std::size_t _value ) { width = _value;
return *
this; }
3682 TextAttributes& setTabChar(
char _value ) { tabChar = _value;
return *
this; }
3684 std::size_t initialIndent;
3692 Text( std::string
const& _str, TextAttributes
const& _attr = TextAttributes() )
3695 std::string wrappableChars =
" [({.,/|\\-";
3696 std::size_t indent = _attr.initialIndent != std::string::npos
3697 ? _attr.initialIndent
3699 std::string remainder = _str;
3701 while( !remainder.empty() ) {
3702 if( lines.size() >= 1000 ) {
3703 lines.push_back(
"... message truncated due to excessive size" );
3706 std::size_t tabPos = std::string::npos;
3707 std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
3708 std::size_t pos = remainder.find_first_of(
'\n' );
3709 if( pos <= width ) {
3712 pos = remainder.find_last_of( _attr.tabChar, width );
3713 if( pos != std::string::npos ) {
3715 if( remainder[width] ==
'\n' )
3717 remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
3720 if( width == remainder.size() ) {
3721 spliceLine( indent, remainder, width );
3723 else if( remainder[width] ==
'\n' ) {
3724 spliceLine( indent, remainder, width );
3725 if( width <= 1 || remainder.size() != 1 )
3726 remainder = remainder.substr( 1 );
3727 indent = _attr.indent;
3730 pos = remainder.find_last_of( wrappableChars, width );
3731 if( pos != std::string::npos && pos > 0 ) {
3732 spliceLine( indent, remainder, pos );
3733 if( remainder[0] ==
' ' )
3734 remainder = remainder.substr( 1 );
3737 spliceLine( indent, remainder, width-1 );
3738 lines.back() +=
"-";
3740 if( lines.size() == 1 )
3741 indent = _attr.indent;
3742 if( tabPos != std::string::npos )
3748 void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
3749 lines.push_back( std::string( _indent,
' ' ) + _remainder.substr( 0, _pos ) );
3750 _remainder = _remainder.substr( _pos );
3753 typedef std::vector<std::string>::const_iterator const_iterator;
3755 const_iterator begin()
const {
return lines.begin(); }
3756 const_iterator end()
const {
return lines.end(); }
3757 std::string
const& last()
const {
return lines.back(); }
3758 std::size_t
size()
const {
return lines.size(); }
3759 std::string
const& operator[]( std::size_t _index )
const {
return lines[_index]; }
3760 std::string toString()
const {
3761 std::ostringstream oss;
3766 inline friend std::ostream& operator << ( std::ostream& _stream, Text
const& _text ) {
3767 for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
3768 it != itEnd; ++it ) {
3769 if( it != _text.begin() )
3778 TextAttributes attr;
3779 std::vector<std::string> lines;
3784 #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE 3788 #endif // TBC_TEXT_FORMAT_H_INCLUDED 3793 #undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE 3797 #ifndef TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED 3798 #define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED 3822 #if __has_feature(cxx_nullptr) 3823 #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR 3826 #if __has_feature(cxx_noexcept) 3827 #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT 3836 #if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) 3837 #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR 3849 #if (_MSC_VER >= 1600) 3850 #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR 3851 #define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR 3854 #if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015)) 3855 #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT 3856 #define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS 3865 #if defined(__cplusplus) && __cplusplus >= 201103L 3867 #define CLARA_CPP11_OR_GREATER 3869 #if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) 3870 #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR 3873 #ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT 3874 #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT 3877 #ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS 3878 #define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS 3881 #if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) 3882 #define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE 3884 #if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) 3885 #define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR 3888 #endif // __cplusplus >= 201103L 3891 #if defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11) 3892 #define CLARA_CONFIG_CPP11_NULLPTR 3894 #if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11) 3895 #define CLARA_CONFIG_CPP11_NOEXCEPT 3897 #if defined(CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_NO_CPP11) 3898 #define CLARA_CONFIG_CPP11_GENERATED_METHODS 3900 #if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11) 3901 #define CLARA_CONFIG_CPP11_OVERRIDE 3903 #if defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_UNIQUE_PTR) && !defined(CLARA_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_CPP11) 3904 #define CLARA_CONFIG_CPP11_UNIQUE_PTR 3908 #if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT) 3909 #define CLARA_NOEXCEPT noexcept 3910 # define CLARA_NOEXCEPT_IS(x) noexcept(x) 3912 #define CLARA_NOEXCEPT throw() 3913 # define CLARA_NOEXCEPT_IS(x) 3917 #ifdef CLARA_CONFIG_CPP11_NULLPTR 3918 #define CLARA_NULL nullptr 3920 #define CLARA_NULL NULL 3924 #ifdef CLARA_CONFIG_CPP11_OVERRIDE 3925 #define CLARA_OVERRIDE override 3927 #define CLARA_OVERRIDE 3931 #ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR 3932 # define CLARA_AUTO_PTR( T ) std::unique_ptr<T> 3934 # define CLARA_AUTO_PTR( T ) std::auto_ptr<T> 3937 #endif // TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED 3943 #include <stdexcept> 3946 #if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) 3947 #define CLARA_PLATFORM_WINDOWS 3951 #ifdef STITCH_CLARA_OPEN_NAMESPACE 3952 STITCH_CLARA_OPEN_NAMESPACE
3957 struct UnpositionalTag {};
3959 extern UnpositionalTag _;
3961 #ifdef CLARA_CONFIG_MAIN 3967 #ifdef CLARA_CONSOLE_WIDTH 3968 const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
3970 const unsigned int consoleWidth = 80;
3973 using namespace Tbc;
3975 inline bool startsWith( std::string
const& str, std::string
const& prefix ) {
3976 return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
3979 template<
typename T>
struct RemoveConstRef{
typedef T type; };
3980 template<
typename T>
struct RemoveConstRef<T&>{
typedef T type; };
3981 template<
typename T>
struct RemoveConstRef<T const&>{
typedef T type; };
3982 template<
typename T>
struct RemoveConstRef<T const>{
typedef T type; };
3984 template<
typename T>
struct IsBool {
static const bool value =
false; };
3985 template<>
struct IsBool<bool> {
static const bool value =
true; };
3987 template<
typename T>
3988 void convertInto( std::string
const& _source, T& _dest ) {
3989 std::stringstream ss;
3993 throw std::runtime_error(
"Unable to convert " + _source +
" to destination type" );
3995 inline void convertInto( std::string
const& _source, std::string& _dest ) {
3998 inline void convertInto( std::string
const& _source,
bool& _dest ) {
3999 std::string sourceLC = _source;
4000 std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower );
4001 if( sourceLC ==
"y" || sourceLC ==
"1" || sourceLC ==
"true" || sourceLC ==
"yes" || sourceLC ==
"on" )
4003 else if( sourceLC ==
"n" || sourceLC ==
"0" || sourceLC ==
"false" || sourceLC ==
"no" || sourceLC ==
"off" )
4006 throw std::runtime_error(
"Expected a boolean value but did not recognise:\n '" + _source +
"'" );
4009 template<
typename ConfigT>
4010 struct IArgFunction {
4011 virtual ~IArgFunction() {}
4012 #ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS 4013 IArgFunction() =
default;
4014 IArgFunction( IArgFunction
const& ) =
default;
4016 virtual void set( ConfigT& config, std::string
const& value )
const = 0;
4017 virtual bool takesArg()
const = 0;
4018 virtual IArgFunction* clone()
const = 0;
4021 template<
typename ConfigT>
4022 class BoundArgFunction {
4024 BoundArgFunction() : functionObj( CLARA_NULL ) {}
4025 BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
4026 BoundArgFunction( BoundArgFunction
const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {}
4027 BoundArgFunction& operator = ( BoundArgFunction
const& other ) {
4028 IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL;
4030 functionObj = newFunctionObj;
4033 ~BoundArgFunction() {
delete functionObj; }
4035 void set( ConfigT& config, std::string
const& value )
const {
4036 functionObj->set( config, value );
4038 bool takesArg()
const {
return functionObj->takesArg(); }
4040 bool isSet()
const {
4041 return functionObj != CLARA_NULL;
4044 IArgFunction<ConfigT>* functionObj;
4047 template<
typename C>
4048 struct NullBinder : IArgFunction<C>{
4049 virtual void set( C&, std::string
const& )
const {}
4050 virtual bool takesArg()
const {
return true; }
4051 virtual IArgFunction<C>* clone()
const {
return new NullBinder( *
this ); }
4054 template<
typename C,
typename M>
4055 struct BoundDataMember : IArgFunction<C>{
4056 BoundDataMember( M C::* _member ) : member( _member ) {}
4057 virtual void set( C& p, std::string
const& stringValue )
const {
4058 convertInto( stringValue, p.*member );
4060 virtual bool takesArg()
const {
return !IsBool<M>::value; }
4061 virtual IArgFunction<C>* clone()
const {
return new BoundDataMember( *
this ); }
4064 template<
typename C,
typename M>
4065 struct BoundUnaryMethod : IArgFunction<C>{
4066 BoundUnaryMethod(
void (C::*_member)( M ) ) : member( _member ) {}
4067 virtual void set( C& p, std::string
const& stringValue )
const {
4068 typename RemoveConstRef<M>::type value;
4069 convertInto( stringValue, value );
4070 (p.*member)( value );
4072 virtual bool takesArg()
const {
return !IsBool<M>::value; }
4073 virtual IArgFunction<C>* clone()
const {
return new BoundUnaryMethod( *
this ); }
4074 void (C::*member)( M );
4076 template<
typename C>
4077 struct BoundNullaryMethod : IArgFunction<C>{
4078 BoundNullaryMethod(
void (C::*_member)() ) : member( _member ) {}
4079 virtual void set( C& p, std::string
const& stringValue )
const {
4081 convertInto( stringValue, value );
4085 virtual bool takesArg()
const {
return false; }
4086 virtual IArgFunction<C>* clone()
const {
return new BoundNullaryMethod( *
this ); }
4087 void (C::*member)();
4090 template<
typename C>
4091 struct BoundUnaryFunction : IArgFunction<C>{
4092 BoundUnaryFunction(
void (*_function)( C& ) ) :
function( _function ) {}
4093 virtual void set( C& obj, std::string
const& stringValue )
const {
4095 convertInto( stringValue, value );
4099 virtual bool takesArg()
const {
return false; }
4100 virtual IArgFunction<C>* clone()
const {
return new BoundUnaryFunction( *
this ); }
4101 void (*
function)( C& );
4104 template<
typename C,
typename T>
4105 struct BoundBinaryFunction : IArgFunction<C>{
4106 BoundBinaryFunction(
void (*_function)( C&, T ) ) :
function( _function ) {}
4107 virtual void set( C& obj, std::string
const& stringValue )
const {
4108 typename RemoveConstRef<T>::type value;
4109 convertInto( stringValue, value );
4110 function( obj, value );
4112 virtual bool takesArg()
const {
return !IsBool<T>::value; }
4113 virtual IArgFunction<C>* clone()
const {
return new BoundBinaryFunction( *
this ); }
4114 void (*
function)( C&, T );
4119 inline std::vector<std::string> argsToVector(
int argc,
char const*
const*
const argv ) {
4120 std::vector<std::string> args( static_cast<std::size_t>( argc ) );
4121 for( std::size_t i = 0; i < static_cast<std::size_t>( argc ); ++i )
4128 enum Mode { None, MaybeShortOpt, SlashOpt, ShortOpt, LongOpt, Positional };
4135 enum Type { Positional, ShortOpt, LongOpt };
4136 Token( Type _type, std::string
const& _data ) : type( _type ), data( _data ) {}
4141 Parser() : mode( None ), from( 0 ), inQuotes(
false ){}
4143 void parseIntoTokens( std::vector<std::string>
const& args, std::vector<Token>& tokens ) {
4144 const std::string doubleDash =
"--";
4145 for( std::size_t i = 1; i < args.size() && args[i] != doubleDash; ++i )
4146 parseIntoTokens( args[i], tokens);
4149 void parseIntoTokens( std::string
const& arg, std::vector<Token>& tokens ) {
4150 for( std::size_t i = 0; i <= arg.size(); ++i ) {
4153 inQuotes = !inQuotes;
4154 mode = handleMode( i, c, arg, tokens );
4157 Mode handleMode( std::size_t i,
char c, std::string
const& arg, std::vector<Token>& tokens ) {
4159 case None:
return handleNone( i, c );
4160 case MaybeShortOpt:
return handleMaybeShortOpt( i, c );
4163 case SlashOpt:
return handleOpt( i, c, arg, tokens );
4164 case Positional:
return handlePositional( i, c, arg, tokens );
4165 default:
throw std::logic_error(
"Unknown mode" );
4169 Mode handleNone( std::size_t i,
char c ) {
4175 case '-':
return MaybeShortOpt;
4176 #ifdef CLARA_PLATFORM_WINDOWS 4177 case '/': from = i+1;
return SlashOpt;
4179 default: from = i;
return Positional;
4182 Mode handleMaybeShortOpt( std::size_t i,
char c ) {
4184 case '-': from = i+1;
return LongOpt;
4185 default: from = i;
return ShortOpt;
4188 Mode handleOpt( std::size_t i,
char c, std::string
const& arg, std::vector<Token>& tokens ) {
4189 if( std::string(
":=\0", 3 ).find( c ) == std::string::npos )
4192 std::string optName = arg.substr( from, i-from );
4193 if( mode == ShortOpt )
4194 for( std::size_t j = 0; j < optName.size(); ++j )
4195 tokens.push_back( Token( Token::ShortOpt, optName.substr( j, 1 ) ) );
4196 else if( mode == SlashOpt && optName.size() == 1 )
4197 tokens.push_back( Token( Token::ShortOpt, optName ) );
4199 tokens.push_back( Token( Token::LongOpt, optName ) );
4202 Mode handlePositional( std::size_t i,
char c, std::string
const& arg, std::vector<Token>& tokens ) {
4203 if( inQuotes || std::string(
"\0", 1 ).find( c ) == std::string::npos )
4206 std::string data = arg.substr( from, i-from );
4207 tokens.push_back( Token( Token::Positional, data ) );
4212 template<
typename ConfigT>
4213 struct CommonArgProperties {
4214 CommonArgProperties() {}
4215 CommonArgProperties( Detail::BoundArgFunction<ConfigT>
const& _boundField ) : boundField( _boundField ) {}
4217 Detail::BoundArgFunction<ConfigT> boundField;
4218 std::string description;
4220 std::string placeholder;
4222 bool takesArg()
const {
4223 return !placeholder.empty();
4225 void validate()
const {
4226 if( !boundField.isSet() )
4227 throw std::logic_error(
"option not bound" );
4230 struct OptionArgProperties {
4231 std::vector<std::string> shortNames;
4232 std::string longName;
4234 bool hasShortName( std::string
const& shortName )
const {
4235 return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end();
4237 bool hasLongName( std::string
const& _longName )
const {
4238 return _longName == longName;
4241 struct PositionalArgProperties {
4242 PositionalArgProperties() : position( -1 ) {}
4245 bool isFixedPositional()
const {
4246 return position != -1;
4250 template<
typename ConfigT>
4253 struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties {
4255 Arg( Detail::BoundArgFunction<ConfigT>
const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {}
4257 using CommonArgProperties<ConfigT>::placeholder;
4259 std::string dbgName()
const {
4260 if( !longName.empty() )
4261 return "--" + longName;
4262 if( !shortNames.empty() )
4263 return "-" + shortNames[0];
4264 return "positional args";
4266 std::string commands()
const {
4267 std::ostringstream oss;
4269 std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
4270 for(; it != itEnd; ++it ) {
4277 if( !longName.empty() ) {
4280 oss <<
"--" << longName;
4282 if( !placeholder.empty() )
4283 oss <<
" <" << placeholder <<
">";
4288 typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr;
4290 friend void addOptName( Arg& arg, std::string
const& optName )
4292 if( optName.empty() )
4294 if( Detail::startsWith( optName,
"--" ) ) {
4295 if( !arg.longName.empty() )
4296 throw std::logic_error(
"Only one long opt may be specified. '" 4298 +
"' already specified, now attempting to add '" 4300 arg.longName = optName.substr( 2 );
4302 else if( Detail::startsWith( optName,
"-" ) )
4303 arg.shortNames.push_back( optName.substr( 1 ) );
4305 throw std::logic_error(
"option must begin with - or --. Option was: '" + optName +
"'" );
4307 friend void setPositionalArg( Arg& arg,
int position )
4309 arg.position = position;
4314 ArgBuilder( Arg* arg ) : m_arg( arg ) {}
4317 template<
typename C,
typename M>
4318 void bind( M C::* field, std::string
const& placeholder ) {
4319 m_arg->boundField =
new Detail::BoundDataMember<C,M>( field );
4320 m_arg->placeholder = placeholder;
4323 template<
typename C>
4324 void bind(
bool C::* field ) {
4325 m_arg->boundField =
new Detail::BoundDataMember<C,bool>( field );
4329 template<
typename C,
typename M>
4330 void bind(
void (C::* unaryMethod)( M ), std::string
const& placeholder ) {
4331 m_arg->boundField =
new Detail::BoundUnaryMethod<C,M>( unaryMethod );
4332 m_arg->placeholder = placeholder;
4336 template<
typename C>
4337 void bind(
void (C::* unaryMethod)(
bool ) ) {
4338 m_arg->boundField =
new Detail::BoundUnaryMethod<C,bool>( unaryMethod );
4342 template<
typename C>
4343 void bind(
void (C::* nullaryMethod)() ) {
4344 m_arg->boundField =
new Detail::BoundNullaryMethod<C>( nullaryMethod );
4348 template<
typename C>
4349 void bind(
void (* unaryFunction)( C& ) ) {
4350 m_arg->boundField =
new Detail::BoundUnaryFunction<C>( unaryFunction );
4354 template<
typename C,
typename T>
4355 void bind(
void (* binaryFunction)( C&,
T ), std::string
const& placeholder ) {
4356 m_arg->boundField =
new Detail::BoundBinaryFunction<C, T>( binaryFunction );
4357 m_arg->placeholder = placeholder;
4360 ArgBuilder& describe( std::string
const& description ) {
4361 m_arg->description = description;
4365 m_arg->detail = detail;
4373 class OptBuilder :
public ArgBuilder {
4375 OptBuilder( Arg* arg ) : ArgBuilder( arg ) {}
4376 OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}
4378 OptBuilder& operator[]( std::string
const& optName ) {
4379 addOptName( *ArgBuilder::m_arg, optName );
4387 : m_boundProcessName(
new Detail::NullBinder<ConfigT>() ),
4388 m_highestSpecifiedArgPosition( 0 ),
4389 m_throwOnUnrecognisedTokens(
false )
4391 CommandLine( CommandLine
const& other )
4392 : m_boundProcessName( other.m_boundProcessName ),
4393 m_options ( other.m_options ),
4394 m_positionalArgs( other.m_positionalArgs ),
4395 m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),
4396 m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )
4398 if( other.m_floatingArg.get() )
4399 m_floatingArg.reset(
new Arg( *other.m_floatingArg ) );
4402 CommandLine& setThrowOnUnrecognisedTokens(
bool shouldThrow =
true ) {
4403 m_throwOnUnrecognisedTokens = shouldThrow;
4407 OptBuilder operator[]( std::string
const& optName ) {
4408 m_options.push_back( Arg() );
4409 addOptName( m_options.back(), optName );
4410 OptBuilder builder( &m_options.back() );
4414 ArgBuilder operator[](
int position ) {
4415 m_positionalArgs.insert( std::make_pair( position, Arg() ) );
4416 if( position > m_highestSpecifiedArgPosition )
4417 m_highestSpecifiedArgPosition = position;
4418 setPositionalArg( m_positionalArgs[position], position );
4419 ArgBuilder builder( &m_positionalArgs[position] );
4424 ArgBuilder operator[]( UnpositionalTag ) {
4425 if( m_floatingArg.get() )
4426 throw std::logic_error(
"Only one unpositional argument can be added" );
4427 m_floatingArg.reset(
new Arg() );
4428 ArgBuilder builder( m_floatingArg.get() );
4432 template<
typename C,
typename M>
4433 void bindProcessName( M C::* field ) {
4434 m_boundProcessName =
new Detail::BoundDataMember<C,M>( field );
4436 template<
typename C,
typename M>
4437 void bindProcessName(
void (C::*_unaryMethod)( M ) ) {
4438 m_boundProcessName =
new Detail::BoundUnaryMethod<C,M>( _unaryMethod );
4441 void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth )
const {
4442 typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
4443 std::size_t maxWidth = 0;
4444 for( it = itBegin; it != itEnd; ++it )
4445 maxWidth = (std::max)( maxWidth, it->commands().size() );
4447 for( it = itBegin; it != itEnd; ++it ) {
4448 Detail::Text usage( it->commands(), Detail::TextAttributes()
4449 .setWidth( maxWidth+indent )
4450 .setIndent( indent ) );
4451 Detail::Text desc( it->description, Detail::TextAttributes()
4452 .setWidth( width - maxWidth - 3 ) );
4454 for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {
4455 std::string usageCol = i < usage.size() ? usage[i] :
"";
4458 if( i < desc.size() && !desc[i].empty() )
4459 os << std::string( indent + 2 + maxWidth - usageCol.size(),
' ' )
4465 std::string optUsage()
const {
4466 std::ostringstream oss;
4471 void argSynopsis( std::ostream& os )
const {
4472 for(
int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
4475 typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
4476 if( it != m_positionalArgs.end() )
4477 os <<
"<" << it->second.placeholder <<
">";
4478 else if( m_floatingArg.get() )
4479 os <<
"<" << m_floatingArg->placeholder <<
">";
4481 throw std::logic_error(
"non consecutive positional arguments with no floating args" );
4484 if( m_floatingArg.get() ) {
4485 if( m_highestSpecifiedArgPosition > 1 )
4487 os <<
"[<" << m_floatingArg->placeholder <<
"> ...]";
4490 std::string argSynopsis()
const {
4491 std::ostringstream oss;
4496 void usage( std::ostream& os, std::string
const& procName )
const {
4498 os <<
"usage:\n " << procName <<
" ";
4500 if( !m_options.empty() ) {
4501 os <<
" [options]\n\nwhere options are: \n";
4506 std::string usage( std::string
const& procName )
const {
4507 std::ostringstream oss;
4508 usage( oss, procName );
4512 ConfigT parse( std::vector<std::string>
const& args )
const {
4514 parseInto( args, config );
4518 std::vector<Parser::Token> parseInto( std::vector<std::string>
const& args, ConfigT& config )
const {
4519 std::string processName = args[0];
4520 std::size_t lastSlash = processName.find_last_of(
"/\\" );
4521 if( lastSlash != std::string::npos )
4522 processName = processName.substr( lastSlash+1 );
4523 m_boundProcessName.set( config, processName );
4524 std::vector<Parser::Token> tokens;
4526 parser.parseIntoTokens( args, tokens );
4527 return populate( tokens, config );
4530 std::vector<Parser::Token> populate( std::vector<Parser::Token>
const& tokens, ConfigT& config )
const {
4532 std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );
4533 unusedTokens = populateFixedArgs( unusedTokens, config );
4534 unusedTokens = populateFloatingArgs( unusedTokens, config );
4535 return unusedTokens;
4538 std::vector<Parser::Token> populateOptions( std::vector<Parser::Token>
const& tokens, ConfigT& config )
const {
4539 std::vector<Parser::Token> unusedTokens;
4540 std::vector<std::string> errors;
4541 for( std::size_t i = 0; i < tokens.size(); ++i ) {
4542 Parser::Token
const& token = tokens[i];
4543 typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
4544 for(; it != itEnd; ++it ) {
4545 Arg
const& arg = *it;
4548 if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
4549 ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
4550 if( arg.takesArg() ) {
4551 if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )
4552 errors.push_back(
"Expected argument to option: " + token.data );
4554 arg.boundField.set( config, tokens[++i].data );
4557 arg.boundField.set( config,
"true" );
4562 catch( std::exception& ex ) {
4563 errors.push_back( std::string( ex.what() ) +
"\n- while parsing: (" + arg.commands() +
")" );
4567 if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )
4568 unusedTokens.push_back( token );
4569 else if( errors.empty() && m_throwOnUnrecognisedTokens )
4570 errors.push_back(
"unrecognised option: " + token.data );
4573 if( !errors.empty() ) {
4574 std::ostringstream oss;
4575 for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();
4578 if( it != errors.begin() )
4582 throw std::runtime_error( oss.str() );
4584 return unusedTokens;
4586 std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token>
const& tokens, ConfigT& config )
const {
4587 std::vector<Parser::Token> unusedTokens;
4589 for( std::size_t i = 0; i < tokens.size(); ++i ) {
4590 Parser::Token
const& token = tokens[i];
4591 typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
4592 if( it != m_positionalArgs.end() )
4593 it->second.boundField.set( config, token.data );
4595 unusedTokens.push_back( token );
4596 if( token.type == Parser::Token::Positional )
4599 return unusedTokens;
4601 std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token>
const& tokens, ConfigT& config )
const {
4602 if( !m_floatingArg.get() )
4604 std::vector<Parser::Token> unusedTokens;
4605 for( std::size_t i = 0; i < tokens.size(); ++i ) {
4606 Parser::Token
const& token = tokens[i];
4607 if( token.type == Parser::Token::Positional )
4608 m_floatingArg->boundField.set( config, token.data );
4610 unusedTokens.push_back( token );
4612 return unusedTokens;
4615 void validate()
const 4617 if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() )
4618 throw std::logic_error(
"No options or arguments specified" );
4620 for(
typename std::vector<Arg>::const_iterator it = m_options.begin(),
4621 itEnd = m_options.end();
4627 Detail::BoundArgFunction<ConfigT> m_boundProcessName;
4628 std::vector<Arg> m_options;
4629 std::map<int, Arg> m_positionalArgs;
4630 ArgAutoPtr m_floatingArg;
4631 int m_highestSpecifiedArgPosition;
4632 bool m_throwOnUnrecognisedTokens;
4637 STITCH_CLARA_CLOSE_NAMESPACE
4638 #undef STITCH_CLARA_OPEN_NAMESPACE 4639 #undef STITCH_CLARA_CLOSE_NAMESPACE 4641 #endif // TWOBLUECUBES_CLARA_H_INCLUDED 4642 #undef STITCH_CLARA_OPEN_NAMESPACE 4645 #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH 4646 #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH 4647 #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH 4654 inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
4655 inline void abortAfterX( ConfigData& config,
int x ) {
4657 throw std::runtime_error(
"Value after -x or --abortAfter must be greater than zero" );
4658 config.abortAfter = x;
4660 inline void addTestOrTags( ConfigData& config, std::string
const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
4661 inline void addReporterName( ConfigData& config, std::string
const& _reporterName ) { config.reporterNames.push_back( _reporterName ); }
4663 inline void addWarning( ConfigData& config, std::string
const& _warning ) {
4664 if( _warning ==
"NoAssertions" )
4665 config.warnings =
static_cast<WarnAbout::What
>( config.warnings | WarnAbout::NoAssertions );
4667 throw std::runtime_error(
"Unrecognised warning: '" + _warning +
"'" );
4669 inline void setOrder( ConfigData& config, std::string
const& order ) {
4670 if( startsWith(
"declared", order ) )
4671 config.runOrder = RunTests::InDeclarationOrder;
4672 else if( startsWith(
"lexical", order ) )
4673 config.runOrder = RunTests::InLexicographicalOrder;
4674 else if( startsWith(
"random", order ) )
4675 config.runOrder = RunTests::InRandomOrder;
4677 throw std::runtime_error(
"Unrecognised ordering: '" + order +
"'" );
4679 inline void setRngSeed( ConfigData& config, std::string
const& seed ) {
4680 if( seed ==
"time" ) {
4681 config.rngSeed =
static_cast<unsigned int>( std::time(0) );
4684 std::stringstream ss;
4686 ss >> config.rngSeed;
4688 throw std::runtime_error(
"Argment to --rng-seed should be the word 'time' or a number" );
4691 inline void setVerbosity( ConfigData& config,
int level ) {
4693 config.verbosity =
static_cast<Verbosity::Level
>( level );
4695 inline void setShowDurations( ConfigData& config,
bool _showDurations ) {
4696 config.showDurations = _showDurations
4697 ? ShowDurations::Always
4698 : ShowDurations::Never;
4700 inline void setUseColour( ConfigData& config, std::string
const& value ) {
4701 std::string mode = toLower( value );
4704 config.useColour = UseColour::Yes;
4705 else if( mode ==
"no" )
4706 config.useColour = UseColour::No;
4707 else if( mode ==
"auto" )
4708 config.useColour = UseColour::Auto;
4710 throw std::runtime_error(
"colour mode must be one of: auto, yes or no" );
4712 inline void forceColour( ConfigData& config ) {
4713 config.useColour = UseColour::Yes;
4715 inline void loadTestNamesFromFile( ConfigData& config, std::string
const& _filename ) {
4716 std::ifstream f( _filename.c_str() );
4718 throw std::domain_error(
"Unable to load input file: " + _filename );
4721 while( std::getline( f, line ) ) {
4723 if( !line.empty() && !startsWith( line,
"#" ) ) {
4724 if( !startsWith( line,
"\"" ) )
4725 line =
"\"" + line +
"\"";
4726 addTestOrTags( config, line +
"," );
4731 inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
4733 using namespace Clara;
4734 CommandLine<ConfigData> cli;
4736 cli.bindProcessName( &ConfigData::processName );
4738 cli["-?"]["-h"]["--help"]
4739 .describe(
"display usage information" )
4740 .bind( &ConfigData::showHelp );
4742 cli["-l"]["--list-tests"]
4743 .describe(
"list all/matching test cases" )
4744 .bind( &ConfigData::listTests );
4746 cli["-t"]["--list-tags"]
4747 .describe(
"list all/matching tags" )
4748 .bind( &ConfigData::listTags );
4750 cli["-s"]["--success"]
4751 .describe(
"include successful tests in output" )
4752 .bind( &ConfigData::showSuccessfulTests );
4754 cli["-b"]["--break"]
4755 .describe(
"break into debugger on failure" )
4756 .bind( &ConfigData::shouldDebugBreak );
4758 cli["-e"]["--nothrow"]
4759 .describe(
"skip exception tests" )
4760 .bind( &ConfigData::noThrow );
4762 cli["-i"]["--invisibles"]
4763 .describe(
"show invisibles (tabs, newlines)" )
4764 .bind( &ConfigData::showInvisibles );
4767 .describe(
"output filename" )
4768 .bind( &ConfigData::outputFilename,
"filename" );
4770 cli["-r"]["--reporter"]
4772 .describe(
"reporter to use (defaults to console)" )
4773 .bind( &addReporterName,
"name" );
4776 .describe(
"suite name" )
4777 .bind( &ConfigData::name,
"name" );
4779 cli["-a"]["--abort"]
4780 .describe(
"abort at first failure" )
4781 .bind( &abortAfterFirst );
4783 cli["-x"]["--abortx"]
4784 .describe(
"abort after x failures" )
4785 .bind( &abortAfterX,
"no. failures" );
4788 .describe(
"enable warnings" )
4789 .bind( &addWarning,
"warning name" );
4799 .describe(
"which test or tests to use" )
4800 .bind( &addTestOrTags,
"test name, pattern or tags" );
4802 cli["-d"]["--durations"]
4803 .describe(
"show test durations" )
4804 .bind( &setShowDurations,
"yes|no" );
4806 cli["-f"]["--input-file"]
4807 .describe(
"load test names to run from a file" )
4808 .bind( &loadTestNamesFromFile,
"filename" );
4810 cli["-#"]["--filenames-as-tags"]
4811 .describe(
"adds a tag for the filename" )
4812 .bind( &ConfigData::filenamesAsTags );
4815 cli["--list-test-names-only"]
4816 .describe(
"list all/matching test cases names only" )
4817 .bind( &ConfigData::listTestNamesOnly );
4819 cli["--list-reporters"]
4820 .describe(
"list all reporters" )
4821 .bind( &ConfigData::listReporters );
4824 .describe(
"test case order (defaults to decl)" )
4825 .bind( &setOrder,
"decl|lex|rand" );
4828 .describe(
"set a specific seed for random numbers" )
4829 .bind( &setRngSeed,
"'time'|number" );
4831 cli["--force-colour"]
4832 .describe(
"force colourised output (deprecated)" )
4833 .bind( &forceColour );
4836 .describe(
"should output be colourised" )
4837 .bind( &setUseColour,
"yes|no" );
4845 #define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED 4848 #define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED 4850 #define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH 4852 #define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch 4855 #ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE 4856 # ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED 4857 # ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED 4858 # define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED 4861 # define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED 4864 #ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED 4870 #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE 4871 namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
4876 #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH 4877 const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
4879 const unsigned int consoleWidth = 80;
4882 struct TextAttributes {
4884 : initialIndent( std::string::npos ),
4886 width( consoleWidth-1 ),
4890 TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value;
return *
this; }
4891 TextAttributes& setIndent( std::size_t _value ) { indent = _value;
return *
this; }
4892 TextAttributes& setWidth( std::size_t _value ) { width = _value;
return *
this; }
4893 TextAttributes& setTabChar(
char _value ) { tabChar = _value;
return *
this; }
4895 std::size_t initialIndent;
4903 Text( std::string
const& _str, TextAttributes
const& _attr = TextAttributes() )
4906 std::string wrappableChars =
" [({.,/|\\-";
4907 std::size_t indent = _attr.initialIndent != std::string::npos
4908 ? _attr.initialIndent
4910 std::string remainder = _str;
4912 while( !remainder.empty() ) {
4913 if( lines.size() >= 1000 ) {
4914 lines.push_back(
"... message truncated due to excessive size" );
4917 std::size_t tabPos = std::string::npos;
4918 std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
4919 std::size_t pos = remainder.find_first_of(
'\n' );
4920 if( pos <= width ) {
4923 pos = remainder.find_last_of( _attr.tabChar, width );
4924 if( pos != std::string::npos ) {
4926 if( remainder[width] ==
'\n' )
4928 remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
4931 if( width == remainder.size() ) {
4932 spliceLine( indent, remainder, width );
4934 else if( remainder[width] ==
'\n' ) {
4935 spliceLine( indent, remainder, width );
4936 if( width <= 1 || remainder.size() != 1 )
4937 remainder = remainder.substr( 1 );
4938 indent = _attr.indent;
4941 pos = remainder.find_last_of( wrappableChars, width );
4942 if( pos != std::string::npos && pos > 0 ) {
4943 spliceLine( indent, remainder, pos );
4944 if( remainder[0] ==
' ' )
4945 remainder = remainder.substr( 1 );
4948 spliceLine( indent, remainder, width-1 );
4949 lines.back() +=
"-";
4951 if( lines.size() == 1 )
4952 indent = _attr.indent;
4953 if( tabPos != std::string::npos )
4959 void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
4960 lines.push_back( std::string( _indent,
' ' ) + _remainder.substr( 0, _pos ) );
4961 _remainder = _remainder.substr( _pos );
4964 typedef std::vector<std::string>::const_iterator const_iterator;
4966 const_iterator begin()
const {
return lines.begin(); }
4967 const_iterator end()
const {
return lines.end(); }
4968 std::string
const& last()
const {
return lines.back(); }
4969 std::size_t
size()
const {
return lines.size(); }
4970 std::string
const& operator[]( std::size_t _index )
const {
return lines[_index]; }
4971 std::string toString()
const {
4972 std::ostringstream oss;
4977 inline friend std::ostream& operator << ( std::ostream& _stream, Text
const& _text ) {
4978 for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
4979 it != itEnd; ++it ) {
4980 if( it != _text.begin() )
4989 TextAttributes attr;
4990 std::vector<std::string> lines;
4995 #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE 4999 #endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED 5000 #undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE 5004 using Tbc::TextAttributes;
5008 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED 5026 BrightRed = Bright | Red,
5027 BrightGreen = Bright | Green,
5028 LightGrey = Bright | Grey,
5029 BrightWhite = Bright | White,
5032 FileName = LightGrey,
5034 ResultError = BrightRed,
5035 ResultSuccess = BrightGreen,
5036 ResultExpectedFailure = Warning,
5041 OriginalExpression = Cyan,
5042 ReconstructedExpression = Yellow,
5044 SecondaryText = LightGrey,
5049 Colour( Code _colourCode );
5050 Colour( Colour
const& other );
5054 static void use( Code _colourCode );
5060 inline std::ostream& operator << ( std::ostream& os, Colour
const& ) {
return os; }
5065 #define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED 5074 struct ReporterConfig {
5076 : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
5079 : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
5081 std::ostream& stream()
const {
return *m_stream; }
5085 std::ostream* m_stream;
5089 struct ReporterPreferences {
5090 ReporterPreferences()
5091 : shouldRedirectStdOut(
false )
5094 bool shouldRedirectStdOut;
5097 template<
typename T>
5098 struct LazyStat :
Option<T> {
5099 LazyStat() : used(
false ) {}
5100 LazyStat& operator=(
T const& _value ) {
5112 struct TestRunInfo {
5113 TestRunInfo( std::string
const& _name ) : name( _name ) {}
5117 GroupInfo( std::string
const& _name,
5118 std::size_t _groupIndex,
5119 std::size_t _groupsCount )
5121 groupIndex( _groupIndex ),
5122 groupsCounts( _groupsCount )
5126 std::size_t groupIndex;
5127 std::size_t groupsCounts;
5130 struct AssertionStats {
5132 std::vector<MessageInfo>
const& _infoMessages,
5134 : assertionResult( _assertionResult ),
5135 infoMessages( _infoMessages ),
5138 if( assertionResult.hasMessage() ) {
5141 MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
5142 builder << assertionResult.getMessage();
5143 builder.m_info.message = builder.m_stream.str();
5145 infoMessages.push_back( builder.m_info );
5148 virtual ~AssertionStats();
5150 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS 5151 AssertionStats( AssertionStats
const& ) =
default;
5152 AssertionStats( AssertionStats && ) =
default;
5153 AssertionStats& operator = ( AssertionStats
const& ) =
default;
5154 AssertionStats& operator = ( AssertionStats && ) =
default;
5158 std::vector<MessageInfo> infoMessages;
5162 struct SectionStats {
5164 Counts const& _assertions,
5165 double _durationInSeconds,
5166 bool _missingAssertions )
5167 : sectionInfo( _sectionInfo ),
5168 assertions( _assertions ),
5169 durationInSeconds( _durationInSeconds ),
5170 missingAssertions( _missingAssertions )
5172 virtual ~SectionStats();
5173 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS 5174 SectionStats( SectionStats
const& ) =
default;
5175 SectionStats( SectionStats && ) =
default;
5176 SectionStats& operator = ( SectionStats
const& ) =
default;
5177 SectionStats& operator = ( SectionStats && ) =
default;
5182 double durationInSeconds;
5183 bool missingAssertions;
5186 struct TestCaseStats {
5189 std::string
const& _stdOut,
5190 std::string
const& _stdErr,
5192 : testInfo( _testInfo ),
5196 aborting( _aborting )
5198 virtual ~TestCaseStats();
5200 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS 5201 TestCaseStats( TestCaseStats
const& ) =
default;
5202 TestCaseStats( TestCaseStats && ) =
default;
5203 TestCaseStats& operator = ( TestCaseStats
const& ) =
default;
5204 TestCaseStats& operator = ( TestCaseStats && ) =
default;
5214 struct TestGroupStats {
5215 TestGroupStats( GroupInfo
const& _groupInfo,
5218 : groupInfo( _groupInfo ),
5220 aborting( _aborting )
5222 TestGroupStats( GroupInfo
const& _groupInfo )
5223 : groupInfo( _groupInfo ),
5226 virtual ~TestGroupStats();
5228 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS 5229 TestGroupStats( TestGroupStats
const& ) =
default;
5230 TestGroupStats( TestGroupStats && ) =
default;
5231 TestGroupStats& operator = ( TestGroupStats
const& ) =
default;
5232 TestGroupStats& operator = ( TestGroupStats && ) =
default;
5235 GroupInfo groupInfo;
5240 struct TestRunStats {
5241 TestRunStats( TestRunInfo
const& _runInfo,
5244 : runInfo( _runInfo ),
5246 aborting( _aborting )
5248 virtual ~TestRunStats();
5250 # ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS 5251 TestRunStats( TestRunStats
const& _other )
5252 : runInfo( _other.runInfo ),
5253 totals( _other.totals ),
5254 aborting( _other.aborting )
5257 TestRunStats( TestRunStats
const& ) =
default;
5258 TestRunStats( TestRunStats && ) =
default;
5259 TestRunStats& operator = ( TestRunStats
const& ) =
default;
5260 TestRunStats& operator = ( TestRunStats && ) =
default;
5263 TestRunInfo runInfo;
5268 class MultipleReporters;
5270 struct IStreamingReporter :
IShared {
5271 virtual ~IStreamingReporter();
5276 virtual ReporterPreferences getPreferences()
const = 0;
5278 virtual void noMatchingTestCases( std::string
const& spec ) = 0;
5280 virtual void testRunStarting( TestRunInfo
const& testRunInfo ) = 0;
5281 virtual void testGroupStarting( GroupInfo
const& groupInfo ) = 0;
5283 virtual void testCaseStarting(
TestCaseInfo const& testInfo ) = 0;
5284 virtual void sectionStarting(
SectionInfo const& sectionInfo ) = 0;
5286 virtual void assertionStarting(
AssertionInfo const& assertionInfo ) = 0;
5289 virtual bool assertionEnded( AssertionStats
const& assertionStats ) = 0;
5291 virtual void sectionEnded( SectionStats
const& sectionStats ) = 0;
5292 virtual void testCaseEnded( TestCaseStats
const& testCaseStats ) = 0;
5293 virtual void testGroupEnded( TestGroupStats
const& testGroupStats ) = 0;
5294 virtual void testRunEnded( TestRunStats
const& testRunStats ) = 0;
5296 virtual void skipTest(
TestCaseInfo const& testInfo ) = 0;
5298 virtual MultipleReporters* tryAsMulti() {
return CATCH_NULL; }
5301 struct IReporterFactory :
IShared {
5302 virtual ~IReporterFactory();
5303 virtual IStreamingReporter* create( ReporterConfig
const& config )
const = 0;
5304 virtual std::string getDescription()
const = 0;
5307 struct IReporterRegistry {
5308 typedef std::map<std::string, Ptr<IReporterFactory> > FactoryMap;
5309 typedef std::vector<Ptr<IReporterFactory> > Listeners;
5311 virtual ~IReporterRegistry();
5312 virtual IStreamingReporter* create( std::string
const& name,
Ptr<IConfig const> const& config )
const = 0;
5313 virtual FactoryMap
const& getFactories()
const = 0;
5314 virtual Listeners
const& getListeners()
const = 0;
5322 #include <algorithm> 5326 inline std::size_t listTests(
Config const& config ) {
5328 TestSpec testSpec = config.testSpec();
5329 if( config.testSpec().hasFilters() )
5330 Catch::cout() <<
"Matching test cases:\n";
5332 Catch::cout() <<
"All available test cases:\n";
5333 testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse(
"*" ).testSpec();
5336 std::size_t matchedTests = 0;
5337 TextAttributes nameAttr, tagsAttr;
5338 nameAttr.setInitialIndent( 2 ).setIndent( 4 );
5339 tagsAttr.setIndent( 6 );
5341 std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
5342 for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
5346 TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
5347 Colour::Code colour = testCaseInfo.isHidden()
5348 ? Colour::SecondaryText
5350 Colour colourGuard( colour );
5352 Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl;
5353 if( !testCaseInfo.tags.empty() )
5354 Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;
5357 if( !config.testSpec().hasFilters() )
5358 Catch::cout() <<
pluralise( matchedTests,
"test case" ) <<
"\n" << std::endl;
5360 Catch::cout() <<
pluralise( matchedTests,
"matching test case" ) <<
"\n" << std::endl;
5361 return matchedTests;
5364 inline std::size_t listTestsNamesOnly(
Config const& config ) {
5365 TestSpec testSpec = config.testSpec();
5366 if( !config.testSpec().hasFilters() )
5367 testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse(
"*" ).testSpec();
5368 std::size_t matchedTests = 0;
5369 std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
5370 for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
5374 TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
5375 if( startsWith( testCaseInfo.name,
"#" ) )
5376 Catch::cout() <<
"\"" << testCaseInfo.name <<
"\"" << std::endl;
5378 Catch::cout() << testCaseInfo.name << std::endl;
5380 return matchedTests;
5384 TagInfo() : count ( 0 ) {}
5385 void add( std::string
const& spelling ) {
5387 spellings.insert( spelling );
5389 std::string all()
const {
5391 for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end();
5394 out +=
"[" + *it +
"]";
5397 std::set<std::string> spellings;
5401 inline std::size_t listTags(
Config const& config ) {
5402 TestSpec testSpec = config.testSpec();
5403 if( config.testSpec().hasFilters() )
5404 Catch::cout() <<
"Tags for matching test cases:\n";
5406 Catch::cout() <<
"All available tags:\n";
5407 testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse(
"*" ).testSpec();
5410 std::map<std::string, TagInfo> tagCounts;
5412 std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
5413 for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
5416 for( std::set<std::string>::const_iterator tagIt = it->getTestCaseInfo().tags.begin(),
5417 tagItEnd = it->getTestCaseInfo().tags.end();
5420 std::string tagName = *tagIt;
5421 std::string lcaseTagName = toLower( tagName );
5422 std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName );
5423 if( countIt == tagCounts.end() )
5424 countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
5425 countIt->second.add( tagName );
5429 for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(),
5430 countItEnd = tagCounts.end();
5431 countIt != countItEnd;
5433 std::ostringstream oss;
5434 oss <<
" " << std::setw(2) << countIt->second.count <<
" ";
5435 Text wrapper( countIt->second.all(), TextAttributes()
5436 .setInitialIndent( 0 )
5437 .setIndent( oss.str().size() )
5439 Catch::cout() << oss.str() << wrapper <<
"\n";
5441 Catch::cout() <<
pluralise( tagCounts.size(),
"tag" ) <<
"\n" << std::endl;
5442 return tagCounts.size();
5445 inline std::size_t listReporters(
Config const& ) {
5446 Catch::cout() <<
"Available reporters:\n";
5447 IReporterRegistry::FactoryMap
const& factories = getRegistryHub().getReporterRegistry().getFactories();
5448 IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
5449 std::size_t maxNameLen = 0;
5450 for(it = itBegin; it != itEnd; ++it )
5451 maxNameLen = (std::max)( maxNameLen, it->first.size() );
5453 for(it = itBegin; it != itEnd; ++it ) {
5454 Text wrapper( it->second->getDescription(), TextAttributes()
5455 .setInitialIndent( 0 )
5456 .setIndent( 7+maxNameLen )
5458 Catch::cout() <<
" " 5461 << std::string( maxNameLen - it->first.size() + 2,
' ' )
5464 Catch::cout() << std::endl;
5465 return factories.size();
5470 if( config.listTests() )
5471 listedCount = listedCount.valueOr(0) + listTests( config );
5472 if( config.listTestNamesOnly() )
5473 listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
5474 if( config.listTags() )
5475 listedCount = listedCount.valueOr(0) + listTags( config );
5476 if( config.listReporters() )
5477 listedCount = listedCount.valueOr(0) + listReporters( config );
5484 #define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED 5487 #define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED 5495 namespace TestCaseTracking {
5498 virtual ~ITracker();
5501 virtual std::string name()
const = 0;
5504 virtual bool isComplete()
const = 0;
5505 virtual bool isSuccessfullyCompleted()
const = 0;
5506 virtual bool isOpen()
const = 0;
5507 virtual bool hasChildren()
const = 0;
5509 virtual ITracker& parent() = 0;
5512 virtual void close() = 0;
5513 virtual void fail() = 0;
5514 virtual void markAsNeedingAnotherRun() = 0;
5517 virtual ITracker* findChild( std::string
const& name ) = 0;
5518 virtual void openChild() = 0;
5521 virtual bool isSectionTracker()
const = 0;
5522 virtual bool isIndexTracker()
const = 0;
5525 class TrackerContext {
5534 ITracker* m_currentTracker;
5535 RunState m_runState;
5539 static TrackerContext& instance() {
5540 static TrackerContext s_instance;
5545 : m_currentTracker( CATCH_NULL ),
5546 m_runState( NotStarted )
5549 ITracker& startRun();
5552 m_rootTracker.reset();
5553 m_currentTracker = CATCH_NULL;
5554 m_runState = NotStarted;
5558 m_currentTracker = m_rootTracker.get();
5559 m_runState = Executing;
5561 void completeCycle() {
5562 m_runState = CompletedCycle;
5565 bool completedCycle()
const {
5566 return m_runState == CompletedCycle;
5568 ITracker& currentTracker() {
5569 return *m_currentTracker;
5571 void setCurrentTracker( ITracker* tracker ) {
5572 m_currentTracker = tracker;
5576 class TrackerBase :
public ITracker {
5583 CompletedSuccessfully,
5586 class TrackerHasName {
5589 TrackerHasName( std::string
const& name ) : m_name( name ) {}
5591 return tracker->name() == m_name;
5594 typedef std::vector<Ptr<ITracker> > Children;
5596 TrackerContext& m_ctx;
5598 Children m_children;
5599 CycleState m_runState;
5601 TrackerBase( std::string
const& name, TrackerContext& ctx, ITracker* parent )
5605 m_runState( NotStarted )
5607 virtual ~TrackerBase();
5609 virtual std::string name()
const CATCH_OVERRIDE {
5612 virtual bool isComplete()
const CATCH_OVERRIDE {
5613 return m_runState == CompletedSuccessfully || m_runState == Failed;
5615 virtual bool isSuccessfullyCompleted()
const CATCH_OVERRIDE {
5616 return m_runState == CompletedSuccessfully;
5618 virtual bool isOpen()
const CATCH_OVERRIDE {
5619 return m_runState != NotStarted && !isComplete();
5621 virtual bool hasChildren()
const CATCH_OVERRIDE {
5622 return !m_children.empty();
5625 virtual void addChild(
Ptr<ITracker> const& child ) CATCH_OVERRIDE {
5626 m_children.push_back( child );
5629 virtual ITracker* findChild( std::string
const& name ) CATCH_OVERRIDE {
5630 Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( name ) );
5631 return( it != m_children.end() )
5635 virtual ITracker& parent() CATCH_OVERRIDE {
5640 virtual void openChild() CATCH_OVERRIDE {
5641 if( m_runState != ExecutingChildren ) {
5642 m_runState = ExecutingChildren;
5644 m_parent->openChild();
5648 virtual bool isSectionTracker()
const CATCH_OVERRIDE {
return false; }
5649 virtual bool isIndexTracker()
const CATCH_OVERRIDE {
return false; }
5652 m_runState = Executing;
5655 m_parent->openChild();
5658 virtual void close() CATCH_OVERRIDE {
5661 while( &m_ctx.currentTracker() != this )
5662 m_ctx.currentTracker().close();
5664 switch( m_runState ) {
5666 case CompletedSuccessfully:
5668 throw std::logic_error(
"Illogical state" );
5670 case NeedsAnotherRun:
5674 m_runState = CompletedSuccessfully;
5676 case ExecutingChildren:
5677 if( m_children.empty() || m_children.back()->isComplete() )
5678 m_runState = CompletedSuccessfully;
5682 throw std::logic_error(
"Unexpected state" );
5685 m_ctx.completeCycle();
5687 virtual void fail() CATCH_OVERRIDE {
5688 m_runState = Failed;
5690 m_parent->markAsNeedingAnotherRun();
5692 m_ctx.completeCycle();
5694 virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE {
5695 m_runState = NeedsAnotherRun;
5698 void moveToParent() {
5700 m_ctx.setCurrentTracker( m_parent );
5703 m_ctx.setCurrentTracker(
this );
5707 class SectionTracker :
public TrackerBase {
5709 SectionTracker( std::string
const& name, TrackerContext& ctx, ITracker* parent )
5710 : TrackerBase( name, ctx, parent )
5712 virtual ~SectionTracker();
5714 virtual bool isSectionTracker()
const CATCH_OVERRIDE {
return true; }
5716 static SectionTracker& acquire( TrackerContext& ctx, std::string
const& name ) {
5717 SectionTracker* section = CATCH_NULL;
5719 ITracker& currentTracker = ctx.currentTracker();
5720 if( ITracker* childTracker = currentTracker.findChild( name ) ) {
5721 assert( childTracker );
5722 assert( childTracker->isSectionTracker() );
5723 section =
static_cast<SectionTracker*
>( childTracker );
5726 section =
new SectionTracker( name, ctx, ¤tTracker );
5727 currentTracker.addChild( section );
5729 if( !ctx.completedCycle() && !section->isComplete() ) {
5737 class IndexTracker :
public TrackerBase {
5741 IndexTracker( std::string
const& name, TrackerContext& ctx, ITracker* parent,
int size )
5742 : TrackerBase( name, ctx, parent ),
5746 virtual ~IndexTracker();
5748 virtual bool isIndexTracker()
const CATCH_OVERRIDE {
return true; }
5750 static IndexTracker& acquire( TrackerContext& ctx, std::string
const& name,
int size ) {
5751 IndexTracker* tracker = CATCH_NULL;
5753 ITracker& currentTracker = ctx.currentTracker();
5754 if( ITracker* childTracker = currentTracker.findChild( name ) ) {
5755 assert( childTracker );
5756 assert( childTracker->isIndexTracker() );
5757 tracker =
static_cast<IndexTracker*
>( childTracker );
5760 tracker =
new IndexTracker( name, ctx, ¤tTracker, size );
5761 currentTracker.addChild( tracker );
5764 if( !ctx.completedCycle() && !tracker->isComplete() ) {
5765 if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
5766 tracker->moveNext();
5773 int index()
const {
return m_index; }
5780 virtual void close() CATCH_OVERRIDE {
5781 TrackerBase::close();
5782 if( m_runState == CompletedSuccessfully && m_index < m_size-1 )
5783 m_runState = Executing;
5787 inline ITracker& TrackerContext::startRun() {
5788 m_rootTracker =
new SectionTracker(
"{root}", *
this, CATCH_NULL );
5789 m_currentTracker = CATCH_NULL;
5790 m_runState = Executing;
5791 return *m_rootTracker;
5796 using TestCaseTracking::ITracker;
5797 using TestCaseTracking::TrackerContext;
5798 using TestCaseTracking::SectionTracker;
5799 using TestCaseTracking::IndexTracker;
5804 #define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED 5809 inline void fatal( std::string
const& message,
int exitCode ) {
5810 IContext& context = Catch::getCurrentContext();
5812 resultCapture->handleFatalErrorCondition( message );
5814 if( Catch::alwaysTrue() )
5820 #if defined ( CATCH_PLATFORM_WINDOWS ) 5824 struct FatalConditionHandler {
5830 #else // Not Windows - assumed to be POSIX compatible 5836 struct SignalDefs {
int id;
const char* name; };
5837 extern SignalDefs signalDefs[];
5838 SignalDefs signalDefs[] = {
5839 { SIGINT,
"SIGINT - Terminal interrupt signal" },
5840 { SIGILL,
"SIGILL - Illegal instruction signal" },
5841 { SIGFPE,
"SIGFPE - Floating point error signal" },
5842 { SIGSEGV,
"SIGSEGV - Segmentation violation signal" },
5843 { SIGTERM,
"SIGTERM - Termination request signal" },
5844 { SIGABRT,
"SIGABRT - Abort (abnormal termination) signal" }
5847 struct FatalConditionHandler {
5849 static void handleSignal(
int sig ) {
5850 for( std::size_t i = 0; i <
sizeof(signalDefs)/
sizeof(SignalDefs); ++i )
5851 if( sig == signalDefs[i].
id )
5852 fatal( signalDefs[i].name, -sig );
5853 fatal(
"<unknown signal>", -sig );
5856 FatalConditionHandler() : m_isSet(
true ) {
5857 for( std::size_t i = 0; i <
sizeof(signalDefs)/
sizeof(SignalDefs); ++i )
5858 signal( signalDefs[i].
id, handleSignal );
5860 ~FatalConditionHandler() {
5865 for( std::size_t i = 0; i <
sizeof(signalDefs)/
sizeof(SignalDefs); ++i )
5866 signal( signalDefs[i].
id, SIG_DFL );
5876 #endif // not Windows 5883 class StreamRedirect {
5886 StreamRedirect( std::ostream& stream, std::string& targetString )
5887 : m_stream( stream ),
5888 m_prevBuf( stream.rdbuf() ),
5889 m_targetString( targetString )
5891 stream.rdbuf( m_oss.rdbuf() );
5895 m_targetString += m_oss.str();
5896 m_stream.rdbuf( m_prevBuf );
5900 std::ostream& m_stream;
5901 std::streambuf* m_prevBuf;
5902 std::ostringstream m_oss;
5903 std::string& m_targetString;
5910 RunContext( RunContext
const& );
5911 void operator =( RunContext
const& );
5916 : m_runInfo( _config->name() ),
5917 m_context( getCurrentMutableContext() ),
5918 m_activeTestCase( CATCH_NULL ),
5919 m_config( _config ),
5920 m_reporter( reporter )
5922 m_context.setRunner(
this );
5923 m_context.setConfig( m_config );
5924 m_context.setResultCapture(
this );
5925 m_reporter->testRunStarting( m_runInfo );
5928 virtual ~RunContext() {
5929 m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
5932 void testGroupStarting( std::string
const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
5933 m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );
5935 void testGroupEnded( std::string
const& testSpec,
Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {
5936 m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
5940 Totals prevTotals = m_totals;
5942 std::string redirectedCout;
5943 std::string redirectedCerr;
5947 m_reporter->testCaseStarting( testInfo );
5949 m_activeTestCase = &testCase;
5952 m_trackerContext.startRun();
5954 m_trackerContext.startCycle();
5955 m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, testInfo.name );
5956 runCurrentTest( redirectedCout, redirectedCerr );
5958 while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() );
5961 while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
5963 Totals deltaTotals = m_totals.delta( prevTotals );
5964 if( testInfo.expectedToFail() && deltaTotals.testCases.passed > 0 ) {
5965 deltaTotals.assertions.failed++;
5966 deltaTotals.testCases.passed--;
5967 deltaTotals.testCases.failed++;
5969 m_totals.testCases += deltaTotals.testCases;
5970 m_reporter->testCaseEnded( TestCaseStats( testInfo,
5976 m_activeTestCase = CATCH_NULL;
5977 m_testCaseTracker = CATCH_NULL;
5989 if( result.getResultType() == ResultWas::Ok ) {
5990 m_totals.assertions.passed++;
5992 else if( !result.isOk() ) {
5993 m_totals.assertions.failed++;
5996 if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) )
6000 m_lastAssertionInfo =
AssertionInfo(
"", m_lastAssertionInfo.lineInfo,
"{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
6001 m_lastResult = result;
6004 virtual bool sectionStarted (
6009 std::ostringstream oss;
6010 oss << sectionInfo.name <<
"@" << sectionInfo.lineInfo;
6012 ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, oss.str() );
6013 if( !sectionTracker.isOpen() )
6015 m_activeSections.push_back( §ionTracker );
6017 m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
6019 m_reporter->sectionStarting( sectionInfo );
6021 assertions = m_totals.assertions;
6025 bool testForMissingAssertions(
Counts& assertions ) {
6026 if( assertions.total() != 0 )
6028 if( !m_config->warnAboutMissingAssertions() )
6030 if( m_trackerContext.currentTracker().hasChildren() )
6032 m_totals.assertions.failed++;
6033 assertions.failed++;
6038 Counts assertions = m_totals.assertions - endInfo.prevAssertions;
6039 bool missingAssertions = testForMissingAssertions( assertions );
6041 if( !m_activeSections.empty() ) {
6042 m_activeSections.back()->close();
6043 m_activeSections.pop_back();
6046 m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) );
6050 virtual void sectionEndedEarly(
SectionEndInfo const& endInfo ) {
6051 if( m_unfinishedSections.empty() )
6052 m_activeSections.back()->fail();
6054 m_activeSections.back()->close();
6055 m_activeSections.pop_back();
6057 m_unfinishedSections.push_back( endInfo );
6060 virtual void pushScopedMessage(
MessageInfo const& message ) {
6061 m_messages.push_back( message );
6064 virtual void popScopedMessage(
MessageInfo const& message ) {
6065 m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );
6068 virtual std::string getCurrentTestName()
const {
6069 return m_activeTestCase
6070 ? m_activeTestCase->getTestCaseInfo().name
6075 return &m_lastResult;
6078 virtual void handleFatalErrorCondition( std::string
const& message ) {
6079 ResultBuilder resultBuilder = makeUnexpectedResultBuilder();
6080 resultBuilder.setResultType( ResultWas::FatalErrorCondition );
6081 resultBuilder << message;
6082 resultBuilder.captureExpression();
6084 handleUnfinishedSections();
6087 TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
6088 SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
6091 assertions.failed = 1;
6092 SectionStats testCaseSectionStats( testCaseSection, assertions, 0,
false );
6093 m_reporter->sectionEnded( testCaseSectionStats );
6095 TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo();
6098 deltaTotals.testCases.failed = 1;
6099 m_reporter->testCaseEnded( TestCaseStats( testInfo,
6104 m_totals.testCases.failed++;
6105 testGroupEnded(
"", m_totals, 1, 1 );
6106 m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals,
false ) );
6111 bool aborting()
const {
6112 return m_totals.assertions.failed ==
static_cast<std::size_t
>( m_config->abortAfter() );
6117 void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
6118 TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
6119 SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
6120 m_reporter->sectionStarting( testCaseSection );
6121 Counts prevAssertions = m_totals.assertions;
6124 m_lastAssertionInfo =
AssertionInfo(
"TEST_CASE", testCaseInfo.lineInfo,
"", ResultDisposition::Normal );
6126 seedRng( *m_config );
6130 if( m_reporter->getPreferences().shouldRedirectStdOut ) {
6131 StreamRedirect coutRedir( Catch::cout(), redirectedCout );
6132 StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr );
6133 invokeActiveTestCase();
6136 invokeActiveTestCase();
6138 duration = timer.getElapsedSeconds();
6144 makeUnexpectedResultBuilder().useActiveException();
6146 m_testCaseTracker->close();
6147 handleUnfinishedSections();
6150 Counts assertions = m_totals.assertions - prevAssertions;
6151 bool missingAssertions = testForMissingAssertions( assertions );
6153 if( testCaseInfo.okToFail() ) {
6154 std::swap( assertions.failedButOk, assertions.failed );
6155 m_totals.assertions.failed -= assertions.failedButOk;
6156 m_totals.assertions.failedButOk += assertions.failedButOk;
6159 SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
6160 m_reporter->sectionEnded( testCaseSectionStats );
6163 void invokeActiveTestCase() {
6164 FatalConditionHandler fatalConditionHandler;
6165 m_activeTestCase->invoke();
6166 fatalConditionHandler.reset();
6172 return ResultBuilder( m_lastAssertionInfo.macroName.c_str(),
6173 m_lastAssertionInfo.lineInfo,
6174 m_lastAssertionInfo.capturedExpression.c_str(),
6175 m_lastAssertionInfo.resultDisposition );
6178 void handleUnfinishedSections() {
6181 for( std::vector<SectionEndInfo>::const_reverse_iterator it = m_unfinishedSections.rbegin(),
6182 itEnd = m_unfinishedSections.rend();
6185 sectionEnded( *it );
6186 m_unfinishedSections.clear();
6189 TestRunInfo m_runInfo;
6192 ITracker* m_testCaseTracker;
6193 ITracker* m_currentSectionTracker;
6199 std::vector<MessageInfo> m_messages;
6201 std::vector<SectionEndInfo> m_unfinishedSections;
6202 std::vector<ITracker*> m_activeSections;
6203 TrackerContext m_trackerContext;
6207 if(
IResultCapture* capture = getCurrentContext().getResultCapture() )
6210 throw std::logic_error(
"No result capture instance" );
6216 #define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED 6222 Version(
unsigned int _majorVersion,
6223 unsigned int _minorVersion,
6224 unsigned int _patchNumber,
6225 std::string
const& _branchName,
6226 unsigned int _buildNumber );
6228 unsigned int const majorVersion;
6229 unsigned int const minorVersion;
6230 unsigned int const patchNumber;
6233 std::string
const branchName;
6234 unsigned int const buildNumber;
6236 friend std::ostream& operator << ( std::ostream& os, Version
const& version );
6239 void operator=( Version
const& );
6242 extern Version libraryVersion;
6252 Ptr<IStreamingReporter> reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() );
6254 std::ostringstream oss;
6255 oss <<
"No reporter registered with name: '" << reporterName <<
"'";
6256 throw std::domain_error( oss.str() );
6262 std::vector<std::string> reporters = config->getReporterNames();
6263 if( reporters.empty() )
6264 reporters.push_back(
"console" );
6267 for( std::vector<std::string>::const_iterator it = reporters.begin(), itEnd = reporters.end();
6270 reporter = addReporter( reporter, createReporter( *it, config ) );
6274 IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners();
6275 for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end();
6278 reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) );
6287 reporter = addListeners( iconfig, reporter );
6289 RunContext context( iconfig, reporter );
6293 context.testGroupStarting( config->name(), 1, 1 );
6295 TestSpec testSpec = config->testSpec();
6296 if( !testSpec.hasFilters() )
6297 testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse(
"~[.]" ).testSpec();
6299 std::vector<TestCase>
const& allTestCases = getAllTestCasesSorted( *iconfig );
6300 for( std::vector<TestCase>::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end();
6303 if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) )
6304 totals += context.runTest( *it );
6306 reporter->skipTest( *it );
6309 context.testGroupEnded( iconfig->name(), totals, 1, 1 );
6313 void applyFilenamesAsTags( IConfig
const& config ) {
6314 std::vector<TestCase>
const& tests = getAllTestCasesSorted( config );
6315 for(std::size_t i = 0; i < tests.size(); ++i ) {
6317 std::set<std::string> tags = test.tags;
6319 std::string filename = test.lineInfo.file;
6320 std::string::size_type lastSlash = filename.find_last_of(
"\\/" );
6321 if( lastSlash != std::string::npos )
6322 filename = filename.substr( lastSlash+1 );
6324 std::string::size_type lastDot = filename.find_last_of(
"." );
6325 if( lastDot != std::string::npos )
6326 filename = filename.substr( 0, lastDot );
6328 tags.insert(
"#" + filename );
6329 setTags( test, tags );
6334 static bool alreadyInstantiated;
6338 struct OnUnusedOptions {
enum DoWhat { Ignore, Fail }; };
6341 : m_cli( makeCommandLineParser() ) {
6342 if( alreadyInstantiated ) {
6343 std::string msg =
"Only one instance of Catch::Session can ever be used";
6344 Catch::cerr() << msg << std::endl;
6345 throw std::logic_error( msg );
6347 alreadyInstantiated =
true;
6353 void showHelp( std::string
const& processName ) {
6354 Catch::cout() <<
"\nCatch v" << libraryVersion <<
"\n";
6356 m_cli.usage( Catch::cout(), processName );
6357 Catch::cout() <<
"For more detail usage please see the project docs\n" << std::endl;
6360 int applyCommandLine(
int argc,
char const*
const*
const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
6362 m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
6363 m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData );
6364 if( m_configData.showHelp )
6365 showHelp( m_configData.processName );
6368 catch( std::exception& ex ) {
6370 Colour colourGuard( Colour::Red );
6372 <<
"\nError(s) in input:\n" 6373 << Text( ex.what(), TextAttributes().setIndent(2) )
6376 m_cli.usage( Catch::cout(), m_configData.processName );
6377 return (std::numeric_limits<int>::max)();
6382 void useConfigData( ConfigData
const& _configData ) {
6383 m_configData = _configData;
6387 int run(
int argc,
char const*
const*
const argv ) {
6389 int returnCode = applyCommandLine( argc, argv );
6390 if( returnCode == 0 )
6396 if( m_configData.showHelp )
6403 seedRng( *m_config );
6405 if( m_configData.filenamesAsTags )
6406 applyFilenamesAsTags( *m_config );
6410 return static_cast<int>( *listed );
6412 return static_cast<int>( runTests( m_config ).assertions.failed );
6414 catch( std::exception& ex ) {
6415 Catch::cerr() << ex.what() << std::endl;
6416 return (std::numeric_limits<int>::max)();
6420 Clara::CommandLine<ConfigData>
const& cli()
const {
6423 std::vector<Clara::Parser::Token>
const& unusedTokens()
const {
6424 return m_unusedTokens;
6426 ConfigData& configData() {
6427 return m_configData;
6431 m_config =
new Config( m_configData );
6435 Clara::CommandLine<ConfigData> m_cli;
6436 std::vector<Clara::Parser::Token> m_unusedTokens;
6437 ConfigData m_configData;
6441 bool Session::alreadyInstantiated =
false;
6446 #define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED 6449 #define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED 6455 #include <algorithm> 6457 #ifdef CATCH_CPP14_OR_GREATER 6463 struct RandomNumberGenerator {
6464 typedef std::ptrdiff_t result_type;
6466 result_type operator()( result_type n )
const {
return std::rand() % n; }
6468 #ifdef CATCH_CPP14_OR_GREATER 6469 static constexpr result_type min() {
return 0; }
6470 static constexpr result_type max() {
return 1000000; }
6471 result_type operator()()
const {
return std::rand() % max(); }
6473 template<
typename V>
6474 static void shuffle( V& vector ) {
6475 RandomNumberGenerator rng;
6476 #ifdef CATCH_CPP14_OR_GREATER 6477 std::shuffle( vector.begin(), vector.end(), rng );
6479 std::random_shuffle( vector.begin(), vector.end(), rng );
6484 inline std::vector<TestCase> sortTests( IConfig
const& config, std::vector<TestCase>
const& unsortedTestCases ) {
6486 std::vector<TestCase> sorted = unsortedTestCases;
6488 switch( config.runOrder() ) {
6489 case RunTests::InLexicographicalOrder:
6490 std::sort( sorted.begin(), sorted.end() );
6492 case RunTests::InRandomOrder:
6495 RandomNumberGenerator::shuffle( sorted );
6498 case RunTests::InDeclarationOrder:
6504 bool matchTest(
TestCase const& testCase, TestSpec
const& testSpec, IConfig
const& config ) {
6505 return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
6508 void enforceNoDuplicateTestCases( std::vector<TestCase>
const& functions ) {
6509 std::set<TestCase> seenFunctions;
6510 for( std::vector<TestCase>::const_iterator it = functions.begin(), itEnd = functions.end();
6513 std::pair<std::set<TestCase>::const_iterator,
bool> prev = seenFunctions.insert( *it );
6514 if( !prev.second ) {
6515 std::ostringstream ss;
6517 ss << Colour( Colour::Red )
6518 <<
"error: TEST_CASE( \"" << it->name <<
"\" ) already defined.\n" 6519 <<
"\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo <<
"\n" 6520 <<
"\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl;
6522 throw std::runtime_error(ss.str());
6527 std::vector<TestCase> filterTests( std::vector<TestCase>
const& testCases, TestSpec
const& testSpec, IConfig
const& config ) {
6528 std::vector<TestCase> filtered;
6529 filtered.reserve( testCases.size() );
6530 for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();
6533 if( matchTest( *it, testSpec, config ) )
6534 filtered.push_back( *it );
6537 std::vector<TestCase>
const& getAllTestCasesSorted( IConfig
const& config ) {
6538 return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
6544 : m_currentSortOrder( RunTests::InDeclarationOrder ),
6547 virtual ~TestRegistry();
6549 virtual void registerTest(
TestCase const& testCase ) {
6550 std::string name = testCase.getTestCaseInfo().name;
6552 std::ostringstream oss;
6553 oss <<
"Anonymous test case " << ++m_unnamedCount;
6554 return registerTest( testCase.withName( oss.str() ) );
6556 m_functions.push_back( testCase );
6559 virtual std::vector<TestCase>
const& getAllTests()
const {
6562 virtual std::vector<TestCase>
const& getAllTestsSorted( IConfig
const& config )
const {
6563 if( m_sortedFunctions.empty() )
6564 enforceNoDuplicateTestCases( m_functions );
6566 if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
6567 m_sortedFunctions = sortTests( config, m_functions );
6568 m_currentSortOrder = config.runOrder();
6570 return m_sortedFunctions;
6574 std::vector<TestCase> m_functions;
6575 mutable RunTests::InWhatOrder m_currentSortOrder;
6576 mutable std::vector<TestCase> m_sortedFunctions;
6577 size_t m_unnamedCount;
6578 std::ios_base::Init m_ostreamInit;
6583 class FreeFunctionTestCase :
public SharedImpl<ITestCase> {
6586 FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
6588 virtual void invoke()
const {
6593 virtual ~FreeFunctionTestCase();
6598 inline std::string extractClassName( std::string
const& classOrQualifiedMethodName ) {
6599 std::string className = classOrQualifiedMethodName;
6600 if( startsWith( className,
"&" ) )
6602 std::size_t lastColons = className.rfind(
"::" );
6603 std::size_t penultimateColons = className.rfind(
"::", lastColons-1 );
6604 if( penultimateColons == std::string::npos )
6605 penultimateColons = 1;
6606 className = className.substr( penultimateColons, lastColons-penultimateColons );
6611 void registerTestCase
6613 char const* classOrQualifiedMethodName,
6617 getMutableRegistryHub().registerTest
6620 extractClassName( classOrQualifiedMethodName ),
6622 nameAndDesc.description,
6625 void registerTestCaseFunction
6626 ( TestFunction
function,
6629 registerTestCase(
new FreeFunctionTestCase(
function ),
"", nameAndDesc, lineInfo );
6635 ( TestFunction
function,
6638 registerTestCaseFunction(
function, lineInfo, nameAndDesc );
6641 AutoReg::~AutoReg() {}
6646 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED 6652 class ReporterRegistry :
public IReporterRegistry {
6656 virtual ~ReporterRegistry() CATCH_OVERRIDE {}
6658 virtual IStreamingReporter* create( std::string
const& name,
Ptr<IConfig const> const& config )
const CATCH_OVERRIDE {
6659 FactoryMap::const_iterator it = m_factories.find( name );
6660 if( it == m_factories.end() )
6662 return it->second->create( ReporterConfig( config ) );
6666 m_factories.insert( std::make_pair( name, factory ) );
6669 m_listeners.push_back( factory );
6672 virtual FactoryMap
const& getFactories()
const CATCH_OVERRIDE {
6675 virtual Listeners
const& getListeners()
const CATCH_OVERRIDE {
6680 FactoryMap m_factories;
6681 Listeners m_listeners;
6686 #define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED 6689 #import "Foundation/Foundation.h" 6696 ~ExceptionTranslatorRegistry() {
6697 deleteAll( m_translators );
6701 m_translators.push_back( translator );
6704 virtual std::string translateActiveException()
const {
6709 return tryTranslators();
6711 @catch (NSException *exception) {
6712 return Catch::toString( [exception description] );
6715 return tryTranslators();
6721 catch( std::exception& ex ) {
6724 catch( std::string& msg ) {
6727 catch(
const char* msg ) {
6731 return "Unknown exception";
6735 std::string tryTranslators()
const {
6736 if( m_translators.empty() )
6739 return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
6743 std::vector<const IExceptionTranslator*> m_translators;
6753 RegistryHub( RegistryHub
const& );
6754 void operator=( RegistryHub
const& );
6759 virtual IReporterRegistry
const& getReporterRegistry()
const CATCH_OVERRIDE {
6760 return m_reporterRegistry;
6763 return m_testCaseRegistry;
6766 return m_exceptionTranslatorRegistry;
6770 virtual void registerReporter( std::string
const& name,
Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
6771 m_reporterRegistry.registerReporter( name, factory );
6774 m_reporterRegistry.registerListener( factory );
6776 virtual void registerTest(
TestCase const& testInfo ) CATCH_OVERRIDE {
6777 m_testCaseRegistry.registerTest( testInfo );
6780 m_exceptionTranslatorRegistry.registerTranslator( translator );
6784 TestRegistry m_testCaseRegistry;
6785 ReporterRegistry m_reporterRegistry;
6786 ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
6790 inline RegistryHub*& getTheRegistryHub() {
6791 static RegistryHub* theRegistryHub = CATCH_NULL;
6792 if( !theRegistryHub )
6793 theRegistryHub =
new RegistryHub();
6794 return theRegistryHub;
6799 return *getTheRegistryHub();
6802 return *getTheRegistryHub();
6805 delete getTheRegistryHub();
6806 getTheRegistryHub() = CATCH_NULL;
6809 std::string translateActiveException() {
6810 return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
6816 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED 6822 NotImplementedException::NotImplementedException(
SourceLineInfo const& lineInfo )
6823 : m_lineInfo( lineInfo ) {
6824 std::ostringstream oss;
6825 oss << lineInfo <<
": function ";
6826 oss <<
"not implemented";
6830 const char* NotImplementedException::what()
const CATCH_NOEXCEPT {
6831 return m_what.c_str();
6837 #define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED 6840 #define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED 6842 #include <stdexcept> 6848 template<
typename WriterF,
size_t bufferSize=256>
6849 class StreamBufImpl :
public StreamBufBase {
6850 char data[bufferSize];
6855 setp( data, data +
sizeof(data) );
6858 ~StreamBufImpl() CATCH_NOEXCEPT {
6863 int overflow(
int c ) {
6867 if( pbase() == epptr() )
6868 m_writer( std::string( 1, static_cast<char>( c ) ) );
6870 sputc( static_cast<char>( c ) );
6876 if( pbase() != pptr() ) {
6877 m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
6878 setp( pbase(), epptr() );
6886 FileStream::FileStream( std::string
const& filename ) {
6887 m_ofs.open( filename.c_str() );
6888 if( m_ofs.fail() ) {
6889 std::ostringstream oss;
6890 oss <<
"Unable to open file: '" << filename <<
"'";
6891 throw std::domain_error( oss.str() );
6895 std::ostream& FileStream::stream()
const {
6899 struct OutputDebugWriter {
6901 void operator()( std::string
const&str ) {
6902 writeToDebugConsole( str );
6906 DebugOutStream::DebugOutStream()
6907 : m_streamBuf(
new StreamBufImpl<OutputDebugWriter>() ),
6908 m_os( m_streamBuf.get() )
6911 std::ostream& DebugOutStream::stream()
const {
6917 CoutStream::CoutStream()
6918 : m_os( Catch::cout().rdbuf() )
6921 std::ostream& CoutStream::stream()
const {
6925 #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions 6926 std::ostream& cout() {
6929 std::ostream& cerr() {
6939 Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {}
6940 Context( Context
const& );
6941 void operator=( Context
const& );
6945 return m_resultCapture;
6947 virtual IRunner* getRunner() {
6950 virtual size_t getGeneratorIndex( std::string
const& fileInfo,
size_t totalSize ) {
6951 return getGeneratorsForCurrentTest()
6952 .getGeneratorInfo( fileInfo, totalSize )
6955 virtual bool advanceGeneratorsForCurrentTest() {
6957 return generators && generators->moveNext();
6966 m_resultCapture = resultCapture;
6968 virtual void setRunner(
IRunner* runner ) {
6979 std::string testName = getResultCapture()->getCurrentTestName();
6981 std::map<std::string, IGeneratorsForTest*>::const_iterator it =
6982 m_generatorsByTestName.find( testName );
6983 return it != m_generatorsByTestName.end()
6991 std::string testName = getResultCapture()->getCurrentTestName();
6992 generators = createGeneratorsForTest();
6993 m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
7002 std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
7006 Context* currentContext = CATCH_NULL;
7009 if( !currentContext )
7010 currentContext =
new Context();
7011 return *currentContext;
7014 return getCurrentMutableContext();
7017 void cleanUpContext() {
7018 delete currentContext;
7019 currentContext = CATCH_NULL;
7024 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED 7029 struct IColourImpl {
7030 virtual ~IColourImpl() {}
7031 virtual void use( Colour::Code _colourCode ) = 0;
7034 struct NoColourImpl : IColourImpl {
7035 void use( Colour::Code ) {}
7037 static IColourImpl* instance() {
7038 static NoColourImpl s_instance;
7046 #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI ) 7047 # ifdef CATCH_PLATFORM_WINDOWS 7048 # define CATCH_CONFIG_COLOUR_WINDOWS 7050 # define CATCH_CONFIG_COLOUR_ANSI 7054 #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) 7063 #include <windows.h> 7069 class Win32ColourImpl :
public IColourImpl {
7071 Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
7073 CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
7074 GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
7075 originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
7076 originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
7079 virtual void use( Colour::Code _colourCode ) {
7080 switch( _colourCode ) {
7081 case Colour::None:
return setTextAttribute( originalForegroundAttributes );
7082 case Colour::White:
return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
7083 case Colour::Red:
return setTextAttribute( FOREGROUND_RED );
7084 case Colour::Green:
return setTextAttribute( FOREGROUND_GREEN );
7085 case Colour::Blue:
return setTextAttribute( FOREGROUND_BLUE );
7086 case Colour::Cyan:
return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
7087 case Colour::Yellow:
return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
7088 case Colour::Grey:
return setTextAttribute( 0 );
7090 case Colour::LightGrey:
return setTextAttribute( FOREGROUND_INTENSITY );
7091 case Colour::BrightRed:
return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
7092 case Colour::BrightGreen:
return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
7093 case Colour::BrightWhite:
return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
7095 case Colour::Bright:
throw std::logic_error(
"not a colour" );
7100 void setTextAttribute( WORD _textAttribute ) {
7101 SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
7103 HANDLE stdoutHandle;
7104 WORD originalForegroundAttributes;
7105 WORD originalBackgroundAttributes;
7108 IColourImpl* platformColourInstance() {
7109 static Win32ColourImpl s_instance;
7112 UseColour::YesOrNo colourMode = config
7113 ? config->useColour()
7115 if( colourMode == UseColour::Auto )
7116 colourMode = !isDebuggerActive()
7119 return colourMode == UseColour::Yes
7121 : NoColourImpl::instance();
7127 #elif defined( CATCH_CONFIG_COLOUR_ANSI ) 7138 class PosixColourImpl :
public IColourImpl {
7140 virtual void use( Colour::Code _colourCode ) {
7141 switch( _colourCode ) {
7143 case Colour::White:
return setColour(
"[0m" );
7144 case Colour::Red:
return setColour(
"[0;31m" );
7145 case Colour::Green:
return setColour(
"[0;32m" );
7146 case Colour::Blue:
return setColour(
"[0:34m" );
7147 case Colour::Cyan:
return setColour(
"[0;36m" );
7148 case Colour::Yellow:
return setColour(
"[0;33m" );
7149 case Colour::Grey:
return setColour(
"[1;30m" );
7151 case Colour::LightGrey:
return setColour(
"[0;37m" );
7152 case Colour::BrightRed:
return setColour(
"[1;31m" );
7153 case Colour::BrightGreen:
return setColour(
"[1;32m" );
7154 case Colour::BrightWhite:
return setColour(
"[1;37m" );
7156 case Colour::Bright:
throw std::logic_error(
"not a colour" );
7159 static IColourImpl* instance() {
7160 static PosixColourImpl s_instance;
7165 void setColour(
const char* _escapeCode ) {
7166 Catch::cout() <<
'\033' << _escapeCode;
7170 IColourImpl* platformColourInstance() {
7172 UseColour::YesOrNo colourMode = config
7173 ? config->useColour()
7175 if( colourMode == UseColour::Auto )
7176 colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) )
7179 return colourMode == UseColour::Yes
7180 ? PosixColourImpl::instance()
7181 : NoColourImpl::instance();
7187 #else // not Windows or ANSI 7191 static IColourImpl* platformColourInstance() {
return NoColourImpl::instance(); }
7195 #endif // Windows/ ANSI/ None 7199 Colour::Colour( Code _colourCode ) : m_moved(
false ) { use( _colourCode ); }
7200 Colour::Colour( Colour
const& _other ) : m_moved(
false ) {
const_cast<Colour&
>( _other ).m_moved =
true; }
7201 Colour::~Colour(){
if( !m_moved ) use( None ); }
7203 void Colour::use( Code _colourCode ) {
7204 static IColourImpl* impl = platformColourInstance();
7205 impl->use( _colourCode );
7211 #define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED 7221 GeneratorInfo( std::size_t
size )
7227 if( ++m_currentIndex == m_size ) {
7234 std::size_t getCurrentIndex()
const {
7235 return m_currentIndex;
7239 std::size_t m_currentIndex;
7247 ~GeneratorsForTest() {
7248 deleteAll( m_generatorsInOrder );
7252 std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
7253 if( it == m_generatorsByName.end() ) {
7255 m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
7256 m_generatorsInOrder.push_back( info );
7263 std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
7264 std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
7265 for(; it != itEnd; ++it ) {
7266 if( (*it)->moveNext() )
7273 std::map<std::string, IGeneratorInfo*> m_generatorsByName;
7274 std::vector<IGeneratorInfo*> m_generatorsInOrder;
7279 return new GeneratorsForTest();
7285 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED 7289 AssertionInfo::AssertionInfo( std::string
const& _macroName,
7291 std::string
const& _capturedExpression,
7292 ResultDisposition::Flags _resultDisposition )
7293 : macroName( _macroName ),
7294 lineInfo( _lineInfo ),
7295 capturedExpression( _capturedExpression ),
7296 resultDisposition( _resultDisposition )
7299 AssertionResult::AssertionResult() {}
7303 m_resultData( data )
7306 AssertionResult::~AssertionResult() {}
7309 bool AssertionResult::succeeded()
const {
7310 return Catch::isOk( m_resultData.resultType );
7314 bool AssertionResult::isOk()
const {
7315 return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
7318 ResultWas::OfType AssertionResult::getResultType()
const {
7319 return m_resultData.resultType;
7322 bool AssertionResult::hasExpression()
const {
7323 return !m_info.capturedExpression.empty();
7326 bool AssertionResult::hasMessage()
const {
7327 return !m_resultData.message.empty();
7330 std::string AssertionResult::getExpression()
const {
7331 if( isFalseTest( m_info.resultDisposition ) )
7332 return "!" + m_info.capturedExpression;
7334 return m_info.capturedExpression;
7336 std::string AssertionResult::getExpressionInMacro()
const {
7337 if( m_info.macroName.empty() )
7338 return m_info.capturedExpression;
7340 return m_info.macroName +
"( " + m_info.capturedExpression +
" )";
7343 bool AssertionResult::hasExpandedExpression()
const {
7344 return hasExpression() && getExpandedExpression() != getExpression();
7347 std::string AssertionResult::getExpandedExpression()
const {
7348 return m_resultData.reconstructedExpression;
7351 std::string AssertionResult::getMessage()
const {
7352 return m_resultData.message;
7355 return m_info.lineInfo;
7358 std::string AssertionResult::getTestMacroName()
const {
7359 return m_info.macroName;
7365 #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED 7369 inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string
const& tag ) {
7370 if( startsWith( tag,
"." ) ||
7373 return TestCaseInfo::IsHidden;
7374 else if( tag ==
"!throws" )
7375 return TestCaseInfo::Throws;
7376 else if( tag ==
"!shouldfail" )
7377 return TestCaseInfo::ShouldFail;
7378 else if( tag ==
"!mayfail" )
7379 return TestCaseInfo::MayFail;
7381 return TestCaseInfo::None;
7383 inline bool isReservedTag( std::string
const& tag ) {
7384 return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] );
7386 inline void enforceNotReservedTag( std::string
const& tag,
SourceLineInfo const& _lineInfo ) {
7387 if( isReservedTag( tag ) ) {
7389 Colour colourGuard( Colour::Red );
7391 <<
"Tag name [" << tag <<
"] not allowed.\n" 7392 <<
"Tag names starting with non alpha-numeric characters are reserved\n";
7395 Colour colourGuard( Colour::FileName );
7396 Catch::cerr() << _lineInfo << std::endl;
7403 std::string
const& _className,
7404 std::string
const& _name,
7405 std::string
const& _descOrTags,
7408 bool isHidden( startsWith( _name,
"./" ) );
7411 std::set<std::string> tags;
7412 std::string desc, tag;
7414 for( std::size_t i = 0; i < _descOrTags.size(); ++i ) {
7415 char c = _descOrTags[i];
7424 TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
7425 if( prop == TestCaseInfo::IsHidden )
7427 else if( prop == TestCaseInfo::None )
7428 enforceNotReservedTag( tag, _lineInfo );
7439 tags.insert(
"hide" );
7443 TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
7444 return TestCase( _testCase, info );
7447 void setTags(
TestCaseInfo& testCaseInfo, std::set<std::string>
const& tags )
7449 testCaseInfo.tags = tags;
7450 testCaseInfo.lcaseTags.clear();
7452 std::ostringstream oss;
7453 for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) {
7454 oss <<
"[" << *it <<
"]";
7455 std::string lcaseTag = toLower( *it );
7456 testCaseInfo.properties =
static_cast<TestCaseInfo::SpecialProperties
>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
7457 testCaseInfo.lcaseTags.insert( lcaseTag );
7459 testCaseInfo.tagsAsString = oss.str();
7462 TestCaseInfo::TestCaseInfo( std::string
const& _name,
7463 std::string
const& _className,
7464 std::string
const& _description,
7465 std::set<std::string>
const& _tags,
7468 className( _className ),
7469 description( _description ),
7470 lineInfo( _lineInfo ),
7473 setTags( *
this, _tags );
7476 TestCaseInfo::TestCaseInfo(
TestCaseInfo const& other )
7477 : name( other.name ),
7478 className( other.className ),
7479 description( other.description ),
7481 lcaseTags( other.lcaseTags ),
7482 tagsAsString( other.tagsAsString ),
7483 lineInfo( other.lineInfo ),
7484 properties( other.properties )
7487 bool TestCaseInfo::isHidden()
const {
7488 return ( properties & IsHidden ) != 0;
7490 bool TestCaseInfo::throws()
const {
7491 return ( properties & Throws ) != 0;
7493 bool TestCaseInfo::okToFail()
const {
7494 return ( properties & (ShouldFail | MayFail ) ) != 0;
7496 bool TestCaseInfo::expectedToFail()
const {
7497 return ( properties & (ShouldFail ) ) != 0;
7502 TestCase::TestCase(
TestCase const& other )
7507 TestCase TestCase::withName( std::string
const& _newName )
const {
7509 other.name = _newName;
7513 void TestCase::swap(
TestCase& other ) {
7514 test.swap( other.test );
7515 name.swap( other.name );
7516 className.swap( other.className );
7517 description.swap( other.description );
7518 tags.swap( other.tags );
7519 lcaseTags.swap( other.lcaseTags );
7520 tagsAsString.swap( other.tagsAsString );
7521 std::swap( TestCaseInfo::properties, static_cast<TestCaseInfo&>( other ).properties );
7522 std::swap( lineInfo, other.lineInfo );
7525 void TestCase::invoke()
const {
7529 bool TestCase::operator == (
TestCase const& other )
const {
7530 return test.get() == other.test.get() &&
7531 name == other.name &&
7532 className == other.className;
7535 bool TestCase::operator < (
TestCase const& other )
const {
7536 return name < other.name;
7552 #define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED 7557 (
unsigned int _majorVersion,
7558 unsigned int _minorVersion,
7559 unsigned int _patchNumber,
7560 std::string
const& _branchName,
7561 unsigned int _buildNumber )
7562 : majorVersion( _majorVersion ),
7563 minorVersion( _minorVersion ),
7564 patchNumber( _patchNumber ),
7565 branchName( _branchName ),
7566 buildNumber( _buildNumber )
7569 std::ostream& operator << ( std::ostream& os, Version
const& version ) {
7570 os << version.majorVersion <<
"." 7571 << version.minorVersion <<
"." 7572 << version.patchNumber;
7574 if( !version.branchName.empty() ) {
7575 os <<
"-" << version.branchName
7576 <<
"." << version.buildNumber;
7581 Version libraryVersion( 1, 5, 8,
"", 0 );
7586 #define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED 7590 MessageInfo::MessageInfo( std::string
const& _macroName,
7592 ResultWas::OfType _type )
7593 : macroName( _macroName ),
7594 lineInfo( _lineInfo ),
7596 sequence( ++globalCount )
7600 unsigned int MessageInfo::globalCount = 0;
7605 : m_info( builder.m_info )
7607 m_info.message = builder.m_stream.str();
7608 getResultCapture().pushScopedMessage( m_info );
7611 : m_info( other.m_info )
7614 ScopedMessage::~ScopedMessage() {
7615 getResultCapture().popScopedMessage( m_info );
7621 #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED 7624 #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED 7630 virtual ~IReporter();
7632 virtual bool shouldRedirectStdout()
const = 0;
7634 virtual void StartTesting() = 0;
7635 virtual void EndTesting(
Totals const& totals ) = 0;
7636 virtual void StartGroup( std::string
const& groupName ) = 0;
7637 virtual void EndGroup( std::string
const& groupName,
Totals const& totals ) = 0;
7638 virtual void StartTestCase(
TestCaseInfo const& testInfo ) = 0;
7639 virtual void EndTestCase(
TestCaseInfo const& testInfo,
Totals const& totals, std::string
const& stdOut, std::string
const& stdErr ) = 0;
7640 virtual void StartSection( std::string
const& sectionName, std::string
const& description ) = 0;
7641 virtual void EndSection( std::string
const& sectionName,
Counts const& assertions ) = 0;
7642 virtual void NoAssertionsInSection( std::string
const& sectionName ) = 0;
7643 virtual void NoAssertionsInTestCase( std::string
const& testName ) = 0;
7644 virtual void Aborted() = 0;
7648 class LegacyReporterAdapter :
public SharedImpl<IStreamingReporter>
7652 virtual ~LegacyReporterAdapter();
7654 virtual ReporterPreferences getPreferences()
const;
7655 virtual void noMatchingTestCases( std::string
const& );
7656 virtual void testRunStarting( TestRunInfo
const& );
7657 virtual void testGroupStarting( GroupInfo
const& groupInfo );
7658 virtual void testCaseStarting(
TestCaseInfo const& testInfo );
7659 virtual void sectionStarting(
SectionInfo const& sectionInfo );
7661 virtual bool assertionEnded( AssertionStats
const& assertionStats );
7662 virtual void sectionEnded( SectionStats
const& sectionStats );
7663 virtual void testCaseEnded( TestCaseStats
const& testCaseStats );
7664 virtual void testGroupEnded( TestGroupStats
const& testGroupStats );
7665 virtual void testRunEnded( TestRunStats
const& testRunStats );
7675 LegacyReporterAdapter::LegacyReporterAdapter(
Ptr<IReporter> const& legacyReporter )
7676 : m_legacyReporter( legacyReporter )
7678 LegacyReporterAdapter::~LegacyReporterAdapter() {}
7680 ReporterPreferences LegacyReporterAdapter::getPreferences()
const {
7681 ReporterPreferences prefs;
7682 prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();
7686 void LegacyReporterAdapter::noMatchingTestCases( std::string
const& ) {}
7687 void LegacyReporterAdapter::testRunStarting( TestRunInfo
const& ) {
7688 m_legacyReporter->StartTesting();
7690 void LegacyReporterAdapter::testGroupStarting( GroupInfo
const& groupInfo ) {
7691 m_legacyReporter->StartGroup( groupInfo.name );
7693 void LegacyReporterAdapter::testCaseStarting(
TestCaseInfo const& testInfo ) {
7694 m_legacyReporter->StartTestCase( testInfo );
7696 void LegacyReporterAdapter::sectionStarting(
SectionInfo const& sectionInfo ) {
7697 m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description );
7699 void LegacyReporterAdapter::assertionStarting(
AssertionInfo const& ) {
7703 bool LegacyReporterAdapter::assertionEnded( AssertionStats
const& assertionStats ) {
7704 if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
7705 for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
7708 if( it->type == ResultWas::Info ) {
7709 ResultBuilder rb( it->macroName.c_str(), it->lineInfo,
"", ResultDisposition::Normal );
7711 rb.setResultType( ResultWas::Info );
7713 m_legacyReporter->Result( result );
7717 m_legacyReporter->Result( assertionStats.assertionResult );
7720 void LegacyReporterAdapter::sectionEnded( SectionStats
const& sectionStats ) {
7721 if( sectionStats.missingAssertions )
7722 m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );
7723 m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );
7725 void LegacyReporterAdapter::testCaseEnded( TestCaseStats
const& testCaseStats ) {
7726 m_legacyReporter->EndTestCase
7727 ( testCaseStats.testInfo,
7728 testCaseStats.totals,
7729 testCaseStats.stdOut,
7730 testCaseStats.stdErr );
7732 void LegacyReporterAdapter::testGroupEnded( TestGroupStats
const& testGroupStats ) {
7733 if( testGroupStats.aborting )
7734 m_legacyReporter->Aborted();
7735 m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );
7737 void LegacyReporterAdapter::testRunEnded( TestRunStats
const& testRunStats ) {
7738 m_legacyReporter->EndTesting( testRunStats.totals );
7740 void LegacyReporterAdapter::skipTest(
TestCaseInfo const& ) {
7747 #pragma clang diagnostic push 7748 #pragma clang diagnostic ignored "-Wc++11-long-long" 7751 #ifdef CATCH_PLATFORM_WINDOWS 7752 #include <windows.h> 7754 #include <sys/time.h> 7760 #ifdef CATCH_PLATFORM_WINDOWS 7761 uint64_t getCurrentTicks() {
7762 static uint64_t hz=0, hzo=0;
7764 QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );
7765 QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );
7768 QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );
7769 return ((t-hzo)*1000000)/hz;
7772 uint64_t getCurrentTicks() {
7774 gettimeofday(&t,CATCH_NULL);
7775 return static_cast<uint64_t
>( t.tv_sec ) * 1000000ull + static_cast<uint64_t>( t.tv_usec );
7780 void Timer::start() {
7781 m_ticks = getCurrentTicks();
7783 unsigned int Timer::getElapsedMicroseconds()
const {
7784 return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
7786 unsigned int Timer::getElapsedMilliseconds()
const {
7787 return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
7789 double Timer::getElapsedSeconds()
const {
7790 return getElapsedMicroseconds()/1000000.0;
7796 #pragma clang diagnostic pop 7799 #define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED 7803 bool startsWith( std::string
const& s, std::string
const& prefix ) {
7804 return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
7806 bool endsWith( std::string
const& s, std::string
const& suffix ) {
7807 return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
7809 bool contains( std::string
const& s, std::string
const& infix ) {
7810 return s.find( infix ) != std::string::npos;
7812 char toLowerCh(
char c) {
7813 return static_cast<char>( ::tolower( c ) );
7815 void toLowerInPlace( std::string& s ) {
7818 std::string toLower( std::string
const& s ) {
7820 toLowerInPlace( lc );
7823 std::string trim( std::string
const& str ) {
7824 static char const* whitespaceChars =
"\n\r\t ";
7825 std::string::size_type start = str.find_first_not_of( whitespaceChars );
7826 std::string::size_type end = str.find_last_not_of( whitespaceChars );
7828 return start != std::string::npos ? str.substr( start, 1+end-start ) :
"";
7831 bool replaceInPlace( std::string& str, std::string
const& replaceThis, std::string
const& withThis ) {
7832 bool replaced =
false;
7833 std::size_t i = str.find( replaceThis );
7834 while( i != std::string::npos ) {
7836 str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
7837 if( i < str.size()-withThis.size() )
7838 i = str.find( replaceThis, i+withThis.size() );
7840 i = std::string::npos;
7845 pluralise::pluralise( std::size_t count, std::string
const& label )
7850 std::ostream& operator << ( std::ostream& os,
pluralise const& pluraliser ) {
7851 os << pluraliser.m_count <<
" " << pluraliser.m_label;
7852 if( pluraliser.m_count != 1 )
7857 SourceLineInfo::SourceLineInfo() : line( 0 ){}
7858 SourceLineInfo::SourceLineInfo(
char const* _file, std::size_t _line )
7863 : file( other.file ),
7866 bool SourceLineInfo::empty()
const {
7867 return file.empty();
7869 bool SourceLineInfo::operator == (
SourceLineInfo const& other )
const {
7870 return line == other.line && file == other.file;
7872 bool SourceLineInfo::operator < (
SourceLineInfo const& other )
const {
7873 return line < other.line || ( line == other.line && file < other.file );
7876 void seedRng( IConfig
const& config ) {
7877 if( config.rngSeed() != 0 )
7878 std::srand( config.rngSeed() );
7880 unsigned int rngSeed() {
7881 return getCurrentContext().getConfig()->rngSeed();
7884 std::ostream& operator << ( std::ostream& os,
SourceLineInfo const& info ) {
7886 os << info.file <<
"(" << info.line <<
")";
7888 os << info.file <<
":" << info.line;
7893 void throwLogicError( std::string
const& message,
SourceLineInfo const& locationInfo ) {
7894 std::ostringstream oss;
7895 oss << locationInfo <<
": Internal Catch error: '" << message <<
"'";
7897 throw std::logic_error( oss.str() );
7902 #define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED 7906 SectionInfo::SectionInfo
7908 std::string
const& _name,
7909 std::string
const& _description )
7911 description( _description ),
7912 lineInfo( _lineInfo )
7917 m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
7922 Section::~Section() {
7923 if( m_sectionIncluded ) {
7924 SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
7925 if( std::uncaught_exception() )
7926 getResultCapture().sectionEndedEarly( endInfo );
7928 getResultCapture().sectionEnded( endInfo );
7933 Section::operator bool()
const {
7934 return m_sectionIncluded;
7940 #define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED 7944 #ifdef CATCH_PLATFORM_MAC 7947 #include <stdbool.h> 7948 #include <sys/types.h> 7950 #include <sys/sysctl.h> 7959 bool isDebuggerActive(){
7962 struct kinfo_proc info;
7968 info.kp_proc.p_flag = 0;
7975 mib[2] = KERN_PROC_PID;
7980 size =
sizeof(info);
7981 if( sysctl(mib,
sizeof(mib) /
sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) {
7982 Catch::cerr() <<
"\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
7988 return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
7992 #elif defined(_MSC_VER) 7993 extern "C" __declspec(dllimport)
int __stdcall IsDebuggerPresent();
7995 bool isDebuggerActive() {
7996 return IsDebuggerPresent() != 0;
7999 #elif defined(__MINGW32__) 8000 extern "C" __declspec(dllimport)
int __stdcall IsDebuggerPresent();
8002 bool isDebuggerActive() {
8003 return IsDebuggerPresent() != 0;
8008 inline bool isDebuggerActive() {
return false; }
8012 #ifdef CATCH_PLATFORM_WINDOWS 8013 extern "C" __declspec(dllimport)
void __stdcall OutputDebugStringA(
const char* );
8015 void writeToDebugConsole( std::string
const& text ) {
8016 ::OutputDebugStringA( text.c_str() );
8021 void writeToDebugConsole( std::string
const& text ) {
8023 Catch::cout() << text;
8029 #define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED 8035 const std::string unprintableString =
"{?}";
8038 const int hexThreshold = 255;
8041 enum Arch { Big, Little };
8043 static Arch which() {
8046 char asChar[sizeof (int)];
8050 return ( u.asChar[
sizeof(
int)-1] == 1 ) ? Big : Little;
8055 std::string rawMemoryToString(
const void *
object, std::size_t
size )
8058 int i = 0, end =
static_cast<int>(
size ), inc = 1;
8059 if( Endianness::which() == Endianness::Little ) {
8064 unsigned char const *bytes =
static_cast<unsigned char const *
>(object);
8065 std::ostringstream os;
8066 os <<
"0x" << std::setfill(
'0') << std::hex;
8067 for( ; i != end; i += inc )
8068 os << std::setw(2) <<
static_cast<unsigned>(bytes[i]);
8073 std::string toString( std::string
const& value ) {
8074 std::string s = value;
8075 if( getCurrentContext().getConfig()->showInvisibles() ) {
8076 for(
size_t i = 0; i < s.size(); ++i ) {
8079 case '\n': subs =
"\\n";
break;
8080 case '\t': subs =
"\\t";
break;
8083 if( !subs.empty() ) {
8084 s = s.substr( 0, i ) + subs + s.substr( i+1 );
8089 return "\"" + s +
"\"";
8091 std::string toString( std::wstring
const& value ) {
8094 s.reserve( value.size() );
8095 for(
size_t i = 0; i < value.size(); ++i )
8096 s += value[i] <= 0xff ? static_cast<char>( value[i] ) :
'?';
8097 return Catch::toString( s );
8100 std::string toString(
const char*
const value ) {
8101 return value ? Catch::toString( std::string( value ) ) : std::string(
"{null string}" );
8104 std::string toString(
char*
const value ) {
8105 return Catch::toString( static_cast<const char*>( value ) );
8108 std::string toString(
const wchar_t*
const value )
8110 return value ? Catch::toString( std::wstring(value) ) : std::string(
"{null string}" );
8113 std::string toString(
wchar_t*
const value )
8115 return Catch::toString( static_cast<const wchar_t*>( value ) );
8118 std::string toString(
int value ) {
8119 std::ostringstream oss;
8121 if( value > Detail::hexThreshold )
8122 oss <<
" (0x" << std::hex << value <<
")";
8126 std::string toString(
unsigned long value ) {
8127 std::ostringstream oss;
8129 if( value > Detail::hexThreshold )
8130 oss <<
" (0x" << std::hex << value <<
")";
8134 std::string toString(
unsigned int value ) {
8135 return Catch::toString( static_cast<unsigned long>( value ) );
8138 template<
typename T>
8139 std::string fpToString(
T value,
int precision ) {
8140 std::ostringstream oss;
8141 oss << std::setprecision( precision )
8144 std::string d = oss.str();
8145 std::size_t i = d.find_last_not_of(
'0' );
8146 if( i != std::string::npos && i != d.size()-1 ) {
8149 d = d.substr( 0, i+1 );
8154 std::string toString(
const double value ) {
8155 return fpToString( value, 10 );
8157 std::string toString(
const float value ) {
8158 return fpToString( value, 5 ) +
"f";
8161 std::string toString(
bool value ) {
8162 return value ?
"true" :
"false";
8165 std::string toString(
char value ) {
8167 ? toString( static_cast<unsigned int>( value ) )
8171 std::string toString(
signed char value ) {
8172 return toString( static_cast<char>( value ) );
8175 std::string toString(
unsigned char value ) {
8176 return toString( static_cast<char>( value ) );
8179 #ifdef CATCH_CONFIG_CPP11_LONG_LONG 8180 std::string toString(
long long value ) {
8181 std::ostringstream oss;
8183 if( value > Detail::hexThreshold )
8184 oss <<
" (0x" << std::hex << value <<
")";
8187 std::string toString(
unsigned long long value ) {
8188 std::ostringstream oss;
8190 if( value > Detail::hexThreshold )
8191 oss <<
" (0x" << std::hex << value <<
")";
8196 #ifdef CATCH_CONFIG_CPP11_NULLPTR 8197 std::string toString( std::nullptr_t ) {
8203 std::string toString( NSString
const *
const& nsstring ) {
8206 return "@" + toString([nsstring UTF8String]);
8208 std::string toString( NSString * CATCH_ARC_STRONG
const& nsstring ) {
8211 return "@" + toString([nsstring UTF8String]);
8213 std::string toString( NSObject*
const& nsObject ) {
8214 return toString( [nsObject description] );
8221 #define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED 8225 std::string capturedExpressionWithSecondArgument( std::string
const& capturedExpression, std::string
const& secondArg ) {
8226 return secondArg.empty() || secondArg ==
"\"\"" 8227 ? capturedExpression
8228 : capturedExpression +
", " + secondArg;
8230 ResultBuilder::ResultBuilder(
char const* macroName,
8232 char const* capturedExpression,
8233 ResultDisposition::Flags resultDisposition,
8234 char const* secondArg )
8235 : m_assertionInfo( macroName, lineInfo, capturedExpressionWithSecondArgument( capturedExpression, secondArg ), resultDisposition ),
8236 m_shouldDebugBreak(
false ),
8237 m_shouldThrow(
false )
8240 ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) {
8241 m_data.resultType = result;
8244 ResultBuilder& ResultBuilder::setResultType(
bool result ) {
8245 m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
8248 ResultBuilder& ResultBuilder::setLhs( std::string
const& lhs ) {
8249 m_exprComponents.lhs = lhs;
8252 ResultBuilder& ResultBuilder::setRhs( std::string
const& rhs ) {
8253 m_exprComponents.rhs = rhs;
8256 ResultBuilder& ResultBuilder::setOp( std::string
const& op ) {
8257 m_exprComponents.op = op;
8261 void ResultBuilder::endExpression() {
8262 m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition );
8263 captureExpression();
8266 void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {
8267 m_assertionInfo.resultDisposition = resultDisposition;
8268 m_stream.oss << Catch::translateActiveException();
8269 captureResult( ResultWas::ThrewException );
8272 void ResultBuilder::captureResult( ResultWas::OfType resultType ) {
8273 setResultType( resultType );
8274 captureExpression();
8276 void ResultBuilder::captureExpectedException( std::string
const& expectedMessage ) {
8277 if( expectedMessage.empty() )
8280 captureExpectedException( Matchers::Equals( expectedMessage ) );
8285 assert( m_exprComponents.testFalse ==
false );
8287 data.resultType = ResultWas::Ok;
8288 data.reconstructedExpression = m_assertionInfo.capturedExpression;
8290 std::string actualMessage = Catch::translateActiveException();
8291 if( !matcher.match( actualMessage ) ) {
8292 data.resultType = ResultWas::ExpressionFailed;
8293 data.reconstructedExpression = actualMessage;
8296 handleResult( result );
8299 void ResultBuilder::captureExpression() {
8301 handleResult( result );
8305 getResultCapture().assertionEnded( result );
8307 if( !result.isOk() ) {
8308 if( getCurrentContext().getConfig()->shouldDebugBreak() )
8309 m_shouldDebugBreak =
true;
8310 if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) )
8311 m_shouldThrow =
true;
8314 void ResultBuilder::react() {
8319 bool ResultBuilder::shouldDebugBreak()
const {
return m_shouldDebugBreak; }
8320 bool ResultBuilder::allowThrows()
const {
return getCurrentContext().getConfig()->allowThrows(); }
8324 assert( m_data.resultType != ResultWas::Unknown );
8329 if( m_exprComponents.testFalse ) {
8330 if( data.resultType == ResultWas::Ok )
8331 data.resultType = ResultWas::ExpressionFailed;
8332 else if( data.resultType == ResultWas::ExpressionFailed )
8333 data.resultType = ResultWas::Ok;
8336 data.message = m_stream.oss.str();
8337 data.reconstructedExpression = reconstructExpression();
8338 if( m_exprComponents.testFalse ) {
8339 if( m_exprComponents.op ==
"" )
8340 data.reconstructedExpression =
"!" + data.reconstructedExpression;
8342 data.reconstructedExpression =
"!(" + data.reconstructedExpression +
")";
8346 std::string ResultBuilder::reconstructExpression()
const {
8347 if( m_exprComponents.op ==
"" )
8348 return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.op + m_exprComponents.lhs;
8349 else if( m_exprComponents.op ==
"matches" )
8350 return m_exprComponents.lhs +
" " + m_exprComponents.rhs;
8351 else if( m_exprComponents.op !=
"!" ) {
8352 if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 &&
8353 m_exprComponents.lhs.find(
"\n") == std::string::npos &&
8354 m_exprComponents.rhs.find(
"\n") == std::string::npos )
8355 return m_exprComponents.lhs +
" " + m_exprComponents.op +
" " + m_exprComponents.rhs;
8357 return m_exprComponents.lhs +
"\n" + m_exprComponents.op +
"\n" + m_exprComponents.rhs;
8360 return "{can't expand - use " + m_assertionInfo.macroName +
"_FALSE( " + m_assertionInfo.capturedExpression.substr(1) +
" ) instead of " + m_assertionInfo.macroName +
"( " + m_assertionInfo.capturedExpression +
" ) for better diagnostics}";
8366 #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED 8369 #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED 8377 virtual ~TagAliasRegistry();
8379 virtual std::string expandAliases( std::string
const& unexpandedTestSpec )
const;
8380 void add(
char const* alias,
char const* tag,
SourceLineInfo const& lineInfo );
8381 static TagAliasRegistry&
get();
8384 std::map<std::string, TagAlias> m_registry;
8394 TagAliasRegistry::~TagAliasRegistry() {}
8396 Option<TagAlias> TagAliasRegistry::find( std::string
const& alias )
const {
8397 std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias );
8398 if( it != m_registry.end() )
8404 std::string TagAliasRegistry::expandAliases( std::string
const& unexpandedTestSpec )
const {
8405 std::string expandedTestSpec = unexpandedTestSpec;
8406 for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end();
8409 std::size_t pos = expandedTestSpec.find( it->first );
8410 if( pos != std::string::npos ) {
8411 expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
8413 expandedTestSpec.substr( pos + it->first.size() );
8416 return expandedTestSpec;
8419 void TagAliasRegistry::add(
char const* alias,
char const* tag,
SourceLineInfo const& lineInfo ) {
8421 if( !startsWith( alias,
"[@" ) || !endsWith( alias,
"]" ) ) {
8422 std::ostringstream oss;
8423 oss <<
"error: tag alias, \"" << alias <<
"\" is not of the form [@alias name].\n" << lineInfo;
8424 throw std::domain_error( oss.str().c_str() );
8426 if( !m_registry.insert( std::make_pair( alias,
TagAlias( tag, lineInfo ) ) ).second ) {
8427 std::ostringstream oss;
8428 oss <<
"error: tag alias, \"" << alias <<
"\" already registered.\n" 8429 <<
"\tFirst seen at " << find(alias)->lineInfo <<
"\n" 8430 <<
"\tRedefined at " << lineInfo;
8431 throw std::domain_error( oss.str().c_str() );
8435 TagAliasRegistry& TagAliasRegistry::get() {
8436 static TagAliasRegistry instance;
8441 ITagAliasRegistry::~ITagAliasRegistry() {}
8442 ITagAliasRegistry const& ITagAliasRegistry::get() {
return TagAliasRegistry::get(); }
8444 RegistrarForTagAliases::RegistrarForTagAliases(
char const* alias,
char const* tag,
SourceLineInfo const& lineInfo ) {
8446 TagAliasRegistry::get().add( alias, tag, lineInfo );
8448 catch( std::exception& ex ) {
8449 Colour colourGuard( Colour::Red );
8450 Catch::cerr() << ex.what() << std::endl;
8458 #define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED 8462 class MultipleReporters :
public SharedImpl<IStreamingReporter> {
8463 typedef std::vector<Ptr<IStreamingReporter> > Reporters;
8464 Reporters m_reporters;
8468 m_reporters.push_back( reporter );
8473 virtual ReporterPreferences getPreferences()
const CATCH_OVERRIDE {
8474 return m_reporters[0]->getPreferences();
8477 virtual void noMatchingTestCases( std::string
const& spec ) CATCH_OVERRIDE {
8478 for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8481 (*it)->noMatchingTestCases( spec );
8484 virtual void testRunStarting( TestRunInfo
const& testRunInfo ) CATCH_OVERRIDE {
8485 for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8488 (*it)->testRunStarting( testRunInfo );
8491 virtual void testGroupStarting( GroupInfo
const& groupInfo ) CATCH_OVERRIDE {
8492 for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8495 (*it)->testGroupStarting( groupInfo );
8498 virtual void testCaseStarting(
TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
8499 for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8502 (*it)->testCaseStarting( testInfo );
8505 virtual void sectionStarting(
SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
8506 for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8509 (*it)->sectionStarting( sectionInfo );
8512 virtual void assertionStarting(
AssertionInfo const& assertionInfo ) CATCH_OVERRIDE {
8513 for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8516 (*it)->assertionStarting( assertionInfo );
8520 virtual bool assertionEnded( AssertionStats
const& assertionStats ) CATCH_OVERRIDE {
8521 bool clearBuffer =
false;
8522 for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8525 clearBuffer |= (*it)->assertionEnded( assertionStats );
8529 virtual void sectionEnded( SectionStats
const& sectionStats ) CATCH_OVERRIDE {
8530 for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8533 (*it)->sectionEnded( sectionStats );
8536 virtual void testCaseEnded( TestCaseStats
const& testCaseStats ) CATCH_OVERRIDE {
8537 for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8540 (*it)->testCaseEnded( testCaseStats );
8543 virtual void testGroupEnded( TestGroupStats
const& testGroupStats ) CATCH_OVERRIDE {
8544 for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8547 (*it)->testGroupEnded( testGroupStats );
8550 virtual void testRunEnded( TestRunStats
const& testRunStats ) CATCH_OVERRIDE {
8551 for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8554 (*it)->testRunEnded( testRunStats );
8557 virtual void skipTest(
TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
8558 for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8561 (*it)->skipTest( testInfo );
8564 virtual MultipleReporters* tryAsMulti() CATCH_OVERRIDE {
8573 if( existingReporter ) {
8574 MultipleReporters* multi = existingReporter->tryAsMulti();
8576 multi =
new MultipleReporters;
8578 if( existingReporter )
8579 multi->add( existingReporter );
8582 resultingReporter = existingReporter;
8583 multi->add( additionalReporter );
8586 resultingReporter = additionalReporter;
8588 return resultingReporter;
8594 #define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED 8597 #define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED 8603 struct StreamingReporterBase :
SharedImpl<IStreamingReporter> {
8605 StreamingReporterBase( ReporterConfig
const& _config )
8606 : m_config( _config.fullConfig() ),
8607 stream( _config.stream() )
8609 m_reporterPrefs.shouldRedirectStdOut =
false;
8612 virtual ReporterPreferences getPreferences()
const CATCH_OVERRIDE {
8613 return m_reporterPrefs;
8616 virtual ~StreamingReporterBase() CATCH_OVERRIDE;
8618 virtual void noMatchingTestCases( std::string
const& ) CATCH_OVERRIDE {}
8620 virtual void testRunStarting( TestRunInfo
const& _testRunInfo ) CATCH_OVERRIDE {
8621 currentTestRunInfo = _testRunInfo;
8623 virtual void testGroupStarting( GroupInfo
const& _groupInfo ) CATCH_OVERRIDE {
8624 currentGroupInfo = _groupInfo;
8627 virtual void testCaseStarting(
TestCaseInfo const& _testInfo ) CATCH_OVERRIDE {
8628 currentTestCaseInfo = _testInfo;
8630 virtual void sectionStarting(
SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
8631 m_sectionStack.push_back( _sectionInfo );
8634 virtual void sectionEnded( SectionStats
const& ) CATCH_OVERRIDE {
8635 m_sectionStack.pop_back();
8637 virtual void testCaseEnded( TestCaseStats
const& ) CATCH_OVERRIDE {
8638 currentTestCaseInfo.reset();
8640 virtual void testGroupEnded( TestGroupStats
const& ) CATCH_OVERRIDE {
8641 currentGroupInfo.reset();
8643 virtual void testRunEnded( TestRunStats
const& ) CATCH_OVERRIDE {
8644 currentTestCaseInfo.reset();
8645 currentGroupInfo.reset();
8646 currentTestRunInfo.reset();
8649 virtual void skipTest(
TestCaseInfo const& ) CATCH_OVERRIDE {
8655 std::ostream& stream;
8657 LazyStat<TestRunInfo> currentTestRunInfo;
8658 LazyStat<GroupInfo> currentGroupInfo;
8659 LazyStat<TestCaseInfo> currentTestCaseInfo;
8661 std::vector<SectionInfo> m_sectionStack;
8662 ReporterPreferences m_reporterPrefs;
8665 struct CumulativeReporterBase :
SharedImpl<IStreamingReporter> {
8666 template<
typename T,
typename ChildNodeT>
8668 explicit Node(
T const& _value ) : value( _value ) {}
8671 typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
8673 ChildNodes children;
8676 explicit SectionNode( SectionStats
const& _stats ) : stats( _stats ) {}
8677 virtual ~SectionNode();
8679 bool operator == ( SectionNode
const& other )
const {
8680 return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
8683 return operator==( *other );
8687 typedef std::vector<Ptr<SectionNode> > ChildSections;
8688 typedef std::vector<AssertionStats> Assertions;
8689 ChildSections childSections;
8690 Assertions assertions;
8695 struct BySectionInfo {
8696 BySectionInfo(
SectionInfo const& other ) : m_other( other ) {}
8697 BySectionInfo( BySectionInfo
const& other ) : m_other( other.m_other ) {}
8699 return node->stats.sectionInfo.lineInfo == m_other.lineInfo;
8702 void operator=( BySectionInfo
const& );
8706 typedef Node<TestCaseStats, SectionNode> TestCaseNode;
8707 typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;
8708 typedef Node<TestRunStats, TestGroupNode> TestRunNode;
8710 CumulativeReporterBase( ReporterConfig
const& _config )
8711 : m_config( _config.fullConfig() ),
8712 stream( _config.stream() )
8714 m_reporterPrefs.shouldRedirectStdOut =
false;
8716 ~CumulativeReporterBase();
8718 virtual ReporterPreferences getPreferences()
const CATCH_OVERRIDE {
8719 return m_reporterPrefs;
8722 virtual void testRunStarting( TestRunInfo
const& ) CATCH_OVERRIDE {}
8723 virtual void testGroupStarting( GroupInfo
const& ) CATCH_OVERRIDE {}
8725 virtual void testCaseStarting(
TestCaseInfo const& ) CATCH_OVERRIDE {}
8727 virtual void sectionStarting(
SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
8728 SectionStats incompleteStats( sectionInfo,
Counts(), 0,
false );
8730 if( m_sectionStack.empty() ) {
8731 if( !m_rootSection )
8732 m_rootSection =
new SectionNode( incompleteStats );
8733 node = m_rootSection;
8736 SectionNode& parentNode = *m_sectionStack.back();
8737 SectionNode::ChildSections::const_iterator it =
8738 std::find_if( parentNode.childSections.begin(),
8739 parentNode.childSections.end(),
8740 BySectionInfo( sectionInfo ) );
8741 if( it == parentNode.childSections.end() ) {
8742 node =
new SectionNode( incompleteStats );
8743 parentNode.childSections.push_back( node );
8748 m_sectionStack.push_back( node );
8749 m_deepestSection = node;
8752 virtual void assertionStarting(
AssertionInfo const& ) CATCH_OVERRIDE {}
8754 virtual bool assertionEnded( AssertionStats
const& assertionStats ) CATCH_OVERRIDE {
8755 assert( !m_sectionStack.empty() );
8756 SectionNode& sectionNode = *m_sectionStack.back();
8757 sectionNode.assertions.push_back( assertionStats );
8760 virtual void sectionEnded( SectionStats
const& sectionStats ) CATCH_OVERRIDE {
8761 assert( !m_sectionStack.empty() );
8762 SectionNode& node = *m_sectionStack.back();
8763 node.stats = sectionStats;
8764 m_sectionStack.pop_back();
8766 virtual void testCaseEnded( TestCaseStats
const& testCaseStats ) CATCH_OVERRIDE {
8768 assert( m_sectionStack.size() == 0 );
8769 node->children.push_back( m_rootSection );
8770 m_testCases.push_back( node );
8771 m_rootSection.reset();
8773 assert( m_deepestSection );
8774 m_deepestSection->stdOut = testCaseStats.stdOut;
8775 m_deepestSection->stdErr = testCaseStats.stdErr;
8777 virtual void testGroupEnded( TestGroupStats
const& testGroupStats ) CATCH_OVERRIDE {
8779 node->children.swap( m_testCases );
8780 m_testGroups.push_back( node );
8782 virtual void testRunEnded( TestRunStats
const& testRunStats ) CATCH_OVERRIDE {
8784 node->children.swap( m_testGroups );
8785 m_testRuns.push_back( node );
8786 testRunEndedCumulative();
8788 virtual void testRunEndedCumulative() = 0;
8790 virtual void skipTest(
TestCaseInfo const& ) CATCH_OVERRIDE {}
8793 std::ostream& stream;
8794 std::vector<AssertionStats> m_assertions;
8795 std::vector<std::vector<Ptr<SectionNode> > > m_sections;
8796 std::vector<Ptr<TestCaseNode> > m_testCases;
8797 std::vector<Ptr<TestGroupNode> > m_testGroups;
8799 std::vector<Ptr<TestRunNode> > m_testRuns;
8803 std::vector<Ptr<SectionNode> > m_sectionStack;
8804 ReporterPreferences m_reporterPrefs;
8809 char const* getLineOfChars() {
8810 static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
8813 line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
8818 struct TestEventListenerBase : StreamingReporterBase {
8819 TestEventListenerBase( ReporterConfig
const& _config )
8820 : StreamingReporterBase( _config )
8823 virtual void assertionStarting(
AssertionInfo const& ) CATCH_OVERRIDE {}
8824 virtual bool assertionEnded( AssertionStats
const& ) CATCH_OVERRIDE {
8832 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED 8836 template<
typename T>
8837 class LegacyReporterRegistrar {
8839 class ReporterFactory :
public IReporterFactory {
8840 virtual IStreamingReporter* create( ReporterConfig
const& config )
const {
8841 return new LegacyReporterAdapter(
new T( config ) );
8844 virtual std::string getDescription()
const {
8845 return T::getDescription();
8851 LegacyReporterRegistrar( std::string
const& name ) {
8852 getMutableRegistryHub().registerReporter( name,
new ReporterFactory() );
8856 template<
typename T>
8857 class ReporterRegistrar {
8859 class ReporterFactory :
public SharedImpl<IReporterFactory> {
8872 virtual IStreamingReporter* create( ReporterConfig
const& config )
const {
8873 return new T( config );
8876 virtual std::string getDescription()
const {
8877 return T::getDescription();
8883 ReporterRegistrar( std::string
const& name ) {
8884 getMutableRegistryHub().registerReporter( name,
new ReporterFactory() );
8888 template<
typename T>
8889 class ListenerRegistrar {
8891 class ListenerFactory :
public SharedImpl<IReporterFactory> {
8893 virtual IStreamingReporter* create( ReporterConfig
const& config )
const {
8894 return new T( config );
8896 virtual std::string getDescription()
const {
8903 ListenerRegistrar() {
8904 getMutableRegistryHub().registerListener(
new ListenerFactory() );
8909 #define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \ 8910 namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } 8912 #define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \ 8913 namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } 8915 #define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \ 8916 namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } 8919 #define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED 8930 enum ForWhat { ForTextNodes, ForAttributes };
8932 XmlEncode( std::string
const& str, ForWhat forWhat = ForTextNodes )
8934 m_forWhat( forWhat )
8937 void encodeTo( std::ostream& os )
const {
8942 for( std::size_t i = 0; i < m_str.size(); ++ i ) {
8945 case '<': os <<
"<";
break;
8946 case '&': os <<
"&";
break;
8950 if( i > 2 && m_str[i-1] ==
']' && m_str[i-2] ==
']' )
8957 if( m_forWhat == ForAttributes )
8966 if ( ( c <
'\x09' ) || ( c >
'\x0D' && c <
'\x20') || c==
'\x7F' )
8967 os <<
"&#x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>( c ) <<
';';
8974 friend std::ostream& operator << ( std::ostream& os, XmlEncode
const& xmlEncode ) {
8975 xmlEncode.encodeTo( os );
8987 class ScopedElement {
8989 ScopedElement( XmlWriter* writer )
8990 : m_writer( writer )
8993 ScopedElement( ScopedElement
const& other )
8994 : m_writer( other.m_writer ){
8995 other.m_writer = CATCH_NULL;
9000 m_writer->endElement();
9003 ScopedElement& writeText( std::string
const& text,
bool indent =
true ) {
9004 m_writer->writeText( text, indent );
9008 template<
typename T>
9009 ScopedElement& writeAttribute( std::string
const& name,
T const& attribute ) {
9010 m_writer->writeAttribute( name, attribute );
9015 mutable XmlWriter* m_writer;
9019 : m_tagIsOpen(
false ),
9020 m_needsNewline(
false ),
9021 m_os( &Catch::cout() )
9026 *m_os <<
"<?xml version=\"1.1\" encoding=\"UTF-8\"?>\n";
9029 XmlWriter( std::ostream& os )
9030 : m_tagIsOpen(
false ),
9031 m_needsNewline(
false ),
9034 *m_os <<
"<?xml version=\"1.1\" encoding=\"UTF-8\"?>\n";
9038 while( !m_tags.empty() )
9042 XmlWriter& startElement( std::string
const& name ) {
9044 newlineIfNecessary();
9045 stream() << m_indent <<
"<" << name;
9046 m_tags.push_back( name );
9052 ScopedElement scopedElement( std::string
const& name ) {
9053 ScopedElement scoped(
this );
9054 startElement( name );
9058 XmlWriter& endElement() {
9059 newlineIfNecessary();
9060 m_indent = m_indent.substr( 0, m_indent.size()-2 );
9063 m_tagIsOpen =
false;
9066 stream() << m_indent <<
"</" << m_tags.back() <<
">\n";
9072 XmlWriter& writeAttribute( std::string
const& name, std::string
const& attribute ) {
9073 if( !name.empty() && !attribute.empty() )
9074 stream() <<
" " << name <<
"=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) <<
"\"";
9078 XmlWriter& writeAttribute( std::string
const& name,
bool attribute ) {
9079 stream() <<
" " << name <<
"=\"" << ( attribute ?
"true" :
"false" ) <<
"\"";
9083 template<
typename T>
9084 XmlWriter& writeAttribute( std::string
const& name,
T const& attribute ) {
9085 std::ostringstream oss;
9087 return writeAttribute( name, oss.str() );
9090 XmlWriter& writeText( std::string
const& text,
bool indent =
true ) {
9091 if( !text.empty() ){
9092 bool tagWasOpen = m_tagIsOpen;
9094 if( tagWasOpen && indent )
9095 stream() << m_indent;
9096 stream() << XmlEncode( text );
9097 m_needsNewline =
true;
9102 XmlWriter& writeComment( std::string
const& text ) {
9104 stream() << m_indent <<
"<!--" << text <<
"-->";
9105 m_needsNewline =
true;
9109 XmlWriter& writeBlankLine() {
9115 void setStream( std::ostream& os ) {
9120 XmlWriter( XmlWriter
const& );
9121 void operator=( XmlWriter
const& );
9123 std::ostream& stream() {
9127 void ensureTagClosed() {
9130 m_tagIsOpen =
false;
9134 void newlineIfNecessary() {
9135 if( m_needsNewline ) {
9137 m_needsNewline =
false;
9142 bool m_needsNewline;
9143 std::vector<std::string> m_tags;
9144 std::string m_indent;
9151 #define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED 9154 # ifdef __ICC // icpc defines the __clang__ macro 9155 # pragma warning(pop) 9157 # pragma clang diagnostic pop 9159 #elif defined __GNUC__ 9160 # pragma GCC diagnostic pop 9165 class XmlReporter :
public StreamingReporterBase {
9167 XmlReporter( ReporterConfig
const& _config )
9168 : StreamingReporterBase( _config ),
9171 m_reporterPrefs.shouldRedirectStdOut =
true;
9174 virtual ~XmlReporter() CATCH_OVERRIDE;
9176 static std::string getDescription() {
9177 return "Reports test results as an XML document";
9182 virtual void noMatchingTestCases( std::string
const& s ) CATCH_OVERRIDE {
9183 StreamingReporterBase::noMatchingTestCases( s );
9186 virtual void testRunStarting( TestRunInfo
const& testInfo ) CATCH_OVERRIDE {
9187 StreamingReporterBase::testRunStarting( testInfo );
9188 m_xml.setStream( stream );
9189 m_xml.startElement(
"Catch" );
9190 if( !m_config->name().empty() )
9191 m_xml.writeAttribute(
"name", m_config->name() );
9194 virtual void testGroupStarting( GroupInfo
const& groupInfo ) CATCH_OVERRIDE {
9195 StreamingReporterBase::testGroupStarting( groupInfo );
9196 m_xml.startElement(
"Group" )
9197 .writeAttribute(
"name", groupInfo.name );
9200 virtual void testCaseStarting(
TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
9201 StreamingReporterBase::testCaseStarting(testInfo);
9202 m_xml.startElement(
"TestCase" ).writeAttribute(
"name", testInfo.name );
9204 if ( m_config->showDurations() == ShowDurations::Always )
9205 m_testCaseTimer.start();
9208 virtual void sectionStarting(
SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
9209 StreamingReporterBase::sectionStarting( sectionInfo );
9210 if( m_sectionDepth++ > 0 ) {
9211 m_xml.startElement(
"Section" )
9212 .writeAttribute(
"name", trim( sectionInfo.name ) )
9213 .writeAttribute(
"description", sectionInfo.description );
9217 virtual void assertionStarting(
AssertionInfo const& ) CATCH_OVERRIDE { }
9219 virtual bool assertionEnded( AssertionStats
const& assertionStats ) CATCH_OVERRIDE {
9220 const AssertionResult& assertionResult = assertionStats.assertionResult;
9223 if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
9224 for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
9227 if( it->type == ResultWas::Info ) {
9228 m_xml.scopedElement(
"Info" )
9229 .writeText( it->message );
9230 }
else if ( it->type == ResultWas::Warning ) {
9231 m_xml.scopedElement(
"Warning" )
9232 .writeText( it->message );
9238 if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) )
9242 if( assertionResult.hasExpression() ) {
9243 m_xml.startElement(
"Expression" )
9244 .writeAttribute(
"success", assertionResult.succeeded() )
9245 .writeAttribute(
"type", assertionResult.getTestMacroName() )
9246 .writeAttribute(
"filename", assertionResult.getSourceInfo().file )
9247 .writeAttribute(
"line", assertionResult.getSourceInfo().line );
9249 m_xml.scopedElement(
"Original" )
9250 .writeText( assertionResult.getExpression() );
9251 m_xml.scopedElement(
"Expanded" )
9252 .writeText( assertionResult.getExpandedExpression() );
9256 switch( assertionResult.getResultType() ) {
9257 case ResultWas::ThrewException:
9258 m_xml.scopedElement(
"Exception" )
9259 .writeAttribute(
"filename", assertionResult.getSourceInfo().file )
9260 .writeAttribute(
"line", assertionResult.getSourceInfo().line )
9261 .writeText( assertionResult.getMessage() );
9263 case ResultWas::FatalErrorCondition:
9264 m_xml.scopedElement(
"FatalErrorCondition" )
9265 .writeAttribute(
"filename", assertionResult.getSourceInfo().file )
9266 .writeAttribute(
"line", assertionResult.getSourceInfo().line )
9267 .writeText( assertionResult.getMessage() );
9269 case ResultWas::Info:
9270 m_xml.scopedElement(
"Info" )
9271 .writeText( assertionResult.getMessage() );
9273 case ResultWas::Warning:
9276 case ResultWas::ExplicitFailure:
9277 m_xml.scopedElement(
"Failure" )
9278 .writeText( assertionResult.getMessage() );
9284 if( assertionResult.hasExpression() )
9290 virtual void sectionEnded( SectionStats
const& sectionStats ) CATCH_OVERRIDE {
9291 StreamingReporterBase::sectionEnded( sectionStats );
9292 if( --m_sectionDepth > 0 ) {
9293 XmlWriter::ScopedElement e = m_xml.scopedElement(
"OverallResults" );
9294 e.writeAttribute(
"successes", sectionStats.assertions.passed );
9295 e.writeAttribute(
"failures", sectionStats.assertions.failed );
9296 e.writeAttribute(
"expectedFailures", sectionStats.assertions.failedButOk );
9298 if ( m_config->showDurations() == ShowDurations::Always )
9299 e.writeAttribute(
"durationInSeconds", sectionStats.durationInSeconds );
9305 virtual void testCaseEnded( TestCaseStats
const& testCaseStats ) CATCH_OVERRIDE {
9306 StreamingReporterBase::testCaseEnded( testCaseStats );
9307 XmlWriter::ScopedElement e = m_xml.scopedElement(
"OverallResult" );
9308 e.writeAttribute(
"success", testCaseStats.totals.assertions.allOk() );
9310 if ( m_config->showDurations() == ShowDurations::Always )
9311 e.writeAttribute(
"durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
9316 virtual void testGroupEnded( TestGroupStats
const& testGroupStats ) CATCH_OVERRIDE {
9317 StreamingReporterBase::testGroupEnded( testGroupStats );
9319 m_xml.scopedElement(
"OverallResults" )
9320 .writeAttribute(
"successes", testGroupStats.totals.assertions.passed )
9321 .writeAttribute(
"failures", testGroupStats.totals.assertions.failed )
9322 .writeAttribute(
"expectedFailures", testGroupStats.totals.assertions.failedButOk );
9326 virtual void testRunEnded( TestRunStats
const& testRunStats ) CATCH_OVERRIDE {
9327 StreamingReporterBase::testRunEnded( testRunStats );
9328 m_xml.scopedElement(
"OverallResults" )
9329 .writeAttribute(
"successes", testRunStats.totals.assertions.passed )
9330 .writeAttribute(
"failures", testRunStats.totals.assertions.failed )
9331 .writeAttribute(
"expectedFailures", testRunStats.totals.assertions.failedButOk );
9336 Timer m_testCaseTimer;
9341 INTERNAL_CATCH_REGISTER_REPORTER(
"xml", XmlReporter )
9346 #define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED 9352 class JunitReporter :
public CumulativeReporterBase {
9354 JunitReporter( ReporterConfig
const& _config )
9355 : CumulativeReporterBase( _config ),
9356 xml( _config.stream() )
9358 m_reporterPrefs.shouldRedirectStdOut =
true;
9361 virtual ~JunitReporter() CATCH_OVERRIDE;
9363 static std::string getDescription() {
9364 return "Reports test results in an XML format that looks like Ant's junitreport target";
9367 virtual void noMatchingTestCases( std::string
const& ) CATCH_OVERRIDE {}
9369 virtual void testRunStarting( TestRunInfo
const& runInfo ) CATCH_OVERRIDE {
9370 CumulativeReporterBase::testRunStarting( runInfo );
9371 xml.startElement(
"testsuites" );
9374 virtual void testGroupStarting( GroupInfo
const& groupInfo ) CATCH_OVERRIDE {
9376 stdOutForSuite.str(
"");
9377 stdErrForSuite.str(
"");
9378 unexpectedExceptions = 0;
9379 CumulativeReporterBase::testGroupStarting( groupInfo );
9382 virtual bool assertionEnded( AssertionStats
const& assertionStats ) CATCH_OVERRIDE {
9383 if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException )
9384 unexpectedExceptions++;
9385 return CumulativeReporterBase::assertionEnded( assertionStats );
9388 virtual void testCaseEnded( TestCaseStats
const& testCaseStats ) CATCH_OVERRIDE {
9389 stdOutForSuite << testCaseStats.stdOut;
9390 stdErrForSuite << testCaseStats.stdErr;
9391 CumulativeReporterBase::testCaseEnded( testCaseStats );
9394 virtual void testGroupEnded( TestGroupStats
const& testGroupStats ) CATCH_OVERRIDE {
9395 double suiteTime = suiteTimer.getElapsedSeconds();
9396 CumulativeReporterBase::testGroupEnded( testGroupStats );
9397 writeGroup( *m_testGroups.back(), suiteTime );
9400 virtual void testRunEndedCumulative() CATCH_OVERRIDE {
9404 void writeGroup( TestGroupNode
const& groupNode,
double suiteTime ) {
9405 XmlWriter::ScopedElement e = xml.scopedElement(
"testsuite" );
9406 TestGroupStats
const& stats = groupNode.value;
9407 xml.writeAttribute(
"name", stats.groupInfo.name );
9408 xml.writeAttribute(
"errors", unexpectedExceptions );
9409 xml.writeAttribute(
"failures", stats.totals.assertions.failed-unexpectedExceptions );
9410 xml.writeAttribute(
"tests", stats.totals.assertions.total() );
9411 xml.writeAttribute(
"hostname",
"tbd" );
9412 if( m_config->showDurations() == ShowDurations::Never )
9413 xml.writeAttribute(
"time",
"" );
9415 xml.writeAttribute(
"time", suiteTime );
9416 xml.writeAttribute(
"timestamp",
"tbd" );
9419 for( TestGroupNode::ChildNodes::const_iterator
9420 it = groupNode.children.begin(), itEnd = groupNode.children.end();
9423 writeTestCase( **it );
9425 xml.scopedElement(
"system-out" ).writeText( trim( stdOutForSuite.str() ),
false );
9426 xml.scopedElement(
"system-err" ).writeText( trim( stdErrForSuite.str() ),
false );
9429 void writeTestCase( TestCaseNode
const& testCaseNode ) {
9430 TestCaseStats
const& stats = testCaseNode.value;
9434 assert( testCaseNode.children.size() == 1 );
9435 SectionNode
const& rootSection = *testCaseNode.children.front();
9437 std::string className = stats.testInfo.className;
9439 if( className.empty() ) {
9440 if( rootSection.childSections.empty() )
9441 className =
"global";
9443 writeSection( className,
"", rootSection );
9446 void writeSection( std::string
const& className,
9447 std::string
const& rootName,
9448 SectionNode
const& sectionNode ) {
9449 std::string name = trim( sectionNode.stats.sectionInfo.name );
9450 if( !rootName.empty() )
9451 name = rootName +
"/" + name;
9453 if( !sectionNode.assertions.empty() ||
9454 !sectionNode.stdOut.empty() ||
9455 !sectionNode.stdErr.empty() ) {
9456 XmlWriter::ScopedElement e = xml.scopedElement(
"testcase" );
9457 if( className.empty() ) {
9458 xml.writeAttribute(
"classname", name );
9459 xml.writeAttribute(
"name",
"root" );
9462 xml.writeAttribute(
"classname", className );
9463 xml.writeAttribute(
"name", name );
9465 xml.writeAttribute(
"time", Catch::toString( sectionNode.stats.durationInSeconds ) );
9467 writeAssertions( sectionNode );
9469 if( !sectionNode.stdOut.empty() )
9470 xml.scopedElement(
"system-out" ).writeText( trim( sectionNode.stdOut ),
false );
9471 if( !sectionNode.stdErr.empty() )
9472 xml.scopedElement(
"system-err" ).writeText( trim( sectionNode.stdErr ),
false );
9474 for( SectionNode::ChildSections::const_iterator
9475 it = sectionNode.childSections.begin(),
9476 itEnd = sectionNode.childSections.end();
9479 if( className.empty() )
9480 writeSection( name,
"", **it );
9482 writeSection( className, name, **it );
9485 void writeAssertions( SectionNode
const& sectionNode ) {
9486 for( SectionNode::Assertions::const_iterator
9487 it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();
9490 writeAssertion( *it );
9492 void writeAssertion( AssertionStats
const& stats ) {
9494 if( !result.isOk() ) {
9495 std::string elementName;
9496 switch( result.getResultType() ) {
9497 case ResultWas::ThrewException:
9498 case ResultWas::FatalErrorCondition:
9499 elementName =
"error";
9501 case ResultWas::ExplicitFailure:
9502 elementName =
"failure";
9504 case ResultWas::ExpressionFailed:
9505 elementName =
"failure";
9507 case ResultWas::DidntThrowException:
9508 elementName =
"failure";
9512 case ResultWas::Info:
9513 case ResultWas::Warning:
9515 case ResultWas::Unknown:
9516 case ResultWas::FailureBit:
9517 case ResultWas::Exception:
9518 elementName =
"internalError";
9522 XmlWriter::ScopedElement e = xml.scopedElement( elementName );
9524 xml.writeAttribute(
"message", result.getExpandedExpression() );
9525 xml.writeAttribute(
"type", result.getTestMacroName() );
9527 std::ostringstream oss;
9528 if( !result.getMessage().empty() )
9529 oss << result.getMessage() <<
"\n";
9530 for( std::vector<MessageInfo>::const_iterator
9531 it = stats.infoMessages.begin(),
9532 itEnd = stats.infoMessages.end();
9535 if( it->type == ResultWas::Info )
9536 oss << it->message <<
"\n";
9538 oss <<
"at " << result.getSourceInfo();
9539 xml.writeText( oss.str(), false );
9545 std::ostringstream stdOutForSuite;
9546 std::ostringstream stdErrForSuite;
9547 unsigned int unexpectedExceptions;
9550 INTERNAL_CATCH_REGISTER_REPORTER(
"junit", JunitReporter )
9555 #define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED 9559 struct ConsoleReporter : StreamingReporterBase {
9560 ConsoleReporter( ReporterConfig
const& _config )
9561 : StreamingReporterBase( _config ),
9562 m_headerPrinted(
false )
9565 virtual ~ConsoleReporter() CATCH_OVERRIDE;
9566 static std::string getDescription() {
9567 return "Reports test results as plain lines of text";
9570 virtual void noMatchingTestCases( std::string
const& spec ) CATCH_OVERRIDE {
9571 stream <<
"No test cases matched '" << spec <<
"'" << std::endl;
9574 virtual void assertionStarting(
AssertionInfo const& ) CATCH_OVERRIDE {
9577 virtual bool assertionEnded( AssertionStats
const& _assertionStats ) CATCH_OVERRIDE {
9580 bool printInfoMessages =
true;
9583 if( !m_config->includeSuccessfulResults() && result.isOk() ) {
9584 if( result.getResultType() != ResultWas::Warning )
9586 printInfoMessages =
false;
9591 AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
9593 stream << std::endl;
9597 virtual void sectionStarting(
SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
9598 m_headerPrinted =
false;
9599 StreamingReporterBase::sectionStarting( _sectionInfo );
9601 virtual void sectionEnded( SectionStats
const& _sectionStats ) CATCH_OVERRIDE {
9602 if( _sectionStats.missingAssertions ) {
9604 Colour colour( Colour::ResultError );
9605 if( m_sectionStack.size() > 1 )
9606 stream <<
"\nNo assertions in section";
9608 stream <<
"\nNo assertions in test case";
9609 stream <<
" '" << _sectionStats.sectionInfo.name <<
"'\n" << std::endl;
9611 if( m_headerPrinted ) {
9612 if( m_config->showDurations() == ShowDurations::Always )
9613 stream <<
"Completed in " << _sectionStats.durationInSeconds <<
"s" << std::endl;
9614 m_headerPrinted =
false;
9617 if( m_config->showDurations() == ShowDurations::Always )
9618 stream << _sectionStats.sectionInfo.name <<
" completed in " << _sectionStats.durationInSeconds <<
"s" << std::endl;
9620 StreamingReporterBase::sectionEnded( _sectionStats );
9623 virtual void testCaseEnded( TestCaseStats
const& _testCaseStats ) CATCH_OVERRIDE {
9624 StreamingReporterBase::testCaseEnded( _testCaseStats );
9625 m_headerPrinted =
false;
9627 virtual void testGroupEnded( TestGroupStats
const& _testGroupStats ) CATCH_OVERRIDE {
9628 if( currentGroupInfo.used ) {
9629 printSummaryDivider();
9630 stream <<
"Summary for group '" << _testGroupStats.groupInfo.name <<
"':\n";
9631 printTotals( _testGroupStats.totals );
9632 stream <<
"\n" << std::endl;
9634 StreamingReporterBase::testGroupEnded( _testGroupStats );
9636 virtual void testRunEnded( TestRunStats
const& _testRunStats ) CATCH_OVERRIDE {
9637 printTotalsDivider( _testRunStats.totals );
9638 printTotals( _testRunStats.totals );
9639 stream << std::endl;
9640 StreamingReporterBase::testRunEnded( _testRunStats );
9645 class AssertionPrinter {
9646 void operator= ( AssertionPrinter
const& );
9648 AssertionPrinter( std::ostream& _stream, AssertionStats
const& _stats,
bool _printInfoMessages )
9649 : stream( _stream ),
9651 result( _stats.assertionResult ),
9652 colour( Colour::None ),
9653 message( result.getMessage() ),
9655 printInfoMessages( _printInfoMessages )
9657 switch( result.getResultType() ) {
9660 passOrFail =
"PASSED";
9662 if( _stats.infoMessages.size() == 1 )
9663 messageLabel =
"with message";
9664 if( _stats.infoMessages.size() > 1 )
9665 messageLabel =
"with messages";
9667 case ResultWas::ExpressionFailed:
9668 if( result.isOk() ) {
9670 passOrFail =
"FAILED - but was ok";
9673 colour = Colour::Error;
9674 passOrFail =
"FAILED";
9676 if( _stats.infoMessages.size() == 1 )
9677 messageLabel =
"with message";
9678 if( _stats.infoMessages.size() > 1 )
9679 messageLabel =
"with messages";
9681 case ResultWas::ThrewException:
9682 colour = Colour::Error;
9683 passOrFail =
"FAILED";
9684 messageLabel =
"due to unexpected exception with message";
9686 case ResultWas::FatalErrorCondition:
9687 colour = Colour::Error;
9688 passOrFail =
"FAILED";
9689 messageLabel =
"due to a fatal error condition";
9691 case ResultWas::DidntThrowException:
9692 colour = Colour::Error;
9693 passOrFail =
"FAILED";
9694 messageLabel =
"because no exception was thrown where one was expected";
9696 case ResultWas::Info:
9697 messageLabel =
"info";
9699 case ResultWas::Warning:
9700 messageLabel =
"warning";
9702 case ResultWas::ExplicitFailure:
9703 passOrFail =
"FAILED";
9704 colour = Colour::Error;
9705 if( _stats.infoMessages.size() == 1 )
9706 messageLabel =
"explicitly with message";
9707 if( _stats.infoMessages.size() > 1 )
9708 messageLabel =
"explicitly with messages";
9711 case ResultWas::Unknown:
9712 case ResultWas::FailureBit:
9713 case ResultWas::Exception:
9714 passOrFail =
"** internal error **";
9715 colour = Colour::Error;
9720 void print()
const {
9722 if( stats.totals.assertions.total() > 0 ) {
9726 printOriginalExpression();
9727 printReconstructedExpression();
9736 void printResultType()
const {
9737 if( !passOrFail.empty() ) {
9738 Colour colourGuard( colour );
9739 stream << passOrFail <<
":\n";
9742 void printOriginalExpression()
const {
9743 if( result.hasExpression() ) {
9744 Colour colourGuard( Colour::OriginalExpression );
9746 stream << result.getExpressionInMacro();
9750 void printReconstructedExpression()
const {
9751 if( result.hasExpandedExpression() ) {
9752 stream <<
"with expansion:\n";
9753 Colour colourGuard( Colour::ReconstructedExpression );
9754 stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) <<
"\n";
9757 void printMessage()
const {
9758 if( !messageLabel.empty() )
9759 stream << messageLabel <<
":" <<
"\n";
9760 for( std::vector<MessageInfo>::const_iterator it =
messages.begin(), itEnd =
messages.end();
9764 if( printInfoMessages || it->type != ResultWas::Info )
9765 stream << Text( it->message, TextAttributes().setIndent(2) ) <<
"\n";
9768 void printSourceInfo()
const {
9769 Colour colourGuard( Colour::FileName );
9770 stream << result.getSourceInfo() <<
": ";
9773 std::ostream& stream;
9774 AssertionStats
const& stats;
9776 Colour::Code colour;
9777 std::string passOrFail;
9778 std::string messageLabel;
9779 std::string message;
9781 bool printInfoMessages;
9786 if( !currentTestRunInfo.used )
9788 if( !currentGroupInfo.used )
9789 lazyPrintGroupInfo();
9791 if( !m_headerPrinted ) {
9792 printTestCaseAndSectionHeader();
9793 m_headerPrinted =
true;
9796 void lazyPrintRunInfo() {
9797 stream <<
"\n" << getLineOfChars<'~'>() <<
"\n";
9798 Colour colour( Colour::SecondaryText );
9799 stream << currentTestRunInfo->name
9800 <<
" is a Catch v" << libraryVersion <<
" host application.\n" 9801 <<
"Run with -? for options\n\n";
9803 if( m_config->rngSeed() != 0 )
9804 stream <<
"Randomness seeded to: " << m_config->rngSeed() <<
"\n\n";
9806 currentTestRunInfo.used =
true;
9808 void lazyPrintGroupInfo() {
9809 if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
9810 printClosedHeader(
"Group: " + currentGroupInfo->name );
9811 currentGroupInfo.used =
true;
9814 void printTestCaseAndSectionHeader() {
9815 assert( !m_sectionStack.empty() );
9816 printOpenHeader( currentTestCaseInfo->name );
9818 if( m_sectionStack.size() > 1 ) {
9819 Colour colourGuard( Colour::Headers );
9821 std::vector<SectionInfo>::const_iterator
9822 it = m_sectionStack.begin()+1,
9823 itEnd = m_sectionStack.end();
9824 for( ; it != itEnd; ++it )
9825 printHeaderString( it->name, 2 );
9830 if( !lineInfo.empty() ){
9831 stream << getLineOfChars<
'-'>() <<
"\n";
9832 Colour colourGuard( Colour::FileName );
9833 stream << lineInfo <<
"\n";
9835 stream << getLineOfChars<
'.'>() <<
"\n" << std::endl;
9838 void printClosedHeader( std::string
const& _name ) {
9839 printOpenHeader( _name );
9840 stream << getLineOfChars<
'.'>() <<
"\n";
9842 void printOpenHeader( std::string
const& _name ) {
9843 stream << getLineOfChars<
'-'>() <<
"\n";
9845 Colour colourGuard( Colour::Headers );
9846 printHeaderString( _name );
9852 void printHeaderString( std::string
const& _string, std::size_t indent = 0 ) {
9853 std::size_t i = _string.find(
": " );
9854 if( i != std::string::npos )
9858 stream << Text( _string, TextAttributes()
9859 .setIndent( indent+i)
9860 .setInitialIndent( indent ) ) <<
"\n";
9863 struct SummaryColumn {
9865 SummaryColumn( std::string
const& _label, Colour::Code _colour )
9869 SummaryColumn addRow( std::size_t count ) {
9870 std::ostringstream oss;
9872 std::string row = oss.str();
9873 for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {
9874 while( it->size() < row.size() )
9876 while( it->size() > row.size() )
9879 rows.push_back( row );
9884 Colour::Code colour;
9885 std::vector<std::string> rows;
9889 void printTotals(
Totals const& totals ) {
9890 if( totals.testCases.total() == 0 ) {
9891 stream << Colour( Colour::Warning ) <<
"No tests ran\n";
9893 else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) {
9894 stream << Colour( Colour::ResultSuccess ) <<
"All tests passed";
9896 <<
pluralise( totals.assertions.passed,
"assertion" ) <<
" in " 9897 <<
pluralise( totals.testCases.passed,
"test case" ) <<
")" 9902 std::vector<SummaryColumn> columns;
9903 columns.push_back( SummaryColumn(
"", Colour::None )
9904 .addRow( totals.testCases.total() )
9905 .addRow( totals.assertions.total() ) );
9907 .addRow( totals.testCases.passed )
9908 .addRow( totals.assertions.passed ) );
9909 columns.push_back( SummaryColumn(
"failed", Colour::ResultError )
9910 .addRow( totals.testCases.failed )
9911 .addRow( totals.assertions.failed ) );
9912 columns.push_back( SummaryColumn(
"failed as expected", Colour::ResultExpectedFailure )
9913 .addRow( totals.testCases.failedButOk )
9914 .addRow( totals.assertions.failedButOk ) );
9916 printSummaryRow(
"test cases", columns, 0 );
9917 printSummaryRow(
"assertions", columns, 1 );
9920 void printSummaryRow( std::string
const& label, std::vector<SummaryColumn>
const& cols, std::size_t row ) {
9921 for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) {
9922 std::string value = it->rows[row];
9923 if( it->label.empty() ) {
9924 stream << label <<
": ";
9928 stream << Colour( Colour::Warning ) <<
"- none -";
9930 else if( value !=
"0" ) {
9931 stream << Colour( Colour::LightGrey ) <<
" | ";
9932 stream << Colour( it->colour )
9933 << value <<
" " << it->label;
9939 static std::size_t makeRatio( std::size_t number, std::size_t total ) {
9941 return ( ratio == 0 && number > 0 ) ? 1 : ratio;
9943 static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
9944 if( i > j && i > k )
9952 void printTotalsDivider(
Totals const& totals ) {
9953 if( totals.testCases.total() > 0 ) {
9954 std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );
9955 std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );
9956 std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );
9958 findMax( failedRatio, failedButOkRatio, passedRatio )++;
9960 findMax( failedRatio, failedButOkRatio, passedRatio )--;
9962 stream << Colour( Colour::Error ) << std::string( failedRatio,
'=' );
9963 stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio,
'=' );
9964 if( totals.testCases.allPassed() )
9965 stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio,
'=' );
9967 stream << Colour(
Colour::Success ) << std::string( passedRatio,
'=' );
9974 void printSummaryDivider() {
9975 stream << getLineOfChars<
'-'>() <<
"\n";
9979 bool m_headerPrinted;
9982 INTERNAL_CATCH_REGISTER_REPORTER(
"console", ConsoleReporter )
9987 #define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED 9991 struct CompactReporter : StreamingReporterBase {
9993 CompactReporter( ReporterConfig
const& _config )
9994 : StreamingReporterBase( _config )
9997 virtual ~CompactReporter();
9999 static std::string getDescription() {
10000 return "Reports test results on a single line, suitable for IDEs";
10003 virtual ReporterPreferences getPreferences()
const {
10004 ReporterPreferences prefs;
10005 prefs.shouldRedirectStdOut =
false;
10009 virtual void noMatchingTestCases( std::string
const& spec ) {
10010 stream <<
"No test cases matched '" << spec <<
"'" << std::endl;
10016 virtual bool assertionEnded( AssertionStats
const& _assertionStats ) {
10019 bool printInfoMessages =
true;
10022 if( !m_config->includeSuccessfulResults() && result.isOk() ) {
10023 if( result.getResultType() != ResultWas::Warning )
10025 printInfoMessages =
false;
10028 AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
10031 stream << std::endl;
10035 virtual void testRunEnded( TestRunStats
const& _testRunStats ) {
10036 printTotals( _testRunStats.totals );
10037 stream <<
"\n" << std::endl;
10038 StreamingReporterBase::testRunEnded( _testRunStats );
10042 class AssertionPrinter {
10043 void operator= ( AssertionPrinter
const& );
10045 AssertionPrinter( std::ostream& _stream, AssertionStats
const& _stats,
bool _printInfoMessages )
10046 : stream( _stream )
10048 , result( _stats.assertionResult )
10050 , itMessage( _stats.infoMessages.begin() )
10051 , printInfoMessages( _printInfoMessages )
10059 switch( result.getResultType() ) {
10060 case ResultWas::Ok:
10061 printResultType( Colour::ResultSuccess, passedString() );
10062 printOriginalExpression();
10063 printReconstructedExpression();
10064 if ( ! result.hasExpression() )
10065 printRemainingMessages( Colour::None );
10067 printRemainingMessages();
10069 case ResultWas::ExpressionFailed:
10070 if( result.isOk() )
10071 printResultType( Colour::ResultSuccess, failedString() + std::string(
" - but was ok" ) );
10073 printResultType( Colour::Error, failedString() );
10074 printOriginalExpression();
10075 printReconstructedExpression();
10076 printRemainingMessages();
10078 case ResultWas::ThrewException:
10079 printResultType( Colour::Error, failedString() );
10080 printIssue(
"unexpected exception with message:" );
10082 printExpressionWas();
10083 printRemainingMessages();
10085 case ResultWas::FatalErrorCondition:
10086 printResultType( Colour::Error, failedString() );
10087 printIssue(
"fatal error condition with message:" );
10089 printExpressionWas();
10090 printRemainingMessages();
10092 case ResultWas::DidntThrowException:
10093 printResultType( Colour::Error, failedString() );
10094 printIssue(
"expected exception, got none" );
10095 printExpressionWas();
10096 printRemainingMessages();
10098 case ResultWas::Info:
10099 printResultType( Colour::None,
"info" );
10101 printRemainingMessages();
10103 case ResultWas::Warning:
10104 printResultType( Colour::None,
"warning" );
10106 printRemainingMessages();
10108 case ResultWas::ExplicitFailure:
10109 printResultType( Colour::Error, failedString() );
10110 printIssue(
"explicitly" );
10111 printRemainingMessages( Colour::None );
10114 case ResultWas::Unknown:
10115 case ResultWas::FailureBit:
10116 case ResultWas::Exception:
10117 printResultType( Colour::Error,
"** internal error **" );
10125 static Colour::Code dimColour() {
return Colour::FileName; }
10127 #ifdef CATCH_PLATFORM_MAC 10128 static const char* failedString() {
return "FAILED"; }
10129 static const char* passedString() {
return "PASSED"; }
10131 static const char* failedString() {
return "failed"; }
10132 static const char* passedString() {
return "passed"; }
10135 void printSourceInfo()
const {
10136 Colour colourGuard( Colour::FileName );
10137 stream << result.getSourceInfo() <<
":";
10140 void printResultType( Colour::Code colour, std::string passOrFail )
const {
10141 if( !passOrFail.empty() ) {
10143 Colour colourGuard( colour );
10144 stream <<
" " << passOrFail;
10150 void printIssue( std::string issue )
const {
10151 stream <<
" " << issue;
10154 void printExpressionWas() {
10155 if( result.hasExpression() ) {
10158 Colour colour( dimColour() );
10159 stream <<
" expression was:";
10161 printOriginalExpression();
10165 void printOriginalExpression()
const {
10166 if( result.hasExpression() ) {
10167 stream <<
" " << result.getExpression();
10171 void printReconstructedExpression()
const {
10172 if( result.hasExpandedExpression() ) {
10174 Colour colour( dimColour() );
10175 stream <<
" for: ";
10177 stream << result.getExpandedExpression();
10181 void printMessage() {
10182 if ( itMessage !=
messages.end() ) {
10183 stream <<
" '" << itMessage->message <<
"'";
10188 void printRemainingMessages( Colour::Code colour = dimColour() ) {
10189 if ( itMessage ==
messages.end() )
10193 std::vector<MessageInfo>::const_iterator itEnd =
messages.end();
10194 const std::size_t N =
static_cast<std::size_t
>( std::distance( itMessage, itEnd ) );
10197 Colour colourGuard( colour );
10198 stream <<
" with " <<
pluralise( N,
"message" ) <<
":";
10201 for(; itMessage != itEnd; ) {
10203 if( printInfoMessages || itMessage->type != ResultWas::Info ) {
10204 stream <<
" '" << itMessage->message <<
"'";
10205 if ( ++itMessage != itEnd ) {
10206 Colour colourGuard( dimColour() );
10214 std::ostream& stream;
10215 AssertionStats
const& stats;
10217 std::vector<MessageInfo>
messages;
10218 std::vector<MessageInfo>::const_iterator itMessage;
10219 bool printInfoMessages;
10229 std::string bothOrAll( std::size_t count )
const {
10230 return count == 1 ?
"" : count == 2 ?
"both " :
"all " ;
10233 void printTotals(
const Totals& totals )
const {
10234 if( totals.testCases.total() == 0 ) {
10235 stream <<
"No tests ran.";
10237 else if( totals.testCases.failed == totals.testCases.total() ) {
10238 Colour colour( Colour::ResultError );
10239 const std::string qualify_assertions_failed =
10240 totals.assertions.failed == totals.assertions.total() ?
10241 bothOrAll( totals.assertions.failed ) :
"";
10243 "Failed " << bothOrAll( totals.testCases.failed )
10244 <<
pluralise( totals.testCases.failed,
"test case" ) <<
", " 10245 "failed " << qualify_assertions_failed <<
10246 pluralise( totals.assertions.failed,
"assertion" ) <<
".";
10248 else if( totals.assertions.total() == 0 ) {
10250 "Passed " << bothOrAll( totals.testCases.total() )
10251 <<
pluralise( totals.testCases.total(),
"test case" )
10252 <<
" (no assertions).";
10254 else if( totals.assertions.failed ) {
10255 Colour colour( Colour::ResultError );
10257 "Failed " <<
pluralise( totals.testCases.failed,
"test case" ) <<
", " 10258 "failed " <<
pluralise( totals.assertions.failed,
"assertion" ) <<
".";
10261 Colour colour( Colour::ResultSuccess );
10263 "Passed " << bothOrAll( totals.testCases.passed )
10264 <<
pluralise( totals.testCases.passed,
"test case" ) <<
10265 " with " <<
pluralise( totals.assertions.passed,
"assertion" ) <<
".";
10270 INTERNAL_CATCH_REGISTER_REPORTER(
"compact", CompactReporter )
10277 NonCopyable::~NonCopyable() {}
10278 IShared::~IShared() {}
10279 IStream::~IStream() CATCH_NOEXCEPT {}
10280 FileStream::~FileStream() CATCH_NOEXCEPT {}
10281 CoutStream::~CoutStream() CATCH_NOEXCEPT {}
10282 DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {}
10283 StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
10284 IContext::~IContext() {}
10285 IResultCapture::~IResultCapture() {}
10286 ITestCase::~ITestCase() {}
10287 ITestCaseRegistry::~ITestCaseRegistry() {}
10288 IRegistryHub::~IRegistryHub() {}
10289 IMutableRegistryHub::~IMutableRegistryHub() {}
10290 IExceptionTranslator::~IExceptionTranslator() {}
10291 IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
10292 IReporter::~IReporter() {}
10293 IReporterFactory::~IReporterFactory() {}
10294 IReporterRegistry::~IReporterRegistry() {}
10295 IStreamingReporter::~IStreamingReporter() {}
10296 AssertionStats::~AssertionStats() {}
10297 SectionStats::~SectionStats() {}
10298 TestCaseStats::~TestCaseStats() {}
10299 TestGroupStats::~TestGroupStats() {}
10300 TestRunStats::~TestRunStats() {}
10301 CumulativeReporterBase::SectionNode::~SectionNode() {}
10302 CumulativeReporterBase::~CumulativeReporterBase() {}
10304 StreamingReporterBase::~StreamingReporterBase() {}
10305 ConsoleReporter::~ConsoleReporter() {}
10306 CompactReporter::~CompactReporter() {}
10307 IRunner::~IRunner() {}
10308 IMutableContext::~IMutableContext() {}
10309 IConfig::~IConfig() {}
10310 XmlReporter::~XmlReporter() {}
10311 JunitReporter::~JunitReporter() {}
10312 TestRegistry::~TestRegistry() {}
10313 FreeFunctionTestCase::~FreeFunctionTestCase() {}
10314 IGeneratorInfo::~IGeneratorInfo() {}
10315 IGeneratorsForTest::~IGeneratorsForTest() {}
10316 WildcardPattern::~WildcardPattern() {}
10317 TestSpec::Pattern::~Pattern() {}
10318 TestSpec::NamePattern::~NamePattern() {}
10319 TestSpec::TagPattern::~TagPattern() {}
10320 TestSpec::ExcludedPattern::~ExcludedPattern() {}
10322 Matchers::Impl::StdString::Equals::~Equals() {}
10323 Matchers::Impl::StdString::Contains::~Contains() {}
10324 Matchers::Impl::StdString::StartsWith::~StartsWith() {}
10325 Matchers::Impl::StdString::EndsWith::~EndsWith() {}
10327 void Config::dummy() {}
10329 namespace TestCaseTracking {
10330 ITracker::~ITracker() {}
10331 TrackerBase::~TrackerBase() {}
10332 SectionTracker::~SectionTracker() {}
10333 IndexTracker::~IndexTracker() {}
10338 #pragma clang diagnostic pop 10343 #ifdef CATCH_CONFIG_MAIN 10345 #define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED 10350 int main (
int argc,
char * argv[]) {
10351 return Catch::Session().run( argc, argv );
10357 int main (
int argc,
char *
const argv[]) {
10358 #if !CATCH_ARC_ENABLED 10359 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
10362 Catch::registerTestMethods();
10363 int result = Catch::Session().run( argc, (
char*
const*)argv );
10365 #if !CATCH_ARC_ENABLED 10376 #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED 10377 # undef CLARA_CONFIG_MAIN 10383 #ifdef CATCH_CONFIG_PREFIX_ALL 10385 #define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" ) 10386 #define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" ) 10388 #define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "CATCH_REQUIRE_THROWS" ) 10389 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" ) 10390 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "CATCH_REQUIRE_THROWS_WITH" ) 10391 #define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" ) 10393 #define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" ) 10394 #define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" ) 10395 #define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" ) 10396 #define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" ) 10397 #define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" ) 10399 #define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS" ) 10400 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" ) 10401 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CATCH_CHECK_THROWS_WITH" ) 10402 #define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" ) 10404 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" ) 10405 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" ) 10407 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" ) 10408 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg ) 10409 #define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" ) 10410 #define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" ) 10411 #define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" ) 10413 #ifdef CATCH_CONFIG_VARIADIC_MACROS 10414 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) 10415 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) 10416 #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) 10417 #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) 10418 #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) 10419 #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ ) 10420 #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ ) 10422 #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) 10423 #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) 10424 #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) 10425 #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description ) 10426 #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) 10427 #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg ) 10428 #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg ) 10430 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) 10432 #define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) 10433 #define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) 10435 #define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) 10438 #ifdef CATCH_CONFIG_VARIADIC_MACROS 10439 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ ) 10440 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) 10442 #define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags ) 10443 #define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) 10445 #define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc, "" ) 10446 #define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc, "" ) 10447 #define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" ) 10448 #define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc, "" ) 10449 #define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" ) 10454 #define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" ) 10455 #define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" ) 10457 #define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "REQUIRE_THROWS" ) 10458 #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" ) 10459 #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "REQUIRE_THROWS_WITH" ) 10460 #define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" ) 10462 #define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" ) 10463 #define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" ) 10464 #define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" ) 10465 #define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" ) 10466 #define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" ) 10468 #define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "", "CHECK_THROWS" ) 10469 #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" ) 10470 #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CHECK_THROWS_WITH" ) 10471 #define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" ) 10473 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" ) 10474 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" ) 10476 #define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" ) 10477 #define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg ) 10478 #define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" ) 10479 #define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" ) 10480 #define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" ) 10482 #ifdef CATCH_CONFIG_VARIADIC_MACROS 10483 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) 10484 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) 10485 #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) 10486 #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) 10487 #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) 10488 #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ ) 10489 #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ ) 10491 #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) 10492 #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) 10493 #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) 10494 #define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description ) 10495 #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) 10496 #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg ) 10497 #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg ) 10499 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) 10501 #define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) 10502 #define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) 10504 #define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) 10508 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) 10511 #ifdef CATCH_CONFIG_VARIADIC_MACROS 10512 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ ) 10513 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) 10515 #define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags ) 10516 #define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) 10518 #define GIVEN( desc ) SECTION( std::string(" Given: ") + desc, "" ) 10519 #define WHEN( desc ) SECTION( std::string(" When: ") + desc, "" ) 10520 #define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" ) 10521 #define THEN( desc ) SECTION( std::string(" Then: ") + desc, "" ) 10522 #define AND_THEN( desc ) SECTION( std::string(" And: ") + desc, "" ) 10526 #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED Definition: catch.hpp:619
#define CATCH_CONFIG_CONSOLE_WIDTH
Widen the console output wrapping so our matrices don't get so mangled in messages.
Definition: TestIMU.h:30
Definition: DummyTree.h:38
apply_list< quote< or_ >, transform< Haystack, detail::is_< Needle >>> contains
Determines if type Needle is in the list Haystack - is an alias for a type that inherits std::true_ty...
Definition: Contains.h:49
Definition: catch.hpp:343
Definition: catch.hpp:835
Definition: catch.hpp:540
Definition: CommonComponent.h:44
Definition: catch.hpp:1209
Definition: catch.hpp:322
Definition: catch.hpp:2348
Definition: catch.hpp:2545
Definition: catch.hpp:661
Definition: catch.hpp:2718
Definition: catch.hpp:1215
Definition: catch.hpp:1678
Definition: catch.hpp:547
Definition: catch.hpp:1312
std::string makeString(const char(&arrayLiteral)[N])
Safely and easily convert a literal array of characters (like from osvr_json_to_c) into a std::string...
Definition: StringLiteralFileToString.h:45
Definition: catch.hpp:1973
Definition: catch_typelist.h:23
Definition: catch.hpp:810
Definition: catch.hpp:1228
Definition: catch.hpp:676
Definition: catch.hpp:2355
Definition: catch.hpp:2572
Definition: catch.hpp:1609
Definition: catch.hpp:1645
OSVR_TimeValue operator+(OSVR_TimeValue const &tv, std::chrono::duration< Rep, Period > const &additionalTime)
Add a util::time::TimeValue and a std::chrono::duration.
Definition: TimeValueChrono.h:45
Definition: catch.hpp:1618
Definition: catch.hpp:2292
Definition: catch.hpp:1052
Definition: catch.hpp:1211
Definition: catch.hpp:420
Definition: catch.hpp:2792
double duration(TimeValue const &a, TimeValue const &b)
Get a double containing seconds between the time points.
Definition: TimeValue.h:62
Definition: catch.hpp:2269
detail::size< coerce_list< Ts... >> size
Get the size of a list (number of elements.)
Definition: Size.h:56
Definition: catch.hpp:2395
Definition: catch.hpp:2374
Definition: catch.hpp:849
Definition: catch.hpp:1092
Definition: catch.hpp:628
Definition: catch.hpp:1331
Definition: catch.hpp:2225
Definition: catch.hpp:919
Definition: newuoa.h:1888
Definition: catch.hpp:438
Definition: catch.hpp:904
t_< detail::transform_< List, Fun >> transform
Given a list and an alias class, apply the alias class to each element in the list and return the res...
Definition: Transform.h:54
Definition: catch.hpp:2537
Definition: catch.hpp:386
Definition: catch.hpp:499
Definition: catch.hpp:2711
Definition: catch.hpp:2732
Definition: catch.hpp:2567
Definition: catch.hpp:1610
Definition: catch.hpp:327
Definition: catch.hpp:2310
time_value_scalar_duration operator-(detail::TimeValueChronoWrapperBase< DerivedA > const &a, detail::TimeValueChronoWrapperBase< DerivedB > const &b)
Subtract one wrapped TimeValue from another and get a std::duration back!
Definition: TimeValueChrono.h:202
Definition: catch.hpp:1605
Definition: catch.hpp:2049
Definition: catch.hpp:468
Definition: MeasureTrackingCameraLatency.cpp:253
Definition: catch.hpp:1109
Computation was successful.
Definition: Constants.h:376
Definition: catch.hpp:1074
Definition: catch.hpp:782
Definition: catch.hpp:2819
Definition: catch.hpp:898
Definition: catch.hpp:2853
Definition: catch.hpp:899
Definition: catch.hpp:900
Definition: catch.hpp:2258
Definition: catch.hpp:1908
Definition: catch.hpp:2629
Definition: catch.hpp:377
Definition: catch.hpp:592
Definition: catch.hpp:858
Definition: catch.hpp:1929
Definition: catch.hpp:643
The main class implementing the common components of the Kalman family of filters.
Definition: FlexibleKalmanFilter.h:74
Definition: catch.hpp:1127
A "Unique Container" designed for composition, not inheritance.
Definition: UniqueContainer.h:327
Definition: catch.hpp:2578
Definition: catch.hpp:2193
Definition: catch.hpp:581
Definition: catch.hpp:1946
Definition: catch.hpp:474