11 #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED 12 #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED 16 #define CATCH_VERSION_MAJOR 2 17 #define CATCH_VERSION_MINOR 4 18 #define CATCH_VERSION_PATCH 2 21 # pragma clang system_header 22 #elif defined __GNUC__ 23 # pragma GCC system_header 29 # ifdef __ICC // icpc defines the __clang__ macro 30 # pragma warning(push) 31 # pragma warning(disable: 161 1682) 33 # pragma clang diagnostic push 34 # pragma clang diagnostic ignored "-Wpadded" 35 # pragma clang diagnostic ignored "-Wswitch-enum" 36 # pragma clang diagnostic ignored "-Wcovered-switch-default" 38 #elif defined __GNUC__ 42 # pragma GCC diagnostic ignored "-Wparentheses" 43 # pragma GCC diagnostic push 44 # pragma GCC diagnostic ignored "-Wunused-variable" 45 # pragma GCC diagnostic ignored "-Wpadded" 48 #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) 50 # define CATCH_CONFIG_ALL_PARTS 55 #if defined(CATCH_CONFIG_ALL_PARTS) 56 # define CATCH_CONFIG_EXTERNAL_INTERFACES 57 # if defined(CATCH_CONFIG_DISABLE_MATCHERS) 58 # undef CATCH_CONFIG_DISABLE_MATCHERS 60 # if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) 61 # define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER 65 #if !defined(CATCH_CONFIG_IMPL_ONLY) 69 # include <TargetConditionals.h> 70 # if TARGET_OS_OSX == 1 71 # define CATCH_PLATFORM_MAC 72 # elif TARGET_OS_IPHONE == 1 73 # define CATCH_PLATFORM_IPHONE 76 #elif defined(linux) || defined(__linux) || defined(__linux__) 77 # define CATCH_PLATFORM_LINUX 79 #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) 80 # define CATCH_PLATFORM_WINDOWS 86 # ifndef CLARA_CONFIG_MAIN 87 # define CLARA_CONFIG_MAIN_NOT_DEFINED 88 # define CLARA_CONFIG_MAIN 124 # if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L) 125 # define CATCH_CPP14_OR_GREATER 128 # if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) 129 # define CATCH_CPP17_OR_GREATER 134 #if defined(CATCH_CPP17_OR_GREATER) 135 # define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS 140 # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ 141 _Pragma( "clang diagnostic push" ) \ 142 _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ 143 _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") 144 # define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ 145 _Pragma( "clang diagnostic pop" ) 147 # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ 148 _Pragma( "clang diagnostic push" ) \ 149 _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) 150 # define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ 151 _Pragma( "clang diagnostic pop" ) 153 # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ 154 _Pragma( "clang diagnostic push" ) \ 155 _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) 156 # define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS \ 157 _Pragma( "clang diagnostic pop" ) 163 #if !defined(CATCH_PLATFORM_WINDOWS) 164 #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS 169 #if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__) 170 #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS 174 # define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS 175 # define CATCH_CONFIG_COLOUR_NONE 180 #if defined(__ANDROID__) 181 # define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING 186 #if defined(__MINGW32__) 187 # define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH 192 #if defined(__ORBIS__) 193 # define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE 205 # if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \ 206 && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) 208 # define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING 217 # if _MSC_VER >= 1900 // Visual Studio 2015 or newer 218 # define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS 223 # if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) 224 # define CATCH_CONFIG_COLOUR_NONE 226 # define CATCH_INTERNAL_CONFIG_WINDOWS_SEH 233 #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND) 234 # define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED 240 # define CATCH_INTERNAL_CONFIG_NO_WCHAR 250 #if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L ) 251 #define CATCH_INTERNAL_CONFIG_COUNTER 257 #if defined(__has_include) 258 #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER) 259 # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW 265 #if defined(__has_include) 266 # if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER) 267 # if defined(__clang__) && (__clang_major__ < 8) 271 # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) 272 # define CATCH_CONFIG_NO_CPP17_VARIANT 274 # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT 275 # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) 276 # endif // defined(__clang__) && (__clang_major__ < 8) 277 # endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER) 278 #endif // __has_include 280 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) 281 # define CATCH_CONFIG_COUNTER 283 #if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH) 284 # define CATCH_CONFIG_WINDOWS_SEH 287 #if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) 288 # define CATCH_CONFIG_POSIX_SIGNALS 291 #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR) 292 # define CATCH_CONFIG_WCHAR 295 #if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING) 296 # define CATCH_CONFIG_CPP11_TO_STRING 299 #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) 300 # define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS 303 #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW) 304 # define CATCH_CONFIG_CPP17_STRING_VIEW 307 #if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT) 308 # define CATCH_CONFIG_CPP17_VARIANT 311 #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) 312 # define CATCH_INTERNAL_CONFIG_NEW_CAPTURE 315 #if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE) 316 # define CATCH_CONFIG_NEW_CAPTURE 319 #if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) 320 # define CATCH_CONFIG_DISABLE_EXCEPTIONS 323 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) 324 # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS 325 # define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS 327 #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) 328 # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS 329 # define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS 331 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS) 332 # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS 333 # define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS 336 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) 337 #define CATCH_TRY if ((true)) 338 #define CATCH_CATCH_ALL if ((false)) 339 #define CATCH_CATCH_ANON(type) if ((false)) 341 #define CATCH_TRY try 342 #define CATCH_CATCH_ALL catch (...) 343 #define CATCH_CATCH_ANON(type) catch (type) 347 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line 348 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) 349 #ifdef CATCH_CONFIG_COUNTER 350 # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) 352 # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) 394 bool empty()
const noexcept;
422 #define CATCH_INTERNAL_LINEINFO \ 423 ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) ) 434 #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \ 435 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ 436 namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \ 437 CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS 452 virtual void invoke ()
const = 0;
463 virtual std::vector<TestCase>
const& getAllTests()
const = 0;
464 virtual std::vector<TestCase>
const& getAllTestsSorted( IConfig
const& config )
const = 0;
467 bool matchTest(
TestCase const& testCase, TestSpec
const& testSpec, IConfig
const& config );
468 std::vector<TestCase>
filterTests( std::vector<TestCase>
const& testCases, TestSpec
const& testSpec, IConfig
const& config );
496 friend struct StringRefTestAccess;
501 char* m_data =
nullptr;
503 void takeOwnership();
505 static constexpr
char const*
const s_empty =
"";
513 : m_start( other.m_start ),
514 m_size( other.m_size )
518 : m_start( other.m_start ),
519 m_size( other.m_size ),
520 m_data( other.m_data )
522 other.m_data =
nullptr;
525 StringRef(
char const* rawChars ) noexcept;
528 : m_start( rawChars ),
533 : m_start( stdString.c_str() ),
534 m_size( stdString.size() )
545 m_size = other.m_size;
549 operator std::string()
const;
554 auto operator == (
StringRef const& other )
const noexcept -> bool;
555 auto operator != (
StringRef const& other )
const noexcept -> bool;
557 auto operator[] (
size_type index )
const noexcept -> char;
560 auto empty() const noexcept ->
bool {
567 auto numberOfCharacters()
const noexcept ->
size_type;
568 auto c_str()
const ->
char const*;
575 auto currentData()
const noexcept ->
char const*;
578 auto isOwned()
const noexcept -> bool;
579 auto isSubstring()
const noexcept -> bool;
589 inline auto operator "" _sr(
char const* rawChars, std::size_t size ) noexcept ->
StringRef {
595 inline auto operator "" _catch_sr(
char const* rawChars, std::size_t size ) noexcept ->
Catch::StringRef {
604 void (C::*m_testAsMethod)();
610 (obj.*m_testAsMethod)();
634 #define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) 635 #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ 636 #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ 637 #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF 639 #if defined(CATCH_CONFIG_DISABLE) 640 #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \ 641 static void TestName() 642 #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \ 644 struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \ 648 void TestName::test() 653 #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \ 654 static void TestName(); \ 655 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ 656 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } \ 657 CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ 658 static void TestName() 659 #define INTERNAL_CATCH_TESTCASE( ... ) \ 660 INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ ) 663 #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ 664 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ 665 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } \ 666 CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS 669 #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\ 670 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ 672 struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \ 675 Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); \ 677 CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ 678 void TestName::test() 679 #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \ 680 INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ ) 683 #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \ 684 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ 685 Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); \ 686 CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS 708 ExpressionFailed = FailureBit | 1,
709 ExplicitFailure = FailureBit | 2,
711 Exception = 0x100 | FailureBit,
713 ThrewException = Exception | 1,
714 DidntThrowException = Exception | 2,
716 FatalErrorCondition = 0x200 | FailureBit
727 ContinueOnFailure = 0x02,
764 #include <type_traits> 774 std::ostream&
cout();
775 std::ostream&
cerr();
776 std::ostream&
clog();
782 virtual std::ostream& stream()
const = 0;
794 auto str() const ->
std::
string;
801 auto get() -> std::ostream& {
return *m_oss; }
807 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW 808 #include <string_view> 814 #import <Foundation/Foundation.h> 817 #define CATCH_ARC_ENABLED __has_feature(objc_arc) 819 #define CATCH_ARC_ENABLED 0 822 void arcSafeRelease( NSObject* obj );
823 id performOptionalSelector(
id obj,
SEL sel );
825 #if !CATCH_ARC_ENABLED 826 inline void arcSafeRelease( NSObject* obj ) {
829 inline id performOptionalSelector(
id obj,
SEL sel ) {
830 if( [obj respondsToSelector: sel] )
831 return [obj performSelector: sel];
834 #define CATCH_UNSAFE_UNRETAINED 835 #define CATCH_ARC_STRONG 837 inline void arcSafeRelease( NSObject* ){}
838 inline id performOptionalSelector(
id obj,
SEL sel ) {
840 #pragma clang diagnostic push 841 #pragma clang diagnostic ignored "-Warc-performSelector-leaks" 843 if( [obj respondsToSelector: sel] )
844 return [obj performSelector: sel];
846 #pragma clang diagnostic pop 850 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained 851 #define CATCH_ARC_STRONG __strong 858 #pragma warning(push) 859 #pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless 876 template<
typename SS,
typename TT>
877 static auto test(
int)
878 -> decltype(std::declval<SS&>() << std::declval<TT>(), std::true_type());
880 template<
typename,
typename>
881 static auto test(...)->std::false_type;
884 static const bool value = decltype(test<std::ostream, const T&>(0))::value;
891 typename std::enable_if<
897 typename std::enable_if<
904 typename std::enable_if<
910 #if defined(_MANAGED) 913 std::string clrReferenceToString( T^ ref ) {
915 return std::string(
"null");
916 auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
917 cli::pin_ptr<System::Byte> p = &bytes[0];
918 return std::string(reinterpret_cast<char const *>(p), bytes->Length);
925 template <
typename T,
typename =
void>
927 template <
typename Fake = T>
934 rss.operator<<(
value);
938 template <
typename Fake = T>
942 #if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER) 945 return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
954 template <
typename T>
956 return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
964 #if defined(_MANAGED) 965 template <
typename T>
967 return ::Catch::StringMaker<T^>::convert(e);
977 static std::string convert(
const std::string& str);
980 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW 983 static std::string convert(std::string_view str);
989 static std::string convert(
char const * str);
993 static std::string convert(
char * str);
996 #ifdef CATCH_CONFIG_WCHAR 999 static std::string convert(
const std::wstring& wstr);
1002 # ifdef CATCH_CONFIG_CPP17_STRING_VIEW 1005 static std::string convert(std::wstring_view str);
1011 static std::string convert(
wchar_t const * str);
1015 static std::string convert(
wchar_t * str);
1029 static std::string
convert(
signed char const* str) {
1035 static std::string
convert(
unsigned char const* str) {
1042 static std::string convert(
int value);
1046 static std::string convert(
long value);
1050 static std::string convert(
long long value);
1054 static std::string convert(
unsigned int value);
1058 static std::string convert(
unsigned long value);
1062 static std::string convert(
unsigned long long value);
1067 static std::string convert(
bool b);
1072 static std::string convert(
char c);
1076 static std::string convert(
signed char c);
1080 static std::string convert(
unsigned char c);
1085 static std::string convert(std::nullptr_t);
1090 static std::string convert(
float value);
1094 static std::string convert(
double value);
1097 template <
typename T>
1099 template <
typename U>
1109 template <
typename R,
typename C>
1120 #if defined(_MANAGED) 1121 template <
typename T>
1123 static std::string convert( T^ ref ) {
1124 return ::Catch::Detail::clrReferenceToString(ref);
1130 template<
typename InputIterator>
1134 if (first != last) {
1136 for (++first; first != last; ++first)
1147 static std::string convert(NSString * nsstring) {
1150 return std::string(
"@") + [nsstring UTF8String];
1155 static std::string convert(NSObject* nsObject) {
1161 inline std::string
stringify( NSString* nsstring ) {
1174 #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS) 1175 # define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER 1176 # define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER 1177 # define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER 1178 # define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER 1182 #if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER) 1185 template<
typename T1,
typename T2>
1187 static std::string convert(
const std::pair<T1, T2>& pair) {
1198 #endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER 1201 #if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER) 1210 struct TupleElementPrinter {
1211 static void print(
const Tuple& tuple, std::ostream& os) {
1212 os << (N ?
", " :
" ")
1214 TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
1222 struct TupleElementPrinter<Tuple, N, false> {
1223 static void print(
const Tuple&, std::ostream&) {}
1228 template<
typename ...Types>
1230 static std::string convert(
const std::tuple<Types...>& tuple) {
1233 Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.
get());
1239 #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER 1241 #if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT) 1246 static std::string convert(
const std::monostate&) {
1251 template<
typename... Elements>
1253 static std::string convert(
const std::variant<Elements...>& variant) {
1254 if (variant.valueless_by_exception()) {
1255 return "{valueless variant}";
1258 [](
const auto&
value) {
1267 #endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER 1279 template <
typename T>
1286 #if defined(_MANAGED) // Managed types are never ranges 1287 template <
typename T>
1289 static const bool value =
false;
1293 template<
typename Range>
1299 template<
typename Allocator>
1315 template<
typename R>
1316 struct StringMaker<R, typename
std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {
1322 template <
typename T,
int SZ>
1332 #if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) 1339 template <
class Ratio>
1340 struct ratio_string {
1341 static std::string symbol();
1344 template <
class Ratio>
1345 std::string ratio_string<Ratio>::symbol() {
1347 rss <<
'[' << Ratio::num <<
'/' 1348 << Ratio::den <<
']';
1352 struct ratio_string<std::atto> {
1353 static std::string symbol();
1356 struct ratio_string<std::femto> {
1357 static std::string symbol();
1360 struct ratio_string<std::pico> {
1361 static std::string symbol();
1364 struct ratio_string<std::nano> {
1365 static std::string symbol();
1368 struct ratio_string<std::micro> {
1369 static std::string symbol();
1372 struct ratio_string<std::milli> {
1373 static std::string symbol();
1378 template<
typename Value,
typename Ratio>
1379 struct StringMaker<std::chrono::duration<Value, Ratio>> {
1380 static std::string convert(std::chrono::duration<Value, Ratio>
const& duration) {
1382 rss << duration.count() <<
' ' << ratio_string<Ratio>::symbol() <<
's';
1386 template<
typename Value>
1387 struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
1388 static std::string convert(std::chrono::duration<Value, std::ratio<1>>
const& duration) {
1390 rss << duration.count() <<
" s";
1394 template<
typename Value>
1395 struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
1396 static std::string convert(std::chrono::duration<Value, std::ratio<60>>
const& duration) {
1398 rss << duration.count() <<
" m";
1402 template<
typename Value>
1403 struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
1404 static std::string convert(std::chrono::duration<Value, std::ratio<3600>>
const& duration) {
1406 rss << duration.count() <<
" h";
1414 template<
typename Clock,
typename Duration>
1415 struct StringMaker<std::chrono::time_point<Clock, Duration>> {
1416 static std::string convert(std::chrono::time_point<Clock, Duration>
const& time_point) {
1421 template<
typename Duration>
1422 struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
1423 static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration>
const& time_point) {
1424 auto converted = std::chrono::system_clock::to_time_t(time_point);
1427 std::tm timeInfo = {};
1428 gmtime_s(&timeInfo, &converted);
1430 std::tm* timeInfo = std::gmtime(&converted);
1433 auto const timeStampSize =
sizeof(
"2017-01-16T17:06:45Z");
1435 const char *
const fmt =
"%Y-%m-%dT%H:%M:%SZ";
1438 std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
1440 std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
1442 return std::string(timeStamp);
1446 #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER 1449 #pragma warning(pop) 1456 #pragma warning(push) 1457 #pragma warning(disable:4389) // '==' : signed/unsigned mismatch 1458 #pragma warning(disable:4018) // more "signed/unsigned mismatch" 1459 #pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform) 1460 #pragma warning(disable:4180) // qualifier applied to function type has no meaning 1468 virtual void streamReconstructedExpression( std::ostream &os )
const = 0;
1471 : m_isBinaryExpression( isBinaryExpression ),
1486 template<
typename LhsT,
typename RhsT>
1506 template<
typename LhsT>
1522 template<
typename LhsT,
typename RhsT>
1523 auto compareEqual( LhsT
const& lhs, RhsT
const& rhs ) ->
bool {
return static_cast<bool>(lhs == rhs); }
1524 template<
typename T>
1525 auto compareEqual( T*
const& lhs,
int rhs ) ->
bool {
return lhs ==
reinterpret_cast<void const*
>( rhs ); }
1526 template<
typename T>
1527 auto compareEqual( T*
const& lhs,
long rhs ) ->
bool {
return lhs ==
reinterpret_cast<void const*
>( rhs ); }
1528 template<
typename T>
1529 auto compareEqual(
int lhs, T*
const& rhs ) ->
bool {
return reinterpret_cast<void const*
>( lhs ) == rhs; }
1530 template<
typename T>
1531 auto compareEqual(
long lhs, T*
const& rhs ) ->
bool {
return reinterpret_cast<void const*
>( lhs ) == rhs; }
1533 template<
typename LhsT,
typename RhsT>
1534 auto compareNotEqual( LhsT
const& lhs, RhsT&& rhs ) ->
bool {
return static_cast<bool>(lhs != rhs); }
1535 template<
typename T>
1536 auto compareNotEqual( T*
const& lhs,
int rhs ) ->
bool {
return lhs !=
reinterpret_cast<void const*
>( rhs ); }
1537 template<
typename T>
1538 auto compareNotEqual( T*
const& lhs,
long rhs ) ->
bool {
return lhs !=
reinterpret_cast<void const*
>( rhs ); }
1539 template<
typename T>
1540 auto compareNotEqual(
int lhs, T*
const& rhs ) ->
bool {
return reinterpret_cast<void const*
>( lhs ) != rhs; }
1541 template<
typename T>
1542 auto compareNotEqual(
long lhs, T*
const& rhs ) ->
bool {
return reinterpret_cast<void const*
>( lhs ) != rhs; }
1544 template<
typename LhsT>
1550 template<
typename RhsT>
1552 return {
compareEqual( m_lhs, rhs ), m_lhs,
"==", rhs };
1555 return { m_lhs == rhs, m_lhs,
"==", rhs };
1558 template<
typename RhsT>
1563 return { m_lhs != rhs, m_lhs,
"!=", rhs };
1566 template<
typename RhsT>
1568 return {
static_cast<bool>(m_lhs > rhs), m_lhs,
">", rhs };
1570 template<
typename RhsT>
1572 return {
static_cast<bool>(m_lhs < rhs), m_lhs,
"<", rhs };
1574 template<
typename RhsT>
1576 return {
static_cast<bool>(m_lhs >= rhs), m_lhs,
">=", rhs };
1578 template<
typename RhsT>
1580 return {
static_cast<bool>(m_lhs <= rhs), m_lhs,
"<=", rhs };
1590 template<
typename T>
1596 template<
typename T>
1609 #pragma warning(pop) 1619 class AssertionResult;
1625 struct BenchmarkInfo;
1626 struct BenchmarkStats;
1637 virtual bool sectionStarted(
SectionInfo const& sectionInfo,
1638 Counts& assertions ) = 0;
1640 virtual void sectionEndedEarly(
SectionEndInfo const& endInfo ) = 0;
1644 virtual void benchmarkStarting( BenchmarkInfo
const& info ) = 0;
1645 virtual void benchmarkEnded( BenchmarkStats
const& stats ) = 0;
1647 virtual void pushScopedMessage(
MessageInfo const& message ) = 0;
1648 virtual void popScopedMessage(
MessageInfo const& message ) = 0;
1650 virtual void handleFatalErrorCondition(
StringRef message ) = 0;
1652 virtual void handleExpr
1656 virtual void handleMessage
1661 virtual void handleUnexpectedExceptionNotThrown
1664 virtual void handleUnexpectedInflightException
1666 std::string
const& message,
1668 virtual void handleIncomplete
1670 virtual void handleNonExpr
1675 virtual bool lastAssertionPassed() = 0;
1676 virtual void assertionPassed() = 0;
1679 virtual std::string getCurrentTestName()
const = 0;
1680 virtual const AssertionResult* getLastResult()
const = 0;
1681 virtual void exceptionEarlyReported() = 0;
1691 struct AssertionResultData;
1697 friend struct AssertionStats;
1698 friend class RunContext;
1707 explicit operator bool()
const;
1713 bool shouldDebugBreak =
false;
1714 bool shouldThrow =
false;
1720 bool m_completed =
false;
1730 if ( !m_completed ) {
1735 template<
typename T>
1743 void handleExceptionThrownAsExpected();
1744 void handleUnexpectedExceptionNotThrown();
1745 void handleExceptionNotThrownAsExpected();
1746 void handleThrowingCallSkipped();
1747 void handleUnexpectedInflightException();
1750 void setCompleted();
1753 auto allowThrows()
const -> bool;
1779 bool operator == (
MessageInfo const& other )
const;
1780 bool operator < (
MessageInfo const& other )
const;
1787 template<
typename T>
1801 template<
typename T>
1821 size_t m_captured = 0;
1828 template<
typename T>
1833 template<
typename T,
typename... Ts>
1835 captureValues( index,
value );
1836 captureValues( index+1,
values... );
1843 #if !defined(CATCH_CONFIG_DISABLE) 1845 #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION) 1846 #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__ 1848 #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION" 1851 #if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) 1856 #define INTERNAL_CATCH_TRY 1857 #define INTERNAL_CATCH_CATCH( capturer ) 1859 #else // CATCH_CONFIG_FAST_COMPILE 1861 #define INTERNAL_CATCH_TRY try 1862 #define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); } 1866 #define INTERNAL_CATCH_REACT( handler ) handler.complete(); 1869 #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \ 1871 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \ 1872 INTERNAL_CATCH_TRY { \ 1873 CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ 1874 catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \ 1875 CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ 1876 } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \ 1877 INTERNAL_CATCH_REACT( catchAssertionHandler ) \ 1878 } while( (void)0, false && static_cast<bool>( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look 1882 #define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \ 1883 INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \ 1884 if( Catch::getResultCapture().lastAssertionPassed() ) 1887 #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \ 1888 INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \ 1889 if( !Catch::getResultCapture().lastAssertionPassed() ) 1892 #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \ 1894 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \ 1896 static_cast<void>(__VA_ARGS__); \ 1897 catchAssertionHandler.handleExceptionNotThrownAsExpected(); \ 1900 catchAssertionHandler.handleUnexpectedInflightException(); \ 1902 INTERNAL_CATCH_REACT( catchAssertionHandler ) \ 1906 #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \ 1908 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \ 1909 if( catchAssertionHandler.allowThrows() ) \ 1911 static_cast<void>(__VA_ARGS__); \ 1912 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ 1915 catchAssertionHandler.handleExceptionThrownAsExpected(); \ 1918 catchAssertionHandler.handleThrowingCallSkipped(); \ 1919 INTERNAL_CATCH_REACT( catchAssertionHandler ) \ 1923 #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \ 1925 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \ 1926 if( catchAssertionHandler.allowThrows() ) \ 1928 static_cast<void>(expr); \ 1929 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ 1931 catch( exceptionType const& ) { \ 1932 catchAssertionHandler.handleExceptionThrownAsExpected(); \ 1935 catchAssertionHandler.handleUnexpectedInflightException(); \ 1938 catchAssertionHandler.handleThrowingCallSkipped(); \ 1939 INTERNAL_CATCH_REACT( catchAssertionHandler ) \ 1943 #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \ 1945 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \ 1946 catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \ 1947 INTERNAL_CATCH_REACT( catchAssertionHandler ) \ 1951 #define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \ 1952 auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \ 1953 varName.captureValues( 0, __VA_ARGS__ ) 1956 #define INTERNAL_CATCH_INFO( macroName, log ) \ 1957 Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log ); 1961 #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \ 1963 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ 1964 if( catchAssertionHandler.allowThrows() ) \ 1966 static_cast<void>(__VA_ARGS__); \ 1967 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ 1970 Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \ 1973 catchAssertionHandler.handleThrowingCallSkipped(); \ 1974 INTERNAL_CATCH_REACT( catchAssertionHandler ) \ 1977 #endif // CATCH_CONFIG_DISABLE 1994 std::size_t total()
const;
1995 bool allPassed()
const;
1998 std::size_t passed = 0;
1999 std::size_t failed = 0;
2000 std::size_t failedButOk = 0;
2024 std::string
const& _name );
2029 std::string
const& _name,
2030 std::string
const& ) :
SectionInfo( _lineInfo, _name ) {}
2056 uint64_t m_nanoseconds = 0;
2059 auto getElapsedNanoseconds() const -> uint64_t;
2060 auto getElapsedMicroseconds() const -> uint64_t;
2061 auto getElapsedMilliseconds() const ->
unsigned int;
2062 auto getElapsedSeconds() const ->
double;
2078 explicit operator bool()
const;
2091 #define INTERNAL_CATCH_SECTION( ... ) \ 2092 CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ 2093 if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \ 2094 CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS 2096 #define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \ 2097 CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ 2098 if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \ 2099 CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS 2112 std::size_t m_count = 0;
2113 std::size_t m_iterationsToRun = 1;
2117 static auto getResolution() -> uint64_t;
2122 m_resolution( getResolution() )
2128 explicit operator bool() {
2129 if( m_count < m_iterationsToRun )
2131 return needsMoreIterations();
2139 auto needsMoreIterations() -> bool;
2144 #define BENCHMARK( name ) \ 2145 for( Catch::BenchmarkLooper looper( name ); looper; looper.increment() ) 2158 struct ITestCaseRegistry;
2159 struct IExceptionTranslatorRegistry;
2160 struct IExceptionTranslator;
2161 struct IReporterRegistry;
2162 struct IReporterFactory;
2163 struct ITagAliasRegistry;
2164 class StartupExceptionRegistry;
2171 virtual IReporterRegistry
const& getReporterRegistry()
const = 0;
2173 virtual ITagAliasRegistry
const& getTagAliasRegistry()
const = 0;
2177 virtual StartupExceptionRegistry
const& getStartupExceptionRegistry()
const = 0;
2182 virtual void registerReporter( std::string
const& name,
IReporterFactoryPtr const& factory ) = 0;
2184 virtual void registerTest(
TestCase const& testInfo ) = 0;
2186 virtual void registerTagAlias( std::string
const& alias, std::string
const& tag,
SourceLineInfo const& lineInfo ) = 0;
2187 virtual void registerStartupException() noexcept = 0;
2198 #if defined(CATCH_CONFIG_DISABLE) 2199 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \ 2200 static std::string translatorName( signature ) 2203 #include <exception> 2215 virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd )
const = 0;
2225 template<
typename T>
2230 : m_translateFunction( translateFunction )
2233 std::string
translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd )
const override {
2236 std::rethrow_exception(std::current_exception());
2238 return (*it)->translate( it+1, itEnd );
2241 return m_translateFunction( ex );
2246 std::string(*m_translateFunction)( T& );
2250 template<
typename T>
2259 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \ 2260 static std::string translatorName( signature ); \ 2261 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ 2262 namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \ 2263 CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ 2264 static std::string translatorName( signature ) 2266 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) 2271 #include <type_traits> 2278 bool equalityComparisonImpl(
double other)
const;
2281 void setMargin(
double margin);
2284 void setEpsilon(
double epsilon);
2291 Approx operator-()
const;
2295 Approx approx( static_cast<double>(value) );
2307 friend bool operator == (
const T& lhs,
Approx const& rhs ) {
2308 auto lhs_v =
static_cast<double>(lhs);
2313 friend bool operator == (
Approx const& lhs,
const T& rhs ) {
2314 return operator==( rhs, lhs );
2318 friend bool operator != ( T
const& lhs,
Approx const& rhs ) {
2319 return !operator==( lhs, rhs );
2323 friend bool operator != (
Approx const& lhs, T
const& rhs ) {
2324 return !operator==( rhs, lhs );
2328 friend bool operator <= ( T
const& lhs,
Approx const& rhs ) {
2329 return static_cast<double>(lhs) < rhs.
m_value || lhs == rhs;
2333 friend bool operator <= (
Approx const& lhs, T
const& rhs ) {
2334 return lhs.
m_value <
static_cast<double>(rhs) || lhs == rhs;
2338 friend bool operator >= ( T
const& lhs,
Approx const& rhs ) {
2339 return static_cast<double>(lhs) > rhs.
m_value || lhs == rhs;
2343 friend bool operator >= (
Approx const& lhs, T
const& rhs ) {
2344 return lhs.
m_value >
static_cast<double>(rhs) || lhs == rhs;
2349 double epsilonAsDouble =
static_cast<double>(newEpsilon);
2350 setEpsilon(epsilonAsDouble);
2356 double marginAsDouble =
static_cast<double>(newMargin);
2357 setMargin(marginAsDouble);
2363 m_scale =
static_cast<double>(newScale);
2367 std::string toString()
const;
2377 namespace literals {
2397 bool startsWith( std::string
const&
s, std::string
const& prefix );
2398 bool startsWith( std::string
const& s,
char prefix );
2399 bool endsWith( std::string
const& s, std::string
const& suffix );
2400 bool endsWith( std::string
const& s,
char suffix );
2401 bool contains( std::string
const& s, std::string
const& infix );
2403 std::string
toLower( std::string
const& s );
2404 std::string
trim( std::string
const& str );
2405 bool replaceInPlace( std::string& str, std::string
const& replaceThis, std::string
const& withThis );
2418 #ifndef CATCH_CONFIG_DISABLE_MATCHERS 2427 namespace Matchers {
2439 std::string toString()
const;
2443 virtual std::string describe()
const = 0;
2448 # pragma clang diagnostic push 2449 # pragma clang diagnostic ignored "-Wnon-virtual-dtor" 2452 template<
typename ObjectT>
2454 virtual bool match( ObjectT
const& arg )
const = 0;
2456 template<
typename PtrT>
2458 virtual bool match( PtrT* arg )
const = 0;
2462 # pragma clang diagnostic pop 2465 template<
typename T>
2473 template<
typename ArgT>
2475 bool match( ArgT
const& arg )
const override {
2476 for(
auto matcher : m_matchers ) {
2477 if (!matcher->match(arg))
2483 std::string description;
2484 description.reserve( 4 + m_matchers.size()*32 );
2485 description +=
"( ";
2487 for(
auto matcher : m_matchers ) {
2491 description +=
" and ";
2492 description += matcher->toString();
2494 description +=
" )";
2499 m_matchers.push_back( &other );
2505 template<
typename ArgT>
2508 bool match( ArgT
const& arg )
const override {
2509 for(
auto matcher : m_matchers ) {
2510 if (matcher->match(arg))
2516 std::string description;
2517 description.reserve( 4 + m_matchers.size()*32 );
2518 description +=
"( ";
2520 for(
auto matcher : m_matchers ) {
2524 description +=
" or ";
2525 description += matcher->toString();
2527 description +=
" )";
2532 m_matchers.push_back( &other );
2539 template<
typename ArgT>
2544 bool match( ArgT
const& arg )
const override {
2545 return !m_underlyingMatcher.match( arg );
2549 return "not " + m_underlyingMatcher.toString();
2554 template<
typename T>
2558 template<
typename T>
2562 template<
typename T>
2571 using namespace Matchers;
2579 #include <type_traits> 2583 namespace Matchers {
2585 namespace Floating {
2587 enum class FloatingPointKind : uint8_t;
2591 bool match(
double const& matchee)
const override;
2592 std::string describe()
const override;
2600 bool match(
double const& matchee)
const override;
2601 std::string describe()
const override;
2622 #include <functional> 2626 namespace Matchers {
2633 template <
typename T>
2640 :m_predicate(
std::move(elem)),
2644 bool match( T
const& item )
const override {
2645 return m_predicate(item);
2649 return m_description;
2659 template<
typename T>
2673 namespace Matchers {
2675 namespace StdString {
2680 std::string adjustString( std::string
const& str )
const;
2681 std::string caseSensitivitySuffix()
const;
2689 std::string describe()
const override;
2697 bool match( std::string
const& source )
const override;
2701 bool match( std::string
const& source )
const override;
2705 bool match( std::string
const& source )
const override;
2709 bool match( std::string
const& source )
const override;
2714 bool match( std::string
const& matchee )
const override;
2715 std::string describe()
const override;
2739 #include <algorithm> 2742 namespace Matchers {
2746 template <
typename InputIterator,
typename T>
2747 size_t count(InputIterator first, InputIterator last, T
const& item) {
2749 for (; first != last; ++first) {
2750 if (*first == item) {
2756 template <
typename InputIterator,
typename T>
2757 bool contains(InputIterator first, InputIterator last, T
const& item) {
2758 for (; first != last; ++first) {
2759 if (*first == item) {
2767 template<
typename T>
2772 bool match(std::vector<T>
const &v)
const override {
2773 for (
auto const& el : v) {
2774 if (el == m_comparator) {
2788 template<
typename T>
2793 bool match(std::vector<T>
const &v)
const override {
2795 if (m_comparator.size() > v.size())
2797 for (
auto const& comparator : m_comparator) {
2798 auto present =
false;
2799 for (
const auto& el : v) {
2800 if (el == comparator) {
2818 template<
typename T>
2823 bool match(std::vector<T>
const &v)
const override {
2828 if (m_comparator.size() != v.size())
2830 for (std::size_t i = 0; i < v.size(); ++i)
2831 if (m_comparator[i] != v[i])
2841 template<
typename T>
2844 bool match(std::vector<T>
const& vec)
const override {
2847 if (m_target.size() != vec.size()) {
2850 auto lfirst = m_target.begin(), llast = m_target.end();
2851 auto rfirst = vec.begin(), rlast = vec.end();
2853 while (lfirst != llast && *lfirst == *rfirst) {
2856 if (lfirst == llast) {
2860 for (
auto mid = lfirst; mid != llast; ++mid) {
2866 if (num_vec == 0 ||
Detail::count(lfirst, llast, *mid) != num_vec) {
2886 template<
typename T>
2891 template<
typename T>
2896 template<
typename T>
2901 template<
typename T>
2912 template<
typename ArgT,
typename MatcherT>
2921 m_matcher( matcher ),
2922 m_matcherString( matcherString )
2926 auto matcherAsString = m_matcher.toString();
2929 os << m_matcherString;
2931 os << matcherAsString;
2939 template<
typename ArgT,
typename MatcherT>
2947 #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \ 2949 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ 2950 INTERNAL_CATCH_TRY { \ 2951 catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \ 2952 } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \ 2953 INTERNAL_CATCH_REACT( catchAssertionHandler ) \ 2957 #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \ 2959 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ 2960 if( catchAssertionHandler.allowThrows() ) \ 2962 static_cast<void>(__VA_ARGS__ ); \ 2963 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ 2965 catch( exceptionType const& ex ) { \ 2966 catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \ 2969 catchAssertionHandler.handleUnexpectedInflightException(); \ 2972 catchAssertionHandler.handleThrowingCallSkipped(); \ 2973 INTERNAL_CATCH_REACT( catchAssertionHandler ) \ 2995 auto size() const ->
size_t {
return m_size; }
3003 virtual auto hasGenerator()
const ->
bool = 0;
3006 virtual auto getIndex()
const -> std::size_t = 0;
3014 #include <stdexcept> 3017 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) 3018 template <
typename Ex>
3023 #else // ^^ Exceptions are enabled // Exceptions are disabled vv 3029 #define CATCH_PREPARE_EXCEPTION( type, msg ) \ 3030 type( ( Catch::ReusableStringStream() << msg ).str() ) 3031 #define CATCH_INTERNAL_ERROR( msg ) \ 3032 Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg)) 3033 #define CATCH_ERROR( msg ) \ 3034 Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::domain_error, msg )) 3035 #define CATCH_RUNTIME_ERROR( msg ) \ 3036 Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::runtime_error, msg )) 3037 #define CATCH_ENFORCE( condition, msg ) \ 3038 do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false) 3048 namespace Generators {
3052 template<
typename T,
typename... Args>
3054 return std::unique_ptr<T>(
new T(std::forward<Args>(args)...));
3058 template<
typename T>
3061 virtual auto get(
size_t index )
const -> T = 0;
3064 template<
typename T>
3070 auto get( size_t )
const -> T
override {
3075 template<
typename T>
3082 auto get(
size_t index )
const -> T
override {
3083 return m_values[index];
3087 template<
typename T>
3094 assert( m_last > m_first );
3097 auto get(
size_t index )
const -> T
override {
3099 return static_cast<T
>(m_first+index);
3103 template<
typename T>
3105 auto get( size_t )
const -> T
override {
3110 template<
typename T>
3117 : m_generator(
std::move( generator ) ),
3121 auto size() const ->
size_t {
return m_size; }
3123 assert( index < m_size );
3124 return m_generator->get( index );
3128 std::vector<size_t>
randomiseIndices(
size_t selectionSize,
size_t sourceSize );
3130 template<
typename T>
3137 : m_baseGenerator(
std::move( baseGenerator ) ),
3138 m_indices( randomiseIndices( numberOfItems, m_baseGenerator.size() ) )
3141 auto get(
size_t index )
const -> T
override {
3142 return m_baseGenerator[m_indices[index]];
3146 template<
typename T>
3149 template<
typename T>
3155 template<
typename T>
3160 template<
typename T>
3162 auto gen =
range( first, last );
3163 auto size = gen.size();
3165 return Generator<T>( size, pf::make_unique<GeneratorRandomiser<T>>( std::move( gen ), size ) );
3167 template<
typename T>
3169 return Generator<T>( size, pf::make_unique<GeneratorRandomiser<T>>( all<T>(), size ) );
3172 template<
typename T>
3176 template<
typename T>
3178 return Generator<T>( 1, pf::make_unique<SingleValueGenerator<T>>( val ) );
3181 template<
typename T>
3183 return Generator<T>( 0, pf::make_unique<NullGenerator<T>>() );
3186 template<
typename... Ts>
3187 auto table( std::initializer_list<std::tuple<Ts...>>&& tuples ) ->
Generator<std::tuple<Ts...>> {
3188 return values<std::tuple<Ts...>>( std::forward<std::initializer_list<std::tuple<Ts...>>>( tuples ) );
3191 template<
typename T>
3201 m_generators.emplace_back(
value( std::move( val ) ) );
3203 template<
typename U>
3205 populate( T( std::move( val ) ) );
3208 m_size += generator.size();
3209 m_generators.emplace_back( std::move( generator ) );
3212 template<
typename U,
typename... Gs>
3213 void populate( U&& valueOrGenerator, Gs... moreGenerators ) {
3214 populate( std::forward<U>( valueOrGenerator ) );
3215 populate( std::forward<Gs>( moreGenerators )... );
3220 for(
auto const& gen : m_generators ) {
3221 auto localIndex = index-sizes;
3222 sizes += gen.size();
3224 return gen[localIndex];
3230 template<
typename T,
typename... Gs>
3233 generators.m_generators.reserve( 1+
sizeof...(Gs) );
3234 generators.populate( std::move( generator ), std::forward<Gs>( moreGenerators )... );
3237 template<
typename T>
3240 generators.populate( std::move( generator ) );
3243 template<
typename T,
typename... Gs>
3245 return makeGenerators(
value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
3247 template<
typename T,
typename U,
typename... Gs>
3249 return makeGenerators(
value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
3254 template<
typename L>
3258 auto generate(
SourceLineInfo const& lineInfo, L
const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>()[0]) {
3259 using UnderlyingType =
typename decltype(generatorExpression())::type;
3266 return generator[tracker.
getIndex()];
3272 #define GENERATE( ... ) \ 3273 Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, []{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) 3286 #pragma clang diagnostic push 3287 #pragma clang diagnostic ignored "-Wpadded" 3292 struct ITestInvoker;
3298 ShouldFail = 1 << 2,
3301 NonPortable = 1 << 5,
3306 std::string
const& _className,
3307 std::string
const& _description,
3308 std::vector<std::string>
const& _tags,
3311 friend void setTags(
TestCaseInfo& testCaseInfo, std::vector<std::string> tags );
3313 bool isHidden()
const;
3314 bool throws()
const;
3315 bool okToFail()
const;
3316 bool expectedToFail()
const;
3318 std::string tagsAsString()
const;
3334 TestCase withName( std::string
const& _newName )
const;
3336 void invoke()
const;
3340 bool operator == (
TestCase const& other )
const;
3341 bool operator < (
TestCase const& other )
const;
3344 std::shared_ptr<ITestInvoker>
test;
3348 std::string
const& className,
3354 #pragma clang diagnostic pop 3364 virtual bool aborting()
const = 0;
3373 #import <objc/runtime.h> 3398 OcMethod( Class cls,
SEL sel ) : m_cls( cls ), m_sel( sel ) {}
3400 virtual void invoke()
const {
3401 id obj = [[m_cls alloc] init];
3403 performOptionalSelector( obj,
@selector(setUp) );
3404 performOptionalSelector( obj, m_sel );
3405 performOptionalSelector( obj,
@selector(tearDown) );
3407 arcSafeRelease( obj );
3410 virtual ~OcMethod() {}
3418 inline std::string getAnnotation( Class cls,
3419 std::string
const& annotationName,
3420 std::string
const& testCaseName ) {
3421 NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
3422 SEL sel = NSSelectorFromString( selStr );
3423 arcSafeRelease( selStr );
3424 id value = performOptionalSelector( cls, sel );
3426 return [(NSString*)value UTF8String];
3431 inline std::size_t registerTestMethods() {
3432 std::size_t noTestMethods = 0;
3433 int noClasses = objc_getClassList(
nullptr, 0 );
3435 Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc(
sizeof(Class) * noClasses);
3436 objc_getClassList( classes, noClasses );
3438 for(
int c = 0; c < noClasses; c++ ) {
3439 Class cls = classes[c];
3442 Method* methods = class_copyMethodList( cls, &count );
3443 for( u_int m = 0; m <
count ; m++ ) {
3444 SEL selector = method_getName(methods[m]);
3445 std::string methodName = sel_getName(selector);
3446 if(
startsWith( methodName,
"Catch_TestCase_" ) ) {
3447 std::string testCaseName = methodName.substr( 15 );
3448 std::string name = Detail::getAnnotation( cls,
"Name", testCaseName );
3449 std::string desc = Detail::getAnnotation( cls,
"Description", testCaseName );
3450 const char* className = class_getName( cls );
3459 return noTestMethods;
3462 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS) 3464 namespace Matchers {
3466 namespace NSStringMatchers {
3468 struct StringHolder : MatcherBase<NSString*>{
3469 StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
3470 StringHolder( StringHolder
const& other ) : m_substr( [other.m_substr copy] ){}
3472 arcSafeRelease( m_substr );
3475 bool match( NSString* arg )
const override {
3479 NSString* CATCH_ARC_STRONG m_substr;
3482 struct Equals : StringHolder {
3483 Equals( NSString* substr ) : StringHolder( substr ){}
3485 bool match( NSString* str )
const override {
3486 return (str != nil || m_substr == nil ) &&
3487 [str isEqualToString:m_substr];
3490 std::string describe()
const override {
3496 Contains( NSString* substr ) : StringHolder( substr ){}
3498 bool match( NSString* str )
const {
3499 return (str != nil || m_substr == nil ) &&
3500 [str rangeOfString:m_substr].location != NSNotFound;
3503 std::string describe()
const override {
3509 StartsWith( NSString* substr ) : StringHolder( substr ){}
3511 bool match( NSString* str )
const override {
3512 return (str != nil || m_substr == nil ) &&
3513 [str rangeOfString:m_substr].location == 0;
3516 std::string describe()
const override {
3521 EndsWith( NSString* substr ) : StringHolder( substr ){}
3523 bool match( NSString* str )
const override {
3524 return (str != nil || m_substr == nil ) &&
3525 [str rangeOfString:m_substr].location == [str length] - [m_substr length];
3528 std::string describe()
const override {
3550 using namespace Matchers;
3552 #endif // CATCH_CONFIG_DISABLE_MATCHERS 3557 #define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix 3558 #define OC_TEST_CASE2( name, desc, uniqueSuffix ) \ 3559 +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \ 3563 +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \ 3567 -(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix ) 3569 #define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ ) 3574 #ifdef CATCH_CONFIG_EXTERNAL_INTERFACES 3586 #pragma clang diagnostic push 3587 #pragma clang diagnostic ignored "-Wpadded" 3593 #pragma clang diagnostic push 3594 #pragma clang diagnostic ignored "-Wpadded" 3601 class WildcardPattern {
3602 enum WildcardPosition {
3604 WildcardAtStart = 1,
3606 WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
3612 virtual ~WildcardPattern() =
default;
3613 virtual bool matches( std::string
const& str )
const;
3616 std::string adjustCase( std::string
const& str )
const;
3618 WildcardPosition m_wildcard = NoWildcard;
3619 std::string m_pattern;
3633 virtual bool matches(
TestCaseInfo const& testCase )
const = 0;
3635 using PatternPtr = std::shared_ptr<Pattern>;
3637 class NamePattern :
public Pattern {
3639 NamePattern( std::string
const& name );
3640 virtual ~NamePattern();
3641 virtual bool matches(
TestCaseInfo const& testCase )
const override;
3643 WildcardPattern m_wildcardPattern;
3646 class TagPattern :
public Pattern {
3648 TagPattern( std::string
const& tag );
3649 virtual ~TagPattern();
3650 virtual bool matches(
TestCaseInfo const& testCase )
const override;
3655 class ExcludedPattern :
public Pattern {
3657 ExcludedPattern( PatternPtr
const& underlyingPattern );
3658 virtual ~ExcludedPattern();
3659 virtual bool matches(
TestCaseInfo const& testCase )
const override;
3661 PatternPtr m_underlyingPattern;
3665 std::vector<PatternPtr> m_patterns;
3671 bool hasFilters()
const;
3675 std::vector<Filter> m_filters;
3677 friend class TestSpecParser;
3682 #pragma clang diagnostic pop 3694 struct ITagAliasRegistry {
3695 virtual ~ITagAliasRegistry();
3697 virtual TagAlias
const* find( std::string
const& alias )
const = 0;
3698 virtual std::string expandAliases( std::string
const& unexpandedTestSpec )
const = 0;
3700 static ITagAliasRegistry
const&
get();
3708 class TestSpecParser {
3709 enum Mode{ None, Name, QuotedName, Tag, EscapedName };
3711 bool m_exclusion =
false;
3712 std::size_t m_start = std::string::npos, m_pos = 0;
3714 std::vector<std::size_t> m_escapeChars;
3715 TestSpec::Filter m_currentFilter;
3716 TestSpec m_testSpec;
3717 ITagAliasRegistry
const* m_tagAliases =
nullptr;
3720 TestSpecParser( ITagAliasRegistry
const& tagAliases );
3722 TestSpecParser& parse( std::string
const& arg );
3723 TestSpec testSpec();
3726 void visitChar(
char c );
3727 void startNewMode( Mode mode, std::size_t
start );
3729 std::string subString()
const;
3731 template<
typename T>
3733 std::string token = subString();
3734 for( std::size_t i = 0; i < m_escapeChars.size(); ++i )
3735 token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 );
3736 m_escapeChars.clear();
3739 token = token.substr( 8 );
3741 if( !token.empty() ) {
3742 TestSpec::PatternPtr pattern = std::make_shared<T>( token );
3744 pattern = std::make_shared<TestSpec::ExcludedPattern>( pattern );
3745 m_currentFilter.m_patterns.push_back( pattern );
3747 m_exclusion =
false;
3753 TestSpec parseTestSpec( std::string
const& arg );
3758 #pragma clang diagnostic pop 3771 enum class Verbosity {
3777 struct WarnAbout {
enum What {
3779 NoAssertions = 0x01,
3783 struct ShowDurations {
enum OrNot {
3788 struct RunTests {
enum InWhatOrder {
3790 InLexicographicalOrder,
3793 struct UseColour {
enum YesOrNo {
3798 struct WaitForKeypress {
enum When {
3802 BeforeStartAndExit = BeforeStart | BeforeExit
3811 virtual bool allowThrows()
const = 0;
3812 virtual std::ostream& stream()
const = 0;
3813 virtual std::string name()
const = 0;
3814 virtual bool includeSuccessfulResults()
const = 0;
3815 virtual bool shouldDebugBreak()
const = 0;
3816 virtual bool warnAboutMissingAssertions()
const = 0;
3817 virtual bool warnAboutNoTests()
const = 0;
3818 virtual int abortAfter()
const = 0;
3819 virtual bool showInvisibles()
const = 0;
3820 virtual ShowDurations::OrNot showDurations()
const = 0;
3821 virtual TestSpec
const& testSpec()
const = 0;
3822 virtual bool hasTestFilters()
const = 0;
3823 virtual RunTests::InWhatOrder runOrder()
const = 0;
3824 virtual unsigned int rngSeed()
const = 0;
3825 virtual int benchmarkResolutionMultiple()
const = 0;
3826 virtual UseColour::YesOrNo useColour()
const = 0;
3827 virtual std::vector<std::string>
const& getSectionsToRun()
const = 0;
3828 virtual Verbosity verbosity()
const = 0;
3831 using IConfigPtr = std::shared_ptr<IConfig const>;
3841 #ifndef CATCH_CONFIG_CONSOLE_WIDTH 3842 #define CATCH_CONFIG_CONSOLE_WIDTH 80 3850 bool listTests =
false;
3851 bool listTags =
false;
3852 bool listReporters =
false;
3853 bool listTestNamesOnly =
false;
3855 bool showSuccessfulTests =
false;
3856 bool shouldDebugBreak =
false;
3857 bool noThrow =
false;
3858 bool showHelp =
false;
3859 bool showInvisibles =
false;
3860 bool filenamesAsTags =
false;
3861 bool libIdentify =
false;
3863 int abortAfter = -1;
3865 int benchmarkResolutionMultiple = 100;
3867 Verbosity verbosity = Verbosity::Normal;
3868 WarnAbout::What warnings = WarnAbout::Nothing;
3869 ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
3870 RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
3871 UseColour::YesOrNo useColour = UseColour::Auto;
3872 WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
3874 std::string outputFilename;
3876 std::string processName;
3877 #ifndef CATCH_CONFIG_DEFAULT_REPORTER 3878 #define CATCH_CONFIG_DEFAULT_REPORTER "console" 3880 std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;
3881 #undef CATCH_CONFIG_DEFAULT_REPORTER 3883 std::vector<std::string> testsOrTags;
3884 std::vector<std::string> sectionsToRun;
3887 class Config :
public IConfig {
3891 Config( ConfigData
const& data );
3892 virtual ~Config() =
default;
3894 std::string
const& getFilename()
const;
3896 bool listTests()
const;
3897 bool listTestNamesOnly()
const;
3898 bool listTags()
const;
3899 bool listReporters()
const;
3901 std::string getProcessName()
const;
3902 std::string
const& getReporterName()
const;
3904 std::vector<std::string>
const& getTestsOrTags()
const;
3905 std::vector<std::string>
const& getSectionsToRun()
const override;
3907 virtual TestSpec
const& testSpec()
const override;
3908 bool hasTestFilters()
const override;
3910 bool showHelp()
const;
3913 bool allowThrows()
const override;
3914 std::ostream& stream()
const override;
3915 std::string name()
const override;
3916 bool includeSuccessfulResults()
const override;
3917 bool warnAboutMissingAssertions()
const override;
3918 bool warnAboutNoTests()
const override;
3919 ShowDurations::OrNot showDurations()
const override;
3920 RunTests::InWhatOrder runOrder()
const override;
3921 unsigned int rngSeed()
const override;
3922 int benchmarkResolutionMultiple()
const override;
3923 UseColour::YesOrNo useColour()
const override;
3924 bool shouldDebugBreak()
const override;
3925 int abortAfter()
const override;
3926 bool showInvisibles()
const override;
3927 Verbosity verbosity()
const override;
3934 std::unique_ptr<IStream const> m_stream;
3935 TestSpec m_testSpec;
3936 bool m_hasTestFilters =
false;
3948 struct AssertionResultData
3950 AssertionResultData() =
delete;
3954 std::string message;
3955 mutable std::string reconstructedExpression;
3959 std::string reconstructExpression()
const;
3962 class AssertionResult {
3964 AssertionResult() =
delete;
3965 AssertionResult(
AssertionInfo const& info, AssertionResultData
const& data );
3968 bool succeeded()
const;
3970 bool hasExpression()
const;
3971 bool hasMessage()
const;
3972 std::string getExpression()
const;
3973 std::string getExpressionInMacro()
const;
3974 bool hasExpandedExpression()
const;
3975 std::string getExpandedExpression()
const;
3976 std::string getMessage()
const;
3982 AssertionResultData m_resultData;
3993 template<
typename T>
3996 Option() : nullableValue(
nullptr ) {}
3997 Option( T
const& _value )
3998 : nullableValue(
new( storage ) T( _value ) )
4000 Option( Option
const& _other )
4001 : nullableValue( _other ?
new( storage ) T( *_other ) :
nullptr )
4008 Option& operator= ( Option
const& _other ) {
4009 if( &_other !=
this ) {
4012 nullableValue =
new( storage ) T( *_other );
4016 Option& operator = ( T
const& _value ) {
4018 nullableValue =
new( storage ) T( _value );
4024 nullableValue->~T();
4025 nullableValue =
nullptr;
4028 T& operator*() {
return *nullableValue; }
4029 T
const& operator*()
const {
return *nullableValue; }
4030 T* operator->() {
return nullableValue; }
4031 const T* operator->()
const {
return nullableValue; }
4033 T valueOr( T
const& defaultValue )
const {
4034 return nullableValue ? *nullableValue : defaultValue;
4037 bool some()
const {
return nullableValue !=
nullptr; }
4038 bool none()
const {
return nullableValue ==
nullptr; }
4040 bool operator !()
const {
return nullableValue ==
nullptr; }
4041 explicit operator bool()
const {
4047 alignas(
alignof(T))
char storage[sizeof(T)];
4061 struct ReporterConfig {
4062 explicit ReporterConfig( IConfigPtr
const& _fullConfig );
4064 ReporterConfig( IConfigPtr
const& _fullConfig, std::ostream& _stream );
4066 std::ostream& stream()
const;
4067 IConfigPtr fullConfig()
const;
4070 std::ostream* m_stream;
4071 IConfigPtr m_fullConfig;
4074 struct ReporterPreferences {
4075 bool shouldRedirectStdOut =
false;
4076 bool shouldReportAllAssertions =
false;
4079 template<
typename T>
4080 struct LazyStat : Option<T> {
4081 LazyStat& operator=( T
const& _value ) {
4082 Option<T>::operator=( _value );
4093 struct TestRunInfo {
4094 TestRunInfo( std::string
const& _name );
4098 GroupInfo( std::string
const& _name,
4099 std::size_t _groupIndex,
4100 std::size_t _groupsCount );
4103 std::size_t groupIndex;
4104 std::size_t groupsCounts;
4107 struct AssertionStats {
4108 AssertionStats( AssertionResult
const& _assertionResult,
4109 std::vector<MessageInfo>
const& _infoMessages,
4112 AssertionStats( AssertionStats
const& ) =
default;
4113 AssertionStats( AssertionStats && ) =
default;
4114 AssertionStats& operator = ( AssertionStats
const& ) =
default;
4115 AssertionStats& operator = ( AssertionStats && ) =
default;
4116 virtual ~AssertionStats();
4118 AssertionResult assertionResult;
4119 std::vector<MessageInfo> infoMessages;
4123 struct SectionStats {
4125 Counts const& _assertions,
4126 double _durationInSeconds,
4127 bool _missingAssertions );
4128 SectionStats( SectionStats
const& ) =
default;
4129 SectionStats( SectionStats && ) =
default;
4130 SectionStats& operator = ( SectionStats
const& ) =
default;
4131 SectionStats& operator = ( SectionStats && ) =
default;
4132 virtual ~SectionStats();
4136 double durationInSeconds;
4137 bool missingAssertions;
4140 struct TestCaseStats {
4143 std::string
const& _stdOut,
4144 std::string
const& _stdErr,
4147 TestCaseStats( TestCaseStats
const& ) =
default;
4148 TestCaseStats( TestCaseStats && ) =
default;
4149 TestCaseStats& operator = ( TestCaseStats
const& ) =
default;
4150 TestCaseStats& operator = ( TestCaseStats && ) =
default;
4151 virtual ~TestCaseStats();
4160 struct TestGroupStats {
4161 TestGroupStats( GroupInfo
const& _groupInfo,
4164 TestGroupStats( GroupInfo
const& _groupInfo );
4166 TestGroupStats( TestGroupStats
const& ) =
default;
4167 TestGroupStats( TestGroupStats && ) =
default;
4168 TestGroupStats& operator = ( TestGroupStats
const& ) =
default;
4169 TestGroupStats& operator = ( TestGroupStats && ) =
default;
4170 virtual ~TestGroupStats();
4172 GroupInfo groupInfo;
4177 struct TestRunStats {
4178 TestRunStats( TestRunInfo
const& _runInfo,
4182 TestRunStats( TestRunStats
const& ) =
default;
4183 TestRunStats( TestRunStats && ) =
default;
4184 TestRunStats& operator = ( TestRunStats
const& ) =
default;
4185 TestRunStats& operator = ( TestRunStats && ) =
default;
4186 virtual ~TestRunStats();
4188 TestRunInfo runInfo;
4193 struct BenchmarkInfo {
4196 struct BenchmarkStats {
4198 std::size_t iterations;
4199 uint64_t elapsedTimeInNanoseconds;
4202 struct IStreamingReporter {
4203 virtual ~IStreamingReporter() =
default;
4209 virtual ReporterPreferences getPreferences()
const = 0;
4211 virtual void noMatchingTestCases( std::string
const& spec ) = 0;
4213 virtual void testRunStarting( TestRunInfo
const& testRunInfo ) = 0;
4214 virtual void testGroupStarting( GroupInfo
const& groupInfo ) = 0;
4216 virtual void testCaseStarting(
TestCaseInfo const& testInfo ) = 0;
4217 virtual void sectionStarting(
SectionInfo const& sectionInfo ) = 0;
4220 virtual void benchmarkStarting( BenchmarkInfo
const& ) {}
4222 virtual void assertionStarting(
AssertionInfo const& assertionInfo ) = 0;
4225 virtual bool assertionEnded( AssertionStats
const& assertionStats ) = 0;
4228 virtual void benchmarkEnded( BenchmarkStats
const& ) {}
4230 virtual void sectionEnded( SectionStats
const& sectionStats ) = 0;
4231 virtual void testCaseEnded( TestCaseStats
const& testCaseStats ) = 0;
4232 virtual void testGroupEnded( TestGroupStats
const& testGroupStats ) = 0;
4233 virtual void testRunEnded( TestRunStats
const& testRunStats ) = 0;
4235 virtual void skipTest(
TestCaseInfo const& testInfo ) = 0;
4238 virtual void fatalErrorEncountered(
StringRef name );
4240 virtual bool isMulti()
const;
4242 using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;
4244 struct IReporterFactory {
4245 virtual ~IReporterFactory();
4246 virtual IStreamingReporterPtr create( ReporterConfig
const& config )
const = 0;
4247 virtual std::string getDescription()
const = 0;
4251 struct IReporterRegistry {
4252 using FactoryMap = std::map<std::string, IReporterFactoryPtr>;
4253 using Listeners = std::vector<IReporterFactoryPtr>;
4255 virtual ~IReporterRegistry();
4256 virtual IStreamingReporterPtr create( std::string
const& name, IConfigPtr
const& config )
const = 0;
4257 virtual FactoryMap
const& getFactories()
const = 0;
4258 virtual Listeners
const& getListeners()
const = 0;
4264 #include <algorithm> 4273 void prepareExpandedExpression(AssertionResult& result);
4276 std::string getFormattedDuration(
double duration );
4278 template<
typename DerivedT>
4279 struct StreamingReporterBase : IStreamingReporter {
4281 StreamingReporterBase( ReporterConfig
const& _config )
4282 : m_config( _config.fullConfig() ),
4283 stream( _config.stream() )
4285 m_reporterPrefs.shouldRedirectStdOut =
false;
4286 if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
4287 CATCH_ERROR(
"Verbosity level not supported by this reporter" );
4290 ReporterPreferences getPreferences()
const override {
4291 return m_reporterPrefs;
4294 static std::set<Verbosity> getSupportedVerbosities() {
4295 return { Verbosity::Normal };
4298 ~StreamingReporterBase()
override =
default;
4300 void noMatchingTestCases(std::string
const&)
override {}
4302 void testRunStarting(TestRunInfo
const& _testRunInfo)
override {
4303 currentTestRunInfo = _testRunInfo;
4305 void testGroupStarting(GroupInfo
const& _groupInfo)
override {
4306 currentGroupInfo = _groupInfo;
4309 void testCaseStarting(
TestCaseInfo const& _testInfo)
override {
4310 currentTestCaseInfo = _testInfo;
4312 void sectionStarting(
SectionInfo const& _sectionInfo)
override {
4313 m_sectionStack.push_back(_sectionInfo);
4316 void sectionEnded(SectionStats
const& )
override {
4317 m_sectionStack.pop_back();
4319 void testCaseEnded(TestCaseStats
const& )
override {
4320 currentTestCaseInfo.reset();
4322 void testGroupEnded(TestGroupStats
const& )
override {
4323 currentGroupInfo.reset();
4325 void testRunEnded(TestRunStats
const& )
override {
4326 currentTestCaseInfo.reset();
4327 currentGroupInfo.reset();
4328 currentTestRunInfo.reset();
4336 IConfigPtr m_config;
4337 std::ostream& stream;
4339 LazyStat<TestRunInfo> currentTestRunInfo;
4340 LazyStat<GroupInfo> currentGroupInfo;
4341 LazyStat<TestCaseInfo> currentTestCaseInfo;
4343 std::vector<SectionInfo> m_sectionStack;
4344 ReporterPreferences m_reporterPrefs;
4347 template<
typename DerivedT>
4348 struct CumulativeReporterBase : IStreamingReporter {
4349 template<
typename T,
typename ChildNodeT>
4351 explicit Node( T
const& _value ) :
value( _value ) {}
4354 using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;
4356 ChildNodes children;
4358 struct SectionNode {
4359 explicit SectionNode(SectionStats
const& _stats) : stats(_stats) {}
4360 virtual ~SectionNode() =
default;
4362 bool operator == (SectionNode
const& other)
const {
4363 return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
4365 bool operator == (std::shared_ptr<SectionNode>
const& other)
const {
4366 return operator==(*other);
4370 using ChildSections = std::vector<std::shared_ptr<SectionNode>>;
4371 using Assertions = std::vector<AssertionStats>;
4372 ChildSections childSections;
4373 Assertions assertions;
4378 struct BySectionInfo {
4379 BySectionInfo(
SectionInfo const& other ) : m_other( other ) {}
4380 BySectionInfo( BySectionInfo
const& other ) : m_other( other.m_other ) {}
4381 bool operator() (std::shared_ptr<SectionNode>
const& node)
const {
4382 return ((node->stats.sectionInfo.name == m_other.name) &&
4383 (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
4385 void operator=(BySectionInfo
const&) =
delete;
4391 using TestCaseNode = Node<TestCaseStats, SectionNode>;
4392 using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
4393 using TestRunNode = Node<TestRunStats, TestGroupNode>;
4395 CumulativeReporterBase( ReporterConfig
const& _config )
4396 : m_config( _config.fullConfig() ),
4397 stream( _config.stream() )
4399 m_reporterPrefs.shouldRedirectStdOut =
false;
4400 if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
4401 CATCH_ERROR(
"Verbosity level not supported by this reporter" );
4403 ~CumulativeReporterBase()
override =
default;
4405 ReporterPreferences getPreferences()
const override {
4406 return m_reporterPrefs;
4409 static std::set<Verbosity> getSupportedVerbosities() {
4410 return { Verbosity::Normal };
4413 void testRunStarting( TestRunInfo
const& )
override {}
4414 void testGroupStarting( GroupInfo
const& )
override {}
4416 void testCaseStarting(
TestCaseInfo const& )
override {}
4418 void sectionStarting(
SectionInfo const& sectionInfo )
override {
4419 SectionStats incompleteStats( sectionInfo,
Counts(), 0,
false );
4420 std::shared_ptr<SectionNode> node;
4421 if( m_sectionStack.empty() ) {
4422 if( !m_rootSection )
4423 m_rootSection = std::make_shared<SectionNode>( incompleteStats );
4424 node = m_rootSection;
4427 SectionNode& parentNode = *m_sectionStack.back();
4429 std::find_if( parentNode.childSections.begin(),
4430 parentNode.childSections.end(),
4431 BySectionInfo( sectionInfo ) );
4432 if( it == parentNode.childSections.end() ) {
4433 node = std::make_shared<SectionNode>( incompleteStats );
4434 parentNode.childSections.push_back( node );
4439 m_sectionStack.push_back( node );
4440 m_deepestSection = std::move(node);
4445 bool assertionEnded(AssertionStats
const& assertionStats)
override {
4446 assert(!m_sectionStack.empty());
4452 prepareExpandedExpression(const_cast<AssertionResult&>( assertionStats.assertionResult ) );
4453 SectionNode& sectionNode = *m_sectionStack.back();
4454 sectionNode.assertions.push_back(assertionStats);
4457 void sectionEnded(SectionStats
const& sectionStats)
override {
4458 assert(!m_sectionStack.empty());
4459 SectionNode& node = *m_sectionStack.back();
4460 node.stats = sectionStats;
4461 m_sectionStack.pop_back();
4463 void testCaseEnded(TestCaseStats
const& testCaseStats)
override {
4464 auto node = std::make_shared<TestCaseNode>(testCaseStats);
4465 assert(m_sectionStack.size() == 0);
4466 node->children.push_back(m_rootSection);
4467 m_testCases.push_back(node);
4468 m_rootSection.reset();
4470 assert(m_deepestSection);
4471 m_deepestSection->stdOut = testCaseStats.stdOut;
4472 m_deepestSection->stdErr = testCaseStats.stdErr;
4474 void testGroupEnded(TestGroupStats
const& testGroupStats)
override {
4475 auto node = std::make_shared<TestGroupNode>(testGroupStats);
4476 node->children.swap(m_testCases);
4477 m_testGroups.push_back(node);
4479 void testRunEnded(TestRunStats
const& testRunStats)
override {
4480 auto node = std::make_shared<TestRunNode>(testRunStats);
4481 node->children.swap(m_testGroups);
4482 m_testRuns.push_back(node);
4483 testRunEndedCumulative();
4485 virtual void testRunEndedCumulative() = 0;
4489 IConfigPtr m_config;
4490 std::ostream& stream;
4491 std::vector<AssertionStats> m_assertions;
4492 std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;
4493 std::vector<std::shared_ptr<TestCaseNode>> m_testCases;
4494 std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;
4496 std::vector<std::shared_ptr<TestRunNode>> m_testRuns;
4498 std::shared_ptr<SectionNode> m_rootSection;
4499 std::shared_ptr<SectionNode> m_deepestSection;
4500 std::vector<std::shared_ptr<SectionNode>> m_sectionStack;
4501 ReporterPreferences m_reporterPrefs;
4505 char const* getLineOfChars() {
4506 static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
4508 std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
4509 line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
4514 struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {
4515 TestEventListenerBase( ReporterConfig
const& _config );
4518 bool assertionEnded(AssertionStats
const&)
override;
4542 BrightRed = Bright | Red,
4543 BrightGreen = Bright | Green,
4544 LightGrey = Bright | Grey,
4545 BrightWhite = Bright | White,
4546 BrightYellow = Bright | Yellow,
4549 FileName = LightGrey,
4550 Warning = BrightYellow,
4551 ResultError = BrightRed,
4552 ResultSuccess = BrightGreen,
4553 ResultExpectedFailure = Warning,
4558 OriginalExpression = Cyan,
4559 ReconstructedExpression = BrightYellow,
4561 SecondaryText = LightGrey,
4566 Colour( Code _colourCode );
4567 Colour( Colour&& other ) noexcept;
4568 Colour& operator=( Colour&& other ) noexcept;
4572 static void use( Code _colourCode );
4575 bool m_moved =
false;
4578 std::ostream&
operator << ( std::ostream& os, Colour
const& );
4588 template<
typename T>
4589 class ReporterRegistrar {
4591 class ReporterFactory :
public IReporterFactory {
4593 virtual IStreamingReporterPtr create( ReporterConfig
const& config )
const override {
4594 return std::unique_ptr<T>(
new T( config ) );
4597 virtual std::string getDescription()
const override {
4598 return T::getDescription();
4604 explicit ReporterRegistrar( std::string
const& name ) {
4609 template<
typename T>
4610 class ListenerRegistrar {
4612 class ListenerFactory :
public IReporterFactory {
4614 virtual IStreamingReporterPtr create( ReporterConfig
const& config )
const override {
4615 return std::unique_ptr<T>(
new T( config ) );
4617 virtual std::string getDescription()
const override {
4618 return std::string();
4624 ListenerRegistrar() {
4630 #if !defined(CATCH_CONFIG_DISABLE) 4632 #define CATCH_REGISTER_REPORTER( name, reporterType ) \ 4633 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ 4634 namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \ 4635 CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS 4637 #define CATCH_REGISTER_LISTENER( listenerType ) \ 4638 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ 4639 namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \ 4640 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS 4641 #else // CATCH_CONFIG_DISABLE 4643 #define CATCH_REGISTER_REPORTER(name, reporterType) 4644 #define CATCH_REGISTER_LISTENER(listenerType) 4646 #endif // CATCH_CONFIG_DISABLE 4654 struct CompactReporter : StreamingReporterBase<CompactReporter> {
4656 using StreamingReporterBase::StreamingReporterBase;
4658 ~CompactReporter()
override;
4660 static std::string getDescription();
4662 ReporterPreferences getPreferences()
const override;
4664 void noMatchingTestCases(std::string
const& spec)
override;
4668 bool assertionEnded(AssertionStats
const& _assertionStats)
override;
4670 void sectionEnded(SectionStats
const& _sectionStats)
override;
4672 void testRunEnded(TestRunStats
const& _testRunStats)
override;
4681 #if defined(_MSC_VER) 4682 #pragma warning(push) 4683 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch 4690 struct SummaryColumn;
4693 struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {
4694 std::unique_ptr<TablePrinter> m_tablePrinter;
4696 ConsoleReporter(ReporterConfig
const& config);
4697 ~ConsoleReporter()
override;
4698 static std::string getDescription();
4700 void noMatchingTestCases(std::string
const& spec)
override;
4704 bool assertionEnded(AssertionStats
const& _assertionStats)
override;
4706 void sectionStarting(
SectionInfo const& _sectionInfo)
override;
4707 void sectionEnded(SectionStats
const& _sectionStats)
override;
4709 void benchmarkStarting(BenchmarkInfo
const& info)
override;
4710 void benchmarkEnded(BenchmarkStats
const& stats)
override;
4712 void testCaseEnded(TestCaseStats
const& _testCaseStats)
override;
4713 void testGroupEnded(TestGroupStats
const& _testGroupStats)
override;
4714 void testRunEnded(TestRunStats
const& _testRunStats)
override;
4720 void lazyPrintWithoutClosingBenchmarkTable();
4721 void lazyPrintRunInfo();
4722 void lazyPrintGroupInfo();
4723 void printTestCaseAndSectionHeader();
4725 void printClosedHeader(std::string
const& _name);
4726 void printOpenHeader(std::string
const& _name);
4730 void printHeaderString(std::string
const& _string, std::size_t indent = 0);
4732 void printTotals(
Totals const& totals);
4733 void printSummaryRow(std::string
const& label, std::vector<SummaryColumn>
const& cols, std::size_t row);
4735 void printTotalsDivider(
Totals const& totals);
4736 void printSummaryDivider();
4739 bool m_headerPrinted =
false;
4744 #if defined(_MSC_VER) 4745 #pragma warning(pop) 4759 enum ForWhat { ForTextNodes, ForAttributes };
4761 XmlEncode( std::string
const& str, ForWhat forWhat = ForTextNodes );
4763 void encodeTo( std::ostream& os )
const;
4765 friend std::ostream&
operator << ( std::ostream& os, XmlEncode
const& xmlEncode );
4775 class ScopedElement {
4777 ScopedElement( XmlWriter* writer );
4779 ScopedElement( ScopedElement&& other ) noexcept;
4780 ScopedElement& operator=( ScopedElement&& other ) noexcept;
4784 ScopedElement& writeText( std::string
const& text,
bool indent =
true );
4786 template<
typename T>
4787 ScopedElement& writeAttribute( std::string
const& name, T
const& attribute ) {
4788 m_writer->writeAttribute( name, attribute );
4793 mutable XmlWriter* m_writer =
nullptr;
4799 XmlWriter( XmlWriter
const& ) =
delete;
4800 XmlWriter& operator=( XmlWriter
const& ) =
delete;
4802 XmlWriter& startElement( std::string
const& name );
4804 ScopedElement scopedElement( std::string
const& name );
4806 XmlWriter& endElement();
4808 XmlWriter& writeAttribute( std::string
const& name, std::string
const& attribute );
4810 XmlWriter& writeAttribute( std::string
const& name,
bool attribute );
4812 template<
typename T>
4813 XmlWriter& writeAttribute( std::string
const& name, T
const& attribute ) {
4816 return writeAttribute( name, rss.
str() );
4819 XmlWriter& writeText( std::string
const& text,
bool indent =
true );
4821 XmlWriter& writeComment( std::string
const& text );
4823 void writeStylesheetRef( std::string
const& url );
4825 XmlWriter& writeBlankLine();
4827 void ensureTagClosed();
4831 void writeDeclaration();
4833 void newlineIfNecessary();
4835 bool m_tagIsOpen =
false;
4836 bool m_needsNewline =
false;
4837 std::vector<std::string> m_tags;
4838 std::string m_indent;
4847 class JunitReporter :
public CumulativeReporterBase<JunitReporter> {
4849 JunitReporter(ReporterConfig
const& _config);
4851 ~JunitReporter()
override;
4853 static std::string getDescription();
4855 void noMatchingTestCases(std::string
const& )
override;
4857 void testRunStarting(TestRunInfo
const& runInfo)
override;
4859 void testGroupStarting(GroupInfo
const& groupInfo)
override;
4861 void testCaseStarting(
TestCaseInfo const& testCaseInfo)
override;
4862 bool assertionEnded(AssertionStats
const& assertionStats)
override;
4864 void testCaseEnded(TestCaseStats
const& testCaseStats)
override;
4866 void testGroupEnded(TestGroupStats
const& testGroupStats)
override;
4868 void testRunEndedCumulative()
override;
4870 void writeGroup(TestGroupNode
const& groupNode,
double suiteTime);
4872 void writeTestCase(TestCaseNode
const& testCaseNode);
4874 void writeSection(std::string
const& className,
4875 std::string
const& rootName,
4876 SectionNode
const& sectionNode);
4878 void writeAssertions(SectionNode
const& sectionNode);
4879 void writeAssertion(AssertionStats
const& stats);
4883 std::string stdOutForSuite;
4884 std::string stdErrForSuite;
4885 unsigned int unexpectedExceptions = 0;
4886 bool m_okToFail =
false;
4895 class XmlReporter :
public StreamingReporterBase<XmlReporter> {
4897 XmlReporter(ReporterConfig
const& _config);
4899 ~XmlReporter()
override;
4901 static std::string getDescription();
4903 virtual std::string getStylesheetRef()
const;
4909 void noMatchingTestCases(std::string
const&
s)
override;
4911 void testRunStarting(TestRunInfo
const& testInfo)
override;
4913 void testGroupStarting(GroupInfo
const& groupInfo)
override;
4915 void testCaseStarting(
TestCaseInfo const& testInfo)
override;
4917 void sectionStarting(
SectionInfo const& sectionInfo)
override;
4921 bool assertionEnded(AssertionStats
const& assertionStats)
override;
4923 void sectionEnded(SectionStats
const& sectionStats)
override;
4925 void testCaseEnded(TestCaseStats
const& testCaseStats)
override;
4927 void testGroupEnded(TestGroupStats
const& testGroupStats)
override;
4929 void testRunEnded(TestRunStats
const& testRunStats)
override;
4932 Timer m_testCaseTimer;
4934 int m_sectionDepth = 0;
4944 #endif // ! CATCH_CONFIG_IMPL_ONLY 4950 #pragma clang diagnostic push 4951 #pragma clang diagnostic ignored "-Wweak-vtables" 4962 namespace TestCaseTracking {
4964 struct NameAndLocation {
4968 NameAndLocation( std::string
const& _name,
SourceLineInfo const& _location );
4973 using ITrackerPtr = std::shared_ptr<ITracker>;
4976 virtual ~ITracker();
4979 virtual NameAndLocation
const& nameAndLocation()
const = 0;
4982 virtual bool isComplete()
const = 0;
4983 virtual bool isSuccessfullyCompleted()
const = 0;
4984 virtual bool isOpen()
const = 0;
4985 virtual bool hasChildren()
const = 0;
4987 virtual ITracker& parent() = 0;
4990 virtual void close() = 0;
4991 virtual void fail() = 0;
4992 virtual void markAsNeedingAnotherRun() = 0;
4994 virtual void addChild( ITrackerPtr
const& child ) = 0;
4995 virtual ITrackerPtr findChild( NameAndLocation
const& nameAndLocation ) = 0;
4996 virtual void openChild() = 0;
4999 virtual bool isSectionTracker()
const = 0;
5000 virtual bool isIndexTracker()
const = 0;
5003 class TrackerContext {
5011 ITrackerPtr m_rootTracker;
5012 ITracker* m_currentTracker =
nullptr;
5013 RunState m_runState = NotStarted;
5017 static TrackerContext& instance();
5019 ITracker& startRun();
5023 void completeCycle();
5025 bool completedCycle()
const;
5026 ITracker& currentTracker();
5027 void setCurrentTracker( ITracker* tracker );
5030 class TrackerBase :
public ITracker {
5037 CompletedSuccessfully,
5041 using Children = std::vector<ITrackerPtr>;
5042 NameAndLocation m_nameAndLocation;
5043 TrackerContext& m_ctx;
5045 Children m_children;
5046 CycleState m_runState = NotStarted;
5049 TrackerBase( NameAndLocation
const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
5051 NameAndLocation
const& nameAndLocation()
const override;
5052 bool isComplete()
const override;
5053 bool isSuccessfullyCompleted()
const override;
5054 bool isOpen()
const override;
5055 bool hasChildren()
const override;
5057 void addChild( ITrackerPtr
const& child )
override;
5059 ITrackerPtr findChild( NameAndLocation
const& nameAndLocation )
override;
5060 ITracker& parent()
override;
5062 void openChild()
override;
5064 bool isSectionTracker()
const override;
5065 bool isIndexTracker()
const override;
5069 void close()
override;
5070 void fail()
override;
5071 void markAsNeedingAnotherRun()
override;
5074 void moveToParent();
5078 class SectionTracker :
public TrackerBase {
5079 std::vector<std::string> m_filters;
5081 SectionTracker( NameAndLocation
const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
5083 bool isSectionTracker()
const override;
5085 static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation
const& nameAndLocation );
5089 void addInitialFilters( std::vector<std::string>
const& filters );
5090 void addNextFilters( std::vector<std::string>
const& filters );
5093 class IndexTracker :
public TrackerBase {
5097 IndexTracker( NameAndLocation
const& nameAndLocation, TrackerContext& ctx, ITracker* parent,
int size );
5099 bool isIndexTracker()
const override;
5100 void close()
override;
5102 static IndexTracker& acquire( TrackerContext& ctx, NameAndLocation
const& nameAndLocation,
int size );
5111 using TestCaseTracking::ITracker;
5112 using TestCaseTracking::TrackerContext;
5113 using TestCaseTracking::SectionTracker;
5114 using TestCaseTracking::IndexTracker;
5124 struct LeakDetector {
5141 bool marginComparison(
double lhs,
double rhs,
double margin) {
5142 return (lhs + margin >= rhs) && (rhs + margin >= lhs);
5150 Approx::Approx (
double value )
5151 : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
5157 Approx Approx::custom() {
5161 Approx Approx::operator-()
const {
5163 temp.m_value = -temp.m_value;
5167 std::string Approx::toString()
const {
5173 bool Approx::equalityComparisonImpl(
const double other)
const {
5176 return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
5179 void Approx::setMargin(
double margin) {
5181 "Invalid Approx::margin: " << margin <<
'.' 5182 <<
" Approx::Margin has to be non-negative.");
5186 void Approx::setEpsilon(
double epsilon) {
5188 "Invalid Approx::epsilon: " << epsilon <<
'.' 5189 <<
" Approx::epsilon has to be in [0, 1]");
5190 m_epsilon = epsilon;
5195 namespace literals {
5221 struct IMutableContext;
5223 using IConfigPtr = std::shared_ptr<IConfig const>;
5227 virtual ~IContext();
5230 virtual IRunner* getRunner() = 0;
5231 virtual IConfigPtr
const& getConfig()
const = 0;
5234 struct IMutableContext : IContext
5236 virtual ~IMutableContext();
5237 virtual void setResultCapture(
IResultCapture* resultCapture ) = 0;
5238 virtual void setRunner(
IRunner* runner ) = 0;
5239 virtual void setConfig( IConfigPtr
const& config ) = 0;
5242 static IMutableContext *currentContext;
5243 friend IMutableContext& getCurrentMutableContext();
5244 friend void cleanUpContext();
5245 static void createContext();
5248 inline IMutableContext& getCurrentMutableContext()
5250 if( !IMutableContext::currentContext )
5251 IMutableContext::createContext();
5252 return *IMutableContext::currentContext;
5255 inline IContext& getCurrentContext()
5257 return getCurrentMutableContext();
5260 void cleanUpContext();
5267 bool isDebuggerActive();
5270 #ifdef CATCH_PLATFORM_MAC 5272 #define CATCH_TRAP() __asm__("int $3\n" : : ) 5274 #elif defined(CATCH_PLATFORM_LINUX) 5278 #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64)) 5279 #define CATCH_TRAP() asm volatile ("int $3") 5280 #else // Fall back to the generic way. 5283 #define CATCH_TRAP() raise(SIGTRAP) 5285 #elif defined(_MSC_VER) 5286 #define CATCH_TRAP() __debugbreak() 5287 #elif defined(__MINGW32__) 5288 extern "C" __declspec(dllimport)
void __stdcall DebugBreak();
5289 #define CATCH_TRAP() DebugBreak() 5293 #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } 5296 inline void doNothing() {}
5298 #define CATCH_BREAK_INTO_DEBUGGER() Catch::doNothing() 5309 #if defined(CATCH_PLATFORM_WINDOWS) 5311 #if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX) 5312 # define CATCH_DEFINED_NOMINMAX 5315 #if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN) 5316 # define CATCH_DEFINED_WIN32_LEAN_AND_MEAN 5317 # define WIN32_LEAN_AND_MEAN 5323 #include <windows.h> 5326 #ifdef CATCH_DEFINED_NOMINMAX 5329 #ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN 5330 # undef WIN32_LEAN_AND_MEAN 5333 #endif // defined(CATCH_PLATFORM_WINDOWS) 5336 #if defined( CATCH_CONFIG_WINDOWS_SEH ) 5340 struct FatalConditionHandler {
5342 static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
5343 FatalConditionHandler();
5344 static void reset();
5345 ~FatalConditionHandler();
5349 static ULONG guaranteeSize;
5350 static PVOID exceptionHandlerHandle;
5355 #elif defined ( CATCH_CONFIG_POSIX_SIGNALS ) 5361 struct FatalConditionHandler {
5364 static struct sigaction oldSigActions[];
5365 static stack_t oldSigStack;
5366 static char altStackMem[];
5368 static void handleSignal(
int sig );
5370 FatalConditionHandler();
5371 ~FatalConditionHandler();
5372 static void reset();
5380 struct FatalConditionHandler {
5392 struct IMutableContext;
5399 RunContext( RunContext
const& ) =
delete;
5400 RunContext& operator =( RunContext
const& ) =
delete;
5402 explicit RunContext( IConfigPtr
const& _config, IStreamingReporterPtr&& reporter );
5404 ~RunContext()
override;
5406 void testGroupStarting( std::string
const& testSpec, std::size_t groupIndex, std::size_t groupsCount );
5407 void testGroupEnded( std::string
const& testSpec,
Totals const& totals, std::size_t groupIndex, std::size_t groupsCount );
5411 IConfigPtr config()
const;
5412 IStreamingReporter& reporter()
const;
5426 void handleUnexpectedExceptionNotThrown
5429 void handleUnexpectedInflightException
5431 std::string
const& message,
5433 void handleIncomplete
5440 bool sectionStarted(
SectionInfo const& sectionInfo,
Counts& assertions )
override;
5443 void sectionEndedEarly(
SectionEndInfo const& endInfo )
override;
5447 void benchmarkStarting( BenchmarkInfo
const& info )
override;
5448 void benchmarkEnded( BenchmarkStats
const& stats )
override;
5450 void pushScopedMessage(
MessageInfo const& message )
override;
5451 void popScopedMessage(
MessageInfo const& message )
override;
5453 std::string getCurrentTestName()
const override;
5455 const AssertionResult* getLastResult()
const override;
5457 void exceptionEarlyReported()
override;
5459 void handleFatalErrorCondition(
StringRef message )
override;
5461 bool lastAssertionPassed()
override;
5463 void assertionPassed()
override;
5467 bool aborting()
const final;
5471 void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr );
5472 void invokeActiveTestCase();
5474 void resetAssertionInfo();
5475 bool testForMissingAssertions(
Counts& assertions );
5477 void assertionEnded( AssertionResult
const& result );
5488 void handleUnfinishedSections();
5490 TestRunInfo m_runInfo;
5491 IMutableContext& m_context;
5492 TestCase const* m_activeTestCase =
nullptr;
5493 ITracker* m_testCaseTracker;
5494 Option<AssertionResult> m_lastResult;
5496 IConfigPtr m_config;
5498 IStreamingReporterPtr m_reporter;
5499 std::vector<MessageInfo> m_messages;
5501 std::vector<SectionEndInfo> m_unfinishedSections;
5502 std::vector<ITracker*> m_activeSections;
5503 TrackerContext m_trackerContext;
5504 bool m_lastAssertionPassed =
false;
5505 bool m_shouldReportUnexpected =
true;
5506 bool m_includeSuccessfulResults;
5522 : m_isNegated( isNegated )
5527 LazyExpression::operator bool()
const {
5528 return m_transientExpression !=
nullptr;
5542 os <<
"{** error - unchecked empty expression requested **}";
5552 : m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
5557 m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );
5560 m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction );
5564 return getCurrentContext().getConfig()->allowThrows();
5569 if( m_reaction.shouldDebugBreak ) {
5575 CATCH_BREAK_INTO_DEBUGGER();
5577 if (m_reaction.shouldThrow) {
5578 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) 5581 CATCH_ERROR(
"Test failure requires aborting test!" );
5594 m_resultCapture.handleNonExpr(m_assertionInfo,
ResultWas::Ok, m_reaction);
5597 m_resultCapture.handleNonExpr(m_assertionInfo,
ResultWas::Ok, m_reaction);
5601 m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction );
5605 m_resultCapture.handleNonExpr(m_assertionInfo,
ResultWas::Ok, m_reaction);
5620 lazyExpression(_lazyExpression),
5621 resultType(_resultType) {}
5623 std::string AssertionResultData::reconstructExpression()
const {
5625 if( reconstructedExpression.empty() ) {
5626 if( lazyExpression ) {
5628 rss << lazyExpression;
5629 reconstructedExpression = rss.
str();
5632 return reconstructedExpression;
5635 AssertionResult::AssertionResult(
AssertionInfo const& info, AssertionResultData
const& data )
5637 m_resultData( data )
5641 bool AssertionResult::succeeded()
const {
5651 return m_resultData.resultType;
5654 bool AssertionResult::hasExpression()
const {
5655 return m_info.capturedExpression[0] != 0;
5658 bool AssertionResult::hasMessage()
const {
5659 return !m_resultData.message.empty();
5662 std::string AssertionResult::getExpression()
const {
5664 return "!(" + m_info.capturedExpression +
")";
5666 return m_info.capturedExpression;
5669 std::string AssertionResult::getExpressionInMacro()
const {
5671 if( m_info.macroName[0] == 0 )
5672 expr = m_info.capturedExpression;
5674 expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
5675 expr += m_info.macroName;
5677 expr += m_info.capturedExpression;
5683 bool AssertionResult::hasExpandedExpression()
const {
5684 return hasExpression() && getExpandedExpression() != getExpression();
5687 std::string AssertionResult::getExpandedExpression()
const {
5688 std::string expr = m_resultData.reconstructExpression();
5694 std::string AssertionResult::getMessage()
const {
5695 return m_resultData.message;
5698 return m_info.lineInfo;
5701 StringRef AssertionResult::getTestMacroName()
const {
5702 return m_info.macroName;
5719 auto elapsed = m_timer.getElapsedNanoseconds();
5722 if( elapsed < m_resolution ) {
5723 m_iterationsToRun *= 10;
5757 #ifdef CLARA_CONFIG_CONSOLE_WIDTH 5758 #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 5759 #undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 5761 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1 5764 #pragma clang diagnostic push 5765 #pragma clang diagnostic ignored "-Wweak-vtables" 5766 #pragma clang diagnostic ignored "-Wexit-time-destructors" 5767 #pragma clang diagnostic ignored "-Wshadow" 5781 #ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH 5782 #define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80 5785 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 5786 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH 5789 #ifndef CLARA_CONFIG_OPTIONAL_TYPE 5790 #ifdef __has_include 5791 #if __has_include(<optional>) && __cplusplus >= 201703L 5793 #define CLARA_CONFIG_OPTIONAL_TYPE std::optional 5815 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 5816 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80 5821 namespace TextFlow {
5823 inline auto isWhitespace(
char c) ->
bool {
5824 static std::string chars =
" \t\n\r";
5825 return chars.find(c) != std::string::npos;
5827 inline auto isBreakableBefore(
char c) ->
bool {
5828 static std::string chars =
"[({<|";
5829 return chars.find(c) != std::string::npos;
5831 inline auto isBreakableAfter(
char c) ->
bool {
5832 static std::string chars =
"])}>.,:;*+-=&/\\";
5833 return chars.find(c) != std::string::npos;
5839 std::vector<std::string> m_strings;
5840 size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
5841 size_t m_indent = 0;
5842 size_t m_initialIndent = std::string::npos;
5848 Column
const& m_column;
5849 size_t m_stringIndex = 0;
5854 bool m_suffix =
false;
5856 iterator(Column
const& column,
size_t stringIndex)
5858 m_stringIndex(stringIndex) {}
5860 auto line()
const -> std::string
const& {
return m_column.m_strings[m_stringIndex]; }
5862 auto isBoundary(
size_t at)
const ->
bool {
5864 assert(at <= line().size());
5866 return at == line().size() ||
5867 (isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||
5868 isBreakableBefore(line()[at]) ||
5869 isBreakableAfter(line()[at - 1]);
5873 assert(m_stringIndex < m_column.m_strings.size());
5876 auto width = m_column.m_width - indent();
5878 while (m_end < line().size() && line()[m_end] !=
'\n')
5881 if (m_end < m_pos + width) {
5882 m_len = m_end - m_pos;
5885 while (len > 0 && !isBoundary(m_pos + len))
5887 while (len > 0 && isWhitespace(line()[m_pos + len - 1]))
5899 auto indent()
const ->
size_t {
5900 auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
5901 return initial == std::string::npos ? m_column.m_indent : initial;
5904 auto addIndentAndSuffix(std::string
const &plain)
const -> std::string {
5905 return std::string(indent(),
' ') + (m_suffix ? plain +
"-" : plain);
5909 using difference_type = std::ptrdiff_t;
5910 using value_type = std::string;
5911 using pointer = value_type * ;
5912 using reference = value_type & ;
5913 using iterator_category = std::forward_iterator_tag;
5915 explicit iterator(Column
const& column) : m_column(column) {
5916 assert(m_column.m_width > m_column.m_indent);
5917 assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);
5923 auto operator *()
const -> std::string {
5924 assert(m_stringIndex < m_column.m_strings.size());
5925 assert(m_pos <= m_end);
5926 return addIndentAndSuffix(line().substr(m_pos, m_len));
5929 auto operator ++() -> iterator& {
5931 if (m_pos < line().size() && line()[m_pos] ==
'\n')
5934 while (m_pos < line().size() && isWhitespace(line()[m_pos]))
5937 if (m_pos == line().size()) {
5941 if (m_stringIndex < m_column.m_strings.size())
5945 auto operator ++(
int) -> iterator {
5946 iterator prev(*
this);
5951 auto operator ==(iterator
const& other)
const ->
bool {
5953 m_pos == other.m_pos &&
5954 m_stringIndex == other.m_stringIndex &&
5955 &m_column == &other.m_column;
5957 auto operator !=(iterator
const& other)
const ->
bool {
5958 return !operator==(other);
5961 using const_iterator = iterator;
5963 explicit Column(std::string
const& text) { m_strings.push_back(text); }
5965 auto width(
size_t newWidth) -> Column& {
5966 assert(newWidth > 0);
5970 auto indent(
size_t newIndent) -> Column& {
5971 m_indent = newIndent;
5974 auto initialIndent(
size_t newIndent) -> Column& {
5975 m_initialIndent = newIndent;
5979 auto width()
const ->
size_t {
return m_width; }
5980 auto begin()
const -> iterator {
return iterator(*
this); }
5981 auto end()
const -> iterator {
return { *
this, m_strings.size() }; }
5983 inline friend std::ostream&
operator << (std::ostream& os, Column
const& col) {
5985 for (
auto line : col) {
5995 auto operator + (Column
const& other)->Columns;
5997 auto toString()
const -> std::string {
5998 std::ostringstream oss;
6004 class Spacer :
public Column {
6007 explicit Spacer(
size_t spaceWidth) : Column(
"") {
6013 std::vector<Column> m_columns;
6021 std::vector<Column>
const& m_columns;
6022 std::vector<Column::iterator> m_iterators;
6023 size_t m_activeIterators;
6025 iterator(Columns
const& columns, EndTag)
6026 : m_columns(columns.m_columns),
6027 m_activeIterators(0) {
6028 m_iterators.reserve(m_columns.size());
6030 for (
auto const& col : m_columns)
6031 m_iterators.push_back(col.end());
6035 using difference_type = std::ptrdiff_t;
6036 using value_type = std::string;
6037 using pointer = value_type * ;
6038 using reference = value_type & ;
6039 using iterator_category = std::forward_iterator_tag;
6041 explicit iterator(Columns
const& columns)
6042 : m_columns(columns.m_columns),
6043 m_activeIterators(m_columns.size()) {
6044 m_iterators.reserve(m_columns.size());
6046 for (
auto const& col : m_columns)
6047 m_iterators.push_back(col.begin());
6050 auto operator ==(iterator
const& other)
const ->
bool {
6051 return m_iterators == other.m_iterators;
6053 auto operator !=(iterator
const& other)
const ->
bool {
6054 return m_iterators != other.m_iterators;
6056 auto operator *()
const -> std::string {
6057 std::string row, padding;
6059 for (
size_t i = 0; i < m_columns.size(); ++i) {
6060 auto width = m_columns[i].width();
6061 if (m_iterators[i] != m_columns[i].
end()) {
6062 std::string col = *m_iterators[i];
6063 row += padding + col;
6064 if (col.size() < width)
6065 padding = std::string(width - col.size(),
' ');
6069 padding += std::string(width,
' ');
6074 auto operator ++() -> iterator& {
6075 for (
size_t i = 0; i < m_columns.size(); ++i) {
6076 if (m_iterators[i] != m_columns[i].
end())
6081 auto operator ++(
int) -> iterator {
6082 iterator prev(*
this);
6087 using const_iterator = iterator;
6089 auto begin()
const -> iterator {
return iterator(*
this); }
6090 auto end()
const -> iterator {
return { *
this, iterator::EndTag() }; }
6092 auto operator += (Column
const& col) -> Columns& {
6093 m_columns.push_back(col);
6096 auto operator + (Column
const& col) -> Columns {
6097 Columns combined = *
this;
6102 inline friend std::ostream&
operator << (std::ostream& os, Columns
const& cols) {
6105 for (
auto line : cols) {
6115 auto toString()
const -> std::string {
6116 std::ostringstream oss;
6139 #include <algorithm> 6141 #if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) ) 6142 #define CATCH_PLATFORM_WINDOWS 6145 namespace Catch {
namespace clara {
6149 template<
typename L>
6150 struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {};
6152 template<
typename ClassT,
typename ReturnT,
typename... Args>
6153 struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> {
6154 static const bool isValid =
false;
6157 template<
typename ClassT,
typename ReturnT,
typename ArgT>
6158 struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
6159 static const bool isValid =
true;
6160 using ArgType =
typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
6161 using ReturnType = ReturnT;
6169 std::string m_exeName;
6170 std::vector<std::string> m_args;
6173 Args(
int argc,
char const*
const* argv )
6174 : m_exeName(argv[0]),
6175 m_args(argv + 1, argv + argc) {}
6177 Args( std::initializer_list<std::string> args )
6178 : m_exeName( *args.begin() ),
6179 m_args( args.begin()+1, args.end() )
6182 auto exeName()
const -> std::string {
6189 enum class TokenType {
6197 inline auto isOptPrefix(
char c ) ->
bool {
6199 #ifdef CATCH_PLATFORM_WINDOWS 6207 using Iterator = std::vector<std::string>::const_iterator;
6210 std::vector<Token> m_tokenBuffer;
6213 m_tokenBuffer.resize( 0 );
6216 while( it != itEnd && it->empty() )
6220 auto const &next = *it;
6221 if( isOptPrefix( next[0] ) ) {
6222 auto delimiterPos = next.find_first_of(
" :=" );
6223 if( delimiterPos != std::string::npos ) {
6224 m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
6225 m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } );
6227 if( next[1] !=
'-' && next.size() > 2 ) {
6228 std::string opt =
"- ";
6229 for(
size_t i = 1; i < next.size(); ++i ) {
6231 m_tokenBuffer.push_back( { TokenType::Option, opt } );
6234 m_tokenBuffer.push_back( { TokenType::Option, next } );
6238 m_tokenBuffer.push_back( { TokenType::Argument, next } );
6244 explicit TokenStream( Args
const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {}
6246 TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) {
6250 explicit operator bool()
const {
6251 return !m_tokenBuffer.empty() || it != itEnd;
6254 auto count()
const ->
size_t {
return m_tokenBuffer.size() + (itEnd - it); }
6256 auto operator*()
const -> Token {
6257 assert( !m_tokenBuffer.empty() );
6258 return m_tokenBuffer.front();
6261 auto operator->()
const -> Token
const * {
6262 assert( !m_tokenBuffer.empty() );
6263 return &m_tokenBuffer.front();
6266 auto operator++() -> TokenStream & {
6267 if( m_tokenBuffer.size() >= 2 ) {
6268 m_tokenBuffer.erase( m_tokenBuffer.begin() );
6281 Ok, LogicError, RuntimeError