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