1 // ====================================================================== 2 // == DO NOT MODIFY THIS FILE BY HAND - IT IS AUTO GENERATED BY CMAKE! == 3 // ====================================================================== 4 // 5 // doctest.h - the lightest feature-rich C++ single-header testing framework for unit tests and TDD 6 // 7 // Copyright (c) 2016 Viktor Kirilov 8 // 9 // Distributed under the MIT Software License 10 // See accompanying file LICENSE.txt or copy at 11 // https://opensource.org/licenses/MIT 12 // 13 // The documentation can be found at the library's page: 14 // https://github.com/onqtam/doctest/blob/master/doc/markdown/readme.md 15 // 16 // ================================================================================================= 17 // ================================================================================================= 18 // ================================================================================================= 19 // 20 // The library is heavily influenced by Catch - https://github.com/philsquared/Catch 21 // which uses the Boost Software License - Version 1.0 22 // see here - https://github.com/philsquared/Catch/blob/master/LICENSE_1_0.txt 23 // 24 // The concept of subcases (sections in Catch) and expression decomposition are from there. 25 // Some parts of the code are taken directly: 26 // - stringification - the detection of "ostream& operator<<(ostream&, const T&)" and StringMaker<> 27 // - the Approx() helper class for floating point comparison 28 // - colors in the console 29 // - breaking into a debugger 30 // 31 // The expression decomposing templates are taken from lest - https://github.com/martinmoene/lest 32 // which uses the Boost Software License - Version 1.0 33 // see here - https://github.com/martinmoene/lest/blob/master/LICENSE_1_0.txt 34 // 35 // ================================================================================================= 36 // ================================================================================================= 37 // ================================================================================================= 38 39 // Suppress this globally (without push/pop) - there is no way to silence it in the 40 // expression decomposition macros _Pragma() in macros doesn't work for the c++ front-end of g++ 41 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55578 42 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69543 43 // Also the warning is completely worthless nowadays - http://stackoverflow.com/questions/14016993 44 #if defined(__GNUC__) && !defined(__clang__) 45 #pragma GCC diagnostic ignored "-Waggregate-return" 46 #endif 47 48 #if defined(__clang__) 49 #pragma clang diagnostic push 50 #pragma clang diagnostic ignored "-Wunknown-pragmas" 51 #pragma clang diagnostic ignored "-Wpadded" 52 #pragma clang diagnostic ignored "-Wmissing-prototypes" 53 #pragma clang diagnostic ignored "-Wshorten-64-to-32" 54 #pragma clang diagnostic ignored "-Wunused-local-typedef" 55 #endif // __clang__ 56 57 #if defined(__GNUC__) && !defined(__clang__) 58 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6) 59 #pragma GCC diagnostic push 60 #endif // > gcc 4.6 61 #pragma GCC diagnostic ignored "-Wunknown-pragmas" 62 #pragma GCC diagnostic ignored "-Weffc++" 63 #pragma GCC diagnostic ignored "-Wstrict-overflow" 64 #pragma GCC diagnostic ignored "-Wmissing-declarations" 65 #pragma GCC diagnostic ignored "-Winline" 66 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6) 67 #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" 68 #endif // > gcc 4.6 69 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 7) 70 #pragma GCC diagnostic ignored "-Wunused-local-typedefs" 71 #endif // > gcc 4.7 72 #if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ > 3) 73 #pragma GCC diagnostic ignored "-Wuseless-cast" 74 #endif // > gcc 5.3 75 #endif // __GNUC__ 76 77 #ifdef _MSC_VER 78 #pragma warning(push) 79 #pragma warning(disable : 4996) // The compiler encountered a deprecated declaration 80 #pragma warning(disable : 4706) // assignment within conditional expression 81 #pragma warning(disable : 4512) // 'class' : assignment operator could not be generated 82 #pragma warning(disable : 4127) // conditional expression is constant 83 #endif // _MSC_VER 84 85 #ifndef DOCTEST_LIBRARY_INCLUDED 86 #define DOCTEST_LIBRARY_INCLUDED 87 88 #define DOCTEST_VERSION_MAJOR 1 89 #define DOCTEST_VERSION_MINOR 1 90 #define DOCTEST_VERSION_PATCH 2 91 #define DOCTEST_VERSION_STR "1.1.2" 92 93 #define DOCTEST_VERSION \ 94 (DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + DOCTEST_VERSION_PATCH) 95 96 // ================================================================================================= 97 // == MODERN C++ FEATURE DETECTION ================================================================= 98 // ================================================================================================= 99 100 #if __cplusplus >= 201103L 101 #ifndef DOCTEST_CONFIG_WITH_NULLPTR 102 #define DOCTEST_CONFIG_WITH_NULLPTR 103 #endif // DOCTEST_CONFIG_WITH_NULLPTR 104 #ifndef DOCTEST_CONFIG_WITH_LONG_LONG 105 #define DOCTEST_CONFIG_WITH_LONG_LONG 106 #endif // DOCTEST_CONFIG_WITH_LONG_LONG 107 #ifndef DOCTEST_CONFIG_WITH_STATIC_ASSERT 108 #define DOCTEST_CONFIG_WITH_STATIC_ASSERT 109 #endif // DOCTEST_CONFIG_WITH_STATIC_ASSERT 110 #endif // __cplusplus >= 201103L 111 112 // nullptr 113 114 #ifndef DOCTEST_CONFIG_WITH_NULLPTR 115 #ifdef __clang__ 116 #if __has_feature(cxx_nullptr) 117 #define DOCTEST_CONFIG_WITH_NULLPTR 118 #endif // __has_feature(cxx_nullptr) 119 #endif // __clang__ 120 121 #if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) 122 #define DOCTEST_CONFIG_WITH_NULLPTR 123 #endif // __GNUC__ 124 125 #if defined(_MSC_VER) && (_MSC_VER >= 1600) // MSVC 2010 126 #define DOCTEST_CONFIG_WITH_NULLPTR 127 #endif // _MSC_VER 128 #endif // DOCTEST_CONFIG_WITH_NULLPTR 129 130 #if defined(DOCTEST_CONFIG_NO_NULLPTR) && defined(DOCTEST_CONFIG_WITH_NULLPTR) 131 #undef DOCTEST_CONFIG_WITH_NULLPTR 132 #endif // DOCTEST_CONFIG_NO_NULLPTR 133 134 // long long 135 136 #ifndef DOCTEST_CONFIG_WITH_LONG_LONG 137 #if !defined(DOCTEST_CONFIG_WITH_LONG_LONG) && defined(_MSC_VER) && (_MSC_VER >= 1400) 138 #define DOCTEST_CONFIG_WITH_LONG_LONG 139 #endif // _MSC_VER 140 #endif // DOCTEST_CONFIG_WITH_LONG_LONG 141 142 #if defined(DOCTEST_CONFIG_NO_LONG_LONG) && defined(DOCTEST_CONFIG_WITH_LONG_LONG) 143 #undef DOCTEST_CONFIG_WITH_LONG_LONG 144 #endif // DOCTEST_CONFIG_NO_LONG_LONG 145 146 // static_assert 147 148 #ifndef DOCTEST_CONFIG_WITH_STATIC_ASSERT 149 #ifdef __clang__ 150 #if __has_feature(cxx_static_assert) 151 #define DOCTEST_CONFIG_WITH_STATIC_ASSERT 152 #endif // __has_feature(cxx_static_assert) 153 #endif // __clang__ 154 155 #if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ >= 3 && defined(__GXX_EXPERIMENTAL_CXX0X__) 156 #define DOCTEST_CONFIG_WITH_STATIC_ASSERT 157 #endif // __GNUC__ 158 159 #if defined(_MSC_VER) && (_MSC_VER >= 1600) // MSVC 2010 160 #define DOCTEST_CONFIG_WITH_STATIC_ASSERT 161 #endif // _MSC_VER 162 #endif // DOCTEST_CONFIG_WITH_STATIC_ASSERT 163 164 #if defined(DOCTEST_CONFIG_NO_STATIC_ASSERT) && defined(DOCTEST_CONFIG_WITH_STATIC_ASSERT) 165 #undef DOCTEST_CONFIG_WITH_STATIC_ASSERT 166 #endif // DOCTEST_CONFIG_NO_STATIC_ASSERT 167 168 #if defined(DOCTEST_CONFIG_WITH_NULLPTR) || defined(DOCTEST_CONFIG_WITH_LONG_LONG) || \ 169 defined(DOCTEST_CONFIG_WITH_STATIC_ASSERT) 170 #define DOCTEST_NO_CPP11_COMPAT 171 #endif // c++11 stuff 172 173 #if defined(__clang__) && defined(DOCTEST_NO_CPP11_COMPAT) 174 #pragma clang diagnostic ignored "-Wc++98-compat" 175 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic" 176 #endif // __clang__ && DOCTEST_NO_CPP11_COMPAT 177 178 // ================================================================================================= 179 // == MODERN C++ FEATURE DETECTION END ============================================================= 180 // ================================================================================================= 181 182 // internal macros for string concatenation and anonymous variable name generation 183 #define DOCTEST_CAT_IMPL(s1, s2) s1##s2 184 #define DOCTEST_CAT(s1, s2) DOCTEST_CAT_IMPL(s1, s2) 185 #ifdef __COUNTER__ // not standard and may be missing for some compilers 186 #define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __COUNTER__) 187 #else // __COUNTER__ 188 #define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __LINE__) 189 #endif // __COUNTER__ 190 191 // macro for making a string out of an identifier 192 #define DOCTEST_TOSTR_IMPL(x) #x 193 #define DOCTEST_TOSTR(x) DOCTEST_TOSTR_IMPL(x) 194 195 // for concatenating literals and making the result a string 196 #define DOCTEST_STR_CONCAT_TOSTR(s1, s2) DOCTEST_TOSTR(s1) DOCTEST_TOSTR(s2) 197 198 // counts the number of elements in a C string 199 #define DOCTEST_COUNTOF(x) (sizeof(x) / sizeof(x[0])) 200 201 #ifndef DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE 202 #define DOCTEST_REF_WRAP(x) x& 203 #else // DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE 204 #define DOCTEST_REF_WRAP(x) x 205 #endif // DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE 206 207 // not using __APPLE__ because... this is how Catch does it 208 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) 209 #define DOCTEST_PLATFORM_MAC 210 #elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) 211 #define DOCTEST_PLATFORM_IPHONE 212 #elif defined(_WIN32) || defined(_MSC_VER) 213 #define DOCTEST_PLATFORM_WINDOWS 214 #else 215 #define DOCTEST_PLATFORM_LINUX 216 #endif 217 218 #define DOCTEST_GCS() (*doctest::detail::getTestsContextState()) 219 220 // should probably take a look at https://github.com/scottt/debugbreak 221 #ifdef DOCTEST_PLATFORM_MAC 222 // The following code snippet based on: 223 // http://cocoawithlove.com/2008/03/break-into-debugger.html 224 #if defined(__ppc64__) || defined(__ppc__) 225 #define DOCTEST_BREAK_INTO_DEBUGGER() \ 226 __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" : : : "memory", "r0", "r3", "r4") 227 #else // __ppc64__ || __ppc__ 228 #define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :) 229 #endif // __ppc64__ || __ppc__ 230 #elif defined(_MSC_VER) 231 #define DOCTEST_BREAK_INTO_DEBUGGER() __debugbreak() 232 #elif defined(__MINGW32__) 233 extern "C" __declspec(dllimport) void __stdcall DebugBreak(); 234 #define DOCTEST_BREAK_INTO_DEBUGGER() ::DebugBreak() 235 #else // linux 236 #define DOCTEST_BREAK_INTO_DEBUGGER() ((void)0) 237 #endif // linux 238 239 #define DOCTEST_BREAK_INTO_DEBUGGER_CHECKED() \ 240 if(doctest::detail::isDebuggerActive() && !DOCTEST_GCS().no_breaks) \ 241 DOCTEST_BREAK_INTO_DEBUGGER(); 242 243 #ifdef __clang__ 244 // to detect if libc++ is being used with clang (the _LIBCPP_VERSION identifier) 245 #include <ciso646> 246 #endif // __clang__ 247 248 #ifdef _LIBCPP_VERSION 249 // not forward declaring ostream for libc++ because I had some problems (inline namespaces vs c++98) 250 // so the <iosfwd> header is used - also it is very light and doesn't drag a ton of stuff 251 #include <iosfwd> 252 #else // _LIBCPP_VERSION 253 #ifndef DOCTEST_CONFIG_USE_IOSFWD 254 namespace std 255 { 256 template <class charT> 257 struct char_traits; 258 template <> 259 struct char_traits<char>; 260 template <class charT, class traits> 261 class basic_ostream; 262 typedef basic_ostream<char, char_traits<char> > ostream; 263 } 264 #else // DOCTEST_CONFIG_USE_IOSFWD 265 #include <iosfwd> 266 #endif // DOCTEST_CONFIG_USE_IOSFWD 267 #endif // _LIBCPP_VERSION 268 269 // static assert macro - because of the c++98 support requires that the message is an 270 // identifier (no spaces and not a C string) - example without quotes: I_am_a_message 271 // taken from here: http://stackoverflow.com/a/1980156/3162383 272 #ifdef DOCTEST_CONFIG_WITH_STATIC_ASSERT 273 #define DOCTEST_STATIC_ASSERT(expression, message) static_assert(expression, #message) 274 #else // DOCTEST_CONFIG_WITH_STATIC_ASSERT 275 #define DOCTEST_STATIC_ASSERT(expression, message) \ 276 struct DOCTEST_CAT(__static_assertion_at_line_, __LINE__) \ 277 { \ 278 doctest::detail::static_assert_impl::StaticAssertion<static_cast<bool>((expression))> \ 279 DOCTEST_CAT(DOCTEST_CAT(DOCTEST_CAT(STATIC_ASSERTION_FAILED_AT_LINE_, __LINE__), \ 280 _), \ 281 message); \ 282 }; \ 283 typedef doctest::detail::static_assert_impl::StaticAssertionTest<sizeof( \ 284 DOCTEST_CAT(__static_assertion_at_line_, __LINE__))> \ 285 DOCTEST_CAT(__static_assertion_test_at_line_, __LINE__) 286 #endif // DOCTEST_CONFIG_WITH_STATIC_ASSERT 287 288 #ifdef DOCTEST_CONFIG_WITH_NULLPTR 289 #ifdef _LIBCPP_VERSION 290 #include <cstddef> 291 #else // _LIBCPP_VERSION 292 namespace std 293 { typedef decltype(nullptr) nullptr_t; } 294 #endif // _LIBCPP_VERSION 295 #endif // DOCTEST_CONFIG_WITH_NULLPTR 296 297 namespace doctest 298 { 299 class String 300 { 301 char* m_str; 302 303 void copy(const String& other); 304 305 public: 306 String(const char* in = ""); 307 String(const String& other); 308 ~String(); 309 310 String& operator=(const String& other); 311 312 String operator+(const String& other) const; 313 String& operator+=(const String& other); 314 315 char& operator[](unsigned pos) { return m_str[pos]; } 316 const char& operator[](unsigned pos) const { return m_str[pos]; } 317 318 char* c_str() { return m_str; } 319 const char* c_str() const { return m_str; } 320 321 unsigned size() const; 322 unsigned length() const; 323 324 int compare(const char* other, bool no_case = false) const; 325 int compare(const String& other, bool no_case = false) const; 326 }; 327 328 // clang-format off 329 inline bool operator==(const String& lhs, const String& rhs) { return lhs.compare(rhs) == 0; } 330 inline bool operator!=(const String& lhs, const String& rhs) { return lhs.compare(rhs) != 0; } 331 inline bool operator< (const String& lhs, const String& rhs) { return lhs.compare(rhs) < 0; } 332 inline bool operator> (const String& lhs, const String& rhs) { return lhs.compare(rhs) > 0; } 333 inline bool operator<=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) < 0 : true; } 334 inline bool operator>=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) > 0 : true; } 335 // clang-format on 336 337 std::ostream& operator<<(std::ostream& stream, const String& in); 338 339 namespace detail 340 { 341 #ifndef DOCTEST_CONFIG_WITH_STATIC_ASSERT 342 namespace static_assert_impl 343 { 344 template <bool> 345 struct StaticAssertion; 346 347 template <> 348 struct StaticAssertion<true> 349 {}; 350 351 template <int i> 352 struct StaticAssertionTest 353 {}; 354 } // namespace static_assert_impl 355 #endif // DOCTEST_CONFIG_WITH_STATIC_ASSERT 356 357 template <typename T> 358 struct deferred_false 359 { static const bool value = false; }; 360 361 namespace has_insertion_operator_impl 362 { 363 typedef char no; 364 typedef char yes[2]; 365 366 struct any_t 367 { 368 template <typename T> 369 any_t(const DOCTEST_REF_WRAP(T)); 370 }; 371 372 yes& testStreamable(std::ostream&); 373 no testStreamable(no); 374 375 no operator<<(const std::ostream&, const any_t&); 376 377 template <typename T> 378 struct has_insertion_operator 379 { 380 static std::ostream& s; 381 static const DOCTEST_REF_WRAP(T) t; 382 static const bool value = sizeof(testStreamable(s << t)) == sizeof(yes); 383 }; 384 } // namespace has_insertion_operator_impl 385 386 template <typename T> 387 struct has_insertion_operator : has_insertion_operator_impl::has_insertion_operator<T> 388 {}; 389 390 std::ostream* createStream(); 391 String getStreamResult(std::ostream*); 392 void freeStream(std::ostream*); 393 394 template <bool C> 395 struct StringMakerBase 396 { 397 template <typename T> 398 static String convert(const DOCTEST_REF_WRAP(T)) { 399 return "{?}"; 400 } 401 }; 402 403 template <> 404 struct StringMakerBase<true> 405 { 406 template <typename T> 407 static String convert(const DOCTEST_REF_WRAP(T) in) { 408 std::ostream* stream = createStream(); 409 *stream << in; 410 String result = getStreamResult(stream); 411 freeStream(stream); 412 return result; 413 } 414 }; 415 416 String rawMemoryToString(const void* object, unsigned size); 417 418 template <typename T> 419 String rawMemoryToString(const DOCTEST_REF_WRAP(T) object) { 420 return rawMemoryToString(&object, sizeof(object)); 421 } 422 } // namespace detail 423 424 template <typename T> 425 struct StringMaker : detail::StringMakerBase<detail::has_insertion_operator<T>::value> 426 {}; 427 428 template <typename T> 429 struct StringMaker<T*> 430 { 431 template <typename U> 432 static String convert(U* p) { 433 if(!p) 434 return "NULL"; 435 else 436 return detail::rawMemoryToString(p); 437 } 438 }; 439 440 template <typename R, typename C> 441 struct StringMaker<R C::*> 442 { 443 static String convert(R C::*p) { 444 if(!p) 445 return "NULL"; 446 else 447 return detail::rawMemoryToString(p); 448 } 449 }; 450 451 template <typename T> 452 String toString(const DOCTEST_REF_WRAP(T) value) { 453 return StringMaker<T>::convert(value); 454 } 455 456 #ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING 457 String toString(char* in); 458 String toString(const char* in); 459 #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING 460 String toString(bool in); 461 String toString(float in); 462 String toString(double in); 463 String toString(double long in); 464 465 String toString(char in); 466 String toString(char unsigned in); 467 String toString(int short in); 468 String toString(int short unsigned in); 469 String toString(int in); 470 String toString(int unsigned in); 471 String toString(int long in); 472 String toString(int long unsigned in); 473 474 #ifdef DOCTEST_CONFIG_WITH_LONG_LONG 475 String toString(int long long in); 476 String toString(int long long unsigned in); 477 #endif // DOCTEST_CONFIG_WITH_LONG_LONG 478 479 #ifdef DOCTEST_CONFIG_WITH_NULLPTR 480 String toString(std::nullptr_t in); 481 #endif // DOCTEST_CONFIG_WITH_NULLPTR 482 483 class Approx 484 { 485 public: 486 explicit Approx(double value); 487 488 Approx(Approx const& other) 489 : m_epsilon(other.m_epsilon) 490 , m_scale(other.m_scale) 491 , m_value(other.m_value) {} 492 493 Approx operator()(double value) { 494 Approx approx(value); 495 approx.epsilon(m_epsilon); 496 approx.scale(m_scale); 497 return approx; 498 } 499 500 friend bool operator==(double lhs, Approx const& rhs); 501 friend bool operator==(Approx const& lhs, double rhs) { return operator==(rhs, lhs); } 502 friend bool operator!=(double lhs, Approx const& rhs) { return !operator==(lhs, rhs); } 503 friend bool operator!=(Approx const& lhs, double rhs) { return !operator==(rhs, lhs); } 504 505 Approx& epsilon(double newEpsilon) { 506 m_epsilon = newEpsilon; 507 return *this; 508 } 509 510 Approx& scale(double newScale) { 511 m_scale = newScale; 512 return *this; 513 } 514 515 String toString() const; 516 517 private: 518 double m_epsilon; 519 double m_scale; 520 double m_value; 521 }; 522 523 template <> 524 inline String toString<Approx>(const DOCTEST_REF_WRAP(Approx) value) { 525 return value.toString(); 526 } 527 528 #if !defined(DOCTEST_CONFIG_DISABLE) 529 530 namespace detail 531 { 532 // the function type this library works with 533 typedef void (*funcType)(void); 534 535 namespace assertType 536 { 537 enum Enum 538 { 539 // macro traits 540 541 is_warn = 1, 542 is_check = 2, 543 is_require = 4, 544 545 is_throws = 8, 546 is_throws_as = 16, 547 is_nothrow = 32, 548 549 is_fast = 64, // not checked anywhere - used just to distinguish the types 550 is_false = 128, 551 is_unary = 256, 552 553 is_eq = 512, 554 is_ne = 1024, 555 556 is_lt = 2048, 557 is_gt = 4096, 558 559 is_ge = 8192, 560 is_le = 16384, 561 562 // macro types 563 564 DT_WARN = is_warn, 565 DT_CHECK = is_check, 566 DT_REQUIRE = is_require, 567 568 DT_WARN_FALSE = is_false | is_warn, 569 DT_CHECK_FALSE = is_false | is_check, 570 DT_REQUIRE_FALSE = is_false | is_require, 571 572 DT_WARN_THROWS = is_throws | is_warn, 573 DT_CHECK_THROWS = is_throws | is_check, 574 DT_REQUIRE_THROWS = is_throws | is_require, 575 576 DT_WARN_THROWS_AS = is_throws_as | is_warn, 577 DT_CHECK_THROWS_AS = is_throws_as | is_check, 578 DT_REQUIRE_THROWS_AS = is_throws_as | is_require, 579 580 DT_WARN_NOTHROW = is_nothrow | is_warn, 581 DT_CHECK_NOTHROW = is_nothrow | is_check, 582 DT_REQUIRE_NOTHROW = is_nothrow | is_require, 583 584 DT_WARN_EQ = is_eq | is_warn, 585 DT_CHECK_EQ = is_eq | is_check, 586 DT_REQUIRE_EQ = is_eq | is_require, 587 588 DT_WARN_NE = is_ne | is_warn, 589 DT_CHECK_NE = is_ne | is_check, 590 DT_REQUIRE_NE = is_ne | is_require, 591 592 DT_WARN_GT = is_gt | is_warn, 593 DT_CHECK_GT = is_gt | is_check, 594 DT_REQUIRE_GT = is_gt | is_require, 595 596 DT_WARN_LT = is_lt | is_warn, 597 DT_CHECK_LT = is_lt | is_check, 598 DT_REQUIRE_LT = is_lt | is_require, 599 600 DT_WARN_GE = is_ge | is_warn, 601 DT_CHECK_GE = is_ge | is_check, 602 DT_REQUIRE_GE = is_ge | is_require, 603 604 DT_WARN_LE = is_le | is_warn, 605 DT_CHECK_LE = is_le | is_check, 606 DT_REQUIRE_LE = is_le | is_require, 607 608 DT_WARN_UNARY = is_unary | is_warn, 609 DT_CHECK_UNARY = is_unary | is_check, 610 DT_REQUIRE_UNARY = is_unary | is_require, 611 612 DT_WARN_UNARY_FALSE = is_false | is_unary | is_warn, 613 DT_CHECK_UNARY_FALSE = is_false | is_unary | is_check, 614 DT_REQUIRE_UNARY_FALSE = is_false | is_unary | is_require, 615 616 DT_FAST_WARN_EQ = is_fast | is_eq | is_warn, 617 DT_FAST_CHECK_EQ = is_fast | is_eq | is_check, 618 DT_FAST_REQUIRE_EQ = is_fast | is_eq | is_require, 619 620 DT_FAST_WARN_NE = is_fast | is_ne | is_warn, 621 DT_FAST_CHECK_NE = is_fast | is_ne | is_check, 622 DT_FAST_REQUIRE_NE = is_fast | is_ne | is_require, 623 624 DT_FAST_WARN_GT = is_fast | is_gt | is_warn, 625 DT_FAST_CHECK_GT = is_fast | is_gt | is_check, 626 DT_FAST_REQUIRE_GT = is_fast | is_gt | is_require, 627 628 DT_FAST_WARN_LT = is_fast | is_lt | is_warn, 629 DT_FAST_CHECK_LT = is_fast | is_lt | is_check, 630 DT_FAST_REQUIRE_LT = is_fast | is_lt | is_require, 631 632 DT_FAST_WARN_GE = is_fast | is_ge | is_warn, 633 DT_FAST_CHECK_GE = is_fast | is_ge | is_check, 634 DT_FAST_REQUIRE_GE = is_fast | is_ge | is_require, 635 636 DT_FAST_WARN_LE = is_fast | is_le | is_warn, 637 DT_FAST_CHECK_LE = is_fast | is_le | is_check, 638 DT_FAST_REQUIRE_LE = is_fast | is_le | is_require, 639 640 DT_FAST_WARN_UNARY = is_fast | is_unary | is_warn, 641 DT_FAST_CHECK_UNARY = is_fast | is_unary | is_check, 642 DT_FAST_REQUIRE_UNARY = is_fast | is_unary | is_require, 643 644 DT_FAST_WARN_UNARY_FALSE = is_fast | is_false | is_unary | is_warn, 645 DT_FAST_CHECK_UNARY_FALSE = is_fast | is_false | is_unary | is_check, 646 DT_FAST_REQUIRE_UNARY_FALSE = is_fast | is_false | is_unary | is_require 647 }; 648 } // namespace assertType 649 650 const char* getAssertString(assertType::Enum val); 651 652 // clang-format off 653 template<class T> struct decay_array { typedef T type; }; 654 template<class T, unsigned N> struct decay_array<T[N]> { typedef T* type; }; 655 template<class T> struct decay_array<T[]> { typedef T* type; }; 656 657 template<class T> struct not_char_pointer { enum { value = true }; }; 658 template<> struct not_char_pointer<char*> { enum { value = false }; }; 659 template<> struct not_char_pointer<const char*> { enum { value = false }; }; 660 661 template<class T> struct can_use_op : not_char_pointer<typename decay_array<T>::type> {}; 662 663 template<bool, class = void> struct enable_if {}; 664 template<class T> struct enable_if<true, T> { typedef T type; }; 665 // clang-format on 666 667 struct TestFailureException 668 {}; 669 670 bool checkIfShouldThrow(assertType::Enum assert_type); 671 void fastAssertThrowIfFlagSet(int flags); 672 void throwException(); 673 bool always_false(); 674 675 // a struct defining a registered test callback 676 struct TestData 677 { 678 // not used for determining uniqueness 679 const char* m_suite; // the test suite in which the test was added 680 const char* m_name; // name of the test function 681 funcType m_f; // a function pointer to the test function 682 683 // fields by which uniqueness of test cases shall be determined 684 const char* m_file; // the file in which the test was registered 685 unsigned m_line; // the line where the test was registered 686 687 TestData(const char* suite, const char* name, funcType f, const char* file, unsigned line) 688 : m_suite(suite) 689 , m_name(name) 690 , m_f(f) 691 , m_file(file) 692 , m_line(line) {} 693 694 bool operator<(const TestData& other) const; 695 }; 696 697 struct SubcaseSignature 698 { 699 const char* m_name; 700 const char* m_file; 701 int m_line; 702 703 SubcaseSignature(const char* name, const char* file, int line) 704 : m_name(name) 705 , m_file(file) 706 , m_line(line) {} 707 708 bool operator<(const SubcaseSignature& other) const; 709 }; 710 711 struct Subcase 712 { 713 SubcaseSignature m_signature; 714 bool m_entered; 715 716 Subcase(const char* name, const char* file, int line); 717 Subcase(const Subcase& other); 718 ~Subcase(); 719 720 operator bool() const { return m_entered; } 721 }; 722 723 template <typename L, typename R> 724 String stringifyBinaryExpr(const DOCTEST_REF_WRAP(L) lhs, const char* op, 725 const DOCTEST_REF_WRAP(R) rhs) { 726 return toString(lhs) + op + toString(rhs); 727 } 728 729 struct Result 730 { 731 bool m_passed; 732 String m_decomposition; 733 734 // to fix gcc 4.7 "-Winline" warnings 735 #if defined(__GNUC__) && !defined(__clang__) 736 __attribute__((noinline)) 737 #endif 738 ~Result() { 739 } 740 741 Result(bool passed = false, const String& decomposition = String()) 742 : m_passed(passed) 743 , m_decomposition(decomposition) {} 744 745 Result(const Result& other) 746 : m_passed(other.m_passed) 747 , m_decomposition(other.m_decomposition) {} 748 749 // to fix gcc 4.7 "-Winline" warnings 750 #if defined(__GNUC__) && !defined(__clang__) 751 __attribute__((noinline)) 752 #endif 753 Result& 754 operator=(const Result& other) { 755 m_passed = other.m_passed; 756 m_decomposition = other.m_decomposition; 757 758 return *this; 759 } 760 761 operator bool() { return !m_passed; } 762 763 void invert() { m_passed = !m_passed; } 764 765 // clang-format off 766 // forbidding some expressions based on this table: http://en.cppreference.com/w/cpp/language/operator_precedence 767 template <typename R> Result operator& (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return Result(); } 768 template <typename R> Result operator^ (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return Result(); } 769 template <typename R> Result operator| (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return Result(); } 770 template <typename R> Result operator&& (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return Result(); } 771 template <typename R> Result operator|| (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return Result(); } 772 template <typename R> Result operator== (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return Result(); } 773 template <typename R> Result operator!= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return Result(); } 774 template <typename R> Result operator< (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return Result(); } 775 template <typename R> Result operator> (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return Result(); } 776 template <typename R> Result operator<= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return Result(); } 777 template <typename R> Result operator>= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return Result(); } 778 template <typename R> Result operator= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return Result(); } 779 template <typename R> Result operator+= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return Result(); } 780 template <typename R> Result operator-= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return Result(); } 781 template <typename R> Result operator*= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return Result(); } 782 template <typename R> Result operator/= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return Result(); } 783 template <typename R> Result operator%= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return Result(); } 784 template <typename R> Result operator<<=(const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return Result(); } 785 template <typename R> Result operator>>=(const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return Result(); } 786 template <typename R> Result operator&= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return Result(); } 787 template <typename R> Result operator^= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return Result(); } 788 template <typename R> Result operator|= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return Result(); } 789 // clang-format on 790 }; 791 792 #ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION 793 794 #if defined(__clang__) 795 #pragma clang diagnostic push 796 #pragma clang diagnostic ignored "-Wsign-conversion" 797 #pragma clang diagnostic ignored "-Wsign-compare" 798 #pragma clang diagnostic ignored "-Wdouble-promotion" 799 //#pragma clang diagnostic ignored "-Wconversion" 800 //#pragma clang diagnostic ignored "-Wfloat-equal" 801 #endif // __clang__ 802 803 #if defined(__GNUC__) && !defined(__clang__) 804 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6) 805 #pragma GCC diagnostic push 806 #endif // > gcc 4.6 807 #pragma GCC diagnostic ignored "-Wsign-conversion" 808 #pragma GCC diagnostic ignored "-Wsign-compare" 809 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5) 810 #pragma GCC diagnostic ignored "-Wdouble-promotion" 811 #endif // > gcc 4.5 812 //#pragma GCC diagnostic ignored "-Wconversion" 813 //#pragma GCC diagnostic ignored "-Wfloat-equal" 814 #endif // __GNUC__ 815 816 #ifdef _MSC_VER 817 #pragma warning(push) 818 // http://stackoverflow.com/questions/39479163 what's the difference between C4018 and C4389 819 #pragma warning(disable : 4389) // 'operator' : signed/unsigned mismatch 820 #pragma warning(disable : 4018) // 'expression' : signed/unsigned mismatch 821 //#pragma warning(disable : 4805) // 'operation' : unsafe mix of type 'type' and type 'type' in operation 822 #endif // _MSC_VER 823 824 #endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION 825 826 // clang-format off 827 #ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING 828 #define DOCTEST_COMPARISON_RETURN_TYPE bool 829 #else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING 830 #define DOCTEST_COMPARISON_RETURN_TYPE typename enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type 831 inline bool eq(const char* lhs, const char* rhs) { return String(lhs) == String(rhs); } 832 inline bool ne(const char* lhs, const char* rhs) { return String(lhs) != String(rhs); } 833 inline bool lt(const char* lhs, const char* rhs) { return String(lhs) < String(rhs); } 834 inline bool gt(const char* lhs, const char* rhs) { return String(lhs) > String(rhs); } 835 inline bool le(const char* lhs, const char* rhs) { return String(lhs) <= String(rhs); } 836 inline bool ge(const char* lhs, const char* rhs) { return String(lhs) >= String(rhs); } 837 #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING 838 839 template <typename L, typename R> DOCTEST_COMPARISON_RETURN_TYPE eq(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) { return lhs == rhs; } 840 template <typename L, typename R> DOCTEST_COMPARISON_RETURN_TYPE ne(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) { return lhs != rhs; } 841 template <typename L, typename R> DOCTEST_COMPARISON_RETURN_TYPE lt(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) { return lhs < rhs; } 842 template <typename L, typename R> DOCTEST_COMPARISON_RETURN_TYPE gt(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) { return lhs > rhs; } 843 template <typename L, typename R> DOCTEST_COMPARISON_RETURN_TYPE le(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) { return lhs <= rhs; } 844 template <typename L, typename R> DOCTEST_COMPARISON_RETURN_TYPE ge(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) { return lhs >= rhs; } 845 // clang-format on 846 847 template <typename L> 848 struct Expression_lhs 849 { 850 L lhs; 851 852 Expression_lhs(L in) 853 : lhs(in) {} 854 855 Expression_lhs(const Expression_lhs& other) 856 : lhs(other.lhs) {} 857 858 operator Result() { return Result(!!lhs, toString(lhs)); } 859 860 // clang-format off 861 #ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING 862 template <typename R> Result operator==(const DOCTEST_REF_WRAP(R) rhs) { return Result(lhs == rhs, stringifyBinaryExpr(lhs, " == ", rhs)); } 863 template <typename R> Result operator!=(const DOCTEST_REF_WRAP(R) rhs) { return Result(lhs != rhs, stringifyBinaryExpr(lhs, " != ", rhs)); } 864 template <typename R> Result operator< (const DOCTEST_REF_WRAP(R) rhs) { return Result(lhs < rhs, stringifyBinaryExpr(lhs, " < " , rhs)); } 865 template <typename R> Result operator<=(const DOCTEST_REF_WRAP(R) rhs) { return Result(lhs <= rhs, stringifyBinaryExpr(lhs, " <= ", rhs)); } 866 template <typename R> Result operator> (const DOCTEST_REF_WRAP(R) rhs) { return Result(lhs > rhs, stringifyBinaryExpr(lhs, " > " , rhs)); } 867 template <typename R> Result operator>=(const DOCTEST_REF_WRAP(R) rhs) { return Result(lhs >= rhs, stringifyBinaryExpr(lhs, " >= ", rhs)); } 868 #else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING 869 template <typename R> Result operator==(const DOCTEST_REF_WRAP(R) rhs) { return Result(eq(lhs, rhs), stringifyBinaryExpr(lhs, " == ", rhs)); } 870 template <typename R> Result operator!=(const DOCTEST_REF_WRAP(R) rhs) { return Result(ne(lhs, rhs), stringifyBinaryExpr(lhs, " != ", rhs)); } 871 template <typename R> Result operator< (const DOCTEST_REF_WRAP(R) rhs) { return Result(lt(lhs, rhs), stringifyBinaryExpr(lhs, " < " , rhs)); } 872 template <typename R> Result operator<=(const DOCTEST_REF_WRAP(R) rhs) { return Result(le(lhs, rhs), stringifyBinaryExpr(lhs, " <= ", rhs)); } 873 template <typename R> Result operator> (const DOCTEST_REF_WRAP(R) rhs) { return Result(gt(lhs, rhs), stringifyBinaryExpr(lhs, " > " , rhs)); } 874 template <typename R> Result operator>=(const DOCTEST_REF_WRAP(R) rhs) { return Result(ge(lhs, rhs), stringifyBinaryExpr(lhs, " >= ", rhs)); } 875 #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING 876 // clang-format on 877 878 // clang-format off 879 // forbidding some expressions based on this table: http://en.cppreference.com/w/cpp/language/operator_precedence 880 template <typename R> int operator& (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return int(); } 881 template <typename R> int operator^ (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return int(); } 882 template <typename R> int operator| (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return int(); } 883 template <typename R> int operator&& (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return int(); } 884 template <typename R> int operator|| (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return int(); } 885 template <typename R> int operator= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return int(); } 886 template <typename R> int operator+= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return int(); } 887 template <typename R> int operator-= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return int(); } 888 template <typename R> int operator*= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return int(); } 889 template <typename R> int operator/= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return int(); } 890 template <typename R> int operator%= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return int(); } 891 template <typename R> int operator<<=(const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return int(); } 892 template <typename R> int operator>>=(const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return int(); } 893 template <typename R> int operator&= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return int(); } 894 template <typename R> int operator^= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return int(); } 895 template <typename R> int operator|= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return int(); } 896 // these 2 are unfortunate because they should be allowed - they have higher precedence over the comparisons, but the 897 // ExpressionDecomposer class uses the left shift operator to capture the left operand of the binary expression... 898 template <typename R> int operator<< (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Please_Surround_The_Left_Shift_Operation_With_Parenthesis); return int(); } 899 template <typename R> int operator>> (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Please_Surround_The_Right_Shift_Operation_With_Parenthesis); return int(); } 900 // clang-format on 901 }; 902 903 #ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION 904 905 #if defined(__clang__) 906 #pragma clang diagnostic pop 907 #endif // __clang__ 908 909 #if defined(__GNUC__) && !defined(__clang__) 910 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6) 911 #pragma GCC diagnostic pop 912 #endif // > gcc 4.6 913 #endif // __GNUC__ 914 915 #ifdef _MSC_VER 916 #pragma warning(pop) 917 #endif // _MSC_VER 918 919 #endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION 920 921 struct ExpressionDecomposer 922 { 923 template <typename L> 924 Expression_lhs<const DOCTEST_REF_WRAP(L)> operator<<(const DOCTEST_REF_WRAP(L) operand) { 925 return Expression_lhs<const DOCTEST_REF_WRAP(L)>(operand); 926 } 927 }; 928 929 // forward declarations of functions used by the macros 930 int regTest(void (*f)(void), unsigned line, const char* file, const char* name); 931 int setTestSuiteName(const char* name); 932 933 void addFailedAssert(assertType::Enum assert_type); 934 935 void logTestStart(const char* name, const char* file, unsigned line); 936 void logTestEnd(); 937 938 void logTestCrashed(); 939 940 void logAssert(bool passed, const char* decomposition, bool threw, const char* expr, 941 assertType::Enum assert_type, const char* file, int line); 942 943 void logAssertThrows(bool threw, const char* expr, assertType::Enum assert_type, 944 const char* file, int line); 945 946 void logAssertThrowsAs(bool threw, bool threw_as, const char* as, const char* expr, 947 assertType::Enum assert_type, const char* file, int line); 948 949 void logAssertNothrow(bool threw, const char* expr, assertType::Enum assert_type, 950 const char* file, int line); 951 952 bool isDebuggerActive(); 953 void writeToDebugConsole(const String&); 954 955 struct TestAccessibleContextState 956 { 957 bool success; // include successful assertions in output 958 bool no_throw; // to skip exceptions-related assertion macros 959 bool no_breaks; // to not break into the debugger 960 const TestData* currentTest; 961 bool hasLoggedCurrentTestStart; 962 int numAssertionsForCurrentTestcase; 963 }; 964 965 struct ContextState; 966 967 TestAccessibleContextState* getTestsContextState(); 968 969 namespace binaryAssertComparison 970 { 971 enum Enum 972 { 973 eq = 0, 974 ne, 975 gt, 976 lt, 977 ge, 978 le 979 }; 980 } // namespace binaryAssertComparison 981 982 // clang-format off 983 template <int, class L, class R> struct RelationalComparator { bool operator()(const DOCTEST_REF_WRAP(L), const DOCTEST_REF_WRAP(R) ) const { return false; } }; 984 template <class L, class R> struct RelationalComparator<0, L, R> { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return eq(lhs, rhs); } }; 985 template <class L, class R> struct RelationalComparator<1, L, R> { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return ne(lhs, rhs); } }; 986 template <class L, class R> struct RelationalComparator<2, L, R> { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return gt(lhs, rhs); } }; 987 template <class L, class R> struct RelationalComparator<3, L, R> { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return lt(lhs, rhs); } }; 988 template <class L, class R> struct RelationalComparator<4, L, R> { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return ge(lhs, rhs); } }; 989 template <class L, class R> struct RelationalComparator<5, L, R> { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return le(lhs, rhs); } }; 990 // clang-format on 991 992 struct ResultBuilder 993 { 994 assertType::Enum m_assert_type; 995 const char* m_file; 996 int m_line; 997 const char* m_expr; 998 const char* m_exception_type; 999 1000 Result m_result; 1001 bool m_threw; 1002 bool m_threw_as; 1003 bool m_failed; 1004 1005 ResultBuilder(assertType::Enum assert_type, const char* file, int line, const char* expr, 1006 const char* exception_type = ""); 1007 1008 // to fix gcc 4.7 "-Winline" warnings 1009 #if defined(__GNUC__) && !defined(__clang__) 1010 __attribute__((noinline)) 1011 #endif 1012 ~ResultBuilder() { 1013 } 1014 1015 void setResult(const Result& res) { m_result = res; } 1016 1017 template <int comparison, typename L, typename R> 1018 void binary_assert(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) { 1019 m_result.m_passed = RelationalComparator<comparison, L, R>()(lhs, rhs); 1020 m_result.m_decomposition = stringifyBinaryExpr(lhs, ", ", rhs); 1021 } 1022 1023 template <typename L> 1024 void unary_assert(const DOCTEST_REF_WRAP(L) val) { 1025 m_result.m_passed = !!val; 1026 m_result.m_decomposition = toString(val); 1027 } 1028 1029 bool log(); 1030 void react() const; 1031 }; 1032 1033 namespace assertAction 1034 { 1035 enum Enum 1036 { 1037 nothing = 0, 1038 dbgbreak = 1, 1039 shouldthrow = 2 1040 }; 1041 } // namespace assertAction 1042 1043 template <int comparison, typename L, typename R> 1044 int fast_binary_assert(assertType::Enum assert_type, const char* file, int line, 1045 const char* lhs_str, const char* rhs_str, const DOCTEST_REF_WRAP(L) lhs, 1046 const DOCTEST_REF_WRAP(R) rhs) { 1047 String expr = String(lhs_str) + ", " + rhs_str; 1048 const char* expr_str = expr.c_str(); 1049 ResultBuilder rb(assert_type, file, line, expr_str); 1050 1051 rb.m_result.m_passed = RelationalComparator<comparison, L, R>()(lhs, rhs); 1052 rb.m_result.m_decomposition = stringifyBinaryExpr(lhs, ", ", rhs); 1053 1054 int res = 0; 1055 1056 if(rb.log()) 1057 res |= assertAction::dbgbreak; 1058 1059 if(rb.m_failed && checkIfShouldThrow(assert_type)) 1060 res |= assertAction::shouldthrow; 1061 1062 #ifdef DOCTEST_CONFIG_SUPER_FAST_ASSERTS 1063 // ######################################################################################### 1064 // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK TO SEE THE FAILING ASSERTION 1065 // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED 1066 // ######################################################################################### 1067 if(res & assertAction::dbgbreak) 1068 DOCTEST_BREAK_INTO_DEBUGGER(); 1069 fastAssertThrowIfFlagSet(res); 1070 #endif // DOCTEST_CONFIG_SUPER_FAST_ASSERTS 1071 1072 return res; 1073 } 1074 1075 template <typename L> 1076 int fast_unary_assert(assertType::Enum assert_type, const char* file, int line, 1077 const char* val_str, const DOCTEST_REF_WRAP(L) val) { 1078 ResultBuilder rb(assert_type, file, line, val_str); 1079 1080 rb.m_result.m_passed = !!val; 1081 rb.m_result.m_decomposition = toString(val); 1082 1083 int res = 0; 1084 1085 if(rb.log()) 1086 res |= assertAction::dbgbreak; 1087 1088 if(rb.m_failed && checkIfShouldThrow(assert_type)) 1089 res |= assertAction::shouldthrow; 1090 1091 #ifdef DOCTEST_CONFIG_SUPER_FAST_ASSERTS 1092 // ######################################################################################### 1093 // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK TO SEE THE FAILING ASSERTION 1094 // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED 1095 // ######################################################################################### 1096 if(res & assertAction::dbgbreak) 1097 DOCTEST_BREAK_INTO_DEBUGGER(); 1098 fastAssertThrowIfFlagSet(res); 1099 #endif // DOCTEST_CONFIG_SUPER_FAST_ASSERTS 1100 1101 return res; 1102 } 1103 } // namespace detail 1104 1105 #endif // DOCTEST_CONFIG_DISABLE 1106 1107 class Context 1108 { 1109 #if !defined(DOCTEST_CONFIG_DISABLE) 1110 detail::ContextState* p; 1111 1112 void parseArgs(int argc, const char* const* argv, bool withDefaults = false); 1113 1114 #endif // DOCTEST_CONFIG_DISABLE 1115 1116 public: 1117 Context(int argc = 0, const char* const* argv = 0); 1118 1119 // to fix gcc 4.7 "-Winline" warnings 1120 #if defined(__GNUC__) && !defined(__clang__) 1121 __attribute__((noinline)) 1122 #endif 1123 ~Context(); 1124 1125 void applyCommandLine(int argc, const char* const* argv); 1126 1127 void addFilter(const char* filter, const char* value); 1128 void clearFilters(); 1129 void setOption(const char* option, int value); 1130 void setOption(const char* option, const char* value); 1131 1132 bool shouldExit(); 1133 1134 int run(); 1135 }; 1136 1137 } // namespace doctest 1138 1139 // if registering is not disabled 1140 #if !defined(DOCTEST_CONFIG_DISABLE) 1141 1142 // registers the test by initializing a dummy var with a function 1143 #if defined(__GNUC__) && !defined(__clang__) 1144 #define DOCTEST_REGISTER_FUNCTION(f, name) \ 1145 static int DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_) __attribute__((unused)) = \ 1146 doctest::detail::regTest(f, __LINE__, __FILE__, name); 1147 #elif defined(__clang__) 1148 #define DOCTEST_REGISTER_FUNCTION(f, name) \ 1149 _Pragma("clang diagnostic push") \ 1150 _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") static int \ 1151 DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_) = \ 1152 doctest::detail::regTest(f, __LINE__, __FILE__, name); \ 1153 _Pragma("clang diagnostic pop") 1154 #else // MSVC 1155 #define DOCTEST_REGISTER_FUNCTION(f, name) \ 1156 static int DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_) = \ 1157 doctest::detail::regTest(f, __LINE__, __FILE__, name); 1158 #endif // MSVC 1159 1160 #define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, name) \ 1161 namespace \ 1162 { \ 1163 struct der : base \ 1164 { void f(); }; \ 1165 static void func() { \ 1166 der v; \ 1167 v.f(); \ 1168 } \ 1169 DOCTEST_REGISTER_FUNCTION(func, name) \ 1170 } \ 1171 inline void der::f() 1172 1173 #define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, name) \ 1174 static void f(); \ 1175 DOCTEST_REGISTER_FUNCTION(f, name) \ 1176 inline void f() 1177 1178 // for registering tests 1179 #define DOCTEST_TEST_CASE(name) \ 1180 DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), name) 1181 1182 // for registering tests with a fixture 1183 #define DOCTEST_TEST_CASE_FIXTURE(c, name) \ 1184 DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(_DOCTEST_ANON_CLASS_), c, \ 1185 DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), name) 1186 1187 // for subcases 1188 #if defined(__GNUC__) 1189 #define DOCTEST_SUBCASE(name) \ 1190 if(const doctest::detail::Subcase & DOCTEST_ANONYMOUS(_DOCTEST_ANON_SUBCASE_) \ 1191 __attribute__((unused)) = \ 1192 doctest::detail::Subcase(name, __FILE__, __LINE__)) 1193 #else // __GNUC__ 1194 #define DOCTEST_SUBCASE(name) \ 1195 if(const doctest::detail::Subcase & DOCTEST_ANONYMOUS(_DOCTEST_ANON_SUBCASE_) = \ 1196 doctest::detail::Subcase(name, __FILE__, __LINE__)) 1197 #endif // __GNUC__ 1198 1199 // for starting a testsuite block 1200 #if defined(__GNUC__) && !defined(__clang__) 1201 #define DOCTEST_TEST_SUITE(name) \ 1202 static int DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_) __attribute__((unused)) = \ 1203 doctest::detail::setTestSuiteName(name); \ 1204 typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) 1205 #elif defined(__clang__) 1206 #define DOCTEST_TEST_SUITE(name) \ 1207 _Pragma("clang diagnostic push") \ 1208 _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") static int \ 1209 DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_) = \ 1210 doctest::detail::setTestSuiteName(name); \ 1211 _Pragma("clang diagnostic pop") typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) 1212 #else // MSVC 1213 #define DOCTEST_TEST_SUITE(name) \ 1214 static int DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_) = doctest::detail::setTestSuiteName(name); \ 1215 typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) 1216 #endif // MSVC 1217 1218 // for ending a testsuite block 1219 #if defined(__GNUC__) && !defined(__clang__) 1220 #define DOCTEST_TEST_SUITE_END \ 1221 static int DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_) __attribute__((unused)) = \ 1222 doctest::detail::setTestSuiteName(""); \ 1223 typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) 1224 #elif defined(__clang__) 1225 #define DOCTEST_TEST_SUITE_END \ 1226 _Pragma("clang diagnostic push") \ 1227 _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") static int \ 1228 DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_) = doctest::detail::setTestSuiteName(""); \ 1229 _Pragma("clang diagnostic pop") typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) 1230 #else // MSVC 1231 #define DOCTEST_TEST_SUITE_END \ 1232 static int DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_) = doctest::detail::setTestSuiteName(""); \ 1233 typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) 1234 #endif // MSVC 1235 1236 #define DOCTEST_ASSERT_LOG_AND_REACT(rb) \ 1237 if(rb.log()) \ 1238 DOCTEST_BREAK_INTO_DEBUGGER(); \ 1239 rb.react() 1240 1241 #define DOCTEST_ASSERT_IMPLEMENT(expr, assert_type) \ 1242 doctest::detail::ResultBuilder _DOCTEST_RB(doctest::detail::assertType::assert_type, __FILE__, \ 1243 __LINE__, #expr); \ 1244 try { \ 1245 _DOCTEST_RB.setResult(doctest::detail::ExpressionDecomposer() << expr); \ 1246 } catch(...) { _DOCTEST_RB.m_threw = true; } \ 1247 DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); 1248 1249 #if defined(__clang__) 1250 #define DOCTEST_ASSERT_PROXY(expr, assert_type) \ 1251 do { \ 1252 _Pragma("clang diagnostic push") \ 1253 _Pragma("clang diagnostic ignored \"-Woverloaded-shift-op-parentheses\"") \ 1254 DOCTEST_ASSERT_IMPLEMENT(expr, assert_type) \ 1255 _Pragma("clang diagnostic pop") \ 1256 } while(doctest::detail::always_false()) 1257 #else // __clang__ 1258 #define DOCTEST_ASSERT_PROXY(expr, assert_type) \ 1259 do { \ 1260 DOCTEST_ASSERT_IMPLEMENT(expr, assert_type) \ 1261 } while(doctest::detail::always_false()) 1262 #endif // __clang__ 1263 1264 #define DOCTEST_WARN(expr) DOCTEST_ASSERT_PROXY(expr, DT_WARN) 1265 #define DOCTEST_CHECK(expr) DOCTEST_ASSERT_PROXY(expr, DT_CHECK) 1266 #define DOCTEST_REQUIRE(expr) DOCTEST_ASSERT_PROXY(expr, DT_REQUIRE) 1267 1268 #define DOCTEST_WARN_FALSE(expr) DOCTEST_ASSERT_PROXY(expr, DT_WARN_FALSE) 1269 #define DOCTEST_CHECK_FALSE(expr) DOCTEST_ASSERT_PROXY(expr, DT_CHECK_FALSE) 1270 #define DOCTEST_REQUIRE_FALSE(expr) DOCTEST_ASSERT_PROXY(expr, DT_REQUIRE_FALSE) 1271 1272 #define DOCTEST_ASSERT_THROWS(expr, assert_type) \ 1273 do { \ 1274 if(!DOCTEST_GCS().no_throw) { \ 1275 doctest::detail::ResultBuilder _DOCTEST_RB(doctest::detail::assertType::assert_type, \ 1276 __FILE__, __LINE__, #expr); \ 1277 try { \ 1278 expr; \ 1279 } catch(...) { _DOCTEST_RB.m_threw = true; } \ 1280 DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ 1281 } \ 1282 } while(doctest::detail::always_false()) 1283 1284 #define DOCTEST_ASSERT_THROWS_AS(expr, as, assert_type) \ 1285 do { \ 1286 if(!DOCTEST_GCS().no_throw) { \ 1287 doctest::detail::ResultBuilder _DOCTEST_RB(doctest::detail::assertType::assert_type, \ 1288 __FILE__, __LINE__, #expr, #as); \ 1289 try { \ 1290 expr; \ 1291 } catch(as) { \ 1292 _DOCTEST_RB.m_threw = true; \ 1293 _DOCTEST_RB.m_threw_as = true; \ 1294 } catch(...) { _DOCTEST_RB.m_threw = true; } \ 1295 DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ 1296 } \ 1297 } while(doctest::detail::always_false()) 1298 1299 #define DOCTEST_ASSERT_NOTHROW(expr, assert_type) \ 1300 do { \ 1301 if(!DOCTEST_GCS().no_throw) { \ 1302 doctest::detail::ResultBuilder _DOCTEST_RB(doctest::detail::assertType::assert_type, \ 1303 __FILE__, __LINE__, #expr); \ 1304 try { \ 1305 expr; \ 1306 } catch(...) { _DOCTEST_RB.m_threw = true; } \ 1307 DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ 1308 } \ 1309 } while(doctest::detail::always_false()) 1310 1311 #define DOCTEST_WARN_THROWS(expr) DOCTEST_ASSERT_THROWS(expr, DT_WARN_THROWS) 1312 #define DOCTEST_CHECK_THROWS(expr) DOCTEST_ASSERT_THROWS(expr, DT_CHECK_THROWS) 1313 #define DOCTEST_REQUIRE_THROWS(expr) DOCTEST_ASSERT_THROWS(expr, DT_REQUIRE_THROWS) 1314 1315 #define DOCTEST_WARN_THROWS_AS(expr, ex) DOCTEST_ASSERT_THROWS_AS(expr, ex, DT_WARN_THROWS_AS) 1316 #define DOCTEST_CHECK_THROWS_AS(expr, ex) DOCTEST_ASSERT_THROWS_AS(expr, ex, DT_CHECK_THROWS_AS) 1317 #define DOCTEST_REQUIRE_THROWS_AS(expr, ex) DOCTEST_ASSERT_THROWS_AS(expr, ex, DT_REQUIRE_THROWS_AS) 1318 1319 #define DOCTEST_WARN_NOTHROW(expr) DOCTEST_ASSERT_NOTHROW(expr, DT_WARN_NOTHROW) 1320 #define DOCTEST_CHECK_NOTHROW(expr) DOCTEST_ASSERT_NOTHROW(expr, DT_CHECK_NOTHROW) 1321 #define DOCTEST_REQUIRE_NOTHROW(expr) DOCTEST_ASSERT_NOTHROW(expr, DT_REQUIRE_NOTHROW) 1322 1323 #define DOCTEST_BINARY_ASSERT(assert_type, lhs, rhs, comp) \ 1324 do { \ 1325 doctest::detail::ResultBuilder _DOCTEST_RB(doctest::detail::assertType::assert_type, \ 1326 __FILE__, __LINE__, #lhs ", " #rhs); \ 1327 try { \ 1328 _DOCTEST_RB.binary_assert<doctest::detail::binaryAssertComparison::comp>(lhs, rhs); \ 1329 } catch(...) { _DOCTEST_RB.m_threw = true; } \ 1330 DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ 1331 } while(doctest::detail::always_false()) 1332 1333 #define DOCTEST_UNARY_ASSERT(assert_type, val) \ 1334 do { \ 1335 doctest::detail::ResultBuilder _DOCTEST_RB(doctest::detail::assertType::assert_type, \ 1336 __FILE__, __LINE__, #val); \ 1337 try { \ 1338 _DOCTEST_RB.unary_assert(val); \ 1339 } catch(...) { _DOCTEST_RB.m_threw = true; } \ 1340 DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ 1341 } while(doctest::detail::always_false()) 1342 1343 #define DOCTEST_WARN_EQ(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_WARN_EQ, lhs, rhs, eq) 1344 #define DOCTEST_CHECK_EQ(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_CHECK_EQ, lhs, rhs, eq) 1345 #define DOCTEST_REQUIRE_EQ(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_REQUIRE_EQ, lhs, rhs, eq) 1346 #define DOCTEST_WARN_NE(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_WARN_NE, lhs, rhs, ne) 1347 #define DOCTEST_CHECK_NE(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_CHECK_NE, lhs, rhs, ne) 1348 #define DOCTEST_REQUIRE_NE(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_REQUIRE_NE, lhs, rhs, ne) 1349 #define DOCTEST_WARN_GT(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_WARN_GT, lhs, rhs, gt) 1350 #define DOCTEST_CHECK_GT(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_CHECK_GT, lhs, rhs, gt) 1351 #define DOCTEST_REQUIRE_GT(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GT, lhs, rhs, gt) 1352 #define DOCTEST_WARN_LT(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_WARN_LT, lhs, rhs, lt) 1353 #define DOCTEST_CHECK_LT(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_CHECK_LT, lhs, rhs, lt) 1354 #define DOCTEST_REQUIRE_LT(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LT, lhs, rhs, lt) 1355 #define DOCTEST_WARN_GE(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_WARN_GE, lhs, rhs, ge) 1356 #define DOCTEST_CHECK_GE(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_CHECK_GE, lhs, rhs, ge) 1357 #define DOCTEST_REQUIRE_GE(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GE, lhs, rhs, ge) 1358 #define DOCTEST_WARN_LE(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_WARN_LE, lhs, rhs, le) 1359 #define DOCTEST_CHECK_LE(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_CHECK_LE, lhs, rhs, le) 1360 #define DOCTEST_REQUIRE_LE(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LE, lhs, rhs, le) 1361 1362 #define DOCTEST_WARN_UNARY(v) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY, v) 1363 #define DOCTEST_CHECK_UNARY(v) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY, v) 1364 #define DOCTEST_REQUIRE_UNARY(v) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY, v) 1365 #define DOCTEST_WARN_UNARY_FALSE(v) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY_FALSE, v) 1366 #define DOCTEST_CHECK_UNARY_FALSE(v) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY_FALSE, v) 1367 #define DOCTEST_REQUIRE_UNARY_FALSE(v) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY_FALSE, v) 1368 1369 #ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS 1370 1371 #define DOCTEST_FAST_BINARY_ASSERT(assert_type, lhs, rhs, comparison) \ 1372 do { \ 1373 int _DOCTEST_FAST_RES = doctest::detail::fast_binary_assert< \ 1374 doctest::detail::binaryAssertComparison::comparison>( \ 1375 doctest::detail::assertType::assert_type, __FILE__, __LINE__, #lhs, #rhs, lhs, \ 1376 rhs); \ 1377 if(_DOCTEST_FAST_RES & doctest::detail::assertAction::dbgbreak) \ 1378 DOCTEST_BREAK_INTO_DEBUGGER(); \ 1379 doctest::detail::fastAssertThrowIfFlagSet(_DOCTEST_FAST_RES); \ 1380 } while(doctest::detail::always_false()) 1381 1382 #define DOCTEST_FAST_UNARY_ASSERT(assert_type, val) \ 1383 do { \ 1384 int _DOCTEST_FAST_RES = doctest::detail::fast_unary_assert( \ 1385 doctest::detail::assertType::assert_type, __FILE__, __LINE__, #val, val); \ 1386 if(_DOCTEST_FAST_RES & doctest::detail::assertAction::dbgbreak) \ 1387 DOCTEST_BREAK_INTO_DEBUGGER(); \ 1388 doctest::detail::fastAssertThrowIfFlagSet(_DOCTEST_FAST_RES); \ 1389 } while(doctest::detail::always_false()) 1390 1391 #else // DOCTEST_CONFIG_SUPER_FAST_ASSERTS 1392 1393 #define DOCTEST_FAST_BINARY_ASSERT(assert_type, lhs, rhs, comparison) \ 1394 doctest::detail::fast_binary_assert<doctest::detail::binaryAssertComparison::comparison>( \ 1395 doctest::detail::assertType::assert_type, __FILE__, __LINE__, #lhs, #rhs, lhs, rhs) 1396 1397 #define DOCTEST_FAST_UNARY_ASSERT(assert_type, val) \ 1398 doctest::detail::fast_unary_assert(doctest::detail::assertType::assert_type, __FILE__, \ 1399 __LINE__, #val, val) 1400 1401 #endif // DOCTEST_CONFIG_SUPER_FAST_ASSERTS 1402 1403 #define DOCTEST_FAST_WARN_EQ(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_WARN_EQ, l, r, eq) 1404 #define DOCTEST_FAST_CHECK_EQ(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_CHECK_EQ, l, r, eq) 1405 #define DOCTEST_FAST_REQUIRE_EQ(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_REQUIRE_EQ, l, r, eq) 1406 #define DOCTEST_FAST_WARN_NE(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_WARN_NE, l, r, ne) 1407 #define DOCTEST_FAST_CHECK_NE(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_CHECK_NE, l, r, ne) 1408 #define DOCTEST_FAST_REQUIRE_NE(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_REQUIRE_NE, l, r, ne) 1409 #define DOCTEST_FAST_WARN_GT(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_WARN_GT, l, r, gt) 1410 #define DOCTEST_FAST_CHECK_GT(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_CHECK_GT, l, r, gt) 1411 #define DOCTEST_FAST_REQUIRE_GT(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_REQUIRE_GT, l, r, gt) 1412 #define DOCTEST_FAST_WARN_LT(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_WARN_LT, l, r, lt) 1413 #define DOCTEST_FAST_CHECK_LT(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_CHECK_LT, l, r, lt) 1414 #define DOCTEST_FAST_REQUIRE_LT(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_REQUIRE_LT, l, r, lt) 1415 #define DOCTEST_FAST_WARN_GE(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_WARN_GE, l, r, ge) 1416 #define DOCTEST_FAST_CHECK_GE(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_CHECK_GE, l, r, ge) 1417 #define DOCTEST_FAST_REQUIRE_GE(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_REQUIRE_GE, l, r, ge) 1418 #define DOCTEST_FAST_WARN_LE(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_WARN_LE, l, r, le) 1419 #define DOCTEST_FAST_CHECK_LE(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_CHECK_LE, l, r, le) 1420 #define DOCTEST_FAST_REQUIRE_LE(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_REQUIRE_LE, l, r, le) 1421 1422 #define DOCTEST_FAST_WARN_UNARY(v) DOCTEST_FAST_UNARY_ASSERT(DT_FAST_WARN_UNARY, v) 1423 #define DOCTEST_FAST_CHECK_UNARY(v) DOCTEST_FAST_UNARY_ASSERT(DT_FAST_CHECK_UNARY, v) 1424 #define DOCTEST_FAST_REQUIRE_UNARY(v) DOCTEST_FAST_UNARY_ASSERT(DT_FAST_REQUIRE_UNARY, v) 1425 #define DOCTEST_FAST_WARN_UNARY_FALSE(v) DOCTEST_FAST_UNARY_ASSERT(DT_FAST_WARN_UNARY_FALSE, v) 1426 #define DOCTEST_FAST_CHECK_UNARY_FALSE(v) DOCTEST_FAST_UNARY_ASSERT(DT_FAST_CHECK_UNARY_FALSE, v) 1427 #define DOCTEST_FAST_REQUIRE_UNARY_FALSE(v) \ 1428 DOCTEST_FAST_UNARY_ASSERT(DT_FAST_REQUIRE_UNARY_FALSE, v) 1429 1430 // ================================================================================================= 1431 // == WHAT FOLLOWS IS VERSIONS OF THE MACROS THAT DO NOT DO ANY REGISTERING! == 1432 // == THIS CAN BE ENABLED BY DEFINING DOCTEST_CONFIG_DISABLE GLOBALLY! == 1433 // ================================================================================================= 1434 #else // DOCTEST_CONFIG_DISABLE 1435 1436 #define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, name) \ 1437 namespace \ 1438 { \ 1439 template <typename T> \ 1440 struct der : base \ 1441 { void f(); }; \ 1442 } \ 1443 template <typename T> \ 1444 inline void der<T>::f() 1445 1446 #define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, name) \ 1447 template <typename T> \ 1448 static inline void f() 1449 1450 // for registering tests 1451 #define DOCTEST_TEST_CASE(name) \ 1452 DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), name) 1453 1454 // for registering tests with a fixture 1455 #define DOCTEST_TEST_CASE_FIXTURE(x, name) \ 1456 DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(_DOCTEST_ANON_CLASS_), x, \ 1457 DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), name) 1458 1459 // for subcases 1460 #define DOCTEST_SUBCASE(name) 1461 1462 // for starting a testsuite block 1463 #define DOCTEST_TEST_SUITE(name) typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) 1464 1465 // for ending a testsuite block 1466 #define DOCTEST_TEST_SUITE_END typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) 1467 1468 #define DOCTEST_WARN(expr) ((void)0) 1469 #define DOCTEST_WARN_FALSE(expr) ((void)0) 1470 #define DOCTEST_WARN_THROWS(expr) ((void)0) 1471 #define DOCTEST_WARN_THROWS_AS(expr, ex) ((void)0) 1472 #define DOCTEST_WARN_NOTHROW(expr) ((void)0) 1473 #define DOCTEST_CHECK(expr) ((void)0) 1474 #define DOCTEST_CHECK_FALSE(expr) ((void)0) 1475 #define DOCTEST_CHECK_THROWS(expr) ((void)0) 1476 #define DOCTEST_CHECK_THROWS_AS(expr, ex) ((void)0) 1477 #define DOCTEST_CHECK_NOTHROW(expr) ((void)0) 1478 #define DOCTEST_REQUIRE(expr) ((void)0) 1479 #define DOCTEST_REQUIRE_FALSE(expr) ((void)0) 1480 #define DOCTEST_REQUIRE_THROWS(expr) ((void)0) 1481 #define DOCTEST_REQUIRE_THROWS_AS(expr, ex) ((void)0) 1482 #define DOCTEST_REQUIRE_NOTHROW(expr) ((void)0) 1483 1484 #define DOCTEST_WARN_EQ(lhs, rhs) ((void)0) 1485 #define DOCTEST_CHECK_EQ(lhs, rhs) ((void)0) 1486 #define DOCTEST_REQUIRE_EQ(lhs, rhs) ((void)0) 1487 #define DOCTEST_WARN_NE(lhs, rhs) ((void)0) 1488 #define DOCTEST_CHECK_NE(lhs, rhs) ((void)0) 1489 #define DOCTEST_REQUIRE_NE(lhs, rhs) ((void)0) 1490 #define DOCTEST_WARN_GT(lhs, rhs) ((void)0) 1491 #define DOCTEST_CHECK_GT(lhs, rhs) ((void)0) 1492 #define DOCTEST_REQUIRE_GT(lhs, rhs) ((void)0) 1493 #define DOCTEST_WARN_LT(lhs, rhs) ((void)0) 1494 #define DOCTEST_CHECK_LT(lhs, rhs) ((void)0) 1495 #define DOCTEST_REQUIRE_LT(lhs, rhs) ((void)0) 1496 #define DOCTEST_WARN_GE(lhs, rhs) ((void)0) 1497 #define DOCTEST_CHECK_GE(lhs, rhs) ((void)0) 1498 #define DOCTEST_REQUIRE_GE(lhs, rhs) ((void)0) 1499 #define DOCTEST_WARN_LE(lhs, rhs) ((void)0) 1500 #define DOCTEST_CHECK_LE(lhs, rhs) ((void)0) 1501 #define DOCTEST_REQUIRE_LE(lhs, rhs) ((void)0) 1502 1503 #define DOCTEST_WARN_UNARY(val) ((void)0) 1504 #define DOCTEST_CHECK_UNARY(val) ((void)0) 1505 #define DOCTEST_REQUIRE_UNARY(val) ((void)0) 1506 #define DOCTEST_WARN_UNARY_FALSE(val) ((void)0) 1507 #define DOCTEST_CHECK_UNARY_FALSE(val) ((void)0) 1508 #define DOCTEST_REQUIRE_UNARY_FALSE(val) ((void)0) 1509 1510 #define DOCTEST_FAST_WARN_EQ(lhs, rhs) ((void)0) 1511 #define DOCTEST_FAST_CHECK_EQ(lhs, rhs) ((void)0) 1512 #define DOCTEST_FAST_REQUIRE_EQ(lhs, rhs) ((void)0) 1513 #define DOCTEST_FAST_WARN_NE(lhs, rhs) ((void)0) 1514 #define DOCTEST_FAST_CHECK_NE(lhs, rhs) ((void)0) 1515 #define DOCTEST_FAST_REQUIRE_NE(lhs, rhs) ((void)0) 1516 #define DOCTEST_FAST_WARN_GT(lhs, rhs) ((void)0) 1517 #define DOCTEST_FAST_CHECK_GT(lhs, rhs) ((void)0) 1518 #define DOCTEST_FAST_REQUIRE_GT(lhs, rhs) ((void)0) 1519 #define DOCTEST_FAST_WARN_LT(lhs, rhs) ((void)0) 1520 #define DOCTEST_FAST_CHECK_LT(lhs, rhs) ((void)0) 1521 #define DOCTEST_FAST_REQUIRE_LT(lhs, rhs) ((void)0) 1522 #define DOCTEST_FAST_WARN_GE(lhs, rhs) ((void)0) 1523 #define DOCTEST_FAST_CHECK_GE(lhs, rhs) ((void)0) 1524 #define DOCTEST_FAST_REQUIRE_GE(lhs, rhs) ((void)0) 1525 #define DOCTEST_FAST_WARN_LE(lhs, rhs) ((void)0) 1526 #define DOCTEST_FAST_CHECK_LE(lhs, rhs) ((void)0) 1527 #define DOCTEST_FAST_REQUIRE_LE(lhs, rhs) ((void)0) 1528 1529 #define DOCTEST_FAST_WARN_UNARY(val) ((void)0) 1530 #define DOCTEST_FAST_CHECK_UNARY(val) ((void)0) 1531 #define DOCTEST_FAST_REQUIRE_UNARY(val) ((void)0) 1532 #define DOCTEST_FAST_WARN_UNARY_FALSE(val) ((void)0) 1533 #define DOCTEST_FAST_CHECK_UNARY_FALSE(val) ((void)0) 1534 #define DOCTEST_FAST_REQUIRE_UNARY_FALSE(val) ((void)0) 1535 1536 #endif // DOCTEST_CONFIG_DISABLE 1537 1538 // BDD style macros 1539 // clang-format off 1540 #define DOCTEST_SCENARIO(name) TEST_CASE(" Scenario: " name) 1541 #define DOCTEST_GIVEN(name) SUBCASE(" Given: " name) 1542 #define DOCTEST_WHEN(name) SUBCASE(" When: " name) 1543 #define DOCTEST_AND_WHEN(name) SUBCASE("And when: " name) 1544 #define DOCTEST_THEN(name) SUBCASE(" Then: " name) 1545 #define DOCTEST_AND_THEN(name) SUBCASE(" And: " name) 1546 // clang-format on 1547 1548 // == SHORT VERSIONS OF THE MACROS 1549 #if !defined(DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES) 1550 1551 #define TEST_CASE DOCTEST_TEST_CASE 1552 #define TEST_CASE_FIXTURE DOCTEST_TEST_CASE_FIXTURE 1553 #define SUBCASE DOCTEST_SUBCASE 1554 #define TEST_SUITE DOCTEST_TEST_SUITE 1555 #define TEST_SUITE_END DOCTEST_TEST_SUITE_END 1556 #define WARN DOCTEST_WARN 1557 #define WARN_FALSE DOCTEST_WARN_FALSE 1558 #define WARN_THROWS DOCTEST_WARN_THROWS 1559 #define WARN_THROWS_AS DOCTEST_WARN_THROWS_AS 1560 #define WARN_NOTHROW DOCTEST_WARN_NOTHROW 1561 #define CHECK DOCTEST_CHECK 1562 #define CHECK_FALSE DOCTEST_CHECK_FALSE 1563 #define CHECK_THROWS DOCTEST_CHECK_THROWS 1564 #define CHECK_THROWS_AS DOCTEST_CHECK_THROWS_AS 1565 #define CHECK_NOTHROW DOCTEST_CHECK_NOTHROW 1566 #define REQUIRE DOCTEST_REQUIRE 1567 #define REQUIRE_FALSE DOCTEST_REQUIRE_FALSE 1568 #define REQUIRE_THROWS DOCTEST_REQUIRE_THROWS 1569 #define REQUIRE_THROWS_AS DOCTEST_REQUIRE_THROWS_AS 1570 #define REQUIRE_NOTHROW DOCTEST_REQUIRE_NOTHROW 1571 1572 #define SCENARIO DOCTEST_SCENARIO 1573 #define GIVEN DOCTEST_GIVEN 1574 #define WHEN DOCTEST_WHEN 1575 #define AND_WHEN DOCTEST_AND_WHEN 1576 #define THEN DOCTEST_THEN 1577 #define AND_THEN DOCTEST_AND_THEN 1578 1579 #define WARN_EQ DOCTEST_WARN_EQ 1580 #define CHECK_EQ DOCTEST_CHECK_EQ 1581 #define REQUIRE_EQ DOCTEST_REQUIRE_EQ 1582 #define WARN_NE DOCTEST_WARN_NE 1583 #define CHECK_NE DOCTEST_CHECK_NE 1584 #define REQUIRE_NE DOCTEST_REQUIRE_NE 1585 #define WARN_GT DOCTEST_WARN_GT 1586 #define CHECK_GT DOCTEST_CHECK_GT 1587 #define REQUIRE_GT DOCTEST_REQUIRE_GT 1588 #define WARN_LT DOCTEST_WARN_LT 1589 #define CHECK_LT DOCTEST_CHECK_LT 1590 #define REQUIRE_LT DOCTEST_REQUIRE_LT 1591 #define WARN_GE DOCTEST_WARN_GE 1592 #define CHECK_GE DOCTEST_CHECK_GE 1593 #define REQUIRE_GE DOCTEST_REQUIRE_GE 1594 #define WARN_LE DOCTEST_WARN_LE 1595 #define CHECK_LE DOCTEST_CHECK_LE 1596 #define REQUIRE_LE DOCTEST_REQUIRE_LE 1597 #define WARN_UNARY DOCTEST_WARN_UNARY 1598 #define CHECK_UNARY DOCTEST_CHECK_UNARY 1599 #define REQUIRE_UNARY DOCTEST_REQUIRE_UNARY 1600 #define WARN_UNARY_FALSE DOCTEST_WARN_UNARY_FALSE 1601 #define CHECK_UNARY_FALSE DOCTEST_CHECK_UNARY_FALSE 1602 #define REQUIRE_UNARY_FALSE DOCTEST_REQUIRE_UNARY_FALSE 1603 1604 #define FAST_WARN_EQ DOCTEST_FAST_WARN_EQ 1605 #define FAST_CHECK_EQ DOCTEST_FAST_CHECK_EQ 1606 #define FAST_REQUIRE_EQ DOCTEST_FAST_REQUIRE_EQ 1607 #define FAST_WARN_NE DOCTEST_FAST_WARN_NE 1608 #define FAST_CHECK_NE DOCTEST_FAST_CHECK_NE 1609 #define FAST_REQUIRE_NE DOCTEST_FAST_REQUIRE_NE 1610 #define FAST_WARN_GT DOCTEST_FAST_WARN_GT 1611 #define FAST_CHECK_GT DOCTEST_FAST_CHECK_GT 1612 #define FAST_REQUIRE_GT DOCTEST_FAST_REQUIRE_GT 1613 #define FAST_WARN_LT DOCTEST_FAST_WARN_LT 1614 #define FAST_CHECK_LT DOCTEST_FAST_CHECK_LT 1615 #define FAST_REQUIRE_LT DOCTEST_FAST_REQUIRE_LT 1616 #define FAST_WARN_GE DOCTEST_FAST_WARN_GE 1617 #define FAST_CHECK_GE DOCTEST_FAST_CHECK_GE 1618 #define FAST_REQUIRE_GE DOCTEST_FAST_REQUIRE_GE 1619 #define FAST_WARN_LE DOCTEST_FAST_WARN_LE 1620 #define FAST_CHECK_LE DOCTEST_FAST_CHECK_LE 1621 #define FAST_REQUIRE_LE DOCTEST_FAST_REQUIRE_LE 1622 #define FAST_WARN_UNARY DOCTEST_FAST_WARN_UNARY 1623 #define FAST_CHECK_UNARY DOCTEST_FAST_CHECK_UNARY 1624 #define FAST_REQUIRE_UNARY DOCTEST_FAST_REQUIRE_UNARY 1625 #define FAST_WARN_UNARY_FALSE DOCTEST_FAST_WARN_UNARY_FALSE 1626 #define FAST_CHECK_UNARY_FALSE DOCTEST_FAST_CHECK_UNARY_FALSE 1627 #define FAST_REQUIRE_UNARY_FALSE DOCTEST_FAST_REQUIRE_UNARY_FALSE 1628 1629 #endif // DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES 1630 1631 // this is here to clear the 'current test suite' for the current translation unit - at the top 1632 DOCTEST_TEST_SUITE_END(); 1633 1634 #endif // DOCTEST_LIBRARY_INCLUDED 1635 1636 #if defined(__clang__) 1637 #pragma clang diagnostic pop 1638 #endif // __clang__ 1639 1640 #if defined(__GNUC__) && !defined(__clang__) 1641 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6) 1642 #pragma GCC diagnostic pop 1643 #endif // > gcc 4.6 1644 #endif // __GNUC__ 1645 1646 #ifdef _MSC_VER 1647 #pragma warning(pop) 1648 #endif // _MSC_VER 1649 1650 #ifndef DOCTEST_SINGLE_HEADER 1651 #define DOCTEST_SINGLE_HEADER 1652 #endif // DOCTEST_SINGLE_HEADER 1653 1654 #if defined(__clang__) 1655 #pragma clang diagnostic push 1656 #pragma clang diagnostic ignored "-Wunknown-pragmas" 1657 #pragma clang diagnostic ignored "-Wpadded" 1658 #pragma clang diagnostic ignored "-Wglobal-constructors" 1659 #pragma clang diagnostic ignored "-Wexit-time-destructors" 1660 #pragma clang diagnostic ignored "-Wmissing-prototypes" 1661 #pragma clang diagnostic ignored "-Wsign-conversion" 1662 #pragma clang diagnostic ignored "-Wshorten-64-to-32" 1663 #pragma clang diagnostic ignored "-Wmissing-variable-declarations" 1664 #pragma clang diagnostic ignored "-Wswitch" 1665 #pragma clang diagnostic ignored "-Wswitch-enum" 1666 #pragma clang diagnostic ignored "-Wcovered-switch-default" 1667 #pragma clang diagnostic ignored "-Wmissing-noreturn" 1668 #pragma clang diagnostic ignored "-Wunused-local-typedef" 1669 #endif // __clang__ 1670 1671 #if defined(__GNUC__) && !defined(__clang__) 1672 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6) 1673 #pragma GCC diagnostic push 1674 #endif // > gcc 4.6 1675 #pragma GCC diagnostic ignored "-Wunknown-pragmas" 1676 #pragma GCC diagnostic ignored "-Wconversion" 1677 #pragma GCC diagnostic ignored "-Weffc++" 1678 #pragma GCC diagnostic ignored "-Wsign-conversion" 1679 #pragma GCC diagnostic ignored "-Wstrict-overflow" 1680 #pragma GCC diagnostic ignored "-Wmissing-declarations" 1681 #pragma GCC diagnostic ignored "-Winline" 1682 #pragma GCC diagnostic ignored "-Wswitch" 1683 #pragma GCC diagnostic ignored "-Wswitch-enum" 1684 #pragma GCC diagnostic ignored "-Wswitch-default" 1685 #pragma GCC diagnostic ignored "-Wunsafe-loop-optimizations" 1686 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6) 1687 #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" 1688 #endif // > gcc 4.6 1689 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 7) 1690 #pragma GCC diagnostic ignored "-Wunused-local-typedefs" 1691 #endif // > gcc 4.7 1692 #if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ > 3) 1693 #pragma GCC diagnostic ignored "-Wuseless-cast" 1694 #endif // > gcc 5.3 1695 #endif // __GNUC__ 1696 1697 #ifdef _MSC_VER 1698 #pragma warning(push) 1699 #pragma warning(disable : 4996) // The compiler encountered a deprecated declaration 1700 #pragma warning(disable : 4267) // 'var' : conversion from 'size_t' to 'type', possible loss of data 1701 #pragma warning(disable : 4706) // assignment within conditional expression 1702 #pragma warning(disable : 4512) // 'class' : assignment operator could not be generated 1703 #pragma warning(disable : 4127) // conditional expression is constant 1704 #endif // _MSC_VER 1705 1706 #if defined(DOCTEST_CONFIG_IMPLEMENT) || defined(DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN) || \ 1707 !defined(DOCTEST_SINGLE_HEADER) 1708 #ifndef DOCTEST_LIBRARY_IMPLEMENTATION 1709 #define DOCTEST_LIBRARY_IMPLEMENTATION 1710 1711 #ifndef DOCTEST_SINGLE_HEADER 1712 #include "doctest_fwd.h" 1713 #endif // DOCTEST_SINGLE_HEADER 1714 1715 #if defined(__clang__) && defined(DOCTEST_NO_CPP11_COMPAT) 1716 #pragma clang diagnostic ignored "-Wc++98-compat" 1717 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic" 1718 #endif // __clang__ && DOCTEST_NO_CPP11_COMPAT 1719 1720 // snprintf() not in the C++98 standard 1721 #ifdef _MSC_VER 1722 #define DOCTEST_SNPRINTF _snprintf 1723 #else 1724 #define DOCTEST_SNPRINTF snprintf 1725 #endif 1726 1727 #define DOCTEST_LOG_START() \ 1728 do { \ 1729 if(!DOCTEST_GCS().hasLoggedCurrentTestStart) { \ 1730 doctest::detail::logTestStart(DOCTEST_GCS().currentTest->m_name, \ 1731 DOCTEST_GCS().currentTest->m_file, \ 1732 DOCTEST_GCS().currentTest->m_line); \ 1733 DOCTEST_GCS().hasLoggedCurrentTestStart = true; \ 1734 } \ 1735 } while(doctest::detail::always_false()) 1736 1737 // required includes - will go only in one translation unit! 1738 #include <ctime> 1739 #include <cmath> 1740 // borland (Embarcadero) compiler requires math.h and not cmath - https://github.com/onqtam/doctest/pull/37 1741 #ifdef __BORLANDC__ 1742 #include <math.h> 1743 #endif // __BORLANDC__ 1744 #include <new> 1745 #include <cstdio> 1746 #include <cstdlib> 1747 #include <cstring> 1748 #include <limits> 1749 #include <utility> 1750 #include <sstream> 1751 #include <iomanip> 1752 #include <vector> 1753 #include <set> 1754 1755 namespace doctest 1756 { 1757 namespace detail 1758 { 1759 // not using std::strlen() because of valgrind errors when optimizations are turned on 1760 // 'Invalid read of size 4' when the test suite len (with '\0') is not a multiple of 4 1761 // for details see http://stackoverflow.com/questions/35671155 1762 size_t my_strlen(const char* in) { 1763 const char* temp = in; 1764 while(temp && *temp) 1765 ++temp; 1766 return temp - in; 1767 } 1768 1769 template <typename T> 1770 T my_max(const T& lhs, const T& rhs) { 1771 return lhs > rhs ? lhs : rhs; 1772 } 1773 1774 // case insensitive strcmp 1775 int stricmp(char const* a, char const* b) { 1776 for(;; a++, b++) { 1777 int d = tolower(*a) - tolower(*b); 1778 if(d != 0 || !*a) 1779 return d; 1780 } 1781 } 1782 1783 template <typename T> 1784 String fpToString(T value, int precision) { 1785 std::ostringstream oss; 1786 oss << std::setprecision(precision) << std::fixed << value; 1787 std::string d = oss.str(); 1788 size_t i = d.find_last_not_of('0'); 1789 if(i != std::string::npos && i != d.size() - 1) { 1790 if(d[i] == '.') 1791 i++; 1792 d = d.substr(0, i + 1); 1793 } 1794 return d.c_str(); 1795 } 1796 1797 struct Endianness 1798 { 1799 enum Arch 1800 { 1801 Big, 1802 Little 1803 }; 1804 1805 static Arch which() { 1806 union _ 1807 { 1808 int asInt; 1809 char asChar[sizeof(int)]; 1810 } u; 1811 1812 u.asInt = 1; 1813 return (u.asChar[sizeof(int) - 1] == 1) ? Big : Little; 1814 } 1815 }; 1816 1817 String rawMemoryToString(const void* object, unsigned size) { 1818 // Reverse order for little endian architectures 1819 int i = 0, end = static_cast<int>(size), inc = 1; 1820 if(Endianness::which() == Endianness::Little) { 1821 i = end - 1; 1822 end = inc = -1; 1823 } 1824 1825 unsigned char const* bytes = static_cast<unsigned char const*>(object); 1826 std::ostringstream os; 1827 os << "0x" << std::setfill('0') << std::hex; 1828 for(; i != end; i += inc) 1829 os << std::setw(2) << static_cast<unsigned>(bytes[i]); 1830 return os.str().c_str(); 1831 } 1832 1833 std::ostream* createStream() { return new std::ostringstream(); } 1834 String getStreamResult(std::ostream* in) { 1835 return static_cast<std::ostringstream*>(in)->str().c_str(); 1836 } 1837 void freeStream(std::ostream* in) { delete in; } 1838 1839 #ifndef DOCTEST_CONFIG_DISABLE 1840 1841 // this holds both parameters for the command line and runtime data for tests 1842 struct ContextState : TestAccessibleContextState 1843 { 1844 // == parameters from the command line 1845 1846 std::vector<std::vector<String> > filters; 1847 1848 String order_by; // how tests should be ordered 1849 unsigned rand_seed; // the seed for rand ordering 1850 1851 unsigned first; // the first (matching) test to be executed 1852 unsigned last; // the last (matching) test to be executed 1853 1854 int abort_after; // stop tests after this many failed assertions 1855 bool case_sensitive; // if filtering should be case sensitive 1856 bool exit; // if the program should be exited after the tests are ran/whatever 1857 bool no_exitcode; // if the framework should return 0 as the exitcode 1858 bool no_run; // to not run the tests at all (can be done with an "*" exclude) 1859 bool no_colors; // if output to the console should be colorized 1860 bool no_path_in_filenames; // if the path to files should be removed from the output 1861 1862 bool help; // to print the help 1863 bool version; // to print the version 1864 bool count; // if only the count of matching tests is to be retreived 1865 bool list_test_cases; // to list all tests matching the filters 1866 bool list_test_suites; // to list all suites matching the filters 1867 1868 // == data for the tests being ran 1869 1870 int numAssertions; 1871 int numFailedAssertions; 1872 int numFailedAssertionsForCurrentTestcase; 1873 1874 // stuff for subcases 1875 std::set<SubcaseSignature> subcasesPassed; 1876 std::set<int> subcasesEnteredLevels; 1877 std::vector<Subcase> subcasesStack; 1878 int subcasesCurrentLevel; 1879 bool subcasesHasSkipped; 1880 1881 void resetRunData() { 1882 numAssertions = 0; 1883 numFailedAssertions = 0; 1884 } 1885 1886 ContextState() 1887 : filters(6) // 6 different filters total 1888 { 1889 resetRunData(); 1890 } 1891 }; 1892 1893 ContextState*& getContextState(); 1894 #endif // DOCTEST_CONFIG_DISABLE 1895 } // namespace detail 1896 1897 String::String(const char* in) 1898 : m_str(static_cast<char*>(malloc(detail::my_strlen(in) + 1))) { 1899 if(in) 1900 strcpy(m_str, in); 1901 else 1902 m_str[0] = '\0'; 1903 } 1904 1905 String::String(const String& other) 1906 : m_str(0) { 1907 copy(other); 1908 } 1909 1910 void String::copy(const String& other) { 1911 if(m_str) 1912 free(m_str); 1913 m_str = static_cast<char*>(malloc(detail::my_strlen(other.m_str) + 1)); 1914 strcpy(m_str, other.m_str); 1915 } 1916 1917 String::~String() { free(m_str); } 1918 1919 String& String::operator=(const String& other) { 1920 if(this != &other) 1921 copy(other); 1922 return *this; 1923 } 1924 1925 String String::operator+(const String& other) const { return String(m_str) += other; } 1926 1927 String& String::operator+=(const String& other) { 1928 using namespace detail; 1929 if(other.m_str != 0) { 1930 char* newStr = static_cast<char*>(malloc(my_strlen(m_str) + my_strlen(other.m_str) + 1)); 1931 strcpy(newStr, m_str); 1932 strcpy(newStr + my_strlen(m_str), other.m_str); 1933 free(m_str); 1934 m_str = newStr; 1935 } 1936 return *this; 1937 } 1938 1939 unsigned String::size() const { return m_str ? detail::my_strlen(m_str) : 0; } 1940 unsigned String::length() const { return size(); } 1941 1942 int String::compare(const char* other, bool no_case) const { 1943 if(no_case) 1944 return detail::stricmp(m_str, other); 1945 return strcmp(m_str, other); 1946 } 1947 1948 int String::compare(const String& other, bool no_case) const { 1949 if(no_case) 1950 return detail::stricmp(m_str, other.m_str); 1951 return strcmp(m_str, other.m_str); 1952 } 1953 1954 std::ostream& operator<<(std::ostream& stream, const String& in) { 1955 stream << in.c_str(); 1956 return stream; 1957 } 1958 1959 Approx::Approx(double value) 1960 : m_epsilon(static_cast<double>(std::numeric_limits<float>::epsilon()) * 100) 1961 , m_scale(1.0) 1962 , m_value(value) {} 1963 1964 bool operator==(double lhs, Approx const& rhs) { 1965 // Thanks to Richard Harris for his help refining this formula 1966 return fabs(lhs - rhs.m_value) < 1967 rhs.m_epsilon * (rhs.m_scale + detail::my_max(fabs(lhs), fabs(rhs.m_value))); 1968 } 1969 1970 String Approx::toString() const { return String("Approx( ") + doctest::toString(m_value) + " )"; } 1971 1972 #ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING 1973 String toString(char* in) { return toString(static_cast<const char*>(in)); } 1974 String toString(const char* in) { return String("\"") + (in ? in : "{null string}") + "\""; } 1975 #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING 1976 String toString(bool in) { return in ? "true" : "false"; } 1977 String toString(float in) { return detail::fpToString(in, 5) + "f"; } 1978 String toString(double in) { return detail::fpToString(in, 10); } 1979 String toString(double long in) { return detail::fpToString(in, 15); } 1980 1981 String toString(char in) { 1982 char buf[64]; 1983 sprintf(buf, "%d", in); 1984 return buf; 1985 } 1986 1987 String toString(char unsigned in) { 1988 char buf[64]; 1989 sprintf(buf, "%ud", in); 1990 return buf; 1991 } 1992 1993 String toString(int short in) { 1994 char buf[64]; 1995 sprintf(buf, "%d", in); 1996 return buf; 1997 } 1998 1999 String toString(int short unsigned in) { 2000 char buf[64]; 2001 sprintf(buf, "%u", in); 2002 return buf; 2003 } 2004 2005 String toString(int in) { 2006 char buf[64]; 2007 sprintf(buf, "%d", in); 2008 return buf; 2009 } 2010 2011 String toString(int unsigned in) { 2012 char buf[64]; 2013 sprintf(buf, "%u", in); 2014 return buf; 2015 } 2016 2017 String toString(int long in) { 2018 char buf[64]; 2019 sprintf(buf, "%ld", in); 2020 return buf; 2021 } 2022 2023 String toString(int long unsigned in) { 2024 char buf[64]; 2025 sprintf(buf, "%lu", in); 2026 return buf; 2027 } 2028 2029 #ifdef DOCTEST_CONFIG_WITH_LONG_LONG 2030 String toString(int long long in) { 2031 char buf[64]; 2032 sprintf(buf, "%lld", in); 2033 return buf; 2034 } 2035 String toString(int long long unsigned in) { 2036 char buf[64]; 2037 sprintf(buf, "%llu", in); 2038 return buf; 2039 } 2040 #endif // DOCTEST_CONFIG_WITH_LONG_LONG 2041 2042 #ifdef DOCTEST_CONFIG_WITH_NULLPTR 2043 String toString(std::nullptr_t) { return "nullptr"; } 2044 #endif // DOCTEST_CONFIG_WITH_NULLPTR 2045 2046 } // namespace doctest 2047 2048 #if defined(DOCTEST_CONFIG_DISABLE) 2049 namespace doctest 2050 { 2051 Context::Context(int, const char* const*) {} 2052 Context::~Context() {} 2053 void Context::applyCommandLine(int, const char* const*) {} 2054 void Context::addFilter(const char*, const char*) {} 2055 void Context::clearFilters() {} 2056 void Context::setOption(const char*, int) {} 2057 void Context::setOption(const char*, const char*) {} 2058 bool Context::shouldExit() { return false; } 2059 int Context::run() { return 0; } 2060 } // namespace doctest 2061 #else // DOCTEST_CONFIG_DISABLE 2062 2063 #if !defined(DOCTEST_CONFIG_COLORS_NONE) 2064 #if !defined(DOCTEST_CONFIG_COLORS_WINDOWS) && !defined(DOCTEST_CONFIG_COLORS_ANSI) 2065 #ifdef DOCTEST_PLATFORM_WINDOWS 2066 #define DOCTEST_CONFIG_COLORS_WINDOWS 2067 #else // linux 2068 #define DOCTEST_CONFIG_COLORS_ANSI 2069 #endif // platform 2070 #endif // DOCTEST_CONFIG_COLORS_WINDOWS && DOCTEST_CONFIG_COLORS_ANSI 2071 #endif // DOCTEST_CONFIG_COLORS_NONE 2072 2073 #define DOCTEST_PRINTF_COLORED(buffer, color) \ 2074 do { \ 2075 if(buffer[0] != 0) { \ 2076 doctest::detail::Color col(color); \ 2077 printf("%s", buffer); \ 2078 } \ 2079 } while(doctest::detail::always_false()) 2080 2081 // the buffer size used for snprintf() calls 2082 #if !defined(DOCTEST_SNPRINTF_BUFFER_LENGTH) 2083 #define DOCTEST_SNPRINTF_BUFFER_LENGTH 1024 2084 #endif // DOCTEST_SNPRINTF_BUFFER_LENGTH 2085 2086 #if defined(_MSC_VER) || defined(__MINGW32__) 2087 #if defined(_MSC_VER) && _MSC_VER >= 1700 2088 #define DOCTEST_WINDOWS_SAL_IN_OPT _In_opt_ 2089 #else // _MSC_VER 2090 #define DOCTEST_WINDOWS_SAL_IN_OPT 2091 #endif // _MSC_VER 2092 extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( 2093 DOCTEST_WINDOWS_SAL_IN_OPT const char*); 2094 extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); 2095 #endif // _MSC_VER || __MINGW32__ 2096 2097 #ifdef DOCTEST_CONFIG_COLORS_ANSI 2098 #include <unistd.h> 2099 #endif // DOCTEST_CONFIG_COLORS_ANSI 2100 2101 #ifdef DOCTEST_CONFIG_COLORS_WINDOWS 2102 2103 // defines for a leaner windows.h 2104 #ifndef WIN32_MEAN_AND_LEAN 2105 #define WIN32_MEAN_AND_LEAN 2106 #endif // WIN32_MEAN_AND_LEAN 2107 #ifndef VC_EXTRA_LEAN 2108 #define VC_EXTRA_LEAN 2109 #endif // VC_EXTRA_LEAN 2110 #ifndef NOMINMAX 2111 #define NOMINMAX 2112 #endif // NOMINMAX 2113 2114 // not sure what AfxWin.h is for - here I do what Catch does 2115 #ifdef __AFXDLL 2116 #include <AfxWin.h> 2117 #else 2118 #include <windows.h> 2119 #endif 2120 2121 #endif // DOCTEST_CONFIG_COLORS_WINDOWS 2122 2123 namespace doctest 2124 { 2125 namespace detail 2126 { 2127 bool TestData::operator<(const TestData& other) const { 2128 if(m_line != other.m_line) 2129 return m_line < other.m_line; 2130 return strcmp(m_file, other.m_file) < 0; 2131 } 2132 2133 const char* getAssertString(assertType::Enum val) { 2134 switch(val) { 2135 // clang-format off 2136 case assertType::DT_WARN : return "WARN"; 2137 case assertType::DT_CHECK : return "CHECK"; 2138 case assertType::DT_REQUIRE : return "REQUIRE"; 2139 2140 case assertType::DT_WARN_FALSE : return "WARN_FALSE"; 2141 case assertType::DT_CHECK_FALSE : return "CHECK_FALSE"; 2142 case assertType::DT_REQUIRE_FALSE : return "REQUIRE_FALSE"; 2143 2144 case assertType::DT_WARN_THROWS : return "WARN_THROWS"; 2145 case assertType::DT_CHECK_THROWS : return "CHECK_THROWS"; 2146 case assertType::DT_REQUIRE_THROWS : return "REQUIRE_THROWS"; 2147 2148 case assertType::DT_WARN_THROWS_AS : return "WARN_THROWS_AS"; 2149 case assertType::DT_CHECK_THROWS_AS : return "CHECK_THROWS_AS"; 2150 case assertType::DT_REQUIRE_THROWS_AS : return "REQUIRE_THROWS_AS"; 2151 2152 case assertType::DT_WARN_NOTHROW : return "WARN_NOTHROW"; 2153 case assertType::DT_CHECK_NOTHROW : return "CHECK_NOTHROW"; 2154 case assertType::DT_REQUIRE_NOTHROW : return "REQUIRE_NOTHROW"; 2155 2156 case assertType::DT_WARN_EQ : return "WARN_EQ"; 2157 case assertType::DT_CHECK_EQ : return "CHECK_EQ"; 2158 case assertType::DT_REQUIRE_EQ : return "REQUIRE_EQ"; 2159 case assertType::DT_WARN_NE : return "WARN_NE"; 2160 case assertType::DT_CHECK_NE : return "CHECK_NE"; 2161 case assertType::DT_REQUIRE_NE : return "REQUIRE_NE"; 2162 case assertType::DT_WARN_GT : return "WARN_GT"; 2163 case assertType::DT_CHECK_GT : return "CHECK_GT"; 2164 case assertType::DT_REQUIRE_GT : return "REQUIRE_GT"; 2165 case assertType::DT_WARN_LT : return "WARN_LT"; 2166 case assertType::DT_CHECK_LT : return "CHECK_LT"; 2167 case assertType::DT_REQUIRE_LT : return "REQUIRE_LT"; 2168 case assertType::DT_WARN_GE : return "WARN_GE"; 2169 case assertType::DT_CHECK_GE : return "CHECK_GE"; 2170 case assertType::DT_REQUIRE_GE : return "REQUIRE_GE"; 2171 case assertType::DT_WARN_LE : return "WARN_LE"; 2172 case assertType::DT_CHECK_LE : return "CHECK_LE"; 2173 case assertType::DT_REQUIRE_LE : return "REQUIRE_LE"; 2174 2175 case assertType::DT_WARN_UNARY : return "WARN_UNARY"; 2176 case assertType::DT_CHECK_UNARY : return "CHECK_UNARY"; 2177 case assertType::DT_REQUIRE_UNARY : return "REQUIRE_UNARY"; 2178 case assertType::DT_WARN_UNARY_FALSE : return "WARN_UNARY_FALSE"; 2179 case assertType::DT_CHECK_UNARY_FALSE : return "CHECK_UNARY_FALSE"; 2180 case assertType::DT_REQUIRE_UNARY_FALSE : return "REQUIRE_UNARY_FALSE"; 2181 2182 case assertType::DT_FAST_WARN_EQ : return "FAST_WARN_EQ"; 2183 case assertType::DT_FAST_CHECK_EQ : return "FAST_CHECK_EQ"; 2184 case assertType::DT_FAST_REQUIRE_EQ : return "FAST_REQUIRE_EQ"; 2185 case assertType::DT_FAST_WARN_NE : return "FAST_WARN_NE"; 2186 case assertType::DT_FAST_CHECK_NE : return "FAST_CHECK_NE"; 2187 case assertType::DT_FAST_REQUIRE_NE : return "FAST_REQUIRE_NE"; 2188 case assertType::DT_FAST_WARN_GT : return "FAST_WARN_GT"; 2189 case assertType::DT_FAST_CHECK_GT : return "FAST_CHECK_GT"; 2190 case assertType::DT_FAST_REQUIRE_GT : return "FAST_REQUIRE_GT"; 2191 case assertType::DT_FAST_WARN_LT : return "FAST_WARN_LT"; 2192 case assertType::DT_FAST_CHECK_LT : return "FAST_CHECK_LT"; 2193 case assertType::DT_FAST_REQUIRE_LT : return "FAST_REQUIRE_LT"; 2194 case assertType::DT_FAST_WARN_GE : return "FAST_WARN_GE"; 2195 case assertType::DT_FAST_CHECK_GE : return "FAST_CHECK_GE"; 2196 case assertType::DT_FAST_REQUIRE_GE : return "FAST_REQUIRE_GE"; 2197 case assertType::DT_FAST_WARN_LE : return "FAST_WARN_LE"; 2198 case assertType::DT_FAST_CHECK_LE : return "FAST_CHECK_LE"; 2199 case assertType::DT_FAST_REQUIRE_LE : return "FAST_REQUIRE_LE"; 2200 2201 case assertType::DT_FAST_WARN_UNARY : return "FAST_WARN_UNARY"; 2202 case assertType::DT_FAST_CHECK_UNARY : return "FAST_CHECK_UNARY"; 2203 case assertType::DT_FAST_REQUIRE_UNARY : return "FAST_REQUIRE_UNARY"; 2204 case assertType::DT_FAST_WARN_UNARY_FALSE : return "FAST_WARN_UNARY_FALSE"; 2205 case assertType::DT_FAST_CHECK_UNARY_FALSE : return "FAST_CHECK_UNARY_FALSE"; 2206 case assertType::DT_FAST_REQUIRE_UNARY_FALSE: return "FAST_REQUIRE_UNARY_FALSE"; 2207 // clang-format on 2208 } 2209 return ""; 2210 } 2211 2212 bool checkIfShouldThrow(assertType::Enum assert_type) { 2213 if(assert_type & assertType::is_require) 2214 return true; 2215 2216 if((assert_type & assertType::is_check) && getContextState()->abort_after > 0) { 2217 if(getContextState()->numFailedAssertions >= getContextState()->abort_after) 2218 return true; 2219 } 2220 2221 return false; 2222 } 2223 void fastAssertThrowIfFlagSet(int flags) { 2224 if(flags & assertAction::shouldthrow) 2225 throwException(); 2226 } 2227 void throwException() { throw TestFailureException(); } 2228 bool always_false() { return false; } 2229 2230 // lowers ascii letters 2231 char tolower(const char c) { return ((c >= 'A' && c <= 'Z') ? static_cast<char>(c + 32) : c); } 2232 2233 // matching of a string against a wildcard mask (case sensitivity configurable) taken from 2234 // http://www.emoticode.net/c/simple-wildcard-string-compare-globbing-function.html 2235 int wildcmp(const char* str, const char* wild, bool caseSensitive) { 2236 const char* cp = 0; 2237 const char* mp = 0; 2238 2239 // rolled my own tolower() to not include more headers 2240 while((*str) && (*wild != '*')) { 2241 if((caseSensitive ? (*wild != *str) : (tolower(*wild) != tolower(*str))) && 2242 (*wild != '?')) { 2243 return 0; 2244 } 2245 wild++; 2246 str++; 2247 } 2248 2249 while(*str) { 2250 if(*wild == '*') { 2251 if(!*++wild) { 2252 return 1; 2253 } 2254 mp = wild; 2255 cp = str + 1; 2256 } else if((caseSensitive ? (*wild == *str) : (tolower(*wild) == tolower(*str))) || 2257 (*wild == '?')) { 2258 wild++; 2259 str++; 2260 } else { 2261 wild = mp; 2262 str = cp++; 2263 } 2264 } 2265 2266 while(*wild == '*') { 2267 wild++; 2268 } 2269 return !*wild; 2270 } 2271 2272 //// C string hash function (djb2) - taken from http://www.cse.yorku.ca/~oz/hash.html 2273 //unsigned hashStr(unsigned const char* str) { 2274 // unsigned long hash = 5381; 2275 // char c; 2276 // while((c = *str++)) 2277 // hash = ((hash << 5) + hash) + c; // hash * 33 + c 2278 // return hash; 2279 //} 2280 2281 // checks if the name matches any of the filters (and can be configured what to do when empty) 2282 int matchesAny(const char* name, std::vector<String> filters, int matchEmpty, 2283 bool caseSensitive) { 2284 if(filters.size() == 0 && matchEmpty) 2285 return 1; 2286 for(unsigned i = 0; i < filters.size(); ++i) 2287 if(wildcmp(name, filters[i].c_str(), caseSensitive)) 2288 return 1; 2289 return 0; 2290 } 2291 2292 // the current ContextState with which tests are being executed 2293 ContextState*& getContextState() { 2294 static ContextState* data = 0; 2295 return data; 2296 } 2297 2298 TestAccessibleContextState* getTestsContextState() { return getContextState(); } 2299 2300 bool SubcaseSignature::operator<(const SubcaseSignature& other) const { 2301 if(m_line != other.m_line) 2302 return m_line < other.m_line; 2303 if(strcmp(m_file, other.m_file) != 0) 2304 return strcmp(m_file, other.m_file) < 0; 2305 return strcmp(m_name, other.m_name) < 0; 2306 } 2307 2308 Subcase::Subcase(const char* name, const char* file, int line) 2309 : m_signature(name, file, line) 2310 , m_entered(false) { 2311 ContextState* s = getContextState(); 2312 2313 // if we have already completed it 2314 if(s->subcasesPassed.count(m_signature) != 0) 2315 return; 2316 2317 // if a Subcase on the same level has already been entered 2318 if(s->subcasesEnteredLevels.count(s->subcasesCurrentLevel) != 0) { 2319 s->subcasesHasSkipped = true; 2320 return; 2321 } 2322 2323 s->subcasesStack.push_back(*this); 2324 if(s->hasLoggedCurrentTestStart) 2325 logTestEnd(); 2326 s->hasLoggedCurrentTestStart = false; 2327 2328 s->subcasesEnteredLevels.insert(s->subcasesCurrentLevel++); 2329 m_entered = true; 2330 } 2331 2332 Subcase::Subcase(const Subcase& other) 2333 : m_signature(other.m_signature.m_name, other.m_signature.m_file, 2334 other.m_signature.m_line) 2335 , m_entered(other.m_entered) {} 2336 2337 Subcase::~Subcase() { 2338 if(m_entered) { 2339 ContextState* s = getContextState(); 2340 2341 s->subcasesCurrentLevel--; 2342 // only mark the subcase as passed if no subcases have been skipped 2343 if(s->subcasesHasSkipped == false) 2344 s->subcasesPassed.insert(m_signature); 2345 2346 if(s->subcasesStack.size() > 0) 2347 s->subcasesStack.pop_back(); 2348 if(s->hasLoggedCurrentTestStart) 2349 logTestEnd(); 2350 s->hasLoggedCurrentTestStart = false; 2351 } 2352 } 2353 2354 // for sorting tests by file/line 2355 int fileOrderComparator(const void* a, const void* b) { 2356 const TestData* lhs = *static_cast<TestData* const*>(a); 2357 const TestData* rhs = *static_cast<TestData* const*>(b); 2358 #ifdef _MSC_VER 2359 // this is needed because MSVC gives different case for drive letters 2360 // for __FILE__ when evaluated in a header and a source file 2361 int res = stricmp(lhs->m_file, rhs->m_file); 2362 #else // _MSC_VER 2363 int res = strcmp(lhs->m_file, rhs->m_file); 2364 #endif // _MSC_VER 2365 if(res != 0) 2366 return res; 2367 return static_cast<int>(lhs->m_line - rhs->m_line); 2368 } 2369 2370 // for sorting tests by suite/file/line 2371 int suiteOrderComparator(const void* a, const void* b) { 2372 const TestData* lhs = *static_cast<TestData* const*>(a); 2373 const TestData* rhs = *static_cast<TestData* const*>(b); 2374 2375 int res = strcmp(lhs->m_suite, rhs->m_suite); 2376 if(res != 0) 2377 return res; 2378 return fileOrderComparator(a, b); 2379 } 2380 2381 // for sorting tests by name/suite/file/line 2382 int nameOrderComparator(const void* a, const void* b) { 2383 const TestData* lhs = *static_cast<TestData* const*>(a); 2384 const TestData* rhs = *static_cast<TestData* const*>(b); 2385 2386 int res = strcmp(lhs->m_name, rhs->m_name); 2387 if(res != 0) 2388 return res; 2389 return suiteOrderComparator(a, b); 2390 } 2391 2392 // holds the current test suite 2393 const char*& getCurrentTestSuite() { 2394 static const char* data = 0; 2395 return data; 2396 } 2397 2398 // sets the current test suite 2399 int setTestSuiteName(const char* name) { 2400 getCurrentTestSuite() = name; 2401 return 0; 2402 } 2403 2404 // all the registered tests 2405 std::set<TestData>& getRegisteredTests() { 2406 static std::set<TestData> data; 2407 return data; 2408 } 2409 2410 // used by the macros for registering tests 2411 int regTest(funcType f, unsigned line, const char* file, const char* name) { 2412 getRegisteredTests().insert(TestData(getCurrentTestSuite(), name, f, file, line)); 2413 return 0; 2414 } 2415 2416 struct Color 2417 { 2418 enum Code 2419 { 2420 None = 0, 2421 White, 2422 Red, 2423 Green, 2424 Blue, 2425 Cyan, 2426 Yellow, 2427 Grey, 2428 2429 Bright = 0x10, 2430 2431 BrightRed = Bright | Red, 2432 BrightGreen = Bright | Green, 2433 LightGrey = Bright | Grey, 2434 BrightWhite = Bright | White 2435 }; 2436 Color(Code code) { use(code); } 2437 ~Color() { use(None); } 2438 2439 void use(Code code); 2440 2441 private: 2442 Color(Color const& other); 2443 }; 2444 2445 void Color::use(Code 2446 #ifndef DOCTEST_CONFIG_COLORS_NONE 2447 code 2448 #endif // DOCTEST_CONFIG_COLORS_NONE 2449 ) { 2450 ContextState* p = getContextState(); 2451 if(p->no_colors) 2452 return; 2453 #ifdef DOCTEST_CONFIG_COLORS_ANSI 2454 if(isatty(STDOUT_FILENO)) { 2455 const char* col = ""; 2456 // clang-format off 2457 switch(code) { 2458 case Color::Red: col = "[0;31m"; break; 2459 case Color::Green: col = "[0;32m"; break; 2460 case Color::Blue: col = "[0;34m"; break; 2461 case Color::Cyan: col = "[0;36m"; break; 2462 case Color::Yellow: col = "[0;33m"; break; 2463 case Color::Grey: col = "[1;30m"; break; 2464 case Color::LightGrey: col = "[0;37m"; break; 2465 case Color::BrightRed: col = "[1;31m"; break; 2466 case Color::BrightGreen: col = "[1;32m"; break; 2467 case Color::BrightWhite: col = "[1;37m"; break; 2468 case Color::Bright: // invalid 2469 case Color::None: 2470 case Color::White: 2471 default: col = "[0m"; 2472 } 2473 // clang-format on 2474 printf("\033%s", col); 2475 } 2476 #endif // DOCTEST_CONFIG_COLORS_ANSI 2477 2478 #ifdef DOCTEST_CONFIG_COLORS_WINDOWS 2479 static HANDLE stdoutHandle(GetStdHandle(STD_OUTPUT_HANDLE)); 2480 static WORD originalForegroundAttributes; 2481 static WORD originalBackgroundAttributes; 2482 static bool attrsInitted = false; 2483 if(!attrsInitted) { 2484 attrsInitted = true; 2485 CONSOLE_SCREEN_BUFFER_INFO csbiInfo; 2486 GetConsoleScreenBufferInfo(stdoutHandle, &csbiInfo); 2487 originalForegroundAttributes = 2488 csbiInfo.wAttributes & 2489 ~(BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY); 2490 originalBackgroundAttributes = 2491 csbiInfo.wAttributes & 2492 ~(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY); 2493 } 2494 2495 #define DOCTEST_SET_ATTR(x) SetConsoleTextAttribute(stdoutHandle, x | originalBackgroundAttributes) 2496 2497 // clang-format off 2498 switch (code) { 2499 case Color::White: DOCTEST_SET_ATTR(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break; 2500 case Color::Red: DOCTEST_SET_ATTR(FOREGROUND_RED); break; 2501 case Color::Green: DOCTEST_SET_ATTR(FOREGROUND_GREEN); break; 2502 case Color::Blue: DOCTEST_SET_ATTR(FOREGROUND_BLUE); break; 2503 case Color::Cyan: DOCTEST_SET_ATTR(FOREGROUND_BLUE | FOREGROUND_GREEN); break; 2504 case Color::Yellow: DOCTEST_SET_ATTR(FOREGROUND_RED | FOREGROUND_GREEN); break; 2505 case Color::Grey: DOCTEST_SET_ATTR(0); break; 2506 case Color::LightGrey: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY); break; 2507 case Color::BrightRed: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_RED); break; 2508 case Color::BrightGreen: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN); break; 2509 case Color::BrightWhite: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break; 2510 case Color::None: 2511 case Color::Bright: // invalid 2512 default: DOCTEST_SET_ATTR(originalForegroundAttributes); 2513 } 2514 // clang-format on 2515 #undef DOCTEST_SET_ATTR 2516 #endif // DOCTEST_CONFIG_COLORS_WINDOWS 2517 } 2518 2519 // this is needed because MSVC does not permit mixing 2 exception handling schemes in a function 2520 int callTestFunc(funcType f) { 2521 int res = EXIT_SUCCESS; 2522 try { 2523 f(); 2524 if(getContextState()->numFailedAssertionsForCurrentTestcase) 2525 res = EXIT_FAILURE; 2526 } catch(const TestFailureException&) { res = EXIT_FAILURE; } catch(...) { 2527 DOCTEST_LOG_START(); 2528 logTestCrashed(); 2529 res = EXIT_FAILURE; 2530 } 2531 return res; 2532 } 2533 2534 // depending on the current options this will remove the path of filenames 2535 const char* fileForOutput(const char* file) { 2536 if(getContextState()->no_path_in_filenames) { 2537 const char* back = strrchr(file, '\\'); 2538 const char* forward = strrchr(file, '/'); 2539 if(back || forward) { 2540 if(back > forward) 2541 forward = back; 2542 return forward + 1; 2543 } 2544 } 2545 return file; 2546 } 2547 2548 #ifdef DOCTEST_PLATFORM_MAC 2549 #include <sys/types.h> 2550 #include <unistd.h> 2551 #include <sys/sysctl.h> 2552 // The following function is taken directly from the following technical note: 2553 // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html 2554 // Returns true if the current process is being debugged (either 2555 // running under the debugger or has a debugger attached post facto). 2556 bool isDebuggerActive() { 2557 int mib[4]; 2558 struct kinfo_proc info; 2559 size_t size; 2560 // Initialize the flags so that, if sysctl fails for some bizarre 2561 // reason, we get a predictable result. 2562 info.kp_proc.p_flag = 0; 2563 // Initialize mib, which tells sysctl the info we want, in this case 2564 // we're looking for information about a specific process ID. 2565 mib[0] = CTL_KERN; 2566 mib[1] = KERN_PROC; 2567 mib[2] = KERN_PROC_PID; 2568 mib[3] = getpid(); 2569 // Call sysctl. 2570 size = sizeof(info); 2571 if(sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, 0, 0) != 0) { 2572 fprintf(stderr, "\n** Call to sysctl failed - unable to determine if debugger is " 2573 "active **\n\n"); 2574 return false; 2575 } 2576 // We're being debugged if the P_TRACED flag is set. 2577 return ((info.kp_proc.p_flag & P_TRACED) != 0); 2578 } 2579 #elif defined(_MSC_VER) || defined(__MINGW32__) 2580 bool isDebuggerActive() { return ::IsDebuggerPresent() != 0; } 2581 #else 2582 bool isDebuggerActive() { return false; } 2583 #endif // Platform 2584 2585 #ifdef DOCTEST_PLATFORM_WINDOWS 2586 void myOutputDebugString(const String& text) { ::OutputDebugStringA(text.c_str()); } 2587 #else 2588 // TODO: integration with XCode and other IDEs 2589 void myOutputDebugString(const String&) {} 2590 #endif // Platform 2591 2592 const char* getSeparator() { 2593 return "===============================================================================\n"; 2594 } 2595 2596 void printToDebugConsole(const String& text) { 2597 if(isDebuggerActive()) 2598 myOutputDebugString(text.c_str()); 2599 } 2600 2601 void addFailedAssert(assertType::Enum assert_type) { 2602 if((assert_type & assertType::is_warn) == 0) { 2603 getContextState()->numFailedAssertionsForCurrentTestcase++; 2604 getContextState()->numFailedAssertions++; 2605 } 2606 } 2607 2608 void logTestStart(const char* name, const char* file, unsigned line) { 2609 const char* newLine = "\n"; 2610 2611 char loc[DOCTEST_SNPRINTF_BUFFER_LENGTH]; 2612 DOCTEST_SNPRINTF(loc, DOCTEST_COUNTOF(loc), "%s(%d)\n", fileForOutput(file), line); 2613 2614 char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH]; 2615 DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), "%s\n", name); 2616 2617 DOCTEST_PRINTF_COLORED(getSeparator(), Color::Yellow); 2618 DOCTEST_PRINTF_COLORED(loc, Color::LightGrey); 2619 DOCTEST_PRINTF_COLORED(msg, Color::None); 2620 2621 String subcaseStuff = ""; 2622 std::vector<Subcase>& subcasesStack = getContextState()->subcasesStack; 2623 for(unsigned i = 0; i < subcasesStack.size(); ++i) { 2624 char subcase[DOCTEST_SNPRINTF_BUFFER_LENGTH]; 2625 DOCTEST_SNPRINTF(subcase, DOCTEST_COUNTOF(loc), " %s\n", 2626 subcasesStack[i].m_signature.m_name); 2627 DOCTEST_PRINTF_COLORED(subcase, Color::None); 2628 subcaseStuff += subcase; 2629 } 2630 2631 DOCTEST_PRINTF_COLORED(newLine, Color::None); 2632 2633 printToDebugConsole(String(getSeparator()) + loc + msg + subcaseStuff.c_str() + newLine); 2634 } 2635 2636 void logTestEnd() {} 2637 2638 void logTestCrashed() { 2639 char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH]; 2640 2641 DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), "TEST CASE FAILED! (threw exception)\n\n"); 2642 2643 DOCTEST_PRINTF_COLORED(msg, Color::Red); 2644 2645 printToDebugConsole(String(msg)); 2646 } 2647 2648 void logAssert(bool passed, const char* decomposition, bool threw, const char* expr, 2649 assertType::Enum assert_type, const char* file, int line) { 2650 char loc[DOCTEST_SNPRINTF_BUFFER_LENGTH]; 2651 DOCTEST_SNPRINTF(loc, DOCTEST_COUNTOF(loc), "%s(%d)", fileForOutput(file), line); 2652 2653 char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH]; 2654 if(passed) 2655 DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " PASSED!\n"); 2656 else 2657 DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " FAILED! %s\n", 2658 (threw ? "(threw exception)" : "")); 2659 2660 char info1[DOCTEST_SNPRINTF_BUFFER_LENGTH]; 2661 DOCTEST_SNPRINTF(info1, DOCTEST_COUNTOF(info1), " %s( %s )\n", 2662 getAssertString(assert_type), expr); 2663 2664 char info2[DOCTEST_SNPRINTF_BUFFER_LENGTH]; 2665 char info3[DOCTEST_SNPRINTF_BUFFER_LENGTH]; 2666 info2[0] = 0; 2667 info3[0] = 0; 2668 if(!threw) { 2669 DOCTEST_SNPRINTF(info2, DOCTEST_COUNTOF(info2), "with expansion:\n"); 2670 DOCTEST_SNPRINTF(info3, DOCTEST_COUNTOF(info3), " %s( %s )\n", 2671 getAssertString(assert_type), decomposition); 2672 } 2673 2674 DOCTEST_PRINTF_COLORED(loc, Color::LightGrey); 2675 DOCTEST_PRINTF_COLORED(msg, passed ? Color::BrightGreen : Color::Red); 2676 DOCTEST_PRINTF_COLORED(info1, Color::Cyan); 2677 DOCTEST_PRINTF_COLORED(info2, Color::None); 2678 DOCTEST_PRINTF_COLORED(info3, Color::Cyan); 2679 DOCTEST_PRINTF_COLORED("\n", Color::None); 2680 2681 printToDebugConsole(String(loc) + msg + info1 + info2 + info3 + "\n"); 2682 } 2683 2684 void logAssertThrows(bool threw, const char* expr, assertType::Enum assert_type, 2685 const char* file, int line) { 2686 char loc[DOCTEST_SNPRINTF_BUFFER_LENGTH]; 2687 DOCTEST_SNPRINTF(loc, DOCTEST_COUNTOF(loc), "%s(%d)", fileForOutput(file), line); 2688 2689 char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH]; 2690 if(threw) 2691 DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " PASSED!\n"); 2692 else 2693 DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " FAILED!\n"); 2694 2695 char info1[DOCTEST_SNPRINTF_BUFFER_LENGTH]; 2696 DOCTEST_SNPRINTF(info1, DOCTEST_COUNTOF(info1), " %s( %s )\n\n", 2697 getAssertString(assert_type), expr); 2698 2699 DOCTEST_PRINTF_COLORED(loc, Color::LightGrey); 2700 DOCTEST_PRINTF_COLORED(msg, threw ? Color::BrightGreen : Color::Red); 2701 DOCTEST_PRINTF_COLORED(info1, Color::Cyan); 2702 2703 printToDebugConsole(String(loc) + msg + info1); 2704 } 2705 2706 void logAssertThrowsAs(bool threw, bool threw_as, const char* as, const char* expr, 2707 assertType::Enum assert_type, const char* file, int line) { 2708 char loc[DOCTEST_SNPRINTF_BUFFER_LENGTH]; 2709 DOCTEST_SNPRINTF(loc, DOCTEST_COUNTOF(loc), "%s(%d)", fileForOutput(file), line); 2710 2711 char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH]; 2712 if(threw_as) 2713 DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " PASSED!\n"); 2714 else 2715 DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " FAILED! %s\n", 2716 (threw ? "(threw something else)" : "(didn't throw at all)")); 2717 2718 char info1[DOCTEST_SNPRINTF_BUFFER_LENGTH]; 2719 DOCTEST_SNPRINTF(info1, DOCTEST_COUNTOF(info1), " %s( %s, %s )\n\n", 2720 getAssertString(assert_type), expr, as); 2721 2722 DOCTEST_PRINTF_COLORED(loc, Color::LightGrey); 2723 DOCTEST_PRINTF_COLORED(msg, threw_as ? Color::BrightGreen : Color::Red); 2724 DOCTEST_PRINTF_COLORED(info1, Color::Cyan); 2725 2726 printToDebugConsole(String(loc) + msg + info1); 2727 } 2728 2729 void logAssertNothrow(bool threw, const char* expr, assertType::Enum assert_type, 2730 const char* file, int line) { 2731 char loc[DOCTEST_SNPRINTF_BUFFER_LENGTH]; 2732 DOCTEST_SNPRINTF(loc, DOCTEST_COUNTOF(loc), "%s(%d)", fileForOutput(file), line); 2733 2734 char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH]; 2735 if(!threw) 2736 DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " PASSED!\n"); 2737 else 2738 DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " FAILED!\n"); 2739 2740 char info1[DOCTEST_SNPRINTF_BUFFER_LENGTH]; 2741 DOCTEST_SNPRINTF(info1, DOCTEST_COUNTOF(info1), " %s( %s )\n\n", 2742 getAssertString(assert_type), expr); 2743 2744 DOCTEST_PRINTF_COLORED(loc, Color::LightGrey); 2745 DOCTEST_PRINTF_COLORED(msg, !threw ? Color::BrightGreen : Color::Red); 2746 DOCTEST_PRINTF_COLORED(info1, Color::Cyan); 2747 2748 printToDebugConsole(String(loc) + msg + info1); 2749 } 2750 2751 ResultBuilder::ResultBuilder(assertType::Enum assert_type, const char* file, int line, 2752 const char* expr, const char* exception_type) 2753 : m_assert_type(assert_type) 2754 , m_file(file) 2755 , m_line(line) 2756 , m_expr(expr) 2757 , m_exception_type(exception_type) 2758 , m_threw(false) 2759 , m_threw_as(false) 2760 , m_failed(false) {} 2761 2762 bool ResultBuilder::log() { 2763 if((m_assert_type & assertType::is_warn) == 0) 2764 DOCTEST_GCS().numAssertionsForCurrentTestcase++; 2765 2766 if(m_assert_type & assertType::is_false) { 2767 m_result.invert(); 2768 m_failed = m_result; 2769 } else if(m_assert_type & assertType::is_throws) { 2770 m_failed = !m_threw; 2771 } else if(m_assert_type & assertType::is_throws_as) { 2772 m_failed = !m_threw_as; 2773 } else if(m_assert_type & assertType::is_nothrow) { 2774 m_failed = m_threw; 2775 } else { 2776 m_failed = m_result; 2777 } 2778 2779 if(m_failed || DOCTEST_GCS().success) { 2780 DOCTEST_LOG_START(); 2781 2782 if(m_assert_type & assertType::is_throws) { 2783 logAssertThrows(m_threw, m_expr, m_assert_type, m_file, m_line); 2784 } else if(m_assert_type & assertType::is_throws_as) { 2785 logAssertThrowsAs(m_threw, m_threw_as, m_exception_type, m_expr, m_assert_type, 2786 m_file, m_line); 2787 } else if(m_assert_type & assertType::is_nothrow) { 2788 logAssertNothrow(m_threw, m_expr, m_assert_type, m_file, m_line); 2789 } else { 2790 logAssert(m_result.m_passed, m_result.m_decomposition.c_str(), m_threw, m_expr, 2791 m_assert_type, m_file, m_line); 2792 } 2793 } 2794 2795 if(m_failed) { 2796 addFailedAssert(m_assert_type); 2797 if(isDebuggerActive() && !DOCTEST_GCS().no_breaks) 2798 return true; // should break into the debugger 2799 } 2800 return false; 2801 } 2802 2803 void ResultBuilder::react() const { 2804 if(m_failed && checkIfShouldThrow(m_assert_type)) 2805 throwException(); 2806 } 2807 2808 // the implementation of parseFlag() 2809 bool parseFlagImpl(int argc, const char* const* argv, const char* pattern) { 2810 for(int i = argc - 1; i >= 0; --i) { 2811 const char* temp = strstr(argv[i], pattern); 2812 if(temp && my_strlen(temp) == my_strlen(pattern)) { 2813 // eliminate strings in which the chars before the option are not '-' 2814 bool noBadCharsFound = true; 2815 while(temp != argv[i]) { 2816 if(*--temp != '-') { 2817 noBadCharsFound = false; 2818 break; 2819 } 2820 } 2821 if(noBadCharsFound && argv[i][0] == '-') 2822 return true; 2823 } 2824 } 2825 return false; 2826 } 2827 2828 // locates a flag on the command line 2829 bool parseFlag(int argc, const char* const* argv, const char* pattern) { 2830 #ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS 2831 if(!parseFlagImpl(argc, argv, pattern)) 2832 return parseFlagImpl(argc, argv, pattern + 3); // 3 for "dt-" 2833 return true; 2834 #else // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS 2835 return parseFlagImpl(argc, argv, pattern); 2836 #endif // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS 2837 } 2838 2839 // the implementation of parseOption() 2840 bool parseOptionImpl(int argc, const char* const* argv, const char* pattern, String& res) { 2841 for(int i = argc - 1; i >= 0; --i) { 2842 const char* temp = strstr(argv[i], pattern); 2843 if(temp) { 2844 // eliminate matches in which the chars before the option are not '-' 2845 bool noBadCharsFound = true; 2846 const char* curr = argv[i]; 2847 while(curr != temp) { 2848 if(*curr++ != '-') { 2849 noBadCharsFound = false; 2850 break; 2851 } 2852 } 2853 if(noBadCharsFound && argv[i][0] == '-') { 2854 temp += my_strlen(pattern); 2855 unsigned len = my_strlen(temp); 2856 if(len) { 2857 res = temp; 2858 return true; 2859 } 2860 } 2861 } 2862 } 2863 return false; 2864 } 2865 2866 // parses an option and returns the string after the '=' character 2867 bool parseOption(int argc, const char* const* argv, const char* pattern, String& res, 2868 const String& defaultVal = String()) { 2869 res = defaultVal; 2870 #ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS 2871 if(!parseOptionImpl(argc, argv, pattern, res)) 2872 return parseOptionImpl(argc, argv, pattern + 3, res); // 3 for "dt-" 2873 return true; 2874 #else // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS 2875 return parseOptionImpl(argc, argv, pattern, res); 2876 #endif // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS 2877 } 2878 2879 // parses a comma separated list of words after a pattern in one of the arguments in argv 2880 bool parseCommaSepArgs(int argc, const char* const* argv, const char* pattern, 2881 std::vector<String>& res) { 2882 String filtersString; 2883 if(parseOption(argc, argv, pattern, filtersString)) { 2884 // tokenize with "," as a separator 2885 char* pch = strtok(filtersString.c_str(), ","); // modifies the string 2886 while(pch != 0) { 2887 if(my_strlen(pch)) 2888 res.push_back(pch); 2889 pch = strtok(0, ","); // uses the strtok() internal state to go to the next token 2890 } 2891 return true; 2892 } 2893 return false; 2894 } 2895 2896 enum optionType 2897 { 2898 option_bool, 2899 option_int 2900 }; 2901 2902 // parses an int/bool option from the command line 2903 bool parseIntOption(int argc, const char* const* argv, const char* pattern, optionType type, 2904 int& res) { 2905 String parsedValue; 2906 if(parseOption(argc, argv, pattern, parsedValue)) { 2907 if(type == 0) { 2908 // boolean 2909 const char positive[][5] = {"1", "true", "on", "yes"}; // 5 - strlen("true") + 1 2910 const char negative[][6] = {"0", "false", "off", "no"}; // 6 - strlen("false") + 1 2911 2912 // if the value matches any of the positive/negative possibilities 2913 for(unsigned i = 0; i < 4; i++) { 2914 if(parsedValue.compare(positive[i], true) == 0) { 2915 res = 1; 2916 return true; 2917 } 2918 if(parsedValue.compare(negative[i], true) == 0) { 2919 res = 0; 2920 return true; 2921 } 2922 } 2923 } else { 2924 // integer 2925 int theInt = atoi(parsedValue.c_str()); 2926 if(theInt != 0) { 2927 res = theInt; 2928 return true; 2929 } 2930 } 2931 } 2932 return false; 2933 } 2934 2935 void printVersion() { 2936 DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); 2937 printf("doctest version is \"%s\"\n", DOCTEST_VERSION_STR); 2938 } 2939 2940 void printHelp() { 2941 printVersion(); 2942 DOCTEST_PRINTF_COLORED("[doctest]\n", Color::Cyan); 2943 DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); 2944 printf("boolean values: \"1/on/yes/true\" or \"0/off/no/false\"\n"); 2945 DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); 2946 printf("filter values: \"str1,str2,str3\" (comma separated strings)\n"); 2947 DOCTEST_PRINTF_COLORED("[doctest]\n", Color::Cyan); 2948 DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); 2949 printf("filters use wildcards for matching strings\n"); 2950 DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); 2951 printf("something passes a filter if any of the strings in a filter matches\n"); 2952 DOCTEST_PRINTF_COLORED("[doctest]\n", Color::Cyan); 2953 DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); 2954 printf("ALL FLAGS, OPTIONS AND FILTERS ALSO AVAILABLE WITH A \"dt-\" PREFIX!!!\n"); 2955 DOCTEST_PRINTF_COLORED("[doctest]\n", Color::Cyan); 2956 DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); 2957 printf("Query flags - the program quits after them. Available:\n\n"); 2958 printf(" -?, --help, -h prints this message\n"); 2959 printf(" -v, --version prints the version\n"); 2960 printf(" -c, --count prints the number of matching tests\n"); 2961 printf(" -ltc, --list-test-cases lists all matching tests by name\n"); 2962 printf(" -lts, --list-test-suites lists all matching test suites\n\n"); 2963 // ==================================================================================== << 79 2964 DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); 2965 printf("The available <int>/<string> options/filters are:\n\n"); 2966 printf(" -tc, --test-case=<filters> filters tests by their name\n"); 2967 printf(" -tce, --test-case-exclude=<filters> filters OUT tests by their name\n"); 2968 printf(" -sf, --source-file=<filters> filters tests by their file\n"); 2969 printf(" -sfe, --source-file-exclude=<filters> filters OUT tests by their file\n"); 2970 printf(" -ts, --test-suite=<filters> filters tests by their test suite\n"); 2971 printf(" -tse, --test-suite-exclude=<filters> filters OUT tests by their test suite\n"); 2972 printf(" -ob, --order-by=<string> how the tests should be ordered\n"); 2973 printf(" <string> - by [file/suite/name/rand]\n"); 2974 printf(" -rs, --rand-seed=<int> seed for random ordering\n"); 2975 printf(" -f, --first=<int> the first test passing the filters to\n"); 2976 printf(" execute - for range-based execution\n"); 2977 printf(" -l, --last=<int> the last test passing the filters to\n"); 2978 printf(" execute - for range-based execution\n"); 2979 printf(" -aa, --abort-after=<int> stop after <int> failed assertions\n\n"); 2980 DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); 2981 printf("Bool options - can be used like flags and true is assumed. Available:\n\n"); 2982 printf(" -s, --success=<bool> include successful assertions in output\n"); 2983 printf(" -cs, --case-sensitive=<bool> filters being treated as case sensitive\n"); 2984 printf(" -e, --exit=<bool> exits after the tests finish\n"); 2985 printf(" -nt, --no-throw=<bool> skips exceptions-related assert checks\n"); 2986 printf(" -ne, --no-exitcode=<bool> returns (or exits) always with success\n"); 2987 printf(" -nr, --no-run=<bool> skips all runtime doctest operations\n"); 2988 printf(" -nc, --no-colors=<bool> disables colors in output\n"); 2989 printf(" -nb, --no-breaks=<bool> disables breakpoints in debuggers\n"); 2990 printf(" -npf, --no-path-filenames=<bool> only filenames and no paths in output\n\n"); 2991 // ==================================================================================== << 79 2992 2993 DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); 2994 printf("for more information visit the project documentation\n\n"); 2995 } 2996 } // namespace detail 2997 2998 Context::Context(int argc, const char* const* argv) 2999 : p(new detail::ContextState) { 3000 parseArgs(argc, argv, true); 3001 } 3002 3003 Context::~Context() { delete p; } 3004 3005 void Context::applyCommandLine(int argc, const char* const* argv) { parseArgs(argc, argv); } 3006 3007 // parses args 3008 void Context::parseArgs(int argc, const char* const* argv, bool withDefaults) { 3009 using namespace detail; 3010 3011 // clang-format off 3012 parseCommaSepArgs(argc, argv, "dt-source-file=", p->filters[0]); 3013 parseCommaSepArgs(argc, argv, "dt-sf=", p->filters[0]); 3014 parseCommaSepArgs(argc, argv, "dt-source-file-exclude=",p->filters[1]); 3015 parseCommaSepArgs(argc, argv, "dt-sfe=", p->filters[1]); 3016 parseCommaSepArgs(argc, argv, "dt-test-suite=", p->filters[2]); 3017 parseCommaSepArgs(argc, argv, "dt-ts=", p->filters[2]); 3018 parseCommaSepArgs(argc, argv, "dt-test-suite-exclude=", p->filters[3]); 3019 parseCommaSepArgs(argc, argv, "dt-tse=", p->filters[3]); 3020 parseCommaSepArgs(argc, argv, "dt-test-case=", p->filters[4]); 3021 parseCommaSepArgs(argc, argv, "dt-tc=", p->filters[4]); 3022 parseCommaSepArgs(argc, argv, "dt-test-case-exclude=", p->filters[5]); 3023 parseCommaSepArgs(argc, argv, "dt-tce=", p->filters[5]); 3024 // clang-format on 3025 3026 int intRes = 0; 3027 String strRes; 3028 3029 #define DOCTEST_PARSE_AS_BOOL_OR_FLAG(name, sname, var, default) \ 3030 if(parseIntOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(name, =), option_bool, intRes) || \ 3031 parseIntOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(sname, =), option_bool, intRes)) \ 3032 p->var = !!intRes; \ 3033 else if(parseFlag(argc, argv, #name) || parseFlag(argc, argv, #sname)) \ 3034 p->var = 1; \ 3035 else if(withDefaults) \ 3036 p->var = default 3037 3038 #define DOCTEST_PARSE_INT_OPTION(name, sname, var, default) \ 3039 if(parseIntOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(name, =), option_int, intRes) || \ 3040 parseIntOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(sname, =), option_int, intRes)) \ 3041 p->var = intRes; \ 3042 else if(withDefaults) \ 3043 p->var = default 3044 3045 #define DOCTEST_PARSE_STR_OPTION(name, sname, var, default) \ 3046 if(parseOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(name, =), strRes, default) || \ 3047 parseOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(sname, =), strRes, default) || \ 3048 withDefaults) \ 3049 p->var = strRes 3050 3051 // clang-format off 3052 DOCTEST_PARSE_STR_OPTION(dt-order-by, dt-ob, order_by, "file"); 3053 DOCTEST_PARSE_INT_OPTION(dt-rand-seed, dt-rs, rand_seed, 0); 3054 3055 DOCTEST_PARSE_INT_OPTION(dt-first, dt-f, first, 1); 3056 DOCTEST_PARSE_INT_OPTION(dt-last, dt-l, last, 0); 3057 3058 DOCTEST_PARSE_INT_OPTION(dt-abort-after, dt-aa, abort_after, 0); 3059 3060 DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-success, dt-s, success, 0); 3061 DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-case-sensitive, dt-cs, case_sensitive, 0); 3062 DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-exit, dt-e, exit, 0); 3063 DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-throw, dt-nt, no_throw, 0); 3064 DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-exitcode, dt-ne, no_exitcode, 0); 3065 DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-run, dt-nr, no_run, 0); 3066 DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-colors, dt-nc, no_colors, 0); 3067 DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-breaks, dt-nb, no_breaks, 0); 3068 DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-path-filenames, dt-npf, no_path_in_filenames, 0); 3069 // clang-format on 3070 3071 #undef DOCTEST_PARSE_STR_OPTION 3072 #undef DOCTEST_PARSE_INT_OPTION 3073 #undef DOCTEST_PARSE_AS_BOOL_OR_FLAG 3074 3075 if(withDefaults) { 3076 p->help = false; 3077 p->version = false; 3078 p->count = false; 3079 p->list_test_cases = false; 3080 p->list_test_suites = false; 3081 } 3082 if(parseFlag(argc, argv, "dt-help") || parseFlag(argc, argv, "dt-h") || 3083 parseFlag(argc, argv, "dt-?")) { 3084 p->help = true; 3085 p->exit = true; 3086 } 3087 if(parseFlag(argc, argv, "dt-version") || parseFlag(argc, argv, "dt-v")) { 3088 p->version = true; 3089 p->exit = true; 3090 } 3091 if(parseFlag(argc, argv, "dt-count") || parseFlag(argc, argv, "dt-c")) { 3092 p->count = true; 3093 p->exit = true; 3094 } 3095 if(parseFlag(argc, argv, "dt-list-test-cases") || parseFlag(argc, argv, "dt-ltc")) { 3096 p->list_test_cases = true; 3097 p->exit = true; 3098 } 3099 if(parseFlag(argc, argv, "dt-list-test-suites") || parseFlag(argc, argv, "dt-lts")) { 3100 p->list_test_suites = true; 3101 p->exit = true; 3102 } 3103 } 3104 3105 // allows the user to add procedurally to the filters from the command line 3106 void Context::addFilter(const char* filter, const char* value) { setOption(filter, value); } 3107 3108 // allows the user to clear all filters from the command line 3109 void Context::clearFilters() { 3110 for(unsigned i = 0; i < p->filters.size(); ++i) 3111 p->filters[i].clear(); 3112 } 3113 3114 // allows the user to override procedurally the int/bool options from the command line 3115 void Context::setOption(const char* option, int value) { 3116 setOption(option, toString(value).c_str()); 3117 } 3118 3119 // allows the user to override procedurally the string options from the command line 3120 void Context::setOption(const char* option, const char* value) { 3121 String argv = String("-") + option + "=" + value; 3122 const char* lvalue = argv.c_str(); 3123 parseArgs(1, &lvalue); 3124 } 3125 3126 // users should query this in their main() and exit the program if true 3127 bool Context::shouldExit() { return p->exit; } 3128 3129 // the main function that does all the filtering and test running 3130 int Context::run() { 3131 using namespace detail; 3132 3133 getContextState() = p; 3134 p->resetRunData(); 3135 3136 // handle version, help and no_run 3137 if(p->no_run || p->version || p->help) { 3138 if(p->version) 3139 printVersion(); 3140 if(p->help) 3141 printHelp(); 3142 3143 getContextState() = 0; 3144 3145 return EXIT_SUCCESS; 3146 } 3147 3148 printVersion(); 3149 DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); 3150 printf("run with \"--help\" for options\n"); 3151 3152 unsigned i = 0; // counter used for loops - here for VC6 3153 3154 std::set<TestData>& registeredTests = getRegisteredTests(); 3155 3156 std::vector<const TestData*> testArray; 3157 for(std::set<TestData>::iterator it = registeredTests.begin(); it != registeredTests.end(); 3158 ++it) 3159 testArray.push_back(&(*it)); 3160 3161 // sort the collected records 3162 if(testArray.size() > 0) { 3163 if(p->order_by.compare("file", true) == 0) { 3164 qsort(&testArray[0], testArray.size(), sizeof(TestData*), fileOrderComparator); 3165 } else if(p->order_by.compare("suite", true) == 0) { 3166 qsort(&testArray[0], testArray.size(), sizeof(TestData*), suiteOrderComparator); 3167 } else if(p->order_by.compare("name", true) == 0) { 3168 qsort(&testArray[0], testArray.size(), sizeof(TestData*), nameOrderComparator); 3169 } else if(p->order_by.compare("rand", true) == 0) { 3170 srand(p->rand_seed); 3171 3172 // random_shuffle implementation 3173 const TestData** first = &testArray[0]; 3174 for(i = testArray.size() - 1; i > 0; --i) { 3175 int idxToSwap = rand() % (i + 1); 3176 3177 const TestData* temp = first[i]; 3178 3179 first[i] = first[idxToSwap]; 3180 first[idxToSwap] = temp; 3181 } 3182 } 3183 } 3184 3185 if(p->list_test_cases) { 3186 DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); 3187 printf("listing all test case names\n"); 3188 } 3189 3190 std::set<String> testSuitesPassingFilters; 3191 if(p->list_test_suites) { 3192 DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); 3193 printf("listing all test suites\n"); 3194 } 3195 3196 unsigned numTestsPassingFilters = 0; 3197 unsigned numFailed = 0; 3198 // invoke the registered functions if they match the filter criteria (or just count them) 3199 for(i = 0; i < testArray.size(); i++) { 3200 const TestData& data = *testArray[i]; 3201 if(!matchesAny(data.m_file, p->filters[0], 1, p->case_sensitive)) 3202 continue; 3203 if(matchesAny(data.m_file, p->filters[1], 0, p->case_sensitive)) 3204 continue; 3205 if(!matchesAny(data.m_suite, p->filters[2], 1, p->case_sensitive)) 3206 continue; 3207 if(matchesAny(data.m_suite, p->filters[3], 0, p->case_sensitive)) 3208 continue; 3209 if(!matchesAny(data.m_name, p->filters[4], 1, p->case_sensitive)) 3210 continue; 3211 if(matchesAny(data.m_name, p->filters[5], 0, p->case_sensitive)) 3212 continue; 3213 3214 numTestsPassingFilters++; 3215 3216 // do not execute the test if we are to only count the number of filter passing tests 3217 if(p->count) 3218 continue; 3219 3220 // print the name of the test and don't execute it 3221 if(p->list_test_cases) { 3222 printf("%s\n", data.m_name); 3223 continue; 3224 } 3225 3226 // print the name of the test suite if not done already and don't execute it 3227 if(p->list_test_suites) { 3228 if(testSuitesPassingFilters.count(data.m_suite) == 0) { 3229 printf("%s\n", data.m_suite); 3230 testSuitesPassingFilters.insert(data.m_suite); 3231 } 3232 continue; 3233 } 3234 3235 // skip the test if it is not in the execution range 3236 if((p->last < numTestsPassingFilters && p->first <= p->last) || 3237 (p->first > numTestsPassingFilters)) 3238 continue; 3239 3240 // execute the test if it passes all the filtering 3241 { 3242 #ifdef _MSC_VER 3243 //__try { 3244 #endif // _MSC_VER 3245 3246 p->currentTest = &data; 3247 3248 // if logging successful tests - force the start log 3249 p->hasLoggedCurrentTestStart = false; 3250 if(p->success) 3251 DOCTEST_LOG_START(); 3252 3253 unsigned didFail = 0; 3254 p->subcasesPassed.clear(); 3255 do { 3256 // reset the assertion state 3257 p->numAssertionsForCurrentTestcase = 0; 3258 p->numFailedAssertionsForCurrentTestcase = 0; 3259 3260 // reset some of the fields for subcases (except for the set of fully passed ones) 3261 p->subcasesHasSkipped = false; 3262 p->subcasesCurrentLevel = 0; 3263 p->subcasesEnteredLevels.clear(); 3264 3265 // execute the test 3266 didFail += callTestFunc(data.m_f); 3267 p->numAssertions += p->numAssertionsForCurrentTestcase; 3268 3269 // exit this loop if enough assertions have failed 3270 if(p->abort_after > 0 && p->numFailedAssertions >= p->abort_after) 3271 p->subcasesHasSkipped = false; 3272 3273 // if the start has been logged 3274 if(p->hasLoggedCurrentTestStart) 3275 logTestEnd(); 3276 p->hasLoggedCurrentTestStart = false; 3277 3278 } while(p->subcasesHasSkipped == true); 3279 3280 if(didFail > 0) 3281 numFailed++; 3282 3283 // stop executing tests if enough assertions have failed 3284 if(p->abort_after > 0 && p->numFailedAssertions >= p->abort_after) 3285 break; 3286 3287 #ifdef _MSC_VER 3288 //} __except(1) { 3289 // printf("Unknown SEH exception caught!\n"); 3290 // numFailed++; 3291 //} 3292 #endif // _MSC_VER 3293 } 3294 } 3295 3296 DOCTEST_PRINTF_COLORED(getSeparator(), numFailed > 0 ? Color::Red : Color::Green); 3297 if(p->count || p->list_test_cases || p->list_test_suites) { 3298 DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); 3299 printf("number of tests passing the current filters: %d\n", numTestsPassingFilters); 3300 } else { 3301 char buff[DOCTEST_SNPRINTF_BUFFER_LENGTH]; 3302 3303 DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); 3304 3305 DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "test cases: %4d", numTestsPassingFilters); 3306 DOCTEST_PRINTF_COLORED(buff, Color::None); 3307 DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), " | "); 3308 DOCTEST_PRINTF_COLORED(buff, Color::None); 3309 DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "%4d passed", 3310 numTestsPassingFilters - numFailed); 3311 DOCTEST_PRINTF_COLORED(buff, numFailed > 0 ? Color::None : Color::Green); 3312 DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), " | "); 3313 DOCTEST_PRINTF_COLORED(buff, Color::None); 3314 DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "%4d failed", numFailed); 3315 DOCTEST_PRINTF_COLORED(buff, numFailed > 0 ? Color::Red : Color::None); 3316 3317 DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), " | "); 3318 DOCTEST_PRINTF_COLORED(buff, Color::None); 3319 DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "%4d skipped\n", 3320 static_cast<unsigned>(testArray.size()) - numTestsPassingFilters); 3321 DOCTEST_PRINTF_COLORED(buff, Color::None); 3322 3323 DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); 3324 3325 DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "assertions: %4d", p->numAssertions); 3326 DOCTEST_PRINTF_COLORED(buff, Color::None); 3327 DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), " | "); 3328 DOCTEST_PRINTF_COLORED(buff, Color::None); 3329 DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "%4d passed", 3330 p->numAssertions - p->numFailedAssertions); 3331 DOCTEST_PRINTF_COLORED(buff, numFailed > 0 ? Color::None : Color::Green); 3332 DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), " | "); 3333 DOCTEST_PRINTF_COLORED(buff, Color::None); 3334 DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "%4d failed", p->numFailedAssertions); 3335 DOCTEST_PRINTF_COLORED(buff, p->numFailedAssertions > 0 ? Color::Red : Color::None); 3336 3337 DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), " |\n"); 3338 DOCTEST_PRINTF_COLORED(buff, Color::None); 3339 } 3340 3341 // remove any coloring 3342 DOCTEST_PRINTF_COLORED("", Color::None); 3343 3344 getContextState() = 0; 3345 3346 if(numFailed && !p->no_exitcode) 3347 return EXIT_FAILURE; 3348 return EXIT_SUCCESS; 3349 } 3350 } // namespace doctest 3351 3352 #endif // DOCTEST_CONFIG_DISABLE 3353 #endif // DOCTEST_LIBRARY_IMPLEMENTATION 3354 #endif // DOCTEST_CONFIG_IMPLEMENT 3355 3356 // == THIS SUPPLIES A MAIN FUNCTION AND SHOULD BE DONE ONLY IN ONE TRANSLATION UNIT 3357 #if defined(DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN) && !defined(DOCTEST_MAIN_CONFIGURED) 3358 #define DOCTEST_MAIN_CONFIGURED 3359 int main(int argc, char** argv) { return doctest::Context(argc, argv).run(); } 3360 #endif // DOCTEST_MAIN_CONFIGURED 3361 3362 #if defined(__clang__) 3363 #pragma clang diagnostic pop 3364 #endif // __clang__ 3365 3366 #if defined(__GNUC__) && !defined(__clang__) 3367 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6) 3368 #pragma GCC diagnostic pop 3369 #endif // > gcc 4.6 3370 #endif // __GNUC__ 3371 3372 #ifdef _MSC_VER 3373 #pragma warning(pop) 3374 #endif // _MSC_VER 3375