No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

17472 líneas
620KB

  1. /*
  2. * Catch v2.10.2
  3. * Generated: 2019-10-24 17:49:11.459934
  4. * ----------------------------------------------------------
  5. * This file has been merged from multiple headers. Please don't edit it directly
  6. * Copyright (c) 2019 Two Blue Cubes Ltd. All rights reserved.
  7. *
  8. * Distributed under the Boost Software License, Version 1.0. (See accompanying
  9. * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  10. */
  11. #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
  12. #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
  13. // start catch.hpp
  14. #define CATCH_VERSION_MAJOR 2
  15. #define CATCH_VERSION_MINOR 10
  16. #define CATCH_VERSION_PATCH 2
  17. #ifdef __clang__
  18. # pragma clang system_header
  19. #elif defined __GNUC__
  20. # pragma GCC system_header
  21. #endif
  22. // start catch_suppress_warnings.h
  23. #ifdef __clang__
  24. # ifdef __ICC // icpc defines the __clang__ macro
  25. # pragma warning(push)
  26. # pragma warning(disable: 161 1682)
  27. # else // __ICC
  28. # pragma clang diagnostic push
  29. # pragma clang diagnostic ignored "-Wpadded"
  30. # pragma clang diagnostic ignored "-Wswitch-enum"
  31. # pragma clang diagnostic ignored "-Wcovered-switch-default"
  32. # endif
  33. #elif defined __GNUC__
  34. // Because REQUIREs trigger GCC's -Wparentheses, and because still
  35. // supported version of g++ have only buggy support for _Pragmas,
  36. // Wparentheses have to be suppressed globally.
  37. # pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details
  38. # pragma GCC diagnostic push
  39. # pragma GCC diagnostic ignored "-Wunused-variable"
  40. # pragma GCC diagnostic ignored "-Wpadded"
  41. #endif
  42. // end catch_suppress_warnings.h
  43. #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
  44. # define CATCH_IMPL
  45. # define CATCH_CONFIG_ALL_PARTS
  46. #endif
  47. // In the impl file, we want to have access to all parts of the headers
  48. // Can also be used to sanely support PCHs
  49. #if defined(CATCH_CONFIG_ALL_PARTS)
  50. # define CATCH_CONFIG_EXTERNAL_INTERFACES
  51. # if defined(CATCH_CONFIG_DISABLE_MATCHERS)
  52. # undef CATCH_CONFIG_DISABLE_MATCHERS
  53. # endif
  54. # if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
  55. # define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
  56. # endif
  57. #endif
  58. #if !defined(CATCH_CONFIG_IMPL_ONLY)
  59. // start catch_platform.h
  60. #ifdef __APPLE__
  61. # include <TargetConditionals.h>
  62. # if TARGET_OS_OSX == 1
  63. # define CATCH_PLATFORM_MAC
  64. # elif TARGET_OS_IPHONE == 1
  65. # define CATCH_PLATFORM_IPHONE
  66. # endif
  67. #elif defined(linux) || defined(__linux) || defined(__linux__)
  68. # define CATCH_PLATFORM_LINUX
  69. #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
  70. # define CATCH_PLATFORM_WINDOWS
  71. #endif
  72. // end catch_platform.h
  73. #ifdef CATCH_IMPL
  74. # ifndef CLARA_CONFIG_MAIN
  75. # define CLARA_CONFIG_MAIN_NOT_DEFINED
  76. # define CLARA_CONFIG_MAIN
  77. # endif
  78. #endif
  79. // start catch_user_interfaces.h
  80. namespace Catch {
  81. unsigned int rngSeed();
  82. }
  83. // end catch_user_interfaces.h
  84. // start catch_tag_alias_autoregistrar.h
  85. // start catch_common.h
  86. // start catch_compiler_capabilities.h
  87. // Detect a number of compiler features - by compiler
  88. // The following features are defined:
  89. //
  90. // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
  91. // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
  92. // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
  93. // CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
  94. // ****************
  95. // Note to maintainers: if new toggles are added please document them
  96. // in configuration.md, too
  97. // ****************
  98. // In general each macro has a _NO_<feature name> form
  99. // (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
  100. // Many features, at point of detection, define an _INTERNAL_ macro, so they
  101. // can be combined, en-mass, with the _NO_ forms later.
  102. #ifdef __cplusplus
  103. # if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
  104. # define CATCH_CPP14_OR_GREATER
  105. # endif
  106. # if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
  107. # define CATCH_CPP17_OR_GREATER
  108. # endif
  109. #endif
  110. #if defined(CATCH_CPP17_OR_GREATER)
  111. # define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
  112. #endif
  113. #ifdef __clang__
  114. # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  115. _Pragma( "clang diagnostic push" ) \
  116. _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
  117. _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
  118. # define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  119. _Pragma( "clang diagnostic pop" )
  120. # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
  121. _Pragma( "clang diagnostic push" ) \
  122. _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
  123. # define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
  124. _Pragma( "clang diagnostic pop" )
  125. # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
  126. _Pragma( "clang diagnostic push" ) \
  127. _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
  128. # define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS \
  129. _Pragma( "clang diagnostic pop" )
  130. # define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
  131. _Pragma( "clang diagnostic push" ) \
  132. _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
  133. # define CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
  134. _Pragma( "clang diagnostic pop" )
  135. # define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
  136. _Pragma( "clang diagnostic push" ) \
  137. _Pragma( "clang diagnostic ignored \"-Wunused-template\"" )
  138. # define CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS \
  139. _Pragma( "clang diagnostic pop" )
  140. #endif // __clang__
  141. ////////////////////////////////////////////////////////////////////////////////
  142. // Assume that non-Windows platforms support posix signals by default
  143. #if !defined(CATCH_PLATFORM_WINDOWS)
  144. #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
  145. #endif
  146. ////////////////////////////////////////////////////////////////////////////////
  147. // We know some environments not to support full POSIX signals
  148. #if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
  149. #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
  150. #endif
  151. #ifdef __OS400__
  152. # define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
  153. # define CATCH_CONFIG_COLOUR_NONE
  154. #endif
  155. ////////////////////////////////////////////////////////////////////////////////
  156. // Android somehow still does not support std::to_string
  157. #if defined(__ANDROID__)
  158. # define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
  159. # define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE
  160. #endif
  161. ////////////////////////////////////////////////////////////////////////////////
  162. // Not all Windows environments support SEH properly
  163. #if defined(__MINGW32__)
  164. # define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
  165. #endif
  166. ////////////////////////////////////////////////////////////////////////////////
  167. // PS4
  168. #if defined(__ORBIS__)
  169. # define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
  170. #endif
  171. ////////////////////////////////////////////////////////////////////////////////
  172. // Cygwin
  173. #ifdef __CYGWIN__
  174. // Required for some versions of Cygwin to declare gettimeofday
  175. // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
  176. # define _BSD_SOURCE
  177. // some versions of cygwin (most) do not support std::to_string. Use the libstd check.
  178. // https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
  179. # if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
  180. && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
  181. # define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
  182. # endif
  183. #endif // __CYGWIN__
  184. ////////////////////////////////////////////////////////////////////////////////
  185. // Visual C++
  186. #ifdef _MSC_VER
  187. # if _MSC_VER >= 1900 // Visual Studio 2015 or newer
  188. # define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
  189. # endif
  190. // Universal Windows platform does not support SEH
  191. // Or console colours (or console at all...)
  192. # if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
  193. # define CATCH_CONFIG_COLOUR_NONE
  194. # else
  195. # define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
  196. # endif
  197. // MSVC traditional preprocessor needs some workaround for __VA_ARGS__
  198. // _MSVC_TRADITIONAL == 0 means new conformant preprocessor
  199. // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
  200. # if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
  201. # define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  202. # endif
  203. #endif // _MSC_VER
  204. #if defined(_REENTRANT) || defined(_MSC_VER)
  205. // Enable async processing, as -pthread is specified or no additional linking is required
  206. # define CATCH_INTERNAL_CONFIG_USE_ASYNC
  207. #endif // _MSC_VER
  208. ////////////////////////////////////////////////////////////////////////////////
  209. // Check if we are compiled with -fno-exceptions or equivalent
  210. #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
  211. # define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
  212. #endif
  213. ////////////////////////////////////////////////////////////////////////////////
  214. // DJGPP
  215. #ifdef __DJGPP__
  216. # define CATCH_INTERNAL_CONFIG_NO_WCHAR
  217. #endif // __DJGPP__
  218. ////////////////////////////////////////////////////////////////////////////////
  219. // Embarcadero C++Build
  220. #if defined(__BORLANDC__)
  221. #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN
  222. #endif
  223. ////////////////////////////////////////////////////////////////////////////////
  224. // Use of __COUNTER__ is suppressed during code analysis in
  225. // CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
  226. // handled by it.
  227. // Otherwise all supported compilers support COUNTER macro,
  228. // but user still might want to turn it off
  229. #if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
  230. #define CATCH_INTERNAL_CONFIG_COUNTER
  231. #endif
  232. ////////////////////////////////////////////////////////////////////////////////
  233. // RTX is a special version of Windows that is real time.
  234. // This means that it is detected as Windows, but does not provide
  235. // the same set of capabilities as real Windows does.
  236. #if defined(UNDER_RTSS) || defined(RTX64_BUILD)
  237. #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
  238. #define CATCH_INTERNAL_CONFIG_NO_ASYNC
  239. #define CATCH_CONFIG_COLOUR_NONE
  240. #endif
  241. #if defined(__UCLIBC__)
  242. #define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER
  243. #endif
  244. // Various stdlib support checks that require __has_include
  245. #if defined(__has_include)
  246. // Check if string_view is available and usable
  247. #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
  248. # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
  249. #endif
  250. // Check if optional is available and usable
  251. # if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
  252. # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
  253. # endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
  254. // Check if byte is available and usable
  255. # if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
  256. # define CATCH_INTERNAL_CONFIG_CPP17_BYTE
  257. # endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
  258. // Check if variant is available and usable
  259. # if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
  260. # if defined(__clang__) && (__clang_major__ < 8)
  261. // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
  262. // fix should be in clang 8, workaround in libstdc++ 8.2
  263. # include <ciso646>
  264. # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
  265. # define CATCH_CONFIG_NO_CPP17_VARIANT
  266. # else
  267. # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
  268. # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
  269. # else
  270. # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
  271. # endif // defined(__clang__) && (__clang_major__ < 8)
  272. # endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
  273. #endif // defined(__has_include)
  274. #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
  275. # define CATCH_CONFIG_COUNTER
  276. #endif
  277. #if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH)
  278. # define CATCH_CONFIG_WINDOWS_SEH
  279. #endif
  280. // This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
  281. #if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
  282. # define CATCH_CONFIG_POSIX_SIGNALS
  283. #endif
  284. // This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
  285. #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
  286. # define CATCH_CONFIG_WCHAR
  287. #endif
  288. #if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
  289. # define CATCH_CONFIG_CPP11_TO_STRING
  290. #endif
  291. #if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL)
  292. # define CATCH_CONFIG_CPP17_OPTIONAL
  293. #endif
  294. #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
  295. # define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
  296. #endif
  297. #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
  298. # define CATCH_CONFIG_CPP17_STRING_VIEW
  299. #endif
  300. #if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
  301. # define CATCH_CONFIG_CPP17_VARIANT
  302. #endif
  303. #if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE)
  304. # define CATCH_CONFIG_CPP17_BYTE
  305. #endif
  306. #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
  307. # define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
  308. #endif
  309. #if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)
  310. # define CATCH_CONFIG_NEW_CAPTURE
  311. #endif
  312. #if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  313. # define CATCH_CONFIG_DISABLE_EXCEPTIONS
  314. #endif
  315. #if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN)
  316. # define CATCH_CONFIG_POLYFILL_ISNAN
  317. #endif
  318. #if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)
  319. # define CATCH_CONFIG_USE_ASYNC
  320. #endif
  321. #if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE)
  322. # define CATCH_CONFIG_ANDROID_LOGWRITE
  323. #endif
  324. #if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
  325. # define CATCH_CONFIG_GLOBAL_NEXTAFTER
  326. #endif
  327. #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
  328. # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
  329. # define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
  330. #endif
  331. #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
  332. # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
  333. # define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  334. #endif
  335. #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
  336. # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
  337. # define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
  338. #endif
  339. #if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
  340. # define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
  341. # define CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS
  342. #endif
  343. #if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
  344. # undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
  345. # undef CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS
  346. #elif defined(__clang__) && (__clang_major__ < 5)
  347. # undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
  348. # undef CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS
  349. #endif
  350. #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)
  351. # define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
  352. # define CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS
  353. #endif
  354. #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  355. #define CATCH_TRY if ((true))
  356. #define CATCH_CATCH_ALL if ((false))
  357. #define CATCH_CATCH_ANON(type) if ((false))
  358. #else
  359. #define CATCH_TRY try
  360. #define CATCH_CATCH_ALL catch (...)
  361. #define CATCH_CATCH_ANON(type) catch (type)
  362. #endif
  363. #if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)
  364. #define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  365. #endif
  366. // end catch_compiler_capabilities.h
  367. #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
  368. #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
  369. #ifdef CATCH_CONFIG_COUNTER
  370. # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
  371. #else
  372. # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
  373. #endif
  374. #include <iosfwd>
  375. #include <string>
  376. #include <cstdint>
  377. // We need a dummy global operator<< so we can bring it into Catch namespace later
  378. struct Catch_global_namespace_dummy {};
  379. std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
  380. namespace Catch {
  381. struct CaseSensitive { enum Choice {
  382. Yes,
  383. No
  384. }; };
  385. class NonCopyable {
  386. NonCopyable( NonCopyable const& ) = delete;
  387. NonCopyable( NonCopyable && ) = delete;
  388. NonCopyable& operator = ( NonCopyable const& ) = delete;
  389. NonCopyable& operator = ( NonCopyable && ) = delete;
  390. protected:
  391. NonCopyable();
  392. virtual ~NonCopyable();
  393. };
  394. struct SourceLineInfo {
  395. SourceLineInfo() = delete;
  396. SourceLineInfo( char const* _file, std::size_t _line ) noexcept
  397. : file( _file ),
  398. line( _line )
  399. {}
  400. SourceLineInfo( SourceLineInfo const& other ) = default;
  401. SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
  402. SourceLineInfo( SourceLineInfo&& ) noexcept = default;
  403. SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default;
  404. bool empty() const noexcept { return file[0] == '\0'; }
  405. bool operator == ( SourceLineInfo const& other ) const noexcept;
  406. bool operator < ( SourceLineInfo const& other ) const noexcept;
  407. char const* file;
  408. std::size_t line;
  409. };
  410. std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
  411. // Bring in operator<< from global namespace into Catch namespace
  412. // This is necessary because the overload of operator<< above makes
  413. // lookup stop at namespace Catch
  414. using ::operator<<;
  415. // Use this in variadic streaming macros to allow
  416. // >> +StreamEndStop
  417. // as well as
  418. // >> stuff +StreamEndStop
  419. struct StreamEndStop {
  420. std::string operator+() const;
  421. };
  422. template<typename T>
  423. T const& operator + ( T const& value, StreamEndStop ) {
  424. return value;
  425. }
  426. }
  427. #define CATCH_INTERNAL_LINEINFO \
  428. ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
  429. // end catch_common.h
  430. namespace Catch {
  431. struct RegistrarForTagAliases {
  432. RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
  433. };
  434. } // end namespace Catch
  435. #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
  436. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  437. namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
  438. CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  439. // end catch_tag_alias_autoregistrar.h
  440. // start catch_test_registry.h
  441. // start catch_interfaces_testcase.h
  442. #include <vector>
  443. namespace Catch {
  444. class TestSpec;
  445. struct ITestInvoker {
  446. virtual void invoke () const = 0;
  447. virtual ~ITestInvoker();
  448. };
  449. class TestCase;
  450. struct IConfig;
  451. struct ITestCaseRegistry {
  452. virtual ~ITestCaseRegistry();
  453. virtual std::vector<TestCase> const& getAllTests() const = 0;
  454. virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
  455. };
  456. bool isThrowSafe( TestCase const& testCase, IConfig const& config );
  457. bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
  458. std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
  459. std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
  460. }
  461. // end catch_interfaces_testcase.h
  462. // start catch_stringref.h
  463. #include <cstddef>
  464. #include <string>
  465. #include <iosfwd>
  466. #include <cassert>
  467. namespace Catch {
  468. /// A non-owning string class (similar to the forthcoming std::string_view)
  469. /// Note that, because a StringRef may be a substring of another string,
  470. /// it may not be null terminated. c_str() must return a null terminated
  471. /// string, however, and so the StringRef will internally take ownership
  472. /// (taking a copy), if necessary. In theory this ownership is not externally
  473. /// visible - but it does mean (substring) StringRefs should not be shared between
  474. /// threads.
  475. class StringRef {
  476. public:
  477. using size_type = std::size_t;
  478. using const_iterator = const char*;
  479. private:
  480. friend struct StringRefTestAccess;
  481. char const* m_start;
  482. size_type m_size;
  483. char* m_data = nullptr;
  484. void takeOwnership();
  485. static constexpr char const* const s_empty = "";
  486. public: // construction/ assignment
  487. StringRef() noexcept
  488. : StringRef( s_empty, 0 )
  489. {}
  490. StringRef( StringRef const& other ) noexcept
  491. : m_start( other.m_start ),
  492. m_size( other.m_size )
  493. {}
  494. StringRef( StringRef&& other ) noexcept
  495. : m_start( other.m_start ),
  496. m_size( other.m_size ),
  497. m_data( other.m_data )
  498. {
  499. other.m_data = nullptr;
  500. }
  501. StringRef( char const* rawChars ) noexcept;
  502. StringRef( char const* rawChars, size_type size ) noexcept
  503. : m_start( rawChars ),
  504. m_size( size )
  505. {}
  506. StringRef( std::string const& stdString ) noexcept
  507. : m_start( stdString.c_str() ),
  508. m_size( stdString.size() )
  509. {}
  510. ~StringRef() noexcept {
  511. delete[] m_data;
  512. }
  513. auto operator = ( StringRef const &other ) noexcept -> StringRef& {
  514. delete[] m_data;
  515. m_data = nullptr;
  516. m_start = other.m_start;
  517. m_size = other.m_size;
  518. return *this;
  519. }
  520. explicit operator std::string() const {
  521. return std::string(m_start, m_size);
  522. }
  523. void swap( StringRef& other ) noexcept;
  524. public: // operators
  525. auto operator == ( StringRef const& other ) const noexcept -> bool;
  526. auto operator != ( StringRef const& other ) const noexcept -> bool;
  527. auto operator[] ( size_type index ) const noexcept -> char {
  528. assert(index < m_size);
  529. return m_start[index];
  530. }
  531. public: // named queries
  532. auto empty() const noexcept -> bool {
  533. return m_size == 0;
  534. }
  535. auto size() const noexcept -> size_type {
  536. return m_size;
  537. }
  538. auto c_str() const -> char const*;
  539. public: // substrings and searches
  540. auto substr( size_type start, size_type size ) const noexcept -> StringRef;
  541. // Returns the current start pointer.
  542. // Note that the pointer can change when if the StringRef is a substring
  543. auto currentData() const noexcept -> char const*;
  544. public: // iterators
  545. const_iterator begin() const { return m_start; }
  546. const_iterator end() const { return m_start + m_size; }
  547. private: // ownership queries - may not be consistent between calls
  548. auto isOwned() const noexcept -> bool;
  549. auto isSubstring() const noexcept -> bool;
  550. };
  551. auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
  552. auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
  553. inline auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
  554. return StringRef( rawChars, size );
  555. }
  556. } // namespace Catch
  557. inline auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
  558. return Catch::StringRef( rawChars, size );
  559. }
  560. // end catch_stringref.h
  561. // start catch_preprocessor.hpp
  562. #define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__
  563. #define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))
  564. #define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))
  565. #define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))
  566. #define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))
  567. #define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))
  568. #ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  569. #define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__
  570. // MSVC needs more evaluations
  571. #define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))
  572. #define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))
  573. #else
  574. #define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__)
  575. #endif
  576. #define CATCH_REC_END(...)
  577. #define CATCH_REC_OUT
  578. #define CATCH_EMPTY()
  579. #define CATCH_DEFER(id) id CATCH_EMPTY()
  580. #define CATCH_REC_GET_END2() 0, CATCH_REC_END
  581. #define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2
  582. #define CATCH_REC_GET_END(...) CATCH_REC_GET_END1
  583. #define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT
  584. #define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0)
  585. #define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)
  586. #define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
  587. #define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ )
  588. #define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
  589. #define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )
  590. #define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ )
  591. #define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )
  592. // Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,
  593. // and passes userdata as the first parameter to each invocation,
  594. // e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)
  595. #define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
  596. #define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
  597. #define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
  598. #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
  599. #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
  600. #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
  601. #define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__)
  602. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  603. #define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__
  604. #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param))
  605. #else
  606. // MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
  607. #define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__)
  608. #define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__
  609. #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)
  610. #endif
  611. #define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__
  612. #define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name)
  613. #define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)
  614. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  615. #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>())
  616. #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
  617. #else
  618. #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>()))
  619. #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
  620. #endif
  621. #define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\
  622. CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__)
  623. #define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0)
  624. #define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1)
  625. #define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2)
  626. #define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3)
  627. #define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4)
  628. #define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5)
  629. #define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _4, _5, _6)
  630. #define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7)
  631. #define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8)
  632. #define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9)
  633. #define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10)
  634. #define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
  635. #define INTERNAL_CATCH_TYPE_GEN\
  636. template<typename...> struct TypeList {};\
  637. template<typename...Ts>\
  638. constexpr auto get_wrapper() noexcept -> TypeList<Ts...> { return {}; }\
  639. template<template<typename...> class...> struct TemplateTypeList{};\
  640. template<template<typename...> class...Cs>\
  641. constexpr auto get_wrapper() noexcept -> TemplateTypeList<Cs...> { return {}; }\
  642. template<typename...>\
  643. struct append;\
  644. template<typename...>\
  645. struct rewrap;\
  646. template<template<typename...> class, typename...>\
  647. struct create;\
  648. template<template<typename...> class, typename>\
  649. struct convert;\
  650. \
  651. template<typename T> \
  652. struct append<T> { using type = T; };\
  653. template< template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2, typename...Rest>\
  654. struct append<L1<E1...>, L2<E2...>, Rest...> { using type = typename append<L1<E1...,E2...>, Rest...>::type; };\
  655. template< template<typename...> class L1, typename...E1, typename...Rest>\
  656. struct append<L1<E1...>, TypeList<mpl_::na>, Rest...> { using type = L1<E1...>; };\
  657. \
  658. template< template<typename...> class Container, template<typename...> class List, typename...elems>\
  659. struct rewrap<TemplateTypeList<Container>, List<elems...>> { using type = TypeList<Container<elems...>>; };\
  660. template< template<typename...> class Container, template<typename...> class List, class...Elems, typename...Elements>\
  661. struct rewrap<TemplateTypeList<Container>, List<Elems...>, Elements...> { using type = typename append<TypeList<Container<Elems...>>, typename rewrap<TemplateTypeList<Container>, Elements...>::type>::type; };\
  662. \
  663. template<template <typename...> class Final, template< typename...> class...Containers, typename...Types>\
  664. struct create<Final, TemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<TemplateTypeList<Containers>, Types...>::type...>::type; };\
  665. template<template <typename...> class Final, template <typename...> class List, typename...Ts>\
  666. struct convert<Final, List<Ts...>> { using type = typename append<Final<>,TypeList<Ts>...>::type; };
  667. #define INTERNAL_CATCH_NTTP_1(signature, ...)\
  668. template<INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp{};\
  669. template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
  670. constexpr auto get_wrapper() noexcept -> Nttp<__VA_ARGS__> { return {}; } \
  671. template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> struct NttpTemplateTypeList{};\
  672. template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Cs>\
  673. constexpr auto get_wrapper() noexcept -> NttpTemplateTypeList<Cs...> { return {}; } \
  674. \
  675. template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\
  676. struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> { using type = TypeList<Container<__VA_ARGS__>>; };\
  677. template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename...Elements>\
  678. struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>, Elements...> { using type = typename append<TypeList<Container<__VA_ARGS__>>, typename rewrap<NttpTemplateTypeList<Container>, Elements...>::type>::type; };\
  679. template<template <typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Containers, typename...Types>\
  680. struct create<Final, NttpTemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<NttpTemplateTypeList<Containers>, Types...>::type...>::type; };
  681. #define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)
  682. #define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature)\
  683. template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
  684. static void TestName()
  685. #define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...)\
  686. template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
  687. static void TestName()
  688. #define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName)
  689. #define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature)\
  690. template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
  691. static void TestName()
  692. #define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature,...)\
  693. template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
  694. static void TestName()
  695. #define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature)\
  696. template<typename Type>\
  697. void reg_test(TypeList<Type>, Catch::NameAndTags nameAndTags)\
  698. {\
  699. Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<Type>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
  700. }
  701. #define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...)\
  702. template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
  703. void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags)\
  704. {\
  705. Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
  706. }
  707. #define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...)\
  708. template<typename Type>\
  709. void reg_test(TypeList<Type>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
  710. {\
  711. Catch::AutoReg( Catch::makeTestInvoker(&TestName<Type>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
  712. }
  713. #define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...)\
  714. template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
  715. void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
  716. {\
  717. Catch::AutoReg( Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
  718. }
  719. #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName)
  720. #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature)\
  721. template<typename TestType> \
  722. struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<TestType> { \
  723. void test();\
  724. }
  725. #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...)\
  726. template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
  727. struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> { \
  728. void test();\
  729. }
  730. #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName)
  731. #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature)\
  732. template<typename TestType> \
  733. void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<TestType>::test()
  734. #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...)\
  735. template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
  736. void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test()
  737. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  738. #define INTERNAL_CATCH_NTTP_0
  739. #define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__),INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_0)
  740. #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__)
  741. #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__)
  742. #define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__)
  743. #define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__)
  744. #define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__)
  745. #define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__)
  746. #define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__)
  747. #else
  748. #define INTERNAL_CATCH_NTTP_0(signature)
  749. #define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1,INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_0)( __VA_ARGS__))
  750. #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__))
  751. #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__))
  752. #define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__))
  753. #define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__))
  754. #define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__))
  755. #define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__))
  756. #define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__))
  757. #endif
  758. // end catch_preprocessor.hpp
  759. // start catch_meta.hpp
  760. #include <type_traits>
  761. namespace Catch {
  762. template<typename T>
  763. struct always_false : std::false_type {};
  764. template <typename> struct true_given : std::true_type {};
  765. struct is_callable_tester {
  766. template <typename Fun, typename... Args>
  767. true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
  768. template <typename...>
  769. std::false_type static test(...);
  770. };
  771. template <typename T>
  772. struct is_callable;
  773. template <typename Fun, typename... Args>
  774. struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};
  775. } // namespace Catch
  776. namespace mpl_{
  777. struct na;
  778. }
  779. // end catch_meta.hpp
  780. namespace Catch {
  781. template<typename C>
  782. class TestInvokerAsMethod : public ITestInvoker {
  783. void (C::*m_testAsMethod)();
  784. public:
  785. TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
  786. void invoke() const override {
  787. C obj;
  788. (obj.*m_testAsMethod)();
  789. }
  790. };
  791. auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;
  792. template<typename C>
  793. auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
  794. return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );
  795. }
  796. struct NameAndTags {
  797. NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;
  798. StringRef name;
  799. StringRef tags;
  800. };
  801. struct AutoReg : NonCopyable {
  802. AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
  803. ~AutoReg();
  804. };
  805. } // end namespace Catch
  806. #if defined(CATCH_CONFIG_DISABLE)
  807. #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
  808. static void TestName()
  809. #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
  810. namespace{ \
  811. struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
  812. void test(); \
  813. }; \
  814. } \
  815. void TestName::test()
  816. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( TestName, TestFunc, Name, Tags, Signature, ... ) \
  817. INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
  818. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
  819. namespace{ \
  820. namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
  821. INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
  822. } \
  823. } \
  824. INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
  825. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  826. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
  827. INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ )
  828. #else
  829. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
  830. INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
  831. #endif
  832. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  833. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
  834. INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ )
  835. #else
  836. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
  837. INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
  838. #endif
  839. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  840. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
  841. INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
  842. #else
  843. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
  844. INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
  845. #endif
  846. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  847. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
  848. INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
  849. #else
  850. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
  851. INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
  852. #endif
  853. #endif
  854. ///////////////////////////////////////////////////////////////////////////////
  855. #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
  856. static void TestName(); \
  857. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  858. namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
  859. CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  860. static void TestName()
  861. #define INTERNAL_CATCH_TESTCASE( ... ) \
  862. INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
  863. ///////////////////////////////////////////////////////////////////////////////
  864. #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
  865. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  866. namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
  867. CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  868. ///////////////////////////////////////////////////////////////////////////////
  869. #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
  870. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  871. namespace{ \
  872. struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
  873. void test(); \
  874. }; \
  875. Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
  876. } \
  877. CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  878. void TestName::test()
  879. #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
  880. INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
  881. ///////////////////////////////////////////////////////////////////////////////
  882. #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
  883. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  884. Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
  885. CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  886. ///////////////////////////////////////////////////////////////////////////////
  887. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\
  888. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  889. CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
  890. CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
  891. INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
  892. namespace {\
  893. namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
  894. INTERNAL_CATCH_TYPE_GEN\
  895. INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
  896. INTERNAL_CATCH_NTTP_REG_GEN(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\
  897. template<typename...Types> \
  898. struct TestName{\
  899. TestName(){\
  900. int index = 0; \
  901. constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
  902. using expander = int[];\
  903. (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
  904. }\
  905. };\
  906. static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
  907. TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
  908. return 0;\
  909. }();\
  910. }\
  911. }\
  912. CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  913. CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
  914. CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS \
  915. INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))
  916. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  917. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
  918. INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ )
  919. #else
  920. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
  921. INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
  922. #endif
  923. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  924. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
  925. INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ )
  926. #else
  927. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
  928. INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
  929. #endif
  930. #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
  931. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  932. CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
  933. CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
  934. template<typename TestType> static void TestFuncName(); \
  935. namespace {\
  936. namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
  937. INTERNAL_CATCH_TYPE_GEN \
  938. INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
  939. template<typename... Types> \
  940. struct TestName { \
  941. void reg_tests() { \
  942. int index = 0; \
  943. using expander = int[]; \
  944. constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
  945. constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
  946. constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
  947. (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */\
  948. } \
  949. }; \
  950. static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
  951. using TestInit = typename create<TestName, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type; \
  952. TestInit t; \
  953. t.reg_tests(); \
  954. return 0; \
  955. }(); \
  956. } \
  957. } \
  958. CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  959. CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
  960. CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS \
  961. template<typename TestType> \
  962. static void TestFuncName()
  963. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  964. #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
  965. INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T,__VA_ARGS__)
  966. #else
  967. #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
  968. INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T, __VA_ARGS__ ) )
  969. #endif
  970. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  971. #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
  972. INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__)
  973. #else
  974. #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
  975. INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
  976. #endif
  977. #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\
  978. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  979. CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
  980. template<typename TestType> static void TestFunc(); \
  981. namespace {\
  982. namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
  983. INTERNAL_CATCH_TYPE_GEN\
  984. template<typename... Types> \
  985. struct TestName { \
  986. void reg_tests() { \
  987. int index = 0; \
  988. using expander = int[]; \
  989. (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */\
  990. } \
  991. };\
  992. static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
  993. using TestInit = typename convert<TestName, TmplList>::type; \
  994. TestInit t; \
  995. t.reg_tests(); \
  996. return 0; \
  997. }(); \
  998. }}\
  999. CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  1000. CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS \
  1001. template<typename TestType> \
  1002. static void TestFunc()
  1003. #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \
  1004. INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, TmplList )
  1005. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
  1006. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  1007. CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
  1008. CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
  1009. namespace {\
  1010. namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
  1011. INTERNAL_CATCH_TYPE_GEN\
  1012. INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
  1013. INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
  1014. INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\
  1015. template<typename...Types> \
  1016. struct TestNameClass{\
  1017. TestNameClass(){\
  1018. int index = 0; \
  1019. constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
  1020. using expander = int[];\
  1021. (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
  1022. }\
  1023. };\
  1024. static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
  1025. TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
  1026. return 0;\
  1027. }();\
  1028. }\
  1029. }\
  1030. CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS\
  1031. CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS\
  1032. CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS\
  1033. INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
  1034. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  1035. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
  1036. INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
  1037. #else
  1038. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
  1039. INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
  1040. #endif
  1041. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  1042. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
  1043. INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
  1044. #else
  1045. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
  1046. INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
  1047. #endif
  1048. #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
  1049. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  1050. CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
  1051. CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
  1052. template<typename TestType> \
  1053. struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
  1054. void test();\
  1055. };\
  1056. namespace {\
  1057. namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) {\
  1058. INTERNAL_CATCH_TYPE_GEN \
  1059. INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
  1060. template<typename...Types>\
  1061. struct TestNameClass{\
  1062. void reg_tests(){\
  1063. int index = 0;\
  1064. using expander = int[];\
  1065. constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
  1066. constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
  1067. constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
  1068. (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */ \
  1069. }\
  1070. };\
  1071. static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
  1072. using TestInit = typename create<TestNameClass, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type;\
  1073. TestInit t;\
  1074. t.reg_tests();\
  1075. return 0;\
  1076. }(); \
  1077. }\
  1078. }\
  1079. CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  1080. CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
  1081. CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS \
  1082. template<typename TestType> \
  1083. void TestName<TestType>::test()
  1084. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  1085. #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
  1086. INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T, __VA_ARGS__ )
  1087. #else
  1088. #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
  1089. INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) )
  1090. #endif
  1091. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  1092. #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
  1093. INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature, __VA_ARGS__ )
  1094. #else
  1095. #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
  1096. INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) )
  1097. #endif
  1098. #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
  1099. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  1100. CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
  1101. template<typename TestType> \
  1102. struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
  1103. void test();\
  1104. };\
  1105. namespace {\
  1106. namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
  1107. INTERNAL_CATCH_TYPE_GEN\
  1108. template<typename...Types>\
  1109. struct TestNameClass{\
  1110. void reg_tests(){\
  1111. int index = 0;\
  1112. using expander = int[];\
  1113. (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */ \
  1114. }\
  1115. };\
  1116. static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
  1117. using TestInit = typename convert<TestNameClass, TmplList>::type;\
  1118. TestInit t;\
  1119. t.reg_tests();\
  1120. return 0;\
  1121. }(); \
  1122. }}\
  1123. CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  1124. CATCH_INTERNAL_UNSUPPRESS_UNUSED_TEMPLATE_WARNINGS \
  1125. template<typename TestType> \
  1126. void TestName<TestType>::test()
  1127. #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \
  1128. INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, TmplList )
  1129. // end catch_test_registry.h
  1130. // start catch_capture.hpp
  1131. // start catch_assertionhandler.h
  1132. // start catch_assertioninfo.h
  1133. // start catch_result_type.h
  1134. namespace Catch {
  1135. // ResultWas::OfType enum
  1136. struct ResultWas { enum OfType {
  1137. Unknown = -1,
  1138. Ok = 0,
  1139. Info = 1,
  1140. Warning = 2,
  1141. FailureBit = 0x10,
  1142. ExpressionFailed = FailureBit | 1,
  1143. ExplicitFailure = FailureBit | 2,
  1144. Exception = 0x100 | FailureBit,
  1145. ThrewException = Exception | 1,
  1146. DidntThrowException = Exception | 2,
  1147. FatalErrorCondition = 0x200 | FailureBit
  1148. }; };
  1149. bool isOk( ResultWas::OfType resultType );
  1150. bool isJustInfo( int flags );
  1151. // ResultDisposition::Flags enum
  1152. struct ResultDisposition { enum Flags {
  1153. Normal = 0x01,
  1154. ContinueOnFailure = 0x02, // Failures fail test, but execution continues
  1155. FalseTest = 0x04, // Prefix expression with !
  1156. SuppressFail = 0x08 // Failures are reported but do not fail the test
  1157. }; };
  1158. ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs );
  1159. bool shouldContinueOnFailure( int flags );
  1160. inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
  1161. bool shouldSuppressFailure( int flags );
  1162. } // end namespace Catch
  1163. // end catch_result_type.h
  1164. namespace Catch {
  1165. struct AssertionInfo
  1166. {
  1167. StringRef macroName;
  1168. SourceLineInfo lineInfo;
  1169. StringRef capturedExpression;
  1170. ResultDisposition::Flags resultDisposition;
  1171. // We want to delete this constructor but a compiler bug in 4.8 means
  1172. // the struct is then treated as non-aggregate
  1173. //AssertionInfo() = delete;
  1174. };
  1175. } // end namespace Catch
  1176. // end catch_assertioninfo.h
  1177. // start catch_decomposer.h
  1178. // start catch_tostring.h
  1179. #include <vector>
  1180. #include <cstddef>
  1181. #include <type_traits>
  1182. #include <string>
  1183. // start catch_stream.h
  1184. #include <iosfwd>
  1185. #include <cstddef>
  1186. #include <ostream>
  1187. namespace Catch {
  1188. std::ostream& cout();
  1189. std::ostream& cerr();
  1190. std::ostream& clog();
  1191. class StringRef;
  1192. struct IStream {
  1193. virtual ~IStream();
  1194. virtual std::ostream& stream() const = 0;
  1195. };
  1196. auto makeStream( StringRef const &filename ) -> IStream const*;
  1197. class ReusableStringStream {
  1198. std::size_t m_index;
  1199. std::ostream* m_oss;
  1200. public:
  1201. ReusableStringStream();
  1202. ~ReusableStringStream();
  1203. auto str() const -> std::string;
  1204. template<typename T>
  1205. auto operator << ( T const& value ) -> ReusableStringStream& {
  1206. *m_oss << value;
  1207. return *this;
  1208. }
  1209. auto get() -> std::ostream& { return *m_oss; }
  1210. };
  1211. }
  1212. // end catch_stream.h
  1213. // start catch_interfaces_enum_values_registry.h
  1214. #include <vector>
  1215. namespace Catch {
  1216. namespace Detail {
  1217. struct EnumInfo {
  1218. StringRef m_name;
  1219. std::vector<std::pair<int, StringRef>> m_values;
  1220. ~EnumInfo();
  1221. StringRef lookup( int value ) const;
  1222. };
  1223. } // namespace Detail
  1224. struct IMutableEnumValuesRegistry {
  1225. virtual ~IMutableEnumValuesRegistry();
  1226. virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values ) = 0;
  1227. template<typename E>
  1228. Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) {
  1229. static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int");
  1230. std::vector<int> intValues;
  1231. intValues.reserve( values.size() );
  1232. for( auto enumValue : values )
  1233. intValues.push_back( static_cast<int>( enumValue ) );
  1234. return registerEnum( enumName, allEnums, intValues );
  1235. }
  1236. };
  1237. } // Catch
  1238. // end catch_interfaces_enum_values_registry.h
  1239. #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
  1240. #include <string_view>
  1241. #endif
  1242. #ifdef __OBJC__
  1243. // start catch_objc_arc.hpp
  1244. #import <Foundation/Foundation.h>
  1245. #ifdef __has_feature
  1246. #define CATCH_ARC_ENABLED __has_feature(objc_arc)
  1247. #else
  1248. #define CATCH_ARC_ENABLED 0
  1249. #endif
  1250. void arcSafeRelease( NSObject* obj );
  1251. id performOptionalSelector( id obj, SEL sel );
  1252. #if !CATCH_ARC_ENABLED
  1253. inline void arcSafeRelease( NSObject* obj ) {
  1254. [obj release];
  1255. }
  1256. inline id performOptionalSelector( id obj, SEL sel ) {
  1257. if( [obj respondsToSelector: sel] )
  1258. return [obj performSelector: sel];
  1259. return nil;
  1260. }
  1261. #define CATCH_UNSAFE_UNRETAINED
  1262. #define CATCH_ARC_STRONG
  1263. #else
  1264. inline void arcSafeRelease( NSObject* ){}
  1265. inline id performOptionalSelector( id obj, SEL sel ) {
  1266. #ifdef __clang__
  1267. #pragma clang diagnostic push
  1268. #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
  1269. #endif
  1270. if( [obj respondsToSelector: sel] )
  1271. return [obj performSelector: sel];
  1272. #ifdef __clang__
  1273. #pragma clang diagnostic pop
  1274. #endif
  1275. return nil;
  1276. }
  1277. #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
  1278. #define CATCH_ARC_STRONG __strong
  1279. #endif
  1280. // end catch_objc_arc.hpp
  1281. #endif
  1282. #ifdef _MSC_VER
  1283. #pragma warning(push)
  1284. #pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
  1285. #endif
  1286. namespace Catch {
  1287. namespace Detail {
  1288. extern const std::string unprintableString;
  1289. std::string rawMemoryToString( const void *object, std::size_t size );
  1290. template<typename T>
  1291. std::string rawMemoryToString( const T& object ) {
  1292. return rawMemoryToString( &object, sizeof(object) );
  1293. }
  1294. template<typename T>
  1295. class IsStreamInsertable {
  1296. template<typename Stream, typename U>
  1297. static auto test(int)
  1298. -> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type());
  1299. template<typename, typename>
  1300. static auto test(...)->std::false_type;
  1301. public:
  1302. static const bool value = decltype(test<std::ostream, const T&>(0))::value;
  1303. };
  1304. template<typename E>
  1305. std::string convertUnknownEnumToString( E e );
  1306. template<typename T>
  1307. typename std::enable_if<
  1308. !std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value,
  1309. std::string>::type convertUnstreamable( T const& ) {
  1310. return Detail::unprintableString;
  1311. }
  1312. template<typename T>
  1313. typename std::enable_if<
  1314. !std::is_enum<T>::value && std::is_base_of<std::exception, T>::value,
  1315. std::string>::type convertUnstreamable(T const& ex) {
  1316. return ex.what();
  1317. }
  1318. template<typename T>
  1319. typename std::enable_if<
  1320. std::is_enum<T>::value
  1321. , std::string>::type convertUnstreamable( T const& value ) {
  1322. return convertUnknownEnumToString( value );
  1323. }
  1324. #if defined(_MANAGED)
  1325. //! Convert a CLR string to a utf8 std::string
  1326. template<typename T>
  1327. std::string clrReferenceToString( T^ ref ) {
  1328. if (ref == nullptr)
  1329. return std::string("null");
  1330. auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
  1331. cli::pin_ptr<System::Byte> p = &bytes[0];
  1332. return std::string(reinterpret_cast<char const *>(p), bytes->Length);
  1333. }
  1334. #endif
  1335. } // namespace Detail
  1336. // If we decide for C++14, change these to enable_if_ts
  1337. template <typename T, typename = void>
  1338. struct StringMaker {
  1339. template <typename Fake = T>
  1340. static
  1341. typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
  1342. convert(const Fake& value) {
  1343. ReusableStringStream rss;
  1344. // NB: call using the function-like syntax to avoid ambiguity with
  1345. // user-defined templated operator<< under clang.
  1346. rss.operator<<(value);
  1347. return rss.str();
  1348. }
  1349. template <typename Fake = T>
  1350. static
  1351. typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
  1352. convert( const Fake& value ) {
  1353. #if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
  1354. return Detail::convertUnstreamable(value);
  1355. #else
  1356. return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
  1357. #endif
  1358. }
  1359. };
  1360. namespace Detail {
  1361. // This function dispatches all stringification requests inside of Catch.
  1362. // Should be preferably called fully qualified, like ::Catch::Detail::stringify
  1363. template <typename T>
  1364. std::string stringify(const T& e) {
  1365. return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
  1366. }
  1367. template<typename E>
  1368. std::string convertUnknownEnumToString( E e ) {
  1369. return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
  1370. }
  1371. #if defined(_MANAGED)
  1372. template <typename T>
  1373. std::string stringify( T^ e ) {
  1374. return ::Catch::StringMaker<T^>::convert(e);
  1375. }
  1376. #endif
  1377. } // namespace Detail
  1378. // Some predefined specializations
  1379. template<>
  1380. struct StringMaker<std::string> {
  1381. static std::string convert(const std::string& str);
  1382. };
  1383. #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
  1384. template<>
  1385. struct StringMaker<std::string_view> {
  1386. static std::string convert(std::string_view str);
  1387. };
  1388. #endif
  1389. template<>
  1390. struct StringMaker<char const *> {
  1391. static std::string convert(char const * str);
  1392. };
  1393. template<>
  1394. struct StringMaker<char *> {
  1395. static std::string convert(char * str);
  1396. };
  1397. #ifdef CATCH_CONFIG_WCHAR
  1398. template<>
  1399. struct StringMaker<std::wstring> {
  1400. static std::string convert(const std::wstring& wstr);
  1401. };
  1402. # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
  1403. template<>
  1404. struct StringMaker<std::wstring_view> {
  1405. static std::string convert(std::wstring_view str);
  1406. };
  1407. # endif
  1408. template<>
  1409. struct StringMaker<wchar_t const *> {
  1410. static std::string convert(wchar_t const * str);
  1411. };
  1412. template<>
  1413. struct StringMaker<wchar_t *> {
  1414. static std::string convert(wchar_t * str);
  1415. };
  1416. #endif
  1417. // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
  1418. // while keeping string semantics?
  1419. template<int SZ>
  1420. struct StringMaker<char[SZ]> {
  1421. static std::string convert(char const* str) {
  1422. return ::Catch::Detail::stringify(std::string{ str });
  1423. }
  1424. };
  1425. template<int SZ>
  1426. struct StringMaker<signed char[SZ]> {
  1427. static std::string convert(signed char const* str) {
  1428. return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
  1429. }
  1430. };
  1431. template<int SZ>
  1432. struct StringMaker<unsigned char[SZ]> {
  1433. static std::string convert(unsigned char const* str) {
  1434. return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
  1435. }
  1436. };
  1437. #if defined(CATCH_CONFIG_CPP17_BYTE)
  1438. template<>
  1439. struct StringMaker<std::byte> {
  1440. static std::string convert(std::byte value);
  1441. };
  1442. #endif // defined(CATCH_CONFIG_CPP17_BYTE)
  1443. template<>
  1444. struct StringMaker<int> {
  1445. static std::string convert(int value);
  1446. };
  1447. template<>
  1448. struct StringMaker<long> {
  1449. static std::string convert(long value);
  1450. };
  1451. template<>
  1452. struct StringMaker<long long> {
  1453. static std::string convert(long long value);
  1454. };
  1455. template<>
  1456. struct StringMaker<unsigned int> {
  1457. static std::string convert(unsigned int value);
  1458. };
  1459. template<>
  1460. struct StringMaker<unsigned long> {
  1461. static std::string convert(unsigned long value);
  1462. };
  1463. template<>
  1464. struct StringMaker<unsigned long long> {
  1465. static std::string convert(unsigned long long value);
  1466. };
  1467. template<>
  1468. struct StringMaker<bool> {
  1469. static std::string convert(bool b);
  1470. };
  1471. template<>
  1472. struct StringMaker<char> {
  1473. static std::string convert(char c);
  1474. };
  1475. template<>
  1476. struct StringMaker<signed char> {
  1477. static std::string convert(signed char c);
  1478. };
  1479. template<>
  1480. struct StringMaker<unsigned char> {
  1481. static std::string convert(unsigned char c);
  1482. };
  1483. template<>
  1484. struct StringMaker<std::nullptr_t> {
  1485. static std::string convert(std::nullptr_t);
  1486. };
  1487. template<>
  1488. struct StringMaker<float> {
  1489. static std::string convert(float value);
  1490. static int precision;
  1491. };
  1492. template<>
  1493. struct StringMaker<double> {
  1494. static std::string convert(double value);
  1495. static int precision;
  1496. };
  1497. template <typename T>
  1498. struct StringMaker<T*> {
  1499. template <typename U>
  1500. static std::string convert(U* p) {
  1501. if (p) {
  1502. return ::Catch::Detail::rawMemoryToString(p);
  1503. } else {
  1504. return "nullptr";
  1505. }
  1506. }
  1507. };
  1508. template <typename R, typename C>
  1509. struct StringMaker<R C::*> {
  1510. static std::string convert(R C::* p) {
  1511. if (p) {
  1512. return ::Catch::Detail::rawMemoryToString(p);
  1513. } else {
  1514. return "nullptr";
  1515. }
  1516. }
  1517. };
  1518. #if defined(_MANAGED)
  1519. template <typename T>
  1520. struct StringMaker<T^> {
  1521. static std::string convert( T^ ref ) {
  1522. return ::Catch::Detail::clrReferenceToString(ref);
  1523. }
  1524. };
  1525. #endif
  1526. namespace Detail {
  1527. template<typename InputIterator>
  1528. std::string rangeToString(InputIterator first, InputIterator last) {
  1529. ReusableStringStream rss;
  1530. rss << "{ ";
  1531. if (first != last) {
  1532. rss << ::Catch::Detail::stringify(*first);
  1533. for (++first; first != last; ++first)
  1534. rss << ", " << ::Catch::Detail::stringify(*first);
  1535. }
  1536. rss << " }";
  1537. return rss.str();
  1538. }
  1539. }
  1540. #ifdef __OBJC__
  1541. template<>
  1542. struct StringMaker<NSString*> {
  1543. static std::string convert(NSString * nsstring) {
  1544. if (!nsstring)
  1545. return "nil";
  1546. return std::string("@") + [nsstring UTF8String];
  1547. }
  1548. };
  1549. template<>
  1550. struct StringMaker<NSObject*> {
  1551. static std::string convert(NSObject* nsObject) {
  1552. return ::Catch::Detail::stringify([nsObject description]);
  1553. }
  1554. };
  1555. namespace Detail {
  1556. inline std::string stringify( NSString* nsstring ) {
  1557. return StringMaker<NSString*>::convert( nsstring );
  1558. }
  1559. } // namespace Detail
  1560. #endif // __OBJC__
  1561. } // namespace Catch
  1562. //////////////////////////////////////////////////////
  1563. // Separate std-lib types stringification, so it can be selectively enabled
  1564. // This means that we do not bring in
  1565. #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
  1566. # define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
  1567. # define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
  1568. # define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
  1569. # define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
  1570. # define CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
  1571. #endif
  1572. // Separate std::pair specialization
  1573. #if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
  1574. #include <utility>
  1575. namespace Catch {
  1576. template<typename T1, typename T2>
  1577. struct StringMaker<std::pair<T1, T2> > {
  1578. static std::string convert(const std::pair<T1, T2>& pair) {
  1579. ReusableStringStream rss;
  1580. rss << "{ "
  1581. << ::Catch::Detail::stringify(pair.first)
  1582. << ", "
  1583. << ::Catch::Detail::stringify(pair.second)
  1584. << " }";
  1585. return rss.str();
  1586. }
  1587. };
  1588. }
  1589. #endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
  1590. #if defined(CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_OPTIONAL)
  1591. #include <optional>
  1592. namespace Catch {
  1593. template<typename T>
  1594. struct StringMaker<std::optional<T> > {
  1595. static std::string convert(const std::optional<T>& optional) {
  1596. ReusableStringStream rss;
  1597. if (optional.has_value()) {
  1598. rss << ::Catch::Detail::stringify(*optional);
  1599. } else {
  1600. rss << "{ }";
  1601. }
  1602. return rss.str();
  1603. }
  1604. };
  1605. }
  1606. #endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
  1607. // Separate std::tuple specialization
  1608. #if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
  1609. #include <tuple>
  1610. namespace Catch {
  1611. namespace Detail {
  1612. template<
  1613. typename Tuple,
  1614. std::size_t N = 0,
  1615. bool = (N < std::tuple_size<Tuple>::value)
  1616. >
  1617. struct TupleElementPrinter {
  1618. static void print(const Tuple& tuple, std::ostream& os) {
  1619. os << (N ? ", " : " ")
  1620. << ::Catch::Detail::stringify(std::get<N>(tuple));
  1621. TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
  1622. }
  1623. };
  1624. template<
  1625. typename Tuple,
  1626. std::size_t N
  1627. >
  1628. struct TupleElementPrinter<Tuple, N, false> {
  1629. static void print(const Tuple&, std::ostream&) {}
  1630. };
  1631. }
  1632. template<typename ...Types>
  1633. struct StringMaker<std::tuple<Types...>> {
  1634. static std::string convert(const std::tuple<Types...>& tuple) {
  1635. ReusableStringStream rss;
  1636. rss << '{';
  1637. Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
  1638. rss << " }";
  1639. return rss.str();
  1640. }
  1641. };
  1642. }
  1643. #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
  1644. #if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
  1645. #include <variant>
  1646. namespace Catch {
  1647. template<>
  1648. struct StringMaker<std::monostate> {
  1649. static std::string convert(const std::monostate&) {
  1650. return "{ }";
  1651. }
  1652. };
  1653. template<typename... Elements>
  1654. struct StringMaker<std::variant<Elements...>> {
  1655. static std::string convert(const std::variant<Elements...>& variant) {
  1656. if (variant.valueless_by_exception()) {
  1657. return "{valueless variant}";
  1658. } else {
  1659. return std::visit(
  1660. [](const auto& value) {
  1661. return ::Catch::Detail::stringify(value);
  1662. },
  1663. variant
  1664. );
  1665. }
  1666. }
  1667. };
  1668. }
  1669. #endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
  1670. namespace Catch {
  1671. struct not_this_one {}; // Tag type for detecting which begin/ end are being selected
  1672. // Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace
  1673. using std::begin;
  1674. using std::end;
  1675. not_this_one begin( ... );
  1676. not_this_one end( ... );
  1677. template <typename T>
  1678. struct is_range {
  1679. static const bool value =
  1680. !std::is_same<decltype(begin(std::declval<T>())), not_this_one>::value &&
  1681. !std::is_same<decltype(end(std::declval<T>())), not_this_one>::value;
  1682. };
  1683. #if defined(_MANAGED) // Managed types are never ranges
  1684. template <typename T>
  1685. struct is_range<T^> {
  1686. static const bool value = false;
  1687. };
  1688. #endif
  1689. template<typename Range>
  1690. std::string rangeToString( Range const& range ) {
  1691. return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
  1692. }
  1693. // Handle vector<bool> specially
  1694. template<typename Allocator>
  1695. std::string rangeToString( std::vector<bool, Allocator> const& v ) {
  1696. ReusableStringStream rss;
  1697. rss << "{ ";
  1698. bool first = true;
  1699. for( bool b : v ) {
  1700. if( first )
  1701. first = false;
  1702. else
  1703. rss << ", ";
  1704. rss << ::Catch::Detail::stringify( b );
  1705. }
  1706. rss << " }";
  1707. return rss.str();
  1708. }
  1709. template<typename R>
  1710. struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {
  1711. static std::string convert( R const& range ) {
  1712. return rangeToString( range );
  1713. }
  1714. };
  1715. template <typename T, int SZ>
  1716. struct StringMaker<T[SZ]> {
  1717. static std::string convert(T const(&arr)[SZ]) {
  1718. return rangeToString(arr);
  1719. }
  1720. };
  1721. } // namespace Catch
  1722. // Separate std::chrono::duration specialization
  1723. #if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
  1724. #include <ctime>
  1725. #include <ratio>
  1726. #include <chrono>
  1727. namespace Catch {
  1728. template <class Ratio>
  1729. struct ratio_string {
  1730. static std::string symbol();
  1731. };
  1732. template <class Ratio>
  1733. std::string ratio_string<Ratio>::symbol() {
  1734. Catch::ReusableStringStream rss;
  1735. rss << '[' << Ratio::num << '/'
  1736. << Ratio::den << ']';
  1737. return rss.str();
  1738. }
  1739. template <>
  1740. struct ratio_string<std::atto> {
  1741. static std::string symbol();
  1742. };
  1743. template <>
  1744. struct ratio_string<std::femto> {
  1745. static std::string symbol();
  1746. };
  1747. template <>
  1748. struct ratio_string<std::pico> {
  1749. static std::string symbol();
  1750. };
  1751. template <>
  1752. struct ratio_string<std::nano> {
  1753. static std::string symbol();
  1754. };
  1755. template <>
  1756. struct ratio_string<std::micro> {
  1757. static std::string symbol();
  1758. };
  1759. template <>
  1760. struct ratio_string<std::milli> {
  1761. static std::string symbol();
  1762. };
  1763. ////////////
  1764. // std::chrono::duration specializations
  1765. template<typename Value, typename Ratio>
  1766. struct StringMaker<std::chrono::duration<Value, Ratio>> {
  1767. static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
  1768. ReusableStringStream rss;
  1769. rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
  1770. return rss.str();
  1771. }
  1772. };
  1773. template<typename Value>
  1774. struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
  1775. static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
  1776. ReusableStringStream rss;
  1777. rss << duration.count() << " s";
  1778. return rss.str();
  1779. }
  1780. };
  1781. template<typename Value>
  1782. struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
  1783. static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
  1784. ReusableStringStream rss;
  1785. rss << duration.count() << " m";
  1786. return rss.str();
  1787. }
  1788. };
  1789. template<typename Value>
  1790. struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
  1791. static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
  1792. ReusableStringStream rss;
  1793. rss << duration.count() << " h";
  1794. return rss.str();
  1795. }
  1796. };
  1797. ////////////
  1798. // std::chrono::time_point specialization
  1799. // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
  1800. template<typename Clock, typename Duration>
  1801. struct StringMaker<std::chrono::time_point<Clock, Duration>> {
  1802. static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
  1803. return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
  1804. }
  1805. };
  1806. // std::chrono::time_point<system_clock> specialization
  1807. template<typename Duration>
  1808. struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
  1809. static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
  1810. auto converted = std::chrono::system_clock::to_time_t(time_point);
  1811. #ifdef _MSC_VER
  1812. std::tm timeInfo = {};
  1813. gmtime_s(&timeInfo, &converted);
  1814. #else
  1815. std::tm* timeInfo = std::gmtime(&converted);
  1816. #endif
  1817. auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
  1818. char timeStamp[timeStampSize];
  1819. const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
  1820. #ifdef _MSC_VER
  1821. std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
  1822. #else
  1823. std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
  1824. #endif
  1825. return std::string(timeStamp);
  1826. }
  1827. };
  1828. }
  1829. #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
  1830. #define INTERNAL_CATCH_REGISTER_ENUM( enumName, ... ) \
  1831. namespace Catch { \
  1832. template<> struct StringMaker<enumName> { \
  1833. static std::string convert( enumName value ) { \
  1834. static const auto& enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum( #enumName, #__VA_ARGS__, { __VA_ARGS__ } ); \
  1835. return static_cast<std::string>(enumInfo.lookup( static_cast<int>( value ) )); \
  1836. } \
  1837. }; \
  1838. }
  1839. #define CATCH_REGISTER_ENUM( enumName, ... ) INTERNAL_CATCH_REGISTER_ENUM( enumName, __VA_ARGS__ )
  1840. #ifdef _MSC_VER
  1841. #pragma warning(pop)
  1842. #endif
  1843. // end catch_tostring.h
  1844. #include <iosfwd>
  1845. #ifdef _MSC_VER
  1846. #pragma warning(push)
  1847. #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
  1848. #pragma warning(disable:4018) // more "signed/unsigned mismatch"
  1849. #pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
  1850. #pragma warning(disable:4180) // qualifier applied to function type has no meaning
  1851. #pragma warning(disable:4800) // Forcing result to true or false
  1852. #endif
  1853. namespace Catch {
  1854. struct ITransientExpression {
  1855. auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
  1856. auto getResult() const -> bool { return m_result; }
  1857. virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
  1858. ITransientExpression( bool isBinaryExpression, bool result )
  1859. : m_isBinaryExpression( isBinaryExpression ),
  1860. m_result( result )
  1861. {}
  1862. // We don't actually need a virtual destructor, but many static analysers
  1863. // complain if it's not here :-(
  1864. virtual ~ITransientExpression();
  1865. bool m_isBinaryExpression;
  1866. bool m_result;
  1867. };
  1868. void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
  1869. template<typename LhsT, typename RhsT>
  1870. class BinaryExpr : public ITransientExpression {
  1871. LhsT m_lhs;
  1872. StringRef m_op;
  1873. RhsT m_rhs;
  1874. void streamReconstructedExpression( std::ostream &os ) const override {
  1875. formatReconstructedExpression
  1876. ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
  1877. }
  1878. public:
  1879. BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
  1880. : ITransientExpression{ true, comparisonResult },
  1881. m_lhs( lhs ),
  1882. m_op( op ),
  1883. m_rhs( rhs )
  1884. {}
  1885. template<typename T>
  1886. auto operator && ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
  1887. static_assert(always_false<T>::value,
  1888. "chained comparisons are not supported inside assertions, "
  1889. "wrap the expression inside parentheses, or decompose it");
  1890. }
  1891. template<typename T>
  1892. auto operator || ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
  1893. static_assert(always_false<T>::value,
  1894. "chained comparisons are not supported inside assertions, "
  1895. "wrap the expression inside parentheses, or decompose it");
  1896. }
  1897. template<typename T>
  1898. auto operator == ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
  1899. static_assert(always_false<T>::value,
  1900. "chained comparisons are not supported inside assertions, "
  1901. "wrap the expression inside parentheses, or decompose it");
  1902. }
  1903. template<typename T>
  1904. auto operator != ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
  1905. static_assert(always_false<T>::value,
  1906. "chained comparisons are not supported inside assertions, "
  1907. "wrap the expression inside parentheses, or decompose it");
  1908. }
  1909. template<typename T>
  1910. auto operator > ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
  1911. static_assert(always_false<T>::value,
  1912. "chained comparisons are not supported inside assertions, "
  1913. "wrap the expression inside parentheses, or decompose it");
  1914. }
  1915. template<typename T>
  1916. auto operator < ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
  1917. static_assert(always_false<T>::value,
  1918. "chained comparisons are not supported inside assertions, "
  1919. "wrap the expression inside parentheses, or decompose it");
  1920. }
  1921. template<typename T>
  1922. auto operator >= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
  1923. static_assert(always_false<T>::value,
  1924. "chained comparisons are not supported inside assertions, "
  1925. "wrap the expression inside parentheses, or decompose it");
  1926. }
  1927. template<typename T>
  1928. auto operator <= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
  1929. static_assert(always_false<T>::value,
  1930. "chained comparisons are not supported inside assertions, "
  1931. "wrap the expression inside parentheses, or decompose it");
  1932. }
  1933. };
  1934. template<typename LhsT>
  1935. class UnaryExpr : public ITransientExpression {
  1936. LhsT m_lhs;
  1937. void streamReconstructedExpression( std::ostream &os ) const override {
  1938. os << Catch::Detail::stringify( m_lhs );
  1939. }
  1940. public:
  1941. explicit UnaryExpr( LhsT lhs )
  1942. : ITransientExpression{ false, static_cast<bool>(lhs) },
  1943. m_lhs( lhs )
  1944. {}
  1945. };
  1946. // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
  1947. template<typename LhsT, typename RhsT>
  1948. auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
  1949. template<typename T>
  1950. auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
  1951. template<typename T>
  1952. auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
  1953. template<typename T>
  1954. auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
  1955. template<typename T>
  1956. auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
  1957. template<typename LhsT, typename RhsT>
  1958. auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
  1959. template<typename T>
  1960. auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
  1961. template<typename T>
  1962. auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
  1963. template<typename T>
  1964. auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
  1965. template<typename T>
  1966. auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
  1967. template<typename LhsT>
  1968. class ExprLhs {
  1969. LhsT m_lhs;
  1970. public:
  1971. explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
  1972. template<typename RhsT>
  1973. auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
  1974. return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs };
  1975. }
  1976. auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
  1977. return { m_lhs == rhs, m_lhs, "==", rhs };
  1978. }
  1979. template<typename RhsT>
  1980. auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
  1981. return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs };
  1982. }
  1983. auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
  1984. return { m_lhs != rhs, m_lhs, "!=", rhs };
  1985. }
  1986. template<typename RhsT>
  1987. auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
  1988. return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs };
  1989. }
  1990. template<typename RhsT>
  1991. auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
  1992. return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs };
  1993. }
  1994. template<typename RhsT>
  1995. auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
  1996. return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs };
  1997. }
  1998. template<typename RhsT>
  1999. auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
  2000. return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
  2001. }
  2002. template<typename RhsT>
  2003. auto operator && ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
  2004. static_assert(always_false<RhsT>::value,
  2005. "operator&& is not supported inside assertions, "
  2006. "wrap the expression inside parentheses, or decompose it");
  2007. }
  2008. template<typename RhsT>
  2009. auto operator || ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
  2010. static_assert(always_false<RhsT>::value,
  2011. "operator|| is not supported inside assertions, "
  2012. "wrap the expression inside parentheses, or decompose it");
  2013. }
  2014. auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
  2015. return UnaryExpr<LhsT>{ m_lhs };
  2016. }
  2017. };
  2018. void handleExpression( ITransientExpression const& expr );
  2019. template<typename T>
  2020. void handleExpression( ExprLhs<T> const& expr ) {
  2021. handleExpression( expr.makeUnaryExpr() );
  2022. }
  2023. struct Decomposer {
  2024. template<typename T>
  2025. auto operator <= ( T const& lhs ) -> ExprLhs<T const&> {
  2026. return ExprLhs<T const&>{ lhs };
  2027. }
  2028. auto operator <=( bool value ) -> ExprLhs<bool> {
  2029. return ExprLhs<bool>{ value };
  2030. }
  2031. };
  2032. } // end namespace Catch
  2033. #ifdef _MSC_VER
  2034. #pragma warning(pop)
  2035. #endif
  2036. // end catch_decomposer.h
  2037. // start catch_interfaces_capture.h
  2038. #include <string>
  2039. #include <chrono>
  2040. namespace Catch {
  2041. class AssertionResult;
  2042. struct AssertionInfo;
  2043. struct SectionInfo;
  2044. struct SectionEndInfo;
  2045. struct MessageInfo;
  2046. struct MessageBuilder;
  2047. struct Counts;
  2048. struct AssertionReaction;
  2049. struct SourceLineInfo;
  2050. struct ITransientExpression;
  2051. struct IGeneratorTracker;
  2052. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  2053. struct BenchmarkInfo;
  2054. template <typename Duration = std::chrono::duration<double, std::nano>>
  2055. struct BenchmarkStats;
  2056. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  2057. struct IResultCapture {
  2058. virtual ~IResultCapture();
  2059. virtual bool sectionStarted( SectionInfo const& sectionInfo,
  2060. Counts& assertions ) = 0;
  2061. virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
  2062. virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
  2063. virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
  2064. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  2065. virtual void benchmarkPreparing( std::string const& name ) = 0;
  2066. virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
  2067. virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0;
  2068. virtual void benchmarkFailed( std::string const& error ) = 0;
  2069. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  2070. virtual void pushScopedMessage( MessageInfo const& message ) = 0;
  2071. virtual void popScopedMessage( MessageInfo const& message ) = 0;
  2072. virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0;
  2073. virtual void handleFatalErrorCondition( StringRef message ) = 0;
  2074. virtual void handleExpr
  2075. ( AssertionInfo const& info,
  2076. ITransientExpression const& expr,
  2077. AssertionReaction& reaction ) = 0;
  2078. virtual void handleMessage
  2079. ( AssertionInfo const& info,
  2080. ResultWas::OfType resultType,
  2081. StringRef const& message,
  2082. AssertionReaction& reaction ) = 0;
  2083. virtual void handleUnexpectedExceptionNotThrown
  2084. ( AssertionInfo const& info,
  2085. AssertionReaction& reaction ) = 0;
  2086. virtual void handleUnexpectedInflightException
  2087. ( AssertionInfo const& info,
  2088. std::string const& message,
  2089. AssertionReaction& reaction ) = 0;
  2090. virtual void handleIncomplete
  2091. ( AssertionInfo const& info ) = 0;
  2092. virtual void handleNonExpr
  2093. ( AssertionInfo const &info,
  2094. ResultWas::OfType resultType,
  2095. AssertionReaction &reaction ) = 0;
  2096. virtual bool lastAssertionPassed() = 0;
  2097. virtual void assertionPassed() = 0;
  2098. // Deprecated, do not use:
  2099. virtual std::string getCurrentTestName() const = 0;
  2100. virtual const AssertionResult* getLastResult() const = 0;
  2101. virtual void exceptionEarlyReported() = 0;
  2102. };
  2103. IResultCapture& getResultCapture();
  2104. }
  2105. // end catch_interfaces_capture.h
  2106. namespace Catch {
  2107. struct TestFailureException{};
  2108. struct AssertionResultData;
  2109. struct IResultCapture;
  2110. class RunContext;
  2111. class LazyExpression {
  2112. friend class AssertionHandler;
  2113. friend struct AssertionStats;
  2114. friend class RunContext;
  2115. ITransientExpression const* m_transientExpression = nullptr;
  2116. bool m_isNegated;
  2117. public:
  2118. LazyExpression( bool isNegated );
  2119. LazyExpression( LazyExpression const& other );
  2120. LazyExpression& operator = ( LazyExpression const& ) = delete;
  2121. explicit operator bool() const;
  2122. friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;
  2123. };
  2124. struct AssertionReaction {
  2125. bool shouldDebugBreak = false;
  2126. bool shouldThrow = false;
  2127. };
  2128. class AssertionHandler {
  2129. AssertionInfo m_assertionInfo;
  2130. AssertionReaction m_reaction;
  2131. bool m_completed = false;
  2132. IResultCapture& m_resultCapture;
  2133. public:
  2134. AssertionHandler
  2135. ( StringRef const& macroName,
  2136. SourceLineInfo const& lineInfo,
  2137. StringRef capturedExpression,
  2138. ResultDisposition::Flags resultDisposition );
  2139. ~AssertionHandler() {
  2140. if ( !m_completed ) {
  2141. m_resultCapture.handleIncomplete( m_assertionInfo );
  2142. }
  2143. }
  2144. template<typename T>
  2145. void handleExpr( ExprLhs<T> const& expr ) {
  2146. handleExpr( expr.makeUnaryExpr() );
  2147. }
  2148. void handleExpr( ITransientExpression const& expr );
  2149. void handleMessage(ResultWas::OfType resultType, StringRef const& message);
  2150. void handleExceptionThrownAsExpected();
  2151. void handleUnexpectedExceptionNotThrown();
  2152. void handleExceptionNotThrownAsExpected();
  2153. void handleThrowingCallSkipped();
  2154. void handleUnexpectedInflightException();
  2155. void complete();
  2156. void setCompleted();
  2157. // query
  2158. auto allowThrows() const -> bool;
  2159. };
  2160. void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString );
  2161. } // namespace Catch
  2162. // end catch_assertionhandler.h
  2163. // start catch_message.h
  2164. #include <string>
  2165. #include <vector>
  2166. namespace Catch {
  2167. struct MessageInfo {
  2168. MessageInfo( StringRef const& _macroName,
  2169. SourceLineInfo const& _lineInfo,
  2170. ResultWas::OfType _type );
  2171. StringRef macroName;
  2172. std::string message;
  2173. SourceLineInfo lineInfo;
  2174. ResultWas::OfType type;
  2175. unsigned int sequence;
  2176. bool operator == ( MessageInfo const& other ) const;
  2177. bool operator < ( MessageInfo const& other ) const;
  2178. private:
  2179. static unsigned int globalCount;
  2180. };
  2181. struct MessageStream {
  2182. template<typename T>
  2183. MessageStream& operator << ( T const& value ) {
  2184. m_stream << value;
  2185. return *this;
  2186. }
  2187. ReusableStringStream m_stream;
  2188. };
  2189. struct MessageBuilder : MessageStream {
  2190. MessageBuilder( StringRef const& macroName,
  2191. SourceLineInfo const& lineInfo,
  2192. ResultWas::OfType type );
  2193. template<typename T>
  2194. MessageBuilder& operator << ( T const& value ) {
  2195. m_stream << value;
  2196. return *this;
  2197. }
  2198. MessageInfo m_info;
  2199. };
  2200. class ScopedMessage {
  2201. public:
  2202. explicit ScopedMessage( MessageBuilder const& builder );
  2203. ScopedMessage( ScopedMessage& duplicate ) = delete;
  2204. ScopedMessage( ScopedMessage&& old );
  2205. ~ScopedMessage();
  2206. MessageInfo m_info;
  2207. bool m_moved;
  2208. };
  2209. class Capturer {
  2210. std::vector<MessageInfo> m_messages;
  2211. IResultCapture& m_resultCapture = getResultCapture();
  2212. size_t m_captured = 0;
  2213. public:
  2214. Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
  2215. ~Capturer();
  2216. void captureValue( size_t index, std::string const& value );
  2217. template<typename T>
  2218. void captureValues( size_t index, T const& value ) {
  2219. captureValue( index, Catch::Detail::stringify( value ) );
  2220. }
  2221. template<typename T, typename... Ts>
  2222. void captureValues( size_t index, T const& value, Ts const&... values ) {
  2223. captureValue( index, Catch::Detail::stringify(value) );
  2224. captureValues( index+1, values... );
  2225. }
  2226. };
  2227. } // end namespace Catch
  2228. // end catch_message.h
  2229. #if !defined(CATCH_CONFIG_DISABLE)
  2230. #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
  2231. #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
  2232. #else
  2233. #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
  2234. #endif
  2235. #if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  2236. ///////////////////////////////////////////////////////////////////////////////
  2237. // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
  2238. // macros.
  2239. #define INTERNAL_CATCH_TRY
  2240. #define INTERNAL_CATCH_CATCH( capturer )
  2241. #else // CATCH_CONFIG_FAST_COMPILE
  2242. #define INTERNAL_CATCH_TRY try
  2243. #define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }
  2244. #endif
  2245. #define INTERNAL_CATCH_REACT( handler ) handler.complete();
  2246. ///////////////////////////////////////////////////////////////////////////////
  2247. #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
  2248. do { \
  2249. Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
  2250. INTERNAL_CATCH_TRY { \
  2251. CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
  2252. catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
  2253. CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
  2254. } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
  2255. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  2256. } while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look
  2257. // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
  2258. ///////////////////////////////////////////////////////////////////////////////
  2259. #define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
  2260. INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
  2261. if( Catch::getResultCapture().lastAssertionPassed() )
  2262. ///////////////////////////////////////////////////////////////////////////////
  2263. #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
  2264. INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
  2265. if( !Catch::getResultCapture().lastAssertionPassed() )
  2266. ///////////////////////////////////////////////////////////////////////////////
  2267. #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
  2268. do { \
  2269. Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
  2270. try { \
  2271. static_cast<void>(__VA_ARGS__); \
  2272. catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
  2273. } \
  2274. catch( ... ) { \
  2275. catchAssertionHandler.handleUnexpectedInflightException(); \
  2276. } \
  2277. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  2278. } while( false )
  2279. ///////////////////////////////////////////////////////////////////////////////
  2280. #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
  2281. do { \
  2282. Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
  2283. if( catchAssertionHandler.allowThrows() ) \
  2284. try { \
  2285. static_cast<void>(__VA_ARGS__); \
  2286. catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
  2287. } \
  2288. catch( ... ) { \
  2289. catchAssertionHandler.handleExceptionThrownAsExpected(); \
  2290. } \
  2291. else \
  2292. catchAssertionHandler.handleThrowingCallSkipped(); \
  2293. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  2294. } while( false )
  2295. ///////////////////////////////////////////////////////////////////////////////
  2296. #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
  2297. do { \
  2298. Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
  2299. if( catchAssertionHandler.allowThrows() ) \
  2300. try { \
  2301. static_cast<void>(expr); \
  2302. catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
  2303. } \
  2304. catch( exceptionType const& ) { \
  2305. catchAssertionHandler.handleExceptionThrownAsExpected(); \
  2306. } \
  2307. catch( ... ) { \
  2308. catchAssertionHandler.handleUnexpectedInflightException(); \
  2309. } \
  2310. else \
  2311. catchAssertionHandler.handleThrowingCallSkipped(); \
  2312. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  2313. } while( false )
  2314. ///////////////////////////////////////////////////////////////////////////////
  2315. #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
  2316. do { \
  2317. Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
  2318. catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
  2319. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  2320. } while( false )
  2321. ///////////////////////////////////////////////////////////////////////////////
  2322. #define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
  2323. auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \
  2324. varName.captureValues( 0, __VA_ARGS__ )
  2325. ///////////////////////////////////////////////////////////////////////////////
  2326. #define INTERNAL_CATCH_INFO( macroName, log ) \
  2327. Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
  2328. ///////////////////////////////////////////////////////////////////////////////
  2329. #define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \
  2330. Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )
  2331. ///////////////////////////////////////////////////////////////////////////////
  2332. // Although this is matcher-based, it can be used with just a string
  2333. #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
  2334. do { \
  2335. Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
  2336. if( catchAssertionHandler.allowThrows() ) \
  2337. try { \
  2338. static_cast<void>(__VA_ARGS__); \
  2339. catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
  2340. } \
  2341. catch( ... ) { \
  2342. Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \
  2343. } \
  2344. else \
  2345. catchAssertionHandler.handleThrowingCallSkipped(); \
  2346. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  2347. } while( false )
  2348. #endif // CATCH_CONFIG_DISABLE
  2349. // end catch_capture.hpp
  2350. // start catch_section.h
  2351. // start catch_section_info.h
  2352. // start catch_totals.h
  2353. #include <cstddef>
  2354. namespace Catch {
  2355. struct Counts {
  2356. Counts operator - ( Counts const& other ) const;
  2357. Counts& operator += ( Counts const& other );
  2358. std::size_t total() const;
  2359. bool allPassed() const;
  2360. bool allOk() const;
  2361. std::size_t passed = 0;
  2362. std::size_t failed = 0;
  2363. std::size_t failedButOk = 0;
  2364. };
  2365. struct Totals {
  2366. Totals operator - ( Totals const& other ) const;
  2367. Totals& operator += ( Totals const& other );
  2368. Totals delta( Totals const& prevTotals ) const;
  2369. int error = 0;
  2370. Counts assertions;
  2371. Counts testCases;
  2372. };
  2373. }
  2374. // end catch_totals.h
  2375. #include <string>
  2376. namespace Catch {
  2377. struct SectionInfo {
  2378. SectionInfo
  2379. ( SourceLineInfo const& _lineInfo,
  2380. std::string const& _name );
  2381. // Deprecated
  2382. SectionInfo
  2383. ( SourceLineInfo const& _lineInfo,
  2384. std::string const& _name,
  2385. std::string const& ) : SectionInfo( _lineInfo, _name ) {}
  2386. std::string name;
  2387. std::string description; // !Deprecated: this will always be empty
  2388. SourceLineInfo lineInfo;
  2389. };
  2390. struct SectionEndInfo {
  2391. SectionInfo sectionInfo;
  2392. Counts prevAssertions;
  2393. double durationInSeconds;
  2394. };
  2395. } // end namespace Catch
  2396. // end catch_section_info.h
  2397. // start catch_timer.h
  2398. #include <cstdint>
  2399. namespace Catch {
  2400. auto getCurrentNanosecondsSinceEpoch() -> uint64_t;
  2401. auto getEstimatedClockResolution() -> uint64_t;
  2402. class Timer {
  2403. uint64_t m_nanoseconds = 0;
  2404. public:
  2405. void start();
  2406. auto getElapsedNanoseconds() const -> uint64_t;
  2407. auto getElapsedMicroseconds() const -> uint64_t;
  2408. auto getElapsedMilliseconds() const -> unsigned int;
  2409. auto getElapsedSeconds() const -> double;
  2410. };
  2411. } // namespace Catch
  2412. // end catch_timer.h
  2413. #include <string>
  2414. namespace Catch {
  2415. class Section : NonCopyable {
  2416. public:
  2417. Section( SectionInfo const& info );
  2418. ~Section();
  2419. // This indicates whether the section should be executed or not
  2420. explicit operator bool() const;
  2421. private:
  2422. SectionInfo m_info;
  2423. std::string m_name;
  2424. Counts m_assertions;
  2425. bool m_sectionIncluded;
  2426. Timer m_timer;
  2427. };
  2428. } // end namespace Catch
  2429. #define INTERNAL_CATCH_SECTION( ... ) \
  2430. CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
  2431. if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
  2432. CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
  2433. #define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
  2434. CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
  2435. if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
  2436. CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
  2437. // end catch_section.h
  2438. // start catch_interfaces_exception.h
  2439. // start catch_interfaces_registry_hub.h
  2440. #include <string>
  2441. #include <memory>
  2442. namespace Catch {
  2443. class TestCase;
  2444. struct ITestCaseRegistry;
  2445. struct IExceptionTranslatorRegistry;
  2446. struct IExceptionTranslator;
  2447. struct IReporterRegistry;
  2448. struct IReporterFactory;
  2449. struct ITagAliasRegistry;
  2450. struct IMutableEnumValuesRegistry;
  2451. class StartupExceptionRegistry;
  2452. using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
  2453. struct IRegistryHub {
  2454. virtual ~IRegistryHub();
  2455. virtual IReporterRegistry const& getReporterRegistry() const = 0;
  2456. virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
  2457. virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
  2458. virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;
  2459. virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
  2460. };
  2461. struct IMutableRegistryHub {
  2462. virtual ~IMutableRegistryHub();
  2463. virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0;
  2464. virtual void registerListener( IReporterFactoryPtr const& factory ) = 0;
  2465. virtual void registerTest( TestCase const& testInfo ) = 0;
  2466. virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
  2467. virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
  2468. virtual void registerStartupException() noexcept = 0;
  2469. virtual IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() = 0;
  2470. };
  2471. IRegistryHub const& getRegistryHub();
  2472. IMutableRegistryHub& getMutableRegistryHub();
  2473. void cleanUp();
  2474. std::string translateActiveException();
  2475. }
  2476. // end catch_interfaces_registry_hub.h
  2477. #if defined(CATCH_CONFIG_DISABLE)
  2478. #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \
  2479. static std::string translatorName( signature )
  2480. #endif
  2481. #include <exception>
  2482. #include <string>
  2483. #include <vector>
  2484. namespace Catch {
  2485. using exceptionTranslateFunction = std::string(*)();
  2486. struct IExceptionTranslator;
  2487. using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;
  2488. struct IExceptionTranslator {
  2489. virtual ~IExceptionTranslator();
  2490. virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
  2491. };
  2492. struct IExceptionTranslatorRegistry {
  2493. virtual ~IExceptionTranslatorRegistry();
  2494. virtual std::string translateActiveException() const = 0;
  2495. };
  2496. class ExceptionTranslatorRegistrar {
  2497. template<typename T>
  2498. class ExceptionTranslator : public IExceptionTranslator {
  2499. public:
  2500. ExceptionTranslator( std::string(*translateFunction)( T& ) )
  2501. : m_translateFunction( translateFunction )
  2502. {}
  2503. std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override {
  2504. try {
  2505. if( it == itEnd )
  2506. std::rethrow_exception(std::current_exception());
  2507. else
  2508. return (*it)->translate( it+1, itEnd );
  2509. }
  2510. catch( T& ex ) {
  2511. return m_translateFunction( ex );
  2512. }
  2513. }
  2514. protected:
  2515. std::string(*m_translateFunction)( T& );
  2516. };
  2517. public:
  2518. template<typename T>
  2519. ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
  2520. getMutableRegistryHub().registerTranslator
  2521. ( new ExceptionTranslator<T>( translateFunction ) );
  2522. }
  2523. };
  2524. }
  2525. ///////////////////////////////////////////////////////////////////////////////
  2526. #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
  2527. static std::string translatorName( signature ); \
  2528. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  2529. namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
  2530. CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  2531. static std::string translatorName( signature )
  2532. #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
  2533. // end catch_interfaces_exception.h
  2534. // start catch_approx.h
  2535. #include <type_traits>
  2536. namespace Catch {
  2537. namespace Detail {
  2538. class Approx {
  2539. private:
  2540. bool equalityComparisonImpl(double other) const;
  2541. // Validates the new margin (margin >= 0)
  2542. // out-of-line to avoid including stdexcept in the header
  2543. void setMargin(double margin);
  2544. // Validates the new epsilon (0 < epsilon < 1)
  2545. // out-of-line to avoid including stdexcept in the header
  2546. void setEpsilon(double epsilon);
  2547. public:
  2548. explicit Approx ( double value );
  2549. static Approx custom();
  2550. Approx operator-() const;
  2551. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2552. Approx operator()( T const& value ) {
  2553. Approx approx( static_cast<double>(value) );
  2554. approx.m_epsilon = m_epsilon;
  2555. approx.m_margin = m_margin;
  2556. approx.m_scale = m_scale;
  2557. return approx;
  2558. }
  2559. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2560. explicit Approx( T const& value ): Approx(static_cast<double>(value))
  2561. {}
  2562. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2563. friend bool operator == ( const T& lhs, Approx const& rhs ) {
  2564. auto lhs_v = static_cast<double>(lhs);
  2565. return rhs.equalityComparisonImpl(lhs_v);
  2566. }
  2567. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2568. friend bool operator == ( Approx const& lhs, const T& rhs ) {
  2569. return operator==( rhs, lhs );
  2570. }
  2571. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2572. friend bool operator != ( T const& lhs, Approx const& rhs ) {
  2573. return !operator==( lhs, rhs );
  2574. }
  2575. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2576. friend bool operator != ( Approx const& lhs, T const& rhs ) {
  2577. return !operator==( rhs, lhs );
  2578. }
  2579. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2580. friend bool operator <= ( T const& lhs, Approx const& rhs ) {
  2581. return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
  2582. }
  2583. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2584. friend bool operator <= ( Approx const& lhs, T const& rhs ) {
  2585. return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
  2586. }
  2587. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2588. friend bool operator >= ( T const& lhs, Approx const& rhs ) {
  2589. return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
  2590. }
  2591. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2592. friend bool operator >= ( Approx const& lhs, T const& rhs ) {
  2593. return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
  2594. }
  2595. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2596. Approx& epsilon( T const& newEpsilon ) {
  2597. double epsilonAsDouble = static_cast<double>(newEpsilon);
  2598. setEpsilon(epsilonAsDouble);
  2599. return *this;
  2600. }
  2601. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2602. Approx& margin( T const& newMargin ) {
  2603. double marginAsDouble = static_cast<double>(newMargin);
  2604. setMargin(marginAsDouble);
  2605. return *this;
  2606. }
  2607. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2608. Approx& scale( T const& newScale ) {
  2609. m_scale = static_cast<double>(newScale);
  2610. return *this;
  2611. }
  2612. std::string toString() const;
  2613. private:
  2614. double m_epsilon;
  2615. double m_margin;
  2616. double m_scale;
  2617. double m_value;
  2618. };
  2619. } // end namespace Detail
  2620. namespace literals {
  2621. Detail::Approx operator "" _a(long double val);
  2622. Detail::Approx operator "" _a(unsigned long long val);
  2623. } // end namespace literals
  2624. template<>
  2625. struct StringMaker<Catch::Detail::Approx> {
  2626. static std::string convert(Catch::Detail::Approx const& value);
  2627. };
  2628. } // end namespace Catch
  2629. // end catch_approx.h
  2630. // start catch_string_manip.h
  2631. #include <string>
  2632. #include <iosfwd>
  2633. #include <vector>
  2634. namespace Catch {
  2635. bool startsWith( std::string const& s, std::string const& prefix );
  2636. bool startsWith( std::string const& s, char prefix );
  2637. bool endsWith( std::string const& s, std::string const& suffix );
  2638. bool endsWith( std::string const& s, char suffix );
  2639. bool contains( std::string const& s, std::string const& infix );
  2640. void toLowerInPlace( std::string& s );
  2641. std::string toLower( std::string const& s );
  2642. //! Returns a new string without whitespace at the start/end
  2643. std::string trim( std::string const& str );
  2644. //! Returns a substring of the original ref without whitespace. Beware lifetimes!
  2645. StringRef trim(StringRef ref);
  2646. // !!! Be aware, returns refs into original string - make sure original string outlives them
  2647. std::vector<StringRef> splitStringRef( StringRef str, char delimiter );
  2648. bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
  2649. struct pluralise {
  2650. pluralise( std::size_t count, std::string const& label );
  2651. friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
  2652. std::size_t m_count;
  2653. std::string m_label;
  2654. };
  2655. }
  2656. // end catch_string_manip.h
  2657. #ifndef CATCH_CONFIG_DISABLE_MATCHERS
  2658. // start catch_capture_matchers.h
  2659. // start catch_matchers.h
  2660. #include <string>
  2661. #include <vector>
  2662. namespace Catch {
  2663. namespace Matchers {
  2664. namespace Impl {
  2665. template<typename ArgT> struct MatchAllOf;
  2666. template<typename ArgT> struct MatchAnyOf;
  2667. template<typename ArgT> struct MatchNotOf;
  2668. class MatcherUntypedBase {
  2669. public:
  2670. MatcherUntypedBase() = default;
  2671. MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
  2672. MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete;
  2673. std::string toString() const;
  2674. protected:
  2675. virtual ~MatcherUntypedBase();
  2676. virtual std::string describe() const = 0;
  2677. mutable std::string m_cachedToString;
  2678. };
  2679. #ifdef __clang__
  2680. # pragma clang diagnostic push
  2681. # pragma clang diagnostic ignored "-Wnon-virtual-dtor"
  2682. #endif
  2683. template<typename ObjectT>
  2684. struct MatcherMethod {
  2685. virtual bool match( ObjectT const& arg ) const = 0;
  2686. };
  2687. #if defined(__OBJC__)
  2688. // Hack to fix Catch GH issue #1661. Could use id for generic Object support.
  2689. // use of const for Object pointers is very uncommon and under ARC it causes some kind of signature mismatch that breaks compilation
  2690. template<>
  2691. struct MatcherMethod<NSString*> {
  2692. virtual bool match( NSString* arg ) const = 0;
  2693. };
  2694. #endif
  2695. #ifdef __clang__
  2696. # pragma clang diagnostic pop
  2697. #endif
  2698. template<typename T>
  2699. struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
  2700. MatchAllOf<T> operator && ( MatcherBase const& other ) const;
  2701. MatchAnyOf<T> operator || ( MatcherBase const& other ) const;
  2702. MatchNotOf<T> operator ! () const;
  2703. };
  2704. template<typename ArgT>
  2705. struct MatchAllOf : MatcherBase<ArgT> {
  2706. bool match( ArgT const& arg ) const override {
  2707. for( auto matcher : m_matchers ) {
  2708. if (!matcher->match(arg))
  2709. return false;
  2710. }
  2711. return true;
  2712. }
  2713. std::string describe() const override {
  2714. std::string description;
  2715. description.reserve( 4 + m_matchers.size()*32 );
  2716. description += "( ";
  2717. bool first = true;
  2718. for( auto matcher : m_matchers ) {
  2719. if( first )
  2720. first = false;
  2721. else
  2722. description += " and ";
  2723. description += matcher->toString();
  2724. }
  2725. description += " )";
  2726. return description;
  2727. }
  2728. MatchAllOf<ArgT>& operator && ( MatcherBase<ArgT> const& other ) {
  2729. m_matchers.push_back( &other );
  2730. return *this;
  2731. }
  2732. std::vector<MatcherBase<ArgT> const*> m_matchers;
  2733. };
  2734. template<typename ArgT>
  2735. struct MatchAnyOf : MatcherBase<ArgT> {
  2736. bool match( ArgT const& arg ) const override {
  2737. for( auto matcher : m_matchers ) {
  2738. if (matcher->match(arg))
  2739. return true;
  2740. }
  2741. return false;
  2742. }
  2743. std::string describe() const override {
  2744. std::string description;
  2745. description.reserve( 4 + m_matchers.size()*32 );
  2746. description += "( ";
  2747. bool first = true;
  2748. for( auto matcher : m_matchers ) {
  2749. if( first )
  2750. first = false;
  2751. else
  2752. description += " or ";
  2753. description += matcher->toString();
  2754. }
  2755. description += " )";
  2756. return description;
  2757. }
  2758. MatchAnyOf<ArgT>& operator || ( MatcherBase<ArgT> const& other ) {
  2759. m_matchers.push_back( &other );
  2760. return *this;
  2761. }
  2762. std::vector<MatcherBase<ArgT> const*> m_matchers;
  2763. };
  2764. template<typename ArgT>
  2765. struct MatchNotOf : MatcherBase<ArgT> {
  2766. MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
  2767. bool match( ArgT const& arg ) const override {
  2768. return !m_underlyingMatcher.match( arg );
  2769. }
  2770. std::string describe() const override {
  2771. return "not " + m_underlyingMatcher.toString();
  2772. }
  2773. MatcherBase<ArgT> const& m_underlyingMatcher;
  2774. };
  2775. template<typename T>
  2776. MatchAllOf<T> MatcherBase<T>::operator && ( MatcherBase const& other ) const {
  2777. return MatchAllOf<T>() && *this && other;
  2778. }
  2779. template<typename T>
  2780. MatchAnyOf<T> MatcherBase<T>::operator || ( MatcherBase const& other ) const {
  2781. return MatchAnyOf<T>() || *this || other;
  2782. }
  2783. template<typename T>
  2784. MatchNotOf<T> MatcherBase<T>::operator ! () const {
  2785. return MatchNotOf<T>( *this );
  2786. }
  2787. } // namespace Impl
  2788. } // namespace Matchers
  2789. using namespace Matchers;
  2790. using Matchers::Impl::MatcherBase;
  2791. } // namespace Catch
  2792. // end catch_matchers.h
  2793. // start catch_matchers_exception.hpp
  2794. namespace Catch {
  2795. namespace Matchers {
  2796. namespace Exception {
  2797. class ExceptionMessageMatcher : public MatcherBase<std::exception> {
  2798. std::string m_message;
  2799. public:
  2800. ExceptionMessageMatcher(std::string const& message):
  2801. m_message(message)
  2802. {}
  2803. bool match(std::exception const& ex) const override;
  2804. std::string describe() const override;
  2805. };
  2806. } // namespace Exception
  2807. Exception::ExceptionMessageMatcher Message(std::string const& message);
  2808. } // namespace Matchers
  2809. } // namespace Catch
  2810. // end catch_matchers_exception.hpp
  2811. // start catch_matchers_floating.h
  2812. namespace Catch {
  2813. namespace Matchers {
  2814. namespace Floating {
  2815. enum class FloatingPointKind : uint8_t;
  2816. struct WithinAbsMatcher : MatcherBase<double> {
  2817. WithinAbsMatcher(double target, double margin);
  2818. bool match(double const& matchee) const override;
  2819. std::string describe() const override;
  2820. private:
  2821. double m_target;
  2822. double m_margin;
  2823. };
  2824. struct WithinUlpsMatcher : MatcherBase<double> {
  2825. WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType);
  2826. bool match(double const& matchee) const override;
  2827. std::string describe() const override;
  2828. private:
  2829. double m_target;
  2830. uint64_t m_ulps;
  2831. FloatingPointKind m_type;
  2832. };
  2833. // Given IEEE-754 format for floats and doubles, we can assume
  2834. // that float -> double promotion is lossless. Given this, we can
  2835. // assume that if we do the standard relative comparison of
  2836. // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get
  2837. // the same result if we do this for floats, as if we do this for
  2838. // doubles that were promoted from floats.
  2839. struct WithinRelMatcher : MatcherBase<double> {
  2840. WithinRelMatcher(double target, double epsilon);
  2841. bool match(double const& matchee) const override;
  2842. std::string describe() const override;
  2843. private:
  2844. double m_target;
  2845. double m_epsilon;
  2846. };
  2847. } // namespace Floating
  2848. // The following functions create the actual matcher objects.
  2849. // This allows the types to be inferred
  2850. Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
  2851. Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
  2852. Floating::WithinAbsMatcher WithinAbs(double target, double margin);
  2853. Floating::WithinRelMatcher WithinRel(double target, double eps);
  2854. // defaults epsilon to 100*numeric_limits<double>::epsilon()
  2855. Floating::WithinRelMatcher WithinRel(double target);
  2856. Floating::WithinRelMatcher WithinRel(float target, float eps);
  2857. // defaults epsilon to 100*numeric_limits<float>::epsilon()
  2858. Floating::WithinRelMatcher WithinRel(float target);
  2859. } // namespace Matchers
  2860. } // namespace Catch
  2861. // end catch_matchers_floating.h
  2862. // start catch_matchers_generic.hpp
  2863. #include <functional>
  2864. #include <string>
  2865. namespace Catch {
  2866. namespace Matchers {
  2867. namespace Generic {
  2868. namespace Detail {
  2869. std::string finalizeDescription(const std::string& desc);
  2870. }
  2871. template <typename T>
  2872. class PredicateMatcher : public MatcherBase<T> {
  2873. std::function<bool(T const&)> m_predicate;
  2874. std::string m_description;
  2875. public:
  2876. PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr)
  2877. :m_predicate(std::move(elem)),
  2878. m_description(Detail::finalizeDescription(descr))
  2879. {}
  2880. bool match( T const& item ) const override {
  2881. return m_predicate(item);
  2882. }
  2883. std::string describe() const override {
  2884. return m_description;
  2885. }
  2886. };
  2887. } // namespace Generic
  2888. // The following functions create the actual matcher objects.
  2889. // The user has to explicitly specify type to the function, because
  2890. // inferring std::function<bool(T const&)> is hard (but possible) and
  2891. // requires a lot of TMP.
  2892. template<typename T>
  2893. Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") {
  2894. return Generic::PredicateMatcher<T>(predicate, description);
  2895. }
  2896. } // namespace Matchers
  2897. } // namespace Catch
  2898. // end catch_matchers_generic.hpp
  2899. // start catch_matchers_string.h
  2900. #include <string>
  2901. namespace Catch {
  2902. namespace Matchers {
  2903. namespace StdString {
  2904. struct CasedString
  2905. {
  2906. CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );
  2907. std::string adjustString( std::string const& str ) const;
  2908. std::string caseSensitivitySuffix() const;
  2909. CaseSensitive::Choice m_caseSensitivity;
  2910. std::string m_str;
  2911. };
  2912. struct StringMatcherBase : MatcherBase<std::string> {
  2913. StringMatcherBase( std::string const& operation, CasedString const& comparator );
  2914. std::string describe() const override;
  2915. CasedString m_comparator;
  2916. std::string m_operation;
  2917. };
  2918. struct EqualsMatcher : StringMatcherBase {
  2919. EqualsMatcher( CasedString const& comparator );
  2920. bool match( std::string const& source ) const override;
  2921. };
  2922. struct ContainsMatcher : StringMatcherBase {
  2923. ContainsMatcher( CasedString const& comparator );
  2924. bool match( std::string const& source ) const override;
  2925. };
  2926. struct StartsWithMatcher : StringMatcherBase {
  2927. StartsWithMatcher( CasedString const& comparator );
  2928. bool match( std::string const& source ) const override;
  2929. };
  2930. struct EndsWithMatcher : StringMatcherBase {
  2931. EndsWithMatcher( CasedString const& comparator );
  2932. bool match( std::string const& source ) const override;
  2933. };
  2934. struct RegexMatcher : MatcherBase<std::string> {
  2935. RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity );
  2936. bool match( std::string const& matchee ) const override;
  2937. std::string describe() const override;
  2938. private:
  2939. std::string m_regex;
  2940. CaseSensitive::Choice m_caseSensitivity;
  2941. };
  2942. } // namespace StdString
  2943. // The following functions create the actual matcher objects.
  2944. // This allows the types to be inferred
  2945. StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
  2946. StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
  2947. StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
  2948. StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
  2949. StdString::RegexMatcher Matches( std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
  2950. } // namespace Matchers
  2951. } // namespace Catch
  2952. // end catch_matchers_string.h
  2953. // start catch_matchers_vector.h
  2954. #include <algorithm>
  2955. namespace Catch {
  2956. namespace Matchers {
  2957. namespace Vector {
  2958. template<typename T>
  2959. struct ContainsElementMatcher : MatcherBase<std::vector<T>> {
  2960. ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
  2961. bool match(std::vector<T> const &v) const override {
  2962. for (auto const& el : v) {
  2963. if (el == m_comparator) {
  2964. return true;
  2965. }
  2966. }
  2967. return false;
  2968. }
  2969. std::string describe() const override {
  2970. return "Contains: " + ::Catch::Detail::stringify( m_comparator );
  2971. }
  2972. T const& m_comparator;
  2973. };
  2974. template<typename T>
  2975. struct ContainsMatcher : MatcherBase<std::vector<T>> {
  2976. ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
  2977. bool match(std::vector<T> const &v) const override {
  2978. // !TBD: see note in EqualsMatcher
  2979. if (m_comparator.size() > v.size())
  2980. return false;
  2981. for (auto const& comparator : m_comparator) {
  2982. auto present = false;
  2983. for (const auto& el : v) {
  2984. if (el == comparator) {
  2985. present = true;
  2986. break;
  2987. }
  2988. }
  2989. if (!present) {
  2990. return false;
  2991. }
  2992. }
  2993. return true;
  2994. }
  2995. std::string describe() const override {
  2996. return "Contains: " + ::Catch::Detail::stringify( m_comparator );
  2997. }
  2998. std::vector<T> const& m_comparator;
  2999. };
  3000. template<typename T>
  3001. struct EqualsMatcher : MatcherBase<std::vector<T>> {
  3002. EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
  3003. bool match(std::vector<T> const &v) const override {
  3004. // !TBD: This currently works if all elements can be compared using !=
  3005. // - a more general approach would be via a compare template that defaults
  3006. // to using !=. but could be specialised for, e.g. std::vector<T> etc
  3007. // - then just call that directly
  3008. if (m_comparator.size() != v.size())
  3009. return false;
  3010. for (std::size_t i = 0; i < v.size(); ++i)
  3011. if (m_comparator[i] != v[i])
  3012. return false;
  3013. return true;
  3014. }
  3015. std::string describe() const override {
  3016. return "Equals: " + ::Catch::Detail::stringify( m_comparator );
  3017. }
  3018. std::vector<T> const& m_comparator;
  3019. };
  3020. template<typename T>
  3021. struct ApproxMatcher : MatcherBase<std::vector<T>> {
  3022. ApproxMatcher(std::vector<T> const& comparator) : m_comparator( comparator ) {}
  3023. bool match(std::vector<T> const &v) const override {
  3024. if (m_comparator.size() != v.size())
  3025. return false;
  3026. for (std::size_t i = 0; i < v.size(); ++i)
  3027. if (m_comparator[i] != approx(v[i]))
  3028. return false;
  3029. return true;
  3030. }
  3031. std::string describe() const override {
  3032. return "is approx: " + ::Catch::Detail::stringify( m_comparator );
  3033. }
  3034. template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  3035. ApproxMatcher& epsilon( T const& newEpsilon ) {
  3036. approx.epsilon(newEpsilon);
  3037. return *this;
  3038. }
  3039. template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  3040. ApproxMatcher& margin( T const& newMargin ) {
  3041. approx.margin(newMargin);
  3042. return *this;
  3043. }
  3044. template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  3045. ApproxMatcher& scale( T const& newScale ) {
  3046. approx.scale(newScale);
  3047. return *this;
  3048. }
  3049. std::vector<T> const& m_comparator;
  3050. mutable Catch::Detail::Approx approx = Catch::Detail::Approx::custom();
  3051. };
  3052. template<typename T>
  3053. struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> {
  3054. UnorderedEqualsMatcher(std::vector<T> const& target) : m_target(target) {}
  3055. bool match(std::vector<T> const& vec) const override {
  3056. // Note: This is a reimplementation of std::is_permutation,
  3057. // because I don't want to include <algorithm> inside the common path
  3058. if (m_target.size() != vec.size()) {
  3059. return false;
  3060. }
  3061. return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
  3062. }
  3063. std::string describe() const override {
  3064. return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
  3065. }
  3066. private:
  3067. std::vector<T> const& m_target;
  3068. };
  3069. } // namespace Vector
  3070. // The following functions create the actual matcher objects.
  3071. // This allows the types to be inferred
  3072. template<typename T>
  3073. Vector::ContainsMatcher<T> Contains( std::vector<T> const& comparator ) {
  3074. return Vector::ContainsMatcher<T>( comparator );
  3075. }
  3076. template<typename T>
  3077. Vector::ContainsElementMatcher<T> VectorContains( T const& comparator ) {
  3078. return Vector::ContainsElementMatcher<T>( comparator );
  3079. }
  3080. template<typename T>
  3081. Vector::EqualsMatcher<T> Equals( std::vector<T> const& comparator ) {
  3082. return Vector::EqualsMatcher<T>( comparator );
  3083. }
  3084. template<typename T>
  3085. Vector::ApproxMatcher<T> Approx( std::vector<T> const& comparator ) {
  3086. return Vector::ApproxMatcher<T>( comparator );
  3087. }
  3088. template<typename T>
  3089. Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const& target) {
  3090. return Vector::UnorderedEqualsMatcher<T>(target);
  3091. }
  3092. } // namespace Matchers
  3093. } // namespace Catch
  3094. // end catch_matchers_vector.h
  3095. namespace Catch {
  3096. template<typename ArgT, typename MatcherT>
  3097. class MatchExpr : public ITransientExpression {
  3098. ArgT const& m_arg;
  3099. MatcherT m_matcher;
  3100. StringRef m_matcherString;
  3101. public:
  3102. MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )
  3103. : ITransientExpression{ true, matcher.match( arg ) },
  3104. m_arg( arg ),
  3105. m_matcher( matcher ),
  3106. m_matcherString( matcherString )
  3107. {}
  3108. void streamReconstructedExpression( std::ostream &os ) const override {
  3109. auto matcherAsString = m_matcher.toString();
  3110. os << Catch::Detail::stringify( m_arg ) << ' ';
  3111. if( matcherAsString == Detail::unprintableString )
  3112. os << m_matcherString;
  3113. else
  3114. os << matcherAsString;
  3115. }
  3116. };
  3117. using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
  3118. void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString );
  3119. template<typename ArgT, typename MatcherT>
  3120. auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString ) -> MatchExpr<ArgT, MatcherT> {
  3121. return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
  3122. }
  3123. } // namespace Catch
  3124. ///////////////////////////////////////////////////////////////////////////////
  3125. #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
  3126. do { \
  3127. Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
  3128. INTERNAL_CATCH_TRY { \
  3129. catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \
  3130. } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
  3131. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  3132. } while( false )
  3133. ///////////////////////////////////////////////////////////////////////////////
  3134. #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
  3135. do { \
  3136. Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
  3137. if( catchAssertionHandler.allowThrows() ) \
  3138. try { \
  3139. static_cast<void>(__VA_ARGS__ ); \
  3140. catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
  3141. } \
  3142. catch( exceptionType const& ex ) { \
  3143. catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \
  3144. } \
  3145. catch( ... ) { \
  3146. catchAssertionHandler.handleUnexpectedInflightException(); \
  3147. } \
  3148. else \
  3149. catchAssertionHandler.handleThrowingCallSkipped(); \
  3150. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  3151. } while( false )
  3152. // end catch_capture_matchers.h
  3153. #endif
  3154. // start catch_generators.hpp
  3155. // start catch_interfaces_generatortracker.h
  3156. #include <memory>
  3157. namespace Catch {
  3158. namespace Generators {
  3159. class GeneratorUntypedBase {
  3160. public:
  3161. GeneratorUntypedBase() = default;
  3162. virtual ~GeneratorUntypedBase();
  3163. // Attempts to move the generator to the next element
  3164. //
  3165. // Returns true iff the move succeeded (and a valid element
  3166. // can be retrieved).
  3167. virtual bool next() = 0;
  3168. };
  3169. using GeneratorBasePtr = std::unique_ptr<GeneratorUntypedBase>;
  3170. } // namespace Generators
  3171. struct IGeneratorTracker {
  3172. virtual ~IGeneratorTracker();
  3173. virtual auto hasGenerator() const -> bool = 0;
  3174. virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;
  3175. virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;
  3176. };
  3177. } // namespace Catch
  3178. // end catch_interfaces_generatortracker.h
  3179. // start catch_enforce.h
  3180. #include <exception>
  3181. namespace Catch {
  3182. #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  3183. template <typename Ex>
  3184. [[noreturn]]
  3185. void throw_exception(Ex const& e) {
  3186. throw e;
  3187. }
  3188. #else // ^^ Exceptions are enabled // Exceptions are disabled vv
  3189. [[noreturn]]
  3190. void throw_exception(std::exception const& e);
  3191. #endif
  3192. [[noreturn]]
  3193. void throw_logic_error(std::string const& msg);
  3194. [[noreturn]]
  3195. void throw_domain_error(std::string const& msg);
  3196. [[noreturn]]
  3197. void throw_runtime_error(std::string const& msg);
  3198. } // namespace Catch;
  3199. #define CATCH_MAKE_MSG(...) \
  3200. (Catch::ReusableStringStream() << __VA_ARGS__).str()
  3201. #define CATCH_INTERNAL_ERROR(...) \
  3202. Catch::throw_logic_error(CATCH_MAKE_MSG( CATCH_INTERNAL_LINEINFO << ": Internal Catch2 error: " << __VA_ARGS__))
  3203. #define CATCH_ERROR(...) \
  3204. Catch::throw_domain_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
  3205. #define CATCH_RUNTIME_ERROR(...) \
  3206. Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
  3207. #define CATCH_ENFORCE( condition, ... ) \
  3208. do{ if( !(condition) ) CATCH_ERROR( __VA_ARGS__ ); } while(false)
  3209. // end catch_enforce.h
  3210. #include <memory>
  3211. #include <vector>
  3212. #include <cassert>
  3213. #include <utility>
  3214. #include <exception>
  3215. namespace Catch {
  3216. class GeneratorException : public std::exception {
  3217. const char* const m_msg = "";
  3218. public:
  3219. GeneratorException(const char* msg):
  3220. m_msg(msg)
  3221. {}
  3222. const char* what() const noexcept override final;
  3223. };
  3224. namespace Generators {
  3225. // !TBD move this into its own location?
  3226. namespace pf{
  3227. template<typename T, typename... Args>
  3228. std::unique_ptr<T> make_unique( Args&&... args ) {
  3229. return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
  3230. }
  3231. }
  3232. template<typename T>
  3233. struct IGenerator : GeneratorUntypedBase {
  3234. virtual ~IGenerator() = default;
  3235. // Returns the current element of the generator
  3236. //
  3237. // \Precondition The generator is either freshly constructed,
  3238. // or the last call to `next()` returned true
  3239. virtual T const& get() const = 0;
  3240. using type = T;
  3241. };
  3242. template<typename T>
  3243. class SingleValueGenerator final : public IGenerator<T> {
  3244. T m_value;
  3245. public:
  3246. SingleValueGenerator(T const& value) : m_value( value ) {}
  3247. SingleValueGenerator(T&& value) : m_value(std::move(value)) {}
  3248. T const& get() const override {
  3249. return m_value;
  3250. }
  3251. bool next() override {
  3252. return false;
  3253. }
  3254. };
  3255. template<typename T>
  3256. class FixedValuesGenerator final : public IGenerator<T> {
  3257. static_assert(!std::is_same<T, bool>::value,
  3258. "FixedValuesGenerator does not support bools because of std::vector<bool>"
  3259. "specialization, use SingleValue Generator instead.");
  3260. std::vector<T> m_values;
  3261. size_t m_idx = 0;
  3262. public:
  3263. FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {}
  3264. T const& get() const override {
  3265. return m_values[m_idx];
  3266. }
  3267. bool next() override {
  3268. ++m_idx;
  3269. return m_idx < m_values.size();
  3270. }
  3271. };
  3272. template <typename T>
  3273. class GeneratorWrapper final {
  3274. std::unique_ptr<IGenerator<T>> m_generator;
  3275. public:
  3276. GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator):
  3277. m_generator(std::move(generator))
  3278. {}
  3279. T const& get() const {
  3280. return m_generator->get();
  3281. }
  3282. bool next() {
  3283. return m_generator->next();
  3284. }
  3285. };
  3286. template <typename T>
  3287. GeneratorWrapper<T> value(T&& value) {
  3288. return GeneratorWrapper<T>(pf::make_unique<SingleValueGenerator<T>>(std::forward<T>(value)));
  3289. }
  3290. template <typename T>
  3291. GeneratorWrapper<T> values(std::initializer_list<T> values) {
  3292. return GeneratorWrapper<T>(pf::make_unique<FixedValuesGenerator<T>>(values));
  3293. }
  3294. template<typename T>
  3295. class Generators : public IGenerator<T> {
  3296. std::vector<GeneratorWrapper<T>> m_generators;
  3297. size_t m_current = 0;
  3298. void populate(GeneratorWrapper<T>&& generator) {
  3299. m_generators.emplace_back(std::move(generator));
  3300. }
  3301. void populate(T&& val) {
  3302. m_generators.emplace_back(value(std::move(val)));
  3303. }
  3304. template<typename U>
  3305. void populate(U&& val) {
  3306. populate(T(std::move(val)));
  3307. }
  3308. template<typename U, typename... Gs>
  3309. void populate(U&& valueOrGenerator, Gs... moreGenerators) {
  3310. populate(std::forward<U>(valueOrGenerator));
  3311. populate(std::forward<Gs>(moreGenerators)...);
  3312. }
  3313. public:
  3314. template <typename... Gs>
  3315. Generators(Gs... moreGenerators) {
  3316. m_generators.reserve(sizeof...(Gs));
  3317. populate(std::forward<Gs>(moreGenerators)...);
  3318. }
  3319. T const& get() const override {
  3320. return m_generators[m_current].get();
  3321. }
  3322. bool next() override {
  3323. if (m_current >= m_generators.size()) {
  3324. return false;
  3325. }
  3326. const bool current_status = m_generators[m_current].next();
  3327. if (!current_status) {
  3328. ++m_current;
  3329. }
  3330. return m_current < m_generators.size();
  3331. }
  3332. };
  3333. template<typename... Ts>
  3334. GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples ) {
  3335. return values<std::tuple<Ts...>>( tuples );
  3336. }
  3337. // Tag type to signal that a generator sequence should convert arguments to a specific type
  3338. template <typename T>
  3339. struct as {};
  3340. template<typename T, typename... Gs>
  3341. auto makeGenerators( GeneratorWrapper<T>&& generator, Gs... moreGenerators ) -> Generators<T> {
  3342. return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...);
  3343. }
  3344. template<typename T>
  3345. auto makeGenerators( GeneratorWrapper<T>&& generator ) -> Generators<T> {
  3346. return Generators<T>(std::move(generator));
  3347. }
  3348. template<typename T, typename... Gs>
  3349. auto makeGenerators( T&& val, Gs... moreGenerators ) -> Generators<T> {
  3350. return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
  3351. }
  3352. template<typename T, typename U, typename... Gs>
  3353. auto makeGenerators( as<T>, U&& val, Gs... moreGenerators ) -> Generators<T> {
  3354. return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
  3355. }
  3356. auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
  3357. template<typename L>
  3358. // Note: The type after -> is weird, because VS2015 cannot parse
  3359. // the expression used in the typedef inside, when it is in
  3360. // return type. Yeah.
  3361. auto generate( SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) {
  3362. using UnderlyingType = typename decltype(generatorExpression())::type;
  3363. IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo );
  3364. if (!tracker.hasGenerator()) {
  3365. tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression()));
  3366. }
  3367. auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() );
  3368. return generator.get();
  3369. }
  3370. } // namespace Generators
  3371. } // namespace Catch
  3372. #define GENERATE( ... ) \
  3373. Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
  3374. #define GENERATE_COPY( ... ) \
  3375. Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
  3376. #define GENERATE_REF( ... ) \
  3377. Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
  3378. // end catch_generators.hpp
  3379. // start catch_generators_generic.hpp
  3380. namespace Catch {
  3381. namespace Generators {
  3382. template <typename T>
  3383. class TakeGenerator : public IGenerator<T> {
  3384. GeneratorWrapper<T> m_generator;
  3385. size_t m_returned = 0;
  3386. size_t m_target;
  3387. public:
  3388. TakeGenerator(size_t target, GeneratorWrapper<T>&& generator):
  3389. m_generator(std::move(generator)),
  3390. m_target(target)
  3391. {
  3392. assert(target != 0 && "Empty generators are not allowed");
  3393. }
  3394. T const& get() const override {
  3395. return m_generator.get();
  3396. }
  3397. bool next() override {
  3398. ++m_returned;
  3399. if (m_returned >= m_target) {
  3400. return false;
  3401. }
  3402. const auto success = m_generator.next();
  3403. // If the underlying generator does not contain enough values
  3404. // then we cut short as well
  3405. if (!success) {
  3406. m_returned = m_target;
  3407. }
  3408. return success;
  3409. }
  3410. };
  3411. template <typename T>
  3412. GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& generator) {
  3413. return GeneratorWrapper<T>(pf::make_unique<TakeGenerator<T>>(target, std::move(generator)));
  3414. }
  3415. template <typename T, typename Predicate>
  3416. class FilterGenerator : public IGenerator<T> {
  3417. GeneratorWrapper<T> m_generator;
  3418. Predicate m_predicate;
  3419. public:
  3420. template <typename P = Predicate>
  3421. FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator):
  3422. m_generator(std::move(generator)),
  3423. m_predicate(std::forward<P>(pred))
  3424. {
  3425. if (!m_predicate(m_generator.get())) {
  3426. // It might happen that there are no values that pass the
  3427. // filter. In that case we throw an exception.
  3428. auto has_initial_value = next();
  3429. if (!has_initial_value) {
  3430. Catch::throw_exception(GeneratorException("No valid value found in filtered generator"));
  3431. }
  3432. }
  3433. }
  3434. T const& get() const override {
  3435. return m_generator.get();
  3436. }
  3437. bool next() override {
  3438. bool success = m_generator.next();
  3439. if (!success) {
  3440. return false;
  3441. }
  3442. while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true);
  3443. return success;
  3444. }
  3445. };
  3446. template <typename T, typename Predicate>
  3447. GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& generator) {
  3448. return GeneratorWrapper<T>(std::unique_ptr<IGenerator<T>>(pf::make_unique<FilterGenerator<T, Predicate>>(std::forward<Predicate>(pred), std::move(generator))));
  3449. }
  3450. template <typename T>
  3451. class RepeatGenerator : public IGenerator<T> {
  3452. static_assert(!std::is_same<T, bool>::value,
  3453. "RepeatGenerator currently does not support bools"
  3454. "because of std::vector<bool> specialization");
  3455. GeneratorWrapper<T> m_generator;
  3456. mutable std::vector<T> m_returned;
  3457. size_t m_target_repeats;
  3458. size_t m_current_repeat = 0;
  3459. size_t m_repeat_index = 0;
  3460. public:
  3461. RepeatGenerator(size_t repeats, GeneratorWrapper<T>&& generator):
  3462. m_generator(std::move(generator)),
  3463. m_target_repeats(repeats)
  3464. {
  3465. assert(m_target_repeats > 0 && "Repeat generator must repeat at least once");
  3466. }
  3467. T const& get() const override {
  3468. if (m_current_repeat == 0) {
  3469. m_returned.push_back(m_generator.get());
  3470. return m_returned.back();
  3471. }
  3472. return m_returned[m_repeat_index];
  3473. }
  3474. bool next() override {
  3475. // There are 2 basic cases:
  3476. // 1) We are still reading the generator
  3477. // 2) We are reading our own cache
  3478. // In the first case, we need to poke the underlying generator.
  3479. // If it happily moves, we are left in that state, otherwise it is time to start reading from our cache
  3480. if (m_current_repeat == 0) {
  3481. const auto success = m_generator.next();
  3482. if (!success) {
  3483. ++m_current_repeat;
  3484. }
  3485. return m_current_repeat < m_target_repeats;
  3486. }
  3487. // In the second case, we need to move indices forward and check that we haven't run up against the end
  3488. ++m_repeat_index;
  3489. if (m_repeat_index == m_returned.size()) {
  3490. m_repeat_index = 0;
  3491. ++m_current_repeat;
  3492. }
  3493. return m_current_repeat < m_target_repeats;
  3494. }
  3495. };
  3496. template <typename T>
  3497. GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& generator) {
  3498. return GeneratorWrapper<T>(pf::make_unique<RepeatGenerator<T>>(repeats, std::move(generator)));
  3499. }
  3500. template <typename T, typename U, typename Func>
  3501. class MapGenerator : public IGenerator<T> {
  3502. // TBD: provide static assert for mapping function, for friendly error message
  3503. GeneratorWrapper<U> m_generator;
  3504. Func m_function;
  3505. // To avoid returning dangling reference, we have to save the values
  3506. T m_cache;
  3507. public:
  3508. template <typename F2 = Func>
  3509. MapGenerator(F2&& function, GeneratorWrapper<U>&& generator) :
  3510. m_generator(std::move(generator)),
  3511. m_function(std::forward<F2>(function)),
  3512. m_cache(m_function(m_generator.get()))
  3513. {}
  3514. T const& get() const override {
  3515. return m_cache;
  3516. }
  3517. bool next() override {
  3518. const auto success = m_generator.next();
  3519. if (success) {
  3520. m_cache = m_function(m_generator.get());
  3521. }
  3522. return success;
  3523. }
  3524. };
  3525. #if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
  3526. // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
  3527. // replaced with std::invoke_result here. Also *_t format is preferred over
  3528. // typename *::type format.
  3529. template <typename Func, typename U>
  3530. using MapFunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U>>>;
  3531. #else
  3532. template <typename Func, typename U>
  3533. using MapFunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U)>::type>::type>::type;
  3534. #endif
  3535. template <typename Func, typename U, typename T = MapFunctionReturnType<Func, U>>
  3536. GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
  3537. return GeneratorWrapper<T>(
  3538. pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
  3539. );
  3540. }
  3541. template <typename T, typename U, typename Func>
  3542. GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
  3543. return GeneratorWrapper<T>(
  3544. pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
  3545. );
  3546. }
  3547. template <typename T>
  3548. class ChunkGenerator final : public IGenerator<std::vector<T>> {
  3549. std::vector<T> m_chunk;
  3550. size_t m_chunk_size;
  3551. GeneratorWrapper<T> m_generator;
  3552. bool m_used_up = false;
  3553. public:
  3554. ChunkGenerator(size_t size, GeneratorWrapper<T> generator) :
  3555. m_chunk_size(size), m_generator(std::move(generator))
  3556. {
  3557. m_chunk.reserve(m_chunk_size);
  3558. if (m_chunk_size != 0) {
  3559. m_chunk.push_back(m_generator.get());
  3560. for (size_t i = 1; i < m_chunk_size; ++i) {
  3561. if (!m_generator.next()) {
  3562. Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk"));
  3563. }
  3564. m_chunk.push_back(m_generator.get());
  3565. }
  3566. }
  3567. }
  3568. std::vector<T> const& get() const override {
  3569. return m_chunk;
  3570. }
  3571. bool next() override {
  3572. m_chunk.clear();
  3573. for (size_t idx = 0; idx < m_chunk_size; ++idx) {
  3574. if (!m_generator.next()) {
  3575. return false;
  3576. }
  3577. m_chunk.push_back(m_generator.get());
  3578. }
  3579. return true;
  3580. }
  3581. };
  3582. template <typename T>
  3583. GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T>&& generator) {
  3584. return GeneratorWrapper<std::vector<T>>(
  3585. pf::make_unique<ChunkGenerator<T>>(size, std::move(generator))
  3586. );
  3587. }
  3588. } // namespace Generators
  3589. } // namespace Catch
  3590. // end catch_generators_generic.hpp
  3591. // start catch_generators_specific.hpp
  3592. // start catch_context.h
  3593. #include <memory>
  3594. namespace Catch {
  3595. struct IResultCapture;
  3596. struct IRunner;
  3597. struct IConfig;
  3598. struct IMutableContext;
  3599. using IConfigPtr = std::shared_ptr<IConfig const>;
  3600. struct IContext
  3601. {
  3602. virtual ~IContext();
  3603. virtual IResultCapture* getResultCapture() = 0;
  3604. virtual IRunner* getRunner() = 0;
  3605. virtual IConfigPtr const& getConfig() const = 0;
  3606. };
  3607. struct IMutableContext : IContext
  3608. {
  3609. virtual ~IMutableContext();
  3610. virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
  3611. virtual void setRunner( IRunner* runner ) = 0;
  3612. virtual void setConfig( IConfigPtr const& config ) = 0;
  3613. private:
  3614. static IMutableContext *currentContext;
  3615. friend IMutableContext& getCurrentMutableContext();
  3616. friend void cleanUpContext();
  3617. static void createContext();
  3618. };
  3619. inline IMutableContext& getCurrentMutableContext()
  3620. {
  3621. if( !IMutableContext::currentContext )
  3622. IMutableContext::createContext();
  3623. // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
  3624. return *IMutableContext::currentContext;
  3625. }
  3626. inline IContext& getCurrentContext()
  3627. {
  3628. return getCurrentMutableContext();
  3629. }
  3630. void cleanUpContext();
  3631. class SimplePcg32;
  3632. SimplePcg32& rng();
  3633. }
  3634. // end catch_context.h
  3635. // start catch_interfaces_config.h
  3636. // start catch_option.hpp
  3637. namespace Catch {
  3638. // An optional type
  3639. template<typename T>
  3640. class Option {
  3641. public:
  3642. Option() : nullableValue( nullptr ) {}
  3643. Option( T const& _value )
  3644. : nullableValue( new( storage ) T( _value ) )
  3645. {}
  3646. Option( Option const& _other )
  3647. : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )
  3648. {}
  3649. ~Option() {
  3650. reset();
  3651. }
  3652. Option& operator= ( Option const& _other ) {
  3653. if( &_other != this ) {
  3654. reset();
  3655. if( _other )
  3656. nullableValue = new( storage ) T( *_other );
  3657. }
  3658. return *this;
  3659. }
  3660. Option& operator = ( T const& _value ) {
  3661. reset();
  3662. nullableValue = new( storage ) T( _value );
  3663. return *this;
  3664. }
  3665. void reset() {
  3666. if( nullableValue )
  3667. nullableValue->~T();
  3668. nullableValue = nullptr;
  3669. }
  3670. T& operator*() { return *nullableValue; }
  3671. T const& operator*() const { return *nullableValue; }
  3672. T* operator->() { return nullableValue; }
  3673. const T* operator->() const { return nullableValue; }
  3674. T valueOr( T const& defaultValue ) const {
  3675. return nullableValue ? *nullableValue : defaultValue;
  3676. }
  3677. bool some() const { return nullableValue != nullptr; }
  3678. bool none() const { return nullableValue == nullptr; }
  3679. bool operator !() const { return nullableValue == nullptr; }
  3680. explicit operator bool() const {
  3681. return some();
  3682. }
  3683. private:
  3684. T *nullableValue;
  3685. alignas(alignof(T)) char storage[sizeof(T)];
  3686. };
  3687. } // end namespace Catch
  3688. // end catch_option.hpp
  3689. #include <iosfwd>
  3690. #include <string>
  3691. #include <vector>
  3692. #include <memory>
  3693. namespace Catch {
  3694. enum class Verbosity {
  3695. Quiet = 0,
  3696. Normal,
  3697. High
  3698. };
  3699. struct WarnAbout { enum What {
  3700. Nothing = 0x00,
  3701. NoAssertions = 0x01,
  3702. NoTests = 0x02
  3703. }; };
  3704. struct ShowDurations { enum OrNot {
  3705. DefaultForReporter,
  3706. Always,
  3707. Never
  3708. }; };
  3709. struct RunTests { enum InWhatOrder {
  3710. InDeclarationOrder,
  3711. InLexicographicalOrder,
  3712. InRandomOrder
  3713. }; };
  3714. struct UseColour { enum YesOrNo {
  3715. Auto,
  3716. Yes,
  3717. No
  3718. }; };
  3719. struct WaitForKeypress { enum When {
  3720. Never,
  3721. BeforeStart = 1,
  3722. BeforeExit = 2,
  3723. BeforeStartAndExit = BeforeStart | BeforeExit
  3724. }; };
  3725. class TestSpec;
  3726. struct IConfig : NonCopyable {
  3727. virtual ~IConfig();
  3728. virtual bool allowThrows() const = 0;
  3729. virtual std::ostream& stream() const = 0;
  3730. virtual std::string name() const = 0;
  3731. virtual bool includeSuccessfulResults() const = 0;
  3732. virtual bool shouldDebugBreak() const = 0;
  3733. virtual bool warnAboutMissingAssertions() const = 0;
  3734. virtual bool warnAboutNoTests() const = 0;
  3735. virtual int abortAfter() const = 0;
  3736. virtual bool showInvisibles() const = 0;
  3737. virtual ShowDurations::OrNot showDurations() const = 0;
  3738. virtual TestSpec const& testSpec() const = 0;
  3739. virtual bool hasTestFilters() const = 0;
  3740. virtual std::vector<std::string> const& getTestsOrTags() const = 0;
  3741. virtual RunTests::InWhatOrder runOrder() const = 0;
  3742. virtual unsigned int rngSeed() const = 0;
  3743. virtual UseColour::YesOrNo useColour() const = 0;
  3744. virtual std::vector<std::string> const& getSectionsToRun() const = 0;
  3745. virtual Verbosity verbosity() const = 0;
  3746. virtual bool benchmarkNoAnalysis() const = 0;
  3747. virtual int benchmarkSamples() const = 0;
  3748. virtual double benchmarkConfidenceInterval() const = 0;
  3749. virtual unsigned int benchmarkResamples() const = 0;
  3750. };
  3751. using IConfigPtr = std::shared_ptr<IConfig const>;
  3752. }
  3753. // end catch_interfaces_config.h
  3754. // start catch_random_number_generator.h
  3755. #include <cstdint>
  3756. namespace Catch {
  3757. // This is a simple implementation of C++11 Uniform Random Number
  3758. // Generator. It does not provide all operators, because Catch2
  3759. // does not use it, but it should behave as expected inside stdlib's
  3760. // distributions.
  3761. // The implementation is based on the PCG family (http://pcg-random.org)
  3762. class SimplePcg32 {
  3763. using state_type = std::uint64_t;
  3764. public:
  3765. using result_type = std::uint32_t;
  3766. static constexpr result_type (min)() {
  3767. return 0;
  3768. }
  3769. static constexpr result_type (max)() {
  3770. return static_cast<result_type>(-1);
  3771. }
  3772. // Provide some default initial state for the default constructor
  3773. SimplePcg32():SimplePcg32(0xed743cc4U) {}
  3774. explicit SimplePcg32(result_type seed_);
  3775. void seed(result_type seed_);
  3776. void discard(uint64_t skip);
  3777. result_type operator()();
  3778. private:
  3779. friend bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
  3780. friend bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
  3781. // In theory we also need operator<< and operator>>
  3782. // In practice we do not use them, so we will skip them for now
  3783. std::uint64_t m_state;
  3784. // This part of the state determines which "stream" of the numbers
  3785. // is chosen -- we take it as a constant for Catch2, so we only
  3786. // need to deal with seeding the main state.
  3787. // Picked by reading 8 bytes from `/dev/random` :-)
  3788. static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL;
  3789. };
  3790. } // end namespace Catch
  3791. // end catch_random_number_generator.h
  3792. #include <random>
  3793. namespace Catch {
  3794. namespace Generators {
  3795. template <typename Float>
  3796. class RandomFloatingGenerator final : public IGenerator<Float> {
  3797. Catch::SimplePcg32& m_rng;
  3798. std::uniform_real_distribution<Float> m_dist;
  3799. Float m_current_number;
  3800. public:
  3801. RandomFloatingGenerator(Float a, Float b):
  3802. m_rng(rng()),
  3803. m_dist(a, b) {
  3804. static_cast<void>(next());
  3805. }
  3806. Float const& get() const override {
  3807. return m_current_number;
  3808. }
  3809. bool next() override {
  3810. m_current_number = m_dist(m_rng);
  3811. return true;
  3812. }
  3813. };
  3814. template <typename Integer>
  3815. class RandomIntegerGenerator final : public IGenerator<Integer> {
  3816. Catch::SimplePcg32& m_rng;
  3817. std::uniform_int_distribution<Integer> m_dist;
  3818. Integer m_current_number;
  3819. public:
  3820. RandomIntegerGenerator(Integer a, Integer b):
  3821. m_rng(rng()),
  3822. m_dist(a, b) {
  3823. static_cast<void>(next());
  3824. }
  3825. Integer const& get() const override {
  3826. return m_current_number;
  3827. }
  3828. bool next() override {
  3829. m_current_number = m_dist(m_rng);
  3830. return true;
  3831. }
  3832. };
  3833. // TODO: Ideally this would be also constrained against the various char types,
  3834. // but I don't expect users to run into that in practice.
  3835. template <typename T>
  3836. typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value,
  3837. GeneratorWrapper<T>>::type
  3838. random(T a, T b) {
  3839. return GeneratorWrapper<T>(
  3840. pf::make_unique<RandomIntegerGenerator<T>>(a, b)
  3841. );
  3842. }
  3843. template <typename T>
  3844. typename std::enable_if<std::is_floating_point<T>::value,
  3845. GeneratorWrapper<T>>::type
  3846. random(T a, T b) {
  3847. return GeneratorWrapper<T>(
  3848. pf::make_unique<RandomFloatingGenerator<T>>(a, b)
  3849. );
  3850. }
  3851. template <typename T>
  3852. class RangeGenerator final : public IGenerator<T> {
  3853. T m_current;
  3854. T m_end;
  3855. T m_step;
  3856. bool m_positive;
  3857. public:
  3858. RangeGenerator(T const& start, T const& end, T const& step):
  3859. m_current(start),
  3860. m_end(end),
  3861. m_step(step),
  3862. m_positive(m_step > T(0))
  3863. {
  3864. assert(m_current != m_end && "Range start and end cannot be equal");
  3865. assert(m_step != T(0) && "Step size cannot be zero");
  3866. assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && "Step moves away from end");
  3867. }
  3868. RangeGenerator(T const& start, T const& end):
  3869. RangeGenerator(start, end, (start < end) ? T(1) : T(-1))
  3870. {}
  3871. T const& get() const override {
  3872. return m_current;
  3873. }
  3874. bool next() override {
  3875. m_current += m_step;
  3876. return (m_positive) ? (m_current < m_end) : (m_current > m_end);
  3877. }
  3878. };
  3879. template <typename T>
  3880. GeneratorWrapper<T> range(T const& start, T const& end, T const& step) {
  3881. static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
  3882. return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end, step));
  3883. }
  3884. template <typename T>
  3885. GeneratorWrapper<T> range(T const& start, T const& end) {
  3886. static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
  3887. return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end));
  3888. }
  3889. template <typename T>
  3890. class IteratorGenerator final : public IGenerator<T> {
  3891. static_assert(!std::is_same<T, bool>::value,
  3892. "IteratorGenerator currently does not support bools"
  3893. "because of std::vector<bool> specialization");
  3894. std::vector<T> m_elems;
  3895. size_t m_current = 0;
  3896. public:
  3897. template <typename InputIterator, typename InputSentinel>
  3898. IteratorGenerator(InputIterator first, InputSentinel last):m_elems(first, last) {
  3899. if (m_elems.empty()) {
  3900. Catch::throw_exception(GeneratorException("IteratorGenerator received no valid values"));
  3901. }
  3902. }
  3903. T const& get() const override {
  3904. return m_elems[m_current];
  3905. }
  3906. bool next() override {
  3907. ++m_current;
  3908. return m_current != m_elems.size();
  3909. }
  3910. };
  3911. template <typename InputIterator,
  3912. typename InputSentinel,
  3913. typename ResultType = typename std::iterator_traits<InputIterator>::value_type>
  3914. GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) {
  3915. return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(from, to));
  3916. }
  3917. template <typename Container,
  3918. typename ResultType = typename Container::value_type>
  3919. GeneratorWrapper<ResultType> from_range(Container const& cnt) {
  3920. return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(cnt.begin(), cnt.end()));
  3921. }
  3922. } // namespace Generators
  3923. } // namespace Catch
  3924. // end catch_generators_specific.hpp
  3925. // These files are included here so the single_include script doesn't put them
  3926. // in the conditionally compiled sections
  3927. // start catch_test_case_info.h
  3928. #include <string>
  3929. #include <vector>
  3930. #include <memory>
  3931. #ifdef __clang__
  3932. #pragma clang diagnostic push
  3933. #pragma clang diagnostic ignored "-Wpadded"
  3934. #endif
  3935. namespace Catch {
  3936. struct ITestInvoker;
  3937. struct TestCaseInfo {
  3938. enum SpecialProperties{
  3939. None = 0,
  3940. IsHidden = 1 << 1,
  3941. ShouldFail = 1 << 2,
  3942. MayFail = 1 << 3,
  3943. Throws = 1 << 4,
  3944. NonPortable = 1 << 5,
  3945. Benchmark = 1 << 6
  3946. };
  3947. TestCaseInfo( std::string const& _name,
  3948. std::string const& _className,
  3949. std::string const& _description,
  3950. std::vector<std::string> const& _tags,
  3951. SourceLineInfo const& _lineInfo );
  3952. friend void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags );
  3953. bool isHidden() const;
  3954. bool throws() const;
  3955. bool okToFail() const;
  3956. bool expectedToFail() const;
  3957. std::string tagsAsString() const;
  3958. std::string name;
  3959. std::string className;
  3960. std::string description;
  3961. std::vector<std::string> tags;
  3962. std::vector<std::string> lcaseTags;
  3963. SourceLineInfo lineInfo;
  3964. SpecialProperties properties;
  3965. };
  3966. class TestCase : public TestCaseInfo {
  3967. public:
  3968. TestCase( ITestInvoker* testCase, TestCaseInfo&& info );
  3969. TestCase withName( std::string const& _newName ) const;
  3970. void invoke() const;
  3971. TestCaseInfo const& getTestCaseInfo() const;
  3972. bool operator == ( TestCase const& other ) const;
  3973. bool operator < ( TestCase const& other ) const;
  3974. private:
  3975. std::shared_ptr<ITestInvoker> test;
  3976. };
  3977. TestCase makeTestCase( ITestInvoker* testCase,
  3978. std::string const& className,
  3979. NameAndTags const& nameAndTags,
  3980. SourceLineInfo const& lineInfo );
  3981. }
  3982. #ifdef __clang__
  3983. #pragma clang diagnostic pop
  3984. #endif
  3985. // end catch_test_case_info.h
  3986. // start catch_interfaces_runner.h
  3987. namespace Catch {
  3988. struct IRunner {
  3989. virtual ~IRunner();
  3990. virtual bool aborting() const = 0;
  3991. };
  3992. }
  3993. // end catch_interfaces_runner.h
  3994. #ifdef __OBJC__
  3995. // start catch_objc.hpp
  3996. #import <objc/runtime.h>
  3997. #include <string>
  3998. // NB. Any general catch headers included here must be included
  3999. // in catch.hpp first to make sure they are included by the single
  4000. // header for non obj-usage
  4001. ///////////////////////////////////////////////////////////////////////////////
  4002. // This protocol is really only here for (self) documenting purposes, since
  4003. // all its methods are optional.
  4004. @protocol OcFixture
  4005. @optional
  4006. -(void) setUp;
  4007. -(void) tearDown;
  4008. @end
  4009. namespace Catch {
  4010. class OcMethod : public ITestInvoker {
  4011. public:
  4012. OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
  4013. virtual void invoke() const {
  4014. id obj = [[m_cls alloc] init];
  4015. performOptionalSelector( obj, @selector(setUp) );
  4016. performOptionalSelector( obj, m_sel );
  4017. performOptionalSelector( obj, @selector(tearDown) );
  4018. arcSafeRelease( obj );
  4019. }
  4020. private:
  4021. virtual ~OcMethod() {}
  4022. Class m_cls;
  4023. SEL m_sel;
  4024. };
  4025. namespace Detail{
  4026. inline std::string getAnnotation( Class cls,
  4027. std::string const& annotationName,
  4028. std::string const& testCaseName ) {
  4029. NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
  4030. SEL sel = NSSelectorFromString( selStr );
  4031. arcSafeRelease( selStr );
  4032. id value = performOptionalSelector( cls, sel );
  4033. if( value )
  4034. return [(NSString*)value UTF8String];
  4035. return "";
  4036. }
  4037. }
  4038. inline std::size_t registerTestMethods() {
  4039. std::size_t noTestMethods = 0;
  4040. int noClasses = objc_getClassList( nullptr, 0 );
  4041. Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
  4042. objc_getClassList( classes, noClasses );
  4043. for( int c = 0; c < noClasses; c++ ) {
  4044. Class cls = classes[c];
  4045. {
  4046. u_int count;
  4047. Method* methods = class_copyMethodList( cls, &count );
  4048. for( u_int m = 0; m < count ; m++ ) {
  4049. SEL selector = method_getName(methods[m]);
  4050. std::string methodName = sel_getName(selector);
  4051. if( startsWith( methodName, "Catch_TestCase_" ) ) {
  4052. std::string testCaseName = methodName.substr( 15 );
  4053. std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
  4054. std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
  4055. const char* className = class_getName( cls );
  4056. getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo("",0) ) );
  4057. noTestMethods++;
  4058. }
  4059. }
  4060. free(methods);
  4061. }
  4062. }
  4063. return noTestMethods;
  4064. }
  4065. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  4066. namespace Matchers {
  4067. namespace Impl {
  4068. namespace NSStringMatchers {
  4069. struct StringHolder : MatcherBase<NSString*>{
  4070. StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
  4071. StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
  4072. StringHolder() {
  4073. arcSafeRelease( m_substr );
  4074. }
  4075. bool match( NSString* str ) const override {
  4076. return false;
  4077. }
  4078. NSString* CATCH_ARC_STRONG m_substr;
  4079. };
  4080. struct Equals : StringHolder {
  4081. Equals( NSString* substr ) : StringHolder( substr ){}
  4082. bool match( NSString* str ) const override {
  4083. return (str != nil || m_substr == nil ) &&
  4084. [str isEqualToString:m_substr];
  4085. }
  4086. std::string describe() const override {
  4087. return "equals string: " + Catch::Detail::stringify( m_substr );
  4088. }
  4089. };
  4090. struct Contains : StringHolder {
  4091. Contains( NSString* substr ) : StringHolder( substr ){}
  4092. bool match( NSString* str ) const override {
  4093. return (str != nil || m_substr == nil ) &&
  4094. [str rangeOfString:m_substr].location != NSNotFound;
  4095. }
  4096. std::string describe() const override {
  4097. return "contains string: " + Catch::Detail::stringify( m_substr );
  4098. }
  4099. };
  4100. struct StartsWith : StringHolder {
  4101. StartsWith( NSString* substr ) : StringHolder( substr ){}
  4102. bool match( NSString* str ) const override {
  4103. return (str != nil || m_substr == nil ) &&
  4104. [str rangeOfString:m_substr].location == 0;
  4105. }
  4106. std::string describe() const override {
  4107. return "starts with: " + Catch::Detail::stringify( m_substr );
  4108. }
  4109. };
  4110. struct EndsWith : StringHolder {
  4111. EndsWith( NSString* substr ) : StringHolder( substr ){}
  4112. bool match( NSString* str ) const override {
  4113. return (str != nil || m_substr == nil ) &&
  4114. [str rangeOfString:m_substr].location == [str length] - [m_substr length];
  4115. }
  4116. std::string describe() const override {
  4117. return "ends with: " + Catch::Detail::stringify( m_substr );
  4118. }
  4119. };
  4120. } // namespace NSStringMatchers
  4121. } // namespace Impl
  4122. inline Impl::NSStringMatchers::Equals
  4123. Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
  4124. inline Impl::NSStringMatchers::Contains
  4125. Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
  4126. inline Impl::NSStringMatchers::StartsWith
  4127. StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
  4128. inline Impl::NSStringMatchers::EndsWith
  4129. EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
  4130. } // namespace Matchers
  4131. using namespace Matchers;
  4132. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  4133. } // namespace Catch
  4134. ///////////////////////////////////////////////////////////////////////////////
  4135. #define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix
  4136. #define OC_TEST_CASE2( name, desc, uniqueSuffix ) \
  4137. +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \
  4138. { \
  4139. return @ name; \
  4140. } \
  4141. +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \
  4142. { \
  4143. return @ desc; \
  4144. } \
  4145. -(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )
  4146. #define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )
  4147. // end catch_objc.hpp
  4148. #endif
  4149. // Benchmarking needs the externally-facing parts of reporters to work
  4150. #if defined(CATCH_CONFIG_EXTERNAL_INTERFACES) || defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  4151. // start catch_external_interfaces.h
  4152. // start catch_reporter_bases.hpp
  4153. // start catch_interfaces_reporter.h
  4154. // start catch_config.hpp
  4155. // start catch_test_spec_parser.h
  4156. #ifdef __clang__
  4157. #pragma clang diagnostic push
  4158. #pragma clang diagnostic ignored "-Wpadded"
  4159. #endif
  4160. // start catch_test_spec.h
  4161. #ifdef __clang__
  4162. #pragma clang diagnostic push
  4163. #pragma clang diagnostic ignored "-Wpadded"
  4164. #endif
  4165. // start catch_wildcard_pattern.h
  4166. namespace Catch
  4167. {
  4168. class WildcardPattern {
  4169. enum WildcardPosition {
  4170. NoWildcard = 0,
  4171. WildcardAtStart = 1,
  4172. WildcardAtEnd = 2,
  4173. WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
  4174. };
  4175. public:
  4176. WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity );
  4177. virtual ~WildcardPattern() = default;
  4178. virtual bool matches( std::string const& str ) const;
  4179. private:
  4180. std::string normaliseString( std::string const& str ) const;
  4181. CaseSensitive::Choice m_caseSensitivity;
  4182. WildcardPosition m_wildcard = NoWildcard;
  4183. std::string m_pattern;
  4184. };
  4185. }
  4186. // end catch_wildcard_pattern.h
  4187. #include <string>
  4188. #include <vector>
  4189. #include <memory>
  4190. namespace Catch {
  4191. struct IConfig;
  4192. class TestSpec {
  4193. class Pattern {
  4194. public:
  4195. explicit Pattern( std::string const& name );
  4196. virtual ~Pattern();
  4197. virtual bool matches( TestCaseInfo const& testCase ) const = 0;
  4198. std::string const& name() const;
  4199. private:
  4200. std::string const m_name;
  4201. };
  4202. using PatternPtr = std::shared_ptr<Pattern>;
  4203. class NamePattern : public Pattern {
  4204. public:
  4205. explicit NamePattern( std::string const& name, std::string const& filterString );
  4206. bool matches( TestCaseInfo const& testCase ) const override;
  4207. private:
  4208. WildcardPattern m_wildcardPattern;
  4209. };
  4210. class TagPattern : public Pattern {
  4211. public:
  4212. explicit TagPattern( std::string const& tag, std::string const& filterString );
  4213. bool matches( TestCaseInfo const& testCase ) const override;
  4214. private:
  4215. std::string m_tag;
  4216. };
  4217. class ExcludedPattern : public Pattern {
  4218. public:
  4219. explicit ExcludedPattern( PatternPtr const& underlyingPattern );
  4220. bool matches( TestCaseInfo const& testCase ) const override;
  4221. private:
  4222. PatternPtr m_underlyingPattern;
  4223. };
  4224. struct Filter {
  4225. std::vector<PatternPtr> m_patterns;
  4226. bool matches( TestCaseInfo const& testCase ) const;
  4227. std::string name() const;
  4228. };
  4229. public:
  4230. struct FilterMatch {
  4231. std::string name;
  4232. std::vector<TestCase const*> tests;
  4233. };
  4234. using Matches = std::vector<FilterMatch>;
  4235. using vectorStrings = std::vector<std::string>;
  4236. bool hasFilters() const;
  4237. bool matches( TestCaseInfo const& testCase ) const;
  4238. Matches matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const;
  4239. const vectorStrings & getInvalidArgs() const;
  4240. private:
  4241. std::vector<Filter> m_filters;
  4242. std::vector<std::string> m_invalidArgs;
  4243. friend class TestSpecParser;
  4244. };
  4245. }
  4246. #ifdef __clang__
  4247. #pragma clang diagnostic pop
  4248. #endif
  4249. // end catch_test_spec.h
  4250. // start catch_interfaces_tag_alias_registry.h
  4251. #include <string>
  4252. namespace Catch {
  4253. struct TagAlias;
  4254. struct ITagAliasRegistry {
  4255. virtual ~ITagAliasRegistry();
  4256. // Nullptr if not present
  4257. virtual TagAlias const* find( std::string const& alias ) const = 0;
  4258. virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
  4259. static ITagAliasRegistry const& get();
  4260. };
  4261. } // end namespace Catch
  4262. // end catch_interfaces_tag_alias_registry.h
  4263. namespace Catch {
  4264. class TestSpecParser {
  4265. enum Mode{ None, Name, QuotedName, Tag, EscapedName };
  4266. Mode m_mode = None;
  4267. Mode lastMode = None;
  4268. bool m_exclusion = false;
  4269. std::size_t m_pos = 0;
  4270. std::size_t m_realPatternPos = 0;
  4271. std::string m_arg;
  4272. std::string m_substring;
  4273. std::string m_patternName;
  4274. std::vector<std::size_t> m_escapeChars;
  4275. TestSpec::Filter m_currentFilter;
  4276. TestSpec m_testSpec;
  4277. ITagAliasRegistry const* m_tagAliases = nullptr;
  4278. public:
  4279. TestSpecParser( ITagAliasRegistry const& tagAliases );
  4280. TestSpecParser& parse( std::string const& arg );
  4281. TestSpec testSpec();
  4282. private:
  4283. bool visitChar( char c );
  4284. void startNewMode( Mode mode );
  4285. bool processNoneChar( char c );
  4286. void processNameChar( char c );
  4287. bool processOtherChar( char c );
  4288. void endMode();
  4289. void escape();
  4290. bool isControlChar( char c ) const;
  4291. void saveLastMode();
  4292. void revertBackToLastMode();
  4293. void addFilter();
  4294. bool separate();
  4295. template<typename T>
  4296. void addPattern() {
  4297. std::string token = m_patternName;
  4298. for( std::size_t i = 0; i < m_escapeChars.size(); ++i )
  4299. token = token.substr( 0, m_escapeChars[i] - i ) + token.substr( m_escapeChars[i] -i +1 );
  4300. m_escapeChars.clear();
  4301. if( startsWith( token, "exclude:" ) ) {
  4302. m_exclusion = true;
  4303. token = token.substr( 8 );
  4304. }
  4305. if( !token.empty() ) {
  4306. TestSpec::PatternPtr pattern = std::make_shared<T>( token, m_substring );
  4307. if( m_exclusion )
  4308. pattern = std::make_shared<TestSpec::ExcludedPattern>( pattern );
  4309. m_currentFilter.m_patterns.push_back( pattern );
  4310. }
  4311. m_substring.clear();
  4312. m_patternName.clear();
  4313. m_exclusion = false;
  4314. m_mode = None;
  4315. }
  4316. inline void addCharToPattern(char c) {
  4317. m_substring += c;
  4318. m_patternName += c;
  4319. m_realPatternPos++;
  4320. }
  4321. };
  4322. TestSpec parseTestSpec( std::string const& arg );
  4323. } // namespace Catch
  4324. #ifdef __clang__
  4325. #pragma clang diagnostic pop
  4326. #endif
  4327. // end catch_test_spec_parser.h
  4328. // Libstdc++ doesn't like incomplete classes for unique_ptr
  4329. #include <memory>
  4330. #include <vector>
  4331. #include <string>
  4332. #ifndef CATCH_CONFIG_CONSOLE_WIDTH
  4333. #define CATCH_CONFIG_CONSOLE_WIDTH 80
  4334. #endif
  4335. namespace Catch {
  4336. struct IStream;
  4337. struct ConfigData {
  4338. bool listTests = false;
  4339. bool listTags = false;
  4340. bool listReporters = false;
  4341. bool listTestNamesOnly = false;
  4342. bool showSuccessfulTests = false;
  4343. bool shouldDebugBreak = false;
  4344. bool noThrow = false;
  4345. bool showHelp = false;
  4346. bool showInvisibles = false;
  4347. bool filenamesAsTags = false;
  4348. bool libIdentify = false;
  4349. int abortAfter = -1;
  4350. unsigned int rngSeed = 0;
  4351. bool benchmarkNoAnalysis = false;
  4352. unsigned int benchmarkSamples = 100;
  4353. double benchmarkConfidenceInterval = 0.95;
  4354. unsigned int benchmarkResamples = 100000;
  4355. Verbosity verbosity = Verbosity::Normal;
  4356. WarnAbout::What warnings = WarnAbout::Nothing;
  4357. ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
  4358. RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
  4359. UseColour::YesOrNo useColour = UseColour::Auto;
  4360. WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
  4361. std::string outputFilename;
  4362. std::string name;
  4363. std::string processName;
  4364. #ifndef CATCH_CONFIG_DEFAULT_REPORTER
  4365. #define CATCH_CONFIG_DEFAULT_REPORTER "console"
  4366. #endif
  4367. std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;
  4368. #undef CATCH_CONFIG_DEFAULT_REPORTER
  4369. std::vector<std::string> testsOrTags;
  4370. std::vector<std::string> sectionsToRun;
  4371. };
  4372. class Config : public IConfig {
  4373. public:
  4374. Config() = default;
  4375. Config( ConfigData const& data );
  4376. virtual ~Config() = default;
  4377. std::string const& getFilename() const;
  4378. bool listTests() const;
  4379. bool listTestNamesOnly() const;
  4380. bool listTags() const;
  4381. bool listReporters() const;
  4382. std::string getProcessName() const;
  4383. std::string const& getReporterName() const;
  4384. std::vector<std::string> const& getTestsOrTags() const override;
  4385. std::vector<std::string> const& getSectionsToRun() const override;
  4386. TestSpec const& testSpec() const override;
  4387. bool hasTestFilters() const override;
  4388. bool showHelp() const;
  4389. // IConfig interface
  4390. bool allowThrows() const override;
  4391. std::ostream& stream() const override;
  4392. std::string name() const override;
  4393. bool includeSuccessfulResults() const override;
  4394. bool warnAboutMissingAssertions() const override;
  4395. bool warnAboutNoTests() const override;
  4396. ShowDurations::OrNot showDurations() const override;
  4397. RunTests::InWhatOrder runOrder() const override;
  4398. unsigned int rngSeed() const override;
  4399. UseColour::YesOrNo useColour() const override;
  4400. bool shouldDebugBreak() const override;
  4401. int abortAfter() const override;
  4402. bool showInvisibles() const override;
  4403. Verbosity verbosity() const override;
  4404. bool benchmarkNoAnalysis() const override;
  4405. int benchmarkSamples() const override;
  4406. double benchmarkConfidenceInterval() const override;
  4407. unsigned int benchmarkResamples() const override;
  4408. private:
  4409. IStream const* openStream();
  4410. ConfigData m_data;
  4411. std::unique_ptr<IStream const> m_stream;
  4412. TestSpec m_testSpec;
  4413. bool m_hasTestFilters = false;
  4414. };
  4415. } // end namespace Catch
  4416. // end catch_config.hpp
  4417. // start catch_assertionresult.h
  4418. #include <string>
  4419. namespace Catch {
  4420. struct AssertionResultData
  4421. {
  4422. AssertionResultData() = delete;
  4423. AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression );
  4424. std::string message;
  4425. mutable std::string reconstructedExpression;
  4426. LazyExpression lazyExpression;
  4427. ResultWas::OfType resultType;
  4428. std::string reconstructExpression() const;
  4429. };
  4430. class AssertionResult {
  4431. public:
  4432. AssertionResult() = delete;
  4433. AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
  4434. bool isOk() const;
  4435. bool succeeded() const;
  4436. ResultWas::OfType getResultType() const;
  4437. bool hasExpression() const;
  4438. bool hasMessage() const;
  4439. std::string getExpression() const;
  4440. std::string getExpressionInMacro() const;
  4441. bool hasExpandedExpression() const;
  4442. std::string getExpandedExpression() const;
  4443. std::string getMessage() const;
  4444. SourceLineInfo getSourceInfo() const;
  4445. StringRef getTestMacroName() const;
  4446. //protected:
  4447. AssertionInfo m_info;
  4448. AssertionResultData m_resultData;
  4449. };
  4450. } // end namespace Catch
  4451. // end catch_assertionresult.h
  4452. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  4453. // start catch_estimate.hpp
  4454. // Statistics estimates
  4455. namespace Catch {
  4456. namespace Benchmark {
  4457. template <typename Duration>
  4458. struct Estimate {
  4459. Duration point;
  4460. Duration lower_bound;
  4461. Duration upper_bound;
  4462. double confidence_interval;
  4463. template <typename Duration2>
  4464. operator Estimate<Duration2>() const {
  4465. return { point, lower_bound, upper_bound, confidence_interval };
  4466. }
  4467. };
  4468. } // namespace Benchmark
  4469. } // namespace Catch
  4470. // end catch_estimate.hpp
  4471. // start catch_outlier_classification.hpp
  4472. // Outlier information
  4473. namespace Catch {
  4474. namespace Benchmark {
  4475. struct OutlierClassification {
  4476. int samples_seen = 0;
  4477. int low_severe = 0; // more than 3 times IQR below Q1
  4478. int low_mild = 0; // 1.5 to 3 times IQR below Q1
  4479. int high_mild = 0; // 1.5 to 3 times IQR above Q3
  4480. int high_severe = 0; // more than 3 times IQR above Q3
  4481. int total() const {
  4482. return low_severe + low_mild + high_mild + high_severe;
  4483. }
  4484. };
  4485. } // namespace Benchmark
  4486. } // namespace Catch
  4487. // end catch_outlier_classification.hpp
  4488. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  4489. #include <string>
  4490. #include <iosfwd>
  4491. #include <map>
  4492. #include <set>
  4493. #include <memory>
  4494. #include <algorithm>
  4495. namespace Catch {
  4496. struct ReporterConfig {
  4497. explicit ReporterConfig( IConfigPtr const& _fullConfig );
  4498. ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream );
  4499. std::ostream& stream() const;
  4500. IConfigPtr fullConfig() const;
  4501. private:
  4502. std::ostream* m_stream;
  4503. IConfigPtr m_fullConfig;
  4504. };
  4505. struct ReporterPreferences {
  4506. bool shouldRedirectStdOut = false;
  4507. bool shouldReportAllAssertions = false;
  4508. };
  4509. template<typename T>
  4510. struct LazyStat : Option<T> {
  4511. LazyStat& operator=( T const& _value ) {
  4512. Option<T>::operator=( _value );
  4513. used = false;
  4514. return *this;
  4515. }
  4516. void reset() {
  4517. Option<T>::reset();
  4518. used = false;
  4519. }
  4520. bool used = false;
  4521. };
  4522. struct TestRunInfo {
  4523. TestRunInfo( std::string const& _name );
  4524. std::string name;
  4525. };
  4526. struct GroupInfo {
  4527. GroupInfo( std::string const& _name,
  4528. std::size_t _groupIndex,
  4529. std::size_t _groupsCount );
  4530. std::string name;
  4531. std::size_t groupIndex;
  4532. std::size_t groupsCounts;
  4533. };
  4534. struct AssertionStats {
  4535. AssertionStats( AssertionResult const& _assertionResult,
  4536. std::vector<MessageInfo> const& _infoMessages,
  4537. Totals const& _totals );
  4538. AssertionStats( AssertionStats const& ) = default;
  4539. AssertionStats( AssertionStats && ) = default;
  4540. AssertionStats& operator = ( AssertionStats const& ) = delete;
  4541. AssertionStats& operator = ( AssertionStats && ) = delete;
  4542. virtual ~AssertionStats();
  4543. AssertionResult assertionResult;
  4544. std::vector<MessageInfo> infoMessages;
  4545. Totals totals;
  4546. };
  4547. struct SectionStats {
  4548. SectionStats( SectionInfo const& _sectionInfo,
  4549. Counts const& _assertions,
  4550. double _durationInSeconds,
  4551. bool _missingAssertions );
  4552. SectionStats( SectionStats const& ) = default;
  4553. SectionStats( SectionStats && ) = default;
  4554. SectionStats& operator = ( SectionStats const& ) = default;
  4555. SectionStats& operator = ( SectionStats && ) = default;
  4556. virtual ~SectionStats();
  4557. SectionInfo sectionInfo;
  4558. Counts assertions;
  4559. double durationInSeconds;
  4560. bool missingAssertions;
  4561. };
  4562. struct TestCaseStats {
  4563. TestCaseStats( TestCaseInfo const& _testInfo,
  4564. Totals const& _totals,
  4565. std::string const& _stdOut,
  4566. std::string const& _stdErr,
  4567. bool _aborting );
  4568. TestCaseStats( TestCaseStats const& ) = default;
  4569. TestCaseStats( TestCaseStats && ) = default;
  4570. TestCaseStats& operator = ( TestCaseStats const& ) = default;
  4571. TestCaseStats& operator = ( TestCaseStats && ) = default;
  4572. virtual ~TestCaseStats();
  4573. TestCaseInfo testInfo;
  4574. Totals totals;
  4575. std::string stdOut;
  4576. std::string stdErr;
  4577. bool aborting;
  4578. };
  4579. struct TestGroupStats {
  4580. TestGroupStats( GroupInfo const& _groupInfo,
  4581. Totals const& _totals,
  4582. bool _aborting );
  4583. TestGroupStats( GroupInfo const& _groupInfo );
  4584. TestGroupStats( TestGroupStats const& ) = default;
  4585. TestGroupStats( TestGroupStats && ) = default;
  4586. TestGroupStats& operator = ( TestGroupStats const& ) = default;
  4587. TestGroupStats& operator = ( TestGroupStats && ) = default;
  4588. virtual ~TestGroupStats();
  4589. GroupInfo groupInfo;
  4590. Totals totals;
  4591. bool aborting;
  4592. };
  4593. struct TestRunStats {
  4594. TestRunStats( TestRunInfo const& _runInfo,
  4595. Totals const& _totals,
  4596. bool _aborting );
  4597. TestRunStats( TestRunStats const& ) = default;
  4598. TestRunStats( TestRunStats && ) = default;
  4599. TestRunStats& operator = ( TestRunStats const& ) = default;
  4600. TestRunStats& operator = ( TestRunStats && ) = default;
  4601. virtual ~TestRunStats();
  4602. TestRunInfo runInfo;
  4603. Totals totals;
  4604. bool aborting;
  4605. };
  4606. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  4607. struct BenchmarkInfo {
  4608. std::string name;
  4609. double estimatedDuration;
  4610. int iterations;
  4611. int samples;
  4612. unsigned int resamples;
  4613. double clockResolution;
  4614. double clockCost;
  4615. };
  4616. template <class Duration>
  4617. struct BenchmarkStats {
  4618. BenchmarkInfo info;
  4619. std::vector<Duration> samples;
  4620. Benchmark::Estimate<Duration> mean;
  4621. Benchmark::Estimate<Duration> standardDeviation;
  4622. Benchmark::OutlierClassification outliers;
  4623. double outlierVariance;
  4624. template <typename Duration2>
  4625. operator BenchmarkStats<Duration2>() const {
  4626. std::vector<Duration2> samples2;
  4627. samples2.reserve(samples.size());
  4628. std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
  4629. return {
  4630. info,
  4631. std::move(samples2),
  4632. mean,
  4633. standardDeviation,
  4634. outliers,
  4635. outlierVariance,
  4636. };
  4637. }
  4638. };
  4639. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  4640. struct IStreamingReporter {
  4641. virtual ~IStreamingReporter() = default;
  4642. // Implementing class must also provide the following static methods:
  4643. // static std::string getDescription();
  4644. // static std::set<Verbosity> getSupportedVerbosities()
  4645. virtual ReporterPreferences getPreferences() const = 0;
  4646. virtual void noMatchingTestCases( std::string const& spec ) = 0;
  4647. virtual void reportInvalidArguments(std::string const&) {}
  4648. virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
  4649. virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
  4650. virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
  4651. virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
  4652. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  4653. virtual void benchmarkPreparing( std::string const& ) {}
  4654. virtual void benchmarkStarting( BenchmarkInfo const& ) {}
  4655. virtual void benchmarkEnded( BenchmarkStats<> const& ) {}
  4656. virtual void benchmarkFailed( std::string const& ) {}
  4657. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  4658. virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
  4659. // The return value indicates if the messages buffer should be cleared:
  4660. virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
  4661. virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
  4662. virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
  4663. virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
  4664. virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
  4665. virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
  4666. // Default empty implementation provided
  4667. virtual void fatalErrorEncountered( StringRef name );
  4668. virtual bool isMulti() const;
  4669. };
  4670. using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;
  4671. struct IReporterFactory {
  4672. virtual ~IReporterFactory();
  4673. virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0;
  4674. virtual std::string getDescription() const = 0;
  4675. };
  4676. using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
  4677. struct IReporterRegistry {
  4678. using FactoryMap = std::map<std::string, IReporterFactoryPtr>;
  4679. using Listeners = std::vector<IReporterFactoryPtr>;
  4680. virtual ~IReporterRegistry();
  4681. virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0;
  4682. virtual FactoryMap const& getFactories() const = 0;
  4683. virtual Listeners const& getListeners() const = 0;
  4684. };
  4685. } // end namespace Catch
  4686. // end catch_interfaces_reporter.h
  4687. #include <algorithm>
  4688. #include <cstring>
  4689. #include <cfloat>
  4690. #include <cstdio>
  4691. #include <cassert>
  4692. #include <memory>
  4693. #include <ostream>
  4694. namespace Catch {
  4695. void prepareExpandedExpression(AssertionResult& result);
  4696. // Returns double formatted as %.3f (format expected on output)
  4697. std::string getFormattedDuration( double duration );
  4698. std::string serializeFilters( std::vector<std::string> const& container );
  4699. template<typename DerivedT>
  4700. struct StreamingReporterBase : IStreamingReporter {
  4701. StreamingReporterBase( ReporterConfig const& _config )
  4702. : m_config( _config.fullConfig() ),
  4703. stream( _config.stream() )
  4704. {
  4705. m_reporterPrefs.shouldRedirectStdOut = false;
  4706. if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
  4707. CATCH_ERROR( "Verbosity level not supported by this reporter" );
  4708. }
  4709. ReporterPreferences getPreferences() const override {
  4710. return m_reporterPrefs;
  4711. }
  4712. static std::set<Verbosity> getSupportedVerbosities() {
  4713. return { Verbosity::Normal };
  4714. }
  4715. ~StreamingReporterBase() override = default;
  4716. void noMatchingTestCases(std::string const&) override {}
  4717. void reportInvalidArguments(std::string const&) override {}
  4718. void testRunStarting(TestRunInfo const& _testRunInfo) override {
  4719. currentTestRunInfo = _testRunInfo;
  4720. }
  4721. void testGroupStarting(GroupInfo const& _groupInfo) override {
  4722. currentGroupInfo = _groupInfo;
  4723. }
  4724. void testCaseStarting(TestCaseInfo const& _testInfo) override {
  4725. currentTestCaseInfo = _testInfo;
  4726. }
  4727. void sectionStarting(SectionInfo const& _sectionInfo) override {
  4728. m_sectionStack.push_back(_sectionInfo);
  4729. }
  4730. void sectionEnded(SectionStats const& /* _sectionStats */) override {
  4731. m_sectionStack.pop_back();
  4732. }
  4733. void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {
  4734. currentTestCaseInfo.reset();
  4735. }
  4736. void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override {
  4737. currentGroupInfo.reset();
  4738. }
  4739. void testRunEnded(TestRunStats const& /* _testRunStats */) override {
  4740. currentTestCaseInfo.reset();
  4741. currentGroupInfo.reset();
  4742. currentTestRunInfo.reset();
  4743. }
  4744. void skipTest(TestCaseInfo const&) override {
  4745. // Don't do anything with this by default.
  4746. // It can optionally be overridden in the derived class.
  4747. }
  4748. IConfigPtr m_config;
  4749. std::ostream& stream;
  4750. LazyStat<TestRunInfo> currentTestRunInfo;
  4751. LazyStat<GroupInfo> currentGroupInfo;
  4752. LazyStat<TestCaseInfo> currentTestCaseInfo;
  4753. std::vector<SectionInfo> m_sectionStack;
  4754. ReporterPreferences m_reporterPrefs;
  4755. };
  4756. template<typename DerivedT>
  4757. struct CumulativeReporterBase : IStreamingReporter {
  4758. template<typename T, typename ChildNodeT>
  4759. struct Node {
  4760. explicit Node( T const& _value ) : value( _value ) {}
  4761. virtual ~Node() {}
  4762. using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;
  4763. T value;
  4764. ChildNodes children;
  4765. };
  4766. struct SectionNode {
  4767. explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
  4768. virtual ~SectionNode() = default;
  4769. bool operator == (SectionNode const& other) const {
  4770. return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
  4771. }
  4772. bool operator == (std::shared_ptr<SectionNode> const& other) const {
  4773. return operator==(*other);
  4774. }
  4775. SectionStats stats;
  4776. using ChildSections = std::vector<std::shared_ptr<SectionNode>>;
  4777. using Assertions = std::vector<AssertionStats>;
  4778. ChildSections childSections;
  4779. Assertions assertions;
  4780. std::string stdOut;
  4781. std::string stdErr;
  4782. };
  4783. struct BySectionInfo {
  4784. BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
  4785. BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
  4786. bool operator() (std::shared_ptr<SectionNode> const& node) const {
  4787. return ((node->stats.sectionInfo.name == m_other.name) &&
  4788. (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
  4789. }
  4790. void operator=(BySectionInfo const&) = delete;
  4791. private:
  4792. SectionInfo const& m_other;
  4793. };
  4794. using TestCaseNode = Node<TestCaseStats, SectionNode>;
  4795. using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
  4796. using TestRunNode = Node<TestRunStats, TestGroupNode>;
  4797. CumulativeReporterBase( ReporterConfig const& _config )
  4798. : m_config( _config.fullConfig() ),
  4799. stream( _config.stream() )
  4800. {
  4801. m_reporterPrefs.shouldRedirectStdOut = false;
  4802. if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
  4803. CATCH_ERROR( "Verbosity level not supported by this reporter" );
  4804. }
  4805. ~CumulativeReporterBase() override = default;
  4806. ReporterPreferences getPreferences() const override {
  4807. return m_reporterPrefs;
  4808. }
  4809. static std::set<Verbosity> getSupportedVerbosities() {
  4810. return { Verbosity::Normal };
  4811. }
  4812. void testRunStarting( TestRunInfo const& ) override {}
  4813. void testGroupStarting( GroupInfo const& ) override {}
  4814. void testCaseStarting( TestCaseInfo const& ) override {}
  4815. void sectionStarting( SectionInfo const& sectionInfo ) override {
  4816. SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
  4817. std::shared_ptr<SectionNode> node;
  4818. if( m_sectionStack.empty() ) {
  4819. if( !m_rootSection )
  4820. m_rootSection = std::make_shared<SectionNode>( incompleteStats );
  4821. node = m_rootSection;
  4822. }
  4823. else {
  4824. SectionNode& parentNode = *m_sectionStack.back();
  4825. auto it =
  4826. std::find_if( parentNode.childSections.begin(),
  4827. parentNode.childSections.end(),
  4828. BySectionInfo( sectionInfo ) );
  4829. if( it == parentNode.childSections.end() ) {
  4830. node = std::make_shared<SectionNode>( incompleteStats );
  4831. parentNode.childSections.push_back( node );
  4832. }
  4833. else
  4834. node = *it;
  4835. }
  4836. m_sectionStack.push_back( node );
  4837. m_deepestSection = std::move(node);
  4838. }
  4839. void assertionStarting(AssertionInfo const&) override {}
  4840. bool assertionEnded(AssertionStats const& assertionStats) override {
  4841. assert(!m_sectionStack.empty());
  4842. // AssertionResult holds a pointer to a temporary DecomposedExpression,
  4843. // which getExpandedExpression() calls to build the expression string.
  4844. // Our section stack copy of the assertionResult will likely outlive the
  4845. // temporary, so it must be expanded or discarded now to avoid calling
  4846. // a destroyed object later.
  4847. prepareExpandedExpression(const_cast<AssertionResult&>( assertionStats.assertionResult ) );
  4848. SectionNode& sectionNode = *m_sectionStack.back();
  4849. sectionNode.assertions.push_back(assertionStats);
  4850. return true;
  4851. }
  4852. void sectionEnded(SectionStats const& sectionStats) override {
  4853. assert(!m_sectionStack.empty());
  4854. SectionNode& node = *m_sectionStack.back();
  4855. node.stats = sectionStats;
  4856. m_sectionStack.pop_back();
  4857. }
  4858. void testCaseEnded(TestCaseStats const& testCaseStats) override {
  4859. auto node = std::make_shared<TestCaseNode>(testCaseStats);
  4860. assert(m_sectionStack.size() == 0);
  4861. node->children.push_back(m_rootSection);
  4862. m_testCases.push_back(node);
  4863. m_rootSection.reset();
  4864. assert(m_deepestSection);
  4865. m_deepestSection->stdOut = testCaseStats.stdOut;
  4866. m_deepestSection->stdErr = testCaseStats.stdErr;
  4867. }
  4868. void testGroupEnded(TestGroupStats const& testGroupStats) override {
  4869. auto node = std::make_shared<TestGroupNode>(testGroupStats);
  4870. node->children.swap(m_testCases);
  4871. m_testGroups.push_back(node);
  4872. }
  4873. void testRunEnded(TestRunStats const& testRunStats) override {
  4874. auto node = std::make_shared<TestRunNode>(testRunStats);
  4875. node->children.swap(m_testGroups);
  4876. m_testRuns.push_back(node);
  4877. testRunEndedCumulative();
  4878. }
  4879. virtual void testRunEndedCumulative() = 0;
  4880. void skipTest(TestCaseInfo const&) override {}
  4881. IConfigPtr m_config;
  4882. std::ostream& stream;
  4883. std::vector<AssertionStats> m_assertions;
  4884. std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;
  4885. std::vector<std::shared_ptr<TestCaseNode>> m_testCases;
  4886. std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;
  4887. std::vector<std::shared_ptr<TestRunNode>> m_testRuns;
  4888. std::shared_ptr<SectionNode> m_rootSection;
  4889. std::shared_ptr<SectionNode> m_deepestSection;
  4890. std::vector<std::shared_ptr<SectionNode>> m_sectionStack;
  4891. ReporterPreferences m_reporterPrefs;
  4892. };
  4893. template<char C>
  4894. char const* getLineOfChars() {
  4895. static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
  4896. if( !*line ) {
  4897. std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
  4898. line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
  4899. }
  4900. return line;
  4901. }
  4902. struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {
  4903. TestEventListenerBase( ReporterConfig const& _config );
  4904. static std::set<Verbosity> getSupportedVerbosities();
  4905. void assertionStarting(AssertionInfo const&) override;
  4906. bool assertionEnded(AssertionStats const&) override;
  4907. };
  4908. } // end namespace Catch
  4909. // end catch_reporter_bases.hpp
  4910. // start catch_console_colour.h
  4911. namespace Catch {
  4912. struct Colour {
  4913. enum Code {
  4914. None = 0,
  4915. White,
  4916. Red,
  4917. Green,
  4918. Blue,
  4919. Cyan,
  4920. Yellow,
  4921. Grey,
  4922. Bright = 0x10,
  4923. BrightRed = Bright | Red,
  4924. BrightGreen = Bright | Green,
  4925. LightGrey = Bright | Grey,
  4926. BrightWhite = Bright | White,
  4927. BrightYellow = Bright | Yellow,
  4928. // By intention
  4929. FileName = LightGrey,
  4930. Warning = BrightYellow,
  4931. ResultError = BrightRed,
  4932. ResultSuccess = BrightGreen,
  4933. ResultExpectedFailure = Warning,
  4934. Error = BrightRed,
  4935. Success = Green,
  4936. OriginalExpression = Cyan,
  4937. ReconstructedExpression = BrightYellow,
  4938. SecondaryText = LightGrey,
  4939. Headers = White
  4940. };
  4941. // Use constructed object for RAII guard
  4942. Colour( Code _colourCode );
  4943. Colour( Colour&& other ) noexcept;
  4944. Colour& operator=( Colour&& other ) noexcept;
  4945. ~Colour();
  4946. // Use static method for one-shot changes
  4947. static void use( Code _colourCode );
  4948. private:
  4949. bool m_moved = false;
  4950. };
  4951. std::ostream& operator << ( std::ostream& os, Colour const& );
  4952. } // end namespace Catch
  4953. // end catch_console_colour.h
  4954. // start catch_reporter_registrars.hpp
  4955. namespace Catch {
  4956. template<typename T>
  4957. class ReporterRegistrar {
  4958. class ReporterFactory : public IReporterFactory {
  4959. IStreamingReporterPtr create( ReporterConfig const& config ) const override {
  4960. return std::unique_ptr<T>( new T( config ) );
  4961. }
  4962. std::string getDescription() const override {
  4963. return T::getDescription();
  4964. }
  4965. };
  4966. public:
  4967. explicit ReporterRegistrar( std::string const& name ) {
  4968. getMutableRegistryHub().registerReporter( name, std::make_shared<ReporterFactory>() );
  4969. }
  4970. };
  4971. template<typename T>
  4972. class ListenerRegistrar {
  4973. class ListenerFactory : public IReporterFactory {
  4974. IStreamingReporterPtr create( ReporterConfig const& config ) const override {
  4975. return std::unique_ptr<T>( new T( config ) );
  4976. }
  4977. std::string getDescription() const override {
  4978. return std::string();
  4979. }
  4980. };
  4981. public:
  4982. ListenerRegistrar() {
  4983. getMutableRegistryHub().registerListener( std::make_shared<ListenerFactory>() );
  4984. }
  4985. };
  4986. }
  4987. #if !defined(CATCH_CONFIG_DISABLE)
  4988. #define CATCH_REGISTER_REPORTER( name, reporterType ) \
  4989. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  4990. namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \
  4991. CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  4992. #define CATCH_REGISTER_LISTENER( listenerType ) \
  4993. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  4994. namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
  4995. CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  4996. #else // CATCH_CONFIG_DISABLE
  4997. #define CATCH_REGISTER_REPORTER(name, reporterType)
  4998. #define CATCH_REGISTER_LISTENER(listenerType)
  4999. #endif // CATCH_CONFIG_DISABLE
  5000. // end catch_reporter_registrars.hpp
  5001. // Allow users to base their work off existing reporters
  5002. // start catch_reporter_compact.h
  5003. namespace Catch {
  5004. struct CompactReporter : StreamingReporterBase<CompactReporter> {
  5005. using StreamingReporterBase::StreamingReporterBase;
  5006. ~CompactReporter() override;
  5007. static std::string getDescription();
  5008. ReporterPreferences getPreferences() const override;
  5009. void noMatchingTestCases(std::string const& spec) override;
  5010. void assertionStarting(AssertionInfo const&) override;
  5011. bool assertionEnded(AssertionStats const& _assertionStats) override;
  5012. void sectionEnded(SectionStats const& _sectionStats) override;
  5013. void testRunEnded(TestRunStats const& _testRunStats) override;
  5014. };
  5015. } // end namespace Catch
  5016. // end catch_reporter_compact.h
  5017. // start catch_reporter_console.h
  5018. #if defined(_MSC_VER)
  5019. #pragma warning(push)
  5020. #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
  5021. // Note that 4062 (not all labels are handled
  5022. // and default is missing) is enabled
  5023. #endif
  5024. namespace Catch {
  5025. // Fwd decls
  5026. struct SummaryColumn;
  5027. class TablePrinter;
  5028. struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {
  5029. std::unique_ptr<TablePrinter> m_tablePrinter;
  5030. ConsoleReporter(ReporterConfig const& config);
  5031. ~ConsoleReporter() override;
  5032. static std::string getDescription();
  5033. void noMatchingTestCases(std::string const& spec) override;
  5034. void reportInvalidArguments(std::string const&arg) override;
  5035. void assertionStarting(AssertionInfo const&) override;
  5036. bool assertionEnded(AssertionStats const& _assertionStats) override;
  5037. void sectionStarting(SectionInfo const& _sectionInfo) override;
  5038. void sectionEnded(SectionStats const& _sectionStats) override;
  5039. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  5040. void benchmarkPreparing(std::string const& name) override;
  5041. void benchmarkStarting(BenchmarkInfo const& info) override;
  5042. void benchmarkEnded(BenchmarkStats<> const& stats) override;
  5043. void benchmarkFailed(std::string const& error) override;
  5044. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  5045. void testCaseEnded(TestCaseStats const& _testCaseStats) override;
  5046. void testGroupEnded(TestGroupStats const& _testGroupStats) override;
  5047. void testRunEnded(TestRunStats const& _testRunStats) override;
  5048. void testRunStarting(TestRunInfo const& _testRunInfo) override;
  5049. private:
  5050. void lazyPrint();
  5051. void lazyPrintWithoutClosingBenchmarkTable();
  5052. void lazyPrintRunInfo();
  5053. void lazyPrintGroupInfo();
  5054. void printTestCaseAndSectionHeader();
  5055. void printClosedHeader(std::string const& _name);
  5056. void printOpenHeader(std::string const& _name);
  5057. // if string has a : in first line will set indent to follow it on
  5058. // subsequent lines
  5059. void printHeaderString(std::string const& _string, std::size_t indent = 0);
  5060. void printTotals(Totals const& totals);
  5061. void printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row);
  5062. void printTotalsDivider(Totals const& totals);
  5063. void printSummaryDivider();
  5064. void printTestFilters();
  5065. private:
  5066. bool m_headerPrinted = false;
  5067. };
  5068. } // end namespace Catch
  5069. #if defined(_MSC_VER)
  5070. #pragma warning(pop)
  5071. #endif
  5072. // end catch_reporter_console.h
  5073. // start catch_reporter_junit.h
  5074. // start catch_xmlwriter.h
  5075. #include <vector>
  5076. namespace Catch {
  5077. class XmlEncode {
  5078. public:
  5079. enum ForWhat { ForTextNodes, ForAttributes };
  5080. XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );
  5081. void encodeTo( std::ostream& os ) const;
  5082. friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );
  5083. private:
  5084. std::string m_str;
  5085. ForWhat m_forWhat;
  5086. };
  5087. class XmlWriter {
  5088. public:
  5089. class ScopedElement {
  5090. public:
  5091. ScopedElement( XmlWriter* writer );
  5092. ScopedElement( ScopedElement&& other ) noexcept;
  5093. ScopedElement& operator=( ScopedElement&& other ) noexcept;
  5094. ~ScopedElement();
  5095. ScopedElement& writeText( std::string const& text, bool indent = true );
  5096. template<typename T>
  5097. ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
  5098. m_writer->writeAttribute( name, attribute );
  5099. return *this;
  5100. }
  5101. private:
  5102. mutable XmlWriter* m_writer = nullptr;
  5103. };
  5104. XmlWriter( std::ostream& os = Catch::cout() );
  5105. ~XmlWriter();
  5106. XmlWriter( XmlWriter const& ) = delete;
  5107. XmlWriter& operator=( XmlWriter const& ) = delete;
  5108. XmlWriter& startElement( std::string const& name );
  5109. ScopedElement scopedElement( std::string const& name );
  5110. XmlWriter& endElement();
  5111. XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );
  5112. XmlWriter& writeAttribute( std::string const& name, bool attribute );
  5113. template<typename T>
  5114. XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
  5115. ReusableStringStream rss;
  5116. rss << attribute;
  5117. return writeAttribute( name, rss.str() );
  5118. }
  5119. XmlWriter& writeText( std::string const& text, bool indent = true );
  5120. XmlWriter& writeComment( std::string const& text );
  5121. void writeStylesheetRef( std::string const& url );
  5122. XmlWriter& writeBlankLine();
  5123. void ensureTagClosed();
  5124. private:
  5125. void writeDeclaration();
  5126. void newlineIfNecessary();
  5127. bool m_tagIsOpen = false;
  5128. bool m_needsNewline = false;
  5129. std::vector<std::string> m_tags;
  5130. std::string m_indent;
  5131. std::ostream& m_os;
  5132. };
  5133. }
  5134. // end catch_xmlwriter.h
  5135. namespace Catch {
  5136. class JunitReporter : public CumulativeReporterBase<JunitReporter> {
  5137. public:
  5138. JunitReporter(ReporterConfig const& _config);
  5139. ~JunitReporter() override;
  5140. static std::string getDescription();
  5141. void noMatchingTestCases(std::string const& /*spec*/) override;
  5142. void testRunStarting(TestRunInfo const& runInfo) override;
  5143. void testGroupStarting(GroupInfo const& groupInfo) override;
  5144. void testCaseStarting(TestCaseInfo const& testCaseInfo) override;
  5145. bool assertionEnded(AssertionStats const& assertionStats) override;
  5146. void testCaseEnded(TestCaseStats const& testCaseStats) override;
  5147. void testGroupEnded(TestGroupStats const& testGroupStats) override;
  5148. void testRunEndedCumulative() override;
  5149. void writeGroup(TestGroupNode const& groupNode, double suiteTime);
  5150. void writeTestCase(TestCaseNode const& testCaseNode);
  5151. void writeSection(std::string const& className,
  5152. std::string const& rootName,
  5153. SectionNode const& sectionNode);
  5154. void writeAssertions(SectionNode const& sectionNode);
  5155. void writeAssertion(AssertionStats const& stats);
  5156. XmlWriter xml;
  5157. Timer suiteTimer;
  5158. std::string stdOutForSuite;
  5159. std::string stdErrForSuite;
  5160. unsigned int unexpectedExceptions = 0;
  5161. bool m_okToFail = false;
  5162. };
  5163. } // end namespace Catch
  5164. // end catch_reporter_junit.h
  5165. // start catch_reporter_xml.h
  5166. namespace Catch {
  5167. class XmlReporter : public StreamingReporterBase<XmlReporter> {
  5168. public:
  5169. XmlReporter(ReporterConfig const& _config);
  5170. ~XmlReporter() override;
  5171. static std::string getDescription();
  5172. virtual std::string getStylesheetRef() const;
  5173. void writeSourceInfo(SourceLineInfo const& sourceInfo);
  5174. public: // StreamingReporterBase
  5175. void noMatchingTestCases(std::string const& s) override;
  5176. void testRunStarting(TestRunInfo const& testInfo) override;
  5177. void testGroupStarting(GroupInfo const& groupInfo) override;
  5178. void testCaseStarting(TestCaseInfo const& testInfo) override;
  5179. void sectionStarting(SectionInfo const& sectionInfo) override;
  5180. void assertionStarting(AssertionInfo const&) override;
  5181. bool assertionEnded(AssertionStats const& assertionStats) override;
  5182. void sectionEnded(SectionStats const& sectionStats) override;
  5183. void testCaseEnded(TestCaseStats const& testCaseStats) override;
  5184. void testGroupEnded(TestGroupStats const& testGroupStats) override;
  5185. void testRunEnded(TestRunStats const& testRunStats) override;
  5186. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  5187. void benchmarkPreparing(std::string const& name) override;
  5188. void benchmarkStarting(BenchmarkInfo const&) override;
  5189. void benchmarkEnded(BenchmarkStats<> const&) override;
  5190. void benchmarkFailed(std::string const&) override;
  5191. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  5192. private:
  5193. Timer m_testCaseTimer;
  5194. XmlWriter m_xml;
  5195. int m_sectionDepth = 0;
  5196. };
  5197. } // end namespace Catch
  5198. // end catch_reporter_xml.h
  5199. // end catch_external_interfaces.h
  5200. #endif
  5201. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  5202. // start catch_benchmark.hpp
  5203. // Benchmark
  5204. // start catch_chronometer.hpp
  5205. // User-facing chronometer
  5206. // start catch_clock.hpp
  5207. // Clocks
  5208. #include <chrono>
  5209. #include <ratio>
  5210. namespace Catch {
  5211. namespace Benchmark {
  5212. template <typename Clock>
  5213. using ClockDuration = typename Clock::duration;
  5214. template <typename Clock>
  5215. using FloatDuration = std::chrono::duration<double, typename Clock::period>;
  5216. template <typename Clock>
  5217. using TimePoint = typename Clock::time_point;
  5218. using default_clock = std::chrono::steady_clock;
  5219. template <typename Clock>
  5220. struct now {
  5221. TimePoint<Clock> operator()() const {
  5222. return Clock::now();
  5223. }
  5224. };
  5225. using fp_seconds = std::chrono::duration<double, std::ratio<1>>;
  5226. } // namespace Benchmark
  5227. } // namespace Catch
  5228. // end catch_clock.hpp
  5229. // start catch_optimizer.hpp
  5230. // Hinting the optimizer
  5231. #if defined(_MSC_VER)
  5232. # include <atomic> // atomic_thread_fence
  5233. #endif
  5234. namespace Catch {
  5235. namespace Benchmark {
  5236. #if defined(__GNUC__) || defined(__clang__)
  5237. template <typename T>
  5238. inline void keep_memory(T* p) {
  5239. asm volatile("" : : "g"(p) : "memory");
  5240. }
  5241. inline void keep_memory() {
  5242. asm volatile("" : : : "memory");
  5243. }
  5244. namespace Detail {
  5245. inline void optimizer_barrier() { keep_memory(); }
  5246. } // namespace Detail
  5247. #elif defined(_MSC_VER)
  5248. #pragma optimize("", off)
  5249. template <typename T>
  5250. inline void keep_memory(T* p) {
  5251. // thanks @milleniumbug
  5252. *reinterpret_cast<char volatile*>(p) = *reinterpret_cast<char const volatile*>(p);
  5253. }
  5254. // TODO equivalent keep_memory()
  5255. #pragma optimize("", on)
  5256. namespace Detail {
  5257. inline void optimizer_barrier() {
  5258. std::atomic_thread_fence(std::memory_order_seq_cst);
  5259. }
  5260. } // namespace Detail
  5261. #endif
  5262. template <typename T>
  5263. inline void deoptimize_value(T&& x) {
  5264. keep_memory(&x);
  5265. }
  5266. template <typename Fn, typename... Args>
  5267. inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<!std::is_same<void, decltype(fn(args...))>::value>::type {
  5268. deoptimize_value(std::forward<Fn>(fn) (std::forward<Args...>(args...)));
  5269. }
  5270. template <typename Fn, typename... Args>
  5271. inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<std::is_same<void, decltype(fn(args...))>::value>::type {
  5272. std::forward<Fn>(fn) (std::forward<Args...>(args...));
  5273. }
  5274. } // namespace Benchmark
  5275. } // namespace Catch
  5276. // end catch_optimizer.hpp
  5277. // start catch_complete_invoke.hpp
  5278. // Invoke with a special case for void
  5279. #include <type_traits>
  5280. #include <utility>
  5281. namespace Catch {
  5282. namespace Benchmark {
  5283. namespace Detail {
  5284. template <typename T>
  5285. struct CompleteType { using type = T; };
  5286. template <>
  5287. struct CompleteType<void> { struct type {}; };
  5288. template <typename T>
  5289. using CompleteType_t = typename CompleteType<T>::type;
  5290. template <typename Result>
  5291. struct CompleteInvoker {
  5292. template <typename Fun, typename... Args>
  5293. static Result invoke(Fun&& fun, Args&&... args) {
  5294. return std::forward<Fun>(fun)(std::forward<Args>(args)...);
  5295. }
  5296. };
  5297. template <>
  5298. struct CompleteInvoker<void> {
  5299. template <typename Fun, typename... Args>
  5300. static CompleteType_t<void> invoke(Fun&& fun, Args&&... args) {
  5301. std::forward<Fun>(fun)(std::forward<Args>(args)...);
  5302. return {};
  5303. }
  5304. };
  5305. template <typename Sig>
  5306. using ResultOf_t = typename std::result_of<Sig>::type;
  5307. // invoke and not return void :(
  5308. template <typename Fun, typename... Args>
  5309. CompleteType_t<ResultOf_t<Fun(Args...)>> complete_invoke(Fun&& fun, Args&&... args) {
  5310. return CompleteInvoker<ResultOf_t<Fun(Args...)>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...);
  5311. }
  5312. const std::string benchmarkErrorMsg = "a benchmark failed to run successfully";
  5313. } // namespace Detail
  5314. template <typename Fun>
  5315. Detail::CompleteType_t<Detail::ResultOf_t<Fun()>> user_code(Fun&& fun) {
  5316. CATCH_TRY{
  5317. return Detail::complete_invoke(std::forward<Fun>(fun));
  5318. } CATCH_CATCH_ALL{
  5319. getResultCapture().benchmarkFailed(translateActiveException());
  5320. CATCH_RUNTIME_ERROR(Detail::benchmarkErrorMsg);
  5321. }
  5322. }
  5323. } // namespace Benchmark
  5324. } // namespace Catch
  5325. // end catch_complete_invoke.hpp
  5326. namespace Catch {
  5327. namespace Benchmark {
  5328. namespace Detail {
  5329. struct ChronometerConcept {
  5330. virtual void start() = 0;
  5331. virtual void finish() = 0;
  5332. virtual ~ChronometerConcept() = default;
  5333. };
  5334. template <typename Clock>
  5335. struct ChronometerModel final : public ChronometerConcept {
  5336. void start() override { started = Clock::now(); }
  5337. void finish() override { finished = Clock::now(); }
  5338. ClockDuration<Clock> elapsed() const { return finished - started; }
  5339. TimePoint<Clock> started;
  5340. TimePoint<Clock> finished;
  5341. };
  5342. } // namespace Detail
  5343. struct Chronometer {
  5344. public:
  5345. template <typename Fun>
  5346. void measure(Fun&& fun) { measure(std::forward<Fun>(fun), is_callable<Fun(int)>()); }
  5347. int runs() const { return k; }
  5348. Chronometer(Detail::ChronometerConcept& meter, int k)
  5349. : impl(&meter)
  5350. , k(k) {}
  5351. private:
  5352. template <typename Fun>
  5353. void measure(Fun&& fun, std::false_type) {
  5354. measure([&fun](int) { return fun(); }, std::true_type());
  5355. }
  5356. template <typename Fun>
  5357. void measure(Fun&& fun, std::true_type) {
  5358. Detail::optimizer_barrier();
  5359. impl->start();
  5360. for (int i = 0; i < k; ++i) invoke_deoptimized(fun, i);
  5361. impl->finish();
  5362. Detail::optimizer_barrier();
  5363. }
  5364. Detail::ChronometerConcept* impl;
  5365. int k;
  5366. };
  5367. } // namespace Benchmark
  5368. } // namespace Catch
  5369. // end catch_chronometer.hpp
  5370. // start catch_environment.hpp
  5371. // Environment information
  5372. namespace Catch {
  5373. namespace Benchmark {
  5374. template <typename Duration>
  5375. struct EnvironmentEstimate {
  5376. Duration mean;
  5377. OutlierClassification outliers;
  5378. template <typename Duration2>
  5379. operator EnvironmentEstimate<Duration2>() const {
  5380. return { mean, outliers };
  5381. }
  5382. };
  5383. template <typename Clock>
  5384. struct Environment {
  5385. using clock_type = Clock;
  5386. EnvironmentEstimate<FloatDuration<Clock>> clock_resolution;
  5387. EnvironmentEstimate<FloatDuration<Clock>> clock_cost;
  5388. };
  5389. } // namespace Benchmark
  5390. } // namespace Catch
  5391. // end catch_environment.hpp
  5392. // start catch_execution_plan.hpp
  5393. // Execution plan
  5394. // start catch_benchmark_function.hpp
  5395. // Dumb std::function implementation for consistent call overhead
  5396. #include <cassert>
  5397. #include <type_traits>
  5398. #include <utility>
  5399. #include <memory>
  5400. namespace Catch {
  5401. namespace Benchmark {
  5402. namespace Detail {
  5403. template <typename T>
  5404. using Decay = typename std::decay<T>::type;
  5405. template <typename T, typename U>
  5406. struct is_related
  5407. : std::is_same<Decay<T>, Decay<U>> {};
  5408. /// We need to reinvent std::function because every piece of code that might add overhead
  5409. /// in a measurement context needs to have consistent performance characteristics so that we
  5410. /// can account for it in the measurement.
  5411. /// Implementations of std::function with optimizations that aren't always applicable, like
  5412. /// small buffer optimizations, are not uncommon.
  5413. /// This is effectively an implementation of std::function without any such optimizations;
  5414. /// it may be slow, but it is consistently slow.
  5415. struct BenchmarkFunction {
  5416. private:
  5417. struct callable {
  5418. virtual void call(Chronometer meter) const = 0;
  5419. virtual callable* clone() const = 0;
  5420. virtual ~callable() = default;
  5421. };
  5422. template <typename Fun>
  5423. struct model : public callable {
  5424. model(Fun&& fun) : fun(std::move(fun)) {}
  5425. model(Fun const& fun) : fun(fun) {}
  5426. model<Fun>* clone() const override { return new model<Fun>(*this); }
  5427. void call(Chronometer meter) const override {
  5428. call(meter, is_callable<Fun(Chronometer)>());
  5429. }
  5430. void call(Chronometer meter, std::true_type) const {
  5431. fun(meter);
  5432. }
  5433. void call(Chronometer meter, std::false_type) const {
  5434. meter.measure(fun);
  5435. }
  5436. Fun fun;
  5437. };
  5438. struct do_nothing { void operator()() const {} };
  5439. template <typename T>
  5440. BenchmarkFunction(model<T>* c) : f(c) {}
  5441. public:
  5442. BenchmarkFunction()
  5443. : f(new model<do_nothing>{ {} }) {}
  5444. template <typename Fun,
  5445. typename std::enable_if<!is_related<Fun, BenchmarkFunction>::value, int>::type = 0>
  5446. BenchmarkFunction(Fun&& fun)
  5447. : f(new model<typename std::decay<Fun>::type>(std::forward<Fun>(fun))) {}
  5448. BenchmarkFunction(BenchmarkFunction&& that)
  5449. : f(std::move(that.f)) {}
  5450. BenchmarkFunction(BenchmarkFunction const& that)
  5451. : f(that.f->clone()) {}
  5452. BenchmarkFunction& operator=(BenchmarkFunction&& that) {
  5453. f = std::move(that.f);
  5454. return *this;
  5455. }
  5456. BenchmarkFunction& operator=(BenchmarkFunction const& that) {
  5457. f.reset(that.f->clone());
  5458. return *this;
  5459. }
  5460. void operator()(Chronometer meter) const { f->call(meter); }
  5461. private:
  5462. std::unique_ptr<callable> f;
  5463. };
  5464. } // namespace Detail
  5465. } // namespace Benchmark
  5466. } // namespace Catch
  5467. // end catch_benchmark_function.hpp
  5468. // start catch_repeat.hpp
  5469. // repeat algorithm
  5470. #include <type_traits>
  5471. #include <utility>
  5472. namespace Catch {
  5473. namespace Benchmark {
  5474. namespace Detail {
  5475. template <typename Fun>
  5476. struct repeater {
  5477. void operator()(int k) const {
  5478. for (int i = 0; i < k; ++i) {
  5479. fun();
  5480. }
  5481. }
  5482. Fun fun;
  5483. };
  5484. template <typename Fun>
  5485. repeater<typename std::decay<Fun>::type> repeat(Fun&& fun) {
  5486. return { std::forward<Fun>(fun) };
  5487. }
  5488. } // namespace Detail
  5489. } // namespace Benchmark
  5490. } // namespace Catch
  5491. // end catch_repeat.hpp
  5492. // start catch_run_for_at_least.hpp
  5493. // Run a function for a minimum amount of time
  5494. // start catch_measure.hpp
  5495. // Measure
  5496. // start catch_timing.hpp
  5497. // Timing
  5498. #include <tuple>
  5499. #include <type_traits>
  5500. namespace Catch {
  5501. namespace Benchmark {
  5502. template <typename Duration, typename Result>
  5503. struct Timing {
  5504. Duration elapsed;
  5505. Result result;
  5506. int iterations;
  5507. };
  5508. template <typename Clock, typename Sig>
  5509. using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<Detail::ResultOf_t<Sig>>>;
  5510. } // namespace Benchmark
  5511. } // namespace Catch
  5512. // end catch_timing.hpp
  5513. #include <utility>
  5514. namespace Catch {
  5515. namespace Benchmark {
  5516. namespace Detail {
  5517. template <typename Clock, typename Fun, typename... Args>
  5518. TimingOf<Clock, Fun(Args...)> measure(Fun&& fun, Args&&... args) {
  5519. auto start = Clock::now();
  5520. auto&& r = Detail::complete_invoke(fun, std::forward<Args>(args)...);
  5521. auto end = Clock::now();
  5522. auto delta = end - start;
  5523. return { delta, std::forward<decltype(r)>(r), 1 };
  5524. }
  5525. } // namespace Detail
  5526. } // namespace Benchmark
  5527. } // namespace Catch
  5528. // end catch_measure.hpp
  5529. #include <utility>
  5530. #include <type_traits>
  5531. namespace Catch {
  5532. namespace Benchmark {
  5533. namespace Detail {
  5534. template <typename Clock, typename Fun>
  5535. TimingOf<Clock, Fun(int)> measure_one(Fun&& fun, int iters, std::false_type) {
  5536. return Detail::measure<Clock>(fun, iters);
  5537. }
  5538. template <typename Clock, typename Fun>
  5539. TimingOf<Clock, Fun(Chronometer)> measure_one(Fun&& fun, int iters, std::true_type) {
  5540. Detail::ChronometerModel<Clock> meter;
  5541. auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters));
  5542. return { meter.elapsed(), std::move(result), iters };
  5543. }
  5544. template <typename Clock, typename Fun>
  5545. using run_for_at_least_argument_t = typename std::conditional<is_callable<Fun(Chronometer)>::value, Chronometer, int>::type;
  5546. struct optimized_away_error : std::exception {
  5547. const char* what() const noexcept override {
  5548. return "could not measure benchmark, maybe it was optimized away";
  5549. }
  5550. };
  5551. template <typename Clock, typename Fun>
  5552. TimingOf<Clock, Fun(run_for_at_least_argument_t<Clock, Fun>)> run_for_at_least(ClockDuration<Clock> how_long, int seed, Fun&& fun) {
  5553. auto iters = seed;
  5554. while (iters < (1 << 30)) {
  5555. auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());
  5556. if (Timing.elapsed >= how_long) {
  5557. return { Timing.elapsed, std::move(Timing.result), iters };
  5558. }
  5559. iters *= 2;
  5560. }
  5561. throw optimized_away_error{};
  5562. }
  5563. } // namespace Detail
  5564. } // namespace Benchmark
  5565. } // namespace Catch
  5566. // end catch_run_for_at_least.hpp
  5567. #include <algorithm>
  5568. namespace Catch {
  5569. namespace Benchmark {
  5570. template <typename Duration>
  5571. struct ExecutionPlan {
  5572. int iterations_per_sample;
  5573. Duration estimated_duration;
  5574. Detail::BenchmarkFunction benchmark;
  5575. Duration warmup_time;
  5576. int warmup_iterations;
  5577. template <typename Duration2>
  5578. operator ExecutionPlan<Duration2>() const {
  5579. return { iterations_per_sample, estimated_duration, benchmark, warmup_time, warmup_iterations };
  5580. }
  5581. template <typename Clock>
  5582. std::vector<FloatDuration<Clock>> run(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
  5583. // warmup a bit
  5584. Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_iterations, Detail::repeat(now<Clock>{}));
  5585. std::vector<FloatDuration<Clock>> times;
  5586. times.reserve(cfg.benchmarkSamples());
  5587. std::generate_n(std::back_inserter(times), cfg.benchmarkSamples(), [this, env] {
  5588. Detail::ChronometerModel<Clock> model;
  5589. this->benchmark(Chronometer(model, iterations_per_sample));
  5590. auto sample_time = model.elapsed() - env.clock_cost.mean;
  5591. if (sample_time < FloatDuration<Clock>::zero()) sample_time = FloatDuration<Clock>::zero();
  5592. return sample_time / iterations_per_sample;
  5593. });
  5594. return times;
  5595. }
  5596. };
  5597. } // namespace Benchmark
  5598. } // namespace Catch
  5599. // end catch_execution_plan.hpp
  5600. // start catch_estimate_clock.hpp
  5601. // Environment measurement
  5602. // start catch_stats.hpp
  5603. // Statistical analysis tools
  5604. #include <algorithm>
  5605. #include <functional>
  5606. #include <vector>
  5607. #include <numeric>
  5608. #include <tuple>
  5609. #include <cmath>
  5610. #include <utility>
  5611. #include <cstddef>
  5612. namespace Catch {
  5613. namespace Benchmark {
  5614. namespace Detail {
  5615. using sample = std::vector<double>;
  5616. double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last);
  5617. template <typename Iterator>
  5618. OutlierClassification classify_outliers(Iterator first, Iterator last) {
  5619. std::vector<double> copy(first, last);
  5620. auto q1 = weighted_average_quantile(1, 4, copy.begin(), copy.end());
  5621. auto q3 = weighted_average_quantile(3, 4, copy.begin(), copy.end());
  5622. auto iqr = q3 - q1;
  5623. auto los = q1 - (iqr * 3.);
  5624. auto lom = q1 - (iqr * 1.5);
  5625. auto him = q3 + (iqr * 1.5);
  5626. auto his = q3 + (iqr * 3.);
  5627. OutlierClassification o;
  5628. for (; first != last; ++first) {
  5629. auto&& t = *first;
  5630. if (t < los) ++o.low_severe;
  5631. else if (t < lom) ++o.low_mild;
  5632. else if (t > his) ++o.high_severe;
  5633. else if (t > him) ++o.high_mild;
  5634. ++o.samples_seen;
  5635. }
  5636. return o;
  5637. }
  5638. template <typename Iterator>
  5639. double mean(Iterator first, Iterator last) {
  5640. auto count = last - first;
  5641. double sum = std::accumulate(first, last, 0.);
  5642. return sum / count;
  5643. }
  5644. template <typename URng, typename Iterator, typename Estimator>
  5645. sample resample(URng& rng, int resamples, Iterator first, Iterator last, Estimator& estimator) {
  5646. auto n = last - first;
  5647. std::uniform_int_distribution<decltype(n)> dist(0, n - 1);
  5648. sample out;
  5649. out.reserve(resamples);
  5650. std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] {
  5651. std::vector<double> resampled;
  5652. resampled.reserve(n);
  5653. std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[dist(rng)]; });
  5654. return estimator(resampled.begin(), resampled.end());
  5655. });
  5656. std::sort(out.begin(), out.end());
  5657. return out;
  5658. }
  5659. template <typename Estimator, typename Iterator>
  5660. sample jackknife(Estimator&& estimator, Iterator first, Iterator last) {
  5661. auto n = last - first;
  5662. auto second = std::next(first);
  5663. sample results;
  5664. results.reserve(n);
  5665. for (auto it = first; it != last; ++it) {
  5666. std::iter_swap(it, first);
  5667. results.push_back(estimator(second, last));
  5668. }
  5669. return results;
  5670. }
  5671. inline double normal_cdf(double x) {
  5672. return std::erfc(-x / std::sqrt(2.0)) / 2.0;
  5673. }
  5674. double erfc_inv(double x);
  5675. double normal_quantile(double p);
  5676. template <typename Iterator, typename Estimator>
  5677. Estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const& resample, Estimator&& estimator) {
  5678. auto n_samples = last - first;
  5679. double point = estimator(first, last);
  5680. // Degenerate case with a single sample
  5681. if (n_samples == 1) return { point, point, point, confidence_level };
  5682. sample jack = jackknife(estimator, first, last);
  5683. double jack_mean = mean(jack.begin(), jack.end());
  5684. double sum_squares, sum_cubes;
  5685. std::tie(sum_squares, sum_cubes) = std::accumulate(jack.begin(), jack.end(), std::make_pair(0., 0.), [jack_mean](std::pair<double, double> sqcb, double x) -> std::pair<double, double> {
  5686. auto d = jack_mean - x;
  5687. auto d2 = d * d;
  5688. auto d3 = d2 * d;
  5689. return { sqcb.first + d2, sqcb.second + d3 };
  5690. });
  5691. double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5));
  5692. int n = static_cast<int>(resample.size());
  5693. double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / (double)n;
  5694. // degenerate case with uniform samples
  5695. if (prob_n == 0) return { point, point, point, confidence_level };
  5696. double bias = normal_quantile(prob_n);
  5697. double z1 = normal_quantile((1. - confidence_level) / 2.);
  5698. auto cumn = [n](double x) -> int {
  5699. return std::lround(normal_cdf(x) * n); };
  5700. auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); };
  5701. double b1 = bias + z1;
  5702. double b2 = bias - z1;
  5703. double a1 = a(b1);
  5704. double a2 = a(b2);
  5705. auto lo = std::max(cumn(a1), 0);
  5706. auto hi = std::min(cumn(a2), n - 1);
  5707. return { point, resample[lo], resample[hi], confidence_level };
  5708. }
  5709. double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n);
  5710. struct bootstrap_analysis {
  5711. Estimate<double> mean;
  5712. Estimate<double> standard_deviation;
  5713. double outlier_variance;
  5714. };
  5715. bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last);
  5716. } // namespace Detail
  5717. } // namespace Benchmark
  5718. } // namespace Catch
  5719. // end catch_stats.hpp
  5720. #include <algorithm>
  5721. #include <iterator>
  5722. #include <tuple>
  5723. #include <vector>
  5724. #include <cmath>
  5725. namespace Catch {
  5726. namespace Benchmark {
  5727. namespace Detail {
  5728. template <typename Clock>
  5729. std::vector<double> resolution(int k) {
  5730. std::vector<TimePoint<Clock>> times;
  5731. times.reserve(k + 1);
  5732. std::generate_n(std::back_inserter(times), k + 1, now<Clock>{});
  5733. std::vector<double> deltas;
  5734. deltas.reserve(k);
  5735. std::transform(std::next(times.begin()), times.end(), times.begin(),
  5736. std::back_inserter(deltas),
  5737. [](TimePoint<Clock> a, TimePoint<Clock> b) { return static_cast<double>((a - b).count()); });
  5738. return deltas;
  5739. }
  5740. const auto warmup_iterations = 10000;
  5741. const auto warmup_time = std::chrono::milliseconds(100);
  5742. const auto minimum_ticks = 1000;
  5743. const auto warmup_seed = 10000;
  5744. const auto clock_resolution_estimation_time = std::chrono::milliseconds(500);
  5745. const auto clock_cost_estimation_time_limit = std::chrono::seconds(1);
  5746. const auto clock_cost_estimation_tick_limit = 100000;
  5747. const auto clock_cost_estimation_time = std::chrono::milliseconds(10);
  5748. const auto clock_cost_estimation_iterations = 10000;
  5749. template <typename Clock>
  5750. int warmup() {
  5751. return run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_seed, &resolution<Clock>)
  5752. .iterations;
  5753. }
  5754. template <typename Clock>
  5755. EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_resolution(int iterations) {
  5756. auto r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_resolution_estimation_time), iterations, &resolution<Clock>)
  5757. .result;
  5758. return {
  5759. FloatDuration<Clock>(mean(r.begin(), r.end())),
  5760. classify_outliers(r.begin(), r.end()),
  5761. };
  5762. }
  5763. template <typename Clock>
  5764. EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) {
  5765. auto time_limit = std::min(resolution * clock_cost_estimation_tick_limit, FloatDuration<Clock>(clock_cost_estimation_time_limit));
  5766. auto time_clock = [](int k) {
  5767. return Detail::measure<Clock>([k] {
  5768. for (int i = 0; i < k; ++i) {
  5769. volatile auto ignored = Clock::now();
  5770. (void)ignored;
  5771. }
  5772. }).elapsed;
  5773. };
  5774. time_clock(1);
  5775. int iters = clock_cost_estimation_iterations;
  5776. auto&& r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_cost_estimation_time), iters, time_clock);
  5777. std::vector<double> times;
  5778. int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));
  5779. times.reserve(nsamples);
  5780. std::generate_n(std::back_inserter(times), nsamples, [time_clock, &r] {
  5781. return static_cast<double>((time_clock(r.iterations) / r.iterations).count());
  5782. });
  5783. return {
  5784. FloatDuration<Clock>(mean(times.begin(), times.end())),
  5785. classify_outliers(times.begin(), times.end()),
  5786. };
  5787. }
  5788. template <typename Clock>
  5789. Environment<FloatDuration<Clock>> measure_environment() {
  5790. static Environment<FloatDuration<Clock>>* env = nullptr;
  5791. if (env) {
  5792. return *env;
  5793. }
  5794. auto iters = Detail::warmup<Clock>();
  5795. auto resolution = Detail::estimate_clock_resolution<Clock>(iters);
  5796. auto cost = Detail::estimate_clock_cost<Clock>(resolution.mean);
  5797. env = new Environment<FloatDuration<Clock>>{ resolution, cost };
  5798. return *env;
  5799. }
  5800. } // namespace Detail
  5801. } // namespace Benchmark
  5802. } // namespace Catch
  5803. // end catch_estimate_clock.hpp
  5804. // start catch_analyse.hpp
  5805. // Run and analyse one benchmark
  5806. // start catch_sample_analysis.hpp
  5807. // Benchmark results
  5808. #include <algorithm>
  5809. #include <vector>
  5810. #include <string>
  5811. #include <iterator>
  5812. namespace Catch {
  5813. namespace Benchmark {
  5814. template <typename Duration>
  5815. struct SampleAnalysis {
  5816. std::vector<Duration> samples;
  5817. Estimate<Duration> mean;
  5818. Estimate<Duration> standard_deviation;
  5819. OutlierClassification outliers;
  5820. double outlier_variance;
  5821. template <typename Duration2>
  5822. operator SampleAnalysis<Duration2>() const {
  5823. std::vector<Duration2> samples2;
  5824. samples2.reserve(samples.size());
  5825. std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
  5826. return {
  5827. std::move(samples2),
  5828. mean,
  5829. standard_deviation,
  5830. outliers,
  5831. outlier_variance,
  5832. };
  5833. }
  5834. };
  5835. } // namespace Benchmark
  5836. } // namespace Catch
  5837. // end catch_sample_analysis.hpp
  5838. #include <algorithm>
  5839. #include <iterator>
  5840. #include <vector>
  5841. namespace Catch {
  5842. namespace Benchmark {
  5843. namespace Detail {
  5844. template <typename Duration, typename Iterator>
  5845. SampleAnalysis<Duration> analyse(const IConfig &cfg, Environment<Duration>, Iterator first, Iterator last) {
  5846. if (!cfg.benchmarkNoAnalysis()) {
  5847. std::vector<double> samples;
  5848. samples.reserve(last - first);
  5849. std::transform(first, last, std::back_inserter(samples), [](Duration d) { return d.count(); });
  5850. auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(), cfg.benchmarkResamples(), samples.begin(), samples.end());
  5851. auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end());
  5852. auto wrap_estimate = [](Estimate<double> e) {
  5853. return Estimate<Duration> {
  5854. Duration(e.point),
  5855. Duration(e.lower_bound),
  5856. Duration(e.upper_bound),
  5857. e.confidence_interval,
  5858. };
  5859. };
  5860. std::vector<Duration> samples2;
  5861. samples2.reserve(samples.size());
  5862. std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](double d) { return Duration(d); });
  5863. return {
  5864. std::move(samples2),
  5865. wrap_estimate(analysis.mean),
  5866. wrap_estimate(analysis.standard_deviation),
  5867. outliers,
  5868. analysis.outlier_variance,
  5869. };
  5870. } else {
  5871. std::vector<Duration> samples;
  5872. samples.reserve(last - first);
  5873. Duration mean = Duration(0);
  5874. int i = 0;
  5875. for (auto it = first; it < last; ++it, ++i) {
  5876. samples.push_back(Duration(*it));
  5877. mean += Duration(*it);
  5878. }
  5879. mean /= i;
  5880. return {
  5881. std::move(samples),
  5882. Estimate<Duration>{mean, mean, mean, 0.0},
  5883. Estimate<Duration>{Duration(0), Duration(0), Duration(0), 0.0},
  5884. OutlierClassification{},
  5885. 0.0
  5886. };
  5887. }
  5888. }
  5889. } // namespace Detail
  5890. } // namespace Benchmark
  5891. } // namespace Catch
  5892. // end catch_analyse.hpp
  5893. #include <algorithm>
  5894. #include <functional>
  5895. #include <string>
  5896. #include <vector>
  5897. #include <cmath>
  5898. namespace Catch {
  5899. namespace Benchmark {
  5900. struct Benchmark {
  5901. Benchmark(std::string &&name)
  5902. : name(std::move(name)) {}
  5903. template <class FUN>
  5904. Benchmark(std::string &&name, FUN &&func)
  5905. : fun(std::move(func)), name(std::move(name)) {}
  5906. template <typename Clock>
  5907. ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
  5908. auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;
  5909. auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(Detail::warmup_time));
  5910. auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun);
  5911. int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));
  5912. return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(Detail::warmup_time), Detail::warmup_iterations };
  5913. }
  5914. template <typename Clock = default_clock>
  5915. void run() {
  5916. IConfigPtr cfg = getCurrentContext().getConfig();
  5917. auto env = Detail::measure_environment<Clock>();
  5918. getResultCapture().benchmarkPreparing(name);
  5919. CATCH_TRY{
  5920. auto plan = user_code([&] {
  5921. return prepare<Clock>(*cfg, env);
  5922. });
  5923. BenchmarkInfo info {
  5924. name,
  5925. plan.estimated_duration.count(),
  5926. plan.iterations_per_sample,
  5927. cfg->benchmarkSamples(),
  5928. cfg->benchmarkResamples(),
  5929. env.clock_resolution.mean.count(),
  5930. env.clock_cost.mean.count()
  5931. };
  5932. getResultCapture().benchmarkStarting(info);
  5933. auto samples = user_code([&] {
  5934. return plan.template run<Clock>(*cfg, env);
  5935. });
  5936. auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());
  5937. BenchmarkStats<std::chrono::duration<double, std::nano>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
  5938. getResultCapture().benchmarkEnded(stats);
  5939. } CATCH_CATCH_ALL{
  5940. if (translateActiveException() != Detail::benchmarkErrorMsg) // benchmark errors have been reported, otherwise rethrow.
  5941. std::rethrow_exception(std::current_exception());
  5942. }
  5943. }
  5944. // sets lambda to be used in fun *and* executes benchmark!
  5945. template <typename Fun,
  5946. typename std::enable_if<!Detail::is_related<Fun, Benchmark>::value, int>::type = 0>
  5947. Benchmark & operator=(Fun func) {
  5948. fun = Detail::BenchmarkFunction(func);
  5949. run();
  5950. return *this;
  5951. }
  5952. explicit operator bool() {
  5953. return true;
  5954. }
  5955. private:
  5956. Detail::BenchmarkFunction fun;
  5957. std::string name;
  5958. };
  5959. }
  5960. } // namespace Catch
  5961. #define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1
  5962. #define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2
  5963. #define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex)\
  5964. if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
  5965. BenchmarkName = [&](int benchmarkIndex)
  5966. #define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name)\
  5967. if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
  5968. BenchmarkName = [&]
  5969. // end catch_benchmark.hpp
  5970. #endif
  5971. #endif // ! CATCH_CONFIG_IMPL_ONLY
  5972. #ifdef CATCH_IMPL
  5973. // start catch_impl.hpp
  5974. #ifdef __clang__
  5975. #pragma clang diagnostic push
  5976. #pragma clang diagnostic ignored "-Wweak-vtables"
  5977. #endif
  5978. // Keep these here for external reporters
  5979. // start catch_test_case_tracker.h
  5980. #include <string>
  5981. #include <vector>
  5982. #include <memory>
  5983. namespace Catch {
  5984. namespace TestCaseTracking {
  5985. struct NameAndLocation {
  5986. std::string name;
  5987. SourceLineInfo location;
  5988. NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
  5989. };
  5990. struct ITracker;
  5991. using ITrackerPtr = std::shared_ptr<ITracker>;
  5992. struct ITracker {
  5993. virtual ~ITracker();
  5994. // static queries
  5995. virtual NameAndLocation const& nameAndLocation() const = 0;
  5996. // dynamic queries
  5997. virtual bool isComplete() const = 0; // Successfully completed or failed
  5998. virtual bool isSuccessfullyCompleted() const = 0;
  5999. virtual bool isOpen() const = 0; // Started but not complete
  6000. virtual bool hasChildren() const = 0;
  6001. virtual ITracker& parent() = 0;
  6002. // actions
  6003. virtual void close() = 0; // Successfully complete
  6004. virtual void fail() = 0;
  6005. virtual void markAsNeedingAnotherRun() = 0;
  6006. virtual void addChild( ITrackerPtr const& child ) = 0;
  6007. virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0;
  6008. virtual void openChild() = 0;
  6009. // Debug/ checking
  6010. virtual bool isSectionTracker() const = 0;
  6011. virtual bool isGeneratorTracker() const = 0;
  6012. };
  6013. class TrackerContext {
  6014. enum RunState {
  6015. NotStarted,
  6016. Executing,
  6017. CompletedCycle
  6018. };
  6019. ITrackerPtr m_rootTracker;
  6020. ITracker* m_currentTracker = nullptr;
  6021. RunState m_runState = NotStarted;
  6022. public:
  6023. ITracker& startRun();
  6024. void endRun();
  6025. void startCycle();
  6026. void completeCycle();
  6027. bool completedCycle() const;
  6028. ITracker& currentTracker();
  6029. void setCurrentTracker( ITracker* tracker );
  6030. };
  6031. class TrackerBase : public ITracker {
  6032. protected:
  6033. enum CycleState {
  6034. NotStarted,
  6035. Executing,
  6036. ExecutingChildren,
  6037. NeedsAnotherRun,
  6038. CompletedSuccessfully,
  6039. Failed
  6040. };
  6041. using Children = std::vector<ITrackerPtr>;
  6042. NameAndLocation m_nameAndLocation;
  6043. TrackerContext& m_ctx;
  6044. ITracker* m_parent;
  6045. Children m_children;
  6046. CycleState m_runState = NotStarted;
  6047. public:
  6048. TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
  6049. NameAndLocation const& nameAndLocation() const override;
  6050. bool isComplete() const override;
  6051. bool isSuccessfullyCompleted() const override;
  6052. bool isOpen() const override;
  6053. bool hasChildren() const override;
  6054. void addChild( ITrackerPtr const& child ) override;
  6055. ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override;
  6056. ITracker& parent() override;
  6057. void openChild() override;
  6058. bool isSectionTracker() const override;
  6059. bool isGeneratorTracker() const override;
  6060. void open();
  6061. void close() override;
  6062. void fail() override;
  6063. void markAsNeedingAnotherRun() override;
  6064. private:
  6065. void moveToParent();
  6066. void moveToThis();
  6067. };
  6068. class SectionTracker : public TrackerBase {
  6069. std::vector<std::string> m_filters;
  6070. std::string m_trimmed_name;
  6071. public:
  6072. SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
  6073. bool isSectionTracker() const override;
  6074. bool isComplete() const override;
  6075. static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );
  6076. void tryOpen();
  6077. void addInitialFilters( std::vector<std::string> const& filters );
  6078. void addNextFilters( std::vector<std::string> const& filters );
  6079. };
  6080. } // namespace TestCaseTracking
  6081. using TestCaseTracking::ITracker;
  6082. using TestCaseTracking::TrackerContext;
  6083. using TestCaseTracking::SectionTracker;
  6084. } // namespace Catch
  6085. // end catch_test_case_tracker.h
  6086. // start catch_leak_detector.h
  6087. namespace Catch {
  6088. struct LeakDetector {
  6089. LeakDetector();
  6090. ~LeakDetector();
  6091. };
  6092. }
  6093. // end catch_leak_detector.h
  6094. // Cpp files will be included in the single-header file here
  6095. // start catch_stats.cpp
  6096. // Statistical analysis tools
  6097. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  6098. #include <cassert>
  6099. #include <random>
  6100. #if defined(CATCH_CONFIG_USE_ASYNC)
  6101. #include <future>
  6102. #endif
  6103. namespace {
  6104. double erf_inv(double x) {
  6105. // Code accompanying the article "Approximating the erfinv function" in GPU Computing Gems, Volume 2
  6106. double w, p;
  6107. w = -log((1.0 - x) * (1.0 + x));
  6108. if (w < 6.250000) {
  6109. w = w - 3.125000;
  6110. p = -3.6444120640178196996e-21;
  6111. p = -1.685059138182016589e-19 + p * w;
  6112. p = 1.2858480715256400167e-18 + p * w;
  6113. p = 1.115787767802518096e-17 + p * w;
  6114. p = -1.333171662854620906e-16 + p * w;
  6115. p = 2.0972767875968561637e-17 + p * w;
  6116. p = 6.6376381343583238325e-15 + p * w;
  6117. p = -4.0545662729752068639e-14 + p * w;
  6118. p = -8.1519341976054721522e-14 + p * w;
  6119. p = 2.6335093153082322977e-12 + p * w;
  6120. p = -1.2975133253453532498e-11 + p * w;
  6121. p = -5.4154120542946279317e-11 + p * w;
  6122. p = 1.051212273321532285e-09 + p * w;
  6123. p = -4.1126339803469836976e-09 + p * w;
  6124. p = -2.9070369957882005086e-08 + p * w;
  6125. p = 4.2347877827932403518e-07 + p * w;
  6126. p = -1.3654692000834678645e-06 + p * w;
  6127. p = -1.3882523362786468719e-05 + p * w;
  6128. p = 0.0001867342080340571352 + p * w;
  6129. p = -0.00074070253416626697512 + p * w;
  6130. p = -0.0060336708714301490533 + p * w;
  6131. p = 0.24015818242558961693 + p * w;
  6132. p = 1.6536545626831027356 + p * w;
  6133. } else if (w < 16.000000) {
  6134. w = sqrt(w) - 3.250000;
  6135. p = 2.2137376921775787049e-09;
  6136. p = 9.0756561938885390979e-08 + p * w;
  6137. p = -2.7517406297064545428e-07 + p * w;
  6138. p = 1.8239629214389227755e-08 + p * w;
  6139. p = 1.5027403968909827627e-06 + p * w;
  6140. p = -4.013867526981545969e-06 + p * w;
  6141. p = 2.9234449089955446044e-06 + p * w;
  6142. p = 1.2475304481671778723e-05 + p * w;
  6143. p = -4.7318229009055733981e-05 + p * w;
  6144. p = 6.8284851459573175448e-05 + p * w;
  6145. p = 2.4031110387097893999e-05 + p * w;
  6146. p = -0.0003550375203628474796 + p * w;
  6147. p = 0.00095328937973738049703 + p * w;
  6148. p = -0.0016882755560235047313 + p * w;
  6149. p = 0.0024914420961078508066 + p * w;
  6150. p = -0.0037512085075692412107 + p * w;
  6151. p = 0.005370914553590063617 + p * w;
  6152. p = 1.0052589676941592334 + p * w;
  6153. p = 3.0838856104922207635 + p * w;
  6154. } else {
  6155. w = sqrt(w) - 5.000000;
  6156. p = -2.7109920616438573243e-11;
  6157. p = -2.5556418169965252055e-10 + p * w;
  6158. p = 1.5076572693500548083e-09 + p * w;
  6159. p = -3.7894654401267369937e-09 + p * w;
  6160. p = 7.6157012080783393804e-09 + p * w;
  6161. p = -1.4960026627149240478e-08 + p * w;
  6162. p = 2.9147953450901080826e-08 + p * w;
  6163. p = -6.7711997758452339498e-08 + p * w;
  6164. p = 2.2900482228026654717e-07 + p * w;
  6165. p = -9.9298272942317002539e-07 + p * w;
  6166. p = 4.5260625972231537039e-06 + p * w;
  6167. p = -1.9681778105531670567e-05 + p * w;
  6168. p = 7.5995277030017761139e-05 + p * w;
  6169. p = -0.00021503011930044477347 + p * w;
  6170. p = -0.00013871931833623122026 + p * w;
  6171. p = 1.0103004648645343977 + p * w;
  6172. p = 4.8499064014085844221 + p * w;
  6173. }
  6174. return p * x;
  6175. }
  6176. double standard_deviation(std::vector<double>::iterator first, std::vector<double>::iterator last) {
  6177. auto m = Catch::Benchmark::Detail::mean(first, last);
  6178. double variance = std::accumulate(first, last, 0., [m](double a, double b) {
  6179. double diff = b - m;
  6180. return a + diff * diff;
  6181. }) / (last - first);
  6182. return std::sqrt(variance);
  6183. }
  6184. }
  6185. namespace Catch {
  6186. namespace Benchmark {
  6187. namespace Detail {
  6188. double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last) {
  6189. auto count = last - first;
  6190. double idx = (count - 1) * k / static_cast<double>(q);
  6191. int j = static_cast<int>(idx);
  6192. double g = idx - j;
  6193. std::nth_element(first, first + j, last);
  6194. auto xj = first[j];
  6195. if (g == 0) return xj;
  6196. auto xj1 = *std::min_element(first + (j + 1), last);
  6197. return xj + g * (xj1 - xj);
  6198. }
  6199. double erfc_inv(double x) {
  6200. return erf_inv(1.0 - x);
  6201. }
  6202. double normal_quantile(double p) {
  6203. static const double ROOT_TWO = std::sqrt(2.0);
  6204. double result = 0.0;
  6205. assert(p >= 0 && p <= 1);
  6206. if (p < 0 || p > 1) {
  6207. return result;
  6208. }
  6209. result = -erfc_inv(2.0 * p);
  6210. // result *= normal distribution standard deviation (1.0) * sqrt(2)
  6211. result *= /*sd * */ ROOT_TWO;
  6212. // result += normal disttribution mean (0)
  6213. return result;
  6214. }
  6215. double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n) {
  6216. double sb = stddev.point;
  6217. double mn = mean.point / n;
  6218. double mg_min = mn / 2.;
  6219. double sg = std::min(mg_min / 4., sb / std::sqrt(n));
  6220. double sg2 = sg * sg;
  6221. double sb2 = sb * sb;
  6222. auto c_max = [n, mn, sb2, sg2](double x) -> double {
  6223. double k = mn - x;
  6224. double d = k * k;
  6225. double nd = n * d;
  6226. double k0 = -n * nd;
  6227. double k1 = sb2 - n * sg2 + nd;
  6228. double det = k1 * k1 - 4 * sg2 * k0;
  6229. return (int)(-2. * k0 / (k1 + std::sqrt(det)));
  6230. };
  6231. auto var_out = [n, sb2, sg2](double c) {
  6232. double nc = n - c;
  6233. return (nc / n) * (sb2 - nc * sg2);
  6234. };
  6235. return std::min(var_out(1), var_out(std::min(c_max(0.), c_max(mg_min)))) / sb2;
  6236. }
  6237. bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) {
  6238. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
  6239. static std::random_device entropy;
  6240. CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  6241. auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++
  6242. auto mean = &Detail::mean<std::vector<double>::iterator>;
  6243. auto stddev = &standard_deviation;
  6244. #if defined(CATCH_CONFIG_USE_ASYNC)
  6245. auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
  6246. auto seed = entropy();
  6247. return std::async(std::launch::async, [=] {
  6248. std::mt19937 rng(seed);
  6249. auto resampled = resample(rng, n_resamples, first, last, f);
  6250. return bootstrap(confidence_level, first, last, resampled, f);
  6251. });
  6252. };
  6253. auto mean_future = Estimate(mean);
  6254. auto stddev_future = Estimate(stddev);
  6255. auto mean_estimate = mean_future.get();
  6256. auto stddev_estimate = stddev_future.get();
  6257. #else
  6258. auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
  6259. auto seed = entropy();
  6260. std::mt19937 rng(seed);
  6261. auto resampled = resample(rng, n_resamples, first, last, f);
  6262. return bootstrap(confidence_level, first, last, resampled, f);
  6263. };
  6264. auto mean_estimate = Estimate(mean);
  6265. auto stddev_estimate = Estimate(stddev);
  6266. #endif // CATCH_USE_ASYNC
  6267. double outlier_variance = Detail::outlier_variance(mean_estimate, stddev_estimate, n);
  6268. return { mean_estimate, stddev_estimate, outlier_variance };
  6269. }
  6270. } // namespace Detail
  6271. } // namespace Benchmark
  6272. } // namespace Catch
  6273. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  6274. // end catch_stats.cpp
  6275. // start catch_approx.cpp
  6276. #include <cmath>
  6277. #include <limits>
  6278. namespace {
  6279. // Performs equivalent check of std::fabs(lhs - rhs) <= margin
  6280. // But without the subtraction to allow for INFINITY in comparison
  6281. bool marginComparison(double lhs, double rhs, double margin) {
  6282. return (lhs + margin >= rhs) && (rhs + margin >= lhs);
  6283. }
  6284. }
  6285. namespace Catch {
  6286. namespace Detail {
  6287. Approx::Approx ( double value )
  6288. : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
  6289. m_margin( 0.0 ),
  6290. m_scale( 0.0 ),
  6291. m_value( value )
  6292. {}
  6293. Approx Approx::custom() {
  6294. return Approx( 0 );
  6295. }
  6296. Approx Approx::operator-() const {
  6297. auto temp(*this);
  6298. temp.m_value = -temp.m_value;
  6299. return temp;
  6300. }
  6301. std::string Approx::toString() const {
  6302. ReusableStringStream rss;
  6303. rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
  6304. return rss.str();
  6305. }
  6306. bool Approx::equalityComparisonImpl(const double other) const {
  6307. // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
  6308. // Thanks to Richard Harris for his help refining the scaled margin value
  6309. return marginComparison(m_value, other, m_margin)
  6310. || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(std::isinf(m_value)? 0 : m_value)));
  6311. }
  6312. void Approx::setMargin(double newMargin) {
  6313. CATCH_ENFORCE(newMargin >= 0,
  6314. "Invalid Approx::margin: " << newMargin << '.'
  6315. << " Approx::Margin has to be non-negative.");
  6316. m_margin = newMargin;
  6317. }
  6318. void Approx::setEpsilon(double newEpsilon) {
  6319. CATCH_ENFORCE(newEpsilon >= 0 && newEpsilon <= 1.0,
  6320. "Invalid Approx::epsilon: " << newEpsilon << '.'
  6321. << " Approx::epsilon has to be in [0, 1]");
  6322. m_epsilon = newEpsilon;
  6323. }
  6324. } // end namespace Detail
  6325. namespace literals {
  6326. Detail::Approx operator "" _a(long double val) {
  6327. return Detail::Approx(val);
  6328. }
  6329. Detail::Approx operator "" _a(unsigned long long val) {
  6330. return Detail::Approx(val);
  6331. }
  6332. } // end namespace literals
  6333. std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
  6334. return value.toString();
  6335. }
  6336. } // end namespace Catch
  6337. // end catch_approx.cpp
  6338. // start catch_assertionhandler.cpp
  6339. // start catch_debugger.h
  6340. namespace Catch {
  6341. bool isDebuggerActive();
  6342. }
  6343. #ifdef CATCH_PLATFORM_MAC
  6344. #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
  6345. #elif defined(CATCH_PLATFORM_LINUX)
  6346. // If we can use inline assembler, do it because this allows us to break
  6347. // directly at the location of the failing check instead of breaking inside
  6348. // raise() called from it, i.e. one stack frame below.
  6349. #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
  6350. #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
  6351. #else // Fall back to the generic way.
  6352. #include <signal.h>
  6353. #define CATCH_TRAP() raise(SIGTRAP)
  6354. #endif
  6355. #elif defined(_MSC_VER)
  6356. #define CATCH_TRAP() __debugbreak()
  6357. #elif defined(__MINGW32__)
  6358. extern "C" __declspec(dllimport) void __stdcall DebugBreak();
  6359. #define CATCH_TRAP() DebugBreak()
  6360. #endif
  6361. #ifdef CATCH_TRAP
  6362. #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()
  6363. #else
  6364. #define CATCH_BREAK_INTO_DEBUGGER() []{}()
  6365. #endif
  6366. // end catch_debugger.h
  6367. // start catch_run_context.h
  6368. // start catch_fatal_condition.h
  6369. // start catch_windows_h_proxy.h
  6370. #if defined(CATCH_PLATFORM_WINDOWS)
  6371. #if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
  6372. # define CATCH_DEFINED_NOMINMAX
  6373. # define NOMINMAX
  6374. #endif
  6375. #if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
  6376. # define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
  6377. # define WIN32_LEAN_AND_MEAN
  6378. #endif
  6379. #ifdef __AFXDLL
  6380. #include <AfxWin.h>
  6381. #else
  6382. #include <windows.h>
  6383. #endif
  6384. #ifdef CATCH_DEFINED_NOMINMAX
  6385. # undef NOMINMAX
  6386. #endif
  6387. #ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
  6388. # undef WIN32_LEAN_AND_MEAN
  6389. #endif
  6390. #endif // defined(CATCH_PLATFORM_WINDOWS)
  6391. // end catch_windows_h_proxy.h
  6392. #if defined( CATCH_CONFIG_WINDOWS_SEH )
  6393. namespace Catch {
  6394. struct FatalConditionHandler {
  6395. static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
  6396. FatalConditionHandler();
  6397. static void reset();
  6398. ~FatalConditionHandler();
  6399. private:
  6400. static bool isSet;
  6401. static ULONG guaranteeSize;
  6402. static PVOID exceptionHandlerHandle;
  6403. };
  6404. } // namespace Catch
  6405. #elif defined ( CATCH_CONFIG_POSIX_SIGNALS )
  6406. #include <signal.h>
  6407. namespace Catch {
  6408. struct FatalConditionHandler {
  6409. static bool isSet;
  6410. static struct sigaction oldSigActions[];
  6411. static stack_t oldSigStack;
  6412. static char altStackMem[];
  6413. static void handleSignal( int sig );
  6414. FatalConditionHandler();
  6415. ~FatalConditionHandler();
  6416. static void reset();
  6417. };
  6418. } // namespace Catch
  6419. #else
  6420. namespace Catch {
  6421. struct FatalConditionHandler {
  6422. void reset();
  6423. };
  6424. }
  6425. #endif
  6426. // end catch_fatal_condition.h
  6427. #include <string>
  6428. namespace Catch {
  6429. struct IMutableContext;
  6430. ///////////////////////////////////////////////////////////////////////////
  6431. class RunContext : public IResultCapture, public IRunner {
  6432. public:
  6433. RunContext( RunContext const& ) = delete;
  6434. RunContext& operator =( RunContext const& ) = delete;
  6435. explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter );
  6436. ~RunContext() override;
  6437. void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount );
  6438. void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount );
  6439. Totals runTest(TestCase const& testCase);
  6440. IConfigPtr config() const;
  6441. IStreamingReporter& reporter() const;
  6442. public: // IResultCapture
  6443. // Assertion handlers
  6444. void handleExpr
  6445. ( AssertionInfo const& info,
  6446. ITransientExpression const& expr,
  6447. AssertionReaction& reaction ) override;
  6448. void handleMessage
  6449. ( AssertionInfo const& info,
  6450. ResultWas::OfType resultType,
  6451. StringRef const& message,
  6452. AssertionReaction& reaction ) override;
  6453. void handleUnexpectedExceptionNotThrown
  6454. ( AssertionInfo const& info,
  6455. AssertionReaction& reaction ) override;
  6456. void handleUnexpectedInflightException
  6457. ( AssertionInfo const& info,
  6458. std::string const& message,
  6459. AssertionReaction& reaction ) override;
  6460. void handleIncomplete
  6461. ( AssertionInfo const& info ) override;
  6462. void handleNonExpr
  6463. ( AssertionInfo const &info,
  6464. ResultWas::OfType resultType,
  6465. AssertionReaction &reaction ) override;
  6466. bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override;
  6467. void sectionEnded( SectionEndInfo const& endInfo ) override;
  6468. void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
  6469. auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
  6470. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  6471. void benchmarkPreparing( std::string const& name ) override;
  6472. void benchmarkStarting( BenchmarkInfo const& info ) override;
  6473. void benchmarkEnded( BenchmarkStats<> const& stats ) override;
  6474. void benchmarkFailed( std::string const& error ) override;
  6475. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  6476. void pushScopedMessage( MessageInfo const& message ) override;
  6477. void popScopedMessage( MessageInfo const& message ) override;
  6478. void emplaceUnscopedMessage( MessageBuilder const& builder ) override;
  6479. std::string getCurrentTestName() const override;
  6480. const AssertionResult* getLastResult() const override;
  6481. void exceptionEarlyReported() override;
  6482. void handleFatalErrorCondition( StringRef message ) override;
  6483. bool lastAssertionPassed() override;
  6484. void assertionPassed() override;
  6485. public:
  6486. // !TBD We need to do this another way!
  6487. bool aborting() const final;
  6488. private:
  6489. void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr );
  6490. void invokeActiveTestCase();
  6491. void resetAssertionInfo();
  6492. bool testForMissingAssertions( Counts& assertions );
  6493. void assertionEnded( AssertionResult const& result );
  6494. void reportExpr
  6495. ( AssertionInfo const &info,
  6496. ResultWas::OfType resultType,
  6497. ITransientExpression const *expr,
  6498. bool negated );
  6499. void populateReaction( AssertionReaction& reaction );
  6500. private:
  6501. void handleUnfinishedSections();
  6502. TestRunInfo m_runInfo;
  6503. IMutableContext& m_context;
  6504. TestCase const* m_activeTestCase = nullptr;
  6505. ITracker* m_testCaseTracker = nullptr;
  6506. Option<AssertionResult> m_lastResult;
  6507. IConfigPtr m_config;
  6508. Totals m_totals;
  6509. IStreamingReporterPtr m_reporter;
  6510. std::vector<MessageInfo> m_messages;
  6511. std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */
  6512. AssertionInfo m_lastAssertionInfo;
  6513. std::vector<SectionEndInfo> m_unfinishedSections;
  6514. std::vector<ITracker*> m_activeSections;
  6515. TrackerContext m_trackerContext;
  6516. bool m_lastAssertionPassed = false;
  6517. bool m_shouldReportUnexpected = true;
  6518. bool m_includeSuccessfulResults;
  6519. };
  6520. void seedRng(IConfig const& config);
  6521. unsigned int rngSeed();
  6522. } // end namespace Catch
  6523. // end catch_run_context.h
  6524. namespace Catch {
  6525. namespace {
  6526. auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
  6527. expr.streamReconstructedExpression( os );
  6528. return os;
  6529. }
  6530. }
  6531. LazyExpression::LazyExpression( bool isNegated )
  6532. : m_isNegated( isNegated )
  6533. {}
  6534. LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {}
  6535. LazyExpression::operator bool() const {
  6536. return m_transientExpression != nullptr;
  6537. }
  6538. auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& {
  6539. if( lazyExpr.m_isNegated )
  6540. os << "!";
  6541. if( lazyExpr ) {
  6542. if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )
  6543. os << "(" << *lazyExpr.m_transientExpression << ")";
  6544. else
  6545. os << *lazyExpr.m_transientExpression;
  6546. }
  6547. else {
  6548. os << "{** error - unchecked empty expression requested **}";
  6549. }
  6550. return os;
  6551. }
  6552. AssertionHandler::AssertionHandler
  6553. ( StringRef const& macroName,
  6554. SourceLineInfo const& lineInfo,
  6555. StringRef capturedExpression,
  6556. ResultDisposition::Flags resultDisposition )
  6557. : m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
  6558. m_resultCapture( getResultCapture() )
  6559. {}
  6560. void AssertionHandler::handleExpr( ITransientExpression const& expr ) {
  6561. m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );
  6562. }
  6563. void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) {
  6564. m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction );
  6565. }
  6566. auto AssertionHandler::allowThrows() const -> bool {
  6567. return getCurrentContext().getConfig()->allowThrows();
  6568. }
  6569. void AssertionHandler::complete() {
  6570. setCompleted();
  6571. if( m_reaction.shouldDebugBreak ) {
  6572. // If you find your debugger stopping you here then go one level up on the
  6573. // call-stack for the code that caused it (typically a failed assertion)
  6574. // (To go back to the test and change execution, jump over the throw, next)
  6575. CATCH_BREAK_INTO_DEBUGGER();
  6576. }
  6577. if (m_reaction.shouldThrow) {
  6578. #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  6579. throw Catch::TestFailureException();
  6580. #else
  6581. CATCH_ERROR( "Test failure requires aborting test!" );
  6582. #endif
  6583. }
  6584. }
  6585. void AssertionHandler::setCompleted() {
  6586. m_completed = true;
  6587. }
  6588. void AssertionHandler::handleUnexpectedInflightException() {
  6589. m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );
  6590. }
  6591. void AssertionHandler::handleExceptionThrownAsExpected() {
  6592. m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
  6593. }
  6594. void AssertionHandler::handleExceptionNotThrownAsExpected() {
  6595. m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
  6596. }
  6597. void AssertionHandler::handleUnexpectedExceptionNotThrown() {
  6598. m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction );
  6599. }
  6600. void AssertionHandler::handleThrowingCallSkipped() {
  6601. m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
  6602. }
  6603. // This is the overload that takes a string and infers the Equals matcher from it
  6604. // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
  6605. void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString ) {
  6606. handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
  6607. }
  6608. } // namespace Catch
  6609. // end catch_assertionhandler.cpp
  6610. // start catch_assertionresult.cpp
  6611. namespace Catch {
  6612. AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression):
  6613. lazyExpression(_lazyExpression),
  6614. resultType(_resultType) {}
  6615. std::string AssertionResultData::reconstructExpression() const {
  6616. if( reconstructedExpression.empty() ) {
  6617. if( lazyExpression ) {
  6618. ReusableStringStream rss;
  6619. rss << lazyExpression;
  6620. reconstructedExpression = rss.str();
  6621. }
  6622. }
  6623. return reconstructedExpression;
  6624. }
  6625. AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
  6626. : m_info( info ),
  6627. m_resultData( data )
  6628. {}
  6629. // Result was a success
  6630. bool AssertionResult::succeeded() const {
  6631. return Catch::isOk( m_resultData.resultType );
  6632. }
  6633. // Result was a success, or failure is suppressed
  6634. bool AssertionResult::isOk() const {
  6635. return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
  6636. }
  6637. ResultWas::OfType AssertionResult::getResultType() const {
  6638. return m_resultData.resultType;
  6639. }
  6640. bool AssertionResult::hasExpression() const {
  6641. return !m_info.capturedExpression.empty();
  6642. }
  6643. bool AssertionResult::hasMessage() const {
  6644. return !m_resultData.message.empty();
  6645. }
  6646. std::string AssertionResult::getExpression() const {
  6647. // Possibly overallocating by 3 characters should be basically free
  6648. std::string expr; expr.reserve(m_info.capturedExpression.size() + 3);
  6649. if (isFalseTest(m_info.resultDisposition)) {
  6650. expr += "!(";
  6651. }
  6652. expr += m_info.capturedExpression;
  6653. if (isFalseTest(m_info.resultDisposition)) {
  6654. expr += ')';
  6655. }
  6656. return expr;
  6657. }
  6658. std::string AssertionResult::getExpressionInMacro() const {
  6659. std::string expr;
  6660. if( m_info.macroName.empty() )
  6661. expr = static_cast<std::string>(m_info.capturedExpression);
  6662. else {
  6663. expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
  6664. expr += m_info.macroName;
  6665. expr += "( ";
  6666. expr += m_info.capturedExpression;
  6667. expr += " )";
  6668. }
  6669. return expr;
  6670. }
  6671. bool AssertionResult::hasExpandedExpression() const {
  6672. return hasExpression() && getExpandedExpression() != getExpression();
  6673. }
  6674. std::string AssertionResult::getExpandedExpression() const {
  6675. std::string expr = m_resultData.reconstructExpression();
  6676. return expr.empty()
  6677. ? getExpression()
  6678. : expr;
  6679. }
  6680. std::string AssertionResult::getMessage() const {
  6681. return m_resultData.message;
  6682. }
  6683. SourceLineInfo AssertionResult::getSourceInfo() const {
  6684. return m_info.lineInfo;
  6685. }
  6686. StringRef AssertionResult::getTestMacroName() const {
  6687. return m_info.macroName;
  6688. }
  6689. } // end namespace Catch
  6690. // end catch_assertionresult.cpp
  6691. // start catch_capture_matchers.cpp
  6692. namespace Catch {
  6693. using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
  6694. // This is the general overload that takes a any string matcher
  6695. // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
  6696. // the Equals matcher (so the header does not mention matchers)
  6697. void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString ) {
  6698. std::string exceptionMessage = Catch::translateActiveException();
  6699. MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );
  6700. handler.handleExpr( expr );
  6701. }
  6702. } // namespace Catch
  6703. // end catch_capture_matchers.cpp
  6704. // start catch_commandline.cpp
  6705. // start catch_commandline.h
  6706. // start catch_clara.h
  6707. // Use Catch's value for console width (store Clara's off to the side, if present)
  6708. #ifdef CLARA_CONFIG_CONSOLE_WIDTH
  6709. #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
  6710. #undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
  6711. #endif
  6712. #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1
  6713. #ifdef __clang__
  6714. #pragma clang diagnostic push
  6715. #pragma clang diagnostic ignored "-Wweak-vtables"
  6716. #pragma clang diagnostic ignored "-Wexit-time-destructors"
  6717. #pragma clang diagnostic ignored "-Wshadow"
  6718. #endif
  6719. // start clara.hpp
  6720. // Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
  6721. //
  6722. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  6723. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6724. //
  6725. // See https://github.com/philsquared/Clara for more details
  6726. // Clara v1.1.5
  6727. #ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
  6728. #define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
  6729. #endif
  6730. #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
  6731. #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
  6732. #endif
  6733. #ifndef CLARA_CONFIG_OPTIONAL_TYPE
  6734. #ifdef __has_include
  6735. #if __has_include(<optional>) && __cplusplus >= 201703L
  6736. #include <optional>
  6737. #define CLARA_CONFIG_OPTIONAL_TYPE std::optional
  6738. #endif
  6739. #endif
  6740. #endif
  6741. // ----------- #included from clara_textflow.hpp -----------
  6742. // TextFlowCpp
  6743. //
  6744. // A single-header library for wrapping and laying out basic text, by Phil Nash
  6745. //
  6746. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  6747. // file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6748. //
  6749. // This project is hosted at https://github.com/philsquared/textflowcpp
  6750. #include <cassert>
  6751. #include <ostream>
  6752. #include <sstream>
  6753. #include <vector>
  6754. #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
  6755. #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80
  6756. #endif
  6757. namespace Catch {
  6758. namespace clara {
  6759. namespace TextFlow {
  6760. inline auto isWhitespace(char c) -> bool {
  6761. static std::string chars = " \t\n\r";
  6762. return chars.find(c) != std::string::npos;
  6763. }
  6764. inline auto isBreakableBefore(char c) -> bool {
  6765. static std::string chars = "[({<|";
  6766. return chars.find(c) != std::string::npos;
  6767. }
  6768. inline auto isBreakableAfter(char c) -> bool {
  6769. static std::string chars = "])}>.,:;*+-=&/\\";
  6770. return chars.find(c) != std::string::npos;
  6771. }
  6772. class Columns;
  6773. class Column {
  6774. std::vector<std::string> m_strings;
  6775. size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
  6776. size_t m_indent = 0;
  6777. size_t m_initialIndent = std::string::npos;
  6778. public:
  6779. class iterator {
  6780. friend Column;
  6781. Column const& m_column;
  6782. size_t m_stringIndex = 0;
  6783. size_t m_pos = 0;
  6784. size_t m_len = 0;
  6785. size_t m_end = 0;
  6786. bool m_suffix = false;
  6787. iterator(Column const& column, size_t stringIndex)
  6788. : m_column(column),
  6789. m_stringIndex(stringIndex) {}
  6790. auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
  6791. auto isBoundary(size_t at) const -> bool {
  6792. assert(at > 0);
  6793. assert(at <= line().size());
  6794. return at == line().size() ||
  6795. (isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||
  6796. isBreakableBefore(line()[at]) ||
  6797. isBreakableAfter(line()[at - 1]);
  6798. }
  6799. void calcLength() {
  6800. assert(m_stringIndex < m_column.m_strings.size());
  6801. m_suffix = false;
  6802. auto width = m_column.m_width - indent();
  6803. m_end = m_pos;
  6804. if (line()[m_pos] == '\n') {
  6805. ++m_end;
  6806. }
  6807. while (m_end < line().size() && line()[m_end] != '\n')
  6808. ++m_end;
  6809. if (m_end < m_pos + width) {
  6810. m_len = m_end - m_pos;
  6811. } else {
  6812. size_t len = width;
  6813. while (len > 0 && !isBoundary(m_pos + len))
  6814. --len;
  6815. while (len > 0 && isWhitespace(line()[m_pos + len - 1]))
  6816. --len;
  6817. if (len > 0) {
  6818. m_len = len;
  6819. } else {
  6820. m_suffix = true;
  6821. m_len = width - 1;
  6822. }
  6823. }
  6824. }
  6825. auto indent() const -> size_t {
  6826. auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
  6827. return initial == std::string::npos ? m_column.m_indent : initial;
  6828. }
  6829. auto addIndentAndSuffix(std::string const &plain) const -> std::string {
  6830. return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain);
  6831. }
  6832. public:
  6833. using difference_type = std::ptrdiff_t;
  6834. using value_type = std::string;
  6835. using pointer = value_type * ;
  6836. using reference = value_type & ;
  6837. using iterator_category = std::forward_iterator_tag;
  6838. explicit iterator(Column const& column) : m_column(column) {
  6839. assert(m_column.m_width > m_column.m_indent);
  6840. assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);
  6841. calcLength();
  6842. if (m_len == 0)
  6843. m_stringIndex++; // Empty string
  6844. }
  6845. auto operator *() const -> std::string {
  6846. assert(m_stringIndex < m_column.m_strings.size());
  6847. assert(m_pos <= m_end);
  6848. return addIndentAndSuffix(line().substr(m_pos, m_len));
  6849. }
  6850. auto operator ++() -> iterator& {
  6851. m_pos += m_len;
  6852. if (m_pos < line().size() && line()[m_pos] == '\n')
  6853. m_pos += 1;
  6854. else
  6855. while (m_pos < line().size() && isWhitespace(line()[m_pos]))
  6856. ++m_pos;
  6857. if (m_pos == line().size()) {
  6858. m_pos = 0;
  6859. ++m_stringIndex;
  6860. }
  6861. if (m_stringIndex < m_column.m_strings.size())
  6862. calcLength();
  6863. return *this;
  6864. }
  6865. auto operator ++(int) -> iterator {
  6866. iterator prev(*this);
  6867. operator++();
  6868. return prev;
  6869. }
  6870. auto operator ==(iterator const& other) const -> bool {
  6871. return
  6872. m_pos == other.m_pos &&
  6873. m_stringIndex == other.m_stringIndex &&
  6874. &m_column == &other.m_column;
  6875. }
  6876. auto operator !=(iterator const& other) const -> bool {
  6877. return !operator==(other);
  6878. }
  6879. };
  6880. using const_iterator = iterator;
  6881. explicit Column(std::string const& text) { m_strings.push_back(text); }
  6882. auto width(size_t newWidth) -> Column& {
  6883. assert(newWidth > 0);
  6884. m_width = newWidth;
  6885. return *this;
  6886. }
  6887. auto indent(size_t newIndent) -> Column& {
  6888. m_indent = newIndent;
  6889. return *this;
  6890. }
  6891. auto initialIndent(size_t newIndent) -> Column& {
  6892. m_initialIndent = newIndent;
  6893. return *this;
  6894. }
  6895. auto width() const -> size_t { return m_width; }
  6896. auto begin() const -> iterator { return iterator(*this); }
  6897. auto end() const -> iterator { return { *this, m_strings.size() }; }
  6898. inline friend std::ostream& operator << (std::ostream& os, Column const& col) {
  6899. bool first = true;
  6900. for (auto line : col) {
  6901. if (first)
  6902. first = false;
  6903. else
  6904. os << "\n";
  6905. os << line;
  6906. }
  6907. return os;
  6908. }
  6909. auto operator + (Column const& other)->Columns;
  6910. auto toString() const -> std::string {
  6911. std::ostringstream oss;
  6912. oss << *this;
  6913. return oss.str();
  6914. }
  6915. };
  6916. class Spacer : public Column {
  6917. public:
  6918. explicit Spacer(size_t spaceWidth) : Column("") {
  6919. width(spaceWidth);
  6920. }
  6921. };
  6922. class Columns {
  6923. std::vector<Column> m_columns;
  6924. public:
  6925. class iterator {
  6926. friend Columns;
  6927. struct EndTag {};
  6928. std::vector<Column> const& m_columns;
  6929. std::vector<Column::iterator> m_iterators;
  6930. size_t m_activeIterators;
  6931. iterator(Columns const& columns, EndTag)
  6932. : m_columns(columns.m_columns),
  6933. m_activeIterators(0) {
  6934. m_iterators.reserve(m_columns.size());
  6935. for (auto const& col : m_columns)
  6936. m_iterators.push_back(col.end());
  6937. }
  6938. public:
  6939. using difference_type = std::ptrdiff_t;
  6940. using value_type = std::string;
  6941. using pointer = value_type * ;
  6942. using reference = value_type & ;
  6943. using iterator_category = std::forward_iterator_tag;
  6944. explicit iterator(Columns const& columns)
  6945. : m_columns(columns.m_columns),
  6946. m_activeIterators(m_columns.size()) {
  6947. m_iterators.reserve(m_columns.size());
  6948. for (auto const& col : m_columns)
  6949. m_iterators.push_back(col.begin());
  6950. }
  6951. auto operator ==(iterator const& other) const -> bool {
  6952. return m_iterators == other.m_iterators;
  6953. }
  6954. auto operator !=(iterator const& other) const -> bool {
  6955. return m_iterators != other.m_iterators;
  6956. }
  6957. auto operator *() const -> std::string {
  6958. std::string row, padding;
  6959. for (size_t i = 0; i < m_columns.size(); ++i) {
  6960. auto width = m_columns[i].width();
  6961. if (m_iterators[i] != m_columns[i].end()) {
  6962. std::string col = *m_iterators[i];
  6963. row += padding + col;
  6964. if (col.size() < width)
  6965. padding = std::string(width - col.size(), ' ');
  6966. else
  6967. padding = "";
  6968. } else {
  6969. padding += std::string(width, ' ');
  6970. }
  6971. }
  6972. return row;
  6973. }
  6974. auto operator ++() -> iterator& {
  6975. for (size_t i = 0; i < m_columns.size(); ++i) {
  6976. if (m_iterators[i] != m_columns[i].end())
  6977. ++m_iterators[i];
  6978. }
  6979. return *this;
  6980. }
  6981. auto operator ++(int) -> iterator {
  6982. iterator prev(*this);
  6983. operator++();
  6984. return prev;
  6985. }
  6986. };
  6987. using const_iterator = iterator;
  6988. auto begin() const -> iterator { return iterator(*this); }
  6989. auto end() const -> iterator { return { *this, iterator::EndTag() }; }
  6990. auto operator += (Column const& col) -> Columns& {
  6991. m_columns.push_back(col);
  6992. return *this;
  6993. }
  6994. auto operator + (Column const& col) -> Columns {
  6995. Columns combined = *this;
  6996. combined += col;
  6997. return combined;
  6998. }
  6999. inline friend std::ostream& operator << (std::ostream& os, Columns const& cols) {
  7000. bool first = true;
  7001. for (auto line : cols) {
  7002. if (first)
  7003. first = false;
  7004. else
  7005. os << "\n";
  7006. os << line;
  7007. }
  7008. return os;
  7009. }
  7010. auto toString() const -> std::string {
  7011. std::ostringstream oss;
  7012. oss << *this;
  7013. return oss.str();
  7014. }
  7015. };
  7016. inline auto Column::operator + (Column const& other) -> Columns {
  7017. Columns cols;
  7018. cols += *this;
  7019. cols += other;
  7020. return cols;
  7021. }
  7022. }
  7023. }
  7024. }
  7025. // ----------- end of #include from clara_textflow.hpp -----------
  7026. // ........... back in clara.hpp
  7027. #include <cctype>
  7028. #include <string>
  7029. #include <memory>
  7030. #include <set>
  7031. #include <algorithm>
  7032. #if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )
  7033. #define CATCH_PLATFORM_WINDOWS
  7034. #endif
  7035. namespace Catch { namespace clara {
  7036. namespace detail {
  7037. // Traits for extracting arg and return type of lambdas (for single argument lambdas)
  7038. template<typename L>
  7039. struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {};
  7040. template<typename ClassT, typename ReturnT, typename... Args>
  7041. struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> {
  7042. static const bool isValid = false;
  7043. };
  7044. template<typename ClassT, typename ReturnT, typename ArgT>
  7045. struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
  7046. static const bool isValid = true;
  7047. using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
  7048. using ReturnType = ReturnT;
  7049. };
  7050. class TokenStream;
  7051. // Transport for raw args (copied from main args, or supplied via init list for testing)
  7052. class Args {
  7053. friend TokenStream;
  7054. std::string m_exeName;
  7055. std::vector<std::string> m_args;
  7056. public:
  7057. Args( int argc, char const* const* argv )
  7058. : m_exeName(argv[0]),
  7059. m_args(argv + 1, argv + argc) {}
  7060. Args( std::initializer_list<std::string> args )
  7061. : m_exeName( *args.begin() ),
  7062. m_args( args.begin()+1, args.end() )
  7063. {}
  7064. auto exeName() const -> std::string {
  7065. return m_exeName;
  7066. }
  7067. };
  7068. // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string
  7069. // may encode an option + its argument if the : or = form is used
  7070. enum class TokenType {
  7071. Option, Argument
  7072. };
  7073. struct Token {
  7074. TokenType type;
  7075. std::string token;
  7076. };
  7077. inline auto isOptPrefix( char c ) -> bool {
  7078. return c == '-'
  7079. #ifdef CATCH_PLATFORM_WINDOWS
  7080. || c == '/'
  7081. #endif
  7082. ;
  7083. }
  7084. // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
  7085. class TokenStream {
  7086. using Iterator = std::vector<std::string>::const_iterator;
  7087. Iterator it;
  7088. Iterator itEnd;
  7089. std::vector<Token> m_tokenBuffer;
  7090. void loadBuffer() {
  7091. m_tokenBuffer.resize( 0 );
  7092. // Skip any empty strings
  7093. while( it != itEnd && it->empty() )
  7094. ++it;
  7095. if( it != itEnd ) {
  7096. auto const &next = *it;
  7097. if( isOptPrefix( next[0] ) ) {
  7098. auto delimiterPos = next.find_first_of( " :=" );
  7099. if( delimiterPos != std::string::npos ) {
  7100. m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
  7101. m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } );
  7102. } else {
  7103. if( next[1] != '-' && next.size() > 2 ) {
  7104. std::string opt = "- ";
  7105. for( size_t i = 1; i < next.size(); ++i ) {
  7106. opt[1] = next[i];
  7107. m_tokenBuffer.push_back( { TokenType::Option, opt } );
  7108. }
  7109. } else {
  7110. m_tokenBuffer.push_back( { TokenType::Option, next } );
  7111. }
  7112. }
  7113. } else {
  7114. m_tokenBuffer.push_back( { TokenType::Argument, next } );
  7115. }
  7116. }
  7117. }
  7118. public:
  7119. explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {}
  7120. TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) {
  7121. loadBuffer();
  7122. }
  7123. explicit operator bool() const {
  7124. return !m_tokenBuffer.empty() || it != itEnd;
  7125. }
  7126. auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }
  7127. auto operator*() const -> Token {
  7128. assert( !m_tokenBuffer.empty() );
  7129. return m_tokenBuffer.front();
  7130. }
  7131. auto operator->() const -> Token const * {
  7132. assert( !m_tokenBuffer.empty() );
  7133. return &m_tokenBuffer.front();
  7134. }
  7135. auto operator++() -> TokenStream & {
  7136. if( m_tokenBuffer.size() >= 2 ) {
  7137. m_tokenBuffer.erase( m_tokenBuffer.begin() );
  7138. } else {
  7139. if( it != itEnd )
  7140. ++it;
  7141. loadBuffer();
  7142. }
  7143. return *this;
  7144. }
  7145. };
  7146. class ResultBase {
  7147. public:
  7148. enum Type {
  7149. Ok, LogicError, RuntimeError
  7150. };
  7151. protected:
  7152. ResultBase( Type type ) : m_type( type ) {}
  7153. virtual ~ResultBase() = default;
  7154. virtual void enforceOk() const = 0;
  7155. Type m_type;
  7156. };
  7157. template<typename T>
  7158. class ResultValueBase : public ResultBase {
  7159. public:
  7160. auto value() const -> T const & {
  7161. enforceOk();
  7162. return m_value;
  7163. }
  7164. protected:
  7165. ResultValueBase( Type type ) : ResultBase( type ) {}
  7166. ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) {
  7167. if( m_type == ResultBase::Ok )
  7168. new( &m_value ) T( other.m_value );
  7169. }
  7170. ResultValueBase( Type, T const &value ) : ResultBase( Ok ) {
  7171. new( &m_value ) T( value );
  7172. }
  7173. auto operator=( ResultValueBase const &other ) -> ResultValueBase & {
  7174. if( m_type == ResultBase::Ok )
  7175. m_value.~T();
  7176. ResultBase::operator=(other);
  7177. if( m_type == ResultBase::Ok )
  7178. new( &m_value ) T( other.m_value );
  7179. return *this;
  7180. }
  7181. ~ResultValueBase() override {
  7182. if( m_type == Ok )
  7183. m_value.~T();
  7184. }
  7185. union {
  7186. T m_value;
  7187. };
  7188. };
  7189. template<>
  7190. class ResultValueBase<void> : public ResultBase {
  7191. protected:
  7192. using ResultBase::ResultBase;
  7193. };
  7194. template<typename T = void>
  7195. class BasicResult : public ResultValueBase<T> {
  7196. public:
  7197. template<typename U>
  7198. explicit BasicResult( BasicResult<U> const &other )
  7199. : ResultValueBase<T>( other.type() ),
  7200. m_errorMessage( other.errorMessage() )
  7201. {
  7202. assert( type() != ResultBase::Ok );
  7203. }
  7204. template<typename U>
  7205. static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; }
  7206. static auto ok() -> BasicResult { return { ResultBase::Ok }; }
  7207. static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; }
  7208. static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; }
  7209. explicit operator bool() const { return m_type == ResultBase::Ok; }
  7210. auto type() const -> ResultBase::Type { return m_type; }
  7211. auto errorMessage() const -> std::string { return m_errorMessage; }
  7212. protected:
  7213. void enforceOk() const override {
  7214. // Errors shouldn't reach this point, but if they do
  7215. // the actual error message will be in m_errorMessage
  7216. assert( m_type != ResultBase::LogicError );
  7217. assert( m_type != ResultBase::RuntimeError );
  7218. if( m_type != ResultBase::Ok )
  7219. std::abort();
  7220. }
  7221. std::string m_errorMessage; // Only populated if resultType is an error
  7222. BasicResult( ResultBase::Type type, std::string const &message )
  7223. : ResultValueBase<T>(type),
  7224. m_errorMessage(message)
  7225. {
  7226. assert( m_type != ResultBase::Ok );
  7227. }
  7228. using ResultValueBase<T>::ResultValueBase;
  7229. using ResultBase::m_type;
  7230. };
  7231. enum class ParseResultType {
  7232. Matched, NoMatch, ShortCircuitAll, ShortCircuitSame
  7233. };
  7234. class ParseState {
  7235. public:
  7236. ParseState( ParseResultType type, TokenStream const &remainingTokens )
  7237. : m_type(type),
  7238. m_remainingTokens( remainingTokens )
  7239. {}
  7240. auto type() const -> ParseResultType { return m_type; }
  7241. auto remainingTokens() const -> TokenStream { return m_remainingTokens; }
  7242. private:
  7243. ParseResultType m_type;
  7244. TokenStream m_remainingTokens;
  7245. };
  7246. using Result = BasicResult<void>;
  7247. using ParserResult = BasicResult<ParseResultType>;
  7248. using InternalParseResult = BasicResult<ParseState>;
  7249. struct HelpColumns {
  7250. std::string left;
  7251. std::string right;
  7252. };
  7253. template<typename T>
  7254. inline auto convertInto( std::string const &source, T& target ) -> ParserResult {
  7255. std::stringstream ss;
  7256. ss << source;
  7257. ss >> target;
  7258. if( ss.fail() )
  7259. return ParserResult::runtimeError( "Unable to convert '" + source + "' to destination type" );
  7260. else
  7261. return ParserResult::ok( ParseResultType::Matched );
  7262. }
  7263. inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult {
  7264. target = source;
  7265. return ParserResult::ok( ParseResultType::Matched );
  7266. }
  7267. inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {
  7268. std::string srcLC = source;
  7269. std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast<char>( std::tolower(c) ); } );
  7270. if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
  7271. target = true;
  7272. else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
  7273. target = false;
  7274. else
  7275. return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" );
  7276. return ParserResult::ok( ParseResultType::Matched );
  7277. }
  7278. #ifdef CLARA_CONFIG_OPTIONAL_TYPE
  7279. template<typename T>
  7280. inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target ) -> ParserResult {
  7281. T temp;
  7282. auto result = convertInto( source, temp );
  7283. if( result )
  7284. target = std::move(temp);
  7285. return result;
  7286. }
  7287. #endif // CLARA_CONFIG_OPTIONAL_TYPE
  7288. struct NonCopyable {
  7289. NonCopyable() = default;
  7290. NonCopyable( NonCopyable const & ) = delete;
  7291. NonCopyable( NonCopyable && ) = delete;
  7292. NonCopyable &operator=( NonCopyable const & ) = delete;
  7293. NonCopyable &operator=( NonCopyable && ) = delete;
  7294. };
  7295. struct BoundRef : NonCopyable {
  7296. virtual ~BoundRef() = default;
  7297. virtual auto isContainer() const -> bool { return false; }
  7298. virtual auto isFlag() const -> bool { return false; }
  7299. };
  7300. struct BoundValueRefBase : BoundRef {
  7301. virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
  7302. };
  7303. struct BoundFlagRefBase : BoundRef {
  7304. virtual auto setFlag( bool flag ) -> ParserResult = 0;
  7305. virtual auto isFlag() const -> bool { return true; }
  7306. };
  7307. template<typename T>
  7308. struct BoundValueRef : BoundValueRefBase {
  7309. T &m_ref;
  7310. explicit BoundValueRef( T &ref ) : m_ref( ref ) {}
  7311. auto setValue( std::string const &arg ) -> ParserResult override {
  7312. return convertInto( arg, m_ref );
  7313. }
  7314. };
  7315. template<typename T>
  7316. struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
  7317. std::vector<T> &m_ref;
  7318. explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}
  7319. auto isContainer() const -> bool override { return true; }
  7320. auto setValue( std::string const &arg ) -> ParserResult override {
  7321. T temp;
  7322. auto result = convertInto( arg, temp );
  7323. if( result )
  7324. m_ref.push_back( temp );
  7325. return result;
  7326. }
  7327. };
  7328. struct BoundFlagRef : BoundFlagRefBase {
  7329. bool &m_ref;
  7330. explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {}
  7331. auto setFlag( bool flag ) -> ParserResult override {
  7332. m_ref = flag;
  7333. return ParserResult::ok( ParseResultType::Matched );
  7334. }
  7335. };
  7336. template<typename ReturnType>
  7337. struct LambdaInvoker {
  7338. static_assert( std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult" );
  7339. template<typename L, typename ArgType>
  7340. static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
  7341. return lambda( arg );
  7342. }
  7343. };
  7344. template<>
  7345. struct LambdaInvoker<void> {
  7346. template<typename L, typename ArgType>
  7347. static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
  7348. lambda( arg );
  7349. return ParserResult::ok( ParseResultType::Matched );
  7350. }
  7351. };
  7352. template<typename ArgType, typename L>
  7353. inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
  7354. ArgType temp{};
  7355. auto result = convertInto( arg, temp );
  7356. return !result
  7357. ? result
  7358. : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
  7359. }
  7360. template<typename L>
  7361. struct BoundLambda : BoundValueRefBase {
  7362. L m_lambda;
  7363. static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
  7364. explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {}
  7365. auto setValue( std::string const &arg ) -> ParserResult override {
  7366. return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg );
  7367. }
  7368. };
  7369. template<typename L>
  7370. struct BoundFlagLambda : BoundFlagRefBase {
  7371. L m_lambda;
  7372. static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
  7373. static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean" );
  7374. explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {}
  7375. auto setFlag( bool flag ) -> ParserResult override {
  7376. return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag );
  7377. }
  7378. };
  7379. enum class Optionality { Optional, Required };
  7380. struct Parser;
  7381. class ParserBase {
  7382. public:
  7383. virtual ~ParserBase() = default;
  7384. virtual auto validate() const -> Result { return Result::ok(); }
  7385. virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult = 0;
  7386. virtual auto cardinality() const -> size_t { return 1; }
  7387. auto parse( Args const &args ) const -> InternalParseResult {
  7388. return parse( args.exeName(), TokenStream( args ) );
  7389. }
  7390. };
  7391. template<typename DerivedT>
  7392. class ComposableParserImpl : public ParserBase {
  7393. public:
  7394. template<typename T>
  7395. auto operator|( T const &other ) const -> Parser;
  7396. template<typename T>
  7397. auto operator+( T const &other ) const -> Parser;
  7398. };
  7399. // Common code and state for Args and Opts
  7400. template<typename DerivedT>
  7401. class ParserRefImpl : public ComposableParserImpl<DerivedT> {
  7402. protected:
  7403. Optionality m_optionality = Optionality::Optional;
  7404. std::shared_ptr<BoundRef> m_ref;
  7405. std::string m_hint;
  7406. std::string m_description;
  7407. explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}
  7408. public:
  7409. template<typename T>
  7410. ParserRefImpl( T &ref, std::string const &hint )
  7411. : m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
  7412. m_hint( hint )
  7413. {}
  7414. template<typename LambdaT>
  7415. ParserRefImpl( LambdaT const &ref, std::string const &hint )
  7416. : m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
  7417. m_hint(hint)
  7418. {}
  7419. auto operator()( std::string const &description ) -> DerivedT & {
  7420. m_description = description;
  7421. return static_cast<DerivedT &>( *this );
  7422. }
  7423. auto optional() -> DerivedT & {
  7424. m_optionality = Optionality::Optional;
  7425. return static_cast<DerivedT &>( *this );
  7426. };
  7427. auto required() -> DerivedT & {
  7428. m_optionality = Optionality::Required;
  7429. return static_cast<DerivedT &>( *this );
  7430. };
  7431. auto isOptional() const -> bool {
  7432. return m_optionality == Optionality::Optional;
  7433. }
  7434. auto cardinality() const -> size_t override {
  7435. if( m_ref->isContainer() )
  7436. return 0;
  7437. else
  7438. return 1;
  7439. }
  7440. auto hint() const -> std::string { return m_hint; }
  7441. };
  7442. class ExeName : public ComposableParserImpl<ExeName> {
  7443. std::shared_ptr<std::string> m_name;
  7444. std::shared_ptr<BoundValueRefBase> m_ref;
  7445. template<typename LambdaT>
  7446. static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
  7447. return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
  7448. }
  7449. public:
  7450. ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
  7451. explicit ExeName( std::string &ref ) : ExeName() {
  7452. m_ref = std::make_shared<BoundValueRef<std::string>>( ref );
  7453. }
  7454. template<typename LambdaT>
  7455. explicit ExeName( LambdaT const& lambda ) : ExeName() {
  7456. m_ref = std::make_shared<BoundLambda<LambdaT>>( lambda );
  7457. }
  7458. // The exe name is not parsed out of the normal tokens, but is handled specially
  7459. auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
  7460. return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
  7461. }
  7462. auto name() const -> std::string { return *m_name; }
  7463. auto set( std::string const& newName ) -> ParserResult {
  7464. auto lastSlash = newName.find_last_of( "\\/" );
  7465. auto filename = ( lastSlash == std::string::npos )
  7466. ? newName
  7467. : newName.substr( lastSlash+1 );
  7468. *m_name = filename;
  7469. if( m_ref )
  7470. return m_ref->setValue( filename );
  7471. else
  7472. return ParserResult::ok( ParseResultType::Matched );
  7473. }
  7474. };
  7475. class Arg : public ParserRefImpl<Arg> {
  7476. public:
  7477. using ParserRefImpl::ParserRefImpl;
  7478. auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override {
  7479. auto validationResult = validate();
  7480. if( !validationResult )
  7481. return InternalParseResult( validationResult );
  7482. auto remainingTokens = tokens;
  7483. auto const &token = *remainingTokens;
  7484. if( token.type != TokenType::Argument )
  7485. return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
  7486. assert( !m_ref->isFlag() );
  7487. auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
  7488. auto result = valueRef->setValue( remainingTokens->token );
  7489. if( !result )
  7490. return InternalParseResult( result );
  7491. else
  7492. return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
  7493. }
  7494. };
  7495. inline auto normaliseOpt( std::string const &optName ) -> std::string {
  7496. #ifdef CATCH_PLATFORM_WINDOWS
  7497. if( optName[0] == '/' )
  7498. return "-" + optName.substr( 1 );
  7499. else
  7500. #endif
  7501. return optName;
  7502. }
  7503. class Opt : public ParserRefImpl<Opt> {
  7504. protected:
  7505. std::vector<std::string> m_optNames;
  7506. public:
  7507. template<typename LambdaT>
  7508. explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {}
  7509. explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {}
  7510. template<typename LambdaT>
  7511. Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
  7512. template<typename T>
  7513. Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
  7514. auto operator[]( std::string const &optName ) -> Opt & {
  7515. m_optNames.push_back( optName );
  7516. return *this;
  7517. }
  7518. auto getHelpColumns() const -> std::vector<HelpColumns> {
  7519. std::ostringstream oss;
  7520. bool first = true;
  7521. for( auto const &opt : m_optNames ) {
  7522. if (first)
  7523. first = false;
  7524. else
  7525. oss << ", ";
  7526. oss << opt;
  7527. }
  7528. if( !m_hint.empty() )
  7529. oss << " <" << m_hint << ">";
  7530. return { { oss.str(), m_description } };
  7531. }
  7532. auto isMatch( std::string const &optToken ) const -> bool {
  7533. auto normalisedToken = normaliseOpt( optToken );
  7534. for( auto const &name : m_optNames ) {
  7535. if( normaliseOpt( name ) == normalisedToken )
  7536. return true;
  7537. }
  7538. return false;
  7539. }
  7540. using ParserBase::parse;
  7541. auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
  7542. auto validationResult = validate();
  7543. if( !validationResult )
  7544. return InternalParseResult( validationResult );
  7545. auto remainingTokens = tokens;
  7546. if( remainingTokens && remainingTokens->type == TokenType::Option ) {
  7547. auto const &token = *remainingTokens;
  7548. if( isMatch(token.token ) ) {
  7549. if( m_ref->isFlag() ) {
  7550. auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() );
  7551. auto result = flagRef->setFlag( true );
  7552. if( !result )
  7553. return InternalParseResult( result );
  7554. if( result.value() == ParseResultType::ShortCircuitAll )
  7555. return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
  7556. } else {
  7557. auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
  7558. ++remainingTokens;
  7559. if( !remainingTokens )
  7560. return InternalParseResult::runtimeError( "Expected argument following " + token.token );
  7561. auto const &argToken = *remainingTokens;
  7562. if( argToken.type != TokenType::Argument )
  7563. return InternalParseResult::runtimeError( "Expected argument following " + token.token );
  7564. auto result = valueRef->setValue( argToken.token );
  7565. if( !result )
  7566. return InternalParseResult( result );
  7567. if( result.value() == ParseResultType::ShortCircuitAll )
  7568. return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
  7569. }
  7570. return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
  7571. }
  7572. }
  7573. return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
  7574. }
  7575. auto validate() const -> Result override {
  7576. if( m_optNames.empty() )
  7577. return Result::logicError( "No options supplied to Opt" );
  7578. for( auto const &name : m_optNames ) {
  7579. if( name.empty() )
  7580. return Result::logicError( "Option name cannot be empty" );
  7581. #ifdef CATCH_PLATFORM_WINDOWS
  7582. if( name[0] != '-' && name[0] != '/' )
  7583. return Result::logicError( "Option name must begin with '-' or '/'" );
  7584. #else
  7585. if( name[0] != '-' )
  7586. return Result::logicError( "Option name must begin with '-'" );
  7587. #endif
  7588. }
  7589. return ParserRefImpl::validate();
  7590. }
  7591. };
  7592. struct Help : Opt {
  7593. Help( bool &showHelpFlag )
  7594. : Opt([&]( bool flag ) {
  7595. showHelpFlag = flag;
  7596. return ParserResult::ok( ParseResultType::ShortCircuitAll );
  7597. })
  7598. {
  7599. static_cast<Opt &>( *this )
  7600. ("display usage information")
  7601. ["-?"]["-h"]["--help"]
  7602. .optional();
  7603. }
  7604. };
  7605. struct Parser : ParserBase {
  7606. mutable ExeName m_exeName;
  7607. std::vector<Opt> m_options;
  7608. std::vector<Arg> m_args;
  7609. auto operator|=( ExeName const &exeName ) -> Parser & {
  7610. m_exeName = exeName;
  7611. return *this;
  7612. }
  7613. auto operator|=( Arg const &arg ) -> Parser & {
  7614. m_args.push_back(arg);
  7615. return *this;
  7616. }
  7617. auto operator|=( Opt const &opt ) -> Parser & {
  7618. m_options.push_back(opt);
  7619. return *this;
  7620. }
  7621. auto operator|=( Parser const &other ) -> Parser & {
  7622. m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
  7623. m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
  7624. return *this;
  7625. }
  7626. template<typename T>
  7627. auto operator|( T const &other ) const -> Parser {
  7628. return Parser( *this ) |= other;
  7629. }
  7630. // Forward deprecated interface with '+' instead of '|'
  7631. template<typename T>
  7632. auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }
  7633. template<typename T>
  7634. auto operator+( T const &other ) const -> Parser { return operator|( other ); }
  7635. auto getHelpColumns() const -> std::vector<HelpColumns> {
  7636. std::vector<HelpColumns> cols;
  7637. for (auto const &o : m_options) {
  7638. auto childCols = o.getHelpColumns();
  7639. cols.insert( cols.end(), childCols.begin(), childCols.end() );
  7640. }
  7641. return cols;
  7642. }
  7643. void writeToStream( std::ostream &os ) const {
  7644. if (!m_exeName.name().empty()) {
  7645. os << "usage:\n" << " " << m_exeName.name() << " ";
  7646. bool required = true, first = true;
  7647. for( auto const &arg : m_args ) {
  7648. if (first)
  7649. first = false;
  7650. else
  7651. os << " ";
  7652. if( arg.isOptional() && required ) {
  7653. os << "[";
  7654. required = false;
  7655. }
  7656. os << "<" << arg.hint() << ">";
  7657. if( arg.cardinality() == 0 )
  7658. os << " ... ";
  7659. }
  7660. if( !required )
  7661. os << "]";
  7662. if( !m_options.empty() )
  7663. os << " options";
  7664. os << "\n\nwhere options are:" << std::endl;
  7665. }
  7666. auto rows = getHelpColumns();
  7667. size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
  7668. size_t optWidth = 0;
  7669. for( auto const &cols : rows )
  7670. optWidth = (std::max)(optWidth, cols.left.size() + 2);
  7671. optWidth = (std::min)(optWidth, consoleWidth/2);
  7672. for( auto const &cols : rows ) {
  7673. auto row =
  7674. TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
  7675. TextFlow::Spacer(4) +
  7676. TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth );
  7677. os << row << std::endl;
  7678. }
  7679. }
  7680. friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& {
  7681. parser.writeToStream( os );
  7682. return os;
  7683. }
  7684. auto validate() const -> Result override {
  7685. for( auto const &opt : m_options ) {
  7686. auto result = opt.validate();
  7687. if( !result )
  7688. return result;
  7689. }
  7690. for( auto const &arg : m_args ) {
  7691. auto result = arg.validate();
  7692. if( !result )
  7693. return result;
  7694. }
  7695. return Result::ok();
  7696. }
  7697. using ParserBase::parse;
  7698. auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override {
  7699. struct ParserInfo {
  7700. ParserBase const* parser = nullptr;
  7701. size_t count = 0;
  7702. };
  7703. const size_t totalParsers = m_options.size() + m_args.size();
  7704. assert( totalParsers < 512 );
  7705. // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
  7706. ParserInfo parseInfos[512];
  7707. {
  7708. size_t i = 0;
  7709. for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
  7710. for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
  7711. }
  7712. m_exeName.set( exeName );
  7713. auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
  7714. while( result.value().remainingTokens() ) {
  7715. bool tokenParsed = false;
  7716. for( size_t i = 0; i < totalParsers; ++i ) {
  7717. auto& parseInfo = parseInfos[i];
  7718. if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {
  7719. result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
  7720. if (!result)
  7721. return result;
  7722. if (result.value().type() != ParseResultType::NoMatch) {
  7723. tokenParsed = true;
  7724. ++parseInfo.count;
  7725. break;
  7726. }
  7727. }
  7728. }
  7729. if( result.value().type() == ParseResultType::ShortCircuitAll )
  7730. return result;
  7731. if( !tokenParsed )
  7732. return InternalParseResult::runtimeError( "Unrecognised token: " + result.value().remainingTokens()->token );
  7733. }
  7734. // !TBD Check missing required options
  7735. return result;
  7736. }
  7737. };
  7738. template<typename DerivedT>
  7739. template<typename T>
  7740. auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser {
  7741. return Parser() | static_cast<DerivedT const &>( *this ) | other;
  7742. }
  7743. } // namespace detail
  7744. // A Combined parser
  7745. using detail::Parser;
  7746. // A parser for options
  7747. using detail::Opt;
  7748. // A parser for arguments
  7749. using detail::Arg;
  7750. // Wrapper for argc, argv from main()
  7751. using detail::Args;
  7752. // Specifies the name of the executable
  7753. using detail::ExeName;
  7754. // Convenience wrapper for option parser that specifies the help option
  7755. using detail::Help;
  7756. // enum of result types from a parse
  7757. using detail::ParseResultType;
  7758. // Result type for parser operation
  7759. using detail::ParserResult;
  7760. }} // namespace Catch::clara
  7761. // end clara.hpp
  7762. #ifdef __clang__
  7763. #pragma clang diagnostic pop
  7764. #endif
  7765. // Restore Clara's value for console width, if present
  7766. #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
  7767. #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
  7768. #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
  7769. #endif
  7770. // end catch_clara.h
  7771. namespace Catch {
  7772. clara::Parser makeCommandLineParser( ConfigData& config );
  7773. } // end namespace Catch
  7774. // end catch_commandline.h
  7775. #include <fstream>
  7776. #include <ctime>
  7777. namespace Catch {
  7778. clara::Parser makeCommandLineParser( ConfigData& config ) {
  7779. using namespace clara;
  7780. auto const setWarning = [&]( std::string const& warning ) {
  7781. auto warningSet = [&]() {
  7782. if( warning == "NoAssertions" )
  7783. return WarnAbout::NoAssertions;
  7784. if ( warning == "NoTests" )
  7785. return WarnAbout::NoTests;
  7786. return WarnAbout::Nothing;
  7787. }();
  7788. if (warningSet == WarnAbout::Nothing)
  7789. return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" );
  7790. config.warnings = static_cast<WarnAbout::What>( config.warnings | warningSet );
  7791. return ParserResult::ok( ParseResultType::Matched );
  7792. };
  7793. auto const loadTestNamesFromFile = [&]( std::string const& filename ) {
  7794. std::ifstream f( filename.c_str() );
  7795. if( !f.is_open() )
  7796. return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" );
  7797. std::string line;
  7798. while( std::getline( f, line ) ) {
  7799. line = trim(line);
  7800. if( !line.empty() && !startsWith( line, '#' ) ) {
  7801. if( !startsWith( line, '"' ) )
  7802. line = '"' + line + '"';
  7803. config.testsOrTags.push_back( line );
  7804. config.testsOrTags.push_back( "," );
  7805. }
  7806. }
  7807. //Remove comma in the end
  7808. if(!config.testsOrTags.empty())
  7809. config.testsOrTags.erase( config.testsOrTags.end()-1 );
  7810. return ParserResult::ok( ParseResultType::Matched );
  7811. };
  7812. auto const setTestOrder = [&]( std::string const& order ) {
  7813. if( startsWith( "declared", order ) )
  7814. config.runOrder = RunTests::InDeclarationOrder;
  7815. else if( startsWith( "lexical", order ) )
  7816. config.runOrder = RunTests::InLexicographicalOrder;
  7817. else if( startsWith( "random", order ) )
  7818. config.runOrder = RunTests::InRandomOrder;
  7819. else
  7820. return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" );
  7821. return ParserResult::ok( ParseResultType::Matched );
  7822. };
  7823. auto const setRngSeed = [&]( std::string const& seed ) {
  7824. if( seed != "time" )
  7825. return clara::detail::convertInto( seed, config.rngSeed );
  7826. config.rngSeed = static_cast<unsigned int>( std::time(nullptr) );
  7827. return ParserResult::ok( ParseResultType::Matched );
  7828. };
  7829. auto const setColourUsage = [&]( std::string const& useColour ) {
  7830. auto mode = toLower( useColour );
  7831. if( mode == "yes" )
  7832. config.useColour = UseColour::Yes;
  7833. else if( mode == "no" )
  7834. config.useColour = UseColour::No;
  7835. else if( mode == "auto" )
  7836. config.useColour = UseColour::Auto;
  7837. else
  7838. return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" );
  7839. return ParserResult::ok( ParseResultType::Matched );
  7840. };
  7841. auto const setWaitForKeypress = [&]( std::string const& keypress ) {
  7842. auto keypressLc = toLower( keypress );
  7843. if( keypressLc == "start" )
  7844. config.waitForKeypress = WaitForKeypress::BeforeStart;
  7845. else if( keypressLc == "exit" )
  7846. config.waitForKeypress = WaitForKeypress::BeforeExit;
  7847. else if( keypressLc == "both" )
  7848. config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
  7849. else
  7850. return ParserResult::runtimeError( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" );
  7851. return ParserResult::ok( ParseResultType::Matched );
  7852. };
  7853. auto const setVerbosity = [&]( std::string const& verbosity ) {
  7854. auto lcVerbosity = toLower( verbosity );
  7855. if( lcVerbosity == "quiet" )
  7856. config.verbosity = Verbosity::Quiet;
  7857. else if( lcVerbosity == "normal" )
  7858. config.verbosity = Verbosity::Normal;
  7859. else if( lcVerbosity == "high" )
  7860. config.verbosity = Verbosity::High;
  7861. else
  7862. return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" );
  7863. return ParserResult::ok( ParseResultType::Matched );
  7864. };
  7865. auto const setReporter = [&]( std::string const& reporter ) {
  7866. IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
  7867. auto lcReporter = toLower( reporter );
  7868. auto result = factories.find( lcReporter );
  7869. if( factories.end() != result )
  7870. config.reporterName = lcReporter;
  7871. else
  7872. return ParserResult::runtimeError( "Unrecognized reporter, '" + reporter + "'. Check available with --list-reporters" );
  7873. return ParserResult::ok( ParseResultType::Matched );
  7874. };
  7875. auto cli
  7876. = ExeName( config.processName )
  7877. | Help( config.showHelp )
  7878. | Opt( config.listTests )
  7879. ["-l"]["--list-tests"]
  7880. ( "list all/matching test cases" )
  7881. | Opt( config.listTags )
  7882. ["-t"]["--list-tags"]
  7883. ( "list all/matching tags" )
  7884. | Opt( config.showSuccessfulTests )
  7885. ["-s"]["--success"]
  7886. ( "include successful tests in output" )
  7887. | Opt( config.shouldDebugBreak )
  7888. ["-b"]["--break"]
  7889. ( "break into debugger on failure" )
  7890. | Opt( config.noThrow )
  7891. ["-e"]["--nothrow"]
  7892. ( "skip exception tests" )
  7893. | Opt( config.showInvisibles )
  7894. ["-i"]["--invisibles"]
  7895. ( "show invisibles (tabs, newlines)" )
  7896. | Opt( config.outputFilename, "filename" )
  7897. ["-o"]["--out"]
  7898. ( "output filename" )
  7899. | Opt( setReporter, "name" )
  7900. ["-r"]["--reporter"]
  7901. ( "reporter to use (defaults to console)" )
  7902. | Opt( config.name, "name" )
  7903. ["-n"]["--name"]
  7904. ( "suite name" )
  7905. | Opt( [&]( bool ){ config.abortAfter = 1; } )
  7906. ["-a"]["--abort"]
  7907. ( "abort at first failure" )
  7908. | Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" )
  7909. ["-x"]["--abortx"]
  7910. ( "abort after x failures" )
  7911. | Opt( setWarning, "warning name" )
  7912. ["-w"]["--warn"]
  7913. ( "enable warnings" )
  7914. | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" )
  7915. ["-d"]["--durations"]
  7916. ( "show test durations" )
  7917. | Opt( loadTestNamesFromFile, "filename" )
  7918. ["-f"]["--input-file"]
  7919. ( "load test names to run from a file" )
  7920. | Opt( config.filenamesAsTags )
  7921. ["-#"]["--filenames-as-tags"]
  7922. ( "adds a tag for the filename" )
  7923. | Opt( config.sectionsToRun, "section name" )
  7924. ["-c"]["--section"]
  7925. ( "specify section to run" )
  7926. | Opt( setVerbosity, "quiet|normal|high" )
  7927. ["-v"]["--verbosity"]
  7928. ( "set output verbosity" )
  7929. | Opt( config.listTestNamesOnly )
  7930. ["--list-test-names-only"]
  7931. ( "list all/matching test cases names only" )
  7932. | Opt( config.listReporters )
  7933. ["--list-reporters"]
  7934. ( "list all reporters" )
  7935. | Opt( setTestOrder, "decl|lex|rand" )
  7936. ["--order"]
  7937. ( "test case order (defaults to decl)" )
  7938. | Opt( setRngSeed, "'time'|number" )
  7939. ["--rng-seed"]
  7940. ( "set a specific seed for random numbers" )
  7941. | Opt( setColourUsage, "yes|no" )
  7942. ["--use-colour"]
  7943. ( "should output be colourised" )
  7944. | Opt( config.libIdentify )
  7945. ["--libidentify"]
  7946. ( "report name and version according to libidentify standard" )
  7947. | Opt( setWaitForKeypress, "start|exit|both" )
  7948. ["--wait-for-keypress"]
  7949. ( "waits for a keypress before exiting" )
  7950. | Opt( config.benchmarkSamples, "samples" )
  7951. ["--benchmark-samples"]
  7952. ( "number of samples to collect (default: 100)" )
  7953. | Opt( config.benchmarkResamples, "resamples" )
  7954. ["--benchmark-resamples"]
  7955. ( "number of resamples for the bootstrap (default: 100000)" )
  7956. | Opt( config.benchmarkConfidenceInterval, "confidence interval" )
  7957. ["--benchmark-confidence-interval"]
  7958. ( "confidence interval for the bootstrap (between 0 and 1, default: 0.95)" )
  7959. | Opt( config.benchmarkNoAnalysis )
  7960. ["--benchmark-no-analysis"]
  7961. ( "perform only measurements; do not perform any analysis" )
  7962. | Arg( config.testsOrTags, "test name|pattern|tags" )
  7963. ( "which test or tests to use" );
  7964. return cli;
  7965. }
  7966. } // end namespace Catch
  7967. // end catch_commandline.cpp
  7968. // start catch_common.cpp
  7969. #include <cstring>
  7970. #include <ostream>
  7971. namespace Catch {
  7972. bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {
  7973. return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
  7974. }
  7975. bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {
  7976. // We can assume that the same file will usually have the same pointer.
  7977. // Thus, if the pointers are the same, there is no point in calling the strcmp
  7978. return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));
  7979. }
  7980. std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
  7981. #ifndef __GNUG__
  7982. os << info.file << '(' << info.line << ')';
  7983. #else
  7984. os << info.file << ':' << info.line;
  7985. #endif
  7986. return os;
  7987. }
  7988. std::string StreamEndStop::operator+() const {
  7989. return std::string();
  7990. }
  7991. NonCopyable::NonCopyable() = default;
  7992. NonCopyable::~NonCopyable() = default;
  7993. }
  7994. // end catch_common.cpp
  7995. // start catch_config.cpp
  7996. namespace Catch {
  7997. Config::Config( ConfigData const& data )
  7998. : m_data( data ),
  7999. m_stream( openStream() )
  8000. {
  8001. // We need to trim filter specs to avoid trouble with superfluous
  8002. // whitespace (esp. important for bdd macros, as those are manually
  8003. // aligned with whitespace).
  8004. for (auto& elem : m_data.testsOrTags) {
  8005. elem = trim(elem);
  8006. }
  8007. for (auto& elem : m_data.sectionsToRun) {
  8008. elem = trim(elem);
  8009. }
  8010. TestSpecParser parser(ITagAliasRegistry::get());
  8011. if (!m_data.testsOrTags.empty()) {
  8012. m_hasTestFilters = true;
  8013. for (auto const& testOrTags : m_data.testsOrTags) {
  8014. parser.parse(testOrTags);
  8015. }
  8016. }
  8017. m_testSpec = parser.testSpec();
  8018. }
  8019. std::string const& Config::getFilename() const {
  8020. return m_data.outputFilename ;
  8021. }
  8022. bool Config::listTests() const { return m_data.listTests; }
  8023. bool Config::listTestNamesOnly() const { return m_data.listTestNamesOnly; }
  8024. bool Config::listTags() const { return m_data.listTags; }
  8025. bool Config::listReporters() const { return m_data.listReporters; }
  8026. std::string Config::getProcessName() const { return m_data.processName; }
  8027. std::string const& Config::getReporterName() const { return m_data.reporterName; }
  8028. std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
  8029. std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
  8030. TestSpec const& Config::testSpec() const { return m_testSpec; }
  8031. bool Config::hasTestFilters() const { return m_hasTestFilters; }
  8032. bool Config::showHelp() const { return m_data.showHelp; }
  8033. // IConfig interface
  8034. bool Config::allowThrows() const { return !m_data.noThrow; }
  8035. std::ostream& Config::stream() const { return m_stream->stream(); }
  8036. std::string Config::name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
  8037. bool Config::includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
  8038. bool Config::warnAboutMissingAssertions() const { return !!(m_data.warnings & WarnAbout::NoAssertions); }
  8039. bool Config::warnAboutNoTests() const { return !!(m_data.warnings & WarnAbout::NoTests); }
  8040. ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
  8041. RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; }
  8042. unsigned int Config::rngSeed() const { return m_data.rngSeed; }
  8043. UseColour::YesOrNo Config::useColour() const { return m_data.useColour; }
  8044. bool Config::shouldDebugBreak() const { return m_data.shouldDebugBreak; }
  8045. int Config::abortAfter() const { return m_data.abortAfter; }
  8046. bool Config::showInvisibles() const { return m_data.showInvisibles; }
  8047. Verbosity Config::verbosity() const { return m_data.verbosity; }
  8048. bool Config::benchmarkNoAnalysis() const { return m_data.benchmarkNoAnalysis; }
  8049. int Config::benchmarkSamples() const { return m_data.benchmarkSamples; }
  8050. double Config::benchmarkConfidenceInterval() const { return m_data.benchmarkConfidenceInterval; }
  8051. unsigned int Config::benchmarkResamples() const { return m_data.benchmarkResamples; }
  8052. IStream const* Config::openStream() {
  8053. return Catch::makeStream(m_data.outputFilename);
  8054. }
  8055. } // end namespace Catch
  8056. // end catch_config.cpp
  8057. // start catch_console_colour.cpp
  8058. #if defined(__clang__)
  8059. # pragma clang diagnostic push
  8060. # pragma clang diagnostic ignored "-Wexit-time-destructors"
  8061. #endif
  8062. // start catch_errno_guard.h
  8063. namespace Catch {
  8064. class ErrnoGuard {
  8065. public:
  8066. ErrnoGuard();
  8067. ~ErrnoGuard();
  8068. private:
  8069. int m_oldErrno;
  8070. };
  8071. }
  8072. // end catch_errno_guard.h
  8073. #include <sstream>
  8074. namespace Catch {
  8075. namespace {
  8076. struct IColourImpl {
  8077. virtual ~IColourImpl() = default;
  8078. virtual void use( Colour::Code _colourCode ) = 0;
  8079. };
  8080. struct NoColourImpl : IColourImpl {
  8081. void use( Colour::Code ) {}
  8082. static IColourImpl* instance() {
  8083. static NoColourImpl s_instance;
  8084. return &s_instance;
  8085. }
  8086. };
  8087. } // anon namespace
  8088. } // namespace Catch
  8089. #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
  8090. # ifdef CATCH_PLATFORM_WINDOWS
  8091. # define CATCH_CONFIG_COLOUR_WINDOWS
  8092. # else
  8093. # define CATCH_CONFIG_COLOUR_ANSI
  8094. # endif
  8095. #endif
  8096. #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
  8097. namespace Catch {
  8098. namespace {
  8099. class Win32ColourImpl : public IColourImpl {
  8100. public:
  8101. Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
  8102. {
  8103. CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
  8104. GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
  8105. originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
  8106. originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
  8107. }
  8108. void use( Colour::Code _colourCode ) override {
  8109. switch( _colourCode ) {
  8110. case Colour::None: return setTextAttribute( originalForegroundAttributes );
  8111. case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
  8112. case Colour::Red: return setTextAttribute( FOREGROUND_RED );
  8113. case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
  8114. case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
  8115. case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
  8116. case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
  8117. case Colour::Grey: return setTextAttribute( 0 );
  8118. case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
  8119. case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
  8120. case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
  8121. case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
  8122. case Colour::BrightYellow: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );
  8123. case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
  8124. default:
  8125. CATCH_ERROR( "Unknown colour requested" );
  8126. }
  8127. }
  8128. private:
  8129. void setTextAttribute( WORD _textAttribute ) {
  8130. SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
  8131. }
  8132. HANDLE stdoutHandle;
  8133. WORD originalForegroundAttributes;
  8134. WORD originalBackgroundAttributes;
  8135. };
  8136. IColourImpl* platformColourInstance() {
  8137. static Win32ColourImpl s_instance;
  8138. IConfigPtr config = getCurrentContext().getConfig();
  8139. UseColour::YesOrNo colourMode = config
  8140. ? config->useColour()
  8141. : UseColour::Auto;
  8142. if( colourMode == UseColour::Auto )
  8143. colourMode = UseColour::Yes;
  8144. return colourMode == UseColour::Yes
  8145. ? &s_instance
  8146. : NoColourImpl::instance();
  8147. }
  8148. } // end anon namespace
  8149. } // end namespace Catch
  8150. #elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
  8151. #include <unistd.h>
  8152. namespace Catch {
  8153. namespace {
  8154. // use POSIX/ ANSI console terminal codes
  8155. // Thanks to Adam Strzelecki for original contribution
  8156. // (http://github.com/nanoant)
  8157. // https://github.com/philsquared/Catch/pull/131
  8158. class PosixColourImpl : public IColourImpl {
  8159. public:
  8160. void use( Colour::Code _colourCode ) override {
  8161. switch( _colourCode ) {
  8162. case Colour::None:
  8163. case Colour::White: return setColour( "[0m" );
  8164. case Colour::Red: return setColour( "[0;31m" );
  8165. case Colour::Green: return setColour( "[0;32m" );
  8166. case Colour::Blue: return setColour( "[0;34m" );
  8167. case Colour::Cyan: return setColour( "[0;36m" );
  8168. case Colour::Yellow: return setColour( "[0;33m" );
  8169. case Colour::Grey: return setColour( "[1;30m" );
  8170. case Colour::LightGrey: return setColour( "[0;37m" );
  8171. case Colour::BrightRed: return setColour( "[1;31m" );
  8172. case Colour::BrightGreen: return setColour( "[1;32m" );
  8173. case Colour::BrightWhite: return setColour( "[1;37m" );
  8174. case Colour::BrightYellow: return setColour( "[1;33m" );
  8175. case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
  8176. default: CATCH_INTERNAL_ERROR( "Unknown colour requested" );
  8177. }
  8178. }
  8179. static IColourImpl* instance() {
  8180. static PosixColourImpl s_instance;
  8181. return &s_instance;
  8182. }
  8183. private:
  8184. void setColour( const char* _escapeCode ) {
  8185. getCurrentContext().getConfig()->stream()
  8186. << '\033' << _escapeCode;
  8187. }
  8188. };
  8189. bool useColourOnPlatform() {
  8190. return
  8191. #ifdef CATCH_PLATFORM_MAC
  8192. !isDebuggerActive() &&
  8193. #endif
  8194. #if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
  8195. isatty(STDOUT_FILENO)
  8196. #else
  8197. false
  8198. #endif
  8199. ;
  8200. }
  8201. IColourImpl* platformColourInstance() {
  8202. ErrnoGuard guard;
  8203. IConfigPtr config = getCurrentContext().getConfig();
  8204. UseColour::YesOrNo colourMode = config
  8205. ? config->useColour()
  8206. : UseColour::Auto;
  8207. if( colourMode == UseColour::Auto )
  8208. colourMode = useColourOnPlatform()
  8209. ? UseColour::Yes
  8210. : UseColour::No;
  8211. return colourMode == UseColour::Yes
  8212. ? PosixColourImpl::instance()
  8213. : NoColourImpl::instance();
  8214. }
  8215. } // end anon namespace
  8216. } // end namespace Catch
  8217. #else // not Windows or ANSI ///////////////////////////////////////////////
  8218. namespace Catch {
  8219. static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
  8220. } // end namespace Catch
  8221. #endif // Windows/ ANSI/ None
  8222. namespace Catch {
  8223. Colour::Colour( Code _colourCode ) { use( _colourCode ); }
  8224. Colour::Colour( Colour&& rhs ) noexcept {
  8225. m_moved = rhs.m_moved;
  8226. rhs.m_moved = true;
  8227. }
  8228. Colour& Colour::operator=( Colour&& rhs ) noexcept {
  8229. m_moved = rhs.m_moved;
  8230. rhs.m_moved = true;
  8231. return *this;
  8232. }
  8233. Colour::~Colour(){ if( !m_moved ) use( None ); }
  8234. void Colour::use( Code _colourCode ) {
  8235. static IColourImpl* impl = platformColourInstance();
  8236. // Strictly speaking, this cannot possibly happen.
  8237. // However, under some conditions it does happen (see #1626),
  8238. // and this change is small enough that we can let practicality
  8239. // triumph over purity in this case.
  8240. if (impl != NULL) {
  8241. impl->use( _colourCode );
  8242. }
  8243. }
  8244. std::ostream& operator << ( std::ostream& os, Colour const& ) {
  8245. return os;
  8246. }
  8247. } // end namespace Catch
  8248. #if defined(__clang__)
  8249. # pragma clang diagnostic pop
  8250. #endif
  8251. // end catch_console_colour.cpp
  8252. // start catch_context.cpp
  8253. namespace Catch {
  8254. class Context : public IMutableContext, NonCopyable {
  8255. public: // IContext
  8256. IResultCapture* getResultCapture() override {
  8257. return m_resultCapture;
  8258. }
  8259. IRunner* getRunner() override {
  8260. return m_runner;
  8261. }
  8262. IConfigPtr const& getConfig() const override {
  8263. return m_config;
  8264. }
  8265. ~Context() override;
  8266. public: // IMutableContext
  8267. void setResultCapture( IResultCapture* resultCapture ) override {
  8268. m_resultCapture = resultCapture;
  8269. }
  8270. void setRunner( IRunner* runner ) override {
  8271. m_runner = runner;
  8272. }
  8273. void setConfig( IConfigPtr const& config ) override {
  8274. m_config = config;
  8275. }
  8276. friend IMutableContext& getCurrentMutableContext();
  8277. private:
  8278. IConfigPtr m_config;
  8279. IRunner* m_runner = nullptr;
  8280. IResultCapture* m_resultCapture = nullptr;
  8281. };
  8282. IMutableContext *IMutableContext::currentContext = nullptr;
  8283. void IMutableContext::createContext()
  8284. {
  8285. currentContext = new Context();
  8286. }
  8287. void cleanUpContext() {
  8288. delete IMutableContext::currentContext;
  8289. IMutableContext::currentContext = nullptr;
  8290. }
  8291. IContext::~IContext() = default;
  8292. IMutableContext::~IMutableContext() = default;
  8293. Context::~Context() = default;
  8294. SimplePcg32& rng() {
  8295. static SimplePcg32 s_rng;
  8296. return s_rng;
  8297. }
  8298. }
  8299. // end catch_context.cpp
  8300. // start catch_debug_console.cpp
  8301. // start catch_debug_console.h
  8302. #include <string>
  8303. namespace Catch {
  8304. void writeToDebugConsole( std::string const& text );
  8305. }
  8306. // end catch_debug_console.h
  8307. #if defined(CATCH_CONFIG_ANDROID_LOGWRITE)
  8308. #include <android/log.h>
  8309. namespace Catch {
  8310. void writeToDebugConsole( std::string const& text ) {
  8311. __android_log_write( ANDROID_LOG_DEBUG, "Catch", text.c_str() );
  8312. }
  8313. }
  8314. #elif defined(CATCH_PLATFORM_WINDOWS)
  8315. namespace Catch {
  8316. void writeToDebugConsole( std::string const& text ) {
  8317. ::OutputDebugStringA( text.c_str() );
  8318. }
  8319. }
  8320. #else
  8321. namespace Catch {
  8322. void writeToDebugConsole( std::string const& text ) {
  8323. // !TBD: Need a version for Mac/ XCode and other IDEs
  8324. Catch::cout() << text;
  8325. }
  8326. }
  8327. #endif // Platform
  8328. // end catch_debug_console.cpp
  8329. // start catch_debugger.cpp
  8330. #ifdef CATCH_PLATFORM_MAC
  8331. # include <assert.h>
  8332. # include <stdbool.h>
  8333. # include <sys/types.h>
  8334. # include <unistd.h>
  8335. # include <cstddef>
  8336. # include <ostream>
  8337. #ifdef __apple_build_version__
  8338. // These headers will only compile with AppleClang (XCode)
  8339. // For other compilers (Clang, GCC, ... ) we need to exclude them
  8340. # include <sys/sysctl.h>
  8341. #endif
  8342. namespace Catch {
  8343. #ifdef __apple_build_version__
  8344. // The following function is taken directly from the following technical note:
  8345. // https://developer.apple.com/library/archive/qa/qa1361/_index.html
  8346. // Returns true if the current process is being debugged (either
  8347. // running under the debugger or has a debugger attached post facto).
  8348. bool isDebuggerActive(){
  8349. int mib[4];
  8350. struct kinfo_proc info;
  8351. std::size_t size;
  8352. // Initialize the flags so that, if sysctl fails for some bizarre
  8353. // reason, we get a predictable result.
  8354. info.kp_proc.p_flag = 0;
  8355. // Initialize mib, which tells sysctl the info we want, in this case
  8356. // we're looking for information about a specific process ID.
  8357. mib[0] = CTL_KERN;
  8358. mib[1] = KERN_PROC;
  8359. mib[2] = KERN_PROC_PID;
  8360. mib[3] = getpid();
  8361. // Call sysctl.
  8362. size = sizeof(info);
  8363. if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) {
  8364. Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
  8365. return false;
  8366. }
  8367. // We're being debugged if the P_TRACED flag is set.
  8368. return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
  8369. }
  8370. #else
  8371. bool isDebuggerActive() {
  8372. // We need to find another way to determine this for non-appleclang compilers on macOS
  8373. return false;
  8374. }
  8375. #endif
  8376. } // namespace Catch
  8377. #elif defined(CATCH_PLATFORM_LINUX)
  8378. #include <fstream>
  8379. #include <string>
  8380. namespace Catch{
  8381. // The standard POSIX way of detecting a debugger is to attempt to
  8382. // ptrace() the process, but this needs to be done from a child and not
  8383. // this process itself to still allow attaching to this process later
  8384. // if wanted, so is rather heavy. Under Linux we have the PID of the
  8385. // "debugger" (which doesn't need to be gdb, of course, it could also
  8386. // be strace, for example) in /proc/$PID/status, so just get it from
  8387. // there instead.
  8388. bool isDebuggerActive(){
  8389. // Libstdc++ has a bug, where std::ifstream sets errno to 0
  8390. // This way our users can properly assert over errno values
  8391. ErrnoGuard guard;
  8392. std::ifstream in("/proc/self/status");
  8393. for( std::string line; std::getline(in, line); ) {
  8394. static const int PREFIX_LEN = 11;
  8395. if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
  8396. // We're traced if the PID is not 0 and no other PID starts
  8397. // with 0 digit, so it's enough to check for just a single
  8398. // character.
  8399. return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
  8400. }
  8401. }
  8402. return false;
  8403. }
  8404. } // namespace Catch
  8405. #elif defined(_MSC_VER)
  8406. extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
  8407. namespace Catch {
  8408. bool isDebuggerActive() {
  8409. return IsDebuggerPresent() != 0;
  8410. }
  8411. }
  8412. #elif defined(__MINGW32__)
  8413. extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
  8414. namespace Catch {
  8415. bool isDebuggerActive() {
  8416. return IsDebuggerPresent() != 0;
  8417. }
  8418. }
  8419. #else
  8420. namespace Catch {
  8421. bool isDebuggerActive() { return false; }
  8422. }
  8423. #endif // Platform
  8424. // end catch_debugger.cpp
  8425. // start catch_decomposer.cpp
  8426. namespace Catch {
  8427. ITransientExpression::~ITransientExpression() = default;
  8428. void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {
  8429. if( lhs.size() + rhs.size() < 40 &&
  8430. lhs.find('\n') == std::string::npos &&
  8431. rhs.find('\n') == std::string::npos )
  8432. os << lhs << " " << op << " " << rhs;
  8433. else
  8434. os << lhs << "\n" << op << "\n" << rhs;
  8435. }
  8436. }
  8437. // end catch_decomposer.cpp
  8438. // start catch_enforce.cpp
  8439. #include <stdexcept>
  8440. namespace Catch {
  8441. #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)
  8442. [[noreturn]]
  8443. void throw_exception(std::exception const& e) {
  8444. Catch::cerr() << "Catch will terminate because it needed to throw an exception.\n"
  8445. << "The message was: " << e.what() << '\n';
  8446. std::terminate();
  8447. }
  8448. #endif
  8449. [[noreturn]]
  8450. void throw_logic_error(std::string const& msg) {
  8451. throw_exception(std::logic_error(msg));
  8452. }
  8453. [[noreturn]]
  8454. void throw_domain_error(std::string const& msg) {
  8455. throw_exception(std::domain_error(msg));
  8456. }
  8457. [[noreturn]]
  8458. void throw_runtime_error(std::string const& msg) {
  8459. throw_exception(std::runtime_error(msg));
  8460. }
  8461. } // namespace Catch;
  8462. // end catch_enforce.cpp
  8463. // start catch_enum_values_registry.cpp
  8464. // start catch_enum_values_registry.h
  8465. #include <vector>
  8466. #include <memory>
  8467. namespace Catch {
  8468. namespace Detail {
  8469. std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values );
  8470. class EnumValuesRegistry : public IMutableEnumValuesRegistry {
  8471. std::vector<std::unique_ptr<EnumInfo>> m_enumInfos;
  8472. EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override;
  8473. };
  8474. std::vector<StringRef> parseEnums( StringRef enums );
  8475. } // Detail
  8476. } // Catch
  8477. // end catch_enum_values_registry.h
  8478. #include <map>
  8479. #include <cassert>
  8480. namespace Catch {
  8481. IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() {}
  8482. namespace Detail {
  8483. namespace {
  8484. // Extracts the actual name part of an enum instance
  8485. // In other words, it returns the Blue part of Bikeshed::Colour::Blue
  8486. StringRef extractInstanceName(StringRef enumInstance) {
  8487. // Find last occurence of ":"
  8488. size_t name_start = enumInstance.size();
  8489. while (name_start > 0 && enumInstance[name_start - 1] != ':') {
  8490. --name_start;
  8491. }
  8492. return enumInstance.substr(name_start, enumInstance.size() - name_start);
  8493. }
  8494. }
  8495. std::vector<StringRef> parseEnums( StringRef enums ) {
  8496. auto enumValues = splitStringRef( enums, ',' );
  8497. std::vector<StringRef> parsed;
  8498. parsed.reserve( enumValues.size() );
  8499. for( auto const& enumValue : enumValues ) {
  8500. parsed.push_back(trim(extractInstanceName(enumValue)));
  8501. }
  8502. return parsed;
  8503. }
  8504. EnumInfo::~EnumInfo() {}
  8505. StringRef EnumInfo::lookup( int value ) const {
  8506. for( auto const& valueToName : m_values ) {
  8507. if( valueToName.first == value )
  8508. return valueToName.second;
  8509. }
  8510. return "{** unexpected enum value **}"_sr;
  8511. }
  8512. std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
  8513. std::unique_ptr<EnumInfo> enumInfo( new EnumInfo );
  8514. enumInfo->m_name = enumName;
  8515. enumInfo->m_values.reserve( values.size() );
  8516. const auto valueNames = Catch::Detail::parseEnums( allValueNames );
  8517. assert( valueNames.size() == values.size() );
  8518. std::size_t i = 0;
  8519. for( auto value : values )
  8520. enumInfo->m_values.push_back({ value, valueNames[i++] });
  8521. return enumInfo;
  8522. }
  8523. EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
  8524. m_enumInfos.push_back(makeEnumInfo(enumName, allValueNames, values));
  8525. return *m_enumInfos.back();
  8526. }
  8527. } // Detail
  8528. } // Catch
  8529. // end catch_enum_values_registry.cpp
  8530. // start catch_errno_guard.cpp
  8531. #include <cerrno>
  8532. namespace Catch {
  8533. ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}
  8534. ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }
  8535. }
  8536. // end catch_errno_guard.cpp
  8537. // start catch_exception_translator_registry.cpp
  8538. // start catch_exception_translator_registry.h
  8539. #include <vector>
  8540. #include <string>
  8541. #include <memory>
  8542. namespace Catch {
  8543. class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
  8544. public:
  8545. ~ExceptionTranslatorRegistry();
  8546. virtual void registerTranslator( const IExceptionTranslator* translator );
  8547. std::string translateActiveException() const override;
  8548. std::string tryTranslators() const;
  8549. private:
  8550. std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;
  8551. };
  8552. }
  8553. // end catch_exception_translator_registry.h
  8554. #ifdef __OBJC__
  8555. #import "Foundation/Foundation.h"
  8556. #endif
  8557. namespace Catch {
  8558. ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
  8559. }
  8560. void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) {
  8561. m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
  8562. }
  8563. #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  8564. std::string ExceptionTranslatorRegistry::translateActiveException() const {
  8565. try {
  8566. #ifdef __OBJC__
  8567. // In Objective-C try objective-c exceptions first
  8568. @try {
  8569. return tryTranslators();
  8570. }
  8571. @catch (NSException *exception) {
  8572. return Catch::Detail::stringify( [exception description] );
  8573. }
  8574. #else
  8575. // Compiling a mixed mode project with MSVC means that CLR
  8576. // exceptions will be caught in (...) as well. However, these
  8577. // do not fill-in std::current_exception and thus lead to crash
  8578. // when attempting rethrow.
  8579. // /EHa switch also causes structured exceptions to be caught
  8580. // here, but they fill-in current_exception properly, so
  8581. // at worst the output should be a little weird, instead of
  8582. // causing a crash.
  8583. if (std::current_exception() == nullptr) {
  8584. return "Non C++ exception. Possibly a CLR exception.";
  8585. }
  8586. return tryTranslators();
  8587. #endif
  8588. }
  8589. catch( TestFailureException& ) {
  8590. std::rethrow_exception(std::current_exception());
  8591. }
  8592. catch( std::exception& ex ) {
  8593. return ex.what();
  8594. }
  8595. catch( std::string& msg ) {
  8596. return msg;
  8597. }
  8598. catch( const char* msg ) {
  8599. return msg;
  8600. }
  8601. catch(...) {
  8602. return "Unknown exception";
  8603. }
  8604. }
  8605. std::string ExceptionTranslatorRegistry::tryTranslators() const {
  8606. if (m_translators.empty()) {
  8607. std::rethrow_exception(std::current_exception());
  8608. } else {
  8609. return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end());
  8610. }
  8611. }
  8612. #else // ^^ Exceptions are enabled // Exceptions are disabled vv
  8613. std::string ExceptionTranslatorRegistry::translateActiveException() const {
  8614. CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
  8615. }
  8616. std::string ExceptionTranslatorRegistry::tryTranslators() const {
  8617. CATCH_INTERNAL_ERROR("Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
  8618. }
  8619. #endif
  8620. }
  8621. // end catch_exception_translator_registry.cpp
  8622. // start catch_fatal_condition.cpp
  8623. #if defined(__GNUC__)
  8624. # pragma GCC diagnostic push
  8625. # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
  8626. #endif
  8627. #if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
  8628. namespace {
  8629. // Report the error condition
  8630. void reportFatal( char const * const message ) {
  8631. Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
  8632. }
  8633. }
  8634. #endif // signals/SEH handling
  8635. #if defined( CATCH_CONFIG_WINDOWS_SEH )
  8636. namespace Catch {
  8637. struct SignalDefs { DWORD id; const char* name; };
  8638. // There is no 1-1 mapping between signals and windows exceptions.
  8639. // Windows can easily distinguish between SO and SigSegV,
  8640. // but SigInt, SigTerm, etc are handled differently.
  8641. static SignalDefs signalDefs[] = {
  8642. { static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION), "SIGILL - Illegal instruction signal" },
  8643. { static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow" },
  8644. { static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION), "SIGSEGV - Segmentation violation signal" },
  8645. { static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" },
  8646. };
  8647. LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
  8648. for (auto const& def : signalDefs) {
  8649. if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
  8650. reportFatal(def.name);
  8651. }
  8652. }
  8653. // If its not an exception we care about, pass it along.
  8654. // This stops us from eating debugger breaks etc.
  8655. return EXCEPTION_CONTINUE_SEARCH;
  8656. }
  8657. FatalConditionHandler::FatalConditionHandler() {
  8658. isSet = true;
  8659. // 32k seems enough for Catch to handle stack overflow,
  8660. // but the value was found experimentally, so there is no strong guarantee
  8661. guaranteeSize = 32 * 1024;
  8662. exceptionHandlerHandle = nullptr;
  8663. // Register as first handler in current chain
  8664. exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
  8665. // Pass in guarantee size to be filled
  8666. SetThreadStackGuarantee(&guaranteeSize);
  8667. }
  8668. void FatalConditionHandler::reset() {
  8669. if (isSet) {
  8670. RemoveVectoredExceptionHandler(exceptionHandlerHandle);
  8671. SetThreadStackGuarantee(&guaranteeSize);
  8672. exceptionHandlerHandle = nullptr;
  8673. isSet = false;
  8674. }
  8675. }
  8676. FatalConditionHandler::~FatalConditionHandler() {
  8677. reset();
  8678. }
  8679. bool FatalConditionHandler::isSet = false;
  8680. ULONG FatalConditionHandler::guaranteeSize = 0;
  8681. PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
  8682. } // namespace Catch
  8683. #elif defined( CATCH_CONFIG_POSIX_SIGNALS )
  8684. namespace Catch {
  8685. struct SignalDefs {
  8686. int id;
  8687. const char* name;
  8688. };
  8689. // 32kb for the alternate stack seems to be sufficient. However, this value
  8690. // is experimentally determined, so that's not guaranteed.
  8691. static constexpr std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
  8692. static SignalDefs signalDefs[] = {
  8693. { SIGINT, "SIGINT - Terminal interrupt signal" },
  8694. { SIGILL, "SIGILL - Illegal instruction signal" },
  8695. { SIGFPE, "SIGFPE - Floating point error signal" },
  8696. { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
  8697. { SIGTERM, "SIGTERM - Termination request signal" },
  8698. { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
  8699. };
  8700. void FatalConditionHandler::handleSignal( int sig ) {
  8701. char const * name = "<unknown signal>";
  8702. for (auto const& def : signalDefs) {
  8703. if (sig == def.id) {
  8704. name = def.name;
  8705. break;
  8706. }
  8707. }
  8708. reset();
  8709. reportFatal(name);
  8710. raise( sig );
  8711. }
  8712. FatalConditionHandler::FatalConditionHandler() {
  8713. isSet = true;
  8714. stack_t sigStack;
  8715. sigStack.ss_sp = altStackMem;
  8716. sigStack.ss_size = sigStackSize;
  8717. sigStack.ss_flags = 0;
  8718. sigaltstack(&sigStack, &oldSigStack);
  8719. struct sigaction sa = { };
  8720. sa.sa_handler = handleSignal;
  8721. sa.sa_flags = SA_ONSTACK;
  8722. for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
  8723. sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
  8724. }
  8725. }
  8726. FatalConditionHandler::~FatalConditionHandler() {
  8727. reset();
  8728. }
  8729. void FatalConditionHandler::reset() {
  8730. if( isSet ) {
  8731. // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
  8732. for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
  8733. sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
  8734. }
  8735. // Return the old stack
  8736. sigaltstack(&oldSigStack, nullptr);
  8737. isSet = false;
  8738. }
  8739. }
  8740. bool FatalConditionHandler::isSet = false;
  8741. struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
  8742. stack_t FatalConditionHandler::oldSigStack = {};
  8743. char FatalConditionHandler::altStackMem[sigStackSize] = {};
  8744. } // namespace Catch
  8745. #else
  8746. namespace Catch {
  8747. void FatalConditionHandler::reset() {}
  8748. }
  8749. #endif // signals/SEH handling
  8750. #if defined(__GNUC__)
  8751. # pragma GCC diagnostic pop
  8752. #endif
  8753. // end catch_fatal_condition.cpp
  8754. // start catch_generators.cpp
  8755. #include <limits>
  8756. #include <set>
  8757. namespace Catch {
  8758. IGeneratorTracker::~IGeneratorTracker() {}
  8759. const char* GeneratorException::what() const noexcept {
  8760. return m_msg;
  8761. }
  8762. namespace Generators {
  8763. GeneratorUntypedBase::~GeneratorUntypedBase() {}
  8764. auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
  8765. return getResultCapture().acquireGeneratorTracker( lineInfo );
  8766. }
  8767. } // namespace Generators
  8768. } // namespace Catch
  8769. // end catch_generators.cpp
  8770. // start catch_interfaces_capture.cpp
  8771. namespace Catch {
  8772. IResultCapture::~IResultCapture() = default;
  8773. }
  8774. // end catch_interfaces_capture.cpp
  8775. // start catch_interfaces_config.cpp
  8776. namespace Catch {
  8777. IConfig::~IConfig() = default;
  8778. }
  8779. // end catch_interfaces_config.cpp
  8780. // start catch_interfaces_exception.cpp
  8781. namespace Catch {
  8782. IExceptionTranslator::~IExceptionTranslator() = default;
  8783. IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;
  8784. }
  8785. // end catch_interfaces_exception.cpp
  8786. // start catch_interfaces_registry_hub.cpp
  8787. namespace Catch {
  8788. IRegistryHub::~IRegistryHub() = default;
  8789. IMutableRegistryHub::~IMutableRegistryHub() = default;
  8790. }
  8791. // end catch_interfaces_registry_hub.cpp
  8792. // start catch_interfaces_reporter.cpp
  8793. // start catch_reporter_listening.h
  8794. namespace Catch {
  8795. class ListeningReporter : public IStreamingReporter {
  8796. using Reporters = std::vector<IStreamingReporterPtr>;
  8797. Reporters m_listeners;
  8798. IStreamingReporterPtr m_reporter = nullptr;
  8799. ReporterPreferences m_preferences;
  8800. public:
  8801. ListeningReporter();
  8802. void addListener( IStreamingReporterPtr&& listener );
  8803. void addReporter( IStreamingReporterPtr&& reporter );
  8804. public: // IStreamingReporter
  8805. ReporterPreferences getPreferences() const override;
  8806. void noMatchingTestCases( std::string const& spec ) override;
  8807. void reportInvalidArguments(std::string const&arg) override;
  8808. static std::set<Verbosity> getSupportedVerbosities();
  8809. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  8810. void benchmarkPreparing(std::string const& name) override;
  8811. void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
  8812. void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override;
  8813. void benchmarkFailed(std::string const&) override;
  8814. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  8815. void testRunStarting( TestRunInfo const& testRunInfo ) override;
  8816. void testGroupStarting( GroupInfo const& groupInfo ) override;
  8817. void testCaseStarting( TestCaseInfo const& testInfo ) override;
  8818. void sectionStarting( SectionInfo const& sectionInfo ) override;
  8819. void assertionStarting( AssertionInfo const& assertionInfo ) override;
  8820. // The return value indicates if the messages buffer should be cleared:
  8821. bool assertionEnded( AssertionStats const& assertionStats ) override;
  8822. void sectionEnded( SectionStats const& sectionStats ) override;
  8823. void testCaseEnded( TestCaseStats const& testCaseStats ) override;
  8824. void testGroupEnded( TestGroupStats const& testGroupStats ) override;
  8825. void testRunEnded( TestRunStats const& testRunStats ) override;
  8826. void skipTest( TestCaseInfo const& testInfo ) override;
  8827. bool isMulti() const override;
  8828. };
  8829. } // end namespace Catch
  8830. // end catch_reporter_listening.h
  8831. namespace Catch {
  8832. ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig )
  8833. : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
  8834. ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream )
  8835. : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
  8836. std::ostream& ReporterConfig::stream() const { return *m_stream; }
  8837. IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; }
  8838. TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {}
  8839. GroupInfo::GroupInfo( std::string const& _name,
  8840. std::size_t _groupIndex,
  8841. std::size_t _groupsCount )
  8842. : name( _name ),
  8843. groupIndex( _groupIndex ),
  8844. groupsCounts( _groupsCount )
  8845. {}
  8846. AssertionStats::AssertionStats( AssertionResult const& _assertionResult,
  8847. std::vector<MessageInfo> const& _infoMessages,
  8848. Totals const& _totals )
  8849. : assertionResult( _assertionResult ),
  8850. infoMessages( _infoMessages ),
  8851. totals( _totals )
  8852. {
  8853. assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;
  8854. if( assertionResult.hasMessage() ) {
  8855. // Copy message into messages list.
  8856. // !TBD This should have been done earlier, somewhere
  8857. MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
  8858. builder << assertionResult.getMessage();
  8859. builder.m_info.message = builder.m_stream.str();
  8860. infoMessages.push_back( builder.m_info );
  8861. }
  8862. }
  8863. AssertionStats::~AssertionStats() = default;
  8864. SectionStats::SectionStats( SectionInfo const& _sectionInfo,
  8865. Counts const& _assertions,
  8866. double _durationInSeconds,
  8867. bool _missingAssertions )
  8868. : sectionInfo( _sectionInfo ),
  8869. assertions( _assertions ),
  8870. durationInSeconds( _durationInSeconds ),
  8871. missingAssertions( _missingAssertions )
  8872. {}
  8873. SectionStats::~SectionStats() = default;
  8874. TestCaseStats::TestCaseStats( TestCaseInfo const& _testInfo,
  8875. Totals const& _totals,
  8876. std::string const& _stdOut,
  8877. std::string const& _stdErr,
  8878. bool _aborting )
  8879. : testInfo( _testInfo ),
  8880. totals( _totals ),
  8881. stdOut( _stdOut ),
  8882. stdErr( _stdErr ),
  8883. aborting( _aborting )
  8884. {}
  8885. TestCaseStats::~TestCaseStats() = default;
  8886. TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo,
  8887. Totals const& _totals,
  8888. bool _aborting )
  8889. : groupInfo( _groupInfo ),
  8890. totals( _totals ),
  8891. aborting( _aborting )
  8892. {}
  8893. TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo )
  8894. : groupInfo( _groupInfo ),
  8895. aborting( false )
  8896. {}
  8897. TestGroupStats::~TestGroupStats() = default;
  8898. TestRunStats::TestRunStats( TestRunInfo const& _runInfo,
  8899. Totals const& _totals,
  8900. bool _aborting )
  8901. : runInfo( _runInfo ),
  8902. totals( _totals ),
  8903. aborting( _aborting )
  8904. {}
  8905. TestRunStats::~TestRunStats() = default;
  8906. void IStreamingReporter::fatalErrorEncountered( StringRef ) {}
  8907. bool IStreamingReporter::isMulti() const { return false; }
  8908. IReporterFactory::~IReporterFactory() = default;
  8909. IReporterRegistry::~IReporterRegistry() = default;
  8910. } // end namespace Catch
  8911. // end catch_interfaces_reporter.cpp
  8912. // start catch_interfaces_runner.cpp
  8913. namespace Catch {
  8914. IRunner::~IRunner() = default;
  8915. }
  8916. // end catch_interfaces_runner.cpp
  8917. // start catch_interfaces_testcase.cpp
  8918. namespace Catch {
  8919. ITestInvoker::~ITestInvoker() = default;
  8920. ITestCaseRegistry::~ITestCaseRegistry() = default;
  8921. }
  8922. // end catch_interfaces_testcase.cpp
  8923. // start catch_leak_detector.cpp
  8924. #ifdef CATCH_CONFIG_WINDOWS_CRTDBG
  8925. #include <crtdbg.h>
  8926. namespace Catch {
  8927. LeakDetector::LeakDetector() {
  8928. int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
  8929. flag |= _CRTDBG_LEAK_CHECK_DF;
  8930. flag |= _CRTDBG_ALLOC_MEM_DF;
  8931. _CrtSetDbgFlag(flag);
  8932. _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
  8933. _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
  8934. // Change this to leaking allocation's number to break there
  8935. _CrtSetBreakAlloc(-1);
  8936. }
  8937. }
  8938. #else
  8939. Catch::LeakDetector::LeakDetector() {}
  8940. #endif
  8941. Catch::LeakDetector::~LeakDetector() {
  8942. Catch::cleanUp();
  8943. }
  8944. // end catch_leak_detector.cpp
  8945. // start catch_list.cpp
  8946. // start catch_list.h
  8947. #include <set>
  8948. namespace Catch {
  8949. std::size_t listTests( Config const& config );
  8950. std::size_t listTestsNamesOnly( Config const& config );
  8951. struct TagInfo {
  8952. void add( std::string const& spelling );
  8953. std::string all() const;
  8954. std::set<std::string> spellings;
  8955. std::size_t count = 0;
  8956. };
  8957. std::size_t listTags( Config const& config );
  8958. std::size_t listReporters();
  8959. Option<std::size_t> list( std::shared_ptr<Config> const& config );
  8960. } // end namespace Catch
  8961. // end catch_list.h
  8962. // start catch_text.h
  8963. namespace Catch {
  8964. using namespace clara::TextFlow;
  8965. }
  8966. // end catch_text.h
  8967. #include <limits>
  8968. #include <algorithm>
  8969. #include <iomanip>
  8970. namespace Catch {
  8971. std::size_t listTests( Config const& config ) {
  8972. TestSpec testSpec = config.testSpec();
  8973. if( config.hasTestFilters() )
  8974. Catch::cout() << "Matching test cases:\n";
  8975. else {
  8976. Catch::cout() << "All available test cases:\n";
  8977. }
  8978. auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
  8979. for( auto const& testCaseInfo : matchedTestCases ) {
  8980. Colour::Code colour = testCaseInfo.isHidden()
  8981. ? Colour::SecondaryText
  8982. : Colour::None;
  8983. Colour colourGuard( colour );
  8984. Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n";
  8985. if( config.verbosity() >= Verbosity::High ) {
  8986. Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl;
  8987. std::string description = testCaseInfo.description;
  8988. if( description.empty() )
  8989. description = "(NO DESCRIPTION)";
  8990. Catch::cout() << Column( description ).indent(4) << std::endl;
  8991. }
  8992. if( !testCaseInfo.tags.empty() )
  8993. Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n";
  8994. }
  8995. if( !config.hasTestFilters() )
  8996. Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl;
  8997. else
  8998. Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl;
  8999. return matchedTestCases.size();
  9000. }
  9001. std::size_t listTestsNamesOnly( Config const& config ) {
  9002. TestSpec testSpec = config.testSpec();
  9003. std::size_t matchedTests = 0;
  9004. std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
  9005. for( auto const& testCaseInfo : matchedTestCases ) {
  9006. matchedTests++;
  9007. if( startsWith( testCaseInfo.name, '#' ) )
  9008. Catch::cout() << '"' << testCaseInfo.name << '"';
  9009. else
  9010. Catch::cout() << testCaseInfo.name;
  9011. if ( config.verbosity() >= Verbosity::High )
  9012. Catch::cout() << "\t@" << testCaseInfo.lineInfo;
  9013. Catch::cout() << std::endl;
  9014. }
  9015. return matchedTests;
  9016. }
  9017. void TagInfo::add( std::string const& spelling ) {
  9018. ++count;
  9019. spellings.insert( spelling );
  9020. }
  9021. std::string TagInfo::all() const {
  9022. size_t size = 0;
  9023. for (auto const& spelling : spellings) {
  9024. // Add 2 for the brackes
  9025. size += spelling.size() + 2;
  9026. }
  9027. std::string out; out.reserve(size);
  9028. for (auto const& spelling : spellings) {
  9029. out += '[';
  9030. out += spelling;
  9031. out += ']';
  9032. }
  9033. return out;
  9034. }
  9035. std::size_t listTags( Config const& config ) {
  9036. TestSpec testSpec = config.testSpec();
  9037. if( config.hasTestFilters() )
  9038. Catch::cout() << "Tags for matching test cases:\n";
  9039. else {
  9040. Catch::cout() << "All available tags:\n";
  9041. }
  9042. std::map<std::string, TagInfo> tagCounts;
  9043. std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
  9044. for( auto const& testCase : matchedTestCases ) {
  9045. for( auto const& tagName : testCase.getTestCaseInfo().tags ) {
  9046. std::string lcaseTagName = toLower( tagName );
  9047. auto countIt = tagCounts.find( lcaseTagName );
  9048. if( countIt == tagCounts.end() )
  9049. countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
  9050. countIt->second.add( tagName );
  9051. }
  9052. }
  9053. for( auto const& tagCount : tagCounts ) {
  9054. ReusableStringStream rss;
  9055. rss << " " << std::setw(2) << tagCount.second.count << " ";
  9056. auto str = rss.str();
  9057. auto wrapper = Column( tagCount.second.all() )
  9058. .initialIndent( 0 )
  9059. .indent( str.size() )
  9060. .width( CATCH_CONFIG_CONSOLE_WIDTH-10 );
  9061. Catch::cout() << str << wrapper << '\n';
  9062. }
  9063. Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
  9064. return tagCounts.size();
  9065. }
  9066. std::size_t listReporters() {
  9067. Catch::cout() << "Available reporters:\n";
  9068. IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
  9069. std::size_t maxNameLen = 0;
  9070. for( auto const& factoryKvp : factories )
  9071. maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() );
  9072. for( auto const& factoryKvp : factories ) {
  9073. Catch::cout()
  9074. << Column( factoryKvp.first + ":" )
  9075. .indent(2)
  9076. .width( 5+maxNameLen )
  9077. + Column( factoryKvp.second->getDescription() )
  9078. .initialIndent(0)
  9079. .indent(2)
  9080. .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 )
  9081. << "\n";
  9082. }
  9083. Catch::cout() << std::endl;
  9084. return factories.size();
  9085. }
  9086. Option<std::size_t> list( std::shared_ptr<Config> const& config ) {
  9087. Option<std::size_t> listedCount;
  9088. getCurrentMutableContext().setConfig( config );
  9089. if( config->listTests() )
  9090. listedCount = listedCount.valueOr(0) + listTests( *config );
  9091. if( config->listTestNamesOnly() )
  9092. listedCount = listedCount.valueOr(0) + listTestsNamesOnly( *config );
  9093. if( config->listTags() )
  9094. listedCount = listedCount.valueOr(0) + listTags( *config );
  9095. if( config->listReporters() )
  9096. listedCount = listedCount.valueOr(0) + listReporters();
  9097. return listedCount;
  9098. }
  9099. } // end namespace Catch
  9100. // end catch_list.cpp
  9101. // start catch_matchers.cpp
  9102. namespace Catch {
  9103. namespace Matchers {
  9104. namespace Impl {
  9105. std::string MatcherUntypedBase::toString() const {
  9106. if( m_cachedToString.empty() )
  9107. m_cachedToString = describe();
  9108. return m_cachedToString;
  9109. }
  9110. MatcherUntypedBase::~MatcherUntypedBase() = default;
  9111. } // namespace Impl
  9112. } // namespace Matchers
  9113. using namespace Matchers;
  9114. using Matchers::Impl::MatcherBase;
  9115. } // namespace Catch
  9116. // end catch_matchers.cpp
  9117. // start catch_matchers_exception.cpp
  9118. namespace Catch {
  9119. namespace Matchers {
  9120. namespace Exception {
  9121. bool ExceptionMessageMatcher::match(std::exception const& ex) const {
  9122. return ex.what() == m_message;
  9123. }
  9124. std::string ExceptionMessageMatcher::describe() const {
  9125. return "exception message matches \"" + m_message + "\"";
  9126. }
  9127. }
  9128. Exception::ExceptionMessageMatcher Message(std::string const& message) {
  9129. return Exception::ExceptionMessageMatcher(message);
  9130. }
  9131. // namespace Exception
  9132. } // namespace Matchers
  9133. } // namespace Catch
  9134. // end catch_matchers_exception.cpp
  9135. // start catch_matchers_floating.cpp
  9136. // start catch_polyfills.hpp
  9137. namespace Catch {
  9138. bool isnan(float f);
  9139. bool isnan(double d);
  9140. }
  9141. // end catch_polyfills.hpp
  9142. // start catch_to_string.hpp
  9143. #include <string>
  9144. namespace Catch {
  9145. template <typename T>
  9146. std::string to_string(T const& t) {
  9147. #if defined(CATCH_CONFIG_CPP11_TO_STRING)
  9148. return std::to_string(t);
  9149. #else
  9150. ReusableStringStream rss;
  9151. rss << t;
  9152. return rss.str();
  9153. #endif
  9154. }
  9155. } // end namespace Catch
  9156. // end catch_to_string.hpp
  9157. #include <algorithm>
  9158. #include <cmath>
  9159. #include <cstdlib>
  9160. #include <cstdint>
  9161. #include <cstring>
  9162. #include <sstream>
  9163. #include <type_traits>
  9164. #include <iomanip>
  9165. #include <limits>
  9166. namespace Catch {
  9167. namespace {
  9168. int32_t convert(float f) {
  9169. static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
  9170. int32_t i;
  9171. std::memcpy(&i, &f, sizeof(f));
  9172. return i;
  9173. }
  9174. int64_t convert(double d) {
  9175. static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
  9176. int64_t i;
  9177. std::memcpy(&i, &d, sizeof(d));
  9178. return i;
  9179. }
  9180. template <typename FP>
  9181. bool almostEqualUlps(FP lhs, FP rhs, uint64_t maxUlpDiff) {
  9182. // Comparison with NaN should always be false.
  9183. // This way we can rule it out before getting into the ugly details
  9184. if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
  9185. return false;
  9186. }
  9187. auto lc = convert(lhs);
  9188. auto rc = convert(rhs);
  9189. if ((lc < 0) != (rc < 0)) {
  9190. // Potentially we can have +0 and -0
  9191. return lhs == rhs;
  9192. }
  9193. auto ulpDiff = std::abs(lc - rc);
  9194. return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff;
  9195. }
  9196. } //end anonymous namespace
  9197. #if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
  9198. #if defined(__clang__)
  9199. #pragma clang diagnostic push
  9200. // The long double overload is currently unused
  9201. #pragma clang diagnostic ignored "-Wunused-function"
  9202. #endif
  9203. float nextafter(float x, float y) {
  9204. return ::nextafterf(x, y);
  9205. }
  9206. double nextafter(double x, double y) {
  9207. return ::nextafter(x, y);
  9208. }
  9209. long double nextafter(long double x, long double y) {
  9210. return ::nextafterl(x, y);
  9211. }
  9212. #if defined(__clang__)
  9213. #pragma clang diagnostic pop
  9214. #endif
  9215. #endif // ^^^ CATCH_CONFIG_GLOBAL_NEXTAFTER ^^^
  9216. namespace {
  9217. template <typename FP>
  9218. FP step(FP start, FP direction, uint64_t steps) {
  9219. for (uint64_t i = 0; i < steps; ++i) {
  9220. #if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
  9221. start = Catch::nextafter(start, direction);
  9222. #else
  9223. start = std::nextafter(start, direction);
  9224. #endif
  9225. }
  9226. return start;
  9227. }
  9228. // Performs equivalent check of std::fabs(lhs - rhs) <= margin
  9229. // But without the subtraction to allow for INFINITY in comparison
  9230. bool marginComparison(double lhs, double rhs, double margin) {
  9231. return (lhs + margin >= rhs) && (rhs + margin >= lhs);
  9232. }
  9233. template <typename FloatingPoint>
  9234. void write(std::ostream& out, FloatingPoint num) {
  9235. out << std::scientific
  9236. << std::setprecision(std::numeric_limits<FloatingPoint>::max_digits10 - 1)
  9237. << num;
  9238. }
  9239. } // end anonymous namespace
  9240. namespace Matchers {
  9241. namespace Floating {
  9242. enum class FloatingPointKind : uint8_t {
  9243. Float,
  9244. Double
  9245. };
  9246. WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
  9247. :m_target{ target }, m_margin{ margin } {
  9248. CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.'
  9249. << " Margin has to be non-negative.");
  9250. }
  9251. // Performs equivalent check of std::fabs(lhs - rhs) <= margin
  9252. // But without the subtraction to allow for INFINITY in comparison
  9253. bool WithinAbsMatcher::match(double const& matchee) const {
  9254. return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);
  9255. }
  9256. std::string WithinAbsMatcher::describe() const {
  9257. return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target);
  9258. }
  9259. WithinUlpsMatcher::WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType)
  9260. :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
  9261. CATCH_ENFORCE(m_type == FloatingPointKind::Double
  9262. || m_ulps < (std::numeric_limits<uint32_t>::max)(),
  9263. "Provided ULP is impossibly large for a float comparison.");
  9264. }
  9265. #if defined(__clang__)
  9266. #pragma clang diagnostic push
  9267. // Clang <3.5 reports on the default branch in the switch below
  9268. #pragma clang diagnostic ignored "-Wunreachable-code"
  9269. #endif
  9270. bool WithinUlpsMatcher::match(double const& matchee) const {
  9271. switch (m_type) {
  9272. case FloatingPointKind::Float:
  9273. return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);
  9274. case FloatingPointKind::Double:
  9275. return almostEqualUlps<double>(matchee, m_target, m_ulps);
  9276. default:
  9277. CATCH_INTERNAL_ERROR( "Unknown FloatingPointKind value" );
  9278. }
  9279. }
  9280. #if defined(__clang__)
  9281. #pragma clang diagnostic pop
  9282. #endif
  9283. std::string WithinUlpsMatcher::describe() const {
  9284. std::stringstream ret;
  9285. ret << "is within " << m_ulps << " ULPs of ";
  9286. if (m_type == FloatingPointKind::Float) {
  9287. write(ret, static_cast<float>(m_target));
  9288. ret << 'f';
  9289. } else {
  9290. write(ret, m_target);
  9291. }
  9292. ret << " ([";
  9293. if (m_type == FloatingPointKind::Double) {
  9294. write(ret, step(m_target, static_cast<double>(-INFINITY), m_ulps));
  9295. ret << ", ";
  9296. write(ret, step(m_target, static_cast<double>( INFINITY), m_ulps));
  9297. } else {
  9298. // We have to cast INFINITY to float because of MinGW, see #1782
  9299. write(ret, step(static_cast<float>(m_target), static_cast<float>(-INFINITY), m_ulps));
  9300. ret << ", ";
  9301. write(ret, step(static_cast<float>(m_target), static_cast<float>( INFINITY), m_ulps));
  9302. }
  9303. ret << "])";
  9304. return ret.str();
  9305. }
  9306. WithinRelMatcher::WithinRelMatcher(double target, double epsilon):
  9307. m_target(target),
  9308. m_epsilon(epsilon){
  9309. CATCH_ENFORCE(m_epsilon >= 0., "Relative comparison with epsilon < 0 does not make sense.");
  9310. CATCH_ENFORCE(m_epsilon < 1., "Relative comparison with epsilon >= 1 does not make sense.");
  9311. }
  9312. bool WithinRelMatcher::match(double const& matchee) const {
  9313. const auto relMargin = m_epsilon * (std::max)(std::fabs(matchee), std::fabs(m_target));
  9314. return marginComparison(matchee, m_target,
  9315. std::isinf(relMargin)? 0 : relMargin);
  9316. }
  9317. std::string WithinRelMatcher::describe() const {
  9318. Catch::ReusableStringStream sstr;
  9319. sstr << "and " << m_target << " are within " << m_epsilon * 100. << "% of each other";
  9320. return sstr.str();
  9321. }
  9322. }// namespace Floating
  9323. Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff) {
  9324. return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
  9325. }
  9326. Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff) {
  9327. return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
  9328. }
  9329. Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
  9330. return Floating::WithinAbsMatcher(target, margin);
  9331. }
  9332. Floating::WithinRelMatcher WithinRel(double target, double eps) {
  9333. return Floating::WithinRelMatcher(target, eps);
  9334. }
  9335. Floating::WithinRelMatcher WithinRel(double target) {
  9336. return Floating::WithinRelMatcher(target, std::numeric_limits<double>::epsilon() * 100);
  9337. }
  9338. Floating::WithinRelMatcher WithinRel(float target, float eps) {
  9339. return Floating::WithinRelMatcher(target, eps);
  9340. }
  9341. Floating::WithinRelMatcher WithinRel(float target) {
  9342. return Floating::WithinRelMatcher(target, std::numeric_limits<float>::epsilon() * 100);
  9343. }
  9344. } // namespace Matchers
  9345. } // namespace Catch
  9346. // end catch_matchers_floating.cpp
  9347. // start catch_matchers_generic.cpp
  9348. std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) {
  9349. if (desc.empty()) {
  9350. return "matches undescribed predicate";
  9351. } else {
  9352. return "matches predicate: \"" + desc + '"';
  9353. }
  9354. }
  9355. // end catch_matchers_generic.cpp
  9356. // start catch_matchers_string.cpp
  9357. #include <regex>
  9358. namespace Catch {
  9359. namespace Matchers {
  9360. namespace StdString {
  9361. CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
  9362. : m_caseSensitivity( caseSensitivity ),
  9363. m_str( adjustString( str ) )
  9364. {}
  9365. std::string CasedString::adjustString( std::string const& str ) const {
  9366. return m_caseSensitivity == CaseSensitive::No
  9367. ? toLower( str )
  9368. : str;
  9369. }
  9370. std::string CasedString::caseSensitivitySuffix() const {
  9371. return m_caseSensitivity == CaseSensitive::No
  9372. ? " (case insensitive)"
  9373. : std::string();
  9374. }
  9375. StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )
  9376. : m_comparator( comparator ),
  9377. m_operation( operation ) {
  9378. }
  9379. std::string StringMatcherBase::describe() const {
  9380. std::string description;
  9381. description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
  9382. m_comparator.caseSensitivitySuffix().size());
  9383. description += m_operation;
  9384. description += ": \"";
  9385. description += m_comparator.m_str;
  9386. description += "\"";
  9387. description += m_comparator.caseSensitivitySuffix();
  9388. return description;
  9389. }
  9390. EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {}
  9391. bool EqualsMatcher::match( std::string const& source ) const {
  9392. return m_comparator.adjustString( source ) == m_comparator.m_str;
  9393. }
  9394. ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {}
  9395. bool ContainsMatcher::match( std::string const& source ) const {
  9396. return contains( m_comparator.adjustString( source ), m_comparator.m_str );
  9397. }
  9398. StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {}
  9399. bool StartsWithMatcher::match( std::string const& source ) const {
  9400. return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
  9401. }
  9402. EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {}
  9403. bool EndsWithMatcher::match( std::string const& source ) const {
  9404. return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
  9405. }
  9406. RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {}
  9407. bool RegexMatcher::match(std::string const& matchee) const {
  9408. auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway
  9409. if (m_caseSensitivity == CaseSensitive::Choice::No) {
  9410. flags |= std::regex::icase;
  9411. }
  9412. auto reg = std::regex(m_regex, flags);
  9413. return std::regex_match(matchee, reg);
  9414. }
  9415. std::string RegexMatcher::describe() const {
  9416. return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? " case sensitively" : " case insensitively");
  9417. }
  9418. } // namespace StdString
  9419. StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
  9420. return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
  9421. }
  9422. StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
  9423. return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
  9424. }
  9425. StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
  9426. return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
  9427. }
  9428. StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
  9429. return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
  9430. }
  9431. StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) {
  9432. return StdString::RegexMatcher(regex, caseSensitivity);
  9433. }
  9434. } // namespace Matchers
  9435. } // namespace Catch
  9436. // end catch_matchers_string.cpp
  9437. // start catch_message.cpp
  9438. // start catch_uncaught_exceptions.h
  9439. namespace Catch {
  9440. bool uncaught_exceptions();
  9441. } // end namespace Catch
  9442. // end catch_uncaught_exceptions.h
  9443. #include <cassert>
  9444. #include <stack>
  9445. namespace Catch {
  9446. MessageInfo::MessageInfo( StringRef const& _macroName,
  9447. SourceLineInfo const& _lineInfo,
  9448. ResultWas::OfType _type )
  9449. : macroName( _macroName ),
  9450. lineInfo( _lineInfo ),
  9451. type( _type ),
  9452. sequence( ++globalCount )
  9453. {}
  9454. bool MessageInfo::operator==( MessageInfo const& other ) const {
  9455. return sequence == other.sequence;
  9456. }
  9457. bool MessageInfo::operator<( MessageInfo const& other ) const {
  9458. return sequence < other.sequence;
  9459. }
  9460. // This may need protecting if threading support is added
  9461. unsigned int MessageInfo::globalCount = 0;
  9462. ////////////////////////////////////////////////////////////////////////////
  9463. Catch::MessageBuilder::MessageBuilder( StringRef const& macroName,
  9464. SourceLineInfo const& lineInfo,
  9465. ResultWas::OfType type )
  9466. :m_info(macroName, lineInfo, type) {}
  9467. ////////////////////////////////////////////////////////////////////////////
  9468. ScopedMessage::ScopedMessage( MessageBuilder const& builder )
  9469. : m_info( builder.m_info ), m_moved()
  9470. {
  9471. m_info.message = builder.m_stream.str();
  9472. getResultCapture().pushScopedMessage( m_info );
  9473. }
  9474. ScopedMessage::ScopedMessage( ScopedMessage&& old )
  9475. : m_info( old.m_info ), m_moved()
  9476. {
  9477. old.m_moved = true;
  9478. }
  9479. ScopedMessage::~ScopedMessage() {
  9480. if ( !uncaught_exceptions() && !m_moved ){
  9481. getResultCapture().popScopedMessage(m_info);
  9482. }
  9483. }
  9484. Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {
  9485. auto trimmed = [&] (size_t start, size_t end) {
  9486. while (names[start] == ',' || isspace(names[start])) {
  9487. ++start;
  9488. }
  9489. while (names[end] == ',' || isspace(names[end])) {
  9490. --end;
  9491. }
  9492. return names.substr(start, end - start + 1);
  9493. };
  9494. auto skipq = [&] (size_t start, char quote) {
  9495. for (auto i = start + 1; i < names.size() ; ++i) {
  9496. if (names[i] == quote)
  9497. return i;
  9498. if (names[i] == '\\')
  9499. ++i;
  9500. }
  9501. CATCH_INTERNAL_ERROR("CAPTURE parsing encountered unmatched quote");
  9502. };
  9503. size_t start = 0;
  9504. std::stack<char> openings;
  9505. for (size_t pos = 0; pos < names.size(); ++pos) {
  9506. char c = names[pos];
  9507. switch (c) {
  9508. case '[':
  9509. case '{':
  9510. case '(':
  9511. // It is basically impossible to disambiguate between
  9512. // comparison and start of template args in this context
  9513. // case '<':
  9514. openings.push(c);
  9515. break;
  9516. case ']':
  9517. case '}':
  9518. case ')':
  9519. // case '>':
  9520. openings.pop();
  9521. break;
  9522. case '"':
  9523. case '\'':
  9524. pos = skipq(pos, c);
  9525. break;
  9526. case ',':
  9527. if (start != pos && openings.size() == 0) {
  9528. m_messages.emplace_back(macroName, lineInfo, resultType);
  9529. m_messages.back().message = static_cast<std::string>(trimmed(start, pos));
  9530. m_messages.back().message += " := ";
  9531. start = pos;
  9532. }
  9533. }
  9534. }
  9535. assert(openings.size() == 0 && "Mismatched openings");
  9536. m_messages.emplace_back(macroName, lineInfo, resultType);
  9537. m_messages.back().message = static_cast<std::string>(trimmed(start, names.size() - 1));
  9538. m_messages.back().message += " := ";
  9539. }
  9540. Capturer::~Capturer() {
  9541. if ( !uncaught_exceptions() ){
  9542. assert( m_captured == m_messages.size() );
  9543. for( size_t i = 0; i < m_captured; ++i )
  9544. m_resultCapture.popScopedMessage( m_messages[i] );
  9545. }
  9546. }
  9547. void Capturer::captureValue( size_t index, std::string const& value ) {
  9548. assert( index < m_messages.size() );
  9549. m_messages[index].message += value;
  9550. m_resultCapture.pushScopedMessage( m_messages[index] );
  9551. m_captured++;
  9552. }
  9553. } // end namespace Catch
  9554. // end catch_message.cpp
  9555. // start catch_output_redirect.cpp
  9556. // start catch_output_redirect.h
  9557. #ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
  9558. #define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
  9559. #include <cstdio>
  9560. #include <iosfwd>
  9561. #include <string>
  9562. namespace Catch {
  9563. class RedirectedStream {
  9564. std::ostream& m_originalStream;
  9565. std::ostream& m_redirectionStream;
  9566. std::streambuf* m_prevBuf;
  9567. public:
  9568. RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream );
  9569. ~RedirectedStream();
  9570. };
  9571. class RedirectedStdOut {
  9572. ReusableStringStream m_rss;
  9573. RedirectedStream m_cout;
  9574. public:
  9575. RedirectedStdOut();
  9576. auto str() const -> std::string;
  9577. };
  9578. // StdErr has two constituent streams in C++, std::cerr and std::clog
  9579. // This means that we need to redirect 2 streams into 1 to keep proper
  9580. // order of writes
  9581. class RedirectedStdErr {
  9582. ReusableStringStream m_rss;
  9583. RedirectedStream m_cerr;
  9584. RedirectedStream m_clog;
  9585. public:
  9586. RedirectedStdErr();
  9587. auto str() const -> std::string;
  9588. };
  9589. class RedirectedStreams {
  9590. public:
  9591. RedirectedStreams(RedirectedStreams const&) = delete;
  9592. RedirectedStreams& operator=(RedirectedStreams const&) = delete;
  9593. RedirectedStreams(RedirectedStreams&&) = delete;
  9594. RedirectedStreams& operator=(RedirectedStreams&&) = delete;
  9595. RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr);
  9596. ~RedirectedStreams();
  9597. private:
  9598. std::string& m_redirectedCout;
  9599. std::string& m_redirectedCerr;
  9600. RedirectedStdOut m_redirectedStdOut;
  9601. RedirectedStdErr m_redirectedStdErr;
  9602. };
  9603. #if defined(CATCH_CONFIG_NEW_CAPTURE)
  9604. // Windows's implementation of std::tmpfile is terrible (it tries
  9605. // to create a file inside system folder, thus requiring elevated
  9606. // privileges for the binary), so we have to use tmpnam(_s) and
  9607. // create the file ourselves there.
  9608. class TempFile {
  9609. public:
  9610. TempFile(TempFile const&) = delete;
  9611. TempFile& operator=(TempFile const&) = delete;
  9612. TempFile(TempFile&&) = delete;
  9613. TempFile& operator=(TempFile&&) = delete;
  9614. TempFile();
  9615. ~TempFile();
  9616. std::FILE* getFile();
  9617. std::string getContents();
  9618. private:
  9619. std::FILE* m_file = nullptr;
  9620. #if defined(_MSC_VER)
  9621. char m_buffer[L_tmpnam] = { 0 };
  9622. #endif
  9623. };
  9624. class OutputRedirect {
  9625. public:
  9626. OutputRedirect(OutputRedirect const&) = delete;
  9627. OutputRedirect& operator=(OutputRedirect const&) = delete;
  9628. OutputRedirect(OutputRedirect&&) = delete;
  9629. OutputRedirect& operator=(OutputRedirect&&) = delete;
  9630. OutputRedirect(std::string& stdout_dest, std::string& stderr_dest);
  9631. ~OutputRedirect();
  9632. private:
  9633. int m_originalStdout = -1;
  9634. int m_originalStderr = -1;
  9635. TempFile m_stdoutFile;
  9636. TempFile m_stderrFile;
  9637. std::string& m_stdoutDest;
  9638. std::string& m_stderrDest;
  9639. };
  9640. #endif
  9641. } // end namespace Catch
  9642. #endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
  9643. // end catch_output_redirect.h
  9644. #include <cstdio>
  9645. #include <cstring>
  9646. #include <fstream>
  9647. #include <sstream>
  9648. #include <stdexcept>
  9649. #if defined(CATCH_CONFIG_NEW_CAPTURE)
  9650. #if defined(_MSC_VER)
  9651. #include <io.h> //_dup and _dup2
  9652. #define dup _dup
  9653. #define dup2 _dup2
  9654. #define fileno _fileno
  9655. #else
  9656. #include <unistd.h> // dup and dup2
  9657. #endif
  9658. #endif
  9659. namespace Catch {
  9660. RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream )
  9661. : m_originalStream( originalStream ),
  9662. m_redirectionStream( redirectionStream ),
  9663. m_prevBuf( m_originalStream.rdbuf() )
  9664. {
  9665. m_originalStream.rdbuf( m_redirectionStream.rdbuf() );
  9666. }
  9667. RedirectedStream::~RedirectedStream() {
  9668. m_originalStream.rdbuf( m_prevBuf );
  9669. }
  9670. RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {}
  9671. auto RedirectedStdOut::str() const -> std::string { return m_rss.str(); }
  9672. RedirectedStdErr::RedirectedStdErr()
  9673. : m_cerr( Catch::cerr(), m_rss.get() ),
  9674. m_clog( Catch::clog(), m_rss.get() )
  9675. {}
  9676. auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }
  9677. RedirectedStreams::RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr)
  9678. : m_redirectedCout(redirectedCout),
  9679. m_redirectedCerr(redirectedCerr)
  9680. {}
  9681. RedirectedStreams::~RedirectedStreams() {
  9682. m_redirectedCout += m_redirectedStdOut.str();
  9683. m_redirectedCerr += m_redirectedStdErr.str();
  9684. }
  9685. #if defined(CATCH_CONFIG_NEW_CAPTURE)
  9686. #if defined(_MSC_VER)
  9687. TempFile::TempFile() {
  9688. if (tmpnam_s(m_buffer)) {
  9689. CATCH_RUNTIME_ERROR("Could not get a temp filename");
  9690. }
  9691. if (fopen_s(&m_file, m_buffer, "w")) {
  9692. char buffer[100];
  9693. if (strerror_s(buffer, errno)) {
  9694. CATCH_RUNTIME_ERROR("Could not translate errno to a string");
  9695. }
  9696. CATCH_RUNTIME_ERROR("Could not open the temp file: '" << m_buffer << "' because: " << buffer);
  9697. }
  9698. }
  9699. #else
  9700. TempFile::TempFile() {
  9701. m_file = std::tmpfile();
  9702. if (!m_file) {
  9703. CATCH_RUNTIME_ERROR("Could not create a temp file.");
  9704. }
  9705. }
  9706. #endif
  9707. TempFile::~TempFile() {
  9708. // TBD: What to do about errors here?
  9709. std::fclose(m_file);
  9710. // We manually create the file on Windows only, on Linux
  9711. // it will be autodeleted
  9712. #if defined(_MSC_VER)
  9713. std::remove(m_buffer);
  9714. #endif
  9715. }
  9716. FILE* TempFile::getFile() {
  9717. return m_file;
  9718. }
  9719. std::string TempFile::getContents() {
  9720. std::stringstream sstr;
  9721. char buffer[100] = {};
  9722. std::rewind(m_file);
  9723. while (std::fgets(buffer, sizeof(buffer), m_file)) {
  9724. sstr << buffer;
  9725. }
  9726. return sstr.str();
  9727. }
  9728. OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest) :
  9729. m_originalStdout(dup(1)),
  9730. m_originalStderr(dup(2)),
  9731. m_stdoutDest(stdout_dest),
  9732. m_stderrDest(stderr_dest) {
  9733. dup2(fileno(m_stdoutFile.getFile()), 1);
  9734. dup2(fileno(m_stderrFile.getFile()), 2);
  9735. }
  9736. OutputRedirect::~OutputRedirect() {
  9737. Catch::cout() << std::flush;
  9738. fflush(stdout);
  9739. // Since we support overriding these streams, we flush cerr
  9740. // even though std::cerr is unbuffered
  9741. Catch::cerr() << std::flush;
  9742. Catch::clog() << std::flush;
  9743. fflush(stderr);
  9744. dup2(m_originalStdout, 1);
  9745. dup2(m_originalStderr, 2);
  9746. m_stdoutDest += m_stdoutFile.getContents();
  9747. m_stderrDest += m_stderrFile.getContents();
  9748. }
  9749. #endif // CATCH_CONFIG_NEW_CAPTURE
  9750. } // namespace Catch
  9751. #if defined(CATCH_CONFIG_NEW_CAPTURE)
  9752. #if defined(_MSC_VER)
  9753. #undef dup
  9754. #undef dup2
  9755. #undef fileno
  9756. #endif
  9757. #endif
  9758. // end catch_output_redirect.cpp
  9759. // start catch_polyfills.cpp
  9760. #include <cmath>
  9761. namespace Catch {
  9762. #if !defined(CATCH_CONFIG_POLYFILL_ISNAN)
  9763. bool isnan(float f) {
  9764. return std::isnan(f);
  9765. }
  9766. bool isnan(double d) {
  9767. return std::isnan(d);
  9768. }
  9769. #else
  9770. // For now we only use this for embarcadero
  9771. bool isnan(float f) {
  9772. return std::_isnan(f);
  9773. }
  9774. bool isnan(double d) {
  9775. return std::_isnan(d);
  9776. }
  9777. #endif
  9778. } // end namespace Catch
  9779. // end catch_polyfills.cpp
  9780. // start catch_random_number_generator.cpp
  9781. namespace Catch {
  9782. namespace {
  9783. #if defined(_MSC_VER)
  9784. #pragma warning(push)
  9785. #pragma warning(disable:4146) // we negate uint32 during the rotate
  9786. #endif
  9787. // Safe rotr implementation thanks to John Regehr
  9788. uint32_t rotate_right(uint32_t val, uint32_t count) {
  9789. const uint32_t mask = 31;
  9790. count &= mask;
  9791. return (val >> count) | (val << (-count & mask));
  9792. }
  9793. #if defined(_MSC_VER)
  9794. #pragma warning(pop)
  9795. #endif
  9796. }
  9797. SimplePcg32::SimplePcg32(result_type seed_) {
  9798. seed(seed_);
  9799. }
  9800. void SimplePcg32::seed(result_type seed_) {
  9801. m_state = 0;
  9802. (*this)();
  9803. m_state += seed_;
  9804. (*this)();
  9805. }
  9806. void SimplePcg32::discard(uint64_t skip) {
  9807. // We could implement this to run in O(log n) steps, but this
  9808. // should suffice for our use case.
  9809. for (uint64_t s = 0; s < skip; ++s) {
  9810. static_cast<void>((*this)());
  9811. }
  9812. }
  9813. SimplePcg32::result_type SimplePcg32::operator()() {
  9814. // prepare the output value
  9815. const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u);
  9816. const auto output = rotate_right(xorshifted, m_state >> 59u);
  9817. // advance state
  9818. m_state = m_state * 6364136223846793005ULL + s_inc;
  9819. return output;
  9820. }
  9821. bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
  9822. return lhs.m_state == rhs.m_state;
  9823. }
  9824. bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
  9825. return lhs.m_state != rhs.m_state;
  9826. }
  9827. }
  9828. // end catch_random_number_generator.cpp
  9829. // start catch_registry_hub.cpp
  9830. // start catch_test_case_registry_impl.h
  9831. #include <vector>
  9832. #include <set>
  9833. #include <algorithm>
  9834. #include <ios>
  9835. namespace Catch {
  9836. class TestCase;
  9837. struct IConfig;
  9838. std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases );
  9839. bool isThrowSafe( TestCase const& testCase, IConfig const& config );
  9840. bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
  9841. void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions );
  9842. std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
  9843. std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
  9844. class TestRegistry : public ITestCaseRegistry {
  9845. public:
  9846. virtual ~TestRegistry() = default;
  9847. virtual void registerTest( TestCase const& testCase );
  9848. std::vector<TestCase> const& getAllTests() const override;
  9849. std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const override;
  9850. private:
  9851. std::vector<TestCase> m_functions;
  9852. mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
  9853. mutable std::vector<TestCase> m_sortedFunctions;
  9854. std::size_t m_unnamedCount = 0;
  9855. std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
  9856. };
  9857. ///////////////////////////////////////////////////////////////////////////
  9858. class TestInvokerAsFunction : public ITestInvoker {
  9859. void(*m_testAsFunction)();
  9860. public:
  9861. TestInvokerAsFunction( void(*testAsFunction)() ) noexcept;
  9862. void invoke() const override;
  9863. };
  9864. std::string extractClassName( StringRef const& classOrQualifiedMethodName );
  9865. ///////////////////////////////////////////////////////////////////////////
  9866. } // end namespace Catch
  9867. // end catch_test_case_registry_impl.h
  9868. // start catch_reporter_registry.h
  9869. #include <map>
  9870. namespace Catch {
  9871. class ReporterRegistry : public IReporterRegistry {
  9872. public:
  9873. ~ReporterRegistry() override;
  9874. IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override;
  9875. void registerReporter( std::string const& name, IReporterFactoryPtr const& factory );
  9876. void registerListener( IReporterFactoryPtr const& factory );
  9877. FactoryMap const& getFactories() const override;
  9878. Listeners const& getListeners() const override;
  9879. private:
  9880. FactoryMap m_factories;
  9881. Listeners m_listeners;
  9882. };
  9883. }
  9884. // end catch_reporter_registry.h
  9885. // start catch_tag_alias_registry.h
  9886. // start catch_tag_alias.h
  9887. #include <string>
  9888. namespace Catch {
  9889. struct TagAlias {
  9890. TagAlias(std::string const& _tag, SourceLineInfo _lineInfo);
  9891. std::string tag;
  9892. SourceLineInfo lineInfo;
  9893. };
  9894. } // end namespace Catch
  9895. // end catch_tag_alias.h
  9896. #include <map>
  9897. namespace Catch {
  9898. class TagAliasRegistry : public ITagAliasRegistry {
  9899. public:
  9900. ~TagAliasRegistry() override;
  9901. TagAlias const* find( std::string const& alias ) const override;
  9902. std::string expandAliases( std::string const& unexpandedTestSpec ) const override;
  9903. void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
  9904. private:
  9905. std::map<std::string, TagAlias> m_registry;
  9906. };
  9907. } // end namespace Catch
  9908. // end catch_tag_alias_registry.h
  9909. // start catch_startup_exception_registry.h
  9910. #include <vector>
  9911. #include <exception>
  9912. namespace Catch {
  9913. class StartupExceptionRegistry {
  9914. public:
  9915. void add(std::exception_ptr const& exception) noexcept;
  9916. std::vector<std::exception_ptr> const& getExceptions() const noexcept;
  9917. private:
  9918. std::vector<std::exception_ptr> m_exceptions;
  9919. };
  9920. } // end namespace Catch
  9921. // end catch_startup_exception_registry.h
  9922. // start catch_singletons.hpp
  9923. namespace Catch {
  9924. struct ISingleton {
  9925. virtual ~ISingleton();
  9926. };
  9927. void addSingleton( ISingleton* singleton );
  9928. void cleanupSingletons();
  9929. template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>
  9930. class Singleton : SingletonImplT, public ISingleton {
  9931. static auto getInternal() -> Singleton* {
  9932. static Singleton* s_instance = nullptr;
  9933. if( !s_instance ) {
  9934. s_instance = new Singleton;
  9935. addSingleton( s_instance );
  9936. }
  9937. return s_instance;
  9938. }
  9939. public:
  9940. static auto get() -> InterfaceT const& {
  9941. return *getInternal();
  9942. }
  9943. static auto getMutable() -> MutableInterfaceT& {
  9944. return *getInternal();
  9945. }
  9946. };
  9947. } // namespace Catch
  9948. // end catch_singletons.hpp
  9949. namespace Catch {
  9950. namespace {
  9951. class RegistryHub : public IRegistryHub, public IMutableRegistryHub,
  9952. private NonCopyable {
  9953. public: // IRegistryHub
  9954. RegistryHub() = default;
  9955. IReporterRegistry const& getReporterRegistry() const override {
  9956. return m_reporterRegistry;
  9957. }
  9958. ITestCaseRegistry const& getTestCaseRegistry() const override {
  9959. return m_testCaseRegistry;
  9960. }
  9961. IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override {
  9962. return m_exceptionTranslatorRegistry;
  9963. }
  9964. ITagAliasRegistry const& getTagAliasRegistry() const override {
  9965. return m_tagAliasRegistry;
  9966. }
  9967. StartupExceptionRegistry const& getStartupExceptionRegistry() const override {
  9968. return m_exceptionRegistry;
  9969. }
  9970. public: // IMutableRegistryHub
  9971. void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override {
  9972. m_reporterRegistry.registerReporter( name, factory );
  9973. }
  9974. void registerListener( IReporterFactoryPtr const& factory ) override {
  9975. m_reporterRegistry.registerListener( factory );
  9976. }
  9977. void registerTest( TestCase const& testInfo ) override {
  9978. m_testCaseRegistry.registerTest( testInfo );
  9979. }
  9980. void registerTranslator( const IExceptionTranslator* translator ) override {
  9981. m_exceptionTranslatorRegistry.registerTranslator( translator );
  9982. }
  9983. void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override {
  9984. m_tagAliasRegistry.add( alias, tag, lineInfo );
  9985. }
  9986. void registerStartupException() noexcept override {
  9987. m_exceptionRegistry.add(std::current_exception());
  9988. }
  9989. IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override {
  9990. return m_enumValuesRegistry;
  9991. }
  9992. private:
  9993. TestRegistry m_testCaseRegistry;
  9994. ReporterRegistry m_reporterRegistry;
  9995. ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
  9996. TagAliasRegistry m_tagAliasRegistry;
  9997. StartupExceptionRegistry m_exceptionRegistry;
  9998. Detail::EnumValuesRegistry m_enumValuesRegistry;
  9999. };
  10000. }
  10001. using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;
  10002. IRegistryHub const& getRegistryHub() {
  10003. return RegistryHubSingleton::get();
  10004. }
  10005. IMutableRegistryHub& getMutableRegistryHub() {
  10006. return RegistryHubSingleton::getMutable();
  10007. }
  10008. void cleanUp() {
  10009. cleanupSingletons();
  10010. cleanUpContext();
  10011. }
  10012. std::string translateActiveException() {
  10013. return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
  10014. }
  10015. } // end namespace Catch
  10016. // end catch_registry_hub.cpp
  10017. // start catch_reporter_registry.cpp
  10018. namespace Catch {
  10019. ReporterRegistry::~ReporterRegistry() = default;
  10020. IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const {
  10021. auto it = m_factories.find( name );
  10022. if( it == m_factories.end() )
  10023. return nullptr;
  10024. return it->second->create( ReporterConfig( config ) );
  10025. }
  10026. void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) {
  10027. m_factories.emplace(name, factory);
  10028. }
  10029. void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) {
  10030. m_listeners.push_back( factory );
  10031. }
  10032. IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const {
  10033. return m_factories;
  10034. }
  10035. IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const {
  10036. return m_listeners;
  10037. }
  10038. }
  10039. // end catch_reporter_registry.cpp
  10040. // start catch_result_type.cpp
  10041. namespace Catch {
  10042. bool isOk( ResultWas::OfType resultType ) {
  10043. return ( resultType & ResultWas::FailureBit ) == 0;
  10044. }
  10045. bool isJustInfo( int flags ) {
  10046. return flags == ResultWas::Info;
  10047. }
  10048. ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
  10049. return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
  10050. }
  10051. bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
  10052. bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
  10053. } // end namespace Catch
  10054. // end catch_result_type.cpp
  10055. // start catch_run_context.cpp
  10056. #include <cassert>
  10057. #include <algorithm>
  10058. #include <sstream>
  10059. namespace Catch {
  10060. namespace Generators {
  10061. struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {
  10062. GeneratorBasePtr m_generator;
  10063. GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
  10064. : TrackerBase( nameAndLocation, ctx, parent )
  10065. {}
  10066. ~GeneratorTracker();
  10067. static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
  10068. std::shared_ptr<GeneratorTracker> tracker;
  10069. ITracker& currentTracker = ctx.currentTracker();
  10070. if( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
  10071. assert( childTracker );
  10072. assert( childTracker->isGeneratorTracker() );
  10073. tracker = std::static_pointer_cast<GeneratorTracker>( childTracker );
  10074. }
  10075. else {
  10076. tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, &currentTracker );
  10077. currentTracker.addChild( tracker );
  10078. }
  10079. if( !ctx.completedCycle() && !tracker->isComplete() ) {
  10080. tracker->open();
  10081. }
  10082. return *tracker;
  10083. }
  10084. // TrackerBase interface
  10085. bool isGeneratorTracker() const override { return true; }
  10086. auto hasGenerator() const -> bool override {
  10087. return !!m_generator;
  10088. }
  10089. void close() override {
  10090. TrackerBase::close();
  10091. // Generator interface only finds out if it has another item on atual move
  10092. if (m_runState == CompletedSuccessfully && m_generator->next()) {
  10093. m_children.clear();
  10094. m_runState = Executing;
  10095. }
  10096. }
  10097. // IGeneratorTracker interface
  10098. auto getGenerator() const -> GeneratorBasePtr const& override {
  10099. return m_generator;
  10100. }
  10101. void setGenerator( GeneratorBasePtr&& generator ) override {
  10102. m_generator = std::move( generator );
  10103. }
  10104. };
  10105. GeneratorTracker::~GeneratorTracker() {}
  10106. }
  10107. RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
  10108. : m_runInfo(_config->name()),
  10109. m_context(getCurrentMutableContext()),
  10110. m_config(_config),
  10111. m_reporter(std::move(reporter)),
  10112. m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
  10113. m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
  10114. {
  10115. m_context.setRunner(this);
  10116. m_context.setConfig(m_config);
  10117. m_context.setResultCapture(this);
  10118. m_reporter->testRunStarting(m_runInfo);
  10119. }
  10120. RunContext::~RunContext() {
  10121. m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
  10122. }
  10123. void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) {
  10124. m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
  10125. }
  10126. void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) {
  10127. m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
  10128. }
  10129. Totals RunContext::runTest(TestCase const& testCase) {
  10130. Totals prevTotals = m_totals;
  10131. std::string redirectedCout;
  10132. std::string redirectedCerr;
  10133. auto const& testInfo = testCase.getTestCaseInfo();
  10134. m_reporter->testCaseStarting(testInfo);
  10135. m_activeTestCase = &testCase;
  10136. ITracker& rootTracker = m_trackerContext.startRun();
  10137. assert(rootTracker.isSectionTracker());
  10138. static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
  10139. do {
  10140. m_trackerContext.startCycle();
  10141. m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
  10142. runCurrentTest(redirectedCout, redirectedCerr);
  10143. } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());
  10144. Totals deltaTotals = m_totals.delta(prevTotals);
  10145. if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {
  10146. deltaTotals.assertions.failed++;
  10147. deltaTotals.testCases.passed--;
  10148. deltaTotals.testCases.failed++;
  10149. }
  10150. m_totals.testCases += deltaTotals.testCases;
  10151. m_reporter->testCaseEnded(TestCaseStats(testInfo,
  10152. deltaTotals,
  10153. redirectedCout,
  10154. redirectedCerr,
  10155. aborting()));
  10156. m_activeTestCase = nullptr;
  10157. m_testCaseTracker = nullptr;
  10158. return deltaTotals;
  10159. }
  10160. IConfigPtr RunContext::config() const {
  10161. return m_config;
  10162. }
  10163. IStreamingReporter& RunContext::reporter() const {
  10164. return *m_reporter;
  10165. }
  10166. void RunContext::assertionEnded(AssertionResult const & result) {
  10167. if (result.getResultType() == ResultWas::Ok) {
  10168. m_totals.assertions.passed++;
  10169. m_lastAssertionPassed = true;
  10170. } else if (!result.isOk()) {
  10171. m_lastAssertionPassed = false;
  10172. if( m_activeTestCase->getTestCaseInfo().okToFail() )
  10173. m_totals.assertions.failedButOk++;
  10174. else
  10175. m_totals.assertions.failed++;
  10176. }
  10177. else {
  10178. m_lastAssertionPassed = true;
  10179. }
  10180. // We have no use for the return value (whether messages should be cleared), because messages were made scoped
  10181. // and should be let to clear themselves out.
  10182. static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
  10183. if (result.getResultType() != ResultWas::Warning)
  10184. m_messageScopes.clear();
  10185. // Reset working state
  10186. resetAssertionInfo();
  10187. m_lastResult = result;
  10188. }
  10189. void RunContext::resetAssertionInfo() {
  10190. m_lastAssertionInfo.macroName = StringRef();
  10191. m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
  10192. }
  10193. bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) {
  10194. ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
  10195. if (!sectionTracker.isOpen())
  10196. return false;
  10197. m_activeSections.push_back(&sectionTracker);
  10198. m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
  10199. m_reporter->sectionStarting(sectionInfo);
  10200. assertions = m_totals.assertions;
  10201. return true;
  10202. }
  10203. auto RunContext::acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
  10204. using namespace Generators;
  10205. GeneratorTracker& tracker = GeneratorTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( "generator", lineInfo ) );
  10206. assert( tracker.isOpen() );
  10207. m_lastAssertionInfo.lineInfo = lineInfo;
  10208. return tracker;
  10209. }
  10210. bool RunContext::testForMissingAssertions(Counts& assertions) {
  10211. if (assertions.total() != 0)
  10212. return false;
  10213. if (!m_config->warnAboutMissingAssertions())
  10214. return false;
  10215. if (m_trackerContext.currentTracker().hasChildren())
  10216. return false;
  10217. m_totals.assertions.failed++;
  10218. assertions.failed++;
  10219. return true;
  10220. }
  10221. void RunContext::sectionEnded(SectionEndInfo const & endInfo) {
  10222. Counts assertions = m_totals.assertions - endInfo.prevAssertions;
  10223. bool missingAssertions = testForMissingAssertions(assertions);
  10224. if (!m_activeSections.empty()) {
  10225. m_activeSections.back()->close();
  10226. m_activeSections.pop_back();
  10227. }
  10228. m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
  10229. m_messages.clear();
  10230. m_messageScopes.clear();
  10231. }
  10232. void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {
  10233. if (m_unfinishedSections.empty())
  10234. m_activeSections.back()->fail();
  10235. else
  10236. m_activeSections.back()->close();
  10237. m_activeSections.pop_back();
  10238. m_unfinishedSections.push_back(endInfo);
  10239. }
  10240. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  10241. void RunContext::benchmarkPreparing(std::string const& name) {
  10242. m_reporter->benchmarkPreparing(name);
  10243. }
  10244. void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
  10245. m_reporter->benchmarkStarting( info );
  10246. }
  10247. void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) {
  10248. m_reporter->benchmarkEnded( stats );
  10249. }
  10250. void RunContext::benchmarkFailed(std::string const & error) {
  10251. m_reporter->benchmarkFailed(error);
  10252. }
  10253. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  10254. void RunContext::pushScopedMessage(MessageInfo const & message) {
  10255. m_messages.push_back(message);
  10256. }
  10257. void RunContext::popScopedMessage(MessageInfo const & message) {
  10258. m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
  10259. }
  10260. void RunContext::emplaceUnscopedMessage( MessageBuilder const& builder ) {
  10261. m_messageScopes.emplace_back( builder );
  10262. }
  10263. std::string RunContext::getCurrentTestName() const {
  10264. return m_activeTestCase
  10265. ? m_activeTestCase->getTestCaseInfo().name
  10266. : std::string();
  10267. }
  10268. const AssertionResult * RunContext::getLastResult() const {
  10269. return &(*m_lastResult);
  10270. }
  10271. void RunContext::exceptionEarlyReported() {
  10272. m_shouldReportUnexpected = false;
  10273. }
  10274. void RunContext::handleFatalErrorCondition( StringRef message ) {
  10275. // First notify reporter that bad things happened
  10276. m_reporter->fatalErrorEncountered(message);
  10277. // Don't rebuild the result -- the stringification itself can cause more fatal errors
  10278. // Instead, fake a result data.
  10279. AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
  10280. tempResult.message = static_cast<std::string>(message);
  10281. AssertionResult result(m_lastAssertionInfo, tempResult);
  10282. assertionEnded(result);
  10283. handleUnfinishedSections();
  10284. // Recreate section for test case (as we will lose the one that was in scope)
  10285. auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
  10286. SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
  10287. Counts assertions;
  10288. assertions.failed = 1;
  10289. SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);
  10290. m_reporter->sectionEnded(testCaseSectionStats);
  10291. auto const& testInfo = m_activeTestCase->getTestCaseInfo();
  10292. Totals deltaTotals;
  10293. deltaTotals.testCases.failed = 1;
  10294. deltaTotals.assertions.failed = 1;
  10295. m_reporter->testCaseEnded(TestCaseStats(testInfo,
  10296. deltaTotals,
  10297. std::string(),
  10298. std::string(),
  10299. false));
  10300. m_totals.testCases.failed++;
  10301. testGroupEnded(std::string(), m_totals, 1, 1);
  10302. m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
  10303. }
  10304. bool RunContext::lastAssertionPassed() {
  10305. return m_lastAssertionPassed;
  10306. }
  10307. void RunContext::assertionPassed() {
  10308. m_lastAssertionPassed = true;
  10309. ++m_totals.assertions.passed;
  10310. resetAssertionInfo();
  10311. m_messageScopes.clear();
  10312. }
  10313. bool RunContext::aborting() const {
  10314. return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());
  10315. }
  10316. void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
  10317. auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
  10318. SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
  10319. m_reporter->sectionStarting(testCaseSection);
  10320. Counts prevAssertions = m_totals.assertions;
  10321. double duration = 0;
  10322. m_shouldReportUnexpected = true;
  10323. m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };
  10324. seedRng(*m_config);
  10325. Timer timer;
  10326. CATCH_TRY {
  10327. if (m_reporter->getPreferences().shouldRedirectStdOut) {
  10328. #if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
  10329. RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr);
  10330. timer.start();
  10331. invokeActiveTestCase();
  10332. #else
  10333. OutputRedirect r(redirectedCout, redirectedCerr);
  10334. timer.start();
  10335. invokeActiveTestCase();
  10336. #endif
  10337. } else {
  10338. timer.start();
  10339. invokeActiveTestCase();
  10340. }
  10341. duration = timer.getElapsedSeconds();
  10342. } CATCH_CATCH_ANON (TestFailureException&) {
  10343. // This just means the test was aborted due to failure
  10344. } CATCH_CATCH_ALL {
  10345. // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
  10346. // are reported without translation at the point of origin.
  10347. if( m_shouldReportUnexpected ) {
  10348. AssertionReaction dummyReaction;
  10349. handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );
  10350. }
  10351. }
  10352. Counts assertions = m_totals.assertions - prevAssertions;
  10353. bool missingAssertions = testForMissingAssertions(assertions);
  10354. m_testCaseTracker->close();
  10355. handleUnfinishedSections();
  10356. m_messages.clear();
  10357. m_messageScopes.clear();
  10358. SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
  10359. m_reporter->sectionEnded(testCaseSectionStats);
  10360. }
  10361. void RunContext::invokeActiveTestCase() {
  10362. FatalConditionHandler fatalConditionHandler; // Handle signals
  10363. m_activeTestCase->invoke();
  10364. fatalConditionHandler.reset();
  10365. }
  10366. void RunContext::handleUnfinishedSections() {
  10367. // If sections ended prematurely due to an exception we stored their
  10368. // infos here so we can tear them down outside the unwind process.
  10369. for (auto it = m_unfinishedSections.rbegin(),
  10370. itEnd = m_unfinishedSections.rend();
  10371. it != itEnd;
  10372. ++it)
  10373. sectionEnded(*it);
  10374. m_unfinishedSections.clear();
  10375. }
  10376. void RunContext::handleExpr(
  10377. AssertionInfo const& info,
  10378. ITransientExpression const& expr,
  10379. AssertionReaction& reaction
  10380. ) {
  10381. m_reporter->assertionStarting( info );
  10382. bool negated = isFalseTest( info.resultDisposition );
  10383. bool result = expr.getResult() != negated;
  10384. if( result ) {
  10385. if (!m_includeSuccessfulResults) {
  10386. assertionPassed();
  10387. }
  10388. else {
  10389. reportExpr(info, ResultWas::Ok, &expr, negated);
  10390. }
  10391. }
  10392. else {
  10393. reportExpr(info, ResultWas::ExpressionFailed, &expr, negated );
  10394. populateReaction( reaction );
  10395. }
  10396. }
  10397. void RunContext::reportExpr(
  10398. AssertionInfo const &info,
  10399. ResultWas::OfType resultType,
  10400. ITransientExpression const *expr,
  10401. bool negated ) {
  10402. m_lastAssertionInfo = info;
  10403. AssertionResultData data( resultType, LazyExpression( negated ) );
  10404. AssertionResult assertionResult{ info, data };
  10405. assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
  10406. assertionEnded( assertionResult );
  10407. }
  10408. void RunContext::handleMessage(
  10409. AssertionInfo const& info,
  10410. ResultWas::OfType resultType,
  10411. StringRef const& message,
  10412. AssertionReaction& reaction
  10413. ) {
  10414. m_reporter->assertionStarting( info );
  10415. m_lastAssertionInfo = info;
  10416. AssertionResultData data( resultType, LazyExpression( false ) );
  10417. data.message = static_cast<std::string>(message);
  10418. AssertionResult assertionResult{ m_lastAssertionInfo, data };
  10419. assertionEnded( assertionResult );
  10420. if( !assertionResult.isOk() )
  10421. populateReaction( reaction );
  10422. }
  10423. void RunContext::handleUnexpectedExceptionNotThrown(
  10424. AssertionInfo const& info,
  10425. AssertionReaction& reaction
  10426. ) {
  10427. handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction);
  10428. }
  10429. void RunContext::handleUnexpectedInflightException(
  10430. AssertionInfo const& info,
  10431. std::string const& message,
  10432. AssertionReaction& reaction
  10433. ) {
  10434. m_lastAssertionInfo = info;
  10435. AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
  10436. data.message = message;
  10437. AssertionResult assertionResult{ info, data };
  10438. assertionEnded( assertionResult );
  10439. populateReaction( reaction );
  10440. }
  10441. void RunContext::populateReaction( AssertionReaction& reaction ) {
  10442. reaction.shouldDebugBreak = m_config->shouldDebugBreak();
  10443. reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);
  10444. }
  10445. void RunContext::handleIncomplete(
  10446. AssertionInfo const& info
  10447. ) {
  10448. m_lastAssertionInfo = info;
  10449. AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
  10450. data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
  10451. AssertionResult assertionResult{ info, data };
  10452. assertionEnded( assertionResult );
  10453. }
  10454. void RunContext::handleNonExpr(
  10455. AssertionInfo const &info,
  10456. ResultWas::OfType resultType,
  10457. AssertionReaction &reaction
  10458. ) {
  10459. m_lastAssertionInfo = info;
  10460. AssertionResultData data( resultType, LazyExpression( false ) );
  10461. AssertionResult assertionResult{ info, data };
  10462. assertionEnded( assertionResult );
  10463. if( !assertionResult.isOk() )
  10464. populateReaction( reaction );
  10465. }
  10466. IResultCapture& getResultCapture() {
  10467. if (auto* capture = getCurrentContext().getResultCapture())
  10468. return *capture;
  10469. else
  10470. CATCH_INTERNAL_ERROR("No result capture instance");
  10471. }
  10472. void seedRng(IConfig const& config) {
  10473. if (config.rngSeed() != 0) {
  10474. std::srand(config.rngSeed());
  10475. rng().seed(config.rngSeed());
  10476. }
  10477. }
  10478. unsigned int rngSeed() {
  10479. return getCurrentContext().getConfig()->rngSeed();
  10480. }
  10481. }
  10482. // end catch_run_context.cpp
  10483. // start catch_section.cpp
  10484. namespace Catch {
  10485. Section::Section( SectionInfo const& info )
  10486. : m_info( info ),
  10487. m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
  10488. {
  10489. m_timer.start();
  10490. }
  10491. Section::~Section() {
  10492. if( m_sectionIncluded ) {
  10493. SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };
  10494. if( uncaught_exceptions() )
  10495. getResultCapture().sectionEndedEarly( endInfo );
  10496. else
  10497. getResultCapture().sectionEnded( endInfo );
  10498. }
  10499. }
  10500. // This indicates whether the section should be executed or not
  10501. Section::operator bool() const {
  10502. return m_sectionIncluded;
  10503. }
  10504. } // end namespace Catch
  10505. // end catch_section.cpp
  10506. // start catch_section_info.cpp
  10507. namespace Catch {
  10508. SectionInfo::SectionInfo
  10509. ( SourceLineInfo const& _lineInfo,
  10510. std::string const& _name )
  10511. : name( _name ),
  10512. lineInfo( _lineInfo )
  10513. {}
  10514. } // end namespace Catch
  10515. // end catch_section_info.cpp
  10516. // start catch_session.cpp
  10517. // start catch_session.h
  10518. #include <memory>
  10519. namespace Catch {
  10520. class Session : NonCopyable {
  10521. public:
  10522. Session();
  10523. ~Session() override;
  10524. void showHelp() const;
  10525. void libIdentify();
  10526. int applyCommandLine( int argc, char const * const * argv );
  10527. #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
  10528. int applyCommandLine( int argc, wchar_t const * const * argv );
  10529. #endif
  10530. void useConfigData( ConfigData const& configData );
  10531. template<typename CharT>
  10532. int run(int argc, CharT const * const argv[]) {
  10533. if (m_startupExceptions)
  10534. return 1;
  10535. int returnCode = applyCommandLine(argc, argv);
  10536. if (returnCode == 0)
  10537. returnCode = run();
  10538. return returnCode;
  10539. }
  10540. int run();
  10541. clara::Parser const& cli() const;
  10542. void cli( clara::Parser const& newParser );
  10543. ConfigData& configData();
  10544. Config& config();
  10545. private:
  10546. int runInternal();
  10547. clara::Parser m_cli;
  10548. ConfigData m_configData;
  10549. std::shared_ptr<Config> m_config;
  10550. bool m_startupExceptions = false;
  10551. };
  10552. } // end namespace Catch
  10553. // end catch_session.h
  10554. // start catch_version.h
  10555. #include <iosfwd>
  10556. namespace Catch {
  10557. // Versioning information
  10558. struct Version {
  10559. Version( Version const& ) = delete;
  10560. Version& operator=( Version const& ) = delete;
  10561. Version( unsigned int _majorVersion,
  10562. unsigned int _minorVersion,
  10563. unsigned int _patchNumber,
  10564. char const * const _branchName,
  10565. unsigned int _buildNumber );
  10566. unsigned int const majorVersion;
  10567. unsigned int const minorVersion;
  10568. unsigned int const patchNumber;
  10569. // buildNumber is only used if branchName is not null
  10570. char const * const branchName;
  10571. unsigned int const buildNumber;
  10572. friend std::ostream& operator << ( std::ostream& os, Version const& version );
  10573. };
  10574. Version const& libraryVersion();
  10575. }
  10576. // end catch_version.h
  10577. #include <cstdlib>
  10578. #include <iomanip>
  10579. #include <set>
  10580. #include <iterator>
  10581. namespace Catch {
  10582. namespace {
  10583. const int MaxExitCode = 255;
  10584. IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) {
  10585. auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);
  10586. CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'");
  10587. return reporter;
  10588. }
  10589. IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) {
  10590. if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) {
  10591. return createReporter(config->getReporterName(), config);
  10592. }
  10593. // On older platforms, returning std::unique_ptr<ListeningReporter>
  10594. // when the return type is std::unique_ptr<IStreamingReporter>
  10595. // doesn't compile without a std::move call. However, this causes
  10596. // a warning on newer platforms. Thus, we have to work around
  10597. // it a bit and downcast the pointer manually.
  10598. auto ret = std::unique_ptr<IStreamingReporter>(new ListeningReporter);
  10599. auto& multi = static_cast<ListeningReporter&>(*ret);
  10600. auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
  10601. for (auto const& listener : listeners) {
  10602. multi.addListener(listener->create(Catch::ReporterConfig(config)));
  10603. }
  10604. multi.addReporter(createReporter(config->getReporterName(), config));
  10605. return ret;
  10606. }
  10607. class TestGroup {
  10608. public:
  10609. explicit TestGroup(std::shared_ptr<Config> const& config)
  10610. : m_config{config}
  10611. , m_context{config, makeReporter(config)}
  10612. {
  10613. auto const& allTestCases = getAllTestCasesSorted(*m_config);
  10614. m_matches = m_config->testSpec().matchesByFilter(allTestCases, *m_config);
  10615. auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
  10616. if (m_matches.empty() && invalidArgs.empty()) {
  10617. for (auto const& test : allTestCases)
  10618. if (!test.isHidden())
  10619. m_tests.emplace(&test);
  10620. } else {
  10621. for (auto const& match : m_matches)
  10622. m_tests.insert(match.tests.begin(), match.tests.end());
  10623. }
  10624. }
  10625. Totals execute() {
  10626. auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
  10627. Totals totals;
  10628. m_context.testGroupStarting(m_config->name(), 1, 1);
  10629. for (auto const& testCase : m_tests) {
  10630. if (!m_context.aborting())
  10631. totals += m_context.runTest(*testCase);
  10632. else
  10633. m_context.reporter().skipTest(*testCase);
  10634. }
  10635. for (auto const& match : m_matches) {
  10636. if (match.tests.empty()) {
  10637. m_context.reporter().noMatchingTestCases(match.name);
  10638. totals.error = -1;
  10639. }
  10640. }
  10641. if (!invalidArgs.empty()) {
  10642. for (auto const& invalidArg: invalidArgs)
  10643. m_context.reporter().reportInvalidArguments(invalidArg);
  10644. }
  10645. m_context.testGroupEnded(m_config->name(), totals, 1, 1);
  10646. return totals;
  10647. }
  10648. private:
  10649. using Tests = std::set<TestCase const*>;
  10650. std::shared_ptr<Config> m_config;
  10651. RunContext m_context;
  10652. Tests m_tests;
  10653. TestSpec::Matches m_matches;
  10654. };
  10655. void applyFilenamesAsTags(Catch::IConfig const& config) {
  10656. auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));
  10657. for (auto& testCase : tests) {
  10658. auto tags = testCase.tags;
  10659. std::string filename = testCase.lineInfo.file;
  10660. auto lastSlash = filename.find_last_of("\\/");
  10661. if (lastSlash != std::string::npos) {
  10662. filename.erase(0, lastSlash);
  10663. filename[0] = '#';
  10664. }
  10665. auto lastDot = filename.find_last_of('.');
  10666. if (lastDot != std::string::npos) {
  10667. filename.erase(lastDot);
  10668. }
  10669. tags.push_back(std::move(filename));
  10670. setTags(testCase, tags);
  10671. }
  10672. }
  10673. } // anon namespace
  10674. Session::Session() {
  10675. static bool alreadyInstantiated = false;
  10676. if( alreadyInstantiated ) {
  10677. CATCH_TRY { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
  10678. CATCH_CATCH_ALL { getMutableRegistryHub().registerStartupException(); }
  10679. }
  10680. // There cannot be exceptions at startup in no-exception mode.
  10681. #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  10682. const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
  10683. if ( !exceptions.empty() ) {
  10684. config();
  10685. getCurrentMutableContext().setConfig(m_config);
  10686. m_startupExceptions = true;
  10687. Colour colourGuard( Colour::Red );
  10688. Catch::cerr() << "Errors occurred during startup!" << '\n';
  10689. // iterate over all exceptions and notify user
  10690. for ( const auto& ex_ptr : exceptions ) {
  10691. try {
  10692. std::rethrow_exception(ex_ptr);
  10693. } catch ( std::exception const& ex ) {
  10694. Catch::cerr() << Column( ex.what() ).indent(2) << '\n';
  10695. }
  10696. }
  10697. }
  10698. #endif
  10699. alreadyInstantiated = true;
  10700. m_cli = makeCommandLineParser( m_configData );
  10701. }
  10702. Session::~Session() {
  10703. Catch::cleanUp();
  10704. }
  10705. void Session::showHelp() const {
  10706. Catch::cout()
  10707. << "\nCatch v" << libraryVersion() << "\n"
  10708. << m_cli << std::endl
  10709. << "For more detailed usage please see the project docs\n" << std::endl;
  10710. }
  10711. void Session::libIdentify() {
  10712. Catch::cout()
  10713. << std::left << std::setw(16) << "description: " << "A Catch2 test executable\n"
  10714. << std::left << std::setw(16) << "category: " << "testframework\n"
  10715. << std::left << std::setw(16) << "framework: " << "Catch Test\n"
  10716. << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
  10717. }
  10718. int Session::applyCommandLine( int argc, char const * const * argv ) {
  10719. if( m_startupExceptions )
  10720. return 1;
  10721. auto result = m_cli.parse( clara::Args( argc, argv ) );
  10722. if( !result ) {
  10723. config();
  10724. getCurrentMutableContext().setConfig(m_config);
  10725. Catch::cerr()
  10726. << Colour( Colour::Red )
  10727. << "\nError(s) in input:\n"
  10728. << Column( result.errorMessage() ).indent( 2 )
  10729. << "\n\n";
  10730. Catch::cerr() << "Run with -? for usage\n" << std::endl;
  10731. return MaxExitCode;
  10732. }
  10733. if( m_configData.showHelp )
  10734. showHelp();
  10735. if( m_configData.libIdentify )
  10736. libIdentify();
  10737. m_config.reset();
  10738. return 0;
  10739. }
  10740. #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
  10741. int Session::applyCommandLine( int argc, wchar_t const * const * argv ) {
  10742. char **utf8Argv = new char *[ argc ];
  10743. for ( int i = 0; i < argc; ++i ) {
  10744. int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL );
  10745. utf8Argv[ i ] = new char[ bufSize ];
  10746. WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
  10747. }
  10748. int returnCode = applyCommandLine( argc, utf8Argv );
  10749. for ( int i = 0; i < argc; ++i )
  10750. delete [] utf8Argv[ i ];
  10751. delete [] utf8Argv;
  10752. return returnCode;
  10753. }
  10754. #endif
  10755. void Session::useConfigData( ConfigData const& configData ) {
  10756. m_configData = configData;
  10757. m_config.reset();
  10758. }
  10759. int Session::run() {
  10760. if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
  10761. Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
  10762. static_cast<void>(std::getchar());
  10763. }
  10764. int exitCode = runInternal();
  10765. if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {
  10766. Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
  10767. static_cast<void>(std::getchar());
  10768. }
  10769. return exitCode;
  10770. }
  10771. clara::Parser const& Session::cli() const {
  10772. return m_cli;
  10773. }
  10774. void Session::cli( clara::Parser const& newParser ) {
  10775. m_cli = newParser;
  10776. }
  10777. ConfigData& Session::configData() {
  10778. return m_configData;
  10779. }
  10780. Config& Session::config() {
  10781. if( !m_config )
  10782. m_config = std::make_shared<Config>( m_configData );
  10783. return *m_config;
  10784. }
  10785. int Session::runInternal() {
  10786. if( m_startupExceptions )
  10787. return 1;
  10788. if (m_configData.showHelp || m_configData.libIdentify) {
  10789. return 0;
  10790. }
  10791. CATCH_TRY {
  10792. config(); // Force config to be constructed
  10793. seedRng( *m_config );
  10794. if( m_configData.filenamesAsTags )
  10795. applyFilenamesAsTags( *m_config );
  10796. // Handle list request
  10797. if( Option<std::size_t> listed = list( m_config ) )
  10798. return static_cast<int>( *listed );
  10799. TestGroup tests { m_config };
  10800. auto const totals = tests.execute();
  10801. if( m_config->warnAboutNoTests() && totals.error == -1 )
  10802. return 2;
  10803. // Note that on unices only the lower 8 bits are usually used, clamping
  10804. // the return value to 255 prevents false negative when some multiple
  10805. // of 256 tests has failed
  10806. return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));
  10807. }
  10808. #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  10809. catch( std::exception& ex ) {
  10810. Catch::cerr() << ex.what() << std::endl;
  10811. return MaxExitCode;
  10812. }
  10813. #endif
  10814. }
  10815. } // end namespace Catch
  10816. // end catch_session.cpp
  10817. // start catch_singletons.cpp
  10818. #include <vector>
  10819. namespace Catch {
  10820. namespace {
  10821. static auto getSingletons() -> std::vector<ISingleton*>*& {
  10822. static std::vector<ISingleton*>* g_singletons = nullptr;
  10823. if( !g_singletons )
  10824. g_singletons = new std::vector<ISingleton*>();
  10825. return g_singletons;
  10826. }
  10827. }
  10828. ISingleton::~ISingleton() {}
  10829. void addSingleton(ISingleton* singleton ) {
  10830. getSingletons()->push_back( singleton );
  10831. }
  10832. void cleanupSingletons() {
  10833. auto& singletons = getSingletons();
  10834. for( auto singleton : *singletons )
  10835. delete singleton;
  10836. delete singletons;
  10837. singletons = nullptr;
  10838. }
  10839. } // namespace Catch
  10840. // end catch_singletons.cpp
  10841. // start catch_startup_exception_registry.cpp
  10842. namespace Catch {
  10843. void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
  10844. CATCH_TRY {
  10845. m_exceptions.push_back(exception);
  10846. } CATCH_CATCH_ALL {
  10847. // If we run out of memory during start-up there's really not a lot more we can do about it
  10848. std::terminate();
  10849. }
  10850. }
  10851. std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept {
  10852. return m_exceptions;
  10853. }
  10854. } // end namespace Catch
  10855. // end catch_startup_exception_registry.cpp
  10856. // start catch_stream.cpp
  10857. #include <cstdio>
  10858. #include <iostream>
  10859. #include <fstream>
  10860. #include <sstream>
  10861. #include <vector>
  10862. #include <memory>
  10863. namespace Catch {
  10864. Catch::IStream::~IStream() = default;
  10865. namespace Detail { namespace {
  10866. template<typename WriterF, std::size_t bufferSize=256>
  10867. class StreamBufImpl : public std::streambuf {
  10868. char data[bufferSize];
  10869. WriterF m_writer;
  10870. public:
  10871. StreamBufImpl() {
  10872. setp( data, data + sizeof(data) );
  10873. }
  10874. ~StreamBufImpl() noexcept {
  10875. StreamBufImpl::sync();
  10876. }
  10877. private:
  10878. int overflow( int c ) override {
  10879. sync();
  10880. if( c != EOF ) {
  10881. if( pbase() == epptr() )
  10882. m_writer( std::string( 1, static_cast<char>( c ) ) );
  10883. else
  10884. sputc( static_cast<char>( c ) );
  10885. }
  10886. return 0;
  10887. }
  10888. int sync() override {
  10889. if( pbase() != pptr() ) {
  10890. m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
  10891. setp( pbase(), epptr() );
  10892. }
  10893. return 0;
  10894. }
  10895. };
  10896. ///////////////////////////////////////////////////////////////////////////
  10897. struct OutputDebugWriter {
  10898. void operator()( std::string const&str ) {
  10899. writeToDebugConsole( str );
  10900. }
  10901. };
  10902. ///////////////////////////////////////////////////////////////////////////
  10903. class FileStream : public IStream {
  10904. mutable std::ofstream m_ofs;
  10905. public:
  10906. FileStream( StringRef filename ) {
  10907. m_ofs.open( filename.c_str() );
  10908. CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" );
  10909. }
  10910. ~FileStream() override = default;
  10911. public: // IStream
  10912. std::ostream& stream() const override {
  10913. return m_ofs;
  10914. }
  10915. };
  10916. ///////////////////////////////////////////////////////////////////////////
  10917. class CoutStream : public IStream {
  10918. mutable std::ostream m_os;
  10919. public:
  10920. // Store the streambuf from cout up-front because
  10921. // cout may get redirected when running tests
  10922. CoutStream() : m_os( Catch::cout().rdbuf() ) {}
  10923. ~CoutStream() override = default;
  10924. public: // IStream
  10925. std::ostream& stream() const override { return m_os; }
  10926. };
  10927. ///////////////////////////////////////////////////////////////////////////
  10928. class DebugOutStream : public IStream {
  10929. std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;
  10930. mutable std::ostream m_os;
  10931. public:
  10932. DebugOutStream()
  10933. : m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
  10934. m_os( m_streamBuf.get() )
  10935. {}
  10936. ~DebugOutStream() override = default;
  10937. public: // IStream
  10938. std::ostream& stream() const override { return m_os; }
  10939. };
  10940. }} // namespace anon::detail
  10941. ///////////////////////////////////////////////////////////////////////////
  10942. auto makeStream( StringRef const &filename ) -> IStream const* {
  10943. if( filename.empty() )
  10944. return new Detail::CoutStream();
  10945. else if( filename[0] == '%' ) {
  10946. if( filename == "%debug" )
  10947. return new Detail::DebugOutStream();
  10948. else
  10949. CATCH_ERROR( "Unrecognised stream: '" << filename << "'" );
  10950. }
  10951. else
  10952. return new Detail::FileStream( filename );
  10953. }
  10954. // This class encapsulates the idea of a pool of ostringstreams that can be reused.
  10955. struct StringStreams {
  10956. std::vector<std::unique_ptr<std::ostringstream>> m_streams;
  10957. std::vector<std::size_t> m_unused;
  10958. std::ostringstream m_referenceStream; // Used for copy state/ flags from
  10959. auto add() -> std::size_t {
  10960. if( m_unused.empty() ) {
  10961. m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) );
  10962. return m_streams.size()-1;
  10963. }
  10964. else {
  10965. auto index = m_unused.back();
  10966. m_unused.pop_back();
  10967. return index;
  10968. }
  10969. }
  10970. void release( std::size_t index ) {
  10971. m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
  10972. m_unused.push_back(index);
  10973. }
  10974. };
  10975. ReusableStringStream::ReusableStringStream()
  10976. : m_index( Singleton<StringStreams>::getMutable().add() ),
  10977. m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() )
  10978. {}
  10979. ReusableStringStream::~ReusableStringStream() {
  10980. static_cast<std::ostringstream*>( m_oss )->str("");
  10981. m_oss->clear();
  10982. Singleton<StringStreams>::getMutable().release( m_index );
  10983. }
  10984. auto ReusableStringStream::str() const -> std::string {
  10985. return static_cast<std::ostringstream*>( m_oss )->str();
  10986. }
  10987. ///////////////////////////////////////////////////////////////////////////
  10988. #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
  10989. std::ostream& cout() { return std::cout; }
  10990. std::ostream& cerr() { return std::cerr; }
  10991. std::ostream& clog() { return std::clog; }
  10992. #endif
  10993. }
  10994. // end catch_stream.cpp
  10995. // start catch_string_manip.cpp
  10996. #include <algorithm>
  10997. #include <ostream>
  10998. #include <cstring>
  10999. #include <cctype>
  11000. #include <vector>
  11001. namespace Catch {
  11002. namespace {
  11003. char toLowerCh(char c) {
  11004. return static_cast<char>( std::tolower( c ) );
  11005. }
  11006. }
  11007. bool startsWith( std::string const& s, std::string const& prefix ) {
  11008. return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
  11009. }
  11010. bool startsWith( std::string const& s, char prefix ) {
  11011. return !s.empty() && s[0] == prefix;
  11012. }
  11013. bool endsWith( std::string const& s, std::string const& suffix ) {
  11014. return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
  11015. }
  11016. bool endsWith( std::string const& s, char suffix ) {
  11017. return !s.empty() && s[s.size()-1] == suffix;
  11018. }
  11019. bool contains( std::string const& s, std::string const& infix ) {
  11020. return s.find( infix ) != std::string::npos;
  11021. }
  11022. void toLowerInPlace( std::string& s ) {
  11023. std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
  11024. }
  11025. std::string toLower( std::string const& s ) {
  11026. std::string lc = s;
  11027. toLowerInPlace( lc );
  11028. return lc;
  11029. }
  11030. std::string trim( std::string const& str ) {
  11031. static char const* whitespaceChars = "\n\r\t ";
  11032. std::string::size_type start = str.find_first_not_of( whitespaceChars );
  11033. std::string::size_type end = str.find_last_not_of( whitespaceChars );
  11034. return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
  11035. }
  11036. StringRef trim(StringRef ref) {
  11037. const auto is_ws = [](char c) {
  11038. return c == ' ' || c == '\t' || c == '\n' || c == '\r';
  11039. };
  11040. size_t real_begin = 0;
  11041. while (real_begin < ref.size() && is_ws(ref[real_begin])) { ++real_begin; }
  11042. size_t real_end = ref.size();
  11043. while (real_end > real_begin && is_ws(ref[real_end - 1])) { --real_end; }
  11044. return ref.substr(real_begin, real_end - real_begin);
  11045. }
  11046. bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
  11047. bool replaced = false;
  11048. std::size_t i = str.find( replaceThis );
  11049. while( i != std::string::npos ) {
  11050. replaced = true;
  11051. str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
  11052. if( i < str.size()-withThis.size() )
  11053. i = str.find( replaceThis, i+withThis.size() );
  11054. else
  11055. i = std::string::npos;
  11056. }
  11057. return replaced;
  11058. }
  11059. std::vector<StringRef> splitStringRef( StringRef str, char delimiter ) {
  11060. std::vector<StringRef> subStrings;
  11061. std::size_t start = 0;
  11062. for(std::size_t pos = 0; pos < str.size(); ++pos ) {
  11063. if( str[pos] == delimiter ) {
  11064. if( pos - start > 1 )
  11065. subStrings.push_back( str.substr( start, pos-start ) );
  11066. start = pos+1;
  11067. }
  11068. }
  11069. if( start < str.size() )
  11070. subStrings.push_back( str.substr( start, str.size()-start ) );
  11071. return subStrings;
  11072. }
  11073. pluralise::pluralise( std::size_t count, std::string const& label )
  11074. : m_count( count ),
  11075. m_label( label )
  11076. {}
  11077. std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
  11078. os << pluraliser.m_count << ' ' << pluraliser.m_label;
  11079. if( pluraliser.m_count != 1 )
  11080. os << 's';
  11081. return os;
  11082. }
  11083. }
  11084. // end catch_string_manip.cpp
  11085. // start catch_stringref.cpp
  11086. #if defined(__clang__)
  11087. # pragma clang diagnostic push
  11088. # pragma clang diagnostic ignored "-Wexit-time-destructors"
  11089. #endif
  11090. #include <ostream>
  11091. #include <cstring>
  11092. #include <cstdint>
  11093. namespace Catch {
  11094. StringRef::StringRef( char const* rawChars ) noexcept
  11095. : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )
  11096. {}
  11097. void StringRef::swap( StringRef& other ) noexcept {
  11098. std::swap( m_start, other.m_start );
  11099. std::swap( m_size, other.m_size );
  11100. std::swap( m_data, other.m_data );
  11101. }
  11102. auto StringRef::c_str() const -> char const* {
  11103. if( !isSubstring() )
  11104. return m_start;
  11105. const_cast<StringRef *>( this )->takeOwnership();
  11106. return m_data;
  11107. }
  11108. auto StringRef::currentData() const noexcept -> char const* {
  11109. return m_start;
  11110. }
  11111. auto StringRef::isOwned() const noexcept -> bool {
  11112. return m_data != nullptr;
  11113. }
  11114. auto StringRef::isSubstring() const noexcept -> bool {
  11115. return m_start[m_size] != '\0';
  11116. }
  11117. void StringRef::takeOwnership() {
  11118. if( !isOwned() ) {
  11119. m_data = new char[m_size+1];
  11120. memcpy( m_data, m_start, m_size );
  11121. m_data[m_size] = '\0';
  11122. }
  11123. }
  11124. auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
  11125. if( start < m_size )
  11126. return StringRef( m_start+start, size );
  11127. else
  11128. return StringRef();
  11129. }
  11130. auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {
  11131. return
  11132. size() == other.size() &&
  11133. (std::strncmp( m_start, other.m_start, size() ) == 0);
  11134. }
  11135. auto StringRef::operator != ( StringRef const& other ) const noexcept -> bool {
  11136. return !operator==( other );
  11137. }
  11138. auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {
  11139. return os.write(str.currentData(), str.size());
  11140. }
  11141. auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& {
  11142. lhs.append(rhs.currentData(), rhs.size());
  11143. return lhs;
  11144. }
  11145. } // namespace Catch
  11146. #if defined(__clang__)
  11147. # pragma clang diagnostic pop
  11148. #endif
  11149. // end catch_stringref.cpp
  11150. // start catch_tag_alias.cpp
  11151. namespace Catch {
  11152. TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {}
  11153. }
  11154. // end catch_tag_alias.cpp
  11155. // start catch_tag_alias_autoregistrar.cpp
  11156. namespace Catch {
  11157. RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
  11158. CATCH_TRY {
  11159. getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
  11160. } CATCH_CATCH_ALL {
  11161. // Do not throw when constructing global objects, instead register the exception to be processed later
  11162. getMutableRegistryHub().registerStartupException();
  11163. }
  11164. }
  11165. }
  11166. // end catch_tag_alias_autoregistrar.cpp
  11167. // start catch_tag_alias_registry.cpp
  11168. #include <sstream>
  11169. namespace Catch {
  11170. TagAliasRegistry::~TagAliasRegistry() {}
  11171. TagAlias const* TagAliasRegistry::find( std::string const& alias ) const {
  11172. auto it = m_registry.find( alias );
  11173. if( it != m_registry.end() )
  11174. return &(it->second);
  11175. else
  11176. return nullptr;
  11177. }
  11178. std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
  11179. std::string expandedTestSpec = unexpandedTestSpec;
  11180. for( auto const& registryKvp : m_registry ) {
  11181. std::size_t pos = expandedTestSpec.find( registryKvp.first );
  11182. if( pos != std::string::npos ) {
  11183. expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
  11184. registryKvp.second.tag +
  11185. expandedTestSpec.substr( pos + registryKvp.first.size() );
  11186. }
  11187. }
  11188. return expandedTestSpec;
  11189. }
  11190. void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {
  11191. CATCH_ENFORCE( startsWith(alias, "[@") && endsWith(alias, ']'),
  11192. "error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo );
  11193. CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
  11194. "error: tag alias, '" << alias << "' already registered.\n"
  11195. << "\tFirst seen at: " << find(alias)->lineInfo << "\n"
  11196. << "\tRedefined at: " << lineInfo );
  11197. }
  11198. ITagAliasRegistry::~ITagAliasRegistry() {}
  11199. ITagAliasRegistry const& ITagAliasRegistry::get() {
  11200. return getRegistryHub().getTagAliasRegistry();
  11201. }
  11202. } // end namespace Catch
  11203. // end catch_tag_alias_registry.cpp
  11204. // start catch_test_case_info.cpp
  11205. #include <cctype>
  11206. #include <exception>
  11207. #include <algorithm>
  11208. #include <sstream>
  11209. namespace Catch {
  11210. namespace {
  11211. TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
  11212. if( startsWith( tag, '.' ) ||
  11213. tag == "!hide" )
  11214. return TestCaseInfo::IsHidden;
  11215. else if( tag == "!throws" )
  11216. return TestCaseInfo::Throws;
  11217. else if( tag == "!shouldfail" )
  11218. return TestCaseInfo::ShouldFail;
  11219. else if( tag == "!mayfail" )
  11220. return TestCaseInfo::MayFail;
  11221. else if( tag == "!nonportable" )
  11222. return TestCaseInfo::NonPortable;
  11223. else if( tag == "!benchmark" )
  11224. return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );
  11225. else
  11226. return TestCaseInfo::None;
  11227. }
  11228. bool isReservedTag( std::string const& tag ) {
  11229. return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );
  11230. }
  11231. void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
  11232. CATCH_ENFORCE( !isReservedTag(tag),
  11233. "Tag name: [" << tag << "] is not allowed.\n"
  11234. << "Tag names starting with non alphanumeric characters are reserved\n"
  11235. << _lineInfo );
  11236. }
  11237. }
  11238. TestCase makeTestCase( ITestInvoker* _testCase,
  11239. std::string const& _className,
  11240. NameAndTags const& nameAndTags,
  11241. SourceLineInfo const& _lineInfo )
  11242. {
  11243. bool isHidden = false;
  11244. // Parse out tags
  11245. std::vector<std::string> tags;
  11246. std::string desc, tag;
  11247. bool inTag = false;
  11248. for (char c : nameAndTags.tags) {
  11249. if( !inTag ) {
  11250. if( c == '[' )
  11251. inTag = true;
  11252. else
  11253. desc += c;
  11254. }
  11255. else {
  11256. if( c == ']' ) {
  11257. TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
  11258. if( ( prop & TestCaseInfo::IsHidden ) != 0 )
  11259. isHidden = true;
  11260. else if( prop == TestCaseInfo::None )
  11261. enforceNotReservedTag( tag, _lineInfo );
  11262. // Merged hide tags like `[.approvals]` should be added as
  11263. // `[.][approvals]`. The `[.]` is added at later point, so
  11264. // we only strip the prefix
  11265. if (startsWith(tag, '.') && tag.size() > 1) {
  11266. tag.erase(0, 1);
  11267. }
  11268. tags.push_back( tag );
  11269. tag.clear();
  11270. inTag = false;
  11271. }
  11272. else
  11273. tag += c;
  11274. }
  11275. }
  11276. if( isHidden ) {
  11277. tags.push_back( "." );
  11278. }
  11279. TestCaseInfo info( static_cast<std::string>(nameAndTags.name), _className, desc, tags, _lineInfo );
  11280. return TestCase( _testCase, std::move(info) );
  11281. }
  11282. void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ) {
  11283. std::sort(begin(tags), end(tags));
  11284. tags.erase(std::unique(begin(tags), end(tags)), end(tags));
  11285. testCaseInfo.lcaseTags.clear();
  11286. for( auto const& tag : tags ) {
  11287. std::string lcaseTag = toLower( tag );
  11288. testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
  11289. testCaseInfo.lcaseTags.push_back( lcaseTag );
  11290. }
  11291. testCaseInfo.tags = std::move(tags);
  11292. }
  11293. TestCaseInfo::TestCaseInfo( std::string const& _name,
  11294. std::string const& _className,
  11295. std::string const& _description,
  11296. std::vector<std::string> const& _tags,
  11297. SourceLineInfo const& _lineInfo )
  11298. : name( _name ),
  11299. className( _className ),
  11300. description( _description ),
  11301. lineInfo( _lineInfo ),
  11302. properties( None )
  11303. {
  11304. setTags( *this, _tags );
  11305. }
  11306. bool TestCaseInfo::isHidden() const {
  11307. return ( properties & IsHidden ) != 0;
  11308. }
  11309. bool TestCaseInfo::throws() const {
  11310. return ( properties & Throws ) != 0;
  11311. }
  11312. bool TestCaseInfo::okToFail() const {
  11313. return ( properties & (ShouldFail | MayFail ) ) != 0;
  11314. }
  11315. bool TestCaseInfo::expectedToFail() const {
  11316. return ( properties & (ShouldFail ) ) != 0;
  11317. }
  11318. std::string TestCaseInfo::tagsAsString() const {
  11319. std::string ret;
  11320. // '[' and ']' per tag
  11321. std::size_t full_size = 2 * tags.size();
  11322. for (const auto& tag : tags) {
  11323. full_size += tag.size();
  11324. }
  11325. ret.reserve(full_size);
  11326. for (const auto& tag : tags) {
  11327. ret.push_back('[');
  11328. ret.append(tag);
  11329. ret.push_back(']');
  11330. }
  11331. return ret;
  11332. }
  11333. TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {}
  11334. TestCase TestCase::withName( std::string const& _newName ) const {
  11335. TestCase other( *this );
  11336. other.name = _newName;
  11337. return other;
  11338. }
  11339. void TestCase::invoke() const {
  11340. test->invoke();
  11341. }
  11342. bool TestCase::operator == ( TestCase const& other ) const {
  11343. return test.get() == other.test.get() &&
  11344. name == other.name &&
  11345. className == other.className;
  11346. }
  11347. bool TestCase::operator < ( TestCase const& other ) const {
  11348. return name < other.name;
  11349. }
  11350. TestCaseInfo const& TestCase::getTestCaseInfo() const
  11351. {
  11352. return *this;
  11353. }
  11354. } // end namespace Catch
  11355. // end catch_test_case_info.cpp
  11356. // start catch_test_case_registry_impl.cpp
  11357. #include <sstream>
  11358. namespace Catch {
  11359. std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
  11360. std::vector<TestCase> sorted = unsortedTestCases;
  11361. switch( config.runOrder() ) {
  11362. case RunTests::InLexicographicalOrder:
  11363. std::sort( sorted.begin(), sorted.end() );
  11364. break;
  11365. case RunTests::InRandomOrder:
  11366. seedRng( config );
  11367. std::shuffle( sorted.begin(), sorted.end(), rng() );
  11368. break;
  11369. case RunTests::InDeclarationOrder:
  11370. // already in declaration order
  11371. break;
  11372. }
  11373. return sorted;
  11374. }
  11375. bool isThrowSafe( TestCase const& testCase, IConfig const& config ) {
  11376. return !testCase.throws() || config.allowThrows();
  11377. }
  11378. bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
  11379. return testSpec.matches( testCase ) && isThrowSafe( testCase, config );
  11380. }
  11381. void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
  11382. std::set<TestCase> seenFunctions;
  11383. for( auto const& function : functions ) {
  11384. auto prev = seenFunctions.insert( function );
  11385. CATCH_ENFORCE( prev.second,
  11386. "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n"
  11387. << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
  11388. << "\tRedefined at " << function.getTestCaseInfo().lineInfo );
  11389. }
  11390. }
  11391. std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
  11392. std::vector<TestCase> filtered;
  11393. filtered.reserve( testCases.size() );
  11394. for (auto const& testCase : testCases) {
  11395. if ((!testSpec.hasFilters() && !testCase.isHidden()) ||
  11396. (testSpec.hasFilters() && matchTest(testCase, testSpec, config))) {
  11397. filtered.push_back(testCase);
  11398. }
  11399. }
  11400. return filtered;
  11401. }
  11402. std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
  11403. return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
  11404. }
  11405. void TestRegistry::registerTest( TestCase const& testCase ) {
  11406. std::string name = testCase.getTestCaseInfo().name;
  11407. if( name.empty() ) {
  11408. ReusableStringStream rss;
  11409. rss << "Anonymous test case " << ++m_unnamedCount;
  11410. return registerTest( testCase.withName( rss.str() ) );
  11411. }
  11412. m_functions.push_back( testCase );
  11413. }
  11414. std::vector<TestCase> const& TestRegistry::getAllTests() const {
  11415. return m_functions;
  11416. }
  11417. std::vector<TestCase> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const {
  11418. if( m_sortedFunctions.empty() )
  11419. enforceNoDuplicateTestCases( m_functions );
  11420. if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
  11421. m_sortedFunctions = sortTests( config, m_functions );
  11422. m_currentSortOrder = config.runOrder();
  11423. }
  11424. return m_sortedFunctions;
  11425. }
  11426. ///////////////////////////////////////////////////////////////////////////
  11427. TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {}
  11428. void TestInvokerAsFunction::invoke() const {
  11429. m_testAsFunction();
  11430. }
  11431. std::string extractClassName( StringRef const& classOrQualifiedMethodName ) {
  11432. std::string className(classOrQualifiedMethodName);
  11433. if( startsWith( className, '&' ) )
  11434. {
  11435. std::size_t lastColons = className.rfind( "::" );
  11436. std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
  11437. if( penultimateColons == std::string::npos )
  11438. penultimateColons = 1;
  11439. className = className.substr( penultimateColons, lastColons-penultimateColons );
  11440. }
  11441. return className;
  11442. }
  11443. } // end namespace Catch
  11444. // end catch_test_case_registry_impl.cpp
  11445. // start catch_test_case_tracker.cpp
  11446. #include <algorithm>
  11447. #include <cassert>
  11448. #include <stdexcept>
  11449. #include <memory>
  11450. #include <sstream>
  11451. #if defined(__clang__)
  11452. # pragma clang diagnostic push
  11453. # pragma clang diagnostic ignored "-Wexit-time-destructors"
  11454. #endif
  11455. namespace Catch {
  11456. namespace TestCaseTracking {
  11457. NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
  11458. : name( _name ),
  11459. location( _location )
  11460. {}
  11461. ITracker::~ITracker() = default;
  11462. ITracker& TrackerContext::startRun() {
  11463. m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr );
  11464. m_currentTracker = nullptr;
  11465. m_runState = Executing;
  11466. return *m_rootTracker;
  11467. }
  11468. void TrackerContext::endRun() {
  11469. m_rootTracker.reset();
  11470. m_currentTracker = nullptr;
  11471. m_runState = NotStarted;
  11472. }
  11473. void TrackerContext::startCycle() {
  11474. m_currentTracker = m_rootTracker.get();
  11475. m_runState = Executing;
  11476. }
  11477. void TrackerContext::completeCycle() {
  11478. m_runState = CompletedCycle;
  11479. }
  11480. bool TrackerContext::completedCycle() const {
  11481. return m_runState == CompletedCycle;
  11482. }
  11483. ITracker& TrackerContext::currentTracker() {
  11484. return *m_currentTracker;
  11485. }
  11486. void TrackerContext::setCurrentTracker( ITracker* tracker ) {
  11487. m_currentTracker = tracker;
  11488. }
  11489. TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
  11490. : m_nameAndLocation( nameAndLocation ),
  11491. m_ctx( ctx ),
  11492. m_parent( parent )
  11493. {}
  11494. NameAndLocation const& TrackerBase::nameAndLocation() const {
  11495. return m_nameAndLocation;
  11496. }
  11497. bool TrackerBase::isComplete() const {
  11498. return m_runState == CompletedSuccessfully || m_runState == Failed;
  11499. }
  11500. bool TrackerBase::isSuccessfullyCompleted() const {
  11501. return m_runState == CompletedSuccessfully;
  11502. }
  11503. bool TrackerBase::isOpen() const {
  11504. return m_runState != NotStarted && !isComplete();
  11505. }
  11506. bool TrackerBase::hasChildren() const {
  11507. return !m_children.empty();
  11508. }
  11509. void TrackerBase::addChild( ITrackerPtr const& child ) {
  11510. m_children.push_back( child );
  11511. }
  11512. ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {
  11513. auto it = std::find_if( m_children.begin(), m_children.end(),
  11514. [&nameAndLocation]( ITrackerPtr const& tracker ){
  11515. return
  11516. tracker->nameAndLocation().location == nameAndLocation.location &&
  11517. tracker->nameAndLocation().name == nameAndLocation.name;
  11518. } );
  11519. return( it != m_children.end() )
  11520. ? *it
  11521. : nullptr;
  11522. }
  11523. ITracker& TrackerBase::parent() {
  11524. assert( m_parent ); // Should always be non-null except for root
  11525. return *m_parent;
  11526. }
  11527. void TrackerBase::openChild() {
  11528. if( m_runState != ExecutingChildren ) {
  11529. m_runState = ExecutingChildren;
  11530. if( m_parent )
  11531. m_parent->openChild();
  11532. }
  11533. }
  11534. bool TrackerBase::isSectionTracker() const { return false; }
  11535. bool TrackerBase::isGeneratorTracker() const { return false; }
  11536. void TrackerBase::open() {
  11537. m_runState = Executing;
  11538. moveToThis();
  11539. if( m_parent )
  11540. m_parent->openChild();
  11541. }
  11542. void TrackerBase::close() {
  11543. // Close any still open children (e.g. generators)
  11544. while( &m_ctx.currentTracker() != this )
  11545. m_ctx.currentTracker().close();
  11546. switch( m_runState ) {
  11547. case NeedsAnotherRun:
  11548. break;
  11549. case Executing:
  11550. m_runState = CompletedSuccessfully;
  11551. break;
  11552. case ExecutingChildren:
  11553. if( std::all_of(m_children.begin(), m_children.end(), [](ITrackerPtr const& t){ return t->isComplete(); }) )
  11554. m_runState = CompletedSuccessfully;
  11555. break;
  11556. case NotStarted:
  11557. case CompletedSuccessfully:
  11558. case Failed:
  11559. CATCH_INTERNAL_ERROR( "Illogical state: " << m_runState );
  11560. default:
  11561. CATCH_INTERNAL_ERROR( "Unknown state: " << m_runState );
  11562. }
  11563. moveToParent();
  11564. m_ctx.completeCycle();
  11565. }
  11566. void TrackerBase::fail() {
  11567. m_runState = Failed;
  11568. if( m_parent )
  11569. m_parent->markAsNeedingAnotherRun();
  11570. moveToParent();
  11571. m_ctx.completeCycle();
  11572. }
  11573. void TrackerBase::markAsNeedingAnotherRun() {
  11574. m_runState = NeedsAnotherRun;
  11575. }
  11576. void TrackerBase::moveToParent() {
  11577. assert( m_parent );
  11578. m_ctx.setCurrentTracker( m_parent );
  11579. }
  11580. void TrackerBase::moveToThis() {
  11581. m_ctx.setCurrentTracker( this );
  11582. }
  11583. SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
  11584. : TrackerBase( nameAndLocation, ctx, parent ),
  11585. m_trimmed_name(trim(nameAndLocation.name))
  11586. {
  11587. if( parent ) {
  11588. while( !parent->isSectionTracker() )
  11589. parent = &parent->parent();
  11590. SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
  11591. addNextFilters( parentSection.m_filters );
  11592. }
  11593. }
  11594. bool SectionTracker::isComplete() const {
  11595. bool complete = true;
  11596. if ((m_filters.empty() || m_filters[0] == "")
  11597. || std::find(m_filters.begin(), m_filters.end(), m_trimmed_name) != m_filters.end()) {
  11598. complete = TrackerBase::isComplete();
  11599. }
  11600. return complete;
  11601. }
  11602. bool SectionTracker::isSectionTracker() const { return true; }
  11603. SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
  11604. std::shared_ptr<SectionTracker> section;
  11605. ITracker& currentTracker = ctx.currentTracker();
  11606. if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
  11607. assert( childTracker );
  11608. assert( childTracker->isSectionTracker() );
  11609. section = std::static_pointer_cast<SectionTracker>( childTracker );
  11610. }
  11611. else {
  11612. section = std::make_shared<SectionTracker>( nameAndLocation, ctx, &currentTracker );
  11613. currentTracker.addChild( section );
  11614. }
  11615. if( !ctx.completedCycle() )
  11616. section->tryOpen();
  11617. return *section;
  11618. }
  11619. void SectionTracker::tryOpen() {
  11620. if( !isComplete() )
  11621. open();
  11622. }
  11623. void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {
  11624. if( !filters.empty() ) {
  11625. m_filters.reserve( m_filters.size() + filters.size() + 2 );
  11626. m_filters.push_back(""); // Root - should never be consulted
  11627. m_filters.push_back(""); // Test Case - not a section filter
  11628. m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
  11629. }
  11630. }
  11631. void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) {
  11632. if( filters.size() > 1 )
  11633. m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() );
  11634. }
  11635. } // namespace TestCaseTracking
  11636. using TestCaseTracking::ITracker;
  11637. using TestCaseTracking::TrackerContext;
  11638. using TestCaseTracking::SectionTracker;
  11639. } // namespace Catch
  11640. #if defined(__clang__)
  11641. # pragma clang diagnostic pop
  11642. #endif
  11643. // end catch_test_case_tracker.cpp
  11644. // start catch_test_registry.cpp
  11645. namespace Catch {
  11646. auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* {
  11647. return new(std::nothrow) TestInvokerAsFunction( testAsFunction );
  11648. }
  11649. NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {}
  11650. AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {
  11651. CATCH_TRY {
  11652. getMutableRegistryHub()
  11653. .registerTest(
  11654. makeTestCase(
  11655. invoker,
  11656. extractClassName( classOrMethod ),
  11657. nameAndTags,
  11658. lineInfo));
  11659. } CATCH_CATCH_ALL {
  11660. // Do not throw when constructing global objects, instead register the exception to be processed later
  11661. getMutableRegistryHub().registerStartupException();
  11662. }
  11663. }
  11664. AutoReg::~AutoReg() = default;
  11665. }
  11666. // end catch_test_registry.cpp
  11667. // start catch_test_spec.cpp
  11668. #include <algorithm>
  11669. #include <string>
  11670. #include <vector>
  11671. #include <memory>
  11672. namespace Catch {
  11673. TestSpec::Pattern::Pattern( std::string const& name )
  11674. : m_name( name )
  11675. {}
  11676. TestSpec::Pattern::~Pattern() = default;
  11677. std::string const& TestSpec::Pattern::name() const {
  11678. return m_name;
  11679. }
  11680. TestSpec::NamePattern::NamePattern( std::string const& name, std::string const& filterString )
  11681. : Pattern( filterString )
  11682. , m_wildcardPattern( toLower( name ), CaseSensitive::No )
  11683. {}
  11684. bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const {
  11685. return m_wildcardPattern.matches( testCase.name );
  11686. }
  11687. TestSpec::TagPattern::TagPattern( std::string const& tag, std::string const& filterString )
  11688. : Pattern( filterString )
  11689. , m_tag( toLower( tag ) )
  11690. {}
  11691. bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const {
  11692. return std::find(begin(testCase.lcaseTags),
  11693. end(testCase.lcaseTags),
  11694. m_tag) != end(testCase.lcaseTags);
  11695. }
  11696. TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern )
  11697. : Pattern( underlyingPattern->name() )
  11698. , m_underlyingPattern( underlyingPattern )
  11699. {}
  11700. bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const {
  11701. return !m_underlyingPattern->matches( testCase );
  11702. }
  11703. bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {
  11704. return std::all_of( m_patterns.begin(), m_patterns.end(), [&]( PatternPtr const& p ){ return p->matches( testCase ); } );
  11705. }
  11706. std::string TestSpec::Filter::name() const {
  11707. std::string name;
  11708. for( auto const& p : m_patterns )
  11709. name += p->name();
  11710. return name;
  11711. }
  11712. bool TestSpec::hasFilters() const {
  11713. return !m_filters.empty();
  11714. }
  11715. bool TestSpec::matches( TestCaseInfo const& testCase ) const {
  11716. return std::any_of( m_filters.begin(), m_filters.end(), [&]( Filter const& f ){ return f.matches( testCase ); } );
  11717. }
  11718. TestSpec::Matches TestSpec::matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const
  11719. {
  11720. Matches matches( m_filters.size() );
  11721. std::transform( m_filters.begin(), m_filters.end(), matches.begin(), [&]( Filter const& filter ){
  11722. std::vector<TestCase const*> currentMatches;
  11723. for( auto const& test : testCases )
  11724. if( isThrowSafe( test, config ) && filter.matches( test ) )
  11725. currentMatches.emplace_back( &test );
  11726. return FilterMatch{ filter.name(), currentMatches };
  11727. } );
  11728. return matches;
  11729. }
  11730. const TestSpec::vectorStrings& TestSpec::getInvalidArgs() const{
  11731. return (m_invalidArgs);
  11732. }
  11733. }
  11734. // end catch_test_spec.cpp
  11735. // start catch_test_spec_parser.cpp
  11736. namespace Catch {
  11737. TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
  11738. TestSpecParser& TestSpecParser::parse( std::string const& arg ) {
  11739. m_mode = None;
  11740. m_exclusion = false;
  11741. m_arg = m_tagAliases->expandAliases( arg );
  11742. m_escapeChars.clear();
  11743. m_substring.reserve(m_arg.size());
  11744. m_patternName.reserve(m_arg.size());
  11745. m_realPatternPos = 0;
  11746. for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
  11747. //if visitChar fails
  11748. if( !visitChar( m_arg[m_pos] ) ){
  11749. m_testSpec.m_invalidArgs.push_back(arg);
  11750. break;
  11751. }
  11752. endMode();
  11753. return *this;
  11754. }
  11755. TestSpec TestSpecParser::testSpec() {
  11756. addFilter();
  11757. return m_testSpec;
  11758. }
  11759. bool TestSpecParser::visitChar( char c ) {
  11760. if( (m_mode != EscapedName) && (c == '\\') ) {
  11761. escape();
  11762. addCharToPattern(c);
  11763. return true;
  11764. }else if((m_mode != EscapedName) && (c == ',') ) {
  11765. return separate();
  11766. }
  11767. switch( m_mode ) {
  11768. case None:
  11769. if( processNoneChar( c ) )
  11770. return true;
  11771. break;
  11772. case Name:
  11773. processNameChar( c );
  11774. break;
  11775. case EscapedName:
  11776. endMode();
  11777. addCharToPattern(c);
  11778. return true;
  11779. default:
  11780. case Tag:
  11781. case QuotedName:
  11782. if( processOtherChar( c ) )
  11783. return true;
  11784. break;
  11785. }
  11786. m_substring += c;
  11787. if( !isControlChar( c ) ) {
  11788. m_patternName += c;
  11789. m_realPatternPos++;
  11790. }
  11791. return true;
  11792. }
  11793. // Two of the processing methods return true to signal the caller to return
  11794. // without adding the given character to the current pattern strings
  11795. bool TestSpecParser::processNoneChar( char c ) {
  11796. switch( c ) {
  11797. case ' ':
  11798. return true;
  11799. case '~':
  11800. m_exclusion = true;
  11801. return false;
  11802. case '[':
  11803. startNewMode( Tag );
  11804. return false;
  11805. case '"':
  11806. startNewMode( QuotedName );
  11807. return false;
  11808. default:
  11809. startNewMode( Name );
  11810. return false;
  11811. }
  11812. }
  11813. void TestSpecParser::processNameChar( char c ) {
  11814. if( c == '[' ) {
  11815. if( m_substring == "exclude:" )
  11816. m_exclusion = true;
  11817. else
  11818. endMode();
  11819. startNewMode( Tag );
  11820. }
  11821. }
  11822. bool TestSpecParser::processOtherChar( char c ) {
  11823. if( !isControlChar( c ) )
  11824. return false;
  11825. m_substring += c;
  11826. endMode();
  11827. return true;
  11828. }
  11829. void TestSpecParser::startNewMode( Mode mode ) {
  11830. m_mode = mode;
  11831. }
  11832. void TestSpecParser::endMode() {
  11833. switch( m_mode ) {
  11834. case Name:
  11835. case QuotedName:
  11836. return addPattern<TestSpec::NamePattern>();
  11837. case Tag:
  11838. return addPattern<TestSpec::TagPattern>();
  11839. case EscapedName:
  11840. revertBackToLastMode();
  11841. return;
  11842. case None:
  11843. default:
  11844. return startNewMode( None );
  11845. }
  11846. }
  11847. void TestSpecParser::escape() {
  11848. saveLastMode();
  11849. m_mode = EscapedName;
  11850. m_escapeChars.push_back(m_realPatternPos);
  11851. }
  11852. bool TestSpecParser::isControlChar( char c ) const {
  11853. switch( m_mode ) {
  11854. default:
  11855. return false;
  11856. case None:
  11857. return c == '~';
  11858. case Name:
  11859. return c == '[';
  11860. case EscapedName:
  11861. return true;
  11862. case QuotedName:
  11863. return c == '"';
  11864. case Tag:
  11865. return c == '[' || c == ']';
  11866. }
  11867. }
  11868. void TestSpecParser::addFilter() {
  11869. if( !m_currentFilter.m_patterns.empty() ) {
  11870. m_testSpec.m_filters.push_back( m_currentFilter );
  11871. m_currentFilter = TestSpec::Filter();
  11872. }
  11873. }
  11874. void TestSpecParser::saveLastMode() {
  11875. lastMode = m_mode;
  11876. }
  11877. void TestSpecParser::revertBackToLastMode() {
  11878. m_mode = lastMode;
  11879. }
  11880. bool TestSpecParser::separate() {
  11881. if( (m_mode==QuotedName) || (m_mode==Tag) ){
  11882. //invalid argument, signal failure to previous scope.
  11883. m_mode = None;
  11884. m_pos = m_arg.size();
  11885. m_substring.clear();
  11886. m_patternName.clear();
  11887. return false;
  11888. }
  11889. endMode();
  11890. addFilter();
  11891. return true; //success
  11892. }
  11893. TestSpec parseTestSpec( std::string const& arg ) {
  11894. return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
  11895. }
  11896. } // namespace Catch
  11897. // end catch_test_spec_parser.cpp
  11898. // start catch_timer.cpp
  11899. #include <chrono>
  11900. static const uint64_t nanosecondsInSecond = 1000000000;
  11901. namespace Catch {
  11902. auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
  11903. return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
  11904. }
  11905. namespace {
  11906. auto estimateClockResolution() -> uint64_t {
  11907. uint64_t sum = 0;
  11908. static const uint64_t iterations = 1000000;
  11909. auto startTime = getCurrentNanosecondsSinceEpoch();
  11910. for( std::size_t i = 0; i < iterations; ++i ) {
  11911. uint64_t ticks;
  11912. uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
  11913. do {
  11914. ticks = getCurrentNanosecondsSinceEpoch();
  11915. } while( ticks == baseTicks );
  11916. auto delta = ticks - baseTicks;
  11917. sum += delta;
  11918. // If we have been calibrating for over 3 seconds -- the clock
  11919. // is terrible and we should move on.
  11920. // TBD: How to signal that the measured resolution is probably wrong?
  11921. if (ticks > startTime + 3 * nanosecondsInSecond) {
  11922. return sum / ( i + 1u );
  11923. }
  11924. }
  11925. // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
  11926. // - and potentially do more iterations if there's a high variance.
  11927. return sum/iterations;
  11928. }
  11929. }
  11930. auto getEstimatedClockResolution() -> uint64_t {
  11931. static auto s_resolution = estimateClockResolution();
  11932. return s_resolution;
  11933. }
  11934. void Timer::start() {
  11935. m_nanoseconds = getCurrentNanosecondsSinceEpoch();
  11936. }
  11937. auto Timer::getElapsedNanoseconds() const -> uint64_t {
  11938. return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;
  11939. }
  11940. auto Timer::getElapsedMicroseconds() const -> uint64_t {
  11941. return getElapsedNanoseconds()/1000;
  11942. }
  11943. auto Timer::getElapsedMilliseconds() const -> unsigned int {
  11944. return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
  11945. }
  11946. auto Timer::getElapsedSeconds() const -> double {
  11947. return getElapsedMicroseconds()/1000000.0;
  11948. }
  11949. } // namespace Catch
  11950. // end catch_timer.cpp
  11951. // start catch_tostring.cpp
  11952. #if defined(__clang__)
  11953. # pragma clang diagnostic push
  11954. # pragma clang diagnostic ignored "-Wexit-time-destructors"
  11955. # pragma clang diagnostic ignored "-Wglobal-constructors"
  11956. #endif
  11957. // Enable specific decls locally
  11958. #if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
  11959. #define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
  11960. #endif
  11961. #include <cmath>
  11962. #include <iomanip>
  11963. namespace Catch {
  11964. namespace Detail {
  11965. const std::string unprintableString = "{?}";
  11966. namespace {
  11967. const int hexThreshold = 255;
  11968. struct Endianness {
  11969. enum Arch { Big, Little };
  11970. static Arch which() {
  11971. union _{
  11972. int asInt;
  11973. char asChar[sizeof (int)];
  11974. } u;
  11975. u.asInt = 1;
  11976. return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
  11977. }
  11978. };
  11979. }
  11980. std::string rawMemoryToString( const void *object, std::size_t size ) {
  11981. // Reverse order for little endian architectures
  11982. int i = 0, end = static_cast<int>( size ), inc = 1;
  11983. if( Endianness::which() == Endianness::Little ) {
  11984. i = end-1;
  11985. end = inc = -1;
  11986. }
  11987. unsigned char const *bytes = static_cast<unsigned char const *>(object);
  11988. ReusableStringStream rss;
  11989. rss << "0x" << std::setfill('0') << std::hex;
  11990. for( ; i != end; i += inc )
  11991. rss << std::setw(2) << static_cast<unsigned>(bytes[i]);
  11992. return rss.str();
  11993. }
  11994. }
  11995. template<typename T>
  11996. std::string fpToString( T value, int precision ) {
  11997. if (Catch::isnan(value)) {
  11998. return "nan";
  11999. }
  12000. ReusableStringStream rss;
  12001. rss << std::setprecision( precision )
  12002. << std::fixed
  12003. << value;
  12004. std::string d = rss.str();
  12005. std::size_t i = d.find_last_not_of( '0' );
  12006. if( i != std::string::npos && i != d.size()-1 ) {
  12007. if( d[i] == '.' )
  12008. i++;
  12009. d = d.substr( 0, i+1 );
  12010. }
  12011. return d;
  12012. }
  12013. //// ======================================================= ////
  12014. //
  12015. // Out-of-line defs for full specialization of StringMaker
  12016. //
  12017. //// ======================================================= ////
  12018. std::string StringMaker<std::string>::convert(const std::string& str) {
  12019. if (!getCurrentContext().getConfig()->showInvisibles()) {
  12020. return '"' + str + '"';
  12021. }
  12022. std::string s("\"");
  12023. for (char c : str) {
  12024. switch (c) {
  12025. case '\n':
  12026. s.append("\\n");
  12027. break;
  12028. case '\t':
  12029. s.append("\\t");
  12030. break;
  12031. default:
  12032. s.push_back(c);
  12033. break;
  12034. }
  12035. }
  12036. s.append("\"");
  12037. return s;
  12038. }
  12039. #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
  12040. std::string StringMaker<std::string_view>::convert(std::string_view str) {
  12041. return ::Catch::Detail::stringify(std::string{ str });
  12042. }
  12043. #endif
  12044. std::string StringMaker<char const*>::convert(char const* str) {
  12045. if (str) {
  12046. return ::Catch::Detail::stringify(std::string{ str });
  12047. } else {
  12048. return{ "{null string}" };
  12049. }
  12050. }
  12051. std::string StringMaker<char*>::convert(char* str) {
  12052. if (str) {
  12053. return ::Catch::Detail::stringify(std::string{ str });
  12054. } else {
  12055. return{ "{null string}" };
  12056. }
  12057. }
  12058. #ifdef CATCH_CONFIG_WCHAR
  12059. std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
  12060. std::string s;
  12061. s.reserve(wstr.size());
  12062. for (auto c : wstr) {
  12063. s += (c <= 0xff) ? static_cast<char>(c) : '?';
  12064. }
  12065. return ::Catch::Detail::stringify(s);
  12066. }
  12067. # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
  12068. std::string StringMaker<std::wstring_view>::convert(std::wstring_view str) {
  12069. return StringMaker<std::wstring>::convert(std::wstring(str));
  12070. }
  12071. # endif
  12072. std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {
  12073. if (str) {
  12074. return ::Catch::Detail::stringify(std::wstring{ str });
  12075. } else {
  12076. return{ "{null string}" };
  12077. }
  12078. }
  12079. std::string StringMaker<wchar_t *>::convert(wchar_t * str) {
  12080. if (str) {
  12081. return ::Catch::Detail::stringify(std::wstring{ str });
  12082. } else {
  12083. return{ "{null string}" };
  12084. }
  12085. }
  12086. #endif
  12087. #if defined(CATCH_CONFIG_CPP17_BYTE)
  12088. #include <cstddef>
  12089. std::string StringMaker<std::byte>::convert(std::byte value) {
  12090. return ::Catch::Detail::stringify(std::to_integer<unsigned long long>(value));
  12091. }
  12092. #endif // defined(CATCH_CONFIG_CPP17_BYTE)
  12093. std::string StringMaker<int>::convert(int value) {
  12094. return ::Catch::Detail::stringify(static_cast<long long>(value));
  12095. }
  12096. std::string StringMaker<long>::convert(long value) {
  12097. return ::Catch::Detail::stringify(static_cast<long long>(value));
  12098. }
  12099. std::string StringMaker<long long>::convert(long long value) {
  12100. ReusableStringStream rss;
  12101. rss << value;
  12102. if (value > Detail::hexThreshold) {
  12103. rss << " (0x" << std::hex << value << ')';
  12104. }
  12105. return rss.str();
  12106. }
  12107. std::string StringMaker<unsigned int>::convert(unsigned int value) {
  12108. return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
  12109. }
  12110. std::string StringMaker<unsigned long>::convert(unsigned long value) {
  12111. return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
  12112. }
  12113. std::string StringMaker<unsigned long long>::convert(unsigned long long value) {
  12114. ReusableStringStream rss;
  12115. rss << value;
  12116. if (value > Detail::hexThreshold) {
  12117. rss << " (0x" << std::hex << value << ')';
  12118. }
  12119. return rss.str();
  12120. }
  12121. std::string StringMaker<bool>::convert(bool b) {
  12122. return b ? "true" : "false";
  12123. }
  12124. std::string StringMaker<signed char>::convert(signed char value) {
  12125. if (value == '\r') {
  12126. return "'\\r'";
  12127. } else if (value == '\f') {
  12128. return "'\\f'";
  12129. } else if (value == '\n') {
  12130. return "'\\n'";
  12131. } else if (value == '\t') {
  12132. return "'\\t'";
  12133. } else if ('\0' <= value && value < ' ') {
  12134. return ::Catch::Detail::stringify(static_cast<unsigned int>(value));
  12135. } else {
  12136. char chstr[] = "' '";
  12137. chstr[1] = value;
  12138. return chstr;
  12139. }
  12140. }
  12141. std::string StringMaker<char>::convert(char c) {
  12142. return ::Catch::Detail::stringify(static_cast<signed char>(c));
  12143. }
  12144. std::string StringMaker<unsigned char>::convert(unsigned char c) {
  12145. return ::Catch::Detail::stringify(static_cast<char>(c));
  12146. }
  12147. std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {
  12148. return "nullptr";
  12149. }
  12150. int StringMaker<float>::precision = 5;
  12151. std::string StringMaker<float>::convert(float value) {
  12152. return fpToString(value, precision) + 'f';
  12153. }
  12154. int StringMaker<double>::precision = 10;
  12155. std::string StringMaker<double>::convert(double value) {
  12156. return fpToString(value, precision);
  12157. }
  12158. std::string ratio_string<std::atto>::symbol() { return "a"; }
  12159. std::string ratio_string<std::femto>::symbol() { return "f"; }
  12160. std::string ratio_string<std::pico>::symbol() { return "p"; }
  12161. std::string ratio_string<std::nano>::symbol() { return "n"; }
  12162. std::string ratio_string<std::micro>::symbol() { return "u"; }
  12163. std::string ratio_string<std::milli>::symbol() { return "m"; }
  12164. } // end namespace Catch
  12165. #if defined(__clang__)
  12166. # pragma clang diagnostic pop
  12167. #endif
  12168. // end catch_tostring.cpp
  12169. // start catch_totals.cpp
  12170. namespace Catch {
  12171. Counts Counts::operator - ( Counts const& other ) const {
  12172. Counts diff;
  12173. diff.passed = passed - other.passed;
  12174. diff.failed = failed - other.failed;
  12175. diff.failedButOk = failedButOk - other.failedButOk;
  12176. return diff;
  12177. }
  12178. Counts& Counts::operator += ( Counts const& other ) {
  12179. passed += other.passed;
  12180. failed += other.failed;
  12181. failedButOk += other.failedButOk;
  12182. return *this;
  12183. }
  12184. std::size_t Counts::total() const {
  12185. return passed + failed + failedButOk;
  12186. }
  12187. bool Counts::allPassed() const {
  12188. return failed == 0 && failedButOk == 0;
  12189. }
  12190. bool Counts::allOk() const {
  12191. return failed == 0;
  12192. }
  12193. Totals Totals::operator - ( Totals const& other ) const {
  12194. Totals diff;
  12195. diff.assertions = assertions - other.assertions;
  12196. diff.testCases = testCases - other.testCases;
  12197. return diff;
  12198. }
  12199. Totals& Totals::operator += ( Totals const& other ) {
  12200. assertions += other.assertions;
  12201. testCases += other.testCases;
  12202. return *this;
  12203. }
  12204. Totals Totals::delta( Totals const& prevTotals ) const {
  12205. Totals diff = *this - prevTotals;
  12206. if( diff.assertions.failed > 0 )
  12207. ++diff.testCases.failed;
  12208. else if( diff.assertions.failedButOk > 0 )
  12209. ++diff.testCases.failedButOk;
  12210. else
  12211. ++diff.testCases.passed;
  12212. return diff;
  12213. }
  12214. }
  12215. // end catch_totals.cpp
  12216. // start catch_uncaught_exceptions.cpp
  12217. #include <exception>
  12218. namespace Catch {
  12219. bool uncaught_exceptions() {
  12220. #if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
  12221. return std::uncaught_exceptions() > 0;
  12222. #else
  12223. return std::uncaught_exception();
  12224. #endif
  12225. }
  12226. } // end namespace Catch
  12227. // end catch_uncaught_exceptions.cpp
  12228. // start catch_version.cpp
  12229. #include <ostream>
  12230. namespace Catch {
  12231. Version::Version
  12232. ( unsigned int _majorVersion,
  12233. unsigned int _minorVersion,
  12234. unsigned int _patchNumber,
  12235. char const * const _branchName,
  12236. unsigned int _buildNumber )
  12237. : majorVersion( _majorVersion ),
  12238. minorVersion( _minorVersion ),
  12239. patchNumber( _patchNumber ),
  12240. branchName( _branchName ),
  12241. buildNumber( _buildNumber )
  12242. {}
  12243. std::ostream& operator << ( std::ostream& os, Version const& version ) {
  12244. os << version.majorVersion << '.'
  12245. << version.minorVersion << '.'
  12246. << version.patchNumber;
  12247. // branchName is never null -> 0th char is \0 if it is empty
  12248. if (version.branchName[0]) {
  12249. os << '-' << version.branchName
  12250. << '.' << version.buildNumber;
  12251. }
  12252. return os;
  12253. }
  12254. Version const& libraryVersion() {
  12255. static Version version( 2, 10, 2, "", 0 );
  12256. return version;
  12257. }
  12258. }
  12259. // end catch_version.cpp
  12260. // start catch_wildcard_pattern.cpp
  12261. namespace Catch {
  12262. WildcardPattern::WildcardPattern( std::string const& pattern,
  12263. CaseSensitive::Choice caseSensitivity )
  12264. : m_caseSensitivity( caseSensitivity ),
  12265. m_pattern( normaliseString( pattern ) )
  12266. {
  12267. if( startsWith( m_pattern, '*' ) ) {
  12268. m_pattern = m_pattern.substr( 1 );
  12269. m_wildcard = WildcardAtStart;
  12270. }
  12271. if( endsWith( m_pattern, '*' ) ) {
  12272. m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
  12273. m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
  12274. }
  12275. }
  12276. bool WildcardPattern::matches( std::string const& str ) const {
  12277. switch( m_wildcard ) {
  12278. case NoWildcard:
  12279. return m_pattern == normaliseString( str );
  12280. case WildcardAtStart:
  12281. return endsWith( normaliseString( str ), m_pattern );
  12282. case WildcardAtEnd:
  12283. return startsWith( normaliseString( str ), m_pattern );
  12284. case WildcardAtBothEnds:
  12285. return contains( normaliseString( str ), m_pattern );
  12286. default:
  12287. CATCH_INTERNAL_ERROR( "Unknown enum" );
  12288. }
  12289. }
  12290. std::string WildcardPattern::normaliseString( std::string const& str ) const {
  12291. return trim( m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str );
  12292. }
  12293. }
  12294. // end catch_wildcard_pattern.cpp
  12295. // start catch_xmlwriter.cpp
  12296. #include <iomanip>
  12297. using uchar = unsigned char;
  12298. namespace Catch {
  12299. namespace {
  12300. size_t trailingBytes(unsigned char c) {
  12301. if ((c & 0xE0) == 0xC0) {
  12302. return 2;
  12303. }
  12304. if ((c & 0xF0) == 0xE0) {
  12305. return 3;
  12306. }
  12307. if ((c & 0xF8) == 0xF0) {
  12308. return 4;
  12309. }
  12310. CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
  12311. }
  12312. uint32_t headerValue(unsigned char c) {
  12313. if ((c & 0xE0) == 0xC0) {
  12314. return c & 0x1F;
  12315. }
  12316. if ((c & 0xF0) == 0xE0) {
  12317. return c & 0x0F;
  12318. }
  12319. if ((c & 0xF8) == 0xF0) {
  12320. return c & 0x07;
  12321. }
  12322. CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
  12323. }
  12324. void hexEscapeChar(std::ostream& os, unsigned char c) {
  12325. std::ios_base::fmtflags f(os.flags());
  12326. os << "\\x"
  12327. << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
  12328. << static_cast<int>(c);
  12329. os.flags(f);
  12330. }
  12331. } // anonymous namespace
  12332. XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
  12333. : m_str( str ),
  12334. m_forWhat( forWhat )
  12335. {}
  12336. void XmlEncode::encodeTo( std::ostream& os ) const {
  12337. // Apostrophe escaping not necessary if we always use " to write attributes
  12338. // (see: http://www.w3.org/TR/xml/#syntax)
  12339. for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
  12340. uchar c = m_str[idx];
  12341. switch (c) {
  12342. case '<': os << "&lt;"; break;
  12343. case '&': os << "&amp;"; break;
  12344. case '>':
  12345. // See: http://www.w3.org/TR/xml/#syntax
  12346. if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
  12347. os << "&gt;";
  12348. else
  12349. os << c;
  12350. break;
  12351. case '\"':
  12352. if (m_forWhat == ForAttributes)
  12353. os << "&quot;";
  12354. else
  12355. os << c;
  12356. break;
  12357. default:
  12358. // Check for control characters and invalid utf-8
  12359. // Escape control characters in standard ascii
  12360. // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
  12361. if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
  12362. hexEscapeChar(os, c);
  12363. break;
  12364. }
  12365. // Plain ASCII: Write it to stream
  12366. if (c < 0x7F) {
  12367. os << c;
  12368. break;
  12369. }
  12370. // UTF-8 territory
  12371. // Check if the encoding is valid and if it is not, hex escape bytes.
  12372. // Important: We do not check the exact decoded values for validity, only the encoding format
  12373. // First check that this bytes is a valid lead byte:
  12374. // This means that it is not encoded as 1111 1XXX
  12375. // Or as 10XX XXXX
  12376. if (c < 0xC0 ||
  12377. c >= 0xF8) {
  12378. hexEscapeChar(os, c);
  12379. break;
  12380. }
  12381. auto encBytes = trailingBytes(c);
  12382. // Are there enough bytes left to avoid accessing out-of-bounds memory?
  12383. if (idx + encBytes - 1 >= m_str.size()) {
  12384. hexEscapeChar(os, c);
  12385. break;
  12386. }
  12387. // The header is valid, check data
  12388. // The next encBytes bytes must together be a valid utf-8
  12389. // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
  12390. bool valid = true;
  12391. uint32_t value = headerValue(c);
  12392. for (std::size_t n = 1; n < encBytes; ++n) {
  12393. uchar nc = m_str[idx + n];
  12394. valid &= ((nc & 0xC0) == 0x80);
  12395. value = (value << 6) | (nc & 0x3F);
  12396. }
  12397. if (
  12398. // Wrong bit pattern of following bytes
  12399. (!valid) ||
  12400. // Overlong encodings
  12401. (value < 0x80) ||
  12402. (0x80 <= value && value < 0x800 && encBytes > 2) ||
  12403. (0x800 < value && value < 0x10000 && encBytes > 3) ||
  12404. // Encoded value out of range
  12405. (value >= 0x110000)
  12406. ) {
  12407. hexEscapeChar(os, c);
  12408. break;
  12409. }
  12410. // If we got here, this is in fact a valid(ish) utf-8 sequence
  12411. for (std::size_t n = 0; n < encBytes; ++n) {
  12412. os << m_str[idx + n];
  12413. }
  12414. idx += encBytes - 1;
  12415. break;
  12416. }
  12417. }
  12418. }
  12419. std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
  12420. xmlEncode.encodeTo( os );
  12421. return os;
  12422. }
  12423. XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer )
  12424. : m_writer( writer )
  12425. {}
  12426. XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept
  12427. : m_writer( other.m_writer ){
  12428. other.m_writer = nullptr;
  12429. }
  12430. XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept {
  12431. if ( m_writer ) {
  12432. m_writer->endElement();
  12433. }
  12434. m_writer = other.m_writer;
  12435. other.m_writer = nullptr;
  12436. return *this;
  12437. }
  12438. XmlWriter::ScopedElement::~ScopedElement() {
  12439. if( m_writer )
  12440. m_writer->endElement();
  12441. }
  12442. XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, bool indent ) {
  12443. m_writer->writeText( text, indent );
  12444. return *this;
  12445. }
  12446. XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )
  12447. {
  12448. writeDeclaration();
  12449. }
  12450. XmlWriter::~XmlWriter() {
  12451. while( !m_tags.empty() )
  12452. endElement();
  12453. }
  12454. XmlWriter& XmlWriter::startElement( std::string const& name ) {
  12455. ensureTagClosed();
  12456. newlineIfNecessary();
  12457. m_os << m_indent << '<' << name;
  12458. m_tags.push_back( name );
  12459. m_indent += " ";
  12460. m_tagIsOpen = true;
  12461. return *this;
  12462. }
  12463. XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name ) {
  12464. ScopedElement scoped( this );
  12465. startElement( name );
  12466. return scoped;
  12467. }
  12468. XmlWriter& XmlWriter::endElement() {
  12469. newlineIfNecessary();
  12470. m_indent = m_indent.substr( 0, m_indent.size()-2 );
  12471. if( m_tagIsOpen ) {
  12472. m_os << "/>";
  12473. m_tagIsOpen = false;
  12474. }
  12475. else {
  12476. m_os << m_indent << "</" << m_tags.back() << ">";
  12477. }
  12478. m_os << std::endl;
  12479. m_tags.pop_back();
  12480. return *this;
  12481. }
  12482. XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {
  12483. if( !name.empty() && !attribute.empty() )
  12484. m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
  12485. return *this;
  12486. }
  12487. XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {
  12488. m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
  12489. return *this;
  12490. }
  12491. XmlWriter& XmlWriter::writeText( std::string const& text, bool indent ) {
  12492. if( !text.empty() ){
  12493. bool tagWasOpen = m_tagIsOpen;
  12494. ensureTagClosed();
  12495. if( tagWasOpen && indent )
  12496. m_os << m_indent;
  12497. m_os << XmlEncode( text );
  12498. m_needsNewline = true;
  12499. }
  12500. return *this;
  12501. }
  12502. XmlWriter& XmlWriter::writeComment( std::string const& text ) {
  12503. ensureTagClosed();
  12504. m_os << m_indent << "<!--" << text << "-->";
  12505. m_needsNewline = true;
  12506. return *this;
  12507. }
  12508. void XmlWriter::writeStylesheetRef( std::string const& url ) {
  12509. m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
  12510. }
  12511. XmlWriter& XmlWriter::writeBlankLine() {
  12512. ensureTagClosed();
  12513. m_os << '\n';
  12514. return *this;
  12515. }
  12516. void XmlWriter::ensureTagClosed() {
  12517. if( m_tagIsOpen ) {
  12518. m_os << ">" << std::endl;
  12519. m_tagIsOpen = false;
  12520. }
  12521. }
  12522. void XmlWriter::writeDeclaration() {
  12523. m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
  12524. }
  12525. void XmlWriter::newlineIfNecessary() {
  12526. if( m_needsNewline ) {
  12527. m_os << std::endl;
  12528. m_needsNewline = false;
  12529. }
  12530. }
  12531. }
  12532. // end catch_xmlwriter.cpp
  12533. // start catch_reporter_bases.cpp
  12534. #include <cstring>
  12535. #include <cfloat>
  12536. #include <cstdio>
  12537. #include <cassert>
  12538. #include <memory>
  12539. namespace Catch {
  12540. void prepareExpandedExpression(AssertionResult& result) {
  12541. result.getExpandedExpression();
  12542. }
  12543. // Because formatting using c++ streams is stateful, drop down to C is required
  12544. // Alternatively we could use stringstream, but its performance is... not good.
  12545. std::string getFormattedDuration( double duration ) {
  12546. // Max exponent + 1 is required to represent the whole part
  12547. // + 1 for decimal point
  12548. // + 3 for the 3 decimal places
  12549. // + 1 for null terminator
  12550. const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
  12551. char buffer[maxDoubleSize];
  12552. // Save previous errno, to prevent sprintf from overwriting it
  12553. ErrnoGuard guard;
  12554. #ifdef _MSC_VER
  12555. sprintf_s(buffer, "%.3f", duration);
  12556. #else
  12557. std::sprintf(buffer, "%.3f", duration);
  12558. #endif
  12559. return std::string(buffer);
  12560. }
  12561. std::string serializeFilters( std::vector<std::string> const& container ) {
  12562. ReusableStringStream oss;
  12563. bool first = true;
  12564. for (auto&& filter : container)
  12565. {
  12566. if (!first)
  12567. oss << ' ';
  12568. else
  12569. first = false;
  12570. oss << filter;
  12571. }
  12572. return oss.str();
  12573. }
  12574. TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)
  12575. :StreamingReporterBase(_config) {}
  12576. std::set<Verbosity> TestEventListenerBase::getSupportedVerbosities() {
  12577. return { Verbosity::Quiet, Verbosity::Normal, Verbosity::High };
  12578. }
  12579. void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}
  12580. bool TestEventListenerBase::assertionEnded(AssertionStats const &) {
  12581. return false;
  12582. }
  12583. } // end namespace Catch
  12584. // end catch_reporter_bases.cpp
  12585. // start catch_reporter_compact.cpp
  12586. namespace {
  12587. #ifdef CATCH_PLATFORM_MAC
  12588. const char* failedString() { return "FAILED"; }
  12589. const char* passedString() { return "PASSED"; }
  12590. #else
  12591. const char* failedString() { return "failed"; }
  12592. const char* passedString() { return "passed"; }
  12593. #endif
  12594. // Colour::LightGrey
  12595. Catch::Colour::Code dimColour() { return Catch::Colour::FileName; }
  12596. std::string bothOrAll( std::size_t count ) {
  12597. return count == 1 ? std::string() :
  12598. count == 2 ? "both " : "all " ;
  12599. }
  12600. } // anon namespace
  12601. namespace Catch {
  12602. namespace {
  12603. // Colour, message variants:
  12604. // - white: No tests ran.
  12605. // - red: Failed [both/all] N test cases, failed [both/all] M assertions.
  12606. // - white: Passed [both/all] N test cases (no assertions).
  12607. // - red: Failed N tests cases, failed M assertions.
  12608. // - green: Passed [both/all] N tests cases with M assertions.
  12609. void printTotals(std::ostream& out, const Totals& totals) {
  12610. if (totals.testCases.total() == 0) {
  12611. out << "No tests ran.";
  12612. } else if (totals.testCases.failed == totals.testCases.total()) {
  12613. Colour colour(Colour::ResultError);
  12614. const std::string qualify_assertions_failed =
  12615. totals.assertions.failed == totals.assertions.total() ?
  12616. bothOrAll(totals.assertions.failed) : std::string();
  12617. out <<
  12618. "Failed " << bothOrAll(totals.testCases.failed)
  12619. << pluralise(totals.testCases.failed, "test case") << ", "
  12620. "failed " << qualify_assertions_failed <<
  12621. pluralise(totals.assertions.failed, "assertion") << '.';
  12622. } else if (totals.assertions.total() == 0) {
  12623. out <<
  12624. "Passed " << bothOrAll(totals.testCases.total())
  12625. << pluralise(totals.testCases.total(), "test case")
  12626. << " (no assertions).";
  12627. } else if (totals.assertions.failed) {
  12628. Colour colour(Colour::ResultError);
  12629. out <<
  12630. "Failed " << pluralise(totals.testCases.failed, "test case") << ", "
  12631. "failed " << pluralise(totals.assertions.failed, "assertion") << '.';
  12632. } else {
  12633. Colour colour(Colour::ResultSuccess);
  12634. out <<
  12635. "Passed " << bothOrAll(totals.testCases.passed)
  12636. << pluralise(totals.testCases.passed, "test case") <<
  12637. " with " << pluralise(totals.assertions.passed, "assertion") << '.';
  12638. }
  12639. }
  12640. // Implementation of CompactReporter formatting
  12641. class AssertionPrinter {
  12642. public:
  12643. AssertionPrinter& operator= (AssertionPrinter const&) = delete;
  12644. AssertionPrinter(AssertionPrinter const&) = delete;
  12645. AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
  12646. : stream(_stream)
  12647. , result(_stats.assertionResult)
  12648. , messages(_stats.infoMessages)
  12649. , itMessage(_stats.infoMessages.begin())
  12650. , printInfoMessages(_printInfoMessages) {}
  12651. void print() {
  12652. printSourceInfo();
  12653. itMessage = messages.begin();
  12654. switch (result.getResultType()) {
  12655. case ResultWas::Ok:
  12656. printResultType(Colour::ResultSuccess, passedString());
  12657. printOriginalExpression();
  12658. printReconstructedExpression();
  12659. if (!result.hasExpression())
  12660. printRemainingMessages(Colour::None);
  12661. else
  12662. printRemainingMessages();
  12663. break;
  12664. case ResultWas::ExpressionFailed:
  12665. if (result.isOk())
  12666. printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok"));
  12667. else
  12668. printResultType(Colour::Error, failedString());
  12669. printOriginalExpression();
  12670. printReconstructedExpression();
  12671. printRemainingMessages();
  12672. break;
  12673. case ResultWas::ThrewException:
  12674. printResultType(Colour::Error, failedString());
  12675. printIssue("unexpected exception with message:");
  12676. printMessage();
  12677. printExpressionWas();
  12678. printRemainingMessages();
  12679. break;
  12680. case ResultWas::FatalErrorCondition:
  12681. printResultType(Colour::Error, failedString());
  12682. printIssue("fatal error condition with message:");
  12683. printMessage();
  12684. printExpressionWas();
  12685. printRemainingMessages();
  12686. break;
  12687. case ResultWas::DidntThrowException:
  12688. printResultType(Colour::Error, failedString());
  12689. printIssue("expected exception, got none");
  12690. printExpressionWas();
  12691. printRemainingMessages();
  12692. break;
  12693. case ResultWas::Info:
  12694. printResultType(Colour::None, "info");
  12695. printMessage();
  12696. printRemainingMessages();
  12697. break;
  12698. case ResultWas::Warning:
  12699. printResultType(Colour::None, "warning");
  12700. printMessage();
  12701. printRemainingMessages();
  12702. break;
  12703. case ResultWas::ExplicitFailure:
  12704. printResultType(Colour::Error, failedString());
  12705. printIssue("explicitly");
  12706. printRemainingMessages(Colour::None);
  12707. break;
  12708. // These cases are here to prevent compiler warnings
  12709. case ResultWas::Unknown:
  12710. case ResultWas::FailureBit:
  12711. case ResultWas::Exception:
  12712. printResultType(Colour::Error, "** internal error **");
  12713. break;
  12714. }
  12715. }
  12716. private:
  12717. void printSourceInfo() const {
  12718. Colour colourGuard(Colour::FileName);
  12719. stream << result.getSourceInfo() << ':';
  12720. }
  12721. void printResultType(Colour::Code colour, std::string const& passOrFail) const {
  12722. if (!passOrFail.empty()) {
  12723. {
  12724. Colour colourGuard(colour);
  12725. stream << ' ' << passOrFail;
  12726. }
  12727. stream << ':';
  12728. }
  12729. }
  12730. void printIssue(std::string const& issue) const {
  12731. stream << ' ' << issue;
  12732. }
  12733. void printExpressionWas() {
  12734. if (result.hasExpression()) {
  12735. stream << ';';
  12736. {
  12737. Colour colour(dimColour());
  12738. stream << " expression was:";
  12739. }
  12740. printOriginalExpression();
  12741. }
  12742. }
  12743. void printOriginalExpression() const {
  12744. if (result.hasExpression()) {
  12745. stream << ' ' << result.getExpression();
  12746. }
  12747. }
  12748. void printReconstructedExpression() const {
  12749. if (result.hasExpandedExpression()) {
  12750. {
  12751. Colour colour(dimColour());
  12752. stream << " for: ";
  12753. }
  12754. stream << result.getExpandedExpression();
  12755. }
  12756. }
  12757. void printMessage() {
  12758. if (itMessage != messages.end()) {
  12759. stream << " '" << itMessage->message << '\'';
  12760. ++itMessage;
  12761. }
  12762. }
  12763. void printRemainingMessages(Colour::Code colour = dimColour()) {
  12764. if (itMessage == messages.end())
  12765. return;
  12766. const auto itEnd = messages.cend();
  12767. const auto N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
  12768. {
  12769. Colour colourGuard(colour);
  12770. stream << " with " << pluralise(N, "message") << ':';
  12771. }
  12772. while (itMessage != itEnd) {
  12773. // If this assertion is a warning ignore any INFO messages
  12774. if (printInfoMessages || itMessage->type != ResultWas::Info) {
  12775. printMessage();
  12776. if (itMessage != itEnd) {
  12777. Colour colourGuard(dimColour());
  12778. stream << " and";
  12779. }
  12780. continue;
  12781. }
  12782. ++itMessage;
  12783. }
  12784. }
  12785. private:
  12786. std::ostream& stream;
  12787. AssertionResult const& result;
  12788. std::vector<MessageInfo> messages;
  12789. std::vector<MessageInfo>::const_iterator itMessage;
  12790. bool printInfoMessages;
  12791. };
  12792. } // anon namespace
  12793. std::string CompactReporter::getDescription() {
  12794. return "Reports test results on a single line, suitable for IDEs";
  12795. }
  12796. ReporterPreferences CompactReporter::getPreferences() const {
  12797. return m_reporterPrefs;
  12798. }
  12799. void CompactReporter::noMatchingTestCases( std::string const& spec ) {
  12800. stream << "No test cases matched '" << spec << '\'' << std::endl;
  12801. }
  12802. void CompactReporter::assertionStarting( AssertionInfo const& ) {}
  12803. bool CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) {
  12804. AssertionResult const& result = _assertionStats.assertionResult;
  12805. bool printInfoMessages = true;
  12806. // Drop out if result was successful and we're not printing those
  12807. if( !m_config->includeSuccessfulResults() && result.isOk() ) {
  12808. if( result.getResultType() != ResultWas::Warning )
  12809. return false;
  12810. printInfoMessages = false;
  12811. }
  12812. AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
  12813. printer.print();
  12814. stream << std::endl;
  12815. return true;
  12816. }
  12817. void CompactReporter::sectionEnded(SectionStats const& _sectionStats) {
  12818. if (m_config->showDurations() == ShowDurations::Always) {
  12819. stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
  12820. }
  12821. }
  12822. void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) {
  12823. printTotals( stream, _testRunStats.totals );
  12824. stream << '\n' << std::endl;
  12825. StreamingReporterBase::testRunEnded( _testRunStats );
  12826. }
  12827. CompactReporter::~CompactReporter() {}
  12828. CATCH_REGISTER_REPORTER( "compact", CompactReporter )
  12829. } // end namespace Catch
  12830. // end catch_reporter_compact.cpp
  12831. // start catch_reporter_console.cpp
  12832. #include <cfloat>
  12833. #include <cstdio>
  12834. #if defined(_MSC_VER)
  12835. #pragma warning(push)
  12836. #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
  12837. // Note that 4062 (not all labels are handled and default is missing) is enabled
  12838. #endif
  12839. #if defined(__clang__)
  12840. # pragma clang diagnostic push
  12841. // For simplicity, benchmarking-only helpers are always enabled
  12842. # pragma clang diagnostic ignored "-Wunused-function"
  12843. #endif
  12844. namespace Catch {
  12845. namespace {
  12846. // Formatter impl for ConsoleReporter
  12847. class ConsoleAssertionPrinter {
  12848. public:
  12849. ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete;
  12850. ConsoleAssertionPrinter(ConsoleAssertionPrinter const&) = delete;
  12851. ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
  12852. : stream(_stream),
  12853. stats(_stats),
  12854. result(_stats.assertionResult),
  12855. colour(Colour::None),
  12856. message(result.getMessage()),
  12857. messages(_stats.infoMessages),
  12858. printInfoMessages(_printInfoMessages) {
  12859. switch (result.getResultType()) {
  12860. case ResultWas::Ok:
  12861. colour = Colour::Success;
  12862. passOrFail = "PASSED";
  12863. //if( result.hasMessage() )
  12864. if (_stats.infoMessages.size() == 1)
  12865. messageLabel = "with message";
  12866. if (_stats.infoMessages.size() > 1)
  12867. messageLabel = "with messages";
  12868. break;
  12869. case ResultWas::ExpressionFailed:
  12870. if (result.isOk()) {
  12871. colour = Colour::Success;
  12872. passOrFail = "FAILED - but was ok";
  12873. } else {
  12874. colour = Colour::Error;
  12875. passOrFail = "FAILED";
  12876. }
  12877. if (_stats.infoMessages.size() == 1)
  12878. messageLabel = "with message";
  12879. if (_stats.infoMessages.size() > 1)
  12880. messageLabel = "with messages";
  12881. break;
  12882. case ResultWas::ThrewException:
  12883. colour = Colour::Error;
  12884. passOrFail = "FAILED";
  12885. messageLabel = "due to unexpected exception with ";
  12886. if (_stats.infoMessages.size() == 1)
  12887. messageLabel += "message";
  12888. if (_stats.infoMessages.size() > 1)
  12889. messageLabel += "messages";
  12890. break;
  12891. case ResultWas::FatalErrorCondition:
  12892. colour = Colour::Error;
  12893. passOrFail = "FAILED";
  12894. messageLabel = "due to a fatal error condition";
  12895. break;
  12896. case ResultWas::DidntThrowException:
  12897. colour = Colour::Error;
  12898. passOrFail = "FAILED";
  12899. messageLabel = "because no exception was thrown where one was expected";
  12900. break;
  12901. case ResultWas::Info:
  12902. messageLabel = "info";
  12903. break;
  12904. case ResultWas::Warning:
  12905. messageLabel = "warning";
  12906. break;
  12907. case ResultWas::ExplicitFailure:
  12908. passOrFail = "FAILED";
  12909. colour = Colour::Error;
  12910. if (_stats.infoMessages.size() == 1)
  12911. messageLabel = "explicitly with message";
  12912. if (_stats.infoMessages.size() > 1)
  12913. messageLabel = "explicitly with messages";
  12914. break;
  12915. // These cases are here to prevent compiler warnings
  12916. case ResultWas::Unknown:
  12917. case ResultWas::FailureBit:
  12918. case ResultWas::Exception:
  12919. passOrFail = "** internal error **";
  12920. colour = Colour::Error;
  12921. break;
  12922. }
  12923. }
  12924. void print() const {
  12925. printSourceInfo();
  12926. if (stats.totals.assertions.total() > 0) {
  12927. printResultType();
  12928. printOriginalExpression();
  12929. printReconstructedExpression();
  12930. } else {
  12931. stream << '\n';
  12932. }
  12933. printMessage();
  12934. }
  12935. private:
  12936. void printResultType() const {
  12937. if (!passOrFail.empty()) {
  12938. Colour colourGuard(colour);
  12939. stream << passOrFail << ":\n";
  12940. }
  12941. }
  12942. void printOriginalExpression() const {
  12943. if (result.hasExpression()) {
  12944. Colour colourGuard(Colour::OriginalExpression);
  12945. stream << " ";
  12946. stream << result.getExpressionInMacro();
  12947. stream << '\n';
  12948. }
  12949. }
  12950. void printReconstructedExpression() const {
  12951. if (result.hasExpandedExpression()) {
  12952. stream << "with expansion:\n";
  12953. Colour colourGuard(Colour::ReconstructedExpression);
  12954. stream << Column(result.getExpandedExpression()).indent(2) << '\n';
  12955. }
  12956. }
  12957. void printMessage() const {
  12958. if (!messageLabel.empty())
  12959. stream << messageLabel << ':' << '\n';
  12960. for (auto const& msg : messages) {
  12961. // If this assertion is a warning ignore any INFO messages
  12962. if (printInfoMessages || msg.type != ResultWas::Info)
  12963. stream << Column(msg.message).indent(2) << '\n';
  12964. }
  12965. }
  12966. void printSourceInfo() const {
  12967. Colour colourGuard(Colour::FileName);
  12968. stream << result.getSourceInfo() << ": ";
  12969. }
  12970. std::ostream& stream;
  12971. AssertionStats const& stats;
  12972. AssertionResult const& result;
  12973. Colour::Code colour;
  12974. std::string passOrFail;
  12975. std::string messageLabel;
  12976. std::string message;
  12977. std::vector<MessageInfo> messages;
  12978. bool printInfoMessages;
  12979. };
  12980. std::size_t makeRatio(std::size_t number, std::size_t total) {
  12981. std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;
  12982. return (ratio == 0 && number > 0) ? 1 : ratio;
  12983. }
  12984. std::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) {
  12985. if (i > j && i > k)
  12986. return i;
  12987. else if (j > k)
  12988. return j;
  12989. else
  12990. return k;
  12991. }
  12992. struct ColumnInfo {
  12993. enum Justification { Left, Right };
  12994. std::string name;
  12995. int width;
  12996. Justification justification;
  12997. };
  12998. struct ColumnBreak {};
  12999. struct RowBreak {};
  13000. class Duration {
  13001. enum class Unit {
  13002. Auto,
  13003. Nanoseconds,
  13004. Microseconds,
  13005. Milliseconds,
  13006. Seconds,
  13007. Minutes
  13008. };
  13009. static const uint64_t s_nanosecondsInAMicrosecond = 1000;
  13010. static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;
  13011. static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;
  13012. static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;
  13013. uint64_t m_inNanoseconds;
  13014. Unit m_units;
  13015. public:
  13016. explicit Duration(double inNanoseconds, Unit units = Unit::Auto)
  13017. : Duration(static_cast<uint64_t>(inNanoseconds), units) {
  13018. }
  13019. explicit Duration(uint64_t inNanoseconds, Unit units = Unit::Auto)
  13020. : m_inNanoseconds(inNanoseconds),
  13021. m_units(units) {
  13022. if (m_units == Unit::Auto) {
  13023. if (m_inNanoseconds < s_nanosecondsInAMicrosecond)
  13024. m_units = Unit::Nanoseconds;
  13025. else if (m_inNanoseconds < s_nanosecondsInAMillisecond)
  13026. m_units = Unit::Microseconds;
  13027. else if (m_inNanoseconds < s_nanosecondsInASecond)
  13028. m_units = Unit::Milliseconds;
  13029. else if (m_inNanoseconds < s_nanosecondsInAMinute)
  13030. m_units = Unit::Seconds;
  13031. else
  13032. m_units = Unit::Minutes;
  13033. }
  13034. }
  13035. auto value() const -> double {
  13036. switch (m_units) {
  13037. case Unit::Microseconds:
  13038. return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond);
  13039. case Unit::Milliseconds:
  13040. return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond);
  13041. case Unit::Seconds:
  13042. return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond);
  13043. case Unit::Minutes:
  13044. return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);
  13045. default:
  13046. return static_cast<double>(m_inNanoseconds);
  13047. }
  13048. }
  13049. auto unitsAsString() const -> std::string {
  13050. switch (m_units) {
  13051. case Unit::Nanoseconds:
  13052. return "ns";
  13053. case Unit::Microseconds:
  13054. return "us";
  13055. case Unit::Milliseconds:
  13056. return "ms";
  13057. case Unit::Seconds:
  13058. return "s";
  13059. case Unit::Minutes:
  13060. return "m";
  13061. default:
  13062. return "** internal error **";
  13063. }
  13064. }
  13065. friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {
  13066. return os << duration.value() << ' ' << duration.unitsAsString();
  13067. }
  13068. };
  13069. } // end anon namespace
  13070. class TablePrinter {
  13071. std::ostream& m_os;
  13072. std::vector<ColumnInfo> m_columnInfos;
  13073. std::ostringstream m_oss;
  13074. int m_currentColumn = -1;
  13075. bool m_isOpen = false;
  13076. public:
  13077. TablePrinter( std::ostream& os, std::vector<ColumnInfo> columnInfos )
  13078. : m_os( os ),
  13079. m_columnInfos( std::move( columnInfos ) ) {}
  13080. auto columnInfos() const -> std::vector<ColumnInfo> const& {
  13081. return m_columnInfos;
  13082. }
  13083. void open() {
  13084. if (!m_isOpen) {
  13085. m_isOpen = true;
  13086. *this << RowBreak();
  13087. Columns headerCols;
  13088. Spacer spacer(2);
  13089. for (auto const& info : m_columnInfos) {
  13090. headerCols += Column(info.name).width(static_cast<std::size_t>(info.width - 2));
  13091. headerCols += spacer;
  13092. }
  13093. m_os << headerCols << '\n';
  13094. m_os << Catch::getLineOfChars<'-'>() << '\n';
  13095. }
  13096. }
  13097. void close() {
  13098. if (m_isOpen) {
  13099. *this << RowBreak();
  13100. m_os << std::endl;
  13101. m_isOpen = false;
  13102. }
  13103. }
  13104. template<typename T>
  13105. friend TablePrinter& operator << (TablePrinter& tp, T const& value) {
  13106. tp.m_oss << value;
  13107. return tp;
  13108. }
  13109. friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {
  13110. auto colStr = tp.m_oss.str();
  13111. const auto strSize = colStr.size();
  13112. tp.m_oss.str("");
  13113. tp.open();
  13114. if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {
  13115. tp.m_currentColumn = -1;
  13116. tp.m_os << '\n';
  13117. }
  13118. tp.m_currentColumn++;
  13119. auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
  13120. auto padding = (strSize + 1 < static_cast<std::size_t>(colInfo.width))
  13121. ? std::string(colInfo.width - (strSize + 1), ' ')
  13122. : std::string();
  13123. if (colInfo.justification == ColumnInfo::Left)
  13124. tp.m_os << colStr << padding << ' ';
  13125. else
  13126. tp.m_os << padding << colStr << ' ';
  13127. return tp;
  13128. }
  13129. friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {
  13130. if (tp.m_currentColumn > 0) {
  13131. tp.m_os << '\n';
  13132. tp.m_currentColumn = -1;
  13133. }
  13134. return tp;
  13135. }
  13136. };
  13137. ConsoleReporter::ConsoleReporter(ReporterConfig const& config)
  13138. : StreamingReporterBase(config),
  13139. m_tablePrinter(new TablePrinter(config.stream(),
  13140. [&config]() -> std::vector<ColumnInfo> {
  13141. if (config.fullConfig()->benchmarkNoAnalysis())
  13142. {
  13143. return{
  13144. { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },
  13145. { " samples", 14, ColumnInfo::Right },
  13146. { " iterations", 14, ColumnInfo::Right },
  13147. { " mean", 14, ColumnInfo::Right }
  13148. };
  13149. }
  13150. else
  13151. {
  13152. return{
  13153. { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left },
  13154. { "samples mean std dev", 14, ColumnInfo::Right },
  13155. { "iterations low mean low std dev", 14, ColumnInfo::Right },
  13156. { "estimated high mean high std dev", 14, ColumnInfo::Right }
  13157. };
  13158. }
  13159. }())) {}
  13160. ConsoleReporter::~ConsoleReporter() = default;
  13161. std::string ConsoleReporter::getDescription() {
  13162. return "Reports test results as plain lines of text";
  13163. }
  13164. void ConsoleReporter::noMatchingTestCases(std::string const& spec) {
  13165. stream << "No test cases matched '" << spec << '\'' << std::endl;
  13166. }
  13167. void ConsoleReporter::reportInvalidArguments(std::string const&arg){
  13168. stream << "Invalid Filter: " << arg << std::endl;
  13169. }
  13170. void ConsoleReporter::assertionStarting(AssertionInfo const&) {}
  13171. bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
  13172. AssertionResult const& result = _assertionStats.assertionResult;
  13173. bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
  13174. // Drop out if result was successful but we're not printing them.
  13175. if (!includeResults && result.getResultType() != ResultWas::Warning)
  13176. return false;
  13177. lazyPrint();
  13178. ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);
  13179. printer.print();
  13180. stream << std::endl;
  13181. return true;
  13182. }
  13183. void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) {
  13184. m_tablePrinter->close();
  13185. m_headerPrinted = false;
  13186. StreamingReporterBase::sectionStarting(_sectionInfo);
  13187. }
  13188. void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {
  13189. m_tablePrinter->close();
  13190. if (_sectionStats.missingAssertions) {
  13191. lazyPrint();
  13192. Colour colour(Colour::ResultError);
  13193. if (m_sectionStack.size() > 1)
  13194. stream << "\nNo assertions in section";
  13195. else
  13196. stream << "\nNo assertions in test case";
  13197. stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
  13198. }
  13199. if (m_config->showDurations() == ShowDurations::Always) {
  13200. stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
  13201. }
  13202. if (m_headerPrinted) {
  13203. m_headerPrinted = false;
  13204. }
  13205. StreamingReporterBase::sectionEnded(_sectionStats);
  13206. }
  13207. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  13208. void ConsoleReporter::benchmarkPreparing(std::string const& name) {
  13209. lazyPrintWithoutClosingBenchmarkTable();
  13210. auto nameCol = Column(name).width(static_cast<std::size_t>(m_tablePrinter->columnInfos()[0].width - 2));
  13211. bool firstLine = true;
  13212. for (auto line : nameCol) {
  13213. if (!firstLine)
  13214. (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
  13215. else
  13216. firstLine = false;
  13217. (*m_tablePrinter) << line << ColumnBreak();
  13218. }
  13219. }
  13220. void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
  13221. (*m_tablePrinter) << info.samples << ColumnBreak()
  13222. << info.iterations << ColumnBreak();
  13223. if (!m_config->benchmarkNoAnalysis())
  13224. (*m_tablePrinter) << Duration(info.estimatedDuration) << ColumnBreak();
  13225. }
  13226. void ConsoleReporter::benchmarkEnded(BenchmarkStats<> const& stats) {
  13227. if (m_config->benchmarkNoAnalysis())
  13228. {
  13229. (*m_tablePrinter) << Duration(stats.mean.point.count()) << ColumnBreak();
  13230. }
  13231. else
  13232. {
  13233. (*m_tablePrinter) << ColumnBreak()
  13234. << Duration(stats.mean.point.count()) << ColumnBreak()
  13235. << Duration(stats.mean.lower_bound.count()) << ColumnBreak()
  13236. << Duration(stats.mean.upper_bound.count()) << ColumnBreak() << ColumnBreak()
  13237. << Duration(stats.standardDeviation.point.count()) << ColumnBreak()
  13238. << Duration(stats.standardDeviation.lower_bound.count()) << ColumnBreak()
  13239. << Duration(stats.standardDeviation.upper_bound.count()) << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak();
  13240. }
  13241. }
  13242. void ConsoleReporter::benchmarkFailed(std::string const& error) {
  13243. Colour colour(Colour::Red);
  13244. (*m_tablePrinter)
  13245. << "Benchmark failed (" << error << ')'
  13246. << ColumnBreak() << RowBreak();
  13247. }
  13248. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  13249. void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
  13250. m_tablePrinter->close();
  13251. StreamingReporterBase::testCaseEnded(_testCaseStats);
  13252. m_headerPrinted = false;
  13253. }
  13254. void ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) {
  13255. if (currentGroupInfo.used) {
  13256. printSummaryDivider();
  13257. stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
  13258. printTotals(_testGroupStats.totals);
  13259. stream << '\n' << std::endl;
  13260. }
  13261. StreamingReporterBase::testGroupEnded(_testGroupStats);
  13262. }
  13263. void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
  13264. printTotalsDivider(_testRunStats.totals);
  13265. printTotals(_testRunStats.totals);
  13266. stream << std::endl;
  13267. StreamingReporterBase::testRunEnded(_testRunStats);
  13268. }
  13269. void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) {
  13270. StreamingReporterBase::testRunStarting(_testInfo);
  13271. printTestFilters();
  13272. }
  13273. void ConsoleReporter::lazyPrint() {
  13274. m_tablePrinter->close();
  13275. lazyPrintWithoutClosingBenchmarkTable();
  13276. }
  13277. void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() {
  13278. if (!currentTestRunInfo.used)
  13279. lazyPrintRunInfo();
  13280. if (!currentGroupInfo.used)
  13281. lazyPrintGroupInfo();
  13282. if (!m_headerPrinted) {
  13283. printTestCaseAndSectionHeader();
  13284. m_headerPrinted = true;
  13285. }
  13286. }
  13287. void ConsoleReporter::lazyPrintRunInfo() {
  13288. stream << '\n' << getLineOfChars<'~'>() << '\n';
  13289. Colour colour(Colour::SecondaryText);
  13290. stream << currentTestRunInfo->name
  13291. << " is a Catch v" << libraryVersion() << " host application.\n"
  13292. << "Run with -? for options\n\n";
  13293. if (m_config->rngSeed() != 0)
  13294. stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
  13295. currentTestRunInfo.used = true;
  13296. }
  13297. void ConsoleReporter::lazyPrintGroupInfo() {
  13298. if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {
  13299. printClosedHeader("Group: " + currentGroupInfo->name);
  13300. currentGroupInfo.used = true;
  13301. }
  13302. }
  13303. void ConsoleReporter::printTestCaseAndSectionHeader() {
  13304. assert(!m_sectionStack.empty());
  13305. printOpenHeader(currentTestCaseInfo->name);
  13306. if (m_sectionStack.size() > 1) {
  13307. Colour colourGuard(Colour::Headers);
  13308. auto
  13309. it = m_sectionStack.begin() + 1, // Skip first section (test case)
  13310. itEnd = m_sectionStack.end();
  13311. for (; it != itEnd; ++it)
  13312. printHeaderString(it->name, 2);
  13313. }
  13314. SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
  13315. stream << getLineOfChars<'-'>() << '\n';
  13316. Colour colourGuard(Colour::FileName);
  13317. stream << lineInfo << '\n';
  13318. stream << getLineOfChars<'.'>() << '\n' << std::endl;
  13319. }
  13320. void ConsoleReporter::printClosedHeader(std::string const& _name) {
  13321. printOpenHeader(_name);
  13322. stream << getLineOfChars<'.'>() << '\n';
  13323. }
  13324. void ConsoleReporter::printOpenHeader(std::string const& _name) {
  13325. stream << getLineOfChars<'-'>() << '\n';
  13326. {
  13327. Colour colourGuard(Colour::Headers);
  13328. printHeaderString(_name);
  13329. }
  13330. }
  13331. // if string has a : in first line will set indent to follow it on
  13332. // subsequent lines
  13333. void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) {
  13334. std::size_t i = _string.find(": ");
  13335. if (i != std::string::npos)
  13336. i += 2;
  13337. else
  13338. i = 0;
  13339. stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n';
  13340. }
  13341. struct SummaryColumn {
  13342. SummaryColumn( std::string _label, Colour::Code _colour )
  13343. : label( std::move( _label ) ),
  13344. colour( _colour ) {}
  13345. SummaryColumn addRow( std::size_t count ) {
  13346. ReusableStringStream rss;
  13347. rss << count;
  13348. std::string row = rss.str();
  13349. for (auto& oldRow : rows) {
  13350. while (oldRow.size() < row.size())
  13351. oldRow = ' ' + oldRow;
  13352. while (oldRow.size() > row.size())
  13353. row = ' ' + row;
  13354. }
  13355. rows.push_back(row);
  13356. return *this;
  13357. }
  13358. std::string label;
  13359. Colour::Code colour;
  13360. std::vector<std::string> rows;
  13361. };
  13362. void ConsoleReporter::printTotals( Totals const& totals ) {
  13363. if (totals.testCases.total() == 0) {
  13364. stream << Colour(Colour::Warning) << "No tests ran\n";
  13365. } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {
  13366. stream << Colour(Colour::ResultSuccess) << "All tests passed";
  13367. stream << " ("
  13368. << pluralise(totals.assertions.passed, "assertion") << " in "
  13369. << pluralise(totals.testCases.passed, "test case") << ')'
  13370. << '\n';
  13371. } else {
  13372. std::vector<SummaryColumn> columns;
  13373. columns.push_back(SummaryColumn("", Colour::None)
  13374. .addRow(totals.testCases.total())
  13375. .addRow(totals.assertions.total()));
  13376. columns.push_back(SummaryColumn("passed", Colour::Success)
  13377. .addRow(totals.testCases.passed)
  13378. .addRow(totals.assertions.passed));
  13379. columns.push_back(SummaryColumn("failed", Colour::ResultError)
  13380. .addRow(totals.testCases.failed)
  13381. .addRow(totals.assertions.failed));
  13382. columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure)
  13383. .addRow(totals.testCases.failedButOk)
  13384. .addRow(totals.assertions.failedButOk));
  13385. printSummaryRow("test cases", columns, 0);
  13386. printSummaryRow("assertions", columns, 1);
  13387. }
  13388. }
  13389. void ConsoleReporter::printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row) {
  13390. for (auto col : cols) {
  13391. std::string value = col.rows[row];
  13392. if (col.label.empty()) {
  13393. stream << label << ": ";
  13394. if (value != "0")
  13395. stream << value;
  13396. else
  13397. stream << Colour(Colour::Warning) << "- none -";
  13398. } else if (value != "0") {
  13399. stream << Colour(Colour::LightGrey) << " | ";
  13400. stream << Colour(col.colour)
  13401. << value << ' ' << col.label;
  13402. }
  13403. }
  13404. stream << '\n';
  13405. }
  13406. void ConsoleReporter::printTotalsDivider(Totals const& totals) {
  13407. if (totals.testCases.total() > 0) {
  13408. std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
  13409. std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
  13410. std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());
  13411. while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
  13412. findMax(failedRatio, failedButOkRatio, passedRatio)++;
  13413. while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
  13414. findMax(failedRatio, failedButOkRatio, passedRatio)--;
  13415. stream << Colour(Colour::Error) << std::string(failedRatio, '=');
  13416. stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');
  13417. if (totals.testCases.allPassed())
  13418. stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');
  13419. else
  13420. stream << Colour(Colour::Success) << std::string(passedRatio, '=');
  13421. } else {
  13422. stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');
  13423. }
  13424. stream << '\n';
  13425. }
  13426. void ConsoleReporter::printSummaryDivider() {
  13427. stream << getLineOfChars<'-'>() << '\n';
  13428. }
  13429. void ConsoleReporter::printTestFilters() {
  13430. if (m_config->testSpec().hasFilters())
  13431. stream << Colour(Colour::BrightYellow) << "Filters: " << serializeFilters( m_config->getTestsOrTags() ) << '\n';
  13432. }
  13433. CATCH_REGISTER_REPORTER("console", ConsoleReporter)
  13434. } // end namespace Catch
  13435. #if defined(_MSC_VER)
  13436. #pragma warning(pop)
  13437. #endif
  13438. #if defined(__clang__)
  13439. # pragma clang diagnostic pop
  13440. #endif
  13441. // end catch_reporter_console.cpp
  13442. // start catch_reporter_junit.cpp
  13443. #include <cassert>
  13444. #include <sstream>
  13445. #include <ctime>
  13446. #include <algorithm>
  13447. namespace Catch {
  13448. namespace {
  13449. std::string getCurrentTimestamp() {
  13450. // Beware, this is not reentrant because of backward compatibility issues
  13451. // Also, UTC only, again because of backward compatibility (%z is C++11)
  13452. time_t rawtime;
  13453. std::time(&rawtime);
  13454. auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
  13455. #ifdef _MSC_VER
  13456. std::tm timeInfo = {};
  13457. gmtime_s(&timeInfo, &rawtime);
  13458. #else
  13459. std::tm* timeInfo;
  13460. timeInfo = std::gmtime(&rawtime);
  13461. #endif
  13462. char timeStamp[timeStampSize];
  13463. const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
  13464. #ifdef _MSC_VER
  13465. std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
  13466. #else
  13467. std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
  13468. #endif
  13469. return std::string(timeStamp);
  13470. }
  13471. std::string fileNameTag(const std::vector<std::string> &tags) {
  13472. auto it = std::find_if(begin(tags),
  13473. end(tags),
  13474. [] (std::string const& tag) {return tag.front() == '#'; });
  13475. if (it != tags.end())
  13476. return it->substr(1);
  13477. return std::string();
  13478. }
  13479. } // anonymous namespace
  13480. JunitReporter::JunitReporter( ReporterConfig const& _config )
  13481. : CumulativeReporterBase( _config ),
  13482. xml( _config.stream() )
  13483. {
  13484. m_reporterPrefs.shouldRedirectStdOut = true;
  13485. m_reporterPrefs.shouldReportAllAssertions = true;
  13486. }
  13487. JunitReporter::~JunitReporter() {}
  13488. std::string JunitReporter::getDescription() {
  13489. return "Reports test results in an XML format that looks like Ant's junitreport target";
  13490. }
  13491. void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {}
  13492. void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) {
  13493. CumulativeReporterBase::testRunStarting( runInfo );
  13494. xml.startElement( "testsuites" );
  13495. }
  13496. void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {
  13497. suiteTimer.start();
  13498. stdOutForSuite.clear();
  13499. stdErrForSuite.clear();
  13500. unexpectedExceptions = 0;
  13501. CumulativeReporterBase::testGroupStarting( groupInfo );
  13502. }
  13503. void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) {
  13504. m_okToFail = testCaseInfo.okToFail();
  13505. }
  13506. bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) {
  13507. if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
  13508. unexpectedExceptions++;
  13509. return CumulativeReporterBase::assertionEnded( assertionStats );
  13510. }
  13511. void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
  13512. stdOutForSuite += testCaseStats.stdOut;
  13513. stdErrForSuite += testCaseStats.stdErr;
  13514. CumulativeReporterBase::testCaseEnded( testCaseStats );
  13515. }
  13516. void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
  13517. double suiteTime = suiteTimer.getElapsedSeconds();
  13518. CumulativeReporterBase::testGroupEnded( testGroupStats );
  13519. writeGroup( *m_testGroups.back(), suiteTime );
  13520. }
  13521. void JunitReporter::testRunEndedCumulative() {
  13522. xml.endElement();
  13523. }
  13524. void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
  13525. XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
  13526. TestGroupStats const& stats = groupNode.value;
  13527. xml.writeAttribute( "name", stats.groupInfo.name );
  13528. xml.writeAttribute( "errors", unexpectedExceptions );
  13529. xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
  13530. xml.writeAttribute( "tests", stats.totals.assertions.total() );
  13531. xml.writeAttribute( "hostname", "tbd" ); // !TBD
  13532. if( m_config->showDurations() == ShowDurations::Never )
  13533. xml.writeAttribute( "time", "" );
  13534. else
  13535. xml.writeAttribute( "time", suiteTime );
  13536. xml.writeAttribute( "timestamp", getCurrentTimestamp() );
  13537. // Write properties if there are any
  13538. if (m_config->hasTestFilters() || m_config->rngSeed() != 0) {
  13539. auto properties = xml.scopedElement("properties");
  13540. if (m_config->hasTestFilters()) {
  13541. xml.scopedElement("property")
  13542. .writeAttribute("name", "filters")
  13543. .writeAttribute("value", serializeFilters(m_config->getTestsOrTags()));
  13544. }
  13545. if (m_config->rngSeed() != 0) {
  13546. xml.scopedElement("property")
  13547. .writeAttribute("name", "random-seed")
  13548. .writeAttribute("value", m_config->rngSeed());
  13549. }
  13550. }
  13551. // Write test cases
  13552. for( auto const& child : groupNode.children )
  13553. writeTestCase( *child );
  13554. xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), false );
  13555. xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), false );
  13556. }
  13557. void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) {
  13558. TestCaseStats const& stats = testCaseNode.value;
  13559. // All test cases have exactly one section - which represents the
  13560. // test case itself. That section may have 0-n nested sections
  13561. assert( testCaseNode.children.size() == 1 );
  13562. SectionNode const& rootSection = *testCaseNode.children.front();
  13563. std::string className = stats.testInfo.className;
  13564. if( className.empty() ) {
  13565. className = fileNameTag(stats.testInfo.tags);
  13566. if ( className.empty() )
  13567. className = "global";
  13568. }
  13569. if ( !m_config->name().empty() )
  13570. className = m_config->name() + "." + className;
  13571. writeSection( className, "", rootSection );
  13572. }
  13573. void JunitReporter::writeSection( std::string const& className,
  13574. std::string const& rootName,
  13575. SectionNode const& sectionNode ) {
  13576. std::string name = trim( sectionNode.stats.sectionInfo.name );
  13577. if( !rootName.empty() )
  13578. name = rootName + '/' + name;
  13579. if( !sectionNode.assertions.empty() ||
  13580. !sectionNode.stdOut.empty() ||
  13581. !sectionNode.stdErr.empty() ) {
  13582. XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
  13583. if( className.empty() ) {
  13584. xml.writeAttribute( "classname", name );
  13585. xml.writeAttribute( "name", "root" );
  13586. }
  13587. else {
  13588. xml.writeAttribute( "classname", className );
  13589. xml.writeAttribute( "name", name );
  13590. }
  13591. xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) );
  13592. writeAssertions( sectionNode );
  13593. if( !sectionNode.stdOut.empty() )
  13594. xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
  13595. if( !sectionNode.stdErr.empty() )
  13596. xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
  13597. }
  13598. for( auto const& childNode : sectionNode.childSections )
  13599. if( className.empty() )
  13600. writeSection( name, "", *childNode );
  13601. else
  13602. writeSection( className, name, *childNode );
  13603. }
  13604. void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {
  13605. for( auto const& assertion : sectionNode.assertions )
  13606. writeAssertion( assertion );
  13607. }
  13608. void JunitReporter::writeAssertion( AssertionStats const& stats ) {
  13609. AssertionResult const& result = stats.assertionResult;
  13610. if( !result.isOk() ) {
  13611. std::string elementName;
  13612. switch( result.getResultType() ) {
  13613. case ResultWas::ThrewException:
  13614. case ResultWas::FatalErrorCondition:
  13615. elementName = "error";
  13616. break;
  13617. case ResultWas::ExplicitFailure:
  13618. elementName = "failure";
  13619. break;
  13620. case ResultWas::ExpressionFailed:
  13621. elementName = "failure";
  13622. break;
  13623. case ResultWas::DidntThrowException:
  13624. elementName = "failure";
  13625. break;
  13626. // We should never see these here:
  13627. case ResultWas::Info:
  13628. case ResultWas::Warning:
  13629. case ResultWas::Ok:
  13630. case ResultWas::Unknown:
  13631. case ResultWas::FailureBit:
  13632. case ResultWas::Exception:
  13633. elementName = "internalError";
  13634. break;
  13635. }
  13636. XmlWriter::ScopedElement e = xml.scopedElement( elementName );
  13637. xml.writeAttribute( "message", result.getExpandedExpression() );
  13638. xml.writeAttribute( "type", result.getTestMacroName() );
  13639. ReusableStringStream rss;
  13640. if( !result.getMessage().empty() )
  13641. rss << result.getMessage() << '\n';
  13642. for( auto const& msg : stats.infoMessages )
  13643. if( msg.type == ResultWas::Info )
  13644. rss << msg.message << '\n';
  13645. rss << "at " << result.getSourceInfo();
  13646. xml.writeText( rss.str(), false );
  13647. }
  13648. }
  13649. CATCH_REGISTER_REPORTER( "junit", JunitReporter )
  13650. } // end namespace Catch
  13651. // end catch_reporter_junit.cpp
  13652. // start catch_reporter_listening.cpp
  13653. #include <cassert>
  13654. namespace Catch {
  13655. ListeningReporter::ListeningReporter() {
  13656. // We will assume that listeners will always want all assertions
  13657. m_preferences.shouldReportAllAssertions = true;
  13658. }
  13659. void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {
  13660. m_listeners.push_back( std::move( listener ) );
  13661. }
  13662. void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {
  13663. assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
  13664. m_reporter = std::move( reporter );
  13665. m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
  13666. }
  13667. ReporterPreferences ListeningReporter::getPreferences() const {
  13668. return m_preferences;
  13669. }
  13670. std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {
  13671. return std::set<Verbosity>{ };
  13672. }
  13673. void ListeningReporter::noMatchingTestCases( std::string const& spec ) {
  13674. for ( auto const& listener : m_listeners ) {
  13675. listener->noMatchingTestCases( spec );
  13676. }
  13677. m_reporter->noMatchingTestCases( spec );
  13678. }
  13679. void ListeningReporter::reportInvalidArguments(std::string const&arg){
  13680. for ( auto const& listener : m_listeners ) {
  13681. listener->reportInvalidArguments( arg );
  13682. }
  13683. m_reporter->reportInvalidArguments( arg );
  13684. }
  13685. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  13686. void ListeningReporter::benchmarkPreparing( std::string const& name ) {
  13687. for (auto const& listener : m_listeners) {
  13688. listener->benchmarkPreparing(name);
  13689. }
  13690. m_reporter->benchmarkPreparing(name);
  13691. }
  13692. void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {
  13693. for ( auto const& listener : m_listeners ) {
  13694. listener->benchmarkStarting( benchmarkInfo );
  13695. }
  13696. m_reporter->benchmarkStarting( benchmarkInfo );
  13697. }
  13698. void ListeningReporter::benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) {
  13699. for ( auto const& listener : m_listeners ) {
  13700. listener->benchmarkEnded( benchmarkStats );
  13701. }
  13702. m_reporter->benchmarkEnded( benchmarkStats );
  13703. }
  13704. void ListeningReporter::benchmarkFailed( std::string const& error ) {
  13705. for (auto const& listener : m_listeners) {
  13706. listener->benchmarkFailed(error);
  13707. }
  13708. m_reporter->benchmarkFailed(error);
  13709. }
  13710. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  13711. void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) {
  13712. for ( auto const& listener : m_listeners ) {
  13713. listener->testRunStarting( testRunInfo );
  13714. }
  13715. m_reporter->testRunStarting( testRunInfo );
  13716. }
  13717. void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) {
  13718. for ( auto const& listener : m_listeners ) {
  13719. listener->testGroupStarting( groupInfo );
  13720. }
  13721. m_reporter->testGroupStarting( groupInfo );
  13722. }
  13723. void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
  13724. for ( auto const& listener : m_listeners ) {
  13725. listener->testCaseStarting( testInfo );
  13726. }
  13727. m_reporter->testCaseStarting( testInfo );
  13728. }
  13729. void ListeningReporter::sectionStarting( SectionInfo const& sectionInfo ) {
  13730. for ( auto const& listener : m_listeners ) {
  13731. listener->sectionStarting( sectionInfo );
  13732. }
  13733. m_reporter->sectionStarting( sectionInfo );
  13734. }
  13735. void ListeningReporter::assertionStarting( AssertionInfo const& assertionInfo ) {
  13736. for ( auto const& listener : m_listeners ) {
  13737. listener->assertionStarting( assertionInfo );
  13738. }
  13739. m_reporter->assertionStarting( assertionInfo );
  13740. }
  13741. // The return value indicates if the messages buffer should be cleared:
  13742. bool ListeningReporter::assertionEnded( AssertionStats const& assertionStats ) {
  13743. for( auto const& listener : m_listeners ) {
  13744. static_cast<void>( listener->assertionEnded( assertionStats ) );
  13745. }
  13746. return m_reporter->assertionEnded( assertionStats );
  13747. }
  13748. void ListeningReporter::sectionEnded( SectionStats const& sectionStats ) {
  13749. for ( auto const& listener : m_listeners ) {
  13750. listener->sectionEnded( sectionStats );
  13751. }
  13752. m_reporter->sectionEnded( sectionStats );
  13753. }
  13754. void ListeningReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
  13755. for ( auto const& listener : m_listeners ) {
  13756. listener->testCaseEnded( testCaseStats );
  13757. }
  13758. m_reporter->testCaseEnded( testCaseStats );
  13759. }
  13760. void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
  13761. for ( auto const& listener : m_listeners ) {
  13762. listener->testGroupEnded( testGroupStats );
  13763. }
  13764. m_reporter->testGroupEnded( testGroupStats );
  13765. }
  13766. void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) {
  13767. for ( auto const& listener : m_listeners ) {
  13768. listener->testRunEnded( testRunStats );
  13769. }
  13770. m_reporter->testRunEnded( testRunStats );
  13771. }
  13772. void ListeningReporter::skipTest( TestCaseInfo const& testInfo ) {
  13773. for ( auto const& listener : m_listeners ) {
  13774. listener->skipTest( testInfo );
  13775. }
  13776. m_reporter->skipTest( testInfo );
  13777. }
  13778. bool ListeningReporter::isMulti() const {
  13779. return true;
  13780. }
  13781. } // end namespace Catch
  13782. // end catch_reporter_listening.cpp
  13783. // start catch_reporter_xml.cpp
  13784. #if defined(_MSC_VER)
  13785. #pragma warning(push)
  13786. #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
  13787. // Note that 4062 (not all labels are handled
  13788. // and default is missing) is enabled
  13789. #endif
  13790. namespace Catch {
  13791. XmlReporter::XmlReporter( ReporterConfig const& _config )
  13792. : StreamingReporterBase( _config ),
  13793. m_xml(_config.stream())
  13794. {
  13795. m_reporterPrefs.shouldRedirectStdOut = true;
  13796. m_reporterPrefs.shouldReportAllAssertions = true;
  13797. }
  13798. XmlReporter::~XmlReporter() = default;
  13799. std::string XmlReporter::getDescription() {
  13800. return "Reports test results as an XML document";
  13801. }
  13802. std::string XmlReporter::getStylesheetRef() const {
  13803. return std::string();
  13804. }
  13805. void XmlReporter::writeSourceInfo( SourceLineInfo const& sourceInfo ) {
  13806. m_xml
  13807. .writeAttribute( "filename", sourceInfo.file )
  13808. .writeAttribute( "line", sourceInfo.line );
  13809. }
  13810. void XmlReporter::noMatchingTestCases( std::string const& s ) {
  13811. StreamingReporterBase::noMatchingTestCases( s );
  13812. }
  13813. void XmlReporter::testRunStarting( TestRunInfo const& testInfo ) {
  13814. StreamingReporterBase::testRunStarting( testInfo );
  13815. std::string stylesheetRef = getStylesheetRef();
  13816. if( !stylesheetRef.empty() )
  13817. m_xml.writeStylesheetRef( stylesheetRef );
  13818. m_xml.startElement( "Catch" );
  13819. if( !m_config->name().empty() )
  13820. m_xml.writeAttribute( "name", m_config->name() );
  13821. if (m_config->testSpec().hasFilters())
  13822. m_xml.writeAttribute( "filters", serializeFilters( m_config->getTestsOrTags() ) );
  13823. if( m_config->rngSeed() != 0 )
  13824. m_xml.scopedElement( "Randomness" )
  13825. .writeAttribute( "seed", m_config->rngSeed() );
  13826. }
  13827. void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) {
  13828. StreamingReporterBase::testGroupStarting( groupInfo );
  13829. m_xml.startElement( "Group" )
  13830. .writeAttribute( "name", groupInfo.name );
  13831. }
  13832. void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
  13833. StreamingReporterBase::testCaseStarting(testInfo);
  13834. m_xml.startElement( "TestCase" )
  13835. .writeAttribute( "name", trim( testInfo.name ) )
  13836. .writeAttribute( "description", testInfo.description )
  13837. .writeAttribute( "tags", testInfo.tagsAsString() );
  13838. writeSourceInfo( testInfo.lineInfo );
  13839. if ( m_config->showDurations() == ShowDurations::Always )
  13840. m_testCaseTimer.start();
  13841. m_xml.ensureTagClosed();
  13842. }
  13843. void XmlReporter::sectionStarting( SectionInfo const& sectionInfo ) {
  13844. StreamingReporterBase::sectionStarting( sectionInfo );
  13845. if( m_sectionDepth++ > 0 ) {
  13846. m_xml.startElement( "Section" )
  13847. .writeAttribute( "name", trim( sectionInfo.name ) );
  13848. writeSourceInfo( sectionInfo.lineInfo );
  13849. m_xml.ensureTagClosed();
  13850. }
  13851. }
  13852. void XmlReporter::assertionStarting( AssertionInfo const& ) { }
  13853. bool XmlReporter::assertionEnded( AssertionStats const& assertionStats ) {
  13854. AssertionResult const& result = assertionStats.assertionResult;
  13855. bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
  13856. if( includeResults || result.getResultType() == ResultWas::Warning ) {
  13857. // Print any info messages in <Info> tags.
  13858. for( auto const& msg : assertionStats.infoMessages ) {
  13859. if( msg.type == ResultWas::Info && includeResults ) {
  13860. m_xml.scopedElement( "Info" )
  13861. .writeText( msg.message );
  13862. } else if ( msg.type == ResultWas::Warning ) {
  13863. m_xml.scopedElement( "Warning" )
  13864. .writeText( msg.message );
  13865. }
  13866. }
  13867. }
  13868. // Drop out if result was successful but we're not printing them.
  13869. if( !includeResults && result.getResultType() != ResultWas::Warning )
  13870. return true;
  13871. // Print the expression if there is one.
  13872. if( result.hasExpression() ) {
  13873. m_xml.startElement( "Expression" )
  13874. .writeAttribute( "success", result.succeeded() )
  13875. .writeAttribute( "type", result.getTestMacroName() );
  13876. writeSourceInfo( result.getSourceInfo() );
  13877. m_xml.scopedElement( "Original" )
  13878. .writeText( result.getExpression() );
  13879. m_xml.scopedElement( "Expanded" )
  13880. .writeText( result.getExpandedExpression() );
  13881. }
  13882. // And... Print a result applicable to each result type.
  13883. switch( result.getResultType() ) {
  13884. case ResultWas::ThrewException:
  13885. m_xml.startElement( "Exception" );
  13886. writeSourceInfo( result.getSourceInfo() );
  13887. m_xml.writeText( result.getMessage() );
  13888. m_xml.endElement();
  13889. break;
  13890. case ResultWas::FatalErrorCondition:
  13891. m_xml.startElement( "FatalErrorCondition" );
  13892. writeSourceInfo( result.getSourceInfo() );
  13893. m_xml.writeText( result.getMessage() );
  13894. m_xml.endElement();
  13895. break;
  13896. case ResultWas::Info:
  13897. m_xml.scopedElement( "Info" )
  13898. .writeText( result.getMessage() );
  13899. break;
  13900. case ResultWas::Warning:
  13901. // Warning will already have been written
  13902. break;
  13903. case ResultWas::ExplicitFailure:
  13904. m_xml.startElement( "Failure" );
  13905. writeSourceInfo( result.getSourceInfo() );
  13906. m_xml.writeText( result.getMessage() );
  13907. m_xml.endElement();
  13908. break;
  13909. default:
  13910. break;
  13911. }
  13912. if( result.hasExpression() )
  13913. m_xml.endElement();
  13914. return true;
  13915. }
  13916. void XmlReporter::sectionEnded( SectionStats const& sectionStats ) {
  13917. StreamingReporterBase::sectionEnded( sectionStats );
  13918. if( --m_sectionDepth > 0 ) {
  13919. XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
  13920. e.writeAttribute( "successes", sectionStats.assertions.passed );
  13921. e.writeAttribute( "failures", sectionStats.assertions.failed );
  13922. e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
  13923. if ( m_config->showDurations() == ShowDurations::Always )
  13924. e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
  13925. m_xml.endElement();
  13926. }
  13927. }
  13928. void XmlReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
  13929. StreamingReporterBase::testCaseEnded( testCaseStats );
  13930. XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
  13931. e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
  13932. if ( m_config->showDurations() == ShowDurations::Always )
  13933. e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
  13934. if( !testCaseStats.stdOut.empty() )
  13935. m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false );
  13936. if( !testCaseStats.stdErr.empty() )
  13937. m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false );
  13938. m_xml.endElement();
  13939. }
  13940. void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
  13941. StreamingReporterBase::testGroupEnded( testGroupStats );
  13942. // TODO: Check testGroupStats.aborting and act accordingly.
  13943. m_xml.scopedElement( "OverallResults" )
  13944. .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
  13945. .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
  13946. .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
  13947. m_xml.endElement();
  13948. }
  13949. void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) {
  13950. StreamingReporterBase::testRunEnded( testRunStats );
  13951. m_xml.scopedElement( "OverallResults" )
  13952. .writeAttribute( "successes", testRunStats.totals.assertions.passed )
  13953. .writeAttribute( "failures", testRunStats.totals.assertions.failed )
  13954. .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
  13955. m_xml.endElement();
  13956. }
  13957. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  13958. void XmlReporter::benchmarkPreparing(std::string const& name) {
  13959. m_xml.startElement("BenchmarkResults")
  13960. .writeAttribute("name", name);
  13961. }
  13962. void XmlReporter::benchmarkStarting(BenchmarkInfo const &info) {
  13963. m_xml.writeAttribute("samples", info.samples)
  13964. .writeAttribute("resamples", info.resamples)
  13965. .writeAttribute("iterations", info.iterations)
  13966. .writeAttribute("clockResolution", static_cast<uint64_t>(info.clockResolution))
  13967. .writeAttribute("estimatedDuration", static_cast<uint64_t>(info.estimatedDuration))
  13968. .writeComment("All values in nano seconds");
  13969. }
  13970. void XmlReporter::benchmarkEnded(BenchmarkStats<> const& benchmarkStats) {
  13971. m_xml.startElement("mean")
  13972. .writeAttribute("value", static_cast<uint64_t>(benchmarkStats.mean.point.count()))
  13973. .writeAttribute("lowerBound", static_cast<uint64_t>(benchmarkStats.mean.lower_bound.count()))
  13974. .writeAttribute("upperBound", static_cast<uint64_t>(benchmarkStats.mean.upper_bound.count()))
  13975. .writeAttribute("ci", benchmarkStats.mean.confidence_interval);
  13976. m_xml.endElement();
  13977. m_xml.startElement("standardDeviation")
  13978. .writeAttribute("value", benchmarkStats.standardDeviation.point.count())
  13979. .writeAttribute("lowerBound", benchmarkStats.standardDeviation.lower_bound.count())
  13980. .writeAttribute("upperBound", benchmarkStats.standardDeviation.upper_bound.count())
  13981. .writeAttribute("ci", benchmarkStats.standardDeviation.confidence_interval);
  13982. m_xml.endElement();
  13983. m_xml.startElement("outliers")
  13984. .writeAttribute("variance", benchmarkStats.outlierVariance)
  13985. .writeAttribute("lowMild", benchmarkStats.outliers.low_mild)
  13986. .writeAttribute("lowSevere", benchmarkStats.outliers.low_severe)
  13987. .writeAttribute("highMild", benchmarkStats.outliers.high_mild)
  13988. .writeAttribute("highSevere", benchmarkStats.outliers.high_severe);
  13989. m_xml.endElement();
  13990. m_xml.endElement();
  13991. }
  13992. void XmlReporter::benchmarkFailed(std::string const &error) {
  13993. m_xml.scopedElement("failed").
  13994. writeAttribute("message", error);
  13995. m_xml.endElement();
  13996. }
  13997. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  13998. CATCH_REGISTER_REPORTER( "xml", XmlReporter )
  13999. } // end namespace Catch
  14000. #if defined(_MSC_VER)
  14001. #pragma warning(pop)
  14002. #endif
  14003. // end catch_reporter_xml.cpp
  14004. namespace Catch {
  14005. LeakDetector leakDetector;
  14006. }
  14007. #ifdef __clang__
  14008. #pragma clang diagnostic pop
  14009. #endif
  14010. // end catch_impl.hpp
  14011. #endif
  14012. #ifdef CATCH_CONFIG_MAIN
  14013. // start catch_default_main.hpp
  14014. #ifndef __OBJC__
  14015. #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
  14016. // Standard C/C++ Win32 Unicode wmain entry point
  14017. extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
  14018. #else
  14019. // Standard C/C++ main entry point
  14020. int main (int argc, char * argv[]) {
  14021. #endif
  14022. return Catch::Session().run( argc, argv );
  14023. }
  14024. #else // __OBJC__
  14025. // Objective-C entry point
  14026. int main (int argc, char * const argv[]) {
  14027. #if !CATCH_ARC_ENABLED
  14028. NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
  14029. #endif
  14030. Catch::registerTestMethods();
  14031. int result = Catch::Session().run( argc, (char**)argv );
  14032. #if !CATCH_ARC_ENABLED
  14033. [pool drain];
  14034. #endif
  14035. return result;
  14036. }
  14037. #endif // __OBJC__
  14038. // end catch_default_main.hpp
  14039. #endif
  14040. #if !defined(CATCH_CONFIG_IMPL_ONLY)
  14041. #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
  14042. # undef CLARA_CONFIG_MAIN
  14043. #endif
  14044. #if !defined(CATCH_CONFIG_DISABLE)
  14045. //////
  14046. // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
  14047. #ifdef CATCH_CONFIG_PREFIX_ALL
  14048. #define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  14049. #define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  14050. #define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  14051. #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
  14052. #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
  14053. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14054. #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
  14055. #endif// CATCH_CONFIG_DISABLE_MATCHERS
  14056. #define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  14057. #define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14058. #define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  14059. #define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14060. #define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14061. #define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
  14062. #define CATCH_CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14063. #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
  14064. #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  14065. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14066. #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  14067. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  14068. #define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14069. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14070. #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
  14071. #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
  14072. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  14073. #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
  14074. #define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "CATCH_UNSCOPED_INFO", msg )
  14075. #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
  14076. #define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ )
  14077. #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
  14078. #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14079. #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
  14080. #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
  14081. #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
  14082. #define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
  14083. #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
  14084. #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14085. #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14086. #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
  14087. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  14088. #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  14089. #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
  14090. #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14091. #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
  14092. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
  14093. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
  14094. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14095. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
  14096. #else
  14097. #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
  14098. #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
  14099. #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
  14100. #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
  14101. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
  14102. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
  14103. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
  14104. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
  14105. #endif
  14106. #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
  14107. #define CATCH_STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__ , #__VA_ARGS__ ); CATCH_SUCCEED( #__VA_ARGS__ )
  14108. #define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ )
  14109. #else
  14110. #define CATCH_STATIC_REQUIRE( ... ) CATCH_REQUIRE( __VA_ARGS__ )
  14111. #define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ )
  14112. #endif
  14113. // "BDD-style" convenience wrappers
  14114. #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
  14115. #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
  14116. #define CATCH_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
  14117. #define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
  14118. #define CATCH_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
  14119. #define CATCH_AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
  14120. #define CATCH_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
  14121. #define CATCH_AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
  14122. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  14123. #define CATCH_BENCHMARK(...) \
  14124. INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
  14125. #define CATCH_BENCHMARK_ADVANCED(name) \
  14126. INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
  14127. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  14128. // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
  14129. #else
  14130. #define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  14131. #define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  14132. #define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  14133. #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
  14134. #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
  14135. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14136. #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
  14137. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  14138. #define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  14139. #define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14140. #define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  14141. #define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14142. #define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14143. #define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
  14144. #define CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14145. #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
  14146. #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  14147. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14148. #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  14149. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  14150. #define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14151. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14152. #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
  14153. #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
  14154. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  14155. #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
  14156. #define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg )
  14157. #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
  14158. #define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ )
  14159. #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
  14160. #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14161. #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
  14162. #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
  14163. #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
  14164. #define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
  14165. #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
  14166. #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14167. #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14168. #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
  14169. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  14170. #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  14171. #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
  14172. #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14173. #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
  14174. #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
  14175. #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
  14176. #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14177. #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
  14178. #define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)
  14179. #define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14180. #else
  14181. #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
  14182. #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
  14183. #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
  14184. #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
  14185. #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
  14186. #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
  14187. #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
  14188. #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
  14189. #define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE( __VA_ARGS__ ) )
  14190. #define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
  14191. #endif
  14192. #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
  14193. #define STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__, #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )
  14194. #define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" )
  14195. #else
  14196. #define STATIC_REQUIRE( ... ) REQUIRE( __VA_ARGS__ )
  14197. #define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ )
  14198. #endif
  14199. #endif
  14200. #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
  14201. // "BDD-style" convenience wrappers
  14202. #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
  14203. #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
  14204. #define GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
  14205. #define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
  14206. #define WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
  14207. #define AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
  14208. #define THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
  14209. #define AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
  14210. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  14211. #define BENCHMARK(...) \
  14212. INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
  14213. #define BENCHMARK_ADVANCED(name) \
  14214. INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
  14215. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  14216. using Catch::Detail::Approx;
  14217. #else // CATCH_CONFIG_DISABLE
  14218. //////
  14219. // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
  14220. #ifdef CATCH_CONFIG_PREFIX_ALL
  14221. #define CATCH_REQUIRE( ... ) (void)(0)
  14222. #define CATCH_REQUIRE_FALSE( ... ) (void)(0)
  14223. #define CATCH_REQUIRE_THROWS( ... ) (void)(0)
  14224. #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
  14225. #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
  14226. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14227. #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  14228. #endif// CATCH_CONFIG_DISABLE_MATCHERS
  14229. #define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)
  14230. #define CATCH_CHECK( ... ) (void)(0)
  14231. #define CATCH_CHECK_FALSE( ... ) (void)(0)
  14232. #define CATCH_CHECKED_IF( ... ) if (__VA_ARGS__)
  14233. #define CATCH_CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
  14234. #define CATCH_CHECK_NOFAIL( ... ) (void)(0)
  14235. #define CATCH_CHECK_THROWS( ... ) (void)(0)
  14236. #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
  14237. #define CATCH_CHECK_THROWS_WITH( expr, matcher ) (void)(0)
  14238. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14239. #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  14240. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  14241. #define CATCH_CHECK_NOTHROW( ... ) (void)(0)
  14242. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14243. #define CATCH_CHECK_THAT( arg, matcher ) (void)(0)
  14244. #define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
  14245. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  14246. #define CATCH_INFO( msg ) (void)(0)
  14247. #define CATCH_UNSCOPED_INFO( msg ) (void)(0)
  14248. #define CATCH_WARN( msg ) (void)(0)
  14249. #define CATCH_CAPTURE( msg ) (void)(0)
  14250. #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  14251. #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  14252. #define CATCH_METHOD_AS_TEST_CASE( method, ... )
  14253. #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
  14254. #define CATCH_SECTION( ... )
  14255. #define CATCH_DYNAMIC_SECTION( ... )
  14256. #define CATCH_FAIL( ... ) (void)(0)
  14257. #define CATCH_FAIL_CHECK( ... ) (void)(0)
  14258. #define CATCH_SUCCEED( ... ) (void)(0)
  14259. #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  14260. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  14261. #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
  14262. #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
  14263. #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
  14264. #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
  14265. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  14266. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  14267. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14268. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14269. #else
  14270. #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
  14271. #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
  14272. #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
  14273. #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
  14274. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  14275. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  14276. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14277. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14278. #endif
  14279. // "BDD-style" convenience wrappers
  14280. #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  14281. #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
  14282. #define CATCH_GIVEN( desc )
  14283. #define CATCH_AND_GIVEN( desc )
  14284. #define CATCH_WHEN( desc )
  14285. #define CATCH_AND_WHEN( desc )
  14286. #define CATCH_THEN( desc )
  14287. #define CATCH_AND_THEN( desc )
  14288. #define CATCH_STATIC_REQUIRE( ... ) (void)(0)
  14289. #define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)
  14290. // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
  14291. #else
  14292. #define REQUIRE( ... ) (void)(0)
  14293. #define REQUIRE_FALSE( ... ) (void)(0)
  14294. #define REQUIRE_THROWS( ... ) (void)(0)
  14295. #define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
  14296. #define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
  14297. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14298. #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  14299. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  14300. #define REQUIRE_NOTHROW( ... ) (void)(0)
  14301. #define CHECK( ... ) (void)(0)
  14302. #define CHECK_FALSE( ... ) (void)(0)
  14303. #define CHECKED_IF( ... ) if (__VA_ARGS__)
  14304. #define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
  14305. #define CHECK_NOFAIL( ... ) (void)(0)
  14306. #define CHECK_THROWS( ... ) (void)(0)
  14307. #define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
  14308. #define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
  14309. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14310. #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  14311. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  14312. #define CHECK_NOTHROW( ... ) (void)(0)
  14313. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14314. #define CHECK_THAT( arg, matcher ) (void)(0)
  14315. #define REQUIRE_THAT( arg, matcher ) (void)(0)
  14316. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  14317. #define INFO( msg ) (void)(0)
  14318. #define UNSCOPED_INFO( msg ) (void)(0)
  14319. #define WARN( msg ) (void)(0)
  14320. #define CAPTURE( msg ) (void)(0)
  14321. #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  14322. #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  14323. #define METHOD_AS_TEST_CASE( method, ... )
  14324. #define REGISTER_TEST_CASE( Function, ... ) (void)(0)
  14325. #define SECTION( ... )
  14326. #define DYNAMIC_SECTION( ... )
  14327. #define FAIL( ... ) (void)(0)
  14328. #define FAIL_CHECK( ... ) (void)(0)
  14329. #define SUCCEED( ... ) (void)(0)
  14330. #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  14331. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  14332. #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
  14333. #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
  14334. #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
  14335. #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
  14336. #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
  14337. #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
  14338. #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14339. #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14340. #else
  14341. #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
  14342. #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
  14343. #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
  14344. #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
  14345. #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
  14346. #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
  14347. #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14348. #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14349. #endif
  14350. #define STATIC_REQUIRE( ... ) (void)(0)
  14351. #define STATIC_REQUIRE_FALSE( ... ) (void)(0)
  14352. #endif
  14353. #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
  14354. // "BDD-style" convenience wrappers
  14355. #define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) )
  14356. #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
  14357. #define GIVEN( desc )
  14358. #define AND_GIVEN( desc )
  14359. #define WHEN( desc )
  14360. #define AND_WHEN( desc )
  14361. #define THEN( desc )
  14362. #define AND_THEN( desc )
  14363. using Catch::Detail::Approx;
  14364. #endif
  14365. #endif // ! CATCH_CONFIG_IMPL_ONLY
  14366. // start catch_reenable_warnings.h
  14367. #ifdef __clang__
  14368. # ifdef __ICC // icpc defines the __clang__ macro
  14369. # pragma warning(pop)
  14370. # else
  14371. # pragma clang diagnostic pop
  14372. # endif
  14373. #elif defined __GNUC__
  14374. # pragma GCC diagnostic pop
  14375. #endif
  14376. // end catch_reenable_warnings.h
  14377. // end catch.hpp
  14378. #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED