Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

11950 rindas
405KB

  1. /*
  2. * Catch v2.0.0-develop.5
  3. * Generated: 2017-10-12 13:05:08.135067
  4. * ----------------------------------------------------------
  5. * This file has been merged from multiple headers. Please don't edit it directly
  6. * Copyright (c) 2017 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. #ifdef __clang__
  15. # pragma clang system_header
  16. #elif defined __GNUC__
  17. # pragma GCC system_header
  18. #endif
  19. // start catch_suppress_warnings.h
  20. #ifdef __clang__
  21. # ifdef __ICC // icpc defines the __clang__ macro
  22. # pragma warning(push)
  23. # pragma warning(disable: 161 1682)
  24. # else // __ICC
  25. # pragma clang diagnostic ignored "-Wglobal-constructors"
  26. # pragma clang diagnostic ignored "-Wvariadic-macros"
  27. # pragma clang diagnostic ignored "-Wc99-extensions"
  28. # pragma clang diagnostic ignored "-Wunused-variable"
  29. # pragma clang diagnostic push
  30. # pragma clang diagnostic ignored "-Wpadded"
  31. # pragma clang diagnostic ignored "-Wswitch-enum"
  32. # pragma clang diagnostic ignored "-Wcovered-switch-default"
  33. # endif
  34. #elif defined __GNUC__
  35. # pragma GCC diagnostic ignored "-Wvariadic-macros"
  36. # pragma GCC diagnostic ignored "-Wunused-variable"
  37. # pragma GCC diagnostic ignored "-Wparentheses"
  38. # pragma GCC diagnostic push
  39. # pragma GCC diagnostic ignored "-Wpadded"
  40. #endif
  41. // end catch_suppress_warnings.h
  42. #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
  43. # define CATCH_IMPL
  44. # define CATCH_CONFIG_EXTERNAL_INTERFACES
  45. # if defined(CATCH_CONFIG_DISABLE_MATCHERS)
  46. # undef CATCH_CONFIG_DISABLE_MATCHERS
  47. # endif
  48. #endif
  49. // start catch_platform.h
  50. #ifdef __APPLE__
  51. # include <TargetConditionals.h>
  52. # if TARGET_OS_MAC == 1
  53. # define CATCH_PLATFORM_MAC
  54. # elif TARGET_OS_IPHONE == 1
  55. # define CATCH_PLATFORM_IPHONE
  56. # endif
  57. #elif defined(linux) || defined(__linux) || defined(__linux__)
  58. # define CATCH_PLATFORM_LINUX
  59. #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
  60. # define CATCH_PLATFORM_WINDOWS
  61. #endif
  62. // end catch_platform.h
  63. #ifdef CATCH_IMPL
  64. # ifndef CLARA_CONFIG_MAIN
  65. # define CLARA_CONFIG_MAIN_NOT_DEFINED
  66. # define CLARA_CONFIG_MAIN
  67. # endif
  68. #endif
  69. // start catch_tag_alias_autoregistrar.h
  70. // start catch_common.h
  71. // start catch_compiler_capabilities.h
  72. // Detect a number of compiler features - by compiler
  73. // The following features are defined:
  74. //
  75. // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
  76. // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
  77. // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
  78. // ****************
  79. // Note to maintainers: if new toggles are added please document them
  80. // in configuration.md, too
  81. // ****************
  82. // In general each macro has a _NO_<feature name> form
  83. // (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
  84. // Many features, at point of detection, define an _INTERNAL_ macro, so they
  85. // can be combined, en-mass, with the _NO_ forms later.
  86. #ifdef __cplusplus
  87. # if __cplusplus >= 201402L
  88. # define CATCH_CPP14_OR_GREATER
  89. # endif
  90. #endif
  91. #ifdef __clang__
  92. # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  93. _Pragma( "clang diagnostic push" ) \
  94. _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
  95. _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
  96. # define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  97. _Pragma( "clang diagnostic pop" )
  98. # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
  99. _Pragma( "clang diagnostic push" ) \
  100. _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
  101. # define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
  102. _Pragma( "clang diagnostic pop" )
  103. #endif // __clang__
  104. ////////////////////////////////////////////////////////////////////////////////
  105. // We know some environments not to support full POSIX signals
  106. #if defined(__CYGWIN__) || defined(__QNX__)
  107. # if !defined(CATCH_CONFIG_POSIX_SIGNALS)
  108. # define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
  109. # endif
  110. #endif
  111. #ifdef __OS400__
  112. # define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
  113. # define CATCH_CONFIG_COLOUR_NONE
  114. #endif
  115. ////////////////////////////////////////////////////////////////////////////////
  116. // Cygwin
  117. #ifdef __CYGWIN__
  118. // Required for some versions of Cygwin to declare gettimeofday
  119. // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
  120. # define _BSD_SOURCE
  121. #endif // __CYGWIN__
  122. ////////////////////////////////////////////////////////////////////////////////
  123. // Visual C++
  124. #ifdef _MSC_VER
  125. // Universal Windows platform does not support SEH
  126. // Or console colours (or console at all...)
  127. # if (WINAPI_FAMILY == WINAPI_FAMILY_APP)
  128. # define CATCH_CONFIG_COLOUR_NONE
  129. # else
  130. # define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
  131. # endif
  132. #endif // _MSC_VER
  133. ////////////////////////////////////////////////////////////////////////////////
  134. // All supported compilers support COUNTER macro,
  135. //but user still might want to turn it off
  136. #define CATCH_INTERNAL_CONFIG_COUNTER
  137. // Now set the actual defines based on the above + anything the user has configured
  138. // Use of __COUNTER__ is suppressed if __JETBRAINS_IDE__ is #defined (meaning we're being parsed by a JetBrains IDE for
  139. // analytics) because, at time of writing, __COUNTER__ is not properly handled by it.
  140. // This does not affect compilation
  141. #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) && !defined(__JETBRAINS_IDE__)
  142. # define CATCH_CONFIG_COUNTER
  143. #endif
  144. #if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH)
  145. # define CATCH_CONFIG_WINDOWS_SEH
  146. #endif
  147. // This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
  148. #if !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
  149. # define CATCH_CONFIG_POSIX_SIGNALS
  150. #endif
  151. #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
  152. # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
  153. # define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
  154. #endif
  155. #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
  156. # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
  157. # define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  158. #endif
  159. // end catch_compiler_capabilities.h
  160. #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
  161. #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
  162. #ifdef CATCH_CONFIG_COUNTER
  163. # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
  164. #else
  165. # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
  166. #endif
  167. #include <iosfwd>
  168. #include <string>
  169. #include <cstdint>
  170. namespace Catch {
  171. struct CaseSensitive { enum Choice {
  172. Yes,
  173. No
  174. }; };
  175. class NonCopyable {
  176. NonCopyable( NonCopyable const& ) = delete;
  177. NonCopyable( NonCopyable && ) = delete;
  178. NonCopyable& operator = ( NonCopyable const& ) = delete;
  179. NonCopyable& operator = ( NonCopyable && ) = delete;
  180. protected:
  181. NonCopyable();
  182. virtual ~NonCopyable();
  183. };
  184. struct SourceLineInfo {
  185. SourceLineInfo() = delete;
  186. SourceLineInfo( char const* _file, std::size_t _line ) noexcept;
  187. SourceLineInfo( SourceLineInfo const& other ) = default;
  188. SourceLineInfo( SourceLineInfo && ) = default;
  189. SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
  190. SourceLineInfo& operator = ( SourceLineInfo && ) = default;
  191. bool empty() const noexcept;
  192. bool operator == ( SourceLineInfo const& other ) const noexcept;
  193. bool operator < ( SourceLineInfo const& other ) const noexcept;
  194. char const* file;
  195. std::size_t line;
  196. };
  197. std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
  198. // This is just here to avoid compiler warnings with macro constants and boolean literals
  199. bool isTrue( bool value );
  200. bool alwaysTrue();
  201. bool alwaysFalse();
  202. // Use this in variadic streaming macros to allow
  203. // >> +StreamEndStop
  204. // as well as
  205. // >> stuff +StreamEndStop
  206. struct StreamEndStop {
  207. std::string operator+() const;
  208. };
  209. template<typename T>
  210. T const& operator + ( T const& value, StreamEndStop ) {
  211. return value;
  212. }
  213. }
  214. #define CATCH_INTERNAL_LINEINFO \
  215. ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
  216. // end catch_common.h
  217. namespace Catch {
  218. struct RegistrarForTagAliases {
  219. RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
  220. };
  221. } // end namespace Catch
  222. #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
  223. // end catch_tag_alias_autoregistrar.h
  224. // start catch_test_registry.h
  225. // start catch_interfaces_testcase.h
  226. #include <vector>
  227. #include <memory>
  228. namespace Catch {
  229. class TestSpec;
  230. struct ITestInvoker {
  231. virtual void invoke () const = 0;
  232. virtual ~ITestInvoker();
  233. };
  234. using ITestCasePtr = std::shared_ptr<ITestInvoker>;
  235. class TestCase;
  236. struct IConfig;
  237. struct ITestCaseRegistry {
  238. virtual ~ITestCaseRegistry();
  239. virtual std::vector<TestCase> const& getAllTests() const = 0;
  240. virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
  241. };
  242. bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
  243. std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
  244. std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
  245. }
  246. // end catch_interfaces_testcase.h
  247. // start catch_stringref.h
  248. #include <cstddef>
  249. #include <string>
  250. #include <iosfwd>
  251. namespace Catch {
  252. class StringData;
  253. /// A non-owning string class (similar to the forthcoming std::string_view)
  254. /// Note that, because a StringRef may be a substring of another string,
  255. /// it may not be null terminated. c_str() must return a null terminated
  256. /// string, however, and so the StringRef will internally take ownership
  257. /// (taking a copy), if necessary. In theory this ownership is not externally
  258. /// visible - but it does mean (substring) StringRefs should not be shared between
  259. /// threads.
  260. class StringRef {
  261. friend struct StringRefTestAccess;
  262. using size_type = std::size_t;
  263. char const* m_start;
  264. size_type m_size;
  265. char* m_data = nullptr;
  266. void takeOwnership();
  267. public: // construction/ assignment
  268. StringRef() noexcept;
  269. StringRef( StringRef const& other ) noexcept;
  270. StringRef( StringRef&& other ) noexcept;
  271. StringRef( char const* rawChars ) noexcept;
  272. StringRef( char const* rawChars, size_type size ) noexcept;
  273. StringRef( std::string const& stdString ) noexcept;
  274. ~StringRef() noexcept;
  275. auto operator = ( StringRef other ) noexcept -> StringRef&;
  276. operator std::string() const;
  277. void swap( StringRef& other ) noexcept;
  278. public: // operators
  279. auto operator == ( StringRef const& other ) const noexcept -> bool;
  280. auto operator != ( StringRef const& other ) const noexcept -> bool;
  281. auto operator[] ( size_type index ) const noexcept -> char;
  282. public: // named queries
  283. auto empty() const noexcept -> bool;
  284. auto size() const noexcept -> size_type;
  285. auto numberOfCharacters() const noexcept -> size_type;
  286. auto c_str() const -> char const*;
  287. public: // substrings and searches
  288. auto substr( size_type start, size_type size ) const noexcept -> StringRef;
  289. private: // ownership queries - may not be consistent between calls
  290. auto isOwned() const noexcept -> bool;
  291. auto isSubstring() const noexcept -> bool;
  292. auto data() const noexcept -> char const*;
  293. };
  294. auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string;
  295. auto operator + ( StringRef const& lhs, char const* rhs ) -> std::string;
  296. auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string;
  297. auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
  298. } // namespace Catch
  299. // end catch_stringref.h
  300. namespace Catch {
  301. template<typename C>
  302. class TestInvokerAsMethod : public ITestInvoker {
  303. void (C::*m_testAsMethod)();
  304. public:
  305. TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
  306. void invoke() const override {
  307. C obj;
  308. (obj.*m_testAsMethod)();
  309. }
  310. };
  311. auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;
  312. template<typename C>
  313. auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
  314. return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );
  315. }
  316. struct NameAndTags {
  317. NameAndTags( StringRef name_ = "", StringRef tags_ = "" ) noexcept;
  318. StringRef name;
  319. StringRef tags;
  320. };
  321. struct AutoReg : NonCopyable {
  322. AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef classOrMethod, NameAndTags const& nameAndTags ) noexcept;
  323. ~AutoReg();
  324. };
  325. } // end namespace Catch
  326. #if defined(CATCH_CONFIG_DISABLE)
  327. #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
  328. static void TestName()
  329. #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
  330. namespace{ \
  331. struct TestName : ClassName { \
  332. void test(); \
  333. }; \
  334. } \
  335. void TestName::test()
  336. #endif
  337. ///////////////////////////////////////////////////////////////////////////////
  338. #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
  339. static void TestName(); \
  340. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  341. namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
  342. CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  343. static void TestName()
  344. #define INTERNAL_CATCH_TESTCASE( ... ) \
  345. INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
  346. ///////////////////////////////////////////////////////////////////////////////
  347. #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
  348. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  349. namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
  350. CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  351. ///////////////////////////////////////////////////////////////////////////////
  352. #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
  353. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  354. namespace{ \
  355. struct TestName : ClassName{ \
  356. void test(); \
  357. }; \
  358. Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
  359. } \
  360. CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  361. void TestName::test()
  362. #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
  363. INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
  364. ///////////////////////////////////////////////////////////////////////////////
  365. #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
  366. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  367. Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
  368. CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  369. // end catch_test_registry.h
  370. // start catch_capture.hpp
  371. // start catch_assertionhandler.h
  372. // start catch_decomposer.h
  373. // start catch_tostring.h
  374. #include <sstream>
  375. #include <vector>
  376. #include <cstddef>
  377. #include <type_traits>
  378. #include <string>
  379. #ifdef __OBJC__
  380. // start catch_objc_arc.hpp
  381. #import <Foundation/Foundation.h>
  382. #ifdef __has_feature
  383. #define CATCH_ARC_ENABLED __has_feature(objc_arc)
  384. #else
  385. #define CATCH_ARC_ENABLED 0
  386. #endif
  387. void arcSafeRelease( NSObject* obj );
  388. id performOptionalSelector( id obj, SEL sel );
  389. #if !CATCH_ARC_ENABLED
  390. inline void arcSafeRelease( NSObject* obj ) {
  391. [obj release];
  392. }
  393. inline id performOptionalSelector( id obj, SEL sel ) {
  394. if( [obj respondsToSelector: sel] )
  395. return [obj performSelector: sel];
  396. return nil;
  397. }
  398. #define CATCH_UNSAFE_UNRETAINED
  399. #define CATCH_ARC_STRONG
  400. #else
  401. inline void arcSafeRelease( NSObject* ){}
  402. inline id performOptionalSelector( id obj, SEL sel ) {
  403. #ifdef __clang__
  404. #pragma clang diagnostic push
  405. #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
  406. #endif
  407. if( [obj respondsToSelector: sel] )
  408. return [obj performSelector: sel];
  409. #ifdef __clang__
  410. #pragma clang diagnostic pop
  411. #endif
  412. return nil;
  413. }
  414. #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
  415. #define CATCH_ARC_STRONG __strong
  416. #endif
  417. // end catch_objc_arc.hpp
  418. #endif
  419. #ifdef _MSC_VER
  420. #pragma warning(push)
  421. #pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
  422. #endif
  423. // We need a dummy global operator<< so we can bring it into Catch namespace later
  424. struct Catch_global_namespace_dummy;
  425. std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
  426. namespace Catch {
  427. // Bring in operator<< from global namespace into Catch namespace
  428. using ::operator<<;
  429. namespace Detail {
  430. extern const std::string unprintableString;
  431. std::string rawMemoryToString( const void *object, std::size_t size );
  432. template<typename T>
  433. std::string rawMemoryToString( const T& object ) {
  434. return rawMemoryToString( &object, sizeof(object) );
  435. }
  436. template<typename T>
  437. class IsStreamInsertable {
  438. template<typename SS, typename TT>
  439. static auto test(int)
  440. -> decltype(std::declval<SS&>() << std::declval<TT>(), std::true_type());
  441. template<typename, typename>
  442. static auto test(...)->std::false_type;
  443. public:
  444. static const bool value = decltype(test<std::ostream, const T&>(0))::value;
  445. };
  446. } // namespace Detail
  447. // If we decide for C++14, change these to enable_if_ts
  448. template <typename T>
  449. struct StringMaker {
  450. template <typename Fake = T>
  451. static
  452. typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
  453. convert(const Fake& t) {
  454. std::ostringstream sstr;
  455. sstr << t;
  456. return sstr.str();
  457. }
  458. template <typename Fake = T>
  459. static
  460. typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
  461. convert(const Fake&) {
  462. return Detail::unprintableString;
  463. }
  464. };
  465. namespace Detail {
  466. // This function dispatches all stringification requests inside of Catch.
  467. // Should be preferably called fully qualified, like ::Catch::Detail::stringify
  468. template <typename T>
  469. std::string stringify(const T& e) {
  470. return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
  471. }
  472. } // namespace Detail
  473. // Some predefined specializations
  474. template<>
  475. struct StringMaker<std::string> {
  476. static std::string convert(const std::string& str);
  477. };
  478. template<>
  479. struct StringMaker<std::wstring> {
  480. static std::string convert(const std::wstring& wstr);
  481. };
  482. template<>
  483. struct StringMaker<char const *> {
  484. static std::string convert(char const * str);
  485. };
  486. template<>
  487. struct StringMaker<char *> {
  488. static std::string convert(char * str);
  489. };
  490. template<>
  491. struct StringMaker<wchar_t const *> {
  492. static std::string convert(wchar_t const * str);
  493. };
  494. template<>
  495. struct StringMaker<wchar_t *> {
  496. static std::string convert(wchar_t * str);
  497. };
  498. template<int SZ>
  499. struct StringMaker<char[SZ]> {
  500. static std::string convert(const char* str) {
  501. return ::Catch::Detail::stringify(std::string{ str });
  502. }
  503. };
  504. template<int SZ>
  505. struct StringMaker<signed char[SZ]> {
  506. static std::string convert(const char* str) {
  507. return ::Catch::Detail::stringify(std::string{ str });
  508. }
  509. };
  510. template<int SZ>
  511. struct StringMaker<unsigned char[SZ]> {
  512. static std::string convert(const char* str) {
  513. return ::Catch::Detail::stringify(std::string{ str });
  514. }
  515. };
  516. template<>
  517. struct StringMaker<int> {
  518. static std::string convert(int value);
  519. };
  520. template<>
  521. struct StringMaker<long> {
  522. static std::string convert(long value);
  523. };
  524. template<>
  525. struct StringMaker<long long> {
  526. static std::string convert(long long value);
  527. };
  528. template<>
  529. struct StringMaker<unsigned int> {
  530. static std::string convert(unsigned int value);
  531. };
  532. template<>
  533. struct StringMaker<unsigned long> {
  534. static std::string convert(unsigned long value);
  535. };
  536. template<>
  537. struct StringMaker<unsigned long long> {
  538. static std::string convert(unsigned long long value);
  539. };
  540. template<>
  541. struct StringMaker<bool> {
  542. static std::string convert(bool b);
  543. };
  544. template<>
  545. struct StringMaker<char> {
  546. static std::string convert(char c);
  547. };
  548. template<>
  549. struct StringMaker<signed char> {
  550. static std::string convert(signed char c);
  551. };
  552. template<>
  553. struct StringMaker<unsigned char> {
  554. static std::string convert(unsigned char c);
  555. };
  556. template<>
  557. struct StringMaker<std::nullptr_t> {
  558. static std::string convert(std::nullptr_t);
  559. };
  560. template<>
  561. struct StringMaker<float> {
  562. static std::string convert(float value);
  563. };
  564. template<>
  565. struct StringMaker<double> {
  566. static std::string convert(double value);
  567. };
  568. template <typename T>
  569. struct StringMaker<T*> {
  570. template <typename U>
  571. static std::string convert(U* p) {
  572. if (p) {
  573. return ::Catch::Detail::rawMemoryToString(p);
  574. } else {
  575. return "nullptr";
  576. }
  577. }
  578. };
  579. template <typename R, typename C>
  580. struct StringMaker<R C::*> {
  581. static std::string convert(R C::* p) {
  582. if (p) {
  583. return ::Catch::Detail::rawMemoryToString(p);
  584. } else {
  585. return "nullptr";
  586. }
  587. }
  588. };
  589. namespace Detail {
  590. template<typename InputIterator>
  591. std::string rangeToString(InputIterator first, InputIterator last) {
  592. std::ostringstream oss;
  593. oss << "{ ";
  594. if (first != last) {
  595. oss << ::Catch::Detail::stringify(*first);
  596. for (++first; first != last; ++first)
  597. oss << ", " << ::Catch::Detail::stringify(*first);
  598. }
  599. oss << " }";
  600. return oss.str();
  601. }
  602. }
  603. template<typename T, typename Allocator>
  604. struct StringMaker<std::vector<T, Allocator> > {
  605. static std::string convert( std::vector<T,Allocator> const& v ) {
  606. return ::Catch::Detail::rangeToString( v.begin(), v.end() );
  607. }
  608. };
  609. template<typename T>
  610. struct EnumStringMaker {
  611. static std::string convert(const T& t) {
  612. return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<T>::type>(t));
  613. }
  614. };
  615. #ifdef __OBJC__
  616. template<>
  617. struct StringMaker<NSString*> {
  618. static std::string convert(NSString * nsstring) {
  619. if (!nsstring)
  620. return "nil";
  621. return std::string("@") + [nsstring UTF8String];
  622. }
  623. };
  624. template<>
  625. struct StringMaker<NSObject*> {
  626. static std::string convert(NSObject* nsObject) {
  627. return ::Catch::Detail::stringify([nsObject description]);
  628. }
  629. };
  630. namespace Detail {
  631. inline std::string stringify( NSString* nsstring ) {
  632. return StringMaker<NSString*>::convert( nsstring );
  633. }
  634. } // namespace Detail
  635. #endif // __OBJC__
  636. } // namespace Catch
  637. //////////////////////////////////////////////////////
  638. // Separate std-lib types stringification, so it can be selectively enabled
  639. // This means that we do not bring in
  640. #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
  641. # define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
  642. # define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
  643. # define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
  644. #endif
  645. // Separate std::pair specialization
  646. #if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
  647. #include <utility>
  648. namespace Catch {
  649. template<typename T1, typename T2>
  650. struct StringMaker<std::pair<T1, T2> > {
  651. static std::string convert(const std::pair<T1, T2>& pair) {
  652. std::ostringstream oss;
  653. oss << "{ "
  654. << ::Catch::Detail::stringify(pair.first)
  655. << ", "
  656. << ::Catch::Detail::stringify(pair.second)
  657. << " }";
  658. return oss.str();
  659. }
  660. };
  661. }
  662. #endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
  663. // Separate std::tuple specialization
  664. #if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
  665. #include <tuple>
  666. namespace Catch {
  667. namespace Detail {
  668. template<
  669. typename Tuple,
  670. std::size_t N = 0,
  671. bool = (N < std::tuple_size<Tuple>::value)
  672. >
  673. struct TupleElementPrinter {
  674. static void print(const Tuple& tuple, std::ostream& os) {
  675. os << (N ? ", " : " ")
  676. << ::Catch::Detail::stringify(std::get<N>(tuple));
  677. TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
  678. }
  679. };
  680. template<
  681. typename Tuple,
  682. std::size_t N
  683. >
  684. struct TupleElementPrinter<Tuple, N, false> {
  685. static void print(const Tuple&, std::ostream&) {}
  686. };
  687. }
  688. template<typename ...Types>
  689. struct StringMaker<std::tuple<Types...>> {
  690. static std::string convert(const std::tuple<Types...>& tuple) {
  691. std::ostringstream os;
  692. os << '{';
  693. Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, os);
  694. os << " }";
  695. return os.str();
  696. }
  697. };
  698. }
  699. #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
  700. // Separate std::chrono::duration specialization
  701. #if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
  702. #include <ctime>
  703. #include <ratio>
  704. #include <chrono>
  705. template <class Ratio>
  706. struct ratio_string {
  707. static std::string symbol();
  708. };
  709. template <class Ratio>
  710. std::string ratio_string<Ratio>::symbol() {
  711. std::ostringstream oss;
  712. oss << '[' << Ratio::num << '/'
  713. << Ratio::den << ']';
  714. return oss.str();
  715. }
  716. template <>
  717. struct ratio_string<std::atto> {
  718. static std::string symbol() { return "a"; }
  719. };
  720. template <>
  721. struct ratio_string<std::femto> {
  722. static std::string symbol() { return "f"; }
  723. };
  724. template <>
  725. struct ratio_string<std::pico> {
  726. static std::string symbol() { return "p"; }
  727. };
  728. template <>
  729. struct ratio_string<std::nano> {
  730. static std::string symbol() { return "n"; }
  731. };
  732. template <>
  733. struct ratio_string<std::micro> {
  734. static std::string symbol() { return "u"; }
  735. };
  736. template <>
  737. struct ratio_string<std::milli> {
  738. static std::string symbol() { return "m"; }
  739. };
  740. namespace Catch {
  741. ////////////
  742. // std::chrono::duration specializations
  743. template<typename Value, typename Ratio>
  744. struct StringMaker<std::chrono::duration<Value, Ratio>> {
  745. static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
  746. std::ostringstream oss;
  747. oss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
  748. return oss.str();
  749. }
  750. };
  751. template<typename Value>
  752. struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
  753. static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
  754. std::ostringstream oss;
  755. oss << duration.count() << " s";
  756. return oss.str();
  757. }
  758. };
  759. template<typename Value>
  760. struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
  761. static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
  762. std::ostringstream oss;
  763. oss << duration.count() << " m";
  764. return oss.str();
  765. }
  766. };
  767. template<typename Value>
  768. struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
  769. static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
  770. std::ostringstream oss;
  771. oss << duration.count() << " h";
  772. return oss.str();
  773. }
  774. };
  775. ////////////
  776. // std::chrono::time_point specialization
  777. // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
  778. template<typename Clock, typename Duration>
  779. struct StringMaker<std::chrono::time_point<Clock, Duration>> {
  780. static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
  781. return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
  782. }
  783. };
  784. // std::chrono::time_point<system_clock> specialization
  785. template<typename Duration>
  786. struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
  787. static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
  788. auto converted = std::chrono::system_clock::to_time_t(time_point);
  789. #ifdef _MSC_VER
  790. std::tm timeInfo = {};
  791. gmtime_s(&timeInfo, &converted);
  792. #else
  793. std::tm* timeInfo = std::gmtime(&converted);
  794. #endif
  795. auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
  796. char timeStamp[timeStampSize];
  797. const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
  798. #ifdef _MSC_VER
  799. std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
  800. #else
  801. std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
  802. #endif
  803. return std::string(timeStamp);
  804. }
  805. };
  806. }
  807. #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
  808. #ifdef _MSC_VER
  809. #pragma warning(pop)
  810. #endif
  811. // end catch_tostring.h
  812. #include <ostream>
  813. #ifdef _MSC_VER
  814. #pragma warning(push)
  815. #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
  816. #pragma warning(disable:4018) // more "signed/unsigned mismatch"
  817. #pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
  818. #pragma warning(disable:4180) // qualifier applied to function type has no meaning
  819. #endif
  820. namespace Catch {
  821. struct ITransientExpression {
  822. virtual auto isBinaryExpression() const -> bool = 0;
  823. virtual auto getResult() const -> bool = 0;
  824. virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
  825. // We don't actually need a virtual destructore, but many static analysers
  826. // complain if it's not here :-(
  827. virtual ~ITransientExpression();
  828. };
  829. void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
  830. template<typename LhsT, typename RhsT>
  831. class BinaryExpr : public ITransientExpression {
  832. bool m_result;
  833. LhsT m_lhs;
  834. StringRef m_op;
  835. RhsT m_rhs;
  836. auto isBinaryExpression() const -> bool override { return true; }
  837. auto getResult() const -> bool override { return m_result; }
  838. void streamReconstructedExpression( std::ostream &os ) const override {
  839. formatReconstructedExpression
  840. ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
  841. }
  842. public:
  843. BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
  844. : m_result( comparisonResult ),
  845. m_lhs( lhs ),
  846. m_op( op ),
  847. m_rhs( rhs )
  848. {}
  849. };
  850. template<typename LhsT>
  851. class UnaryExpr : public ITransientExpression {
  852. LhsT m_lhs;
  853. auto isBinaryExpression() const -> bool override { return false; }
  854. auto getResult() const -> bool override { return m_lhs ? true : false; }
  855. void streamReconstructedExpression( std::ostream &os ) const override {
  856. os << Catch::Detail::stringify( m_lhs );
  857. }
  858. public:
  859. UnaryExpr( LhsT lhs ) : m_lhs( lhs ) {}
  860. };
  861. // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
  862. template<typename LhsT, typename RhsT>
  863. auto compareEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return lhs == rhs; };
  864. template<typename T>
  865. auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
  866. template<typename T>
  867. auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
  868. template<typename T>
  869. auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
  870. template<typename T>
  871. auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
  872. template<typename LhsT, typename RhsT>
  873. auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return lhs != rhs; };
  874. template<typename T>
  875. auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
  876. template<typename T>
  877. auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
  878. template<typename T>
  879. auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
  880. template<typename T>
  881. auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
  882. template<typename LhsT>
  883. class ExprLhs {
  884. LhsT m_lhs;
  885. public:
  886. ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
  887. template<typename RhsT>
  888. auto operator == ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
  889. return BinaryExpr<LhsT, RhsT&>( compareEqual( m_lhs, rhs ), m_lhs, "==", rhs );
  890. }
  891. auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
  892. return BinaryExpr<LhsT, bool>( m_lhs == rhs, m_lhs, "==", rhs );
  893. }
  894. template<typename RhsT>
  895. auto operator != ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
  896. return BinaryExpr<LhsT, RhsT&>( compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs );
  897. }
  898. auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
  899. return BinaryExpr<LhsT, bool>( m_lhs != rhs, m_lhs, "!=", rhs );
  900. }
  901. template<typename RhsT>
  902. auto operator > ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
  903. return BinaryExpr<LhsT, RhsT&>( m_lhs > rhs, m_lhs, ">", rhs );
  904. }
  905. template<typename RhsT>
  906. auto operator < ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
  907. return BinaryExpr<LhsT, RhsT&>( m_lhs < rhs, m_lhs, "<", rhs );
  908. }
  909. template<typename RhsT>
  910. auto operator >= ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
  911. return BinaryExpr<LhsT, RhsT&>( m_lhs >= rhs, m_lhs, ">=", rhs );
  912. }
  913. template<typename RhsT>
  914. auto operator <= ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
  915. return BinaryExpr<LhsT, RhsT&>( m_lhs <= rhs, m_lhs, "<=", rhs );
  916. }
  917. auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
  918. return UnaryExpr<LhsT>( m_lhs );
  919. }
  920. };
  921. void handleExpression( ITransientExpression const& expr );
  922. template<typename T>
  923. void handleExpression( ExprLhs<T> const& expr ) {
  924. handleExpression( expr.makeUnaryExpr() );
  925. }
  926. struct Decomposer {
  927. template<typename T>
  928. auto operator <= ( T const& lhs ) -> ExprLhs<T const&> {
  929. return ExprLhs<T const&>( lhs );
  930. }
  931. auto operator <=( bool value ) -> ExprLhs<bool> {
  932. return ExprLhs<bool>( value );
  933. }
  934. };
  935. } // end namespace Catch
  936. // end catch_decomposer.h
  937. // start catch_assertioninfo.h
  938. // start catch_result_type.h
  939. namespace Catch {
  940. // ResultWas::OfType enum
  941. struct ResultWas { enum OfType {
  942. Unknown = -1,
  943. Ok = 0,
  944. Info = 1,
  945. Warning = 2,
  946. FailureBit = 0x10,
  947. ExpressionFailed = FailureBit | 1,
  948. ExplicitFailure = FailureBit | 2,
  949. Exception = 0x100 | FailureBit,
  950. ThrewException = Exception | 1,
  951. DidntThrowException = Exception | 2,
  952. FatalErrorCondition = 0x200 | FailureBit
  953. }; };
  954. bool isOk( ResultWas::OfType resultType );
  955. bool isJustInfo( int flags );
  956. // ResultDisposition::Flags enum
  957. struct ResultDisposition { enum Flags {
  958. Normal = 0x01,
  959. ContinueOnFailure = 0x02, // Failures fail test, but execution continues
  960. FalseTest = 0x04, // Prefix expression with !
  961. SuppressFail = 0x08 // Failures are reported but do not fail the test
  962. }; };
  963. ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs );
  964. bool shouldContinueOnFailure( int flags );
  965. bool isFalseTest( int flags );
  966. bool shouldSuppressFailure( int flags );
  967. } // end namespace Catch
  968. // end catch_result_type.h
  969. namespace Catch {
  970. struct AssertionInfo
  971. {
  972. StringRef macroName;
  973. SourceLineInfo lineInfo;
  974. StringRef capturedExpression;
  975. ResultDisposition::Flags resultDisposition;
  976. // We want to delete this constructor but a compiler bug in 4.8 means
  977. // the struct is then treated as non-aggregate
  978. //AssertionInfo() = delete;
  979. };
  980. } // end namespace Catch
  981. // end catch_assertioninfo.h
  982. namespace Catch {
  983. struct TestFailureException{};
  984. struct AssertionResultData;
  985. class LazyExpression {
  986. friend class AssertionHandler;
  987. friend struct AssertionStats;
  988. ITransientExpression const* m_transientExpression = nullptr;
  989. bool m_isNegated;
  990. public:
  991. LazyExpression( bool isNegated );
  992. LazyExpression( LazyExpression const& other );
  993. LazyExpression& operator = ( LazyExpression const& ) = delete;
  994. explicit operator bool() const;
  995. friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;
  996. };
  997. class AssertionHandler {
  998. AssertionInfo m_assertionInfo;
  999. bool m_shouldDebugBreak = false;
  1000. bool m_shouldThrow = false;
  1001. bool m_inExceptionGuard = false;
  1002. public:
  1003. AssertionHandler
  1004. ( StringRef macroName,
  1005. SourceLineInfo const& lineInfo,
  1006. StringRef capturedExpression,
  1007. ResultDisposition::Flags resultDisposition );
  1008. ~AssertionHandler();
  1009. void handle( ITransientExpression const& expr );
  1010. template<typename T>
  1011. void handle( ExprLhs<T> const& expr ) {
  1012. handle( expr.makeUnaryExpr() );
  1013. }
  1014. void handle( ResultWas::OfType resultType );
  1015. void handle( ResultWas::OfType resultType, StringRef const& message );
  1016. void handle( ResultWas::OfType resultType, ITransientExpression const* expr, bool negated );
  1017. void handle( AssertionResultData const& resultData, ITransientExpression const* expr );
  1018. auto shouldDebugBreak() const -> bool;
  1019. auto allowThrows() const -> bool;
  1020. void reactWithDebugBreak() const;
  1021. void reactWithoutDebugBreak() const;
  1022. void useActiveException();
  1023. void setExceptionGuard();
  1024. void unsetExceptionGuard();
  1025. };
  1026. void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef matcherString );
  1027. } // namespace Catch
  1028. // end catch_assertionhandler.h
  1029. // start catch_message.h
  1030. #include <string>
  1031. #include <sstream>
  1032. namespace Catch {
  1033. struct MessageInfo {
  1034. MessageInfo( std::string const& _macroName,
  1035. SourceLineInfo const& _lineInfo,
  1036. ResultWas::OfType _type );
  1037. std::string macroName;
  1038. std::string message;
  1039. SourceLineInfo lineInfo;
  1040. ResultWas::OfType type;
  1041. unsigned int sequence;
  1042. bool operator == ( MessageInfo const& other ) const;
  1043. bool operator < ( MessageInfo const& other ) const;
  1044. private:
  1045. static unsigned int globalCount;
  1046. };
  1047. struct MessageStream {
  1048. template<typename T>
  1049. MessageStream& operator << ( T const& value ) {
  1050. m_stream << value;
  1051. return *this;
  1052. }
  1053. // !TBD reuse a global/ thread-local stream
  1054. std::ostringstream m_stream;
  1055. };
  1056. struct MessageBuilder : MessageStream {
  1057. MessageBuilder( std::string const& macroName,
  1058. SourceLineInfo const& lineInfo,
  1059. ResultWas::OfType type );
  1060. template<typename T>
  1061. MessageBuilder& operator << ( T const& value ) {
  1062. m_stream << value;
  1063. return *this;
  1064. }
  1065. MessageInfo m_info;
  1066. };
  1067. class ScopedMessage {
  1068. public:
  1069. ScopedMessage( MessageBuilder const& builder );
  1070. ~ScopedMessage();
  1071. MessageInfo m_info;
  1072. };
  1073. } // end namespace Catch
  1074. // end catch_message.h
  1075. // start catch_interfaces_capture.h
  1076. #include <string>
  1077. namespace Catch {
  1078. class AssertionResult;
  1079. struct AssertionInfo;
  1080. struct SectionInfo;
  1081. struct SectionEndInfo;
  1082. struct MessageInfo;
  1083. struct Counts;
  1084. struct BenchmarkInfo;
  1085. struct BenchmarkStats;
  1086. struct IResultCapture {
  1087. virtual ~IResultCapture();
  1088. virtual void assertionStarting( AssertionInfo const& info ) = 0;
  1089. virtual void assertionEnded( AssertionResult const& result ) = 0;
  1090. virtual bool sectionStarted( SectionInfo const& sectionInfo,
  1091. Counts& assertions ) = 0;
  1092. virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
  1093. virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
  1094. virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
  1095. virtual void benchmarkEnded( BenchmarkStats const& stats ) = 0;
  1096. virtual void pushScopedMessage( MessageInfo const& message ) = 0;
  1097. virtual void popScopedMessage( MessageInfo const& message ) = 0;
  1098. virtual std::string getCurrentTestName() const = 0;
  1099. virtual const AssertionResult* getLastResult() const = 0;
  1100. virtual void exceptionEarlyReported() = 0;
  1101. virtual void handleFatalErrorCondition( StringRef message ) = 0;
  1102. virtual bool lastAssertionPassed() = 0;
  1103. virtual void assertionPassed() = 0;
  1104. virtual void assertionRun() = 0;
  1105. };
  1106. IResultCapture& getResultCapture();
  1107. }
  1108. // end catch_interfaces_capture.h
  1109. // start catch_debugger.h
  1110. namespace Catch {
  1111. bool isDebuggerActive();
  1112. }
  1113. #ifdef CATCH_PLATFORM_MAC
  1114. #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
  1115. #elif defined(CATCH_PLATFORM_LINUX)
  1116. // If we can use inline assembler, do it because this allows us to break
  1117. // directly at the location of the failing check instead of breaking inside
  1118. // raise() called from it, i.e. one stack frame below.
  1119. #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
  1120. #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
  1121. #else // Fall back to the generic way.
  1122. #include <signal.h>
  1123. #define CATCH_TRAP() raise(SIGTRAP)
  1124. #endif
  1125. #elif defined(_MSC_VER)
  1126. #define CATCH_TRAP() __debugbreak()
  1127. #elif defined(__MINGW32__)
  1128. extern "C" __declspec(dllimport) void __stdcall DebugBreak();
  1129. #define CATCH_TRAP() DebugBreak()
  1130. #endif
  1131. #ifdef CATCH_TRAP
  1132. #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); }
  1133. #else
  1134. #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
  1135. #endif
  1136. // end catch_debugger.h
  1137. #if !defined(CATCH_CONFIG_DISABLE)
  1138. #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
  1139. #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
  1140. #else
  1141. #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
  1142. #endif
  1143. #if defined(CATCH_CONFIG_FAST_COMPILE)
  1144. ///////////////////////////////////////////////////////////////////////////////
  1145. // We can speedup compilation significantly by breaking into debugger lower in
  1146. // the callstack, because then we don't have to expand CATCH_BREAK_INTO_DEBUGGER
  1147. // macro in each assertion
  1148. #define INTERNAL_CATCH_REACT( handler ) \
  1149. handler.reactWithDebugBreak();
  1150. ///////////////////////////////////////////////////////////////////////////////
  1151. // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
  1152. // macros.
  1153. // This can potentially cause false negative, if the test code catches
  1154. // the exception before it propagates back up to the runner.
  1155. #define INTERNAL_CATCH_TRY( capturer ) capturer.setExceptionGuard();
  1156. #define INTERNAL_CATCH_CATCH( capturer ) capturer.unsetExceptionGuard();
  1157. #else // CATCH_CONFIG_FAST_COMPILE
  1158. ///////////////////////////////////////////////////////////////////////////////
  1159. // In the event of a failure works out if the debugger needs to be invoked
  1160. // and/or an exception thrown and takes appropriate action.
  1161. // This needs to be done as a macro so the debugger will stop in the user
  1162. // source code rather than in Catch library code
  1163. #define INTERNAL_CATCH_REACT( handler ) \
  1164. if( handler.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
  1165. handler.reactWithoutDebugBreak();
  1166. #define INTERNAL_CATCH_TRY( capturer ) try
  1167. #define INTERNAL_CATCH_CATCH( capturer ) catch(...) { capturer.useActiveException(); }
  1168. #endif
  1169. ///////////////////////////////////////////////////////////////////////////////
  1170. #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
  1171. do { \
  1172. Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
  1173. INTERNAL_CATCH_TRY( catchAssertionHandler ) { \
  1174. CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
  1175. catchAssertionHandler.handle( Catch::Decomposer() <= __VA_ARGS__ ); \
  1176. CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
  1177. } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
  1178. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  1179. } while( Catch::isTrue( false && static_cast<bool>( !!(__VA_ARGS__) ) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look
  1180. // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
  1181. ///////////////////////////////////////////////////////////////////////////////
  1182. #define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
  1183. INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
  1184. if( Catch::getResultCapture().lastAssertionPassed() )
  1185. ///////////////////////////////////////////////////////////////////////////////
  1186. #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
  1187. INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
  1188. if( !Catch::getResultCapture().lastAssertionPassed() )
  1189. ///////////////////////////////////////////////////////////////////////////////
  1190. #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
  1191. do { \
  1192. Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
  1193. try { \
  1194. static_cast<void>(__VA_ARGS__); \
  1195. catchAssertionHandler.handle( Catch::ResultWas::Ok ); \
  1196. } \
  1197. catch( ... ) { \
  1198. catchAssertionHandler.useActiveException(); \
  1199. } \
  1200. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  1201. } while( Catch::alwaysFalse() )
  1202. ///////////////////////////////////////////////////////////////////////////////
  1203. #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
  1204. do { \
  1205. Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
  1206. if( catchAssertionHandler.allowThrows() ) \
  1207. try { \
  1208. static_cast<void>(__VA_ARGS__); \
  1209. catchAssertionHandler.handle( Catch::ResultWas::DidntThrowException ); \
  1210. } \
  1211. catch( ... ) { \
  1212. catchAssertionHandler.handle( Catch::ResultWas::Ok ); \
  1213. } \
  1214. else \
  1215. catchAssertionHandler.handle( Catch::ResultWas::Ok ); \
  1216. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  1217. } while( Catch::alwaysFalse() )
  1218. ///////////////////////////////////////////////////////////////////////////////
  1219. #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
  1220. do { \
  1221. Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
  1222. if( catchAssertionHandler.allowThrows() ) \
  1223. try { \
  1224. static_cast<void>(expr); \
  1225. catchAssertionHandler.handle( Catch::ResultWas::DidntThrowException ); \
  1226. } \
  1227. catch( exceptionType const& ) { \
  1228. catchAssertionHandler.handle( Catch::ResultWas::Ok ); \
  1229. } \
  1230. catch( ... ) { \
  1231. catchAssertionHandler.useActiveException(); \
  1232. } \
  1233. else \
  1234. catchAssertionHandler.handle( Catch::ResultWas::Ok ); \
  1235. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  1236. } while( Catch::alwaysFalse() )
  1237. ///////////////////////////////////////////////////////////////////////////////
  1238. #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
  1239. do { \
  1240. Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
  1241. catchAssertionHandler.handle( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
  1242. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  1243. } while( Catch::alwaysFalse() )
  1244. ///////////////////////////////////////////////////////////////////////////////
  1245. #define INTERNAL_CATCH_INFO( macroName, log ) \
  1246. Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
  1247. ///////////////////////////////////////////////////////////////////////////////
  1248. // Although this is matcher-based, it can be used with just a string
  1249. #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
  1250. do { \
  1251. Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
  1252. if( catchAssertionHandler.allowThrows() ) \
  1253. try { \
  1254. static_cast<void>(__VA_ARGS__); \
  1255. catchAssertionHandler.handle( Catch::ResultWas::DidntThrowException ); \
  1256. } \
  1257. catch( ... ) { \
  1258. handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher ); \
  1259. } \
  1260. else \
  1261. catchAssertionHandler.handle( Catch::ResultWas::Ok ); \
  1262. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  1263. } while( Catch::alwaysFalse() )
  1264. #endif // CATCH_CONFIG_DISABLE
  1265. // end catch_capture.hpp
  1266. // start catch_section.h
  1267. // start catch_section_info.h
  1268. // start catch_totals.h
  1269. #include <cstddef>
  1270. namespace Catch {
  1271. struct Counts {
  1272. Counts operator - ( Counts const& other ) const;
  1273. Counts& operator += ( Counts const& other );
  1274. std::size_t total() const;
  1275. bool allPassed() const;
  1276. bool allOk() const;
  1277. std::size_t passed = 0;
  1278. std::size_t failed = 0;
  1279. std::size_t failedButOk = 0;
  1280. };
  1281. struct Totals {
  1282. Totals operator - ( Totals const& other ) const;
  1283. Totals& operator += ( Totals const& other );
  1284. Totals delta( Totals const& prevTotals ) const;
  1285. Counts assertions;
  1286. Counts testCases;
  1287. };
  1288. }
  1289. // end catch_totals.h
  1290. #include <string>
  1291. namespace Catch {
  1292. struct SectionInfo {
  1293. SectionInfo
  1294. ( SourceLineInfo const& _lineInfo,
  1295. std::string const& _name,
  1296. std::string const& _description = std::string() );
  1297. std::string name;
  1298. std::string description;
  1299. SourceLineInfo lineInfo;
  1300. };
  1301. struct SectionEndInfo {
  1302. SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds );
  1303. SectionInfo sectionInfo;
  1304. Counts prevAssertions;
  1305. double durationInSeconds;
  1306. };
  1307. } // end namespace Catch
  1308. // end catch_section_info.h
  1309. // start catch_timer.h
  1310. #include <cstdint>
  1311. namespace Catch {
  1312. auto getCurrentNanosecondsSinceEpoch() -> uint64_t;
  1313. auto getEstimatedClockResolution() -> uint64_t;
  1314. class Timer {
  1315. uint64_t m_nanoseconds = 0;
  1316. public:
  1317. void start();
  1318. auto getElapsedNanoseconds() const -> unsigned int;
  1319. auto getElapsedMicroseconds() const -> unsigned int;
  1320. auto getElapsedMilliseconds() const -> unsigned int;
  1321. auto getElapsedSeconds() const -> double;
  1322. };
  1323. } // namespace Catch
  1324. // end catch_timer.h
  1325. #include <string>
  1326. namespace Catch {
  1327. class Section : NonCopyable {
  1328. public:
  1329. Section( SectionInfo const& info );
  1330. ~Section();
  1331. // This indicates whether the section should be executed or not
  1332. explicit operator bool() const;
  1333. private:
  1334. SectionInfo m_info;
  1335. std::string m_name;
  1336. Counts m_assertions;
  1337. bool m_sectionIncluded;
  1338. Timer m_timer;
  1339. };
  1340. } // end namespace Catch
  1341. #define INTERNAL_CATCH_SECTION( ... ) \
  1342. if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
  1343. // end catch_section.h
  1344. // start catch_benchmark.h
  1345. #include <cstdint>
  1346. #include <string>
  1347. namespace Catch {
  1348. class BenchmarkLooper {
  1349. std::string m_name;
  1350. std::size_t m_count = 0;
  1351. std::size_t m_iterationsToRun = 1;
  1352. uint64_t m_resolution;
  1353. Timer m_timer;
  1354. static auto getResolution() -> uint64_t;
  1355. public:
  1356. // Keep most of this inline as it's on the code path that is being timed
  1357. BenchmarkLooper( StringRef name )
  1358. : m_name( name ),
  1359. m_resolution( getResolution() )
  1360. {
  1361. reportStart();
  1362. m_timer.start();
  1363. }
  1364. explicit operator bool() {
  1365. if( m_count < m_iterationsToRun )
  1366. return true;
  1367. return needsMoreIterations();
  1368. }
  1369. void increment() {
  1370. ++m_count;
  1371. }
  1372. void reportStart();
  1373. auto needsMoreIterations() -> bool;
  1374. };
  1375. } // end namespace Catch
  1376. #define BENCHMARK( name ) \
  1377. for( Catch::BenchmarkLooper looper( name ); looper; looper.increment() )
  1378. // end catch_benchmark.h
  1379. // start catch_interfaces_exception.h
  1380. // start catch_interfaces_registry_hub.h
  1381. #include <string>
  1382. #include <memory>
  1383. namespace Catch {
  1384. class TestCase;
  1385. struct ITestCaseRegistry;
  1386. struct IExceptionTranslatorRegistry;
  1387. struct IExceptionTranslator;
  1388. struct IReporterRegistry;
  1389. struct IReporterFactory;
  1390. struct ITagAliasRegistry;
  1391. class StartupExceptionRegistry;
  1392. using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
  1393. struct IRegistryHub {
  1394. virtual ~IRegistryHub();
  1395. virtual IReporterRegistry const& getReporterRegistry() const = 0;
  1396. virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
  1397. virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
  1398. virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
  1399. virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
  1400. };
  1401. struct IMutableRegistryHub {
  1402. virtual ~IMutableRegistryHub();
  1403. virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0;
  1404. virtual void registerListener( IReporterFactoryPtr const& factory ) = 0;
  1405. virtual void registerTest( TestCase const& testInfo ) = 0;
  1406. virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
  1407. virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
  1408. virtual void registerStartupException() noexcept = 0;
  1409. };
  1410. IRegistryHub& getRegistryHub();
  1411. IMutableRegistryHub& getMutableRegistryHub();
  1412. void cleanUp();
  1413. std::string translateActiveException();
  1414. }
  1415. // end catch_interfaces_registry_hub.h
  1416. #if defined(CATCH_CONFIG_DISABLE)
  1417. #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \
  1418. static std::string translatorName( signature )
  1419. #endif
  1420. #include <exception>
  1421. #include <string>
  1422. #include <vector>
  1423. namespace Catch {
  1424. using exceptionTranslateFunction = std::string(*)();
  1425. struct IExceptionTranslator;
  1426. using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;
  1427. struct IExceptionTranslator {
  1428. virtual ~IExceptionTranslator();
  1429. virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
  1430. };
  1431. struct IExceptionTranslatorRegistry {
  1432. virtual ~IExceptionTranslatorRegistry();
  1433. virtual std::string translateActiveException() const = 0;
  1434. };
  1435. class ExceptionTranslatorRegistrar {
  1436. template<typename T>
  1437. class ExceptionTranslator : public IExceptionTranslator {
  1438. public:
  1439. ExceptionTranslator( std::string(*translateFunction)( T& ) )
  1440. : m_translateFunction( translateFunction )
  1441. {}
  1442. std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override {
  1443. try {
  1444. if( it == itEnd )
  1445. std::rethrow_exception(std::current_exception());
  1446. else
  1447. return (*it)->translate( it+1, itEnd );
  1448. }
  1449. catch( T& ex ) {
  1450. return m_translateFunction( ex );
  1451. }
  1452. }
  1453. protected:
  1454. std::string(*m_translateFunction)( T& );
  1455. };
  1456. public:
  1457. template<typename T>
  1458. ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
  1459. getMutableRegistryHub().registerTranslator
  1460. ( new ExceptionTranslator<T>( translateFunction ) );
  1461. }
  1462. };
  1463. }
  1464. ///////////////////////////////////////////////////////////////////////////////
  1465. #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
  1466. static std::string translatorName( signature ); \
  1467. namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\
  1468. static std::string translatorName( signature )
  1469. #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
  1470. // end catch_interfaces_exception.h
  1471. // start catch_approx.h
  1472. #include <cmath>
  1473. #include <type_traits>
  1474. namespace Catch {
  1475. namespace Detail {
  1476. double max(double lhs, double rhs);
  1477. class Approx {
  1478. public:
  1479. explicit Approx ( double value );
  1480. static Approx custom();
  1481. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1482. Approx operator()( T const& value ) {
  1483. Approx approx( static_cast<double>(value) );
  1484. approx.epsilon( m_epsilon );
  1485. approx.margin( m_margin );
  1486. approx.scale( m_scale );
  1487. return approx;
  1488. }
  1489. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1490. explicit Approx( T const& value ): Approx(static_cast<double>(value))
  1491. {}
  1492. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1493. friend bool operator == ( const T& lhs, Approx const& rhs ) {
  1494. // Thanks to Richard Harris for his help refining this formula
  1495. auto lhs_v = static_cast<double>(lhs);
  1496. bool relativeOK = std::fabs(lhs_v - rhs.m_value) < rhs.m_epsilon * (rhs.m_scale + (max)(std::fabs(lhs_v), std::fabs(rhs.m_value)));
  1497. if (relativeOK) {
  1498. return true;
  1499. }
  1500. return std::fabs(lhs_v - rhs.m_value) < rhs.m_margin;
  1501. }
  1502. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1503. friend bool operator == ( Approx const& lhs, const T& rhs ) {
  1504. return operator==( rhs, lhs );
  1505. }
  1506. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1507. friend bool operator != ( T const& lhs, Approx const& rhs ) {
  1508. return !operator==( lhs, rhs );
  1509. }
  1510. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1511. friend bool operator != ( Approx const& lhs, T const& rhs ) {
  1512. return !operator==( rhs, lhs );
  1513. }
  1514. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1515. friend bool operator <= ( T const& lhs, Approx const& rhs ) {
  1516. return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
  1517. }
  1518. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1519. friend bool operator <= ( Approx const& lhs, T const& rhs ) {
  1520. return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
  1521. }
  1522. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1523. friend bool operator >= ( T const& lhs, Approx const& rhs ) {
  1524. return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
  1525. }
  1526. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1527. friend bool operator >= ( Approx const& lhs, T const& rhs ) {
  1528. return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
  1529. }
  1530. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1531. Approx& epsilon( T const& newEpsilon ) {
  1532. m_epsilon = static_cast<double>(newEpsilon);
  1533. return *this;
  1534. }
  1535. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1536. Approx& margin( T const& newMargin ) {
  1537. m_margin = static_cast<double>(newMargin);
  1538. return *this;
  1539. }
  1540. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1541. Approx& scale( T const& newScale ) {
  1542. m_scale = static_cast<double>(newScale);
  1543. return *this;
  1544. }
  1545. std::string toString() const;
  1546. private:
  1547. double m_epsilon;
  1548. double m_margin;
  1549. double m_scale;
  1550. double m_value;
  1551. };
  1552. }
  1553. template<>
  1554. struct StringMaker<Catch::Detail::Approx> {
  1555. static std::string convert(Catch::Detail::Approx const& value);
  1556. };
  1557. } // end namespace Catch
  1558. // end catch_approx.h
  1559. // start catch_string_manip.h
  1560. #include <string>
  1561. #include <iosfwd>
  1562. namespace Catch {
  1563. bool startsWith( std::string const& s, std::string const& prefix );
  1564. bool startsWith( std::string const& s, char prefix );
  1565. bool endsWith( std::string const& s, std::string const& suffix );
  1566. bool endsWith( std::string const& s, char suffix );
  1567. bool contains( std::string const& s, std::string const& infix );
  1568. void toLowerInPlace( std::string& s );
  1569. std::string toLower( std::string const& s );
  1570. std::string trim( std::string const& str );
  1571. bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
  1572. struct pluralise {
  1573. pluralise( std::size_t count, std::string const& label );
  1574. friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
  1575. std::size_t m_count;
  1576. std::string m_label;
  1577. };
  1578. }
  1579. // end catch_string_manip.h
  1580. #ifndef CATCH_CONFIG_DISABLE_MATCHERS
  1581. // start catch_capture_matchers.h
  1582. // start catch_matchers.h
  1583. #include <string>
  1584. #include <vector>
  1585. namespace Catch {
  1586. namespace Matchers {
  1587. namespace Impl {
  1588. template<typename ArgT> struct MatchAllOf;
  1589. template<typename ArgT> struct MatchAnyOf;
  1590. template<typename ArgT> struct MatchNotOf;
  1591. class MatcherUntypedBase {
  1592. public:
  1593. MatcherUntypedBase() = default;
  1594. MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
  1595. MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete;
  1596. std::string toString() const;
  1597. protected:
  1598. virtual ~MatcherUntypedBase();
  1599. virtual std::string describe() const = 0;
  1600. mutable std::string m_cachedToString;
  1601. };
  1602. template<typename ObjectT>
  1603. struct MatcherMethod {
  1604. virtual bool match( ObjectT const& arg ) const = 0;
  1605. };
  1606. template<typename PtrT>
  1607. struct MatcherMethod<PtrT*> {
  1608. virtual bool match( PtrT* arg ) const = 0;
  1609. };
  1610. template<typename ObjectT, typename ComparatorT = ObjectT>
  1611. struct MatcherBase : MatcherUntypedBase, MatcherMethod<ObjectT> {
  1612. MatchAllOf<ComparatorT> operator && ( MatcherBase const& other ) const;
  1613. MatchAnyOf<ComparatorT> operator || ( MatcherBase const& other ) const;
  1614. MatchNotOf<ComparatorT> operator ! () const;
  1615. };
  1616. template<typename ArgT>
  1617. struct MatchAllOf : MatcherBase<ArgT> {
  1618. bool match( ArgT const& arg ) const override {
  1619. for( auto matcher : m_matchers ) {
  1620. if (!matcher->match(arg))
  1621. return false;
  1622. }
  1623. return true;
  1624. }
  1625. std::string describe() const override {
  1626. std::string description;
  1627. description.reserve( 4 + m_matchers.size()*32 );
  1628. description += "( ";
  1629. bool first = true;
  1630. for( auto matcher : m_matchers ) {
  1631. if( first )
  1632. first = false;
  1633. else
  1634. description += " and ";
  1635. description += matcher->toString();
  1636. }
  1637. description += " )";
  1638. return description;
  1639. }
  1640. MatchAllOf<ArgT>& operator && ( MatcherBase<ArgT> const& other ) {
  1641. m_matchers.push_back( &other );
  1642. return *this;
  1643. }
  1644. std::vector<MatcherBase<ArgT> const*> m_matchers;
  1645. };
  1646. template<typename ArgT>
  1647. struct MatchAnyOf : MatcherBase<ArgT> {
  1648. bool match( ArgT const& arg ) const override {
  1649. for( auto matcher : m_matchers ) {
  1650. if (matcher->match(arg))
  1651. return true;
  1652. }
  1653. return false;
  1654. }
  1655. std::string describe() const override {
  1656. std::string description;
  1657. description.reserve( 4 + m_matchers.size()*32 );
  1658. description += "( ";
  1659. bool first = true;
  1660. for( auto matcher : m_matchers ) {
  1661. if( first )
  1662. first = false;
  1663. else
  1664. description += " or ";
  1665. description += matcher->toString();
  1666. }
  1667. description += " )";
  1668. return description;
  1669. }
  1670. MatchAnyOf<ArgT>& operator || ( MatcherBase<ArgT> const& other ) {
  1671. m_matchers.push_back( &other );
  1672. return *this;
  1673. }
  1674. std::vector<MatcherBase<ArgT> const*> m_matchers;
  1675. };
  1676. template<typename ArgT>
  1677. struct MatchNotOf : MatcherBase<ArgT> {
  1678. MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
  1679. bool match( ArgT const& arg ) const override {
  1680. return !m_underlyingMatcher.match( arg );
  1681. }
  1682. std::string describe() const override {
  1683. return "not " + m_underlyingMatcher.toString();
  1684. }
  1685. MatcherBase<ArgT> const& m_underlyingMatcher;
  1686. };
  1687. template<typename ObjectT, typename ComparatorT>
  1688. MatchAllOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator && ( MatcherBase const& other ) const {
  1689. return MatchAllOf<ComparatorT>() && *this && other;
  1690. }
  1691. template<typename ObjectT, typename ComparatorT>
  1692. MatchAnyOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator || ( MatcherBase const& other ) const {
  1693. return MatchAnyOf<ComparatorT>() || *this || other;
  1694. }
  1695. template<typename ObjectT, typename ComparatorT>
  1696. MatchNotOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator ! () const {
  1697. return MatchNotOf<ComparatorT>( *this );
  1698. }
  1699. } // namespace Impl
  1700. } // namespace Matchers
  1701. using namespace Matchers;
  1702. using Matchers::Impl::MatcherBase;
  1703. } // namespace Catch
  1704. // end catch_matchers.h
  1705. // start catch_matchers_string.h
  1706. #include <string>
  1707. namespace Catch {
  1708. namespace Matchers {
  1709. namespace StdString {
  1710. struct CasedString
  1711. {
  1712. CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );
  1713. std::string adjustString( std::string const& str ) const;
  1714. std::string caseSensitivitySuffix() const;
  1715. CaseSensitive::Choice m_caseSensitivity;
  1716. std::string m_str;
  1717. };
  1718. struct StringMatcherBase : MatcherBase<std::string> {
  1719. StringMatcherBase( std::string const& operation, CasedString const& comparator );
  1720. std::string describe() const override;
  1721. CasedString m_comparator;
  1722. std::string m_operation;
  1723. };
  1724. struct EqualsMatcher : StringMatcherBase {
  1725. EqualsMatcher( CasedString const& comparator );
  1726. bool match( std::string const& source ) const override;
  1727. };
  1728. struct ContainsMatcher : StringMatcherBase {
  1729. ContainsMatcher( CasedString const& comparator );
  1730. bool match( std::string const& source ) const override;
  1731. };
  1732. struct StartsWithMatcher : StringMatcherBase {
  1733. StartsWithMatcher( CasedString const& comparator );
  1734. bool match( std::string const& source ) const override;
  1735. };
  1736. struct EndsWithMatcher : StringMatcherBase {
  1737. EndsWithMatcher( CasedString const& comparator );
  1738. bool match( std::string const& source ) const override;
  1739. };
  1740. } // namespace StdString
  1741. // The following functions create the actual matcher objects.
  1742. // This allows the types to be inferred
  1743. StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
  1744. StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
  1745. StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
  1746. StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
  1747. } // namespace Matchers
  1748. } // namespace Catch
  1749. // end catch_matchers_string.h
  1750. // start catch_matchers_vector.h
  1751. namespace Catch {
  1752. namespace Matchers {
  1753. namespace Vector {
  1754. template<typename T>
  1755. struct ContainsElementMatcher : MatcherBase<std::vector<T>, T> {
  1756. ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
  1757. bool match(std::vector<T> const &v) const override {
  1758. for (auto const& el : v) {
  1759. if (el == m_comparator) {
  1760. return true;
  1761. }
  1762. }
  1763. return false;
  1764. }
  1765. std::string describe() const override {
  1766. return "Contains: " + ::Catch::Detail::stringify( m_comparator );
  1767. }
  1768. T const& m_comparator;
  1769. };
  1770. template<typename T>
  1771. struct ContainsMatcher : MatcherBase<std::vector<T>, std::vector<T> > {
  1772. ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
  1773. bool match(std::vector<T> const &v) const override {
  1774. // !TBD: see note in EqualsMatcher
  1775. if (m_comparator.size() > v.size())
  1776. return false;
  1777. for (auto const& comparator : m_comparator) {
  1778. auto present = false;
  1779. for (const auto& el : v) {
  1780. if (el == comparator) {
  1781. present = true;
  1782. break;
  1783. }
  1784. }
  1785. if (!present) {
  1786. return false;
  1787. }
  1788. }
  1789. return true;
  1790. }
  1791. std::string describe() const override {
  1792. return "Contains: " + ::Catch::Detail::stringify( m_comparator );
  1793. }
  1794. std::vector<T> const& m_comparator;
  1795. };
  1796. template<typename T>
  1797. struct EqualsMatcher : MatcherBase<std::vector<T>, std::vector<T> > {
  1798. EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
  1799. bool match(std::vector<T> const &v) const override {
  1800. // !TBD: This currently works if all elements can be compared using !=
  1801. // - a more general approach would be via a compare template that defaults
  1802. // to using !=. but could be specialised for, e.g. std::vector<T> etc
  1803. // - then just call that directly
  1804. if (m_comparator.size() != v.size())
  1805. return false;
  1806. for (std::size_t i = 0; i < v.size(); ++i)
  1807. if (m_comparator[i] != v[i])
  1808. return false;
  1809. return true;
  1810. }
  1811. std::string describe() const override {
  1812. return "Equals: " + ::Catch::Detail::stringify( m_comparator );
  1813. }
  1814. std::vector<T> const& m_comparator;
  1815. };
  1816. } // namespace Vector
  1817. // The following functions create the actual matcher objects.
  1818. // This allows the types to be inferred
  1819. template<typename T>
  1820. Vector::ContainsMatcher<T> Contains( std::vector<T> const& comparator ) {
  1821. return Vector::ContainsMatcher<T>( comparator );
  1822. }
  1823. template<typename T>
  1824. Vector::ContainsElementMatcher<T> VectorContains( T const& comparator ) {
  1825. return Vector::ContainsElementMatcher<T>( comparator );
  1826. }
  1827. template<typename T>
  1828. Vector::EqualsMatcher<T> Equals( std::vector<T> const& comparator ) {
  1829. return Vector::EqualsMatcher<T>( comparator );
  1830. }
  1831. } // namespace Matchers
  1832. } // namespace Catch
  1833. // end catch_matchers_vector.h
  1834. namespace Catch {
  1835. template<typename ArgT, typename MatcherT>
  1836. class MatchExpr : public ITransientExpression {
  1837. ArgT const& m_arg;
  1838. MatcherT m_matcher;
  1839. StringRef m_matcherString;
  1840. bool m_result;
  1841. public:
  1842. MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef matcherString )
  1843. : m_arg( arg ),
  1844. m_matcher( matcher ),
  1845. m_matcherString( matcherString ),
  1846. m_result( matcher.match( arg ) )
  1847. {}
  1848. auto isBinaryExpression() const -> bool override { return true; }
  1849. auto getResult() const -> bool override { return m_result; }
  1850. void streamReconstructedExpression( std::ostream &os ) const override {
  1851. auto matcherAsString = m_matcher.toString();
  1852. os << Catch::Detail::stringify( m_arg ) << ' ';
  1853. if( matcherAsString == Detail::unprintableString )
  1854. os << m_matcherString;
  1855. else
  1856. os << matcherAsString;
  1857. }
  1858. };
  1859. using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
  1860. void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString );
  1861. template<typename ArgT, typename MatcherT>
  1862. auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef matcherString ) -> MatchExpr<ArgT, MatcherT> {
  1863. return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
  1864. }
  1865. } // namespace Catch
  1866. ///////////////////////////////////////////////////////////////////////////////
  1867. #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
  1868. do { \
  1869. Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
  1870. INTERNAL_CATCH_TRY( catchAssertionHandler ) { \
  1871. catchAssertionHandler.handle( Catch::makeMatchExpr( arg, matcher, #matcher ) ); \
  1872. } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
  1873. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  1874. } while( Catch::alwaysFalse() )
  1875. ///////////////////////////////////////////////////////////////////////////////
  1876. #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
  1877. do { \
  1878. Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
  1879. if( catchAssertionHandler.allowThrows() ) \
  1880. try { \
  1881. static_cast<void>(__VA_ARGS__ ); \
  1882. catchAssertionHandler.handle( Catch::ResultWas::DidntThrowException ); \
  1883. } \
  1884. catch( exceptionType const& ex ) { \
  1885. catchAssertionHandler.handle( Catch::makeMatchExpr( ex, matcher, #matcher ) ); \
  1886. } \
  1887. catch( ... ) { \
  1888. catchAssertionHandler.useActiveException(); \
  1889. } \
  1890. else \
  1891. catchAssertionHandler.handle( Catch::ResultWas::Ok ); \
  1892. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  1893. } while( Catch::alwaysFalse() )
  1894. // end catch_capture_matchers.h
  1895. #endif
  1896. // These files are included here so the single_include script doesn't put them
  1897. // in the conditionally compiled sections
  1898. // start catch_test_case_info.h
  1899. #include <string>
  1900. #include <vector>
  1901. #include <memory>
  1902. #ifdef __clang__
  1903. #pragma clang diagnostic push
  1904. #pragma clang diagnostic ignored "-Wpadded"
  1905. #endif
  1906. namespace Catch {
  1907. struct ITestInvoker;
  1908. struct TestCaseInfo {
  1909. enum SpecialProperties{
  1910. None = 0,
  1911. IsHidden = 1 << 1,
  1912. ShouldFail = 1 << 2,
  1913. MayFail = 1 << 3,
  1914. Throws = 1 << 4,
  1915. NonPortable = 1 << 5,
  1916. Benchmark = 1 << 6
  1917. };
  1918. TestCaseInfo( std::string const& _name,
  1919. std::string const& _className,
  1920. std::string const& _description,
  1921. std::vector<std::string> const& _tags,
  1922. SourceLineInfo const& _lineInfo );
  1923. friend void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags );
  1924. bool isHidden() const;
  1925. bool throws() const;
  1926. bool okToFail() const;
  1927. bool expectedToFail() const;
  1928. std::string tagsAsString() const;
  1929. std::string name;
  1930. std::string className;
  1931. std::string description;
  1932. std::vector<std::string> tags;
  1933. std::vector<std::string> lcaseTags;
  1934. SourceLineInfo lineInfo;
  1935. SpecialProperties properties;
  1936. };
  1937. class TestCase : public TestCaseInfo {
  1938. public:
  1939. TestCase( ITestInvoker* testCase, TestCaseInfo const& info );
  1940. TestCase withName( std::string const& _newName ) const;
  1941. void invoke() const;
  1942. TestCaseInfo const& getTestCaseInfo() const;
  1943. bool operator == ( TestCase const& other ) const;
  1944. bool operator < ( TestCase const& other ) const;
  1945. private:
  1946. std::shared_ptr<ITestInvoker> test;
  1947. };
  1948. TestCase makeTestCase( ITestInvoker* testCase,
  1949. std::string const& className,
  1950. std::string const& name,
  1951. std::string const& description,
  1952. SourceLineInfo const& lineInfo );
  1953. }
  1954. #ifdef __clang__
  1955. #pragma clang diagnostic pop
  1956. #endif
  1957. // end catch_test_case_info.h
  1958. // start catch_interfaces_runner.h
  1959. namespace Catch {
  1960. struct IRunner {
  1961. virtual ~IRunner();
  1962. virtual bool aborting() const = 0;
  1963. };
  1964. }
  1965. // end catch_interfaces_runner.h
  1966. #ifdef __OBJC__
  1967. // start catch_objc.hpp
  1968. #import <objc/runtime.h>
  1969. #include <string>
  1970. // NB. Any general catch headers included here must be included
  1971. // in catch.hpp first to make sure they are included by the single
  1972. // header for non obj-usage
  1973. ///////////////////////////////////////////////////////////////////////////////
  1974. // This protocol is really only here for (self) documenting purposes, since
  1975. // all its methods are optional.
  1976. @protocol OcFixture
  1977. @optional
  1978. -(void) setUp;
  1979. -(void) tearDown;
  1980. @end
  1981. namespace Catch {
  1982. class OcMethod : public ITestInvoker {
  1983. public:
  1984. OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
  1985. virtual void invoke() const {
  1986. id obj = [[m_cls alloc] init];
  1987. performOptionalSelector( obj, @selector(setUp) );
  1988. performOptionalSelector( obj, m_sel );
  1989. performOptionalSelector( obj, @selector(tearDown) );
  1990. arcSafeRelease( obj );
  1991. }
  1992. private:
  1993. virtual ~OcMethod() {}
  1994. Class m_cls;
  1995. SEL m_sel;
  1996. };
  1997. namespace Detail{
  1998. inline std::string getAnnotation( Class cls,
  1999. std::string const& annotationName,
  2000. std::string const& testCaseName ) {
  2001. NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
  2002. SEL sel = NSSelectorFromString( selStr );
  2003. arcSafeRelease( selStr );
  2004. id value = performOptionalSelector( cls, sel );
  2005. if( value )
  2006. return [(NSString*)value UTF8String];
  2007. return "";
  2008. }
  2009. }
  2010. inline std::size_t registerTestMethods() {
  2011. std::size_t noTestMethods = 0;
  2012. int noClasses = objc_getClassList( nullptr, 0 );
  2013. Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
  2014. objc_getClassList( classes, noClasses );
  2015. for( int c = 0; c < noClasses; c++ ) {
  2016. Class cls = classes[c];
  2017. {
  2018. u_int count;
  2019. Method* methods = class_copyMethodList( cls, &count );
  2020. for( u_int m = 0; m < count ; m++ ) {
  2021. SEL selector = method_getName(methods[m]);
  2022. std::string methodName = sel_getName(selector);
  2023. if( startsWith( methodName, "Catch_TestCase_" ) ) {
  2024. std::string testCaseName = methodName.substr( 15 );
  2025. std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
  2026. std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
  2027. const char* className = class_getName( cls );
  2028. getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo("",0) ) );
  2029. noTestMethods++;
  2030. }
  2031. }
  2032. free(methods);
  2033. }
  2034. }
  2035. return noTestMethods;
  2036. }
  2037. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  2038. namespace Matchers {
  2039. namespace Impl {
  2040. namespace NSStringMatchers {
  2041. struct StringHolder : MatcherBase<NSString*>{
  2042. StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
  2043. StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
  2044. StringHolder() {
  2045. arcSafeRelease( m_substr );
  2046. }
  2047. bool match( NSString* arg ) const override {
  2048. return false;
  2049. }
  2050. NSString* CATCH_ARC_STRONG m_substr;
  2051. };
  2052. struct Equals : StringHolder {
  2053. Equals( NSString* substr ) : StringHolder( substr ){}
  2054. bool match( NSString* str ) const override {
  2055. return (str != nil || m_substr == nil ) &&
  2056. [str isEqualToString:m_substr];
  2057. }
  2058. std::string describe() const override {
  2059. return "equals string: " + Catch::Detail::stringify( m_substr );
  2060. }
  2061. };
  2062. struct Contains : StringHolder {
  2063. Contains( NSString* substr ) : StringHolder( substr ){}
  2064. bool match( NSString* str ) const {
  2065. return (str != nil || m_substr == nil ) &&
  2066. [str rangeOfString:m_substr].location != NSNotFound;
  2067. }
  2068. std::string describe() const override {
  2069. return "contains string: " + Catch::Detail::stringify( m_substr );
  2070. }
  2071. };
  2072. struct StartsWith : StringHolder {
  2073. StartsWith( NSString* substr ) : StringHolder( substr ){}
  2074. bool match( NSString* str ) const override {
  2075. return (str != nil || m_substr == nil ) &&
  2076. [str rangeOfString:m_substr].location == 0;
  2077. }
  2078. std::string describe() const override {
  2079. return "starts with: " + Catch::Detail::stringify( m_substr );
  2080. }
  2081. };
  2082. struct EndsWith : StringHolder {
  2083. EndsWith( NSString* substr ) : StringHolder( substr ){}
  2084. bool match( NSString* str ) const override {
  2085. return (str != nil || m_substr == nil ) &&
  2086. [str rangeOfString:m_substr].location == [str length] - [m_substr length];
  2087. }
  2088. std::string describe() const override {
  2089. return "ends with: " + Catch::Detail::stringify( m_substr );
  2090. }
  2091. };
  2092. } // namespace NSStringMatchers
  2093. } // namespace Impl
  2094. inline Impl::NSStringMatchers::Equals
  2095. Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
  2096. inline Impl::NSStringMatchers::Contains
  2097. Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
  2098. inline Impl::NSStringMatchers::StartsWith
  2099. StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
  2100. inline Impl::NSStringMatchers::EndsWith
  2101. EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
  2102. } // namespace Matchers
  2103. using namespace Matchers;
  2104. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  2105. } // namespace Catch
  2106. ///////////////////////////////////////////////////////////////////////////////
  2107. #define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix
  2108. #define OC_TEST_CASE2( name, desc, uniqueSuffix ) \
  2109. +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \
  2110. { \
  2111. return @ name; \
  2112. } \
  2113. +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \
  2114. { \
  2115. return @ desc; \
  2116. } \
  2117. -(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )
  2118. #define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )
  2119. // end catch_objc.hpp
  2120. #endif
  2121. #ifdef CATCH_CONFIG_EXTERNAL_INTERFACES
  2122. // start catch_external_interfaces.h
  2123. // start catch_reporter_bases.hpp
  2124. // start catch_enforce.h
  2125. #include <sstream>
  2126. #include <stdexcept>
  2127. #define CATCH_PREPARE_EXCEPTION( type, msg ) \
  2128. type( static_cast<std::ostringstream&&>( std::ostringstream() << msg ).str() )
  2129. #define CATCH_INTERNAL_ERROR( msg ) \
  2130. throw CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg);
  2131. #define CATCH_ERROR( msg ) \
  2132. throw CATCH_PREPARE_EXCEPTION( std::domain_error, msg )
  2133. #define CATCH_ENFORCE( condition, msg ) \
  2134. do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false)
  2135. // end catch_enforce.h
  2136. // start catch_interfaces_reporter.h
  2137. // start catch_config.hpp
  2138. // start catch_test_spec_parser.h
  2139. #ifdef __clang__
  2140. #pragma clang diagnostic push
  2141. #pragma clang diagnostic ignored "-Wpadded"
  2142. #endif
  2143. // start catch_test_spec.h
  2144. #ifdef __clang__
  2145. #pragma clang diagnostic push
  2146. #pragma clang diagnostic ignored "-Wpadded"
  2147. #endif
  2148. // start catch_wildcard_pattern.h
  2149. namespace Catch
  2150. {
  2151. class WildcardPattern {
  2152. enum WildcardPosition {
  2153. NoWildcard = 0,
  2154. WildcardAtStart = 1,
  2155. WildcardAtEnd = 2,
  2156. WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
  2157. };
  2158. public:
  2159. WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity );
  2160. virtual ~WildcardPattern() = default;
  2161. virtual bool matches( std::string const& str ) const;
  2162. private:
  2163. std::string adjustCase( std::string const& str ) const;
  2164. CaseSensitive::Choice m_caseSensitivity;
  2165. WildcardPosition m_wildcard = NoWildcard;
  2166. std::string m_pattern;
  2167. };
  2168. }
  2169. // end catch_wildcard_pattern.h
  2170. #include <string>
  2171. #include <vector>
  2172. #include <memory>
  2173. namespace Catch {
  2174. class TestSpec {
  2175. struct Pattern {
  2176. virtual ~Pattern();
  2177. virtual bool matches( TestCaseInfo const& testCase ) const = 0;
  2178. };
  2179. using PatternPtr = std::shared_ptr<Pattern>;
  2180. class NamePattern : public Pattern {
  2181. public:
  2182. NamePattern( std::string const& name );
  2183. virtual ~NamePattern();
  2184. virtual bool matches( TestCaseInfo const& testCase ) const override;
  2185. private:
  2186. WildcardPattern m_wildcardPattern;
  2187. };
  2188. class TagPattern : public Pattern {
  2189. public:
  2190. TagPattern( std::string const& tag );
  2191. virtual ~TagPattern();
  2192. virtual bool matches( TestCaseInfo const& testCase ) const override;
  2193. private:
  2194. std::string m_tag;
  2195. };
  2196. class ExcludedPattern : public Pattern {
  2197. public:
  2198. ExcludedPattern( PatternPtr const& underlyingPattern );
  2199. virtual ~ExcludedPattern();
  2200. virtual bool matches( TestCaseInfo const& testCase ) const override;
  2201. private:
  2202. PatternPtr m_underlyingPattern;
  2203. };
  2204. struct Filter {
  2205. std::vector<PatternPtr> m_patterns;
  2206. bool matches( TestCaseInfo const& testCase ) const;
  2207. };
  2208. public:
  2209. bool hasFilters() const;
  2210. bool matches( TestCaseInfo const& testCase ) const;
  2211. private:
  2212. std::vector<Filter> m_filters;
  2213. friend class TestSpecParser;
  2214. };
  2215. }
  2216. #ifdef __clang__
  2217. #pragma clang diagnostic pop
  2218. #endif
  2219. // end catch_test_spec.h
  2220. // start catch_interfaces_tag_alias_registry.h
  2221. #include <string>
  2222. namespace Catch {
  2223. struct TagAlias;
  2224. struct ITagAliasRegistry {
  2225. virtual ~ITagAliasRegistry();
  2226. // Nullptr if not present
  2227. virtual TagAlias const* find( std::string const& alias ) const = 0;
  2228. virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
  2229. static ITagAliasRegistry const& get();
  2230. };
  2231. } // end namespace Catch
  2232. // end catch_interfaces_tag_alias_registry.h
  2233. namespace Catch {
  2234. class TestSpecParser {
  2235. enum Mode{ None, Name, QuotedName, Tag, EscapedName };
  2236. Mode m_mode = None;
  2237. bool m_exclusion = false;
  2238. std::size_t m_start = std::string::npos, m_pos = 0;
  2239. std::string m_arg;
  2240. std::vector<std::size_t> m_escapeChars;
  2241. TestSpec::Filter m_currentFilter;
  2242. TestSpec m_testSpec;
  2243. ITagAliasRegistry const* m_tagAliases = nullptr;
  2244. public:
  2245. TestSpecParser( ITagAliasRegistry const& tagAliases );
  2246. TestSpecParser& parse( std::string const& arg );
  2247. TestSpec testSpec();
  2248. private:
  2249. void visitChar( char c );
  2250. void startNewMode( Mode mode, std::size_t start );
  2251. void escape();
  2252. std::string subString() const;
  2253. template<typename T>
  2254. void addPattern() {
  2255. std::string token = subString();
  2256. for( std::size_t i = 0; i < m_escapeChars.size(); ++i )
  2257. token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 );
  2258. m_escapeChars.clear();
  2259. if( startsWith( token, "exclude:" ) ) {
  2260. m_exclusion = true;
  2261. token = token.substr( 8 );
  2262. }
  2263. if( !token.empty() ) {
  2264. TestSpec::PatternPtr pattern = std::make_shared<T>( token );
  2265. if( m_exclusion )
  2266. pattern = std::make_shared<TestSpec::ExcludedPattern>( pattern );
  2267. m_currentFilter.m_patterns.push_back( pattern );
  2268. }
  2269. m_exclusion = false;
  2270. m_mode = None;
  2271. }
  2272. void addFilter();
  2273. };
  2274. TestSpec parseTestSpec( std::string const& arg );
  2275. } // namespace Catch
  2276. #ifdef __clang__
  2277. #pragma clang diagnostic pop
  2278. #endif
  2279. // end catch_test_spec_parser.h
  2280. // start catch_interfaces_config.h
  2281. #include <iosfwd>
  2282. #include <string>
  2283. #include <vector>
  2284. #include <memory>
  2285. namespace Catch {
  2286. enum class Verbosity {
  2287. Quiet = 0,
  2288. Normal,
  2289. High
  2290. };
  2291. struct WarnAbout { enum What {
  2292. Nothing = 0x00,
  2293. NoAssertions = 0x01
  2294. }; };
  2295. struct ShowDurations { enum OrNot {
  2296. DefaultForReporter,
  2297. Always,
  2298. Never
  2299. }; };
  2300. struct RunTests { enum InWhatOrder {
  2301. InDeclarationOrder,
  2302. InLexicographicalOrder,
  2303. InRandomOrder
  2304. }; };
  2305. struct UseColour { enum YesOrNo {
  2306. Auto,
  2307. Yes,
  2308. No
  2309. }; };
  2310. struct WaitForKeypress { enum When {
  2311. Never,
  2312. BeforeStart = 1,
  2313. BeforeExit = 2,
  2314. BeforeStartAndExit = BeforeStart | BeforeExit
  2315. }; };
  2316. class TestSpec;
  2317. struct IConfig : NonCopyable {
  2318. virtual ~IConfig();
  2319. virtual bool allowThrows() const = 0;
  2320. virtual std::ostream& stream() const = 0;
  2321. virtual std::string name() const = 0;
  2322. virtual bool includeSuccessfulResults() const = 0;
  2323. virtual bool shouldDebugBreak() const = 0;
  2324. virtual bool warnAboutMissingAssertions() const = 0;
  2325. virtual int abortAfter() const = 0;
  2326. virtual bool showInvisibles() const = 0;
  2327. virtual ShowDurations::OrNot showDurations() const = 0;
  2328. virtual TestSpec const& testSpec() const = 0;
  2329. virtual RunTests::InWhatOrder runOrder() const = 0;
  2330. virtual unsigned int rngSeed() const = 0;
  2331. virtual int benchmarkResolutionMultiple() const = 0;
  2332. virtual UseColour::YesOrNo useColour() const = 0;
  2333. virtual std::vector<std::string> const& getSectionsToRun() const = 0;
  2334. virtual Verbosity verbosity() const = 0;
  2335. };
  2336. using IConfigPtr = std::shared_ptr<IConfig const>;
  2337. }
  2338. // end catch_interfaces_config.h
  2339. // Libstdc++ doesn't like incomplete classes for unique_ptr
  2340. // start catch_stream.h
  2341. // start catch_streambuf.h
  2342. #include <streambuf>
  2343. namespace Catch {
  2344. class StreamBufBase : public std::streambuf {
  2345. public:
  2346. virtual ~StreamBufBase();
  2347. };
  2348. }
  2349. // end catch_streambuf.h
  2350. #include <streambuf>
  2351. #include <ostream>
  2352. #include <fstream>
  2353. #include <memory>
  2354. namespace Catch {
  2355. std::ostream& cout();
  2356. std::ostream& cerr();
  2357. std::ostream& clog();
  2358. struct IStream {
  2359. virtual ~IStream();
  2360. virtual std::ostream& stream() const = 0;
  2361. };
  2362. class FileStream : public IStream {
  2363. mutable std::ofstream m_ofs;
  2364. public:
  2365. FileStream( std::string const& filename );
  2366. ~FileStream() override = default;
  2367. public: // IStream
  2368. std::ostream& stream() const override;
  2369. };
  2370. class CoutStream : public IStream {
  2371. mutable std::ostream m_os;
  2372. public:
  2373. CoutStream();
  2374. ~CoutStream() override = default;
  2375. public: // IStream
  2376. std::ostream& stream() const override;
  2377. };
  2378. class DebugOutStream : public IStream {
  2379. std::unique_ptr<StreamBufBase> m_streamBuf;
  2380. mutable std::ostream m_os;
  2381. public:
  2382. DebugOutStream();
  2383. ~DebugOutStream() override = default;
  2384. public: // IStream
  2385. std::ostream& stream() const override;
  2386. };
  2387. }
  2388. // end catch_stream.h
  2389. #include <memory>
  2390. #include <vector>
  2391. #include <string>
  2392. #ifndef CATCH_CONFIG_CONSOLE_WIDTH
  2393. #define CATCH_CONFIG_CONSOLE_WIDTH 80
  2394. #endif
  2395. namespace Catch {
  2396. struct IStream;
  2397. struct ConfigData {
  2398. bool listTests = false;
  2399. bool listTags = false;
  2400. bool listReporters = false;
  2401. bool listTestNamesOnly = false;
  2402. bool showSuccessfulTests = false;
  2403. bool shouldDebugBreak = false;
  2404. bool noThrow = false;
  2405. bool showHelp = false;
  2406. bool showInvisibles = false;
  2407. bool filenamesAsTags = false;
  2408. bool libIdentify = false;
  2409. int abortAfter = -1;
  2410. unsigned int rngSeed = 0;
  2411. int benchmarkResolutionMultiple = 100;
  2412. Verbosity verbosity = Verbosity::Normal;
  2413. WarnAbout::What warnings = WarnAbout::Nothing;
  2414. ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
  2415. RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
  2416. UseColour::YesOrNo useColour = UseColour::Auto;
  2417. WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
  2418. std::string outputFilename;
  2419. std::string name;
  2420. std::string processName;
  2421. std::vector<std::string> reporterNames;
  2422. std::vector<std::string> testsOrTags;
  2423. std::vector<std::string> sectionsToRun;
  2424. };
  2425. class Config : public IConfig {
  2426. public:
  2427. Config() = default;
  2428. Config( ConfigData const& data );
  2429. virtual ~Config() = default;
  2430. std::string const& getFilename() const;
  2431. bool listTests() const;
  2432. bool listTestNamesOnly() const;
  2433. bool listTags() const;
  2434. bool listReporters() const;
  2435. std::string getProcessName() const;
  2436. std::vector<std::string> const& getReporterNames() const;
  2437. std::vector<std::string> const& getSectionsToRun() const override;
  2438. virtual TestSpec const& testSpec() const override;
  2439. bool showHelp() const;
  2440. // IConfig interface
  2441. bool allowThrows() const override;
  2442. std::ostream& stream() const override;
  2443. std::string name() const override;
  2444. bool includeSuccessfulResults() const override;
  2445. bool warnAboutMissingAssertions() const override;
  2446. ShowDurations::OrNot showDurations() const override;
  2447. RunTests::InWhatOrder runOrder() const override;
  2448. unsigned int rngSeed() const override;
  2449. int benchmarkResolutionMultiple() const override;
  2450. UseColour::YesOrNo useColour() const override;
  2451. bool shouldDebugBreak() const override;
  2452. int abortAfter() const override;
  2453. bool showInvisibles() const override;
  2454. Verbosity verbosity() const override;
  2455. private:
  2456. IStream const* openStream();
  2457. ConfigData m_data;
  2458. std::unique_ptr<IStream const> m_stream;
  2459. TestSpec m_testSpec;
  2460. };
  2461. } // end namespace Catch
  2462. // end catch_config.hpp
  2463. // start catch_assertionresult.h
  2464. #include <string>
  2465. namespace Catch {
  2466. struct AssertionResultData
  2467. {
  2468. AssertionResultData() = delete;
  2469. AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression );
  2470. std::string message;
  2471. mutable std::string reconstructedExpression;
  2472. LazyExpression lazyExpression;
  2473. ResultWas::OfType resultType;
  2474. std::string reconstructExpression() const;
  2475. };
  2476. class AssertionResult {
  2477. public:
  2478. AssertionResult() = delete;
  2479. AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
  2480. bool isOk() const;
  2481. bool succeeded() const;
  2482. ResultWas::OfType getResultType() const;
  2483. bool hasExpression() const;
  2484. bool hasMessage() const;
  2485. std::string getExpression() const;
  2486. std::string getExpressionInMacro() const;
  2487. bool hasExpandedExpression() const;
  2488. std::string getExpandedExpression() const;
  2489. std::string getMessage() const;
  2490. SourceLineInfo getSourceInfo() const;
  2491. std::string getTestMacroName() const;
  2492. //protected:
  2493. AssertionInfo m_info;
  2494. AssertionResultData m_resultData;
  2495. };
  2496. } // end namespace Catch
  2497. // end catch_assertionresult.h
  2498. // start catch_option.hpp
  2499. namespace Catch {
  2500. // An optional type
  2501. template<typename T>
  2502. class Option {
  2503. public:
  2504. Option() : nullableValue( nullptr ) {}
  2505. Option( T const& _value )
  2506. : nullableValue( new( storage ) T( _value ) )
  2507. {}
  2508. Option( Option const& _other )
  2509. : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )
  2510. {}
  2511. ~Option() {
  2512. reset();
  2513. }
  2514. Option& operator= ( Option const& _other ) {
  2515. if( &_other != this ) {
  2516. reset();
  2517. if( _other )
  2518. nullableValue = new( storage ) T( *_other );
  2519. }
  2520. return *this;
  2521. }
  2522. Option& operator = ( T const& _value ) {
  2523. reset();
  2524. nullableValue = new( storage ) T( _value );
  2525. return *this;
  2526. }
  2527. void reset() {
  2528. if( nullableValue )
  2529. nullableValue->~T();
  2530. nullableValue = nullptr;
  2531. }
  2532. T& operator*() { return *nullableValue; }
  2533. T const& operator*() const { return *nullableValue; }
  2534. T* operator->() { return nullableValue; }
  2535. const T* operator->() const { return nullableValue; }
  2536. T valueOr( T const& defaultValue ) const {
  2537. return nullableValue ? *nullableValue : defaultValue;
  2538. }
  2539. bool some() const { return nullableValue != nullptr; }
  2540. bool none() const { return nullableValue == nullptr; }
  2541. bool operator !() const { return nullableValue == nullptr; }
  2542. explicit operator bool() const {
  2543. return some();
  2544. }
  2545. private:
  2546. T *nullableValue;
  2547. alignas(alignof(T)) char storage[sizeof(T)];
  2548. };
  2549. } // end namespace Catch
  2550. // end catch_option.hpp
  2551. #include <string>
  2552. #include <iosfwd>
  2553. #include <map>
  2554. #include <set>
  2555. #include <memory>
  2556. namespace Catch {
  2557. struct ReporterConfig {
  2558. explicit ReporterConfig( IConfigPtr const& _fullConfig );
  2559. ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream );
  2560. std::ostream& stream() const;
  2561. IConfigPtr fullConfig() const;
  2562. private:
  2563. std::ostream* m_stream;
  2564. IConfigPtr m_fullConfig;
  2565. };
  2566. struct ReporterPreferences {
  2567. bool shouldRedirectStdOut = false;
  2568. };
  2569. template<typename T>
  2570. struct LazyStat : Option<T> {
  2571. LazyStat& operator=( T const& _value ) {
  2572. Option<T>::operator=( _value );
  2573. used = false;
  2574. return *this;
  2575. }
  2576. void reset() {
  2577. Option<T>::reset();
  2578. used = false;
  2579. }
  2580. bool used = false;
  2581. };
  2582. struct TestRunInfo {
  2583. TestRunInfo( std::string const& _name );
  2584. std::string name;
  2585. };
  2586. struct GroupInfo {
  2587. GroupInfo( std::string const& _name,
  2588. std::size_t _groupIndex,
  2589. std::size_t _groupsCount );
  2590. std::string name;
  2591. std::size_t groupIndex;
  2592. std::size_t groupsCounts;
  2593. };
  2594. struct AssertionStats {
  2595. AssertionStats( AssertionResult const& _assertionResult,
  2596. std::vector<MessageInfo> const& _infoMessages,
  2597. Totals const& _totals );
  2598. AssertionStats( AssertionStats const& ) = default;
  2599. AssertionStats( AssertionStats && ) = default;
  2600. AssertionStats& operator = ( AssertionStats const& ) = default;
  2601. AssertionStats& operator = ( AssertionStats && ) = default;
  2602. virtual ~AssertionStats();
  2603. AssertionResult assertionResult;
  2604. std::vector<MessageInfo> infoMessages;
  2605. Totals totals;
  2606. };
  2607. struct SectionStats {
  2608. SectionStats( SectionInfo const& _sectionInfo,
  2609. Counts const& _assertions,
  2610. double _durationInSeconds,
  2611. bool _missingAssertions );
  2612. SectionStats( SectionStats const& ) = default;
  2613. SectionStats( SectionStats && ) = default;
  2614. SectionStats& operator = ( SectionStats const& ) = default;
  2615. SectionStats& operator = ( SectionStats && ) = default;
  2616. virtual ~SectionStats();
  2617. SectionInfo sectionInfo;
  2618. Counts assertions;
  2619. double durationInSeconds;
  2620. bool missingAssertions;
  2621. };
  2622. struct TestCaseStats {
  2623. TestCaseStats( TestCaseInfo const& _testInfo,
  2624. Totals const& _totals,
  2625. std::string const& _stdOut,
  2626. std::string const& _stdErr,
  2627. bool _aborting );
  2628. TestCaseStats( TestCaseStats const& ) = default;
  2629. TestCaseStats( TestCaseStats && ) = default;
  2630. TestCaseStats& operator = ( TestCaseStats const& ) = default;
  2631. TestCaseStats& operator = ( TestCaseStats && ) = default;
  2632. virtual ~TestCaseStats();
  2633. TestCaseInfo testInfo;
  2634. Totals totals;
  2635. std::string stdOut;
  2636. std::string stdErr;
  2637. bool aborting;
  2638. };
  2639. struct TestGroupStats {
  2640. TestGroupStats( GroupInfo const& _groupInfo,
  2641. Totals const& _totals,
  2642. bool _aborting );
  2643. TestGroupStats( GroupInfo const& _groupInfo );
  2644. TestGroupStats( TestGroupStats const& ) = default;
  2645. TestGroupStats( TestGroupStats && ) = default;
  2646. TestGroupStats& operator = ( TestGroupStats const& ) = default;
  2647. TestGroupStats& operator = ( TestGroupStats && ) = default;
  2648. virtual ~TestGroupStats();
  2649. GroupInfo groupInfo;
  2650. Totals totals;
  2651. bool aborting;
  2652. };
  2653. struct TestRunStats {
  2654. TestRunStats( TestRunInfo const& _runInfo,
  2655. Totals const& _totals,
  2656. bool _aborting );
  2657. TestRunStats( TestRunStats const& ) = default;
  2658. TestRunStats( TestRunStats && ) = default;
  2659. TestRunStats& operator = ( TestRunStats const& ) = default;
  2660. TestRunStats& operator = ( TestRunStats && ) = default;
  2661. virtual ~TestRunStats();
  2662. TestRunInfo runInfo;
  2663. Totals totals;
  2664. bool aborting;
  2665. };
  2666. struct BenchmarkInfo {
  2667. std::string name;
  2668. };
  2669. struct BenchmarkStats {
  2670. BenchmarkInfo info;
  2671. std::size_t iterations;
  2672. uint64_t elapsedTimeInNanoseconds;
  2673. };
  2674. struct IStreamingReporter {
  2675. virtual ~IStreamingReporter() = default;
  2676. // Implementing class must also provide the following static methods:
  2677. // static std::string getDescription();
  2678. // static std::set<Verbosity> getSupportedVerbosities()
  2679. virtual ReporterPreferences getPreferences() const = 0;
  2680. virtual void noMatchingTestCases( std::string const& spec ) = 0;
  2681. virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
  2682. virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
  2683. virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
  2684. virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
  2685. // *** experimental ***
  2686. virtual void benchmarkStarting( BenchmarkInfo const& ) {}
  2687. virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
  2688. // The return value indicates if the messages buffer should be cleared:
  2689. virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
  2690. // *** experimental ***
  2691. virtual void benchmarkEnded( BenchmarkStats const& ) {}
  2692. virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
  2693. virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
  2694. virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
  2695. virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
  2696. virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
  2697. // Default empty implementation provided
  2698. virtual void fatalErrorEncountered( StringRef name );
  2699. virtual bool isMulti() const;
  2700. };
  2701. using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;
  2702. struct IReporterFactory {
  2703. virtual ~IReporterFactory();
  2704. virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0;
  2705. virtual std::string getDescription() const = 0;
  2706. };
  2707. using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
  2708. struct IReporterRegistry {
  2709. using FactoryMap = std::map<std::string, IReporterFactoryPtr>;
  2710. using Listeners = std::vector<IReporterFactoryPtr>;
  2711. virtual ~IReporterRegistry();
  2712. virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0;
  2713. virtual FactoryMap const& getFactories() const = 0;
  2714. virtual Listeners const& getListeners() const = 0;
  2715. };
  2716. void addReporter( IStreamingReporterPtr& existingReporter, IStreamingReporterPtr&& additionalReporter );
  2717. } // end namespace Catch
  2718. // end catch_interfaces_reporter.h
  2719. #include <algorithm>
  2720. #include <cstring>
  2721. #include <cfloat>
  2722. #include <cstdio>
  2723. #include <assert.h>
  2724. #include <memory>
  2725. namespace Catch {
  2726. void prepareExpandedExpression(AssertionResult& result);
  2727. // Returns double formatted as %.3f (format expected on output)
  2728. std::string getFormattedDuration( double duration );
  2729. template<typename DerivedT>
  2730. struct StreamingReporterBase : IStreamingReporter {
  2731. StreamingReporterBase( ReporterConfig const& _config )
  2732. : m_config( _config.fullConfig() ),
  2733. stream( _config.stream() )
  2734. {
  2735. m_reporterPrefs.shouldRedirectStdOut = false;
  2736. CATCH_ENFORCE( DerivedT::getSupportedVerbosities().count( m_config->verbosity() ), "Verbosity level not supported by this reporter" );
  2737. }
  2738. ReporterPreferences getPreferences() const override {
  2739. return m_reporterPrefs;
  2740. }
  2741. static std::set<Verbosity> getSupportedVerbosities() {
  2742. return { Verbosity::Normal };
  2743. }
  2744. ~StreamingReporterBase() override = default;
  2745. void noMatchingTestCases(std::string const&) override {}
  2746. void testRunStarting(TestRunInfo const& _testRunInfo) override {
  2747. currentTestRunInfo = _testRunInfo;
  2748. }
  2749. void testGroupStarting(GroupInfo const& _groupInfo) override {
  2750. currentGroupInfo = _groupInfo;
  2751. }
  2752. void testCaseStarting(TestCaseInfo const& _testInfo) override {
  2753. currentTestCaseInfo = _testInfo;
  2754. }
  2755. void sectionStarting(SectionInfo const& _sectionInfo) override {
  2756. m_sectionStack.push_back(_sectionInfo);
  2757. }
  2758. void sectionEnded(SectionStats const& /* _sectionStats */) override {
  2759. m_sectionStack.pop_back();
  2760. }
  2761. void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {
  2762. currentTestCaseInfo.reset();
  2763. }
  2764. void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override {
  2765. currentGroupInfo.reset();
  2766. }
  2767. void testRunEnded(TestRunStats const& /* _testRunStats */) override {
  2768. currentTestCaseInfo.reset();
  2769. currentGroupInfo.reset();
  2770. currentTestRunInfo.reset();
  2771. }
  2772. void skipTest(TestCaseInfo const&) override {
  2773. // Don't do anything with this by default.
  2774. // It can optionally be overridden in the derived class.
  2775. }
  2776. IConfigPtr m_config;
  2777. std::ostream& stream;
  2778. LazyStat<TestRunInfo> currentTestRunInfo;
  2779. LazyStat<GroupInfo> currentGroupInfo;
  2780. LazyStat<TestCaseInfo> currentTestCaseInfo;
  2781. std::vector<SectionInfo> m_sectionStack;
  2782. ReporterPreferences m_reporterPrefs;
  2783. };
  2784. template<typename DerivedT>
  2785. struct CumulativeReporterBase : IStreamingReporter {
  2786. template<typename T, typename ChildNodeT>
  2787. struct Node {
  2788. explicit Node( T const& _value ) : value( _value ) {}
  2789. virtual ~Node() {}
  2790. using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;
  2791. T value;
  2792. ChildNodes children;
  2793. };
  2794. struct SectionNode {
  2795. explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
  2796. virtual ~SectionNode() = default;
  2797. bool operator == (SectionNode const& other) const {
  2798. return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
  2799. }
  2800. bool operator == (std::shared_ptr<SectionNode> const& other) const {
  2801. return operator==(*other);
  2802. }
  2803. SectionStats stats;
  2804. using ChildSections = std::vector<std::shared_ptr<SectionNode>>;
  2805. using Assertions = std::vector<AssertionStats>;
  2806. ChildSections childSections;
  2807. Assertions assertions;
  2808. std::string stdOut;
  2809. std::string stdErr;
  2810. };
  2811. struct BySectionInfo {
  2812. BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
  2813. BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
  2814. bool operator() (std::shared_ptr<SectionNode> const& node) const {
  2815. return ((node->stats.sectionInfo.name == m_other.name) &&
  2816. (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
  2817. }
  2818. void operator=(BySectionInfo const&) = delete;
  2819. private:
  2820. SectionInfo const& m_other;
  2821. };
  2822. using TestCaseNode = Node<TestCaseStats, SectionNode>;
  2823. using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
  2824. using TestRunNode = Node<TestRunStats, TestGroupNode>;
  2825. CumulativeReporterBase( ReporterConfig const& _config )
  2826. : m_config( _config.fullConfig() ),
  2827. stream( _config.stream() )
  2828. {
  2829. m_reporterPrefs.shouldRedirectStdOut = false;
  2830. CATCH_ENFORCE( DerivedT::getSupportedVerbosities().count( m_config->verbosity() ), "Verbosity level not supported by this reporter" );
  2831. }
  2832. ~CumulativeReporterBase() override = default;
  2833. ReporterPreferences getPreferences() const override {
  2834. return m_reporterPrefs;
  2835. }
  2836. static std::set<Verbosity> getSupportedVerbosities() {
  2837. return { Verbosity::Normal };
  2838. }
  2839. void testRunStarting( TestRunInfo const& ) override {}
  2840. void testGroupStarting( GroupInfo const& ) override {}
  2841. void testCaseStarting( TestCaseInfo const& ) override {}
  2842. void sectionStarting( SectionInfo const& sectionInfo ) override {
  2843. SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
  2844. std::shared_ptr<SectionNode> node;
  2845. if( m_sectionStack.empty() ) {
  2846. if( !m_rootSection )
  2847. m_rootSection = std::make_shared<SectionNode>( incompleteStats );
  2848. node = m_rootSection;
  2849. }
  2850. else {
  2851. SectionNode& parentNode = *m_sectionStack.back();
  2852. auto it =
  2853. std::find_if( parentNode.childSections.begin(),
  2854. parentNode.childSections.end(),
  2855. BySectionInfo( sectionInfo ) );
  2856. if( it == parentNode.childSections.end() ) {
  2857. node = std::make_shared<SectionNode>( incompleteStats );
  2858. parentNode.childSections.push_back( node );
  2859. }
  2860. else
  2861. node = *it;
  2862. }
  2863. m_sectionStack.push_back( node );
  2864. m_deepestSection = std::move(node);
  2865. }
  2866. void assertionStarting(AssertionInfo const&) override {}
  2867. bool assertionEnded(AssertionStats const& assertionStats) override {
  2868. assert(!m_sectionStack.empty());
  2869. // AssertionResult holds a pointer to a temporary DecomposedExpression,
  2870. // which getExpandedExpression() calls to build the expression string.
  2871. // Our section stack copy of the assertionResult will likely outlive the
  2872. // temporary, so it must be expanded or discarded now to avoid calling
  2873. // a destroyed object later.
  2874. prepareExpandedExpression(const_cast<AssertionResult&>( assertionStats.assertionResult ) );
  2875. SectionNode& sectionNode = *m_sectionStack.back();
  2876. sectionNode.assertions.push_back(assertionStats);
  2877. return true;
  2878. }
  2879. void sectionEnded(SectionStats const& sectionStats) override {
  2880. assert(!m_sectionStack.empty());
  2881. SectionNode& node = *m_sectionStack.back();
  2882. node.stats = sectionStats;
  2883. m_sectionStack.pop_back();
  2884. }
  2885. void testCaseEnded(TestCaseStats const& testCaseStats) override {
  2886. auto node = std::make_shared<TestCaseNode>(testCaseStats);
  2887. assert(m_sectionStack.size() == 0);
  2888. node->children.push_back(m_rootSection);
  2889. m_testCases.push_back(node);
  2890. m_rootSection.reset();
  2891. assert(m_deepestSection);
  2892. m_deepestSection->stdOut = testCaseStats.stdOut;
  2893. m_deepestSection->stdErr = testCaseStats.stdErr;
  2894. }
  2895. void testGroupEnded(TestGroupStats const& testGroupStats) override {
  2896. auto node = std::make_shared<TestGroupNode>(testGroupStats);
  2897. node->children.swap(m_testCases);
  2898. m_testGroups.push_back(node);
  2899. }
  2900. void testRunEnded(TestRunStats const& testRunStats) override {
  2901. auto node = std::make_shared<TestRunNode>(testRunStats);
  2902. node->children.swap(m_testGroups);
  2903. m_testRuns.push_back(node);
  2904. testRunEndedCumulative();
  2905. }
  2906. virtual void testRunEndedCumulative() = 0;
  2907. void skipTest(TestCaseInfo const&) override {}
  2908. IConfigPtr m_config;
  2909. std::ostream& stream;
  2910. std::vector<AssertionStats> m_assertions;
  2911. std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;
  2912. std::vector<std::shared_ptr<TestCaseNode>> m_testCases;
  2913. std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;
  2914. std::vector<std::shared_ptr<TestRunNode>> m_testRuns;
  2915. std::shared_ptr<SectionNode> m_rootSection;
  2916. std::shared_ptr<SectionNode> m_deepestSection;
  2917. std::vector<std::shared_ptr<SectionNode>> m_sectionStack;
  2918. ReporterPreferences m_reporterPrefs;
  2919. };
  2920. template<char C>
  2921. char const* getLineOfChars() {
  2922. static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
  2923. if( !*line ) {
  2924. std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
  2925. line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
  2926. }
  2927. return line;
  2928. }
  2929. struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {
  2930. TestEventListenerBase( ReporterConfig const& _config );
  2931. void assertionStarting(AssertionInfo const&) override;
  2932. bool assertionEnded(AssertionStats const&) override;
  2933. };
  2934. } // end namespace Catch
  2935. // end catch_reporter_bases.hpp
  2936. // start catch_console_colour.h
  2937. namespace Catch {
  2938. struct Colour {
  2939. enum Code {
  2940. None = 0,
  2941. White,
  2942. Red,
  2943. Green,
  2944. Blue,
  2945. Cyan,
  2946. Yellow,
  2947. Grey,
  2948. Bright = 0x10,
  2949. BrightRed = Bright | Red,
  2950. BrightGreen = Bright | Green,
  2951. LightGrey = Bright | Grey,
  2952. BrightWhite = Bright | White,
  2953. // By intention
  2954. FileName = LightGrey,
  2955. Warning = Yellow,
  2956. ResultError = BrightRed,
  2957. ResultSuccess = BrightGreen,
  2958. ResultExpectedFailure = Warning,
  2959. Error = BrightRed,
  2960. Success = Green,
  2961. OriginalExpression = Cyan,
  2962. ReconstructedExpression = Yellow,
  2963. SecondaryText = LightGrey,
  2964. Headers = White
  2965. };
  2966. // Use constructed object for RAII guard
  2967. Colour( Code _colourCode );
  2968. Colour( Colour&& other ) noexcept;
  2969. Colour& operator=( Colour&& other ) noexcept;
  2970. ~Colour();
  2971. // Use static method for one-shot changes
  2972. static void use( Code _colourCode );
  2973. private:
  2974. bool m_moved = false;
  2975. };
  2976. std::ostream& operator << ( std::ostream& os, Colour const& );
  2977. } // end namespace Catch
  2978. // end catch_console_colour.h
  2979. // start catch_reporter_registrars.hpp
  2980. namespace Catch {
  2981. template<typename T>
  2982. class ReporterRegistrar {
  2983. class ReporterFactory : public IReporterFactory {
  2984. virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override {
  2985. return std::unique_ptr<T>( new T( config ) );
  2986. }
  2987. virtual std::string getDescription() const override {
  2988. return T::getDescription();
  2989. }
  2990. };
  2991. public:
  2992. ReporterRegistrar( std::string const& name ) {
  2993. getMutableRegistryHub().registerReporter( name, std::make_shared<ReporterFactory>() );
  2994. }
  2995. };
  2996. template<typename T>
  2997. class ListenerRegistrar {
  2998. class ListenerFactory : public IReporterFactory {
  2999. virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override {
  3000. return std::unique_ptr<T>( new T( config ) );
  3001. }
  3002. virtual std::string getDescription() const override {
  3003. return std::string();
  3004. }
  3005. };
  3006. public:
  3007. ListenerRegistrar() {
  3008. getMutableRegistryHub().registerListener( std::make_shared<ListenerFactory>() );
  3009. }
  3010. };
  3011. }
  3012. #if !defined(CATCH_CONFIG_DISABLE)
  3013. #define CATCH_REGISTER_REPORTER( name, reporterType ) \
  3014. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  3015. namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \
  3016. CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  3017. #define CATCH_REGISTER_LISTENER( listenerType ) \
  3018. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  3019. namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
  3020. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
  3021. #else // CATCH_CONFIG_DISABLE
  3022. #define CATCH_REGISTER_REPORTER(name, reporterType)
  3023. #define CATCH_REGISTER_LISTENER(listenerType)
  3024. #endif // CATCH_CONFIG_DISABLE
  3025. // end catch_reporter_registrars.hpp
  3026. // end catch_external_interfaces.h
  3027. #endif
  3028. #ifdef CATCH_IMPL
  3029. // start catch_impl.hpp
  3030. #ifdef __clang__
  3031. #pragma clang diagnostic push
  3032. #pragma clang diagnostic ignored "-Wweak-vtables"
  3033. #endif
  3034. // Keep these here for external reporters
  3035. // start catch_test_case_tracker.h
  3036. #include <string>
  3037. #include <vector>
  3038. #include <memory>
  3039. namespace Catch {
  3040. namespace TestCaseTracking {
  3041. struct NameAndLocation {
  3042. std::string name;
  3043. SourceLineInfo location;
  3044. NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
  3045. };
  3046. struct ITracker;
  3047. using ITrackerPtr = std::shared_ptr<ITracker>;
  3048. struct ITracker {
  3049. virtual ~ITracker();
  3050. // static queries
  3051. virtual NameAndLocation const& nameAndLocation() const = 0;
  3052. // dynamic queries
  3053. virtual bool isComplete() const = 0; // Successfully completed or failed
  3054. virtual bool isSuccessfullyCompleted() const = 0;
  3055. virtual bool isOpen() const = 0; // Started but not complete
  3056. virtual bool hasChildren() const = 0;
  3057. virtual ITracker& parent() = 0;
  3058. // actions
  3059. virtual void close() = 0; // Successfully complete
  3060. virtual void fail() = 0;
  3061. virtual void markAsNeedingAnotherRun() = 0;
  3062. virtual void addChild( ITrackerPtr const& child ) = 0;
  3063. virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0;
  3064. virtual void openChild() = 0;
  3065. // Debug/ checking
  3066. virtual bool isSectionTracker() const = 0;
  3067. virtual bool isIndexTracker() const = 0;
  3068. };
  3069. class TrackerContext {
  3070. enum RunState {
  3071. NotStarted,
  3072. Executing,
  3073. CompletedCycle
  3074. };
  3075. ITrackerPtr m_rootTracker;
  3076. ITracker* m_currentTracker = nullptr;
  3077. RunState m_runState = NotStarted;
  3078. public:
  3079. static TrackerContext& instance();
  3080. ITracker& startRun();
  3081. void endRun();
  3082. void startCycle();
  3083. void completeCycle();
  3084. bool completedCycle() const;
  3085. ITracker& currentTracker();
  3086. void setCurrentTracker( ITracker* tracker );
  3087. };
  3088. class TrackerBase : public ITracker {
  3089. protected:
  3090. enum CycleState {
  3091. NotStarted,
  3092. Executing,
  3093. ExecutingChildren,
  3094. NeedsAnotherRun,
  3095. CompletedSuccessfully,
  3096. Failed
  3097. };
  3098. class TrackerHasName {
  3099. NameAndLocation m_nameAndLocation;
  3100. public:
  3101. TrackerHasName( NameAndLocation const& nameAndLocation );
  3102. bool operator ()( ITrackerPtr const& tracker ) const;
  3103. };
  3104. using Children = std::vector<ITrackerPtr>;
  3105. NameAndLocation m_nameAndLocation;
  3106. TrackerContext& m_ctx;
  3107. ITracker* m_parent;
  3108. Children m_children;
  3109. CycleState m_runState = NotStarted;
  3110. public:
  3111. TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
  3112. NameAndLocation const& nameAndLocation() const override;
  3113. bool isComplete() const override;
  3114. bool isSuccessfullyCompleted() const override;
  3115. bool isOpen() const override;
  3116. bool hasChildren() const override;
  3117. void addChild( ITrackerPtr const& child ) override;
  3118. ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override;
  3119. ITracker& parent() override;
  3120. void openChild() override;
  3121. bool isSectionTracker() const override;
  3122. bool isIndexTracker() const override;
  3123. void open();
  3124. void close() override;
  3125. void fail() override;
  3126. void markAsNeedingAnotherRun() override;
  3127. private:
  3128. void moveToParent();
  3129. void moveToThis();
  3130. };
  3131. class SectionTracker : public TrackerBase {
  3132. std::vector<std::string> m_filters;
  3133. public:
  3134. SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
  3135. bool isSectionTracker() const override;
  3136. static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );
  3137. void tryOpen();
  3138. void addInitialFilters( std::vector<std::string> const& filters );
  3139. void addNextFilters( std::vector<std::string> const& filters );
  3140. };
  3141. class IndexTracker : public TrackerBase {
  3142. int m_size;
  3143. int m_index = -1;
  3144. public:
  3145. IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size );
  3146. bool isIndexTracker() const override;
  3147. void close() override;
  3148. static IndexTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size );
  3149. int index() const;
  3150. void moveNext();
  3151. };
  3152. } // namespace TestCaseTracking
  3153. using TestCaseTracking::ITracker;
  3154. using TestCaseTracking::TrackerContext;
  3155. using TestCaseTracking::SectionTracker;
  3156. using TestCaseTracking::IndexTracker;
  3157. } // namespace Catch
  3158. // end catch_test_case_tracker.h
  3159. // start catch_leak_detector.h
  3160. namespace Catch {
  3161. struct LeakDetector {
  3162. LeakDetector();
  3163. };
  3164. }
  3165. // end catch_leak_detector.h
  3166. // Cpp files will be included in the single-header file here
  3167. // start catch_approx.cpp
  3168. #include <limits>
  3169. namespace Catch {
  3170. namespace Detail {
  3171. double max(double lhs, double rhs) {
  3172. if (lhs < rhs) {
  3173. return rhs;
  3174. }
  3175. return lhs;
  3176. }
  3177. Approx::Approx ( double value )
  3178. : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
  3179. m_margin( 0.0 ),
  3180. m_scale( 1.0 ),
  3181. m_value( value )
  3182. {}
  3183. Approx Approx::custom() {
  3184. return Approx( 0 );
  3185. }
  3186. std::string Approx::toString() const {
  3187. std::ostringstream oss;
  3188. oss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
  3189. return oss.str();
  3190. }
  3191. } // end namespace Detail
  3192. std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
  3193. return value.toString();
  3194. }
  3195. } // end namespace Catch
  3196. // end catch_approx.cpp
  3197. // start catch_assertionhandler.cpp
  3198. // start catch_context.h
  3199. #include <memory>
  3200. namespace Catch {
  3201. struct IResultCapture;
  3202. struct IRunner;
  3203. struct IConfig;
  3204. using IConfigPtr = std::shared_ptr<IConfig const>;
  3205. struct IContext
  3206. {
  3207. virtual ~IContext();
  3208. virtual IResultCapture* getResultCapture() = 0;
  3209. virtual IRunner* getRunner() = 0;
  3210. virtual IConfigPtr getConfig() const = 0;
  3211. };
  3212. struct IMutableContext : IContext
  3213. {
  3214. virtual ~IMutableContext();
  3215. virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
  3216. virtual void setRunner( IRunner* runner ) = 0;
  3217. virtual void setConfig( IConfigPtr const& config ) = 0;
  3218. };
  3219. IContext& getCurrentContext();
  3220. IMutableContext& getCurrentMutableContext();
  3221. void cleanUpContext();
  3222. }
  3223. // end catch_context.h
  3224. #include <cassert>
  3225. namespace Catch {
  3226. auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
  3227. expr.streamReconstructedExpression( os );
  3228. return os;
  3229. }
  3230. LazyExpression::LazyExpression( bool isNegated )
  3231. : m_isNegated( isNegated )
  3232. {}
  3233. LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {}
  3234. LazyExpression::operator bool() const {
  3235. return m_transientExpression != nullptr;
  3236. }
  3237. auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& {
  3238. if( lazyExpr.m_isNegated )
  3239. os << "!";
  3240. if( lazyExpr ) {
  3241. if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )
  3242. os << "(" << *lazyExpr.m_transientExpression << ")";
  3243. else
  3244. os << *lazyExpr.m_transientExpression;
  3245. }
  3246. else {
  3247. os << "{** error - unchecked empty expression requested **}";
  3248. }
  3249. return os;
  3250. }
  3251. AssertionHandler::AssertionHandler
  3252. ( StringRef macroName,
  3253. SourceLineInfo const& lineInfo,
  3254. StringRef capturedExpression,
  3255. ResultDisposition::Flags resultDisposition )
  3256. : m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition }
  3257. {
  3258. getCurrentContext().getResultCapture()->assertionStarting( m_assertionInfo );
  3259. }
  3260. AssertionHandler::~AssertionHandler() {
  3261. if ( m_inExceptionGuard ) {
  3262. handle( ResultWas::ThrewException, "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE" );
  3263. getCurrentContext().getResultCapture()->exceptionEarlyReported();
  3264. }
  3265. }
  3266. void AssertionHandler::handle( ITransientExpression const& expr ) {
  3267. bool negated = isFalseTest( m_assertionInfo.resultDisposition );
  3268. bool result = expr.getResult() != negated;
  3269. handle( result ? ResultWas::Ok : ResultWas::ExpressionFailed, &expr, negated );
  3270. }
  3271. void AssertionHandler::handle( ResultWas::OfType resultType ) {
  3272. handle( resultType, nullptr, false );
  3273. }
  3274. void AssertionHandler::handle( ResultWas::OfType resultType, StringRef const& message ) {
  3275. AssertionResultData data( resultType, LazyExpression( false ) );
  3276. data.message = message;
  3277. handle( data, nullptr );
  3278. }
  3279. void AssertionHandler::handle( ResultWas::OfType resultType, ITransientExpression const* expr, bool negated ) {
  3280. AssertionResultData data( resultType, LazyExpression( negated ) );
  3281. handle( data, expr );
  3282. }
  3283. void AssertionHandler::handle( AssertionResultData const& resultData, ITransientExpression const* expr ) {
  3284. getResultCapture().assertionRun();
  3285. AssertionResult assertionResult{ m_assertionInfo, resultData };
  3286. assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
  3287. getResultCapture().assertionEnded( assertionResult );
  3288. if( !assertionResult.isOk() ) {
  3289. m_shouldDebugBreak = getCurrentContext().getConfig()->shouldDebugBreak();
  3290. m_shouldThrow =
  3291. getCurrentContext().getRunner()->aborting() ||
  3292. (m_assertionInfo.resultDisposition & ResultDisposition::Normal);
  3293. }
  3294. }
  3295. auto AssertionHandler::allowThrows() const -> bool {
  3296. return getCurrentContext().getConfig()->allowThrows();
  3297. }
  3298. auto AssertionHandler::shouldDebugBreak() const -> bool {
  3299. return m_shouldDebugBreak;
  3300. }
  3301. void AssertionHandler::reactWithDebugBreak() const {
  3302. if (m_shouldDebugBreak) {
  3303. ///////////////////////////////////////////////////////////////////
  3304. // To inspect the state during test, you need to go one level up the callstack
  3305. // To go back to the test and change execution, jump over the reactWithoutDebugBreak() call
  3306. ///////////////////////////////////////////////////////////////////
  3307. CATCH_BREAK_INTO_DEBUGGER();
  3308. }
  3309. reactWithoutDebugBreak();
  3310. }
  3311. void AssertionHandler::reactWithoutDebugBreak() const {
  3312. if( m_shouldThrow )
  3313. throw Catch::TestFailureException();
  3314. }
  3315. void AssertionHandler::useActiveException() {
  3316. handle( ResultWas::ThrewException, Catch::translateActiveException() );
  3317. }
  3318. void AssertionHandler::setExceptionGuard() {
  3319. assert( m_inExceptionGuard == false );
  3320. m_inExceptionGuard = true;
  3321. }
  3322. void AssertionHandler::unsetExceptionGuard() {
  3323. assert( m_inExceptionGuard == true );
  3324. m_inExceptionGuard = false;
  3325. }
  3326. // This is the overload that takes a string and infers the Equals matcher from it
  3327. // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
  3328. void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef matcherString ) {
  3329. handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
  3330. }
  3331. } // namespace Catch
  3332. // end catch_assertionhandler.cpp
  3333. // start catch_assertionresult.cpp
  3334. namespace Catch {
  3335. AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression):
  3336. lazyExpression(_lazyExpression),
  3337. resultType(_resultType) {}
  3338. std::string AssertionResultData::reconstructExpression() const {
  3339. if( reconstructedExpression.empty() ) {
  3340. if( lazyExpression ) {
  3341. // !TBD Use stringstream for now, but rework above to pass stream in
  3342. std::ostringstream oss;
  3343. oss << lazyExpression;
  3344. reconstructedExpression = oss.str();
  3345. }
  3346. }
  3347. return reconstructedExpression;
  3348. }
  3349. AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
  3350. : m_info( info ),
  3351. m_resultData( data )
  3352. {}
  3353. // Result was a success
  3354. bool AssertionResult::succeeded() const {
  3355. return Catch::isOk( m_resultData.resultType );
  3356. }
  3357. // Result was a success, or failure is suppressed
  3358. bool AssertionResult::isOk() const {
  3359. return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
  3360. }
  3361. ResultWas::OfType AssertionResult::getResultType() const {
  3362. return m_resultData.resultType;
  3363. }
  3364. bool AssertionResult::hasExpression() const {
  3365. return m_info.capturedExpression[0] != 0;
  3366. }
  3367. bool AssertionResult::hasMessage() const {
  3368. return !m_resultData.message.empty();
  3369. }
  3370. std::string AssertionResult::getExpression() const {
  3371. if (isFalseTest(m_info.resultDisposition))
  3372. return '!' + std::string(m_info.capturedExpression);
  3373. else
  3374. return m_info.capturedExpression;
  3375. }
  3376. std::string AssertionResult::getExpressionInMacro() const {
  3377. std::string expr;
  3378. if( m_info.macroName[0] == 0 )
  3379. expr = m_info.capturedExpression;
  3380. else {
  3381. expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
  3382. expr += m_info.macroName;
  3383. expr += "( ";
  3384. expr += m_info.capturedExpression;
  3385. expr += " )";
  3386. }
  3387. return expr;
  3388. }
  3389. bool AssertionResult::hasExpandedExpression() const {
  3390. return hasExpression() && getExpandedExpression() != getExpression();
  3391. }
  3392. std::string AssertionResult::getExpandedExpression() const {
  3393. std::string expr = m_resultData.reconstructExpression();
  3394. return expr.empty()
  3395. ? getExpression()
  3396. : expr;
  3397. }
  3398. std::string AssertionResult::getMessage() const {
  3399. return m_resultData.message;
  3400. }
  3401. SourceLineInfo AssertionResult::getSourceInfo() const {
  3402. return m_info.lineInfo;
  3403. }
  3404. std::string AssertionResult::getTestMacroName() const {
  3405. return m_info.macroName;
  3406. }
  3407. } // end namespace Catch
  3408. // end catch_assertionresult.cpp
  3409. // start catch_benchmark.cpp
  3410. namespace Catch {
  3411. auto BenchmarkLooper::getResolution() -> uint64_t {
  3412. return getEstimatedClockResolution() * getCurrentContext().getConfig()->benchmarkResolutionMultiple();
  3413. }
  3414. void BenchmarkLooper::reportStart() {
  3415. getResultCapture().benchmarkStarting( { m_name } );
  3416. }
  3417. auto BenchmarkLooper::needsMoreIterations() -> bool {
  3418. auto elapsed = m_timer.getElapsedNanoseconds();
  3419. // Exponentially increasing iterations until we're confident in our timer resolution
  3420. if( elapsed < m_resolution ) {
  3421. m_iterationsToRun *= 10;
  3422. return true;
  3423. }
  3424. getResultCapture().benchmarkEnded( { { m_name }, m_count, elapsed } );
  3425. return false;
  3426. }
  3427. } // end namespace Catch
  3428. // end catch_benchmark.cpp
  3429. // start catch_capture_matchers.cpp
  3430. namespace Catch {
  3431. using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
  3432. // This is the general overload that takes a any string matcher
  3433. // There is another overload, in catch_assertinhandler.h/.cpp, that only takes a string and infers
  3434. // the Equals matcher (so the header does not mention matchers)
  3435. void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString ) {
  3436. std::string exceptionMessage = Catch::translateActiveException();
  3437. MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );
  3438. handler.handle( expr );
  3439. }
  3440. } // namespace Catch
  3441. // end catch_capture_matchers.cpp
  3442. // start catch_commandline.cpp
  3443. // start catch_commandline.h
  3444. // start catch_clara.h
  3445. // Use Catch's value for console width (store Clara's off to the side, if present)
  3446. #ifdef CLARA_CONFIG_CONSOLE_WIDTH
  3447. #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
  3448. #undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
  3449. #endif
  3450. #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1
  3451. #ifdef __clang__
  3452. #pragma clang diagnostic push
  3453. #pragma clang diagnostic ignored "-Wweak-vtables"
  3454. #pragma clang diagnostic ignored "-Wexit-time-destructors"
  3455. #pragma clang diagnostic ignored "-Wshadow"
  3456. #endif
  3457. // start clara.hpp
  3458. // v1.0
  3459. // See https://github.com/philsquared/Clara
  3460. #ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
  3461. #define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
  3462. #endif
  3463. #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
  3464. #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
  3465. #endif
  3466. // ----------- #included from clara_textflow.hpp -----------
  3467. // TextFlowCpp
  3468. //
  3469. // A single-header library for wrapping and laying out basic text, by Phil Nash
  3470. //
  3471. // This work is licensed under the BSD 2-Clause license.
  3472. // See the accompanying LICENSE file, or the one at https://opensource.org/licenses/BSD-2-Clause
  3473. //
  3474. // This project is hosted at https://github.com/philsquared/textflowcpp
  3475. #include <cassert>
  3476. #include <ostream>
  3477. #include <sstream>
  3478. #include <vector>
  3479. #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
  3480. #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80
  3481. #endif
  3482. namespace Catch { namespace clara { namespace TextFlow {
  3483. inline auto isWhitespace( char c ) -> bool {
  3484. static std::string chars = " \t\n\r";
  3485. return chars.find( c ) != std::string::npos;
  3486. }
  3487. inline auto isBreakableBefore( char c ) -> bool {
  3488. static std::string chars = "[({<|";
  3489. return chars.find( c ) != std::string::npos;
  3490. }
  3491. inline auto isBreakableAfter( char c ) -> bool {
  3492. static std::string chars = "])}>.,:;*+-=&/\\";
  3493. return chars.find( c ) != std::string::npos;
  3494. }
  3495. class Columns;
  3496. class Column {
  3497. std::vector<std::string> m_strings;
  3498. size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
  3499. size_t m_indent = 0;
  3500. size_t m_initialIndent = std::string::npos;
  3501. public:
  3502. class iterator {
  3503. friend Column;
  3504. Column const& m_column;
  3505. size_t m_stringIndex = 0;
  3506. size_t m_pos = 0;
  3507. size_t m_len = 0;
  3508. size_t m_end = 0;
  3509. bool m_suffix = false;
  3510. iterator( Column const& column, size_t stringIndex )
  3511. : m_column( column ),
  3512. m_stringIndex( stringIndex )
  3513. {}
  3514. auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
  3515. auto isBoundary( size_t at ) const -> bool {
  3516. assert( at > 0 );
  3517. assert( at <= line().size() );
  3518. return at == line().size() ||
  3519. ( isWhitespace( line()[at] ) && !isWhitespace( line()[at-1] ) ) ||
  3520. isBreakableBefore( line()[at] ) ||
  3521. isBreakableAfter( line()[at-1] );
  3522. }
  3523. void calcLength() {
  3524. assert( m_stringIndex < m_column.m_strings.size() );
  3525. m_suffix = false;
  3526. auto width = m_column.m_width-indent();
  3527. m_end = m_pos;
  3528. while( m_end < line().size() && line()[m_end] != '\n' )
  3529. ++m_end;
  3530. if( m_end < m_pos + width ) {
  3531. m_len = m_end - m_pos;
  3532. }
  3533. else {
  3534. size_t len = width;
  3535. while (len > 0 && !isBoundary(m_pos + len))
  3536. --len;
  3537. while (len > 0 && isWhitespace( line()[m_pos + len - 1] ))
  3538. --len;
  3539. if (len > 0) {
  3540. m_len = len;
  3541. } else {
  3542. m_suffix = true;
  3543. m_len = width - 1;
  3544. }
  3545. }
  3546. }
  3547. auto indent() const -> size_t {
  3548. auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
  3549. return initial == std::string::npos ? m_column.m_indent : initial;
  3550. }
  3551. auto addIndentAndSuffix(std::string const &plain) const -> std::string {
  3552. return std::string( indent(), ' ' ) + (m_suffix ? plain + "-" : plain);
  3553. }
  3554. public:
  3555. explicit iterator( Column const& column ) : m_column( column ) {
  3556. assert( m_column.m_width > m_column.m_indent );
  3557. assert( m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent );
  3558. calcLength();
  3559. if( m_len == 0 )
  3560. m_stringIndex++; // Empty string
  3561. }
  3562. auto operator *() const -> std::string {
  3563. assert( m_stringIndex < m_column.m_strings.size() );
  3564. assert( m_pos <= m_end );
  3565. if( m_pos + m_column.m_width < m_end )
  3566. return addIndentAndSuffix(line().substr(m_pos, m_len));
  3567. else
  3568. return addIndentAndSuffix(line().substr(m_pos, m_end - m_pos));
  3569. }
  3570. auto operator ++() -> iterator& {
  3571. m_pos += m_len;
  3572. if( m_pos < line().size() && line()[m_pos] == '\n' )
  3573. m_pos += 1;
  3574. else
  3575. while( m_pos < line().size() && isWhitespace( line()[m_pos] ) )
  3576. ++m_pos;
  3577. if( m_pos == line().size() ) {
  3578. m_pos = 0;
  3579. ++m_stringIndex;
  3580. }
  3581. if( m_stringIndex < m_column.m_strings.size() )
  3582. calcLength();
  3583. return *this;
  3584. }
  3585. auto operator ++(int) -> iterator {
  3586. iterator prev( *this );
  3587. operator++();
  3588. return prev;
  3589. }
  3590. auto operator ==( iterator const& other ) const -> bool {
  3591. return
  3592. m_pos == other.m_pos &&
  3593. m_stringIndex == other.m_stringIndex &&
  3594. &m_column == &other.m_column;
  3595. }
  3596. auto operator !=( iterator const& other ) const -> bool {
  3597. return !operator==( other );
  3598. }
  3599. };
  3600. using const_iterator = iterator;
  3601. explicit Column( std::string const& text ) { m_strings.push_back( text ); }
  3602. auto width( size_t newWidth ) -> Column& {
  3603. assert( newWidth > 0 );
  3604. m_width = newWidth;
  3605. return *this;
  3606. }
  3607. auto indent( size_t newIndent ) -> Column& {
  3608. m_indent = newIndent;
  3609. return *this;
  3610. }
  3611. auto initialIndent( size_t newIndent ) -> Column& {
  3612. m_initialIndent = newIndent;
  3613. return *this;
  3614. }
  3615. auto width() const -> size_t { return m_width; }
  3616. auto begin() const -> iterator { return iterator( *this ); }
  3617. auto end() const -> iterator { return { *this, m_strings.size() }; }
  3618. inline friend std::ostream& operator << ( std::ostream& os, Column const& col ) {
  3619. bool first = true;
  3620. for( auto line : col ) {
  3621. if( first )
  3622. first = false;
  3623. else
  3624. os << "\n";
  3625. os << line;
  3626. }
  3627. return os;
  3628. }
  3629. auto operator + ( Column const& other ) -> Columns;
  3630. auto toString() const -> std::string {
  3631. std::ostringstream oss;
  3632. oss << *this;
  3633. return oss.str();
  3634. }
  3635. };
  3636. class Spacer : public Column {
  3637. public:
  3638. explicit Spacer( size_t spaceWidth ) : Column( "" ) {
  3639. width( spaceWidth );
  3640. }
  3641. };
  3642. class Columns {
  3643. std::vector<Column> m_columns;
  3644. public:
  3645. class iterator {
  3646. friend Columns;
  3647. struct EndTag {};
  3648. std::vector<Column> const& m_columns;
  3649. std::vector<Column::iterator> m_iterators;
  3650. size_t m_activeIterators;
  3651. iterator( Columns const& columns, EndTag )
  3652. : m_columns( columns.m_columns ),
  3653. m_activeIterators( 0 )
  3654. {
  3655. m_iterators.reserve( m_columns.size() );
  3656. for( auto const& col : m_columns )
  3657. m_iterators.push_back( col.end() );
  3658. }
  3659. public:
  3660. explicit iterator( Columns const& columns )
  3661. : m_columns( columns.m_columns ),
  3662. m_activeIterators( m_columns.size() )
  3663. {
  3664. m_iterators.reserve( m_columns.size() );
  3665. for( auto const& col : m_columns )
  3666. m_iterators.push_back( col.begin() );
  3667. }
  3668. auto operator ==( iterator const& other ) const -> bool {
  3669. return m_iterators == other.m_iterators;
  3670. }
  3671. auto operator !=( iterator const& other ) const -> bool {
  3672. return m_iterators != other.m_iterators;
  3673. }
  3674. auto operator *() const -> std::string {
  3675. std::string row, padding;
  3676. for( size_t i = 0; i < m_columns.size(); ++i ) {
  3677. auto width = m_columns[i].width();
  3678. if( m_iterators[i] != m_columns[i].end() ) {
  3679. std::string col = *m_iterators[i];
  3680. row += padding + col;
  3681. if( col.size() < width )
  3682. padding = std::string( width - col.size(), ' ' );
  3683. else
  3684. padding = "";
  3685. }
  3686. else {
  3687. padding += std::string( width, ' ' );
  3688. }
  3689. }
  3690. return row;
  3691. }
  3692. auto operator ++() -> iterator& {
  3693. for( size_t i = 0; i < m_columns.size(); ++i ) {
  3694. if (m_iterators[i] != m_columns[i].end())
  3695. ++m_iterators[i];
  3696. }
  3697. return *this;
  3698. }
  3699. auto operator ++(int) -> iterator {
  3700. iterator prev( *this );
  3701. operator++();
  3702. return prev;
  3703. }
  3704. };
  3705. using const_iterator = iterator;
  3706. auto begin() const -> iterator { return iterator( *this ); }
  3707. auto end() const -> iterator { return { *this, iterator::EndTag() }; }
  3708. auto operator += ( Column const& col ) -> Columns& {
  3709. m_columns.push_back( col );
  3710. return *this;
  3711. }
  3712. auto operator + ( Column const& col ) -> Columns {
  3713. Columns combined = *this;
  3714. combined += col;
  3715. return combined;
  3716. }
  3717. inline friend std::ostream& operator << ( std::ostream& os, Columns const& cols ) {
  3718. bool first = true;
  3719. for( auto line : cols ) {
  3720. if( first )
  3721. first = false;
  3722. else
  3723. os << "\n";
  3724. os << line;
  3725. }
  3726. return os;
  3727. }
  3728. auto toString() const -> std::string {
  3729. std::ostringstream oss;
  3730. oss << *this;
  3731. return oss.str();
  3732. }
  3733. };
  3734. inline auto Column::operator + ( Column const& other ) -> Columns {
  3735. Columns cols;
  3736. cols += *this;
  3737. cols += other;
  3738. return cols;
  3739. }
  3740. }}} // namespace Catch::clara::TextFlow
  3741. // ----------- end of #include from clara_textflow.hpp -----------
  3742. // ........... back in clara.hpp
  3743. #include <memory>
  3744. #include <set>
  3745. #include <algorithm>
  3746. #if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )
  3747. #define CATCH_PLATFORM_WINDOWS
  3748. #endif
  3749. namespace Catch { namespace clara {
  3750. namespace detail {
  3751. // Traits for extracting arg and return type of lambdas (for single argument lambdas)
  3752. template<typename L>
  3753. struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {};
  3754. template<typename ClassT, typename ReturnT, typename... Args>
  3755. struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> {
  3756. static const bool isValid = false;
  3757. };
  3758. template<typename ClassT, typename ReturnT, typename ArgT>
  3759. struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
  3760. static const bool isValid = true;
  3761. using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;;
  3762. using ReturnType = ReturnT;
  3763. };
  3764. class TokenStream;
  3765. // Transport for raw args (copied from main args, or supplied via init list for testing)
  3766. class Args {
  3767. friend TokenStream;
  3768. std::string m_exeName;
  3769. std::vector<std::string> m_args;
  3770. public:
  3771. Args( int argc, char *argv[] ) {
  3772. m_exeName = argv[0];
  3773. for( int i = 1; i < argc; ++i )
  3774. m_args.push_back( argv[i] );
  3775. }
  3776. Args( std::initializer_list<std::string> args )
  3777. : m_exeName( *args.begin() ),
  3778. m_args( args.begin()+1, args.end() )
  3779. {}
  3780. auto exeName() const -> std::string {
  3781. return m_exeName;
  3782. }
  3783. };
  3784. // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string
  3785. // may encode an option + its argument if the : or = form is used
  3786. enum class TokenType {
  3787. Option, Argument
  3788. };
  3789. struct Token {
  3790. TokenType type;
  3791. std::string token;
  3792. };
  3793. // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
  3794. class TokenStream {
  3795. using Iterator = std::vector<std::string>::const_iterator;
  3796. Iterator it;
  3797. Iterator itEnd;
  3798. std::vector<Token> m_tokenBuffer;
  3799. void loadBuffer() {
  3800. m_tokenBuffer.resize( 0 );
  3801. // Skip any empty strings
  3802. while( it != itEnd && it->empty() )
  3803. ++it;
  3804. if( it != itEnd ) {
  3805. auto const &next = *it;
  3806. if( next[0] == '-' || next[0] == '/' ) {
  3807. auto delimiterPos = next.find_first_of( " :=" );
  3808. if( delimiterPos != std::string::npos ) {
  3809. m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
  3810. m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } );
  3811. } else {
  3812. if( next[1] != '-' && next.size() > 2 ) {
  3813. std::string opt = "- ";
  3814. for( size_t i = 1; i < next.size(); ++i ) {
  3815. opt[1] = next[i];
  3816. m_tokenBuffer.push_back( { TokenType::Option, opt } );
  3817. }
  3818. } else {
  3819. m_tokenBuffer.push_back( { TokenType::Option, next } );
  3820. }
  3821. }
  3822. } else {
  3823. m_tokenBuffer.push_back( { TokenType::Argument, next } );
  3824. }
  3825. }
  3826. }
  3827. public:
  3828. explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {}
  3829. TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) {
  3830. loadBuffer();
  3831. }
  3832. explicit operator bool() const {
  3833. return !m_tokenBuffer.empty() || it != itEnd;
  3834. }
  3835. auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }
  3836. auto operator*() const -> Token {
  3837. assert( !m_tokenBuffer.empty() );
  3838. return m_tokenBuffer.front();
  3839. }
  3840. auto operator->() const -> Token const * {
  3841. assert( !m_tokenBuffer.empty() );
  3842. return &m_tokenBuffer.front();
  3843. }
  3844. auto operator++() -> TokenStream & {
  3845. if( m_tokenBuffer.size() >= 2 ) {
  3846. m_tokenBuffer.erase( m_tokenBuffer.begin() );
  3847. } else {
  3848. if( it != itEnd )
  3849. ++it;
  3850. loadBuffer();
  3851. }
  3852. return *this;
  3853. }
  3854. };
  3855. class ResultBase {
  3856. public:
  3857. enum Type {
  3858. Ok, LogicError, RuntimeError
  3859. };
  3860. protected:
  3861. ResultBase( Type type ) : m_type( type ) {}
  3862. virtual ~ResultBase() = default;
  3863. virtual void enforceOk() const = 0;
  3864. Type m_type;
  3865. };
  3866. template<typename T>
  3867. class ResultValueBase : public ResultBase {
  3868. public:
  3869. auto value() const -> T const & {
  3870. enforceOk();
  3871. return m_value;
  3872. }
  3873. protected:
  3874. ResultValueBase( Type type ) : ResultBase( type ) {}
  3875. ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) {
  3876. if( m_type == ResultBase::Ok )
  3877. new( &m_value ) T( other.m_value );
  3878. }
  3879. ResultValueBase( Type, T const &value ) : ResultBase( Ok ) {
  3880. new( &m_value ) T( value );
  3881. }
  3882. auto operator=( ResultValueBase const &other ) -> ResultValueBase & {
  3883. if( m_type == ResultBase::Ok )
  3884. m_value.~T();
  3885. ResultBase::operator=(other);
  3886. if( m_type == ResultBase::Ok )
  3887. new( &m_value ) T( other.m_value );
  3888. return *this;
  3889. }
  3890. ~ResultValueBase() {
  3891. if( m_type == Ok )
  3892. m_value.~T();
  3893. }
  3894. union {
  3895. T m_value;
  3896. };
  3897. };
  3898. template<>
  3899. class ResultValueBase<void> : public ResultBase {
  3900. protected:
  3901. using ResultBase::ResultBase;
  3902. };
  3903. template<typename T = void>
  3904. class BasicResult : public ResultValueBase<T> {
  3905. public:
  3906. template<typename U>
  3907. explicit BasicResult( BasicResult<U> const &other )
  3908. : ResultValueBase<T>( other.type() ),
  3909. m_errorMessage( other.errorMessage() )
  3910. {
  3911. assert( type() != ResultBase::Ok );
  3912. }
  3913. template<typename U>
  3914. static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; }
  3915. static auto ok() -> BasicResult { return { ResultBase::Ok }; }
  3916. static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; }
  3917. static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; }
  3918. explicit operator bool() const { return m_type == ResultBase::Ok; }
  3919. auto type() const -> ResultBase::Type { return m_type; }
  3920. auto errorMessage() const -> std::string { return m_errorMessage; }
  3921. protected:
  3922. virtual void enforceOk() const {
  3923. // !TBD: If no exceptions, std::terminate here or something
  3924. switch( m_type ) {
  3925. case ResultBase::LogicError:
  3926. throw std::logic_error( m_errorMessage );
  3927. case ResultBase::RuntimeError:
  3928. throw std::runtime_error( m_errorMessage );
  3929. case ResultBase::Ok:
  3930. break;
  3931. }
  3932. }
  3933. std::string m_errorMessage; // Only populated if resultType is an error
  3934. BasicResult( ResultBase::Type type, std::string const &message )
  3935. : ResultValueBase<T>(type),
  3936. m_errorMessage(message)
  3937. {
  3938. assert( m_type != ResultBase::Ok );
  3939. }
  3940. using ResultValueBase<T>::ResultValueBase;
  3941. using ResultBase::m_type;
  3942. };
  3943. enum class ParseResultType {
  3944. Matched, NoMatch, ShortCircuitAll, ShortCircuitSame
  3945. };
  3946. class ParseState {
  3947. public:
  3948. ParseState( ParseResultType type, TokenStream const &remainingTokens )
  3949. : m_type(type),
  3950. m_remainingTokens( remainingTokens )
  3951. {}
  3952. auto type() const -> ParseResultType { return m_type; }
  3953. auto remainingTokens() const -> TokenStream { return m_remainingTokens; }
  3954. private:
  3955. ParseResultType m_type;
  3956. TokenStream m_remainingTokens;
  3957. };
  3958. using Result = BasicResult<void>;
  3959. using ParserResult = BasicResult<ParseResultType>;
  3960. using InternalParseResult = BasicResult<ParseState>;
  3961. struct HelpColumns {
  3962. std::string left;
  3963. std::string right;
  3964. };
  3965. template<typename T>
  3966. inline auto convertInto( std::string const &source, T& target ) -> ParserResult {
  3967. std::stringstream ss;
  3968. ss << source;
  3969. ss >> target;
  3970. if( ss.fail() )
  3971. return ParserResult::runtimeError( "Unable to convert '" + source + "' to destination type" );
  3972. else
  3973. return ParserResult::ok( ParseResultType::Matched );
  3974. }
  3975. inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult {
  3976. target = source;
  3977. return ParserResult::ok( ParseResultType::Matched );
  3978. }
  3979. inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {
  3980. std::string srcLC = source;
  3981. std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast<char>( ::tolower(c) ); } );
  3982. if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
  3983. target = true;
  3984. else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
  3985. target = false;
  3986. else
  3987. return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" );
  3988. return ParserResult::ok( ParseResultType::Matched );
  3989. }
  3990. struct BoundRefBase {
  3991. BoundRefBase() = default;
  3992. BoundRefBase( BoundRefBase const & ) = delete;
  3993. BoundRefBase( BoundRefBase && ) = delete;
  3994. BoundRefBase &operator=( BoundRefBase const & ) = delete;
  3995. BoundRefBase &operator=( BoundRefBase && ) = delete;
  3996. virtual ~BoundRefBase() = default;
  3997. virtual auto isFlag() const -> bool = 0;
  3998. virtual auto isContainer() const -> bool { return false; }
  3999. virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
  4000. virtual auto setFlag( bool flag ) -> ParserResult = 0;
  4001. };
  4002. struct BoundValueRefBase : BoundRefBase {
  4003. auto isFlag() const -> bool override { return false; }
  4004. auto setFlag( bool ) -> ParserResult override {
  4005. return ParserResult::logicError( "Flags can only be set on boolean fields" );
  4006. }
  4007. };
  4008. struct BoundFlagRefBase : BoundRefBase {
  4009. auto isFlag() const -> bool override { return true; }
  4010. auto setValue( std::string const &arg ) -> ParserResult override {
  4011. bool flag;
  4012. auto result = convertInto( arg, flag );
  4013. if( result )
  4014. setFlag( flag );
  4015. return result;
  4016. }
  4017. };
  4018. template<typename T>
  4019. struct BoundRef : BoundValueRefBase {
  4020. T &m_ref;
  4021. explicit BoundRef( T &ref ) : m_ref( ref ) {}
  4022. auto setValue( std::string const &arg ) -> ParserResult override {
  4023. return convertInto( arg, m_ref );
  4024. }
  4025. };
  4026. template<typename T>
  4027. struct BoundRef<std::vector<T>> : BoundValueRefBase {
  4028. std::vector<T> &m_ref;
  4029. explicit BoundRef( std::vector<T> &ref ) : m_ref( ref ) {}
  4030. auto isContainer() const -> bool override { return true; }
  4031. auto setValue( std::string const &arg ) -> ParserResult override {
  4032. T temp;
  4033. auto result = convertInto( arg, temp );
  4034. if( result )
  4035. m_ref.push_back( temp );
  4036. return result;
  4037. }
  4038. };
  4039. struct BoundFlagRef : BoundFlagRefBase {
  4040. bool &m_ref;
  4041. explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {}
  4042. auto setFlag( bool flag ) -> ParserResult override {
  4043. m_ref = flag;
  4044. return ParserResult::ok( ParseResultType::Matched );
  4045. }
  4046. };
  4047. template<typename ReturnType>
  4048. struct LambdaInvoker {
  4049. static_assert( std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult" );
  4050. template<typename L, typename ArgType>
  4051. static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
  4052. return lambda( arg );
  4053. }
  4054. };
  4055. template<>
  4056. struct LambdaInvoker<void> {
  4057. template<typename L, typename ArgType>
  4058. static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
  4059. lambda( arg );
  4060. return ParserResult::ok( ParseResultType::Matched );
  4061. }
  4062. };
  4063. template<typename ArgType, typename L>
  4064. inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
  4065. ArgType temp;
  4066. auto result = convertInto( arg, temp );
  4067. return !result
  4068. ? result
  4069. : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
  4070. };
  4071. template<typename L>
  4072. struct BoundLambda : BoundValueRefBase {
  4073. L m_lambda;
  4074. static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
  4075. explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {}
  4076. auto setValue( std::string const &arg ) -> ParserResult override {
  4077. return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg );
  4078. }
  4079. };
  4080. template<typename L>
  4081. struct BoundFlagLambda : BoundFlagRefBase {
  4082. L m_lambda;
  4083. static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
  4084. static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean" );
  4085. explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {}
  4086. auto setFlag( bool flag ) -> ParserResult override {
  4087. return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag );
  4088. }
  4089. };
  4090. enum class Optionality { Optional, Required };
  4091. struct Parser;
  4092. class ParserBase {
  4093. public:
  4094. virtual ~ParserBase() = default;
  4095. virtual auto validate() const -> Result { return Result::ok(); }
  4096. virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult = 0;
  4097. virtual auto cardinality() const -> size_t { return 1; }
  4098. auto parse( Args const &args ) const -> InternalParseResult {
  4099. return parse( args.exeName(), TokenStream( args ) );
  4100. }
  4101. };
  4102. template<typename DerivedT>
  4103. class ComposableParserImpl : public ParserBase {
  4104. public:
  4105. template<typename T>
  4106. auto operator|( T const &other ) const -> Parser;
  4107. };
  4108. // Common code and state for Args and Opts
  4109. template<typename DerivedT>
  4110. class ParserRefImpl : public ComposableParserImpl<DerivedT> {
  4111. protected:
  4112. Optionality m_optionality = Optionality::Optional;
  4113. std::shared_ptr<BoundRefBase> m_ref;
  4114. std::string m_hint;
  4115. std::string m_description;
  4116. explicit ParserRefImpl( std::shared_ptr<BoundRefBase> const &ref ) : m_ref( ref ) {}
  4117. public:
  4118. template<typename T>
  4119. ParserRefImpl( T &ref, std::string const &hint )
  4120. : m_ref( std::make_shared<BoundRef<T>>( ref ) ),
  4121. m_hint( hint )
  4122. {}
  4123. template<typename LambdaT>
  4124. ParserRefImpl( LambdaT const &ref, std::string const &hint )
  4125. : m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
  4126. m_hint(hint)
  4127. {}
  4128. auto operator()( std::string const &description ) -> DerivedT & {
  4129. m_description = description;
  4130. return static_cast<DerivedT &>( *this );
  4131. }
  4132. auto optional() -> DerivedT & {
  4133. m_optionality = Optionality::Optional;
  4134. return static_cast<DerivedT &>( *this );
  4135. };
  4136. auto required() -> DerivedT & {
  4137. m_optionality = Optionality::Required;
  4138. return static_cast<DerivedT &>( *this );
  4139. };
  4140. auto isOptional() const -> bool {
  4141. return m_optionality == Optionality::Optional;
  4142. }
  4143. auto cardinality() const -> size_t override {
  4144. if( m_ref->isContainer() )
  4145. return 0;
  4146. else
  4147. return 1;
  4148. }
  4149. auto hint() const -> std::string { return m_hint; }
  4150. };
  4151. class ExeName : public ComposableParserImpl<ExeName> {
  4152. std::shared_ptr<std::string> m_name;
  4153. std::shared_ptr<BoundRefBase> m_ref;
  4154. template<typename LambdaT>
  4155. static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundRefBase> {
  4156. return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
  4157. }
  4158. public:
  4159. ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
  4160. explicit ExeName( std::string &ref ) : ExeName() {
  4161. m_ref = std::make_shared<BoundRef<std::string>>( ref );
  4162. }
  4163. template<typename LambdaT>
  4164. explicit ExeName( LambdaT const& lambda ) : ExeName() {
  4165. m_ref = std::make_shared<BoundLambda<LambdaT>>( lambda );
  4166. }
  4167. // The exe name is not parsed out of the normal tokens, but is handled specially
  4168. auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
  4169. return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
  4170. }
  4171. auto name() const -> std::string { return *m_name; }
  4172. auto set( std::string const& newName ) -> ParserResult {
  4173. auto lastSlash = newName.find_last_of( "\\/" );
  4174. auto filename = ( lastSlash == std::string::npos )
  4175. ? newName
  4176. : newName.substr( lastSlash+1 );
  4177. *m_name = filename;
  4178. if( m_ref )
  4179. return m_ref->setValue( filename );
  4180. else
  4181. return ParserResult::ok( ParseResultType::Matched );
  4182. }
  4183. };
  4184. class Arg : public ParserRefImpl<Arg> {
  4185. public:
  4186. using ParserRefImpl::ParserRefImpl;
  4187. auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override {
  4188. auto validationResult = validate();
  4189. if( !validationResult )
  4190. return InternalParseResult( validationResult );
  4191. auto remainingTokens = tokens;
  4192. auto const &token = *remainingTokens;
  4193. if( token.type != TokenType::Argument )
  4194. return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
  4195. auto result = m_ref->setValue( remainingTokens->token );
  4196. if( !result )
  4197. return InternalParseResult( result );
  4198. else
  4199. return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
  4200. }
  4201. };
  4202. inline auto normaliseOpt( std::string const &optName ) -> std::string {
  4203. if( optName[0] == '/' )
  4204. return "-" + optName.substr( 1 );
  4205. else
  4206. return optName;
  4207. }
  4208. class Opt : public ParserRefImpl<Opt> {
  4209. protected:
  4210. std::vector<std::string> m_optNames;
  4211. public:
  4212. template<typename LambdaT>
  4213. explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {}
  4214. explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {}
  4215. template<typename LambdaT>
  4216. Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
  4217. template<typename T>
  4218. Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
  4219. auto operator[]( std::string const &optName ) -> Opt & {
  4220. m_optNames.push_back( optName );
  4221. return *this;
  4222. }
  4223. auto getHelpColumns() const -> std::vector<HelpColumns> {
  4224. std::ostringstream oss;
  4225. bool first = true;
  4226. for( auto const &opt : m_optNames ) {
  4227. if (first)
  4228. first = false;
  4229. else
  4230. oss << ", ";
  4231. oss << opt;
  4232. }
  4233. if( !m_hint.empty() )
  4234. oss << " <" << m_hint << ">";
  4235. return { { oss.str(), m_description } };
  4236. }
  4237. auto isMatch( std::string const &optToken ) const -> bool {
  4238. #ifdef CATCH_PLATFORM_WINDOWS
  4239. auto normalisedToken = normaliseOpt( optToken );
  4240. #else
  4241. auto const &normalisedToken = optToken;
  4242. #endif
  4243. for( auto const &name : m_optNames ) {
  4244. if( normaliseOpt( name ) == normalisedToken )
  4245. return true;
  4246. }
  4247. return false;
  4248. }
  4249. using ParserBase::parse;
  4250. auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
  4251. auto validationResult = validate();
  4252. if( !validationResult )
  4253. return InternalParseResult( validationResult );
  4254. auto remainingTokens = tokens;
  4255. if( remainingTokens && remainingTokens->type == TokenType::Option ) {
  4256. auto const &token = *remainingTokens;
  4257. if( isMatch(token.token ) ) {
  4258. if( m_ref->isFlag() ) {
  4259. auto result = m_ref->setFlag( true );
  4260. if( !result )
  4261. return InternalParseResult( result );
  4262. if( result.value() == ParseResultType::ShortCircuitAll )
  4263. return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
  4264. } else {
  4265. ++remainingTokens;
  4266. if( !remainingTokens )
  4267. return InternalParseResult::runtimeError( "Expected argument following " + token.token );
  4268. auto const &argToken = *remainingTokens;
  4269. if( argToken.type != TokenType::Argument )
  4270. return InternalParseResult::runtimeError( "Expected argument following " + token.token );
  4271. auto result = m_ref->setValue( argToken.token );
  4272. if( !result )
  4273. return InternalParseResult( result );
  4274. if( result.value() == ParseResultType::ShortCircuitAll )
  4275. return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
  4276. }
  4277. return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
  4278. }
  4279. }
  4280. return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
  4281. }
  4282. auto validate() const -> Result override {
  4283. if( m_optNames.empty() )
  4284. return Result::logicError( "No options supplied to Opt" );
  4285. for( auto const &name : m_optNames ) {
  4286. if( name.empty() )
  4287. return Result::logicError( "Option name cannot be empty" );
  4288. if( name[0] != '-' && name[0] != '/' )
  4289. return Result::logicError( "Option name must begin with '-' or '/'" );
  4290. }
  4291. return ParserRefImpl::validate();
  4292. }
  4293. };
  4294. struct Help : Opt {
  4295. Help( bool &showHelpFlag )
  4296. : Opt([&]( bool flag ) {
  4297. showHelpFlag = flag;
  4298. return ParserResult::ok( ParseResultType::ShortCircuitAll );
  4299. })
  4300. {
  4301. static_cast<Opt &>( *this )
  4302. ("display usage information")
  4303. ["-?"]["-h"]["--help"]
  4304. .optional();
  4305. }
  4306. };
  4307. struct Parser : ParserBase {
  4308. mutable ExeName m_exeName;
  4309. std::vector<Opt> m_options;
  4310. std::vector<Arg> m_args;
  4311. auto operator|=( ExeName const &exeName ) -> Parser & {
  4312. m_exeName = exeName;
  4313. return *this;
  4314. }
  4315. auto operator|=( Arg const &arg ) -> Parser & {
  4316. m_args.push_back(arg);
  4317. return *this;
  4318. }
  4319. auto operator|=( Opt const &opt ) -> Parser & {
  4320. m_options.push_back(opt);
  4321. return *this;
  4322. }
  4323. auto operator|=( Parser const &other ) -> Parser & {
  4324. m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
  4325. m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
  4326. return *this;
  4327. }
  4328. template<typename T>
  4329. auto operator|( T const &other ) const -> Parser {
  4330. return Parser( *this ) |= other;
  4331. }
  4332. auto getHelpColumns() const -> std::vector<HelpColumns> {
  4333. std::vector<HelpColumns> cols;
  4334. for (auto const &o : m_options) {
  4335. auto childCols = o.getHelpColumns();
  4336. cols.insert( cols.end(), childCols.begin(), childCols.end() );
  4337. }
  4338. return cols;
  4339. }
  4340. void writeToStream( std::ostream &os ) const {
  4341. if (!m_exeName.name().empty()) {
  4342. os << "usage:\n" << " " << m_exeName.name() << " ";
  4343. bool required = true, first = true;
  4344. for( auto const &arg : m_args ) {
  4345. if (first)
  4346. first = false;
  4347. else
  4348. os << " ";
  4349. if( arg.isOptional() && required ) {
  4350. os << "[";
  4351. required = false;
  4352. }
  4353. os << "<" << arg.hint() << ">";
  4354. if( arg.cardinality() == 0 )
  4355. os << " ... ";
  4356. }
  4357. if( !required )
  4358. os << "]";
  4359. if( !m_options.empty() )
  4360. os << " options";
  4361. os << "\n\nwhere options are:" << std::endl;
  4362. }
  4363. auto rows = getHelpColumns();
  4364. size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
  4365. size_t optWidth = 0;
  4366. for( auto const &cols : rows )
  4367. optWidth = std::max(optWidth, cols.left.size() + 2);
  4368. for( auto const &cols : rows ) {
  4369. auto row =
  4370. TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
  4371. TextFlow::Spacer(4) +
  4372. TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth );
  4373. os << row << std::endl;
  4374. }
  4375. }
  4376. friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& {
  4377. parser.writeToStream( os );
  4378. return os;
  4379. }
  4380. auto validate() const -> Result override {
  4381. for( auto const &opt : m_options ) {
  4382. auto result = opt.validate();
  4383. if( !result )
  4384. return result;
  4385. }
  4386. for( auto const &arg : m_args ) {
  4387. auto result = arg.validate();
  4388. if( !result )
  4389. return result;
  4390. }
  4391. return Result::ok();
  4392. }
  4393. using ParserBase::parse;
  4394. auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override {
  4395. struct ParserInfo {
  4396. ParserBase const* parser = nullptr;
  4397. size_t count = 0;
  4398. };
  4399. const size_t totalParsers = m_options.size() + m_args.size();
  4400. assert( totalParsers < 512 );
  4401. // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
  4402. ParserInfo parseInfos[512];
  4403. {
  4404. size_t i = 0;
  4405. for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
  4406. for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
  4407. }
  4408. m_exeName.set( exeName );
  4409. auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
  4410. while( result.value().remainingTokens() ) {
  4411. bool tokenParsed = false;
  4412. for( size_t i = 0; i < totalParsers; ++i ) {
  4413. auto& parseInfo = parseInfos[i];
  4414. if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {
  4415. result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
  4416. if (!result)
  4417. return result;
  4418. if (result.value().type() != ParseResultType::NoMatch) {
  4419. tokenParsed = true;
  4420. ++parseInfo.count;
  4421. break;
  4422. }
  4423. }
  4424. }
  4425. if( result.value().type() == ParseResultType::ShortCircuitAll )
  4426. return result;
  4427. if( !tokenParsed )
  4428. return InternalParseResult::runtimeError( "Unrecognised token: " + result.value().remainingTokens()->token );
  4429. }
  4430. // !TBD Check missing required options
  4431. return result;
  4432. }
  4433. };
  4434. template<typename DerivedT>
  4435. template<typename T>
  4436. auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser {
  4437. return Parser() | static_cast<DerivedT const &>( *this ) | other;
  4438. }
  4439. } // namespace detail
  4440. // A Combined parser
  4441. using detail::Parser;
  4442. // A parser for options
  4443. using detail::Opt;
  4444. // A parser for arguments
  4445. using detail::Arg;
  4446. // Wrapper for argc, argv from main()
  4447. using detail::Args;
  4448. // Specifies the name of the executable
  4449. using detail::ExeName;
  4450. // Convenience wrapper for option parser that specifies the help option
  4451. using detail::Help;
  4452. // enum of result types from a parse
  4453. using detail::ParseResultType;
  4454. // Result type for parser operation
  4455. using detail::ParserResult;
  4456. }} // namespace Catch::clara
  4457. // end clara.hpp
  4458. #ifdef __clang__
  4459. #pragma clang diagnostic pop
  4460. #endif
  4461. // Restore Clara's value for console width, if present
  4462. #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
  4463. #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
  4464. #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
  4465. #endif
  4466. // end catch_clara.h
  4467. namespace Catch {
  4468. clara::Parser makeCommandLineParser( ConfigData& config );
  4469. } // end namespace Catch
  4470. // end catch_commandline.h
  4471. #include <fstream>
  4472. #include <ctime>
  4473. namespace Catch {
  4474. clara::Parser makeCommandLineParser( ConfigData& config ) {
  4475. using namespace clara;
  4476. auto const setWarning = [&]( std::string const& warning ) {
  4477. if( warning != "NoAssertions" )
  4478. return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" );
  4479. config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
  4480. return ParserResult::ok( ParseResultType::Matched );
  4481. };
  4482. auto const loadTestNamesFromFile = [&]( std::string const& filename ) {
  4483. std::ifstream f( filename.c_str() );
  4484. if( !f.is_open() )
  4485. return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" );
  4486. std::string line;
  4487. while( std::getline( f, line ) ) {
  4488. line = trim(line);
  4489. if( !line.empty() && !startsWith( line, '#' ) ) {
  4490. if( !startsWith( line, '"' ) )
  4491. line = '"' + line + '"';
  4492. config.testsOrTags.push_back( line + ',' );
  4493. }
  4494. }
  4495. return ParserResult::ok( ParseResultType::Matched );
  4496. };
  4497. auto const setTestOrder = [&]( std::string const& order ) {
  4498. if( startsWith( "declared", order ) )
  4499. config.runOrder = RunTests::InDeclarationOrder;
  4500. else if( startsWith( "lexical", order ) )
  4501. config.runOrder = RunTests::InLexicographicalOrder;
  4502. else if( startsWith( "random", order ) )
  4503. config.runOrder = RunTests::InRandomOrder;
  4504. else
  4505. return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" );
  4506. return ParserResult::ok( ParseResultType::Matched );
  4507. };
  4508. auto const setRngSeed = [&]( std::string const& seed ) {
  4509. if( seed != "time" )
  4510. return clara::detail::convertInto( seed, config.rngSeed );
  4511. config.rngSeed = static_cast<unsigned int>( std::time(nullptr) );
  4512. return ParserResult::ok( ParseResultType::Matched );
  4513. };
  4514. auto const setColourUsage = [&]( std::string const& useColour ) {
  4515. auto mode = toLower( useColour );
  4516. if( mode == "yes" )
  4517. config.useColour = UseColour::Yes;
  4518. else if( mode == "no" )
  4519. config.useColour = UseColour::No;
  4520. else if( mode == "auto" )
  4521. config.useColour = UseColour::Auto;
  4522. else
  4523. return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" );
  4524. return ParserResult::ok( ParseResultType::Matched );
  4525. };
  4526. auto const setWaitForKeypress = [&]( std::string const& keypress ) {
  4527. auto keypressLc = toLower( keypress );
  4528. if( keypressLc == "start" )
  4529. config.waitForKeypress = WaitForKeypress::BeforeStart;
  4530. else if( keypressLc == "exit" )
  4531. config.waitForKeypress = WaitForKeypress::BeforeExit;
  4532. else if( keypressLc == "both" )
  4533. config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
  4534. else
  4535. return ParserResult::runtimeError( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" );
  4536. return ParserResult::ok( ParseResultType::Matched );
  4537. };
  4538. auto const setVerbosity = [&]( std::string const& verbosity ) {
  4539. auto lcVerbosity = toLower( verbosity );
  4540. if( lcVerbosity == "quiet" )
  4541. config.verbosity = Verbosity::Quiet;
  4542. else if( lcVerbosity == "normal" )
  4543. config.verbosity = Verbosity::Normal;
  4544. else if( lcVerbosity == "high" )
  4545. config.verbosity = Verbosity::High;
  4546. else
  4547. return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" );
  4548. return ParserResult::ok( ParseResultType::Matched );
  4549. };
  4550. auto cli
  4551. = ExeName( config.processName )
  4552. | Help( config.showHelp )
  4553. | Opt( config.listTests )
  4554. ["-l"]["--list-tests"]
  4555. ( "list all/matching test cases" )
  4556. | Opt( config.listTags )
  4557. ["-t"]["--list-tags"]
  4558. ( "list all/matching tags" )
  4559. | Opt( config.showSuccessfulTests )
  4560. ["-s"]["--success"]
  4561. ( "include successful tests in output" )
  4562. | Opt( config.shouldDebugBreak )
  4563. ["-b"]["--break"]
  4564. ( "break into debugger on failure" )
  4565. | Opt( config.noThrow )
  4566. ["-e"]["--nothrow"]
  4567. ( "skip exception tests" )
  4568. | Opt( config.showInvisibles )
  4569. ["-i"]["--invisibles"]
  4570. ( "show invisibles (tabs, newlines)" )
  4571. | Opt( config.outputFilename, "filename" )
  4572. ["-o"]["--out"]
  4573. ( "output filename" )
  4574. | Opt( config.reporterNames, "name" )
  4575. ["-r"]["--reporter"]
  4576. ( "reporter to use (defaults to console)" )
  4577. | Opt( config.name, "name" )
  4578. ["-n"]["--name"]
  4579. ( "suite name" )
  4580. | Opt( [&]( bool ){ config.abortAfter = 1; } )
  4581. ["-a"]["--abort"]
  4582. ( "abort at first failure" )
  4583. | Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" )
  4584. ["-x"]["--abortx"]
  4585. ( "abort after x failures" )
  4586. | Opt( setWarning, "warning name" )
  4587. ["-w"]["--warn"]
  4588. ( "enable warnings" )
  4589. | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" )
  4590. ["-d"]["--durations"]
  4591. ( "show test durations" )
  4592. | Opt( loadTestNamesFromFile, "filename" )
  4593. ["-f"]["--input-file"]
  4594. ( "load test names to run from a file" )
  4595. | Opt( config.filenamesAsTags )
  4596. ["-#"]["--filenames-as-tags"]
  4597. ( "adds a tag for the filename" )
  4598. | Opt( config.sectionsToRun, "section name" )
  4599. ["-c"]["--section"]
  4600. ( "specify section to run" )
  4601. | Opt( setVerbosity, "quiet|normal|high" )
  4602. ["-v"]["--verbosity"]
  4603. ( "set output verbosity" )
  4604. | Opt( config.listTestNamesOnly )
  4605. ["--list-test-names-only"]
  4606. ( "list all/matching test cases names only" )
  4607. | Opt( config.listReporters )
  4608. ["--list-reporters"]
  4609. ( "list all reporters" )
  4610. | Opt( setTestOrder, "decl|lex|rand" )
  4611. ["--order"]
  4612. ( "test case order (defaults to decl)" )
  4613. | Opt( setRngSeed, "'time'|number" )
  4614. ["--rng-seed"]
  4615. ( "set a specific seed for random numbers" )
  4616. | Opt( setColourUsage, "yes|no" )
  4617. ["--use-colour"]
  4618. ( "should output be colourised" )
  4619. | Opt( config.libIdentify )
  4620. ["--libidentify"]
  4621. ( "report name and version according to libidentify standard" )
  4622. | Opt( setWaitForKeypress, "start|exit|both" )
  4623. ["--wait-for-keypress"]
  4624. ( "waits for a keypress before exiting" )
  4625. | Opt( config.benchmarkResolutionMultiple, "multiplier" )
  4626. ["--benchmark-resolution-multiple"]
  4627. ( "multiple of clock resolution to run benchmarks" )
  4628. | Arg( config.testsOrTags, "test name|pattern|tags" )
  4629. ( "which test or tests to use" );
  4630. return cli;
  4631. }
  4632. } // end namespace Catch
  4633. // end catch_commandline.cpp
  4634. // start catch_common.cpp
  4635. #include <cstring>
  4636. #include <ostream>
  4637. namespace Catch {
  4638. SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line ) noexcept
  4639. : file( _file ),
  4640. line( _line )
  4641. {}
  4642. bool SourceLineInfo::empty() const noexcept {
  4643. return file[0] == '\0';
  4644. }
  4645. bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {
  4646. return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
  4647. }
  4648. bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {
  4649. return line < other.line || ( line == other.line && (std::strcmp(file, other.file) < 0));
  4650. }
  4651. std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
  4652. #ifndef __GNUG__
  4653. os << info.file << '(' << info.line << ')';
  4654. #else
  4655. os << info.file << ':' << info.line;
  4656. #endif
  4657. return os;
  4658. }
  4659. bool isTrue( bool value ){ return value; }
  4660. bool alwaysTrue() { return true; }
  4661. bool alwaysFalse() { return false; }
  4662. std::string StreamEndStop::operator+() const {
  4663. return std::string();
  4664. }
  4665. NonCopyable::NonCopyable() = default;
  4666. NonCopyable::~NonCopyable() = default;
  4667. }
  4668. // end catch_common.cpp
  4669. // start catch_config.cpp
  4670. namespace Catch {
  4671. Config::Config( ConfigData const& data )
  4672. : m_data( data ),
  4673. m_stream( openStream() )
  4674. {
  4675. if( !data.testsOrTags.empty() ) {
  4676. TestSpecParser parser( ITagAliasRegistry::get() );
  4677. for( auto const& testOrTags : data.testsOrTags )
  4678. parser.parse( testOrTags );
  4679. m_testSpec = parser.testSpec();
  4680. }
  4681. }
  4682. std::string const& Config::getFilename() const {
  4683. return m_data.outputFilename ;
  4684. }
  4685. bool Config::listTests() const { return m_data.listTests; }
  4686. bool Config::listTestNamesOnly() const { return m_data.listTestNamesOnly; }
  4687. bool Config::listTags() const { return m_data.listTags; }
  4688. bool Config::listReporters() const { return m_data.listReporters; }
  4689. std::string Config::getProcessName() const { return m_data.processName; }
  4690. std::vector<std::string> const& Config::getReporterNames() const { return m_data.reporterNames; }
  4691. std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
  4692. TestSpec const& Config::testSpec() const { return m_testSpec; }
  4693. bool Config::showHelp() const { return m_data.showHelp; }
  4694. // IConfig interface
  4695. bool Config::allowThrows() const { return !m_data.noThrow; }
  4696. std::ostream& Config::stream() const { return m_stream->stream(); }
  4697. std::string Config::name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
  4698. bool Config::includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
  4699. bool Config::warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
  4700. ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
  4701. RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; }
  4702. unsigned int Config::rngSeed() const { return m_data.rngSeed; }
  4703. int Config::benchmarkResolutionMultiple() const { return m_data.benchmarkResolutionMultiple; }
  4704. UseColour::YesOrNo Config::useColour() const { return m_data.useColour; }
  4705. bool Config::shouldDebugBreak() const { return m_data.shouldDebugBreak; }
  4706. int Config::abortAfter() const { return m_data.abortAfter; }
  4707. bool Config::showInvisibles() const { return m_data.showInvisibles; }
  4708. Verbosity Config::verbosity() const { return m_data.verbosity; }
  4709. IStream const* Config::openStream() {
  4710. if( m_data.outputFilename.empty() )
  4711. return new CoutStream();
  4712. else if( m_data.outputFilename[0] == '%' ) {
  4713. if( m_data.outputFilename == "%debug" )
  4714. return new DebugOutStream();
  4715. else
  4716. CATCH_ERROR( "Unrecognised stream: '" << m_data.outputFilename << "'" );
  4717. }
  4718. else
  4719. return new FileStream( m_data.outputFilename );
  4720. }
  4721. } // end namespace Catch
  4722. // end catch_config.cpp
  4723. // start catch_console_colour.cpp
  4724. #if defined(__clang__)
  4725. # pragma clang diagnostic push
  4726. # pragma clang diagnostic ignored "-Wexit-time-destructors"
  4727. #endif
  4728. // start catch_errno_guard.h
  4729. namespace Catch {
  4730. class ErrnoGuard {
  4731. public:
  4732. ErrnoGuard();
  4733. ~ErrnoGuard();
  4734. private:
  4735. int m_oldErrno;
  4736. };
  4737. }
  4738. // end catch_errno_guard.h
  4739. // start catch_windows_h_proxy.h
  4740. #if defined(CATCH_PLATFORM_WINDOWS)
  4741. #if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
  4742. # define CATCH_DEFINED_NOMINMAX
  4743. # define NOMINMAX
  4744. #endif
  4745. #if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
  4746. # define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
  4747. # define WIN32_LEAN_AND_MEAN
  4748. #endif
  4749. #ifdef __AFXDLL
  4750. #include <AfxWin.h>
  4751. #else
  4752. #include <windows.h>
  4753. #endif
  4754. #ifdef CATCH_DEFINED_NOMINMAX
  4755. # undef NOMINMAX
  4756. #endif
  4757. #ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
  4758. # undef WIN32_LEAN_AND_MEAN
  4759. #endif
  4760. #endif // defined(CATCH_PLATFORM_WINDOWS)
  4761. // end catch_windows_h_proxy.h
  4762. namespace Catch {
  4763. namespace {
  4764. struct IColourImpl {
  4765. virtual ~IColourImpl() = default;
  4766. virtual void use( Colour::Code _colourCode ) = 0;
  4767. };
  4768. struct NoColourImpl : IColourImpl {
  4769. void use( Colour::Code ) {}
  4770. static IColourImpl* instance() {
  4771. static NoColourImpl s_instance;
  4772. return &s_instance;
  4773. }
  4774. };
  4775. } // anon namespace
  4776. } // namespace Catch
  4777. #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
  4778. # ifdef CATCH_PLATFORM_WINDOWS
  4779. # define CATCH_CONFIG_COLOUR_WINDOWS
  4780. # else
  4781. # define CATCH_CONFIG_COLOUR_ANSI
  4782. # endif
  4783. #endif
  4784. #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
  4785. namespace Catch {
  4786. namespace {
  4787. class Win32ColourImpl : public IColourImpl {
  4788. public:
  4789. Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
  4790. {
  4791. CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
  4792. GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
  4793. originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
  4794. originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
  4795. }
  4796. virtual void use( Colour::Code _colourCode ) override {
  4797. switch( _colourCode ) {
  4798. case Colour::None: return setTextAttribute( originalForegroundAttributes );
  4799. case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
  4800. case Colour::Red: return setTextAttribute( FOREGROUND_RED );
  4801. case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
  4802. case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
  4803. case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
  4804. case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
  4805. case Colour::Grey: return setTextAttribute( 0 );
  4806. case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
  4807. case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
  4808. case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
  4809. case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
  4810. case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
  4811. }
  4812. }
  4813. private:
  4814. void setTextAttribute( WORD _textAttribute ) {
  4815. SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
  4816. }
  4817. HANDLE stdoutHandle;
  4818. WORD originalForegroundAttributes;
  4819. WORD originalBackgroundAttributes;
  4820. };
  4821. IColourImpl* platformColourInstance() {
  4822. static Win32ColourImpl s_instance;
  4823. IConfigPtr config = getCurrentContext().getConfig();
  4824. UseColour::YesOrNo colourMode = config
  4825. ? config->useColour()
  4826. : UseColour::Auto;
  4827. if( colourMode == UseColour::Auto )
  4828. colourMode = UseColour::Yes;
  4829. return colourMode == UseColour::Yes
  4830. ? &s_instance
  4831. : NoColourImpl::instance();
  4832. }
  4833. } // end anon namespace
  4834. } // end namespace Catch
  4835. #elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
  4836. #include <unistd.h>
  4837. namespace Catch {
  4838. namespace {
  4839. // use POSIX/ ANSI console terminal codes
  4840. // Thanks to Adam Strzelecki for original contribution
  4841. // (http://github.com/nanoant)
  4842. // https://github.com/philsquared/Catch/pull/131
  4843. class PosixColourImpl : public IColourImpl {
  4844. public:
  4845. virtual void use( Colour::Code _colourCode ) override {
  4846. switch( _colourCode ) {
  4847. case Colour::None:
  4848. case Colour::White: return setColour( "[0m" );
  4849. case Colour::Red: return setColour( "[0;31m" );
  4850. case Colour::Green: return setColour( "[0;32m" );
  4851. case Colour::Blue: return setColour( "[0;34m" );
  4852. case Colour::Cyan: return setColour( "[0;36m" );
  4853. case Colour::Yellow: return setColour( "[0;33m" );
  4854. case Colour::Grey: return setColour( "[1;30m" );
  4855. case Colour::LightGrey: return setColour( "[0;37m" );
  4856. case Colour::BrightRed: return setColour( "[1;31m" );
  4857. case Colour::BrightGreen: return setColour( "[1;32m" );
  4858. case Colour::BrightWhite: return setColour( "[1;37m" );
  4859. case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
  4860. }
  4861. }
  4862. static IColourImpl* instance() {
  4863. static PosixColourImpl s_instance;
  4864. return &s_instance;
  4865. }
  4866. private:
  4867. void setColour( const char* _escapeCode ) {
  4868. Catch::cout() << '\033' << _escapeCode;
  4869. }
  4870. };
  4871. bool useColourOnPlatform() {
  4872. return
  4873. #ifdef CATCH_PLATFORM_MAC
  4874. !isDebuggerActive() &&
  4875. #endif
  4876. isatty(STDOUT_FILENO);
  4877. }
  4878. IColourImpl* platformColourInstance() {
  4879. ErrnoGuard guard;
  4880. IConfigPtr config = getCurrentContext().getConfig();
  4881. UseColour::YesOrNo colourMode = config
  4882. ? config->useColour()
  4883. : UseColour::Auto;
  4884. if( colourMode == UseColour::Auto )
  4885. colourMode = useColourOnPlatform()
  4886. ? UseColour::Yes
  4887. : UseColour::No;
  4888. return colourMode == UseColour::Yes
  4889. ? PosixColourImpl::instance()
  4890. : NoColourImpl::instance();
  4891. }
  4892. } // end anon namespace
  4893. } // end namespace Catch
  4894. #else // not Windows or ANSI ///////////////////////////////////////////////
  4895. namespace Catch {
  4896. static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
  4897. } // end namespace Catch
  4898. #endif // Windows/ ANSI/ None
  4899. namespace Catch {
  4900. Colour::Colour( Code _colourCode ) { use( _colourCode ); }
  4901. Colour::Colour( Colour&& rhs ) noexcept {
  4902. m_moved = rhs.m_moved;
  4903. rhs.m_moved = true;
  4904. }
  4905. Colour& Colour::operator=( Colour&& rhs ) noexcept {
  4906. m_moved = rhs.m_moved;
  4907. rhs.m_moved = true;
  4908. return *this;
  4909. }
  4910. Colour::~Colour(){ if( !m_moved ) use( None ); }
  4911. void Colour::use( Code _colourCode ) {
  4912. static IColourImpl* impl = platformColourInstance();
  4913. impl->use( _colourCode );
  4914. }
  4915. std::ostream& operator << ( std::ostream& os, Colour const& ) {
  4916. return os;
  4917. }
  4918. } // end namespace Catch
  4919. #if defined(__clang__)
  4920. # pragma clang diagnostic pop
  4921. #endif
  4922. // end catch_console_colour.cpp
  4923. // start catch_context.cpp
  4924. namespace Catch {
  4925. class Context : public IMutableContext, NonCopyable {
  4926. public: // IContext
  4927. virtual IResultCapture* getResultCapture() override {
  4928. return m_resultCapture;
  4929. }
  4930. virtual IRunner* getRunner() override {
  4931. return m_runner;
  4932. }
  4933. virtual IConfigPtr getConfig() const override {
  4934. return m_config;
  4935. }
  4936. virtual ~Context() override;
  4937. public: // IMutableContext
  4938. virtual void setResultCapture( IResultCapture* resultCapture ) override {
  4939. m_resultCapture = resultCapture;
  4940. }
  4941. virtual void setRunner( IRunner* runner ) override {
  4942. m_runner = runner;
  4943. }
  4944. virtual void setConfig( IConfigPtr const& config ) override {
  4945. m_config = config;
  4946. }
  4947. friend IMutableContext& getCurrentMutableContext();
  4948. private:
  4949. IConfigPtr m_config;
  4950. IRunner* m_runner = nullptr;
  4951. IResultCapture* m_resultCapture = nullptr;
  4952. };
  4953. namespace {
  4954. Context* currentContext = nullptr;
  4955. }
  4956. IMutableContext& getCurrentMutableContext() {
  4957. if( !currentContext )
  4958. currentContext = new Context();
  4959. return *currentContext;
  4960. }
  4961. IContext& getCurrentContext() {
  4962. return getCurrentMutableContext();
  4963. }
  4964. void cleanUpContext() {
  4965. delete currentContext;
  4966. currentContext = nullptr;
  4967. }
  4968. IContext::~IContext() = default;
  4969. IMutableContext::~IMutableContext() = default;
  4970. Context::~Context() = default;
  4971. }
  4972. // end catch_context.cpp
  4973. // start catch_debug_console.cpp
  4974. // start catch_debug_console.h
  4975. #include <string>
  4976. namespace Catch {
  4977. void writeToDebugConsole( std::string const& text );
  4978. }
  4979. // end catch_debug_console.h
  4980. #ifdef CATCH_PLATFORM_WINDOWS
  4981. namespace Catch {
  4982. void writeToDebugConsole( std::string const& text ) {
  4983. ::OutputDebugStringA( text.c_str() );
  4984. }
  4985. }
  4986. #else
  4987. namespace Catch {
  4988. void writeToDebugConsole( std::string const& text ) {
  4989. // !TBD: Need a version for Mac/ XCode and other IDEs
  4990. Catch::cout() << text;
  4991. }
  4992. }
  4993. #endif // Platform
  4994. // end catch_debug_console.cpp
  4995. // start catch_debugger.cpp
  4996. #ifdef CATCH_PLATFORM_MAC
  4997. #include <assert.h>
  4998. #include <stdbool.h>
  4999. #include <sys/types.h>
  5000. #include <unistd.h>
  5001. #include <sys/sysctl.h>
  5002. namespace Catch {
  5003. // The following function is taken directly from the following technical note:
  5004. // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
  5005. // Returns true if the current process is being debugged (either
  5006. // running under the debugger or has a debugger attached post facto).
  5007. bool isDebuggerActive(){
  5008. int mib[4];
  5009. struct kinfo_proc info;
  5010. std::size_t size;
  5011. // Initialize the flags so that, if sysctl fails for some bizarre
  5012. // reason, we get a predictable result.
  5013. info.kp_proc.p_flag = 0;
  5014. // Initialize mib, which tells sysctl the info we want, in this case
  5015. // we're looking for information about a specific process ID.
  5016. mib[0] = CTL_KERN;
  5017. mib[1] = KERN_PROC;
  5018. mib[2] = KERN_PROC_PID;
  5019. mib[3] = getpid();
  5020. // Call sysctl.
  5021. size = sizeof(info);
  5022. if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) {
  5023. Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
  5024. return false;
  5025. }
  5026. // We're being debugged if the P_TRACED flag is set.
  5027. return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
  5028. }
  5029. } // namespace Catch
  5030. #elif defined(CATCH_PLATFORM_LINUX)
  5031. #include <fstream>
  5032. #include <string>
  5033. namespace Catch{
  5034. // The standard POSIX way of detecting a debugger is to attempt to
  5035. // ptrace() the process, but this needs to be done from a child and not
  5036. // this process itself to still allow attaching to this process later
  5037. // if wanted, so is rather heavy. Under Linux we have the PID of the
  5038. // "debugger" (which doesn't need to be gdb, of course, it could also
  5039. // be strace, for example) in /proc/$PID/status, so just get it from
  5040. // there instead.
  5041. bool isDebuggerActive(){
  5042. // Libstdc++ has a bug, where std::ifstream sets errno to 0
  5043. // This way our users can properly assert over errno values
  5044. ErrnoGuard guard;
  5045. std::ifstream in("/proc/self/status");
  5046. for( std::string line; std::getline(in, line); ) {
  5047. static const int PREFIX_LEN = 11;
  5048. if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
  5049. // We're traced if the PID is not 0 and no other PID starts
  5050. // with 0 digit, so it's enough to check for just a single
  5051. // character.
  5052. return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
  5053. }
  5054. }
  5055. return false;
  5056. }
  5057. } // namespace Catch
  5058. #elif defined(_MSC_VER)
  5059. extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
  5060. namespace Catch {
  5061. bool isDebuggerActive() {
  5062. return IsDebuggerPresent() != 0;
  5063. }
  5064. }
  5065. #elif defined(__MINGW32__)
  5066. extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
  5067. namespace Catch {
  5068. bool isDebuggerActive() {
  5069. return IsDebuggerPresent() != 0;
  5070. }
  5071. }
  5072. #else
  5073. namespace Catch {
  5074. bool isDebuggerActive() { return false; }
  5075. }
  5076. #endif // Platform
  5077. // end catch_debugger.cpp
  5078. // start catch_decomposer.cpp
  5079. namespace Catch {
  5080. ITransientExpression::~ITransientExpression() = default;
  5081. void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {
  5082. if( lhs.size() + rhs.size() < 40 &&
  5083. lhs.find('\n') == std::string::npos &&
  5084. rhs.find('\n') == std::string::npos )
  5085. os << lhs << " " << op << " " << rhs;
  5086. else
  5087. os << lhs << "\n" << op << "\n" << rhs;
  5088. }
  5089. }
  5090. // end catch_decomposer.cpp
  5091. // start catch_errno_guard.cpp
  5092. #include <cerrno>
  5093. namespace Catch {
  5094. ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}
  5095. ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }
  5096. }
  5097. // end catch_errno_guard.cpp
  5098. // start catch_exception_translator_registry.cpp
  5099. // start catch_exception_translator_registry.h
  5100. #include <vector>
  5101. #include <string>
  5102. #include <memory>
  5103. namespace Catch {
  5104. class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
  5105. public:
  5106. ~ExceptionTranslatorRegistry();
  5107. virtual void registerTranslator( const IExceptionTranslator* translator );
  5108. virtual std::string translateActiveException() const override;
  5109. std::string tryTranslators() const;
  5110. private:
  5111. std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;
  5112. };
  5113. }
  5114. // end catch_exception_translator_registry.h
  5115. #ifdef __OBJC__
  5116. #import "Foundation/Foundation.h"
  5117. #endif
  5118. namespace Catch {
  5119. ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
  5120. }
  5121. void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) {
  5122. m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
  5123. }
  5124. std::string ExceptionTranslatorRegistry::translateActiveException() const {
  5125. try {
  5126. #ifdef __OBJC__
  5127. // In Objective-C try objective-c exceptions first
  5128. @try {
  5129. return tryTranslators();
  5130. }
  5131. @catch (NSException *exception) {
  5132. return Catch::Detail::stringify( [exception description] );
  5133. }
  5134. #else
  5135. return tryTranslators();
  5136. #endif
  5137. }
  5138. catch( TestFailureException& ) {
  5139. std::rethrow_exception(std::current_exception());
  5140. }
  5141. catch( std::exception& ex ) {
  5142. return ex.what();
  5143. }
  5144. catch( std::string& msg ) {
  5145. return msg;
  5146. }
  5147. catch( const char* msg ) {
  5148. return msg;
  5149. }
  5150. catch(...) {
  5151. return "Unknown exception";
  5152. }
  5153. }
  5154. std::string ExceptionTranslatorRegistry::tryTranslators() const {
  5155. if( m_translators.empty() )
  5156. std::rethrow_exception(std::current_exception());
  5157. else
  5158. return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
  5159. }
  5160. }
  5161. // end catch_exception_translator_registry.cpp
  5162. // start catch_fatal_condition.cpp
  5163. // start catch_fatal_condition.h
  5164. #include <string>
  5165. #if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
  5166. # if !defined ( CATCH_CONFIG_WINDOWS_SEH )
  5167. namespace Catch {
  5168. struct FatalConditionHandler {
  5169. void reset();
  5170. };
  5171. }
  5172. # else // CATCH_CONFIG_WINDOWS_SEH is defined
  5173. namespace Catch {
  5174. struct FatalConditionHandler {
  5175. static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
  5176. FatalConditionHandler();
  5177. static void reset();
  5178. ~FatalConditionHandler();
  5179. private:
  5180. static bool isSet;
  5181. static ULONG guaranteeSize;
  5182. static PVOID exceptionHandlerHandle;
  5183. };
  5184. } // namespace Catch
  5185. # endif // CATCH_CONFIG_WINDOWS_SEH
  5186. #else // Not Windows - assumed to be POSIX compatible //////////////////////////
  5187. # if !defined(CATCH_CONFIG_POSIX_SIGNALS)
  5188. namespace Catch {
  5189. struct FatalConditionHandler {
  5190. void reset();
  5191. };
  5192. }
  5193. # else // CATCH_CONFIG_POSIX_SIGNALS is defined
  5194. #include <signal.h>
  5195. namespace Catch {
  5196. struct FatalConditionHandler {
  5197. static bool isSet;
  5198. static struct sigaction oldSigActions[];// [sizeof(signalDefs) / sizeof(SignalDefs)];
  5199. static stack_t oldSigStack;
  5200. static char altStackMem[];
  5201. static void handleSignal( int sig );
  5202. FatalConditionHandler();
  5203. ~FatalConditionHandler();
  5204. static void reset();
  5205. };
  5206. } // namespace Catch
  5207. # endif // CATCH_CONFIG_POSIX_SIGNALS
  5208. #endif // not Windows
  5209. // end catch_fatal_condition.h
  5210. namespace {
  5211. // Report the error condition
  5212. void reportFatal( char const * const message ) {
  5213. Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
  5214. }
  5215. }
  5216. #if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
  5217. # if !defined ( CATCH_CONFIG_WINDOWS_SEH )
  5218. namespace Catch {
  5219. void FatalConditionHandler::reset() {}
  5220. }
  5221. # else // CATCH_CONFIG_WINDOWS_SEH is defined
  5222. namespace Catch {
  5223. struct SignalDefs { DWORD id; const char* name; };
  5224. // There is no 1-1 mapping between signals and windows exceptions.
  5225. // Windows can easily distinguish between SO and SigSegV,
  5226. // but SigInt, SigTerm, etc are handled differently.
  5227. static SignalDefs signalDefs[] = {
  5228. { EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal" },
  5229. { EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" },
  5230. { EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" },
  5231. { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" },
  5232. };
  5233. LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
  5234. for (auto const& def : signalDefs) {
  5235. if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
  5236. reportFatal(def.name);
  5237. }
  5238. }
  5239. // If its not an exception we care about, pass it along.
  5240. // This stops us from eating debugger breaks etc.
  5241. return EXCEPTION_CONTINUE_SEARCH;
  5242. }
  5243. FatalConditionHandler::FatalConditionHandler() {
  5244. isSet = true;
  5245. // 32k seems enough for Catch to handle stack overflow,
  5246. // but the value was found experimentally, so there is no strong guarantee
  5247. guaranteeSize = 32 * 1024;
  5248. exceptionHandlerHandle = nullptr;
  5249. // Register as first handler in current chain
  5250. exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
  5251. // Pass in guarantee size to be filled
  5252. SetThreadStackGuarantee(&guaranteeSize);
  5253. }
  5254. void FatalConditionHandler::reset() {
  5255. if (isSet) {
  5256. // Unregister handler and restore the old guarantee
  5257. RemoveVectoredExceptionHandler(exceptionHandlerHandle);
  5258. SetThreadStackGuarantee(&guaranteeSize);
  5259. exceptionHandlerHandle = nullptr;
  5260. isSet = false;
  5261. }
  5262. }
  5263. FatalConditionHandler::~FatalConditionHandler() {
  5264. reset();
  5265. }
  5266. bool FatalConditionHandler::isSet = false;
  5267. ULONG FatalConditionHandler::guaranteeSize = 0;
  5268. PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
  5269. } // namespace Catch
  5270. # endif // CATCH_CONFIG_WINDOWS_SEH
  5271. #else // Not Windows - assumed to be POSIX compatible //////////////////////////
  5272. # if !defined(CATCH_CONFIG_POSIX_SIGNALS)
  5273. namespace Catch {
  5274. void FatalConditionHandler::reset() {}
  5275. }
  5276. # else // CATCH_CONFIG_POSIX_SIGNALS is defined
  5277. #include <signal.h>
  5278. namespace Catch {
  5279. struct SignalDefs {
  5280. int id;
  5281. const char* name;
  5282. };
  5283. static SignalDefs signalDefs[] = {
  5284. { SIGINT, "SIGINT - Terminal interrupt signal" },
  5285. { SIGILL, "SIGILL - Illegal instruction signal" },
  5286. { SIGFPE, "SIGFPE - Floating point error signal" },
  5287. { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
  5288. { SIGTERM, "SIGTERM - Termination request signal" },
  5289. { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
  5290. };
  5291. void FatalConditionHandler::handleSignal( int sig ) {
  5292. char const * name = "<unknown signal>";
  5293. for (auto const& def : signalDefs) {
  5294. if (sig == def.id) {
  5295. name = def.name;
  5296. break;
  5297. }
  5298. }
  5299. reset();
  5300. reportFatal(name);
  5301. raise( sig );
  5302. }
  5303. FatalConditionHandler::FatalConditionHandler() {
  5304. isSet = true;
  5305. stack_t sigStack;
  5306. sigStack.ss_sp = altStackMem;
  5307. sigStack.ss_size = SIGSTKSZ;
  5308. sigStack.ss_flags = 0;
  5309. sigaltstack(&sigStack, &oldSigStack);
  5310. struct sigaction sa = { };
  5311. sa.sa_handler = handleSignal;
  5312. sa.sa_flags = SA_ONSTACK;
  5313. for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
  5314. sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
  5315. }
  5316. }
  5317. FatalConditionHandler::~FatalConditionHandler() {
  5318. reset();
  5319. }
  5320. void FatalConditionHandler::reset() {
  5321. if( isSet ) {
  5322. // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
  5323. for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
  5324. sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
  5325. }
  5326. // Return the old stack
  5327. sigaltstack(&oldSigStack, nullptr);
  5328. isSet = false;
  5329. }
  5330. }
  5331. bool FatalConditionHandler::isSet = false;
  5332. struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
  5333. stack_t FatalConditionHandler::oldSigStack = {};
  5334. char FatalConditionHandler::altStackMem[SIGSTKSZ] = {};
  5335. } // namespace Catch
  5336. # endif // CATCH_CONFIG_POSIX_SIGNALS
  5337. #endif // not Windows
  5338. // end catch_fatal_condition.cpp
  5339. // start catch_interfaces_capture.cpp
  5340. namespace Catch {
  5341. IResultCapture::~IResultCapture() = default;
  5342. }
  5343. // end catch_interfaces_capture.cpp
  5344. // start catch_interfaces_config.cpp
  5345. namespace Catch {
  5346. IConfig::~IConfig() = default;
  5347. }
  5348. // end catch_interfaces_config.cpp
  5349. // start catch_interfaces_exception.cpp
  5350. namespace Catch {
  5351. IExceptionTranslator::~IExceptionTranslator() = default;
  5352. IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;
  5353. }
  5354. // end catch_interfaces_exception.cpp
  5355. // start catch_interfaces_registry_hub.cpp
  5356. namespace Catch {
  5357. IRegistryHub::~IRegistryHub() = default;
  5358. IMutableRegistryHub::~IMutableRegistryHub() = default;
  5359. }
  5360. // end catch_interfaces_registry_hub.cpp
  5361. // start catch_interfaces_reporter.cpp
  5362. // start catch_reporter_multi.h
  5363. namespace Catch {
  5364. class MultipleReporters : public IStreamingReporter {
  5365. using Reporters = std::vector<IStreamingReporterPtr>;
  5366. Reporters m_reporters;
  5367. public:
  5368. void add( IStreamingReporterPtr&& reporter );
  5369. public: // IStreamingReporter
  5370. ReporterPreferences getPreferences() const override;
  5371. void noMatchingTestCases( std::string const& spec ) override;
  5372. static std::set<Verbosity> getSupportedVerbosities();
  5373. void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
  5374. void benchmarkEnded( BenchmarkStats const& benchmarkStats ) override;
  5375. void testRunStarting( TestRunInfo const& testRunInfo ) override;
  5376. void testGroupStarting( GroupInfo const& groupInfo ) override;
  5377. void testCaseStarting( TestCaseInfo const& testInfo ) override;
  5378. void sectionStarting( SectionInfo const& sectionInfo ) override;
  5379. void assertionStarting( AssertionInfo const& assertionInfo ) override;
  5380. // The return value indicates if the messages buffer should be cleared:
  5381. bool assertionEnded( AssertionStats const& assertionStats ) override;
  5382. void sectionEnded( SectionStats const& sectionStats ) override;
  5383. void testCaseEnded( TestCaseStats const& testCaseStats ) override;
  5384. void testGroupEnded( TestGroupStats const& testGroupStats ) override;
  5385. void testRunEnded( TestRunStats const& testRunStats ) override;
  5386. void skipTest( TestCaseInfo const& testInfo ) override;
  5387. bool isMulti() const override;
  5388. };
  5389. } // end namespace Catch
  5390. // end catch_reporter_multi.h
  5391. namespace Catch {
  5392. ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig )
  5393. : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
  5394. ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream )
  5395. : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
  5396. std::ostream& ReporterConfig::stream() const { return *m_stream; }
  5397. IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; }
  5398. TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {}
  5399. GroupInfo::GroupInfo( std::string const& _name,
  5400. std::size_t _groupIndex,
  5401. std::size_t _groupsCount )
  5402. : name( _name ),
  5403. groupIndex( _groupIndex ),
  5404. groupsCounts( _groupsCount )
  5405. {}
  5406. AssertionStats::AssertionStats( AssertionResult const& _assertionResult,
  5407. std::vector<MessageInfo> const& _infoMessages,
  5408. Totals const& _totals )
  5409. : assertionResult( _assertionResult ),
  5410. infoMessages( _infoMessages ),
  5411. totals( _totals )
  5412. {
  5413. assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;
  5414. if( assertionResult.hasMessage() ) {
  5415. // Copy message into messages list.
  5416. // !TBD This should have been done earlier, somewhere
  5417. MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
  5418. builder << assertionResult.getMessage();
  5419. builder.m_info.message = builder.m_stream.str();
  5420. infoMessages.push_back( builder.m_info );
  5421. }
  5422. }
  5423. AssertionStats::~AssertionStats() = default;
  5424. SectionStats::SectionStats( SectionInfo const& _sectionInfo,
  5425. Counts const& _assertions,
  5426. double _durationInSeconds,
  5427. bool _missingAssertions )
  5428. : sectionInfo( _sectionInfo ),
  5429. assertions( _assertions ),
  5430. durationInSeconds( _durationInSeconds ),
  5431. missingAssertions( _missingAssertions )
  5432. {}
  5433. SectionStats::~SectionStats() = default;
  5434. TestCaseStats::TestCaseStats( TestCaseInfo const& _testInfo,
  5435. Totals const& _totals,
  5436. std::string const& _stdOut,
  5437. std::string const& _stdErr,
  5438. bool _aborting )
  5439. : testInfo( _testInfo ),
  5440. totals( _totals ),
  5441. stdOut( _stdOut ),
  5442. stdErr( _stdErr ),
  5443. aborting( _aborting )
  5444. {}
  5445. TestCaseStats::~TestCaseStats() = default;
  5446. TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo,
  5447. Totals const& _totals,
  5448. bool _aborting )
  5449. : groupInfo( _groupInfo ),
  5450. totals( _totals ),
  5451. aborting( _aborting )
  5452. {}
  5453. TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo )
  5454. : groupInfo( _groupInfo ),
  5455. aborting( false )
  5456. {}
  5457. TestGroupStats::~TestGroupStats() = default;
  5458. TestRunStats::TestRunStats( TestRunInfo const& _runInfo,
  5459. Totals const& _totals,
  5460. bool _aborting )
  5461. : runInfo( _runInfo ),
  5462. totals( _totals ),
  5463. aborting( _aborting )
  5464. {}
  5465. TestRunStats::~TestRunStats() = default;
  5466. void IStreamingReporter::fatalErrorEncountered( StringRef ) {}
  5467. bool IStreamingReporter::isMulti() const { return false; }
  5468. IReporterFactory::~IReporterFactory() = default;
  5469. IReporterRegistry::~IReporterRegistry() = default;
  5470. void addReporter( IStreamingReporterPtr& existingReporter, IStreamingReporterPtr&& additionalReporter ) {
  5471. if( !existingReporter ) {
  5472. existingReporter = std::move( additionalReporter );
  5473. return;
  5474. }
  5475. MultipleReporters* multi = nullptr;
  5476. if( existingReporter->isMulti() ) {
  5477. multi = static_cast<MultipleReporters*>( existingReporter.get() );
  5478. }
  5479. else {
  5480. auto newMulti = std::unique_ptr<MultipleReporters>( new MultipleReporters );
  5481. newMulti->add( std::move( existingReporter ) );
  5482. multi = newMulti.get();
  5483. existingReporter = std::move( newMulti );
  5484. }
  5485. multi->add( std::move( additionalReporter ) );
  5486. }
  5487. } // end namespace Catch
  5488. // end catch_interfaces_reporter.cpp
  5489. // start catch_interfaces_runner.cpp
  5490. namespace Catch {
  5491. IRunner::~IRunner() = default;
  5492. }
  5493. // end catch_interfaces_runner.cpp
  5494. // start catch_interfaces_testcase.cpp
  5495. namespace Catch {
  5496. ITestInvoker::~ITestInvoker() = default;
  5497. ITestCaseRegistry::~ITestCaseRegistry() = default;
  5498. }
  5499. // end catch_interfaces_testcase.cpp
  5500. // start catch_leak_detector.cpp
  5501. namespace Catch {
  5502. #ifdef CATCH_CONFIG_WINDOWS_CRTDBG
  5503. #include <crtdbg.h>
  5504. LeakDetector::LeakDetector() {
  5505. int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
  5506. flag |= _CRTDBG_LEAK_CHECK_DF;
  5507. flag |= _CRTDBG_ALLOC_MEM_DF;
  5508. _CrtSetDbgFlag(flag);
  5509. _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
  5510. _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
  5511. // Change this to leaking allocation's number to break there
  5512. _CrtSetBreakAlloc(-1);
  5513. }
  5514. #else
  5515. LeakDetector::LeakDetector(){}
  5516. #endif
  5517. }
  5518. // end catch_leak_detector.cpp
  5519. // start catch_list.cpp
  5520. // start catch_list.h
  5521. #include <set>
  5522. namespace Catch {
  5523. std::size_t listTests( Config const& config );
  5524. std::size_t listTestsNamesOnly( Config const& config );
  5525. struct TagInfo {
  5526. void add( std::string const& spelling );
  5527. std::string all() const;
  5528. std::set<std::string> spellings;
  5529. std::size_t count = 0;
  5530. };
  5531. std::size_t listTags( Config const& config );
  5532. std::size_t listReporters( Config const& /*config*/ );
  5533. Option<std::size_t> list( Config const& config );
  5534. } // end namespace Catch
  5535. // end catch_list.h
  5536. // start catch_text.h
  5537. namespace Catch {
  5538. using namespace clara::TextFlow;
  5539. }
  5540. // end catch_text.h
  5541. #include <limits>
  5542. #include <algorithm>
  5543. #include <iomanip>
  5544. namespace Catch {
  5545. std::size_t listTests( Config const& config ) {
  5546. TestSpec testSpec = config.testSpec();
  5547. if( config.testSpec().hasFilters() )
  5548. Catch::cout() << "Matching test cases:\n";
  5549. else {
  5550. Catch::cout() << "All available test cases:\n";
  5551. testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
  5552. }
  5553. auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
  5554. for( auto const& testCaseInfo : matchedTestCases ) {
  5555. Colour::Code colour = testCaseInfo.isHidden()
  5556. ? Colour::SecondaryText
  5557. : Colour::None;
  5558. Colour colourGuard( colour );
  5559. Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n";
  5560. if( config.verbosity() >= Verbosity::High ) {
  5561. Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl;
  5562. std::string description = testCaseInfo.description;
  5563. if( description.empty() )
  5564. description = "(NO DESCRIPTION)";
  5565. Catch::cout() << Column( description ).indent(4) << std::endl;
  5566. }
  5567. if( !testCaseInfo.tags.empty() )
  5568. Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n";
  5569. }
  5570. if( !config.testSpec().hasFilters() )
  5571. Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl;
  5572. else
  5573. Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl;
  5574. return matchedTestCases.size();
  5575. }
  5576. std::size_t listTestsNamesOnly( Config const& config ) {
  5577. TestSpec testSpec = config.testSpec();
  5578. if( !config.testSpec().hasFilters() )
  5579. testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
  5580. std::size_t matchedTests = 0;
  5581. std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
  5582. for( auto const& testCaseInfo : matchedTestCases ) {
  5583. matchedTests++;
  5584. if( startsWith( testCaseInfo.name, '#' ) )
  5585. Catch::cout() << '"' << testCaseInfo.name << '"';
  5586. else
  5587. Catch::cout() << testCaseInfo.name;
  5588. if ( config.verbosity() >= Verbosity::High )
  5589. Catch::cout() << "\t@" << testCaseInfo.lineInfo;
  5590. Catch::cout() << std::endl;
  5591. }
  5592. return matchedTests;
  5593. }
  5594. void TagInfo::add( std::string const& spelling ) {
  5595. ++count;
  5596. spellings.insert( spelling );
  5597. }
  5598. std::string TagInfo::all() const {
  5599. std::string out;
  5600. for( auto const& spelling : spellings )
  5601. out += "[" + spelling + "]";
  5602. return out;
  5603. }
  5604. std::size_t listTags( Config const& config ) {
  5605. TestSpec testSpec = config.testSpec();
  5606. if( config.testSpec().hasFilters() )
  5607. Catch::cout() << "Tags for matching test cases:\n";
  5608. else {
  5609. Catch::cout() << "All available tags:\n";
  5610. testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
  5611. }
  5612. std::map<std::string, TagInfo> tagCounts;
  5613. std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
  5614. for( auto const& testCase : matchedTestCases ) {
  5615. for( auto const& tagName : testCase.getTestCaseInfo().tags ) {
  5616. std::string lcaseTagName = toLower( tagName );
  5617. auto countIt = tagCounts.find( lcaseTagName );
  5618. if( countIt == tagCounts.end() )
  5619. countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
  5620. countIt->second.add( tagName );
  5621. }
  5622. }
  5623. for( auto const& tagCount : tagCounts ) {
  5624. std::ostringstream oss;
  5625. oss << " " << std::setw(2) << tagCount.second.count << " ";
  5626. auto wrapper = Column( tagCount.second.all() )
  5627. .initialIndent( 0 )
  5628. .indent( oss.str().size() )
  5629. .width( CATCH_CONFIG_CONSOLE_WIDTH-10 );
  5630. Catch::cout() << oss.str() << wrapper << '\n';
  5631. }
  5632. Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
  5633. return tagCounts.size();
  5634. }
  5635. std::size_t listReporters( Config const& /*config*/ ) {
  5636. Catch::cout() << "Available reporters:\n";
  5637. IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
  5638. std::size_t maxNameLen = 0;
  5639. for( auto const& factoryKvp : factories )
  5640. maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() );
  5641. for( auto const& factoryKvp : factories ) {
  5642. Catch::cout()
  5643. << Column( factoryKvp.first + ":" )
  5644. .indent(2)
  5645. .width( 5+maxNameLen )
  5646. + Column( factoryKvp.second->getDescription() )
  5647. .initialIndent(0)
  5648. .indent(2)
  5649. .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 )
  5650. << "\n";
  5651. }
  5652. Catch::cout() << std::endl;
  5653. return factories.size();
  5654. }
  5655. Option<std::size_t> list( Config const& config ) {
  5656. Option<std::size_t> listedCount;
  5657. if( config.listTests() )
  5658. listedCount = listedCount.valueOr(0) + listTests( config );
  5659. if( config.listTestNamesOnly() )
  5660. listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
  5661. if( config.listTags() )
  5662. listedCount = listedCount.valueOr(0) + listTags( config );
  5663. if( config.listReporters() )
  5664. listedCount = listedCount.valueOr(0) + listReporters( config );
  5665. return listedCount;
  5666. }
  5667. } // end namespace Catch
  5668. // end catch_list.cpp
  5669. // start catch_matchers.cpp
  5670. namespace Catch {
  5671. namespace Matchers {
  5672. namespace Impl {
  5673. std::string MatcherUntypedBase::toString() const {
  5674. if( m_cachedToString.empty() )
  5675. m_cachedToString = describe();
  5676. return m_cachedToString;
  5677. }
  5678. MatcherUntypedBase::~MatcherUntypedBase() = default;
  5679. } // namespace Impl
  5680. } // namespace Matchers
  5681. using namespace Matchers;
  5682. using Matchers::Impl::MatcherBase;
  5683. } // namespace Catch
  5684. // end catch_matchers.cpp
  5685. // start catch_matchers_string.cpp
  5686. namespace Catch {
  5687. namespace Matchers {
  5688. namespace StdString {
  5689. CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
  5690. : m_caseSensitivity( caseSensitivity ),
  5691. m_str( adjustString( str ) )
  5692. {}
  5693. std::string CasedString::adjustString( std::string const& str ) const {
  5694. return m_caseSensitivity == CaseSensitive::No
  5695. ? toLower( str )
  5696. : str;
  5697. }
  5698. std::string CasedString::caseSensitivitySuffix() const {
  5699. return m_caseSensitivity == CaseSensitive::No
  5700. ? " (case insensitive)"
  5701. : std::string();
  5702. }
  5703. StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )
  5704. : m_comparator( comparator ),
  5705. m_operation( operation ) {
  5706. }
  5707. std::string StringMatcherBase::describe() const {
  5708. std::string description;
  5709. description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
  5710. m_comparator.caseSensitivitySuffix().size());
  5711. description += m_operation;
  5712. description += ": \"";
  5713. description += m_comparator.m_str;
  5714. description += "\"";
  5715. description += m_comparator.caseSensitivitySuffix();
  5716. return description;
  5717. }
  5718. EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {}
  5719. bool EqualsMatcher::match( std::string const& source ) const {
  5720. return m_comparator.adjustString( source ) == m_comparator.m_str;
  5721. }
  5722. ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {}
  5723. bool ContainsMatcher::match( std::string const& source ) const {
  5724. return contains( m_comparator.adjustString( source ), m_comparator.m_str );
  5725. }
  5726. StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {}
  5727. bool StartsWithMatcher::match( std::string const& source ) const {
  5728. return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
  5729. }
  5730. EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {}
  5731. bool EndsWithMatcher::match( std::string const& source ) const {
  5732. return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
  5733. }
  5734. } // namespace StdString
  5735. StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
  5736. return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
  5737. }
  5738. StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
  5739. return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
  5740. }
  5741. StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
  5742. return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
  5743. }
  5744. StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
  5745. return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
  5746. }
  5747. } // namespace Matchers
  5748. } // namespace Catch
  5749. // end catch_matchers_string.cpp
  5750. // start catch_message.cpp
  5751. namespace Catch {
  5752. MessageInfo::MessageInfo( std::string const& _macroName,
  5753. SourceLineInfo const& _lineInfo,
  5754. ResultWas::OfType _type )
  5755. : macroName( _macroName ),
  5756. lineInfo( _lineInfo ),
  5757. type( _type ),
  5758. sequence( ++globalCount )
  5759. {}
  5760. bool MessageInfo::operator==( MessageInfo const& other ) const {
  5761. return sequence == other.sequence;
  5762. }
  5763. bool MessageInfo::operator<( MessageInfo const& other ) const {
  5764. return sequence < other.sequence;
  5765. }
  5766. // This may need protecting if threading support is added
  5767. unsigned int MessageInfo::globalCount = 0;
  5768. ////////////////////////////////////////////////////////////////////////////
  5769. Catch::MessageBuilder::MessageBuilder( std::string const& macroName,
  5770. SourceLineInfo const& lineInfo,
  5771. ResultWas::OfType type )
  5772. :m_info(macroName, lineInfo, type) {}
  5773. ////////////////////////////////////////////////////////////////////////////
  5774. ScopedMessage::ScopedMessage( MessageBuilder const& builder )
  5775. : m_info( builder.m_info )
  5776. {
  5777. m_info.message = builder.m_stream.str();
  5778. getResultCapture().pushScopedMessage( m_info );
  5779. }
  5780. ScopedMessage::~ScopedMessage() {
  5781. if ( !std::uncaught_exception() ){
  5782. getResultCapture().popScopedMessage(m_info);
  5783. }
  5784. }
  5785. } // end namespace Catch
  5786. // end catch_message.cpp
  5787. // start catch_random_number_generator.cpp
  5788. // start catch_random_number_generator.h
  5789. #include <algorithm>
  5790. namespace Catch {
  5791. struct IConfig;
  5792. void seedRng( IConfig const& config );
  5793. unsigned int rngSeed();
  5794. struct RandomNumberGenerator {
  5795. using result_type = std::ptrdiff_t;
  5796. static constexpr result_type min() { return 0; }
  5797. static constexpr result_type max() { return 1000000; }
  5798. result_type operator()( result_type n ) const;
  5799. result_type operator()() const;
  5800. template<typename V>
  5801. static void shuffle( V& vector ) {
  5802. RandomNumberGenerator rng;
  5803. std::shuffle( vector.begin(), vector.end(), rng );
  5804. }
  5805. };
  5806. }
  5807. // end catch_random_number_generator.h
  5808. #include <cstdlib>
  5809. namespace Catch {
  5810. void seedRng( IConfig const& config ) {
  5811. if( config.rngSeed() != 0 )
  5812. std::srand( config.rngSeed() );
  5813. }
  5814. unsigned int rngSeed() {
  5815. return getCurrentContext().getConfig()->rngSeed();
  5816. }
  5817. RandomNumberGenerator::result_type RandomNumberGenerator::operator()( result_type n ) const {
  5818. return std::rand() % n;
  5819. }
  5820. RandomNumberGenerator::result_type RandomNumberGenerator::operator()() const {
  5821. return std::rand() % max();
  5822. }
  5823. }
  5824. // end catch_random_number_generator.cpp
  5825. // start catch_registry_hub.cpp
  5826. // start catch_test_case_registry_impl.h
  5827. #include <vector>
  5828. #include <set>
  5829. #include <algorithm>
  5830. #include <ios>
  5831. namespace Catch {
  5832. class TestCase;
  5833. struct IConfig;
  5834. std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases );
  5835. bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
  5836. void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions );
  5837. std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
  5838. std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
  5839. class TestRegistry : public ITestCaseRegistry {
  5840. public:
  5841. virtual ~TestRegistry() = default;
  5842. virtual void registerTest( TestCase const& testCase );
  5843. std::vector<TestCase> const& getAllTests() const override;
  5844. std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const override;
  5845. private:
  5846. std::vector<TestCase> m_functions;
  5847. mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
  5848. mutable std::vector<TestCase> m_sortedFunctions;
  5849. std::size_t m_unnamedCount = 0;
  5850. std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
  5851. };
  5852. ///////////////////////////////////////////////////////////////////////////
  5853. class TestInvokerAsFunction : public ITestInvoker {
  5854. void(*m_testAsFunction)();
  5855. public:
  5856. TestInvokerAsFunction( void(*testAsFunction)() ) noexcept;
  5857. void invoke() const override;
  5858. };
  5859. std::string extractClassName( std::string const& classOrQualifiedMethodName );
  5860. ///////////////////////////////////////////////////////////////////////////
  5861. } // end namespace Catch
  5862. // end catch_test_case_registry_impl.h
  5863. // start catch_reporter_registry.h
  5864. #include <map>
  5865. namespace Catch {
  5866. class ReporterRegistry : public IReporterRegistry {
  5867. public:
  5868. ~ReporterRegistry() override;
  5869. IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override;
  5870. void registerReporter( std::string const& name, IReporterFactoryPtr const& factory );
  5871. void registerListener( IReporterFactoryPtr const& factory );
  5872. FactoryMap const& getFactories() const override;
  5873. Listeners const& getListeners() const override;
  5874. private:
  5875. FactoryMap m_factories;
  5876. Listeners m_listeners;
  5877. };
  5878. }
  5879. // end catch_reporter_registry.h
  5880. // start catch_tag_alias_registry.h
  5881. // start catch_tag_alias.h
  5882. #include <string>
  5883. namespace Catch {
  5884. struct TagAlias {
  5885. TagAlias(std::string const& _tag, SourceLineInfo _lineInfo);
  5886. std::string tag;
  5887. SourceLineInfo lineInfo;
  5888. };
  5889. } // end namespace Catch
  5890. // end catch_tag_alias.h
  5891. #include <map>
  5892. namespace Catch {
  5893. class TagAliasRegistry : public ITagAliasRegistry {
  5894. public:
  5895. ~TagAliasRegistry() override;
  5896. TagAlias const* find( std::string const& alias ) const override;
  5897. std::string expandAliases( std::string const& unexpandedTestSpec ) const override;
  5898. void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
  5899. private:
  5900. std::map<std::string, TagAlias> m_registry;
  5901. };
  5902. } // end namespace Catch
  5903. // end catch_tag_alias_registry.h
  5904. // start catch_startup_exception_registry.h
  5905. #include <vector>
  5906. #include <exception>
  5907. namespace Catch {
  5908. class StartupExceptionRegistry {
  5909. public:
  5910. void add(std::exception_ptr const& exception) noexcept;
  5911. std::vector<std::exception_ptr> const& getExceptions() const noexcept;
  5912. private:
  5913. std::vector<std::exception_ptr> m_exceptions;
  5914. };
  5915. } // end namespace Catch
  5916. // end catch_startup_exception_registry.h
  5917. namespace Catch {
  5918. namespace {
  5919. class RegistryHub : public IRegistryHub, public IMutableRegistryHub,
  5920. private NonCopyable {
  5921. public: // IRegistryHub
  5922. RegistryHub() = default;
  5923. IReporterRegistry const& getReporterRegistry() const override {
  5924. return m_reporterRegistry;
  5925. }
  5926. ITestCaseRegistry const& getTestCaseRegistry() const override {
  5927. return m_testCaseRegistry;
  5928. }
  5929. IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() override {
  5930. return m_exceptionTranslatorRegistry;
  5931. }
  5932. ITagAliasRegistry const& getTagAliasRegistry() const override {
  5933. return m_tagAliasRegistry;
  5934. }
  5935. StartupExceptionRegistry const& getStartupExceptionRegistry() const override {
  5936. return m_exceptionRegistry;
  5937. }
  5938. public: // IMutableRegistryHub
  5939. void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override {
  5940. m_reporterRegistry.registerReporter( name, factory );
  5941. }
  5942. void registerListener( IReporterFactoryPtr const& factory ) override {
  5943. m_reporterRegistry.registerListener( factory );
  5944. }
  5945. void registerTest( TestCase const& testInfo ) override {
  5946. m_testCaseRegistry.registerTest( testInfo );
  5947. }
  5948. void registerTranslator( const IExceptionTranslator* translator ) override {
  5949. m_exceptionTranslatorRegistry.registerTranslator( translator );
  5950. }
  5951. void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override {
  5952. m_tagAliasRegistry.add( alias, tag, lineInfo );
  5953. }
  5954. void registerStartupException() noexcept override {
  5955. m_exceptionRegistry.add(std::current_exception());
  5956. }
  5957. private:
  5958. TestRegistry m_testCaseRegistry;
  5959. ReporterRegistry m_reporterRegistry;
  5960. ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
  5961. TagAliasRegistry m_tagAliasRegistry;
  5962. StartupExceptionRegistry m_exceptionRegistry;
  5963. };
  5964. // Single, global, instance
  5965. RegistryHub*& getTheRegistryHub() {
  5966. static RegistryHub* theRegistryHub = nullptr;
  5967. if( !theRegistryHub )
  5968. theRegistryHub = new RegistryHub();
  5969. return theRegistryHub;
  5970. }
  5971. }
  5972. IRegistryHub& getRegistryHub() {
  5973. return *getTheRegistryHub();
  5974. }
  5975. IMutableRegistryHub& getMutableRegistryHub() {
  5976. return *getTheRegistryHub();
  5977. }
  5978. void cleanUp() {
  5979. delete getTheRegistryHub();
  5980. getTheRegistryHub() = nullptr;
  5981. cleanUpContext();
  5982. }
  5983. std::string translateActiveException() {
  5984. return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
  5985. }
  5986. } // end namespace Catch
  5987. // end catch_registry_hub.cpp
  5988. // start catch_reporter_registry.cpp
  5989. namespace Catch {
  5990. ReporterRegistry::~ReporterRegistry() = default;
  5991. IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const {
  5992. auto it = m_factories.find( name );
  5993. if( it == m_factories.end() )
  5994. return nullptr;
  5995. return it->second->create( ReporterConfig( config ) );
  5996. }
  5997. void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) {
  5998. m_factories.emplace(name, factory);
  5999. }
  6000. void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) {
  6001. m_listeners.push_back( factory );
  6002. }
  6003. IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const {
  6004. return m_factories;
  6005. }
  6006. IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const {
  6007. return m_listeners;
  6008. }
  6009. }
  6010. // end catch_reporter_registry.cpp
  6011. // start catch_result_type.cpp
  6012. namespace Catch {
  6013. bool isOk( ResultWas::OfType resultType ) {
  6014. return ( resultType & ResultWas::FailureBit ) == 0;
  6015. }
  6016. bool isJustInfo( int flags ) {
  6017. return flags == ResultWas::Info;
  6018. }
  6019. ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
  6020. return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
  6021. }
  6022. bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
  6023. bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
  6024. bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
  6025. } // end namespace Catch
  6026. // end catch_result_type.cpp
  6027. // start catch_run_context.cpp
  6028. // start catch_run_context.h
  6029. #include <string>
  6030. namespace Catch {
  6031. struct IMutableContext;
  6032. class StreamRedirect {
  6033. public:
  6034. StreamRedirect(std::ostream& stream, std::string& targetString);
  6035. ~StreamRedirect();
  6036. private:
  6037. std::ostream& m_stream;
  6038. std::streambuf* m_prevBuf;
  6039. std::ostringstream m_oss;
  6040. std::string& m_targetString;
  6041. };
  6042. // StdErr has two constituent streams in C++, std::cerr and std::clog
  6043. // This means that we need to redirect 2 streams into 1 to keep proper
  6044. // order of writes and cannot use StreamRedirect on its own
  6045. class StdErrRedirect {
  6046. public:
  6047. StdErrRedirect(std::string& targetString);
  6048. ~StdErrRedirect();
  6049. private:
  6050. std::streambuf* m_cerrBuf;
  6051. std::streambuf* m_clogBuf;
  6052. std::ostringstream m_oss;
  6053. std::string& m_targetString;
  6054. };
  6055. ///////////////////////////////////////////////////////////////////////////
  6056. class RunContext : public IResultCapture, public IRunner {
  6057. public:
  6058. RunContext( RunContext const& ) = delete;
  6059. RunContext& operator =( RunContext const& ) = delete;
  6060. explicit RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter);
  6061. virtual ~RunContext();
  6062. void testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount);
  6063. void testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount);
  6064. Totals runTest(TestCase const& testCase);
  6065. IConfigPtr config() const;
  6066. IStreamingReporter& reporter() const;
  6067. private: // IResultCapture
  6068. void assertionStarting(AssertionInfo const& info) override;
  6069. void assertionEnded(AssertionResult const& result) override;
  6070. bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override;
  6071. bool testForMissingAssertions(Counts& assertions);
  6072. void sectionEnded(SectionEndInfo const& endInfo) override;
  6073. void sectionEndedEarly(SectionEndInfo const& endInfo) override;
  6074. void benchmarkStarting( BenchmarkInfo const& info ) override;
  6075. void benchmarkEnded( BenchmarkStats const& stats ) override;
  6076. void pushScopedMessage(MessageInfo const& message) override;
  6077. void popScopedMessage(MessageInfo const& message) override;
  6078. std::string getCurrentTestName() const override;
  6079. const AssertionResult* getLastResult() const override;
  6080. void exceptionEarlyReported() override;
  6081. void handleFatalErrorCondition( StringRef message ) override;
  6082. bool lastAssertionPassed() override;
  6083. void assertionPassed() override;
  6084. void assertionRun() override;
  6085. public:
  6086. // !TBD We need to do this another way!
  6087. bool aborting() const override;
  6088. private:
  6089. void runCurrentTest(std::string& redirectedCout, std::string& redirectedCerr);
  6090. void invokeActiveTestCase();
  6091. private:
  6092. void handleUnfinishedSections();
  6093. TestRunInfo m_runInfo;
  6094. IMutableContext& m_context;
  6095. TestCase const* m_activeTestCase = nullptr;
  6096. ITracker* m_testCaseTracker;
  6097. Option<AssertionResult> m_lastResult;
  6098. IConfigPtr m_config;
  6099. Totals m_totals;
  6100. IStreamingReporterPtr m_reporter;
  6101. std::vector<MessageInfo> m_messages;
  6102. AssertionInfo m_lastAssertionInfo;
  6103. std::vector<SectionEndInfo> m_unfinishedSections;
  6104. std::vector<ITracker*> m_activeSections;
  6105. TrackerContext m_trackerContext;
  6106. std::size_t m_prevPassed = 0;
  6107. bool m_shouldReportUnexpected = true;
  6108. };
  6109. IResultCapture& getResultCapture();
  6110. } // end namespace Catch
  6111. // end catch_run_context.h
  6112. #include <cassert>
  6113. #include <algorithm>
  6114. namespace Catch {
  6115. StreamRedirect::StreamRedirect(std::ostream& stream, std::string& targetString)
  6116. : m_stream(stream),
  6117. m_prevBuf(stream.rdbuf()),
  6118. m_targetString(targetString) {
  6119. stream.rdbuf(m_oss.rdbuf());
  6120. }
  6121. StreamRedirect::~StreamRedirect() {
  6122. m_targetString += m_oss.str();
  6123. m_stream.rdbuf(m_prevBuf);
  6124. }
  6125. StdErrRedirect::StdErrRedirect(std::string & targetString)
  6126. :m_cerrBuf(cerr().rdbuf()), m_clogBuf(clog().rdbuf()),
  6127. m_targetString(targetString) {
  6128. cerr().rdbuf(m_oss.rdbuf());
  6129. clog().rdbuf(m_oss.rdbuf());
  6130. }
  6131. StdErrRedirect::~StdErrRedirect() {
  6132. m_targetString += m_oss.str();
  6133. cerr().rdbuf(m_cerrBuf);
  6134. clog().rdbuf(m_clogBuf);
  6135. }
  6136. RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
  6137. : m_runInfo(_config->name()),
  6138. m_context(getCurrentMutableContext()),
  6139. m_config(_config),
  6140. m_reporter(std::move(reporter)),
  6141. m_lastAssertionInfo{ "", SourceLineInfo("",0), "", ResultDisposition::Normal }
  6142. {
  6143. m_context.setRunner(this);
  6144. m_context.setConfig(m_config);
  6145. m_context.setResultCapture(this);
  6146. m_reporter->testRunStarting(m_runInfo);
  6147. }
  6148. RunContext::~RunContext() {
  6149. m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
  6150. }
  6151. void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) {
  6152. m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
  6153. }
  6154. void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) {
  6155. m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
  6156. }
  6157. Totals RunContext::runTest(TestCase const& testCase) {
  6158. Totals prevTotals = m_totals;
  6159. std::string redirectedCout;
  6160. std::string redirectedCerr;
  6161. TestCaseInfo testInfo = testCase.getTestCaseInfo();
  6162. m_reporter->testCaseStarting(testInfo);
  6163. m_activeTestCase = &testCase;
  6164. ITracker& rootTracker = m_trackerContext.startRun();
  6165. assert(rootTracker.isSectionTracker());
  6166. static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
  6167. do {
  6168. m_trackerContext.startCycle();
  6169. m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
  6170. runCurrentTest(redirectedCout, redirectedCerr);
  6171. } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());
  6172. Totals deltaTotals = m_totals.delta(prevTotals);
  6173. if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {
  6174. deltaTotals.assertions.failed++;
  6175. deltaTotals.testCases.passed--;
  6176. deltaTotals.testCases.failed++;
  6177. }
  6178. m_totals.testCases += deltaTotals.testCases;
  6179. m_reporter->testCaseEnded(TestCaseStats(testInfo,
  6180. deltaTotals,
  6181. redirectedCout,
  6182. redirectedCerr,
  6183. aborting()));
  6184. m_activeTestCase = nullptr;
  6185. m_testCaseTracker = nullptr;
  6186. return deltaTotals;
  6187. }
  6188. IConfigPtr RunContext::config() const {
  6189. return m_config;
  6190. }
  6191. IStreamingReporter& RunContext::reporter() const {
  6192. return *m_reporter;
  6193. }
  6194. void RunContext::assertionStarting(AssertionInfo const& info) {
  6195. m_reporter->assertionStarting( info );
  6196. }
  6197. void RunContext::assertionEnded(AssertionResult const & result) {
  6198. if (result.getResultType() == ResultWas::Ok) {
  6199. m_totals.assertions.passed++;
  6200. } else if (!result.isOk()) {
  6201. if( m_activeTestCase->getTestCaseInfo().okToFail() )
  6202. m_totals.assertions.failedButOk++;
  6203. else
  6204. m_totals.assertions.failed++;
  6205. }
  6206. // We have no use for the return value (whether messages should be cleared), because messages were made scoped
  6207. // and should be let to clear themselves out.
  6208. static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
  6209. // Reset working state
  6210. m_lastAssertionInfo = { "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}", m_lastAssertionInfo.resultDisposition };
  6211. m_lastResult = result;
  6212. }
  6213. bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) {
  6214. ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
  6215. if (!sectionTracker.isOpen())
  6216. return false;
  6217. m_activeSections.push_back(&sectionTracker);
  6218. m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
  6219. m_reporter->sectionStarting(sectionInfo);
  6220. assertions = m_totals.assertions;
  6221. return true;
  6222. }
  6223. bool RunContext::testForMissingAssertions(Counts& assertions) {
  6224. if (assertions.total() != 0)
  6225. return false;
  6226. if (!m_config->warnAboutMissingAssertions())
  6227. return false;
  6228. if (m_trackerContext.currentTracker().hasChildren())
  6229. return false;
  6230. m_totals.assertions.failed++;
  6231. assertions.failed++;
  6232. return true;
  6233. }
  6234. void RunContext::sectionEnded(SectionEndInfo const & endInfo) {
  6235. Counts assertions = m_totals.assertions - endInfo.prevAssertions;
  6236. bool missingAssertions = testForMissingAssertions(assertions);
  6237. if (!m_activeSections.empty()) {
  6238. m_activeSections.back()->close();
  6239. m_activeSections.pop_back();
  6240. }
  6241. m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
  6242. m_messages.clear();
  6243. }
  6244. void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {
  6245. if (m_unfinishedSections.empty())
  6246. m_activeSections.back()->fail();
  6247. else
  6248. m_activeSections.back()->close();
  6249. m_activeSections.pop_back();
  6250. m_unfinishedSections.push_back(endInfo);
  6251. }
  6252. void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
  6253. m_reporter->benchmarkStarting( info );
  6254. }
  6255. void RunContext::benchmarkEnded( BenchmarkStats const& stats ) {
  6256. m_reporter->benchmarkEnded( stats );
  6257. }
  6258. void RunContext::pushScopedMessage(MessageInfo const & message) {
  6259. m_messages.push_back(message);
  6260. }
  6261. void RunContext::popScopedMessage(MessageInfo const & message) {
  6262. m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
  6263. }
  6264. std::string RunContext::getCurrentTestName() const {
  6265. return m_activeTestCase
  6266. ? m_activeTestCase->getTestCaseInfo().name
  6267. : std::string();
  6268. }
  6269. const AssertionResult * RunContext::getLastResult() const {
  6270. return &(*m_lastResult);
  6271. }
  6272. void RunContext::exceptionEarlyReported() {
  6273. m_shouldReportUnexpected = false;
  6274. }
  6275. void RunContext::handleFatalErrorCondition( StringRef message ) {
  6276. // First notify reporter that bad things happened
  6277. m_reporter->fatalErrorEncountered(message);
  6278. // Don't rebuild the result -- the stringification itself can cause more fatal errors
  6279. // Instead, fake a result data.
  6280. AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
  6281. tempResult.message = message;
  6282. AssertionResult result(m_lastAssertionInfo, tempResult);
  6283. getResultCapture().assertionEnded(result);
  6284. handleUnfinishedSections();
  6285. // Recreate section for test case (as we will lose the one that was in scope)
  6286. auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
  6287. SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);
  6288. Counts assertions;
  6289. assertions.failed = 1;
  6290. SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);
  6291. m_reporter->sectionEnded(testCaseSectionStats);
  6292. auto const& testInfo = m_activeTestCase->getTestCaseInfo();
  6293. Totals deltaTotals;
  6294. deltaTotals.testCases.failed = 1;
  6295. deltaTotals.assertions.failed = 1;
  6296. m_reporter->testCaseEnded(TestCaseStats(testInfo,
  6297. deltaTotals,
  6298. std::string(),
  6299. std::string(),
  6300. false));
  6301. m_totals.testCases.failed++;
  6302. testGroupEnded(std::string(), m_totals, 1, 1);
  6303. m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
  6304. }
  6305. bool RunContext::lastAssertionPassed() {
  6306. return m_totals.assertions.passed == (m_prevPassed + 1);
  6307. }
  6308. void RunContext::assertionPassed() {
  6309. ++m_totals.assertions.passed;
  6310. m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}";
  6311. m_lastAssertionInfo.macroName = "";
  6312. }
  6313. void RunContext::assertionRun() {
  6314. m_prevPassed = m_totals.assertions.passed;
  6315. }
  6316. bool RunContext::aborting() const {
  6317. return m_totals.assertions.failed == static_cast<std::size_t>(m_config->abortAfter());
  6318. }
  6319. void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
  6320. auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
  6321. SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);
  6322. m_reporter->sectionStarting(testCaseSection);
  6323. Counts prevAssertions = m_totals.assertions;
  6324. double duration = 0;
  6325. m_shouldReportUnexpected = true;
  6326. try {
  6327. m_lastAssertionInfo = { "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal };
  6328. seedRng(*m_config);
  6329. Timer timer;
  6330. timer.start();
  6331. if (m_reporter->getPreferences().shouldRedirectStdOut) {
  6332. StreamRedirect coutRedir(cout(), redirectedCout);
  6333. StdErrRedirect errRedir(redirectedCerr);
  6334. invokeActiveTestCase();
  6335. } else {
  6336. invokeActiveTestCase();
  6337. }
  6338. duration = timer.getElapsedSeconds();
  6339. } catch (TestFailureException&) {
  6340. // This just means the test was aborted due to failure
  6341. } catch (...) {
  6342. // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
  6343. // are reported without translation at the point of origin.
  6344. if (m_shouldReportUnexpected) {
  6345. AssertionHandler
  6346. ( m_lastAssertionInfo.macroName,
  6347. m_lastAssertionInfo.lineInfo,
  6348. m_lastAssertionInfo.capturedExpression,
  6349. m_lastAssertionInfo.resultDisposition ).useActiveException();
  6350. }
  6351. }
  6352. m_testCaseTracker->close();
  6353. handleUnfinishedSections();
  6354. m_messages.clear();
  6355. Counts assertions = m_totals.assertions - prevAssertions;
  6356. bool missingAssertions = testForMissingAssertions(assertions);
  6357. SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
  6358. m_reporter->sectionEnded(testCaseSectionStats);
  6359. }
  6360. void RunContext::invokeActiveTestCase() {
  6361. FatalConditionHandler fatalConditionHandler; // Handle signals
  6362. m_activeTestCase->invoke();
  6363. fatalConditionHandler.reset();
  6364. }
  6365. void RunContext::handleUnfinishedSections() {
  6366. // If sections ended prematurely due to an exception we stored their
  6367. // infos here so we can tear them down outside the unwind process.
  6368. for (auto it = m_unfinishedSections.rbegin(),
  6369. itEnd = m_unfinishedSections.rend();
  6370. it != itEnd;
  6371. ++it)
  6372. sectionEnded(*it);
  6373. m_unfinishedSections.clear();
  6374. }
  6375. IResultCapture& getResultCapture() {
  6376. if (auto* capture = getCurrentContext().getResultCapture())
  6377. return *capture;
  6378. else
  6379. CATCH_INTERNAL_ERROR("No result capture instance");
  6380. }
  6381. }
  6382. // end catch_run_context.cpp
  6383. // start catch_section.cpp
  6384. namespace Catch {
  6385. Section::Section( SectionInfo const& info )
  6386. : m_info( info ),
  6387. m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
  6388. {
  6389. m_timer.start();
  6390. }
  6391. #if defined(_MSC_VER)
  6392. #pragma warning(push)
  6393. #pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17
  6394. #endif
  6395. Section::~Section() {
  6396. if( m_sectionIncluded ) {
  6397. SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
  6398. if( std::uncaught_exception() )
  6399. getResultCapture().sectionEndedEarly( endInfo );
  6400. else
  6401. getResultCapture().sectionEnded( endInfo );
  6402. }
  6403. }
  6404. #if defined(_MSC_VER)
  6405. #pragma warning(pop)
  6406. #endif
  6407. // This indicates whether the section should be executed or not
  6408. Section::operator bool() const {
  6409. return m_sectionIncluded;
  6410. }
  6411. } // end namespace Catch
  6412. // end catch_section.cpp
  6413. // start catch_section_info.cpp
  6414. namespace Catch {
  6415. SectionInfo::SectionInfo
  6416. ( SourceLineInfo const& _lineInfo,
  6417. std::string const& _name,
  6418. std::string const& _description )
  6419. : name( _name ),
  6420. description( _description ),
  6421. lineInfo( _lineInfo )
  6422. {}
  6423. SectionEndInfo::SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
  6424. : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
  6425. {}
  6426. } // end namespace Catch
  6427. // end catch_section_info.cpp
  6428. // start catch_session.cpp
  6429. // start catch_session.h
  6430. #include <memory>
  6431. namespace Catch {
  6432. class Session : NonCopyable {
  6433. public:
  6434. Session();
  6435. ~Session() override;
  6436. void showHelp() const;
  6437. void libIdentify();
  6438. int applyCommandLine( int argc, char* argv[] );
  6439. void useConfigData( ConfigData const& configData );
  6440. int run( int argc, char* argv[] );
  6441. #if defined(WIN32) && defined(UNICODE)
  6442. int run( int argc, wchar_t* const argv[] );
  6443. #endif
  6444. int run();
  6445. clara::Parser const& cli() const;
  6446. void cli( clara::Parser const& newParser );
  6447. ConfigData& configData();
  6448. Config& config();
  6449. private:
  6450. int runInternal();
  6451. clara::Parser m_cli;
  6452. ConfigData m_configData;
  6453. std::shared_ptr<Config> m_config;
  6454. };
  6455. } // end namespace Catch
  6456. // end catch_session.h
  6457. // start catch_version.h
  6458. #include <iosfwd>
  6459. namespace Catch {
  6460. // Versioning information
  6461. struct Version {
  6462. Version( Version const& ) = delete;
  6463. Version& operator=( Version const& ) = delete;
  6464. Version( unsigned int _majorVersion,
  6465. unsigned int _minorVersion,
  6466. unsigned int _patchNumber,
  6467. char const * const _branchName,
  6468. unsigned int _buildNumber );
  6469. unsigned int const majorVersion;
  6470. unsigned int const minorVersion;
  6471. unsigned int const patchNumber;
  6472. // buildNumber is only used if branchName is not null
  6473. char const * const branchName;
  6474. unsigned int const buildNumber;
  6475. friend std::ostream& operator << ( std::ostream& os, Version const& version );
  6476. };
  6477. Version const& libraryVersion();
  6478. }
  6479. // end catch_version.h
  6480. #include <cstdlib>
  6481. #include <iomanip>
  6482. namespace {
  6483. const int MaxExitCode = 255;
  6484. using Catch::IStreamingReporterPtr;
  6485. using Catch::IConfigPtr;
  6486. using Catch::Config;
  6487. IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) {
  6488. auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);
  6489. CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'");
  6490. return reporter;
  6491. }
  6492. #ifndef CATCH_CONFIG_DEFAULT_REPORTER
  6493. #define CATCH_CONFIG_DEFAULT_REPORTER "console"
  6494. #endif
  6495. IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) {
  6496. auto const& reporterNames = config->getReporterNames();
  6497. if (reporterNames.empty())
  6498. return createReporter(CATCH_CONFIG_DEFAULT_REPORTER, config);
  6499. IStreamingReporterPtr reporter;
  6500. for (auto const& name : reporterNames)
  6501. addReporter(reporter, createReporter(name, config));
  6502. return reporter;
  6503. }
  6504. #undef CATCH_CONFIG_DEFAULT_REPORTER
  6505. void addListeners(IStreamingReporterPtr& reporters, IConfigPtr const& config) {
  6506. auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
  6507. for (auto const& listener : listeners)
  6508. addReporter(reporters, listener->create(Catch::ReporterConfig(config)));
  6509. }
  6510. Catch::Totals runTests(std::shared_ptr<Config> const& config) {
  6511. using namespace Catch;
  6512. IStreamingReporterPtr reporter = makeReporter(config);
  6513. addListeners(reporter, config);
  6514. RunContext context(config, std::move(reporter));
  6515. Totals totals;
  6516. context.testGroupStarting(config->name(), 1, 1);
  6517. TestSpec testSpec = config->testSpec();
  6518. if (!testSpec.hasFilters())
  6519. testSpec = TestSpecParser(ITagAliasRegistry::get()).parse("~[.]").testSpec(); // All not hidden tests
  6520. auto const& allTestCases = getAllTestCasesSorted(*config);
  6521. for (auto const& testCase : allTestCases) {
  6522. if (!context.aborting() && matchTest(testCase, testSpec, *config))
  6523. totals += context.runTest(testCase);
  6524. else
  6525. context.reporter().skipTest(testCase);
  6526. }
  6527. context.testGroupEnded(config->name(), totals, 1, 1);
  6528. return totals;
  6529. }
  6530. void applyFilenamesAsTags(Catch::IConfig const& config) {
  6531. using namespace Catch;
  6532. auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));
  6533. for (auto& testCase : tests) {
  6534. auto tags = testCase.tags;
  6535. std::string filename = testCase.lineInfo.file;
  6536. auto lastSlash = filename.find_last_of("\\/");
  6537. if (lastSlash != std::string::npos) {
  6538. filename.erase(0, lastSlash);
  6539. filename[0] = '#';
  6540. }
  6541. auto lastDot = filename.find_last_of('.');
  6542. if (lastDot != std::string::npos) {
  6543. filename.erase(lastDot);
  6544. }
  6545. tags.push_back(std::move(filename));
  6546. setTags(testCase, tags);
  6547. }
  6548. }
  6549. }
  6550. namespace Catch {
  6551. Session::Session() {
  6552. static bool alreadyInstantiated = false;
  6553. if( alreadyInstantiated )
  6554. CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" );
  6555. alreadyInstantiated = true;
  6556. m_cli = makeCommandLineParser( m_configData );
  6557. }
  6558. Session::~Session() {
  6559. Catch::cleanUp();
  6560. }
  6561. void Session::showHelp() const {
  6562. Catch::cout()
  6563. << "\nCatch v" << libraryVersion() << "\n"
  6564. << m_cli << std::endl
  6565. << "For more detailed usage please see the project docs\n" << std::endl;
  6566. }
  6567. void Session::libIdentify() {
  6568. Catch::cout()
  6569. << std::left << std::setw(16) << "description: " << "A Catch test executable\n"
  6570. << std::left << std::setw(16) << "category: " << "testframework\n"
  6571. << std::left << std::setw(16) << "framework: " << "Catch Test\n"
  6572. << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
  6573. }
  6574. int Session::applyCommandLine( int argc, char* argv[] ) {
  6575. auto result = m_cli.parse( clara::Args( argc, argv ) );
  6576. if( !result ) {
  6577. Catch::cerr()
  6578. << Colour( Colour::Red )
  6579. << "\nError(s) in input:\n"
  6580. << Column( result.errorMessage() ).indent( 2 )
  6581. << "\n\n";
  6582. Catch::cerr() << "Run with -? for usage\n" << std::endl;
  6583. return MaxExitCode;
  6584. }
  6585. if( m_configData.showHelp )
  6586. showHelp();
  6587. if( m_configData.libIdentify )
  6588. libIdentify();
  6589. m_config.reset();
  6590. return 0;
  6591. }
  6592. void Session::useConfigData( ConfigData const& configData ) {
  6593. m_configData = configData;
  6594. m_config.reset();
  6595. }
  6596. int Session::run( int argc, char* argv[] ) {
  6597. const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
  6598. if ( !exceptions.empty() ) {
  6599. Catch::cerr() << "Errors occured during startup!" << '\n';
  6600. // iterate over all exceptions and notify user
  6601. for ( const auto& ex_ptr : exceptions ) {
  6602. try {
  6603. std::rethrow_exception(ex_ptr);
  6604. } catch ( std::exception const& ex ) {
  6605. Catch::cerr() << ex.what() << '\n';
  6606. }
  6607. }
  6608. return 1;
  6609. }
  6610. int returnCode = applyCommandLine( argc, argv );
  6611. if( returnCode == 0 )
  6612. returnCode = run();
  6613. return returnCode;
  6614. }
  6615. #if defined(WIN32) && defined(UNICODE)
  6616. int Session::run( int argc, wchar_t* const argv[] ) {
  6617. char **utf8Argv = new char *[ argc ];
  6618. for ( int i = 0; i < argc; ++i ) {
  6619. int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL );
  6620. utf8Argv[ i ] = new char[ bufSize ];
  6621. WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
  6622. }
  6623. int returnCode = run( argc, utf8Argv );
  6624. for ( int i = 0; i < argc; ++i )
  6625. delete [] utf8Argv[ i ];
  6626. delete [] utf8Argv;
  6627. return returnCode;
  6628. }
  6629. #endif
  6630. int Session::run() {
  6631. if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
  6632. Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
  6633. static_cast<void>(std::getchar());
  6634. }
  6635. int exitCode = runInternal();
  6636. if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {
  6637. Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
  6638. static_cast<void>(std::getchar());
  6639. }
  6640. return exitCode;
  6641. }
  6642. clara::Parser const& Session::cli() const {
  6643. return m_cli;
  6644. }
  6645. void Session::cli( clara::Parser const& newParser ) {
  6646. m_cli = newParser;
  6647. }
  6648. ConfigData& Session::configData() {
  6649. return m_configData;
  6650. }
  6651. Config& Session::config() {
  6652. if( !m_config )
  6653. m_config = std::make_shared<Config>( m_configData );
  6654. return *m_config;
  6655. }
  6656. int Session::runInternal() {
  6657. if( m_configData.showHelp || m_configData.libIdentify )
  6658. return 0;
  6659. try
  6660. {
  6661. config(); // Force config to be constructed
  6662. seedRng( *m_config );
  6663. if( m_configData.filenamesAsTags )
  6664. applyFilenamesAsTags( *m_config );
  6665. // Handle list request
  6666. if( Option<std::size_t> listed = list( config() ) )
  6667. return static_cast<int>( *listed );
  6668. return (std::min)( MaxExitCode, static_cast<int>( runTests( m_config ).assertions.failed ) );
  6669. }
  6670. catch( std::exception& ex ) {
  6671. Catch::cerr() << ex.what() << std::endl;
  6672. return MaxExitCode;
  6673. }
  6674. }
  6675. } // end namespace Catch
  6676. // end catch_session.cpp
  6677. // start catch_startup_exception_registry.cpp
  6678. namespace Catch {
  6679. void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
  6680. try {
  6681. m_exceptions.push_back(exception);
  6682. }
  6683. catch(...) {
  6684. // If we run out of memory during start-up there's really not a lot more we can do about it
  6685. std::terminate();
  6686. }
  6687. }
  6688. std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept {
  6689. return m_exceptions;
  6690. }
  6691. } // end namespace Catch
  6692. // end catch_startup_exception_registry.cpp
  6693. // start catch_stream.cpp
  6694. #include <stdexcept>
  6695. #include <cstdio>
  6696. #include <iostream>
  6697. namespace Catch {
  6698. template<typename WriterF, std::size_t bufferSize=256>
  6699. class StreamBufImpl : public StreamBufBase {
  6700. char data[bufferSize];
  6701. WriterF m_writer;
  6702. public:
  6703. StreamBufImpl() {
  6704. setp( data, data + sizeof(data) );
  6705. }
  6706. ~StreamBufImpl() noexcept {
  6707. StreamBufImpl::sync();
  6708. }
  6709. private:
  6710. int overflow( int c ) override {
  6711. sync();
  6712. if( c != EOF ) {
  6713. if( pbase() == epptr() )
  6714. m_writer( std::string( 1, static_cast<char>( c ) ) );
  6715. else
  6716. sputc( static_cast<char>( c ) );
  6717. }
  6718. return 0;
  6719. }
  6720. int sync() override {
  6721. if( pbase() != pptr() ) {
  6722. m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
  6723. setp( pbase(), epptr() );
  6724. }
  6725. return 0;
  6726. }
  6727. };
  6728. ///////////////////////////////////////////////////////////////////////////
  6729. Catch::IStream::~IStream() = default;
  6730. FileStream::FileStream( std::string const& filename ) {
  6731. m_ofs.open( filename.c_str() );
  6732. CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" );
  6733. }
  6734. std::ostream& FileStream::stream() const {
  6735. return m_ofs;
  6736. }
  6737. struct OutputDebugWriter {
  6738. void operator()( std::string const&str ) {
  6739. writeToDebugConsole( str );
  6740. }
  6741. };
  6742. DebugOutStream::DebugOutStream()
  6743. : m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
  6744. m_os( m_streamBuf.get() )
  6745. {}
  6746. std::ostream& DebugOutStream::stream() const {
  6747. return m_os;
  6748. }
  6749. // Store the streambuf from cout up-front because
  6750. // cout may get redirected when running tests
  6751. CoutStream::CoutStream()
  6752. : m_os( Catch::cout().rdbuf() )
  6753. {}
  6754. std::ostream& CoutStream::stream() const {
  6755. return m_os;
  6756. }
  6757. #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
  6758. std::ostream& cout() {
  6759. return std::cout;
  6760. }
  6761. std::ostream& cerr() {
  6762. return std::cerr;
  6763. }
  6764. std::ostream& clog() {
  6765. return std::clog;
  6766. }
  6767. #endif
  6768. }
  6769. // end catch_stream.cpp
  6770. // start catch_streambuf.cpp
  6771. namespace Catch {
  6772. StreamBufBase::~StreamBufBase() = default;
  6773. }
  6774. // end catch_streambuf.cpp
  6775. // start catch_string_manip.cpp
  6776. #include <algorithm>
  6777. #include <ostream>
  6778. #include <cstring>
  6779. #include <cctype>
  6780. namespace Catch {
  6781. bool startsWith( std::string const& s, std::string const& prefix ) {
  6782. return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
  6783. }
  6784. bool startsWith( std::string const& s, char prefix ) {
  6785. return !s.empty() && s[0] == prefix;
  6786. }
  6787. bool endsWith( std::string const& s, std::string const& suffix ) {
  6788. return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
  6789. }
  6790. bool endsWith( std::string const& s, char suffix ) {
  6791. return !s.empty() && s[s.size()-1] == suffix;
  6792. }
  6793. bool contains( std::string const& s, std::string const& infix ) {
  6794. return s.find( infix ) != std::string::npos;
  6795. }
  6796. char toLowerCh(char c) {
  6797. return static_cast<char>( std::tolower( c ) );
  6798. }
  6799. void toLowerInPlace( std::string& s ) {
  6800. std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
  6801. }
  6802. std::string toLower( std::string const& s ) {
  6803. std::string lc = s;
  6804. toLowerInPlace( lc );
  6805. return lc;
  6806. }
  6807. std::string trim( std::string const& str ) {
  6808. static char const* whitespaceChars = "\n\r\t ";
  6809. std::string::size_type start = str.find_first_not_of( whitespaceChars );
  6810. std::string::size_type end = str.find_last_not_of( whitespaceChars );
  6811. return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
  6812. }
  6813. bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
  6814. bool replaced = false;
  6815. std::size_t i = str.find( replaceThis );
  6816. while( i != std::string::npos ) {
  6817. replaced = true;
  6818. str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
  6819. if( i < str.size()-withThis.size() )
  6820. i = str.find( replaceThis, i+withThis.size() );
  6821. else
  6822. i = std::string::npos;
  6823. }
  6824. return replaced;
  6825. }
  6826. pluralise::pluralise( std::size_t count, std::string const& label )
  6827. : m_count( count ),
  6828. m_label( label )
  6829. {}
  6830. std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
  6831. os << pluraliser.m_count << ' ' << pluraliser.m_label;
  6832. if( pluraliser.m_count != 1 )
  6833. os << 's';
  6834. return os;
  6835. }
  6836. }
  6837. // end catch_string_manip.cpp
  6838. // start catch_stringref.cpp
  6839. #if defined(__clang__)
  6840. # pragma clang diagnostic push
  6841. # pragma clang diagnostic ignored "-Wexit-time-destructors"
  6842. #endif
  6843. #include <ostream>
  6844. #include <cassert>
  6845. #include <cstring>
  6846. namespace Catch {
  6847. auto getEmptyStringRef() -> StringRef {
  6848. static StringRef s_emptyStringRef("");
  6849. return s_emptyStringRef;
  6850. }
  6851. StringRef::StringRef() noexcept
  6852. : StringRef( getEmptyStringRef() )
  6853. {}
  6854. StringRef::StringRef( StringRef const& other ) noexcept
  6855. : m_start( other.m_start ),
  6856. m_size( other.m_size )
  6857. {}
  6858. StringRef::StringRef( StringRef&& other ) noexcept
  6859. : m_start( other.m_start ),
  6860. m_size( other.m_size ),
  6861. m_data( other.m_data )
  6862. {
  6863. other.m_data = nullptr;
  6864. }
  6865. StringRef::StringRef( char const* rawChars ) noexcept
  6866. : m_start( rawChars ),
  6867. m_size( static_cast<size_type>( std::strlen( rawChars ) ) )
  6868. {
  6869. assert( rawChars != nullptr );
  6870. }
  6871. StringRef::StringRef( char const* rawChars, size_type size ) noexcept
  6872. : m_start( rawChars ),
  6873. m_size( size )
  6874. {
  6875. size_type rawSize = rawChars == nullptr ? 0 : static_cast<size_type>( std::strlen( rawChars ) );
  6876. if( rawSize < size )
  6877. m_size = rawSize;
  6878. }
  6879. StringRef::StringRef( std::string const& stdString ) noexcept
  6880. : m_start( stdString.c_str() ),
  6881. m_size( stdString.size() )
  6882. {}
  6883. StringRef::~StringRef() noexcept {
  6884. delete[] m_data;
  6885. }
  6886. auto StringRef::operator = ( StringRef other ) noexcept -> StringRef& {
  6887. swap( other );
  6888. return *this;
  6889. }
  6890. StringRef::operator std::string() const {
  6891. return std::string( m_start, m_size );
  6892. }
  6893. void StringRef::swap( StringRef& other ) noexcept {
  6894. std::swap( m_start, other.m_start );
  6895. std::swap( m_size, other.m_size );
  6896. std::swap( m_data, other.m_data );
  6897. }
  6898. auto StringRef::c_str() const -> char const* {
  6899. if( isSubstring() )
  6900. const_cast<StringRef*>( this )->takeOwnership();
  6901. return m_start;
  6902. }
  6903. auto StringRef::data() const noexcept -> char const* {
  6904. return m_start;
  6905. }
  6906. auto StringRef::isOwned() const noexcept -> bool {
  6907. return m_data != nullptr;
  6908. }
  6909. auto StringRef::isSubstring() const noexcept -> bool {
  6910. return m_start[m_size] != '\0';
  6911. }
  6912. void StringRef::takeOwnership() {
  6913. if( !isOwned() ) {
  6914. m_data = new char[m_size+1];
  6915. memcpy( m_data, m_start, m_size );
  6916. m_data[m_size] = '\0';
  6917. m_start = m_data;
  6918. }
  6919. }
  6920. auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
  6921. if( start < m_size )
  6922. return StringRef( m_start+start, size );
  6923. else
  6924. return StringRef();
  6925. }
  6926. auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {
  6927. return
  6928. size() == other.size() &&
  6929. (std::strncmp( m_start, other.m_start, size() ) == 0);
  6930. }
  6931. auto StringRef::operator != ( StringRef const& other ) const noexcept -> bool {
  6932. return !operator==( other );
  6933. }
  6934. auto StringRef::operator[](size_type index) const noexcept -> char {
  6935. return m_start[index];
  6936. }
  6937. auto StringRef::empty() const noexcept -> bool {
  6938. return m_size == 0;
  6939. }
  6940. auto StringRef::size() const noexcept -> size_type {
  6941. return m_size;
  6942. }
  6943. auto StringRef::numberOfCharacters() const noexcept -> size_type {
  6944. size_type noChars = m_size;
  6945. // Make adjustments for uft encodings
  6946. for( size_type i=0; i < m_size; ++i ) {
  6947. char c = m_start[i];
  6948. if( ( c & 0b11000000 ) == 0b11000000 ) {
  6949. if( ( c & 0b11100000 ) == 0b11000000 )
  6950. noChars--;
  6951. else if( ( c & 0b11110000 ) == 0b11100000 )
  6952. noChars-=2;
  6953. else if( ( c & 0b11111000 ) == 0b11110000 )
  6954. noChars-=3;
  6955. }
  6956. }
  6957. return noChars;
  6958. }
  6959. auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string {
  6960. std::string str;
  6961. str.reserve( lhs.size() + rhs.size() );
  6962. str += lhs;
  6963. str += rhs;
  6964. return str;
  6965. }
  6966. auto operator + ( StringRef const& lhs, const char* rhs ) -> std::string {
  6967. return std::string( lhs ) + std::string( rhs );
  6968. }
  6969. auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string {
  6970. return std::string( lhs ) + std::string( rhs );
  6971. }
  6972. auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {
  6973. return os << str.c_str();
  6974. }
  6975. } // namespace Catch
  6976. #if defined(__clang__)
  6977. # pragma clang diagnostic pop
  6978. #endif
  6979. // end catch_stringref.cpp
  6980. // start catch_tag_alias.cpp
  6981. namespace Catch {
  6982. TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {}
  6983. }
  6984. // end catch_tag_alias.cpp
  6985. // start catch_tag_alias_autoregistrar.cpp
  6986. namespace Catch {
  6987. RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
  6988. try {
  6989. getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
  6990. } catch (...) {
  6991. // Do not throw when constructing global objects, instead register the exception to be processed later
  6992. getMutableRegistryHub().registerStartupException();
  6993. }
  6994. }
  6995. }
  6996. // end catch_tag_alias_autoregistrar.cpp
  6997. // start catch_tag_alias_registry.cpp
  6998. namespace Catch {
  6999. TagAliasRegistry::~TagAliasRegistry() {}
  7000. TagAlias const* TagAliasRegistry::find( std::string const& alias ) const {
  7001. auto it = m_registry.find( alias );
  7002. if( it != m_registry.end() )
  7003. return &(it->second);
  7004. else
  7005. return nullptr;
  7006. }
  7007. std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
  7008. std::string expandedTestSpec = unexpandedTestSpec;
  7009. for( auto const& registryKvp : m_registry ) {
  7010. std::size_t pos = expandedTestSpec.find( registryKvp.first );
  7011. if( pos != std::string::npos ) {
  7012. expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
  7013. registryKvp.second.tag +
  7014. expandedTestSpec.substr( pos + registryKvp.first.size() );
  7015. }
  7016. }
  7017. return expandedTestSpec;
  7018. }
  7019. void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {
  7020. CATCH_ENFORCE( startsWith(alias, "[@") && endsWith(alias, ']'),
  7021. "error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo );
  7022. CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
  7023. "error: tag alias, '" << alias << "' already registered.\n"
  7024. << "\tFirst seen at: " << find(alias)->lineInfo << "\n"
  7025. << "\tRedefined at: " << lineInfo );
  7026. }
  7027. ITagAliasRegistry::~ITagAliasRegistry() {}
  7028. ITagAliasRegistry const& ITagAliasRegistry::get() {
  7029. return getRegistryHub().getTagAliasRegistry();
  7030. }
  7031. } // end namespace Catch
  7032. // end catch_tag_alias_registry.cpp
  7033. // start catch_test_case_info.cpp
  7034. #include <cctype>
  7035. #include <exception>
  7036. #include <algorithm>
  7037. namespace Catch {
  7038. TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
  7039. if( startsWith( tag, '.' ) ||
  7040. tag == "!hide" )
  7041. return TestCaseInfo::IsHidden;
  7042. else if( tag == "!throws" )
  7043. return TestCaseInfo::Throws;
  7044. else if( tag == "!shouldfail" )
  7045. return TestCaseInfo::ShouldFail;
  7046. else if( tag == "!mayfail" )
  7047. return TestCaseInfo::MayFail;
  7048. else if( tag == "!nonportable" )
  7049. return TestCaseInfo::NonPortable;
  7050. else if( tag == "!benchmark" )
  7051. return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );
  7052. else
  7053. return TestCaseInfo::None;
  7054. }
  7055. bool isReservedTag( std::string const& tag ) {
  7056. return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( tag[0] );
  7057. }
  7058. void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
  7059. CATCH_ENFORCE( !isReservedTag(tag),
  7060. "Tag name: [" << tag << "] is not allowed.\n"
  7061. << "Tag names starting with non alpha-numeric characters are reserved\n"
  7062. << _lineInfo );
  7063. }
  7064. TestCase makeTestCase( ITestInvoker* _testCase,
  7065. std::string const& _className,
  7066. std::string const& _name,
  7067. std::string const& _descOrTags,
  7068. SourceLineInfo const& _lineInfo )
  7069. {
  7070. bool isHidden = false;
  7071. // Parse out tags
  7072. std::vector<std::string> tags;
  7073. std::string desc, tag;
  7074. bool inTag = false;
  7075. for (char c : _descOrTags) {
  7076. if( !inTag ) {
  7077. if( c == '[' )
  7078. inTag = true;
  7079. else
  7080. desc += c;
  7081. }
  7082. else {
  7083. if( c == ']' ) {
  7084. TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
  7085. if( ( prop & TestCaseInfo::IsHidden ) != 0 )
  7086. isHidden = true;
  7087. else if( prop == TestCaseInfo::None )
  7088. enforceNotReservedTag( tag, _lineInfo );
  7089. tags.push_back( tag );
  7090. tag.clear();
  7091. inTag = false;
  7092. }
  7093. else
  7094. tag += c;
  7095. }
  7096. }
  7097. if( isHidden ) {
  7098. tags.push_back( "." );
  7099. }
  7100. TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
  7101. return TestCase( _testCase, info );
  7102. }
  7103. void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ) {
  7104. std::sort(begin(tags), end(tags));
  7105. tags.erase(std::unique(begin(tags), end(tags)), end(tags));
  7106. testCaseInfo.lcaseTags.clear();
  7107. for( auto const& tag : tags ) {
  7108. std::string lcaseTag = toLower( tag );
  7109. testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
  7110. testCaseInfo.lcaseTags.push_back( lcaseTag );
  7111. }
  7112. testCaseInfo.tags = std::move(tags);
  7113. }
  7114. TestCaseInfo::TestCaseInfo( std::string const& _name,
  7115. std::string const& _className,
  7116. std::string const& _description,
  7117. std::vector<std::string> const& _tags,
  7118. SourceLineInfo const& _lineInfo )
  7119. : name( _name ),
  7120. className( _className ),
  7121. description( _description ),
  7122. lineInfo( _lineInfo ),
  7123. properties( None )
  7124. {
  7125. setTags( *this, _tags );
  7126. }
  7127. bool TestCaseInfo::isHidden() const {
  7128. return ( properties & IsHidden ) != 0;
  7129. }
  7130. bool TestCaseInfo::throws() const {
  7131. return ( properties & Throws ) != 0;
  7132. }
  7133. bool TestCaseInfo::okToFail() const {
  7134. return ( properties & (ShouldFail | MayFail ) ) != 0;
  7135. }
  7136. bool TestCaseInfo::expectedToFail() const {
  7137. return ( properties & (ShouldFail ) ) != 0;
  7138. }
  7139. std::string TestCaseInfo::tagsAsString() const {
  7140. std::string ret;
  7141. // '[' and ']' per tag
  7142. std::size_t full_size = 2 * tags.size();
  7143. for (const auto& tag : tags) {
  7144. full_size += tag.size();
  7145. }
  7146. ret.reserve(full_size);
  7147. for (const auto& tag : tags) {
  7148. ret.push_back('[');
  7149. ret.append(tag);
  7150. ret.push_back(']');
  7151. }
  7152. return ret;
  7153. }
  7154. TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
  7155. TestCase TestCase::withName( std::string const& _newName ) const {
  7156. TestCase other( *this );
  7157. other.name = _newName;
  7158. return other;
  7159. }
  7160. void TestCase::invoke() const {
  7161. test->invoke();
  7162. }
  7163. bool TestCase::operator == ( TestCase const& other ) const {
  7164. return test.get() == other.test.get() &&
  7165. name == other.name &&
  7166. className == other.className;
  7167. }
  7168. bool TestCase::operator < ( TestCase const& other ) const {
  7169. return name < other.name;
  7170. }
  7171. TestCaseInfo const& TestCase::getTestCaseInfo() const
  7172. {
  7173. return *this;
  7174. }
  7175. } // end namespace Catch
  7176. // end catch_test_case_info.cpp
  7177. // start catch_test_case_registry_impl.cpp
  7178. #include <sstream>
  7179. namespace Catch {
  7180. std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
  7181. std::vector<TestCase> sorted = unsortedTestCases;
  7182. switch( config.runOrder() ) {
  7183. case RunTests::InLexicographicalOrder:
  7184. std::sort( sorted.begin(), sorted.end() );
  7185. break;
  7186. case RunTests::InRandomOrder:
  7187. seedRng( config );
  7188. RandomNumberGenerator::shuffle( sorted );
  7189. break;
  7190. case RunTests::InDeclarationOrder:
  7191. // already in declaration order
  7192. break;
  7193. }
  7194. return sorted;
  7195. }
  7196. bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
  7197. return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
  7198. }
  7199. void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
  7200. std::set<TestCase> seenFunctions;
  7201. for( auto const& function : functions ) {
  7202. auto prev = seenFunctions.insert( function );
  7203. CATCH_ENFORCE( prev.second,
  7204. "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n"
  7205. << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
  7206. << "\tRedefined at " << function.getTestCaseInfo().lineInfo );
  7207. }
  7208. }
  7209. std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
  7210. std::vector<TestCase> filtered;
  7211. filtered.reserve( testCases.size() );
  7212. for( auto const& testCase : testCases )
  7213. if( matchTest( testCase, testSpec, config ) )
  7214. filtered.push_back( testCase );
  7215. return filtered;
  7216. }
  7217. std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
  7218. return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
  7219. }
  7220. void TestRegistry::registerTest( TestCase const& testCase ) {
  7221. std::string name = testCase.getTestCaseInfo().name;
  7222. if( name.empty() ) {
  7223. std::ostringstream oss;
  7224. oss << "Anonymous test case " << ++m_unnamedCount;
  7225. return registerTest( testCase.withName( oss.str() ) );
  7226. }
  7227. m_functions.push_back( testCase );
  7228. }
  7229. std::vector<TestCase> const& TestRegistry::getAllTests() const {
  7230. return m_functions;
  7231. }
  7232. std::vector<TestCase> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const {
  7233. if( m_sortedFunctions.empty() )
  7234. enforceNoDuplicateTestCases( m_functions );
  7235. if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
  7236. m_sortedFunctions = sortTests( config, m_functions );
  7237. m_currentSortOrder = config.runOrder();
  7238. }
  7239. return m_sortedFunctions;
  7240. }
  7241. ///////////////////////////////////////////////////////////////////////////
  7242. TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {}
  7243. void TestInvokerAsFunction::invoke() const {
  7244. m_testAsFunction();
  7245. }
  7246. std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
  7247. std::string className = classOrQualifiedMethodName;
  7248. if( startsWith( className, '&' ) )
  7249. {
  7250. std::size_t lastColons = className.rfind( "::" );
  7251. std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
  7252. if( penultimateColons == std::string::npos )
  7253. penultimateColons = 1;
  7254. className = className.substr( penultimateColons, lastColons-penultimateColons );
  7255. }
  7256. return className;
  7257. }
  7258. } // end namespace Catch
  7259. // end catch_test_case_registry_impl.cpp
  7260. // start catch_test_case_tracker.cpp
  7261. #include <algorithm>
  7262. #include <assert.h>
  7263. #include <stdexcept>
  7264. #include <memory>
  7265. #if defined(__clang__)
  7266. # pragma clang diagnostic push
  7267. # pragma clang diagnostic ignored "-Wexit-time-destructors"
  7268. #endif
  7269. namespace Catch {
  7270. namespace TestCaseTracking {
  7271. NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
  7272. : name( _name ),
  7273. location( _location )
  7274. {}
  7275. ITracker::~ITracker() = default;
  7276. TrackerContext& TrackerContext::instance() {
  7277. static TrackerContext s_instance;
  7278. return s_instance;
  7279. }
  7280. ITracker& TrackerContext::startRun() {
  7281. m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr );
  7282. m_currentTracker = nullptr;
  7283. m_runState = Executing;
  7284. return *m_rootTracker;
  7285. }
  7286. void TrackerContext::endRun() {
  7287. m_rootTracker.reset();
  7288. m_currentTracker = nullptr;
  7289. m_runState = NotStarted;
  7290. }
  7291. void TrackerContext::startCycle() {
  7292. m_currentTracker = m_rootTracker.get();
  7293. m_runState = Executing;
  7294. }
  7295. void TrackerContext::completeCycle() {
  7296. m_runState = CompletedCycle;
  7297. }
  7298. bool TrackerContext::completedCycle() const {
  7299. return m_runState == CompletedCycle;
  7300. }
  7301. ITracker& TrackerContext::currentTracker() {
  7302. return *m_currentTracker;
  7303. }
  7304. void TrackerContext::setCurrentTracker( ITracker* tracker ) {
  7305. m_currentTracker = tracker;
  7306. }
  7307. TrackerBase::TrackerHasName::TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {}
  7308. bool TrackerBase::TrackerHasName::operator ()( ITrackerPtr const& tracker ) const {
  7309. return
  7310. tracker->nameAndLocation().name == m_nameAndLocation.name &&
  7311. tracker->nameAndLocation().location == m_nameAndLocation.location;
  7312. }
  7313. TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
  7314. : m_nameAndLocation( nameAndLocation ),
  7315. m_ctx( ctx ),
  7316. m_parent( parent )
  7317. {}
  7318. NameAndLocation const& TrackerBase::nameAndLocation() const {
  7319. return m_nameAndLocation;
  7320. }
  7321. bool TrackerBase::isComplete() const {
  7322. return m_runState == CompletedSuccessfully || m_runState == Failed;
  7323. }
  7324. bool TrackerBase::isSuccessfullyCompleted() const {
  7325. return m_runState == CompletedSuccessfully;
  7326. }
  7327. bool TrackerBase::isOpen() const {
  7328. return m_runState != NotStarted && !isComplete();
  7329. }
  7330. bool TrackerBase::hasChildren() const {
  7331. return !m_children.empty();
  7332. }
  7333. void TrackerBase::addChild( ITrackerPtr const& child ) {
  7334. m_children.push_back( child );
  7335. }
  7336. ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {
  7337. auto it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( nameAndLocation ) );
  7338. return( it != m_children.end() )
  7339. ? *it
  7340. : nullptr;
  7341. }
  7342. ITracker& TrackerBase::parent() {
  7343. assert( m_parent ); // Should always be non-null except for root
  7344. return *m_parent;
  7345. }
  7346. void TrackerBase::openChild() {
  7347. if( m_runState != ExecutingChildren ) {
  7348. m_runState = ExecutingChildren;
  7349. if( m_parent )
  7350. m_parent->openChild();
  7351. }
  7352. }
  7353. bool TrackerBase::isSectionTracker() const { return false; }
  7354. bool TrackerBase::isIndexTracker() const { return false; }
  7355. void TrackerBase::open() {
  7356. m_runState = Executing;
  7357. moveToThis();
  7358. if( m_parent )
  7359. m_parent->openChild();
  7360. }
  7361. void TrackerBase::close() {
  7362. // Close any still open children (e.g. generators)
  7363. while( &m_ctx.currentTracker() != this )
  7364. m_ctx.currentTracker().close();
  7365. switch( m_runState ) {
  7366. case NeedsAnotherRun:
  7367. break;
  7368. case Executing:
  7369. m_runState = CompletedSuccessfully;
  7370. break;
  7371. case ExecutingChildren:
  7372. if( m_children.empty() || m_children.back()->isComplete() )
  7373. m_runState = CompletedSuccessfully;
  7374. break;
  7375. case NotStarted:
  7376. case CompletedSuccessfully:
  7377. case Failed:
  7378. CATCH_INTERNAL_ERROR( "Illogical state: " << m_runState );
  7379. default:
  7380. CATCH_INTERNAL_ERROR( "Unknown state: " << m_runState );
  7381. }
  7382. moveToParent();
  7383. m_ctx.completeCycle();
  7384. }
  7385. void TrackerBase::fail() {
  7386. m_runState = Failed;
  7387. if( m_parent )
  7388. m_parent->markAsNeedingAnotherRun();
  7389. moveToParent();
  7390. m_ctx.completeCycle();
  7391. }
  7392. void TrackerBase::markAsNeedingAnotherRun() {
  7393. m_runState = NeedsAnotherRun;
  7394. }
  7395. void TrackerBase::moveToParent() {
  7396. assert( m_parent );
  7397. m_ctx.setCurrentTracker( m_parent );
  7398. }
  7399. void TrackerBase::moveToThis() {
  7400. m_ctx.setCurrentTracker( this );
  7401. }
  7402. SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
  7403. : TrackerBase( nameAndLocation, ctx, parent )
  7404. {
  7405. if( parent ) {
  7406. while( !parent->isSectionTracker() )
  7407. parent = &parent->parent();
  7408. SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
  7409. addNextFilters( parentSection.m_filters );
  7410. }
  7411. }
  7412. bool SectionTracker::isSectionTracker() const { return true; }
  7413. SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
  7414. std::shared_ptr<SectionTracker> section;
  7415. ITracker& currentTracker = ctx.currentTracker();
  7416. if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
  7417. assert( childTracker );
  7418. assert( childTracker->isSectionTracker() );
  7419. section = std::static_pointer_cast<SectionTracker>( childTracker );
  7420. }
  7421. else {
  7422. section = std::make_shared<SectionTracker>( nameAndLocation, ctx, &currentTracker );
  7423. currentTracker.addChild( section );
  7424. }
  7425. if( !ctx.completedCycle() )
  7426. section->tryOpen();
  7427. return *section;
  7428. }
  7429. void SectionTracker::tryOpen() {
  7430. if( !isComplete() && (m_filters.empty() || m_filters[0].empty() || m_filters[0] == m_nameAndLocation.name ) )
  7431. open();
  7432. }
  7433. void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {
  7434. if( !filters.empty() ) {
  7435. m_filters.push_back(""); // Root - should never be consulted
  7436. m_filters.push_back(""); // Test Case - not a section filter
  7437. m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
  7438. }
  7439. }
  7440. void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) {
  7441. if( filters.size() > 1 )
  7442. m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() );
  7443. }
  7444. IndexTracker::IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size )
  7445. : TrackerBase( nameAndLocation, ctx, parent ),
  7446. m_size( size )
  7447. {}
  7448. bool IndexTracker::isIndexTracker() const { return true; }
  7449. IndexTracker& IndexTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ) {
  7450. std::shared_ptr<IndexTracker> tracker;
  7451. ITracker& currentTracker = ctx.currentTracker();
  7452. if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
  7453. assert( childTracker );
  7454. assert( childTracker->isIndexTracker() );
  7455. tracker = std::static_pointer_cast<IndexTracker>( childTracker );
  7456. }
  7457. else {
  7458. tracker = std::make_shared<IndexTracker>( nameAndLocation, ctx, &currentTracker, size );
  7459. currentTracker.addChild( tracker );
  7460. }
  7461. if( !ctx.completedCycle() && !tracker->isComplete() ) {
  7462. if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
  7463. tracker->moveNext();
  7464. tracker->open();
  7465. }
  7466. return *tracker;
  7467. }
  7468. int IndexTracker::index() const { return m_index; }
  7469. void IndexTracker::moveNext() {
  7470. m_index++;
  7471. m_children.clear();
  7472. }
  7473. void IndexTracker::close() {
  7474. TrackerBase::close();
  7475. if( m_runState == CompletedSuccessfully && m_index < m_size-1 )
  7476. m_runState = Executing;
  7477. }
  7478. } // namespace TestCaseTracking
  7479. using TestCaseTracking::ITracker;
  7480. using TestCaseTracking::TrackerContext;
  7481. using TestCaseTracking::SectionTracker;
  7482. using TestCaseTracking::IndexTracker;
  7483. } // namespace Catch
  7484. #if defined(__clang__)
  7485. # pragma clang diagnostic pop
  7486. #endif
  7487. // end catch_test_case_tracker.cpp
  7488. // start catch_test_registry.cpp
  7489. namespace Catch {
  7490. auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* {
  7491. return new(std::nothrow) TestInvokerAsFunction( testAsFunction );
  7492. }
  7493. NameAndTags::NameAndTags( StringRef name_ , StringRef tags_ ) noexcept : name( name_ ), tags( tags_ ) {}
  7494. AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef classOrMethod, NameAndTags const& nameAndTags ) noexcept {
  7495. try {
  7496. getMutableRegistryHub()
  7497. .registerTest(
  7498. makeTestCase(
  7499. invoker,
  7500. extractClassName( classOrMethod ),
  7501. nameAndTags.name,
  7502. nameAndTags.tags,
  7503. lineInfo));
  7504. } catch (...) {
  7505. // Do not throw when constructing global objects, instead register the exception to be processed later
  7506. getMutableRegistryHub().registerStartupException();
  7507. }
  7508. }
  7509. AutoReg::~AutoReg() = default;
  7510. }
  7511. // end catch_test_registry.cpp
  7512. // start catch_test_spec.cpp
  7513. #include <algorithm>
  7514. #include <string>
  7515. #include <vector>
  7516. #include <memory>
  7517. namespace Catch {
  7518. TestSpec::Pattern::~Pattern() = default;
  7519. TestSpec::NamePattern::~NamePattern() = default;
  7520. TestSpec::TagPattern::~TagPattern() = default;
  7521. TestSpec::ExcludedPattern::~ExcludedPattern() = default;
  7522. TestSpec::NamePattern::NamePattern( std::string const& name )
  7523. : m_wildcardPattern( toLower( name ), CaseSensitive::No )
  7524. {}
  7525. bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const {
  7526. return m_wildcardPattern.matches( toLower( testCase.name ) );
  7527. }
  7528. TestSpec::TagPattern::TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
  7529. bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const {
  7530. return std::find(begin(testCase.lcaseTags),
  7531. end(testCase.lcaseTags),
  7532. m_tag) != end(testCase.lcaseTags);
  7533. }
  7534. TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
  7535. bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
  7536. bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {
  7537. // All patterns in a filter must match for the filter to be a match
  7538. for( auto const& pattern : m_patterns ) {
  7539. if( !pattern->matches( testCase ) )
  7540. return false;
  7541. }
  7542. return true;
  7543. }
  7544. bool TestSpec::hasFilters() const {
  7545. return !m_filters.empty();
  7546. }
  7547. bool TestSpec::matches( TestCaseInfo const& testCase ) const {
  7548. // A TestSpec matches if any filter matches
  7549. for( auto const& filter : m_filters )
  7550. if( filter.matches( testCase ) )
  7551. return true;
  7552. return false;
  7553. }
  7554. }
  7555. // end catch_test_spec.cpp
  7556. // start catch_test_spec_parser.cpp
  7557. namespace Catch {
  7558. TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
  7559. TestSpecParser& TestSpecParser::parse( std::string const& arg ) {
  7560. m_mode = None;
  7561. m_exclusion = false;
  7562. m_start = std::string::npos;
  7563. m_arg = m_tagAliases->expandAliases( arg );
  7564. m_escapeChars.clear();
  7565. for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
  7566. visitChar( m_arg[m_pos] );
  7567. if( m_mode == Name )
  7568. addPattern<TestSpec::NamePattern>();
  7569. return *this;
  7570. }
  7571. TestSpec TestSpecParser::testSpec() {
  7572. addFilter();
  7573. return m_testSpec;
  7574. }
  7575. void TestSpecParser::visitChar( char c ) {
  7576. if( m_mode == None ) {
  7577. switch( c ) {
  7578. case ' ': return;
  7579. case '~': m_exclusion = true; return;
  7580. case '[': return startNewMode( Tag, ++m_pos );
  7581. case '"': return startNewMode( QuotedName, ++m_pos );
  7582. case '\\': return escape();
  7583. default: startNewMode( Name, m_pos ); break;
  7584. }
  7585. }
  7586. if( m_mode == Name ) {
  7587. if( c == ',' ) {
  7588. addPattern<TestSpec::NamePattern>();
  7589. addFilter();
  7590. }
  7591. else if( c == '[' ) {
  7592. if( subString() == "exclude:" )
  7593. m_exclusion = true;
  7594. else
  7595. addPattern<TestSpec::NamePattern>();
  7596. startNewMode( Tag, ++m_pos );
  7597. }
  7598. else if( c == '\\' )
  7599. escape();
  7600. }
  7601. else if( m_mode == EscapedName )
  7602. m_mode = Name;
  7603. else if( m_mode == QuotedName && c == '"' )
  7604. addPattern<TestSpec::NamePattern>();
  7605. else if( m_mode == Tag && c == ']' )
  7606. addPattern<TestSpec::TagPattern>();
  7607. }
  7608. void TestSpecParser::startNewMode( Mode mode, std::size_t start ) {
  7609. m_mode = mode;
  7610. m_start = start;
  7611. }
  7612. void TestSpecParser::escape() {
  7613. if( m_mode == None )
  7614. m_start = m_pos;
  7615. m_mode = EscapedName;
  7616. m_escapeChars.push_back( m_pos );
  7617. }
  7618. std::string TestSpecParser::subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
  7619. void TestSpecParser::addFilter() {
  7620. if( !m_currentFilter.m_patterns.empty() ) {
  7621. m_testSpec.m_filters.push_back( m_currentFilter );
  7622. m_currentFilter = TestSpec::Filter();
  7623. }
  7624. }
  7625. TestSpec parseTestSpec( std::string const& arg ) {
  7626. return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
  7627. }
  7628. } // namespace Catch
  7629. // end catch_test_spec_parser.cpp
  7630. // start catch_timer.cpp
  7631. #include <chrono>
  7632. namespace Catch {
  7633. auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
  7634. return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
  7635. }
  7636. auto estimateClockResolution() -> uint64_t {
  7637. uint64_t sum = 0;
  7638. static const uint64_t iterations = 1000000;
  7639. for( std::size_t i = 0; i < iterations; ++i ) {
  7640. uint64_t ticks;
  7641. uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
  7642. do {
  7643. ticks = getCurrentNanosecondsSinceEpoch();
  7644. }
  7645. while( ticks == baseTicks );
  7646. auto delta = ticks - baseTicks;
  7647. sum += delta;
  7648. }
  7649. // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
  7650. // - and potentially do more iterations if there's a high variance.
  7651. return sum/iterations;
  7652. }
  7653. auto getEstimatedClockResolution() -> uint64_t {
  7654. static auto s_resolution = estimateClockResolution();
  7655. return s_resolution;
  7656. }
  7657. void Timer::start() {
  7658. m_nanoseconds = getCurrentNanosecondsSinceEpoch();
  7659. }
  7660. auto Timer::getElapsedNanoseconds() const -> unsigned int {
  7661. return static_cast<unsigned int>(getCurrentNanosecondsSinceEpoch() - m_nanoseconds);
  7662. }
  7663. auto Timer::getElapsedMicroseconds() const -> unsigned int {
  7664. return static_cast<unsigned int>(getElapsedNanoseconds()/1000);
  7665. }
  7666. auto Timer::getElapsedMilliseconds() const -> unsigned int {
  7667. return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
  7668. }
  7669. auto Timer::getElapsedSeconds() const -> double {
  7670. return getElapsedMicroseconds()/1000000.0;
  7671. }
  7672. } // namespace Catch
  7673. // end catch_timer.cpp
  7674. // start catch_tostring.cpp
  7675. #if defined(__clang__)
  7676. # pragma clang diagnostic push
  7677. # pragma clang diagnostic ignored "-Wexit-time-destructors"
  7678. # pragma clang diagnostic ignored "-Wglobal-constructors"
  7679. #endif
  7680. #include <iomanip>
  7681. namespace Catch {
  7682. namespace Detail {
  7683. const std::string unprintableString = "{?}";
  7684. namespace {
  7685. const int hexThreshold = 255;
  7686. struct Endianness {
  7687. enum Arch { Big, Little };
  7688. static Arch which() {
  7689. union _{
  7690. int asInt;
  7691. char asChar[sizeof (int)];
  7692. } u;
  7693. u.asInt = 1;
  7694. return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
  7695. }
  7696. };
  7697. }
  7698. std::string rawMemoryToString( const void *object, std::size_t size ) {
  7699. // Reverse order for little endian architectures
  7700. int i = 0, end = static_cast<int>( size ), inc = 1;
  7701. if( Endianness::which() == Endianness::Little ) {
  7702. i = end-1;
  7703. end = inc = -1;
  7704. }
  7705. unsigned char const *bytes = static_cast<unsigned char const *>(object);
  7706. std::ostringstream os;
  7707. os << "0x" << std::setfill('0') << std::hex;
  7708. for( ; i != end; i += inc )
  7709. os << std::setw(2) << static_cast<unsigned>(bytes[i]);
  7710. return os.str();
  7711. }
  7712. }
  7713. template<typename T>
  7714. std::string fpToString( T value, int precision ) {
  7715. std::ostringstream oss;
  7716. oss << std::setprecision( precision )
  7717. << std::fixed
  7718. << value;
  7719. std::string d = oss.str();
  7720. std::size_t i = d.find_last_not_of( '0' );
  7721. if( i != std::string::npos && i != d.size()-1 ) {
  7722. if( d[i] == '.' )
  7723. i++;
  7724. d = d.substr( 0, i+1 );
  7725. }
  7726. return d;
  7727. }
  7728. //// ======================================================= ////
  7729. //
  7730. // Out-of-line defs for full specialization of StringMaker
  7731. //
  7732. //// ======================================================= ////
  7733. std::string StringMaker<std::string>::convert(const std::string& str) {
  7734. if (!getCurrentContext().getConfig()->showInvisibles()) {
  7735. return '"' + str + '"';
  7736. }
  7737. std::string s("\"");
  7738. for (char c : str) {
  7739. switch (c) {
  7740. case '\n':
  7741. s.append("\\n");
  7742. break;
  7743. case '\t':
  7744. s.append("\\t");
  7745. break;
  7746. default:
  7747. s.push_back(c);
  7748. break;
  7749. }
  7750. }
  7751. s.append("\"");
  7752. return s;
  7753. }
  7754. std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
  7755. std::string s;
  7756. s.reserve(wstr.size());
  7757. for (auto c : wstr) {
  7758. s += (c <= 0xff) ? static_cast<char>(c) : '?';
  7759. }
  7760. return ::Catch::Detail::stringify(s);
  7761. }
  7762. std::string StringMaker<char const*>::convert(char const* str) {
  7763. if (str) {
  7764. return ::Catch::Detail::stringify(std::string{ str });
  7765. } else {
  7766. return{ "{null string}" };
  7767. }
  7768. }
  7769. std::string StringMaker<char*>::convert(char* str) {
  7770. if (str) {
  7771. return ::Catch::Detail::stringify(std::string{ str });
  7772. } else {
  7773. return{ "{null string}" };
  7774. }
  7775. }
  7776. std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {
  7777. if (str) {
  7778. return ::Catch::Detail::stringify(std::wstring{ str });
  7779. } else {
  7780. return{ "{null string}" };
  7781. }
  7782. }
  7783. std::string StringMaker<wchar_t *>::convert(wchar_t * str) {
  7784. if (str) {
  7785. return ::Catch::Detail::stringify(std::wstring{ str });
  7786. } else {
  7787. return{ "{null string}" };
  7788. }
  7789. }
  7790. std::string StringMaker<int>::convert(int value) {
  7791. return ::Catch::Detail::stringify(static_cast<long long>(value));
  7792. }
  7793. std::string StringMaker<long>::convert(long value) {
  7794. return ::Catch::Detail::stringify(static_cast<long long>(value));
  7795. }
  7796. std::string StringMaker<long long>::convert(long long value) {
  7797. std::ostringstream oss;
  7798. oss << value;
  7799. if (value > Detail::hexThreshold) {
  7800. oss << " (0x" << std::hex << value << ')';
  7801. }
  7802. return oss.str();
  7803. }
  7804. std::string StringMaker<unsigned int>::convert(unsigned int value) {
  7805. return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
  7806. }
  7807. std::string StringMaker<unsigned long>::convert(unsigned long value) {
  7808. return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
  7809. }
  7810. std::string StringMaker<unsigned long long>::convert(unsigned long long value) {
  7811. std::ostringstream oss;
  7812. oss << value;
  7813. if (value > Detail::hexThreshold) {
  7814. oss << " (0x" << std::hex << value << ')';
  7815. }
  7816. return oss.str();
  7817. }
  7818. std::string StringMaker<bool>::convert(bool b) {
  7819. return b ? "true" : "false";
  7820. }
  7821. std::string StringMaker<char>::convert(char value) {
  7822. if (value == '\r') {
  7823. return "'\\r'";
  7824. } else if (value == '\f') {
  7825. return "'\\f'";
  7826. } else if (value == '\n') {
  7827. return "'\\n'";
  7828. } else if (value == '\t') {
  7829. return "'\\t'";
  7830. } else if ('\0' <= value && value < ' ') {
  7831. return ::Catch::Detail::stringify(static_cast<unsigned int>(value));
  7832. } else {
  7833. char chstr[] = "' '";
  7834. chstr[1] = value;
  7835. return chstr;
  7836. }
  7837. }
  7838. std::string StringMaker<signed char>::convert(signed char c) {
  7839. return ::Catch::Detail::stringify(static_cast<char>(c));
  7840. }
  7841. std::string StringMaker<unsigned char>::convert(unsigned char c) {
  7842. return ::Catch::Detail::stringify(static_cast<char>(c));
  7843. }
  7844. std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {
  7845. return "nullptr";
  7846. }
  7847. std::string StringMaker<float>::convert(float value) {
  7848. return fpToString(value, 5) + 'f';
  7849. }
  7850. std::string StringMaker<double>::convert(double value) {
  7851. return fpToString(value, 10);
  7852. }
  7853. } // end namespace Catch
  7854. #if defined(__clang__)
  7855. # pragma clang diagnostic pop
  7856. #endif
  7857. // end catch_tostring.cpp
  7858. // start catch_totals.cpp
  7859. namespace Catch {
  7860. Counts Counts::operator - ( Counts const& other ) const {
  7861. Counts diff;
  7862. diff.passed = passed - other.passed;
  7863. diff.failed = failed - other.failed;
  7864. diff.failedButOk = failedButOk - other.failedButOk;
  7865. return diff;
  7866. }
  7867. Counts& Counts::operator += ( Counts const& other ) {
  7868. passed += other.passed;
  7869. failed += other.failed;
  7870. failedButOk += other.failedButOk;
  7871. return *this;
  7872. }
  7873. std::size_t Counts::total() const {
  7874. return passed + failed + failedButOk;
  7875. }
  7876. bool Counts::allPassed() const {
  7877. return failed == 0 && failedButOk == 0;
  7878. }
  7879. bool Counts::allOk() const {
  7880. return failed == 0;
  7881. }
  7882. Totals Totals::operator - ( Totals const& other ) const {
  7883. Totals diff;
  7884. diff.assertions = assertions - other.assertions;
  7885. diff.testCases = testCases - other.testCases;
  7886. return diff;
  7887. }
  7888. Totals& Totals::operator += ( Totals const& other ) {
  7889. assertions += other.assertions;
  7890. testCases += other.testCases;
  7891. return *this;
  7892. }
  7893. Totals Totals::delta( Totals const& prevTotals ) const {
  7894. Totals diff = *this - prevTotals;
  7895. if( diff.assertions.failed > 0 )
  7896. ++diff.testCases.failed;
  7897. else if( diff.assertions.failedButOk > 0 )
  7898. ++diff.testCases.failedButOk;
  7899. else
  7900. ++diff.testCases.passed;
  7901. return diff;
  7902. }
  7903. }
  7904. // end catch_totals.cpp
  7905. // start catch_version.cpp
  7906. #include <ostream>
  7907. namespace Catch {
  7908. Version::Version
  7909. ( unsigned int _majorVersion,
  7910. unsigned int _minorVersion,
  7911. unsigned int _patchNumber,
  7912. char const * const _branchName,
  7913. unsigned int _buildNumber )
  7914. : majorVersion( _majorVersion ),
  7915. minorVersion( _minorVersion ),
  7916. patchNumber( _patchNumber ),
  7917. branchName( _branchName ),
  7918. buildNumber( _buildNumber )
  7919. {}
  7920. std::ostream& operator << ( std::ostream& os, Version const& version ) {
  7921. os << version.majorVersion << '.'
  7922. << version.minorVersion << '.'
  7923. << version.patchNumber;
  7924. // branchName is never null -> 0th char is \0 if it is empty
  7925. if (version.branchName[0]) {
  7926. os << '-' << version.branchName
  7927. << '.' << version.buildNumber;
  7928. }
  7929. return os;
  7930. }
  7931. Version const& libraryVersion() {
  7932. static Version version( 2, 0, 0, "develop", 5 );
  7933. return version;
  7934. }
  7935. }
  7936. // end catch_version.cpp
  7937. // start catch_wildcard_pattern.cpp
  7938. namespace Catch {
  7939. WildcardPattern::WildcardPattern( std::string const& pattern,
  7940. CaseSensitive::Choice caseSensitivity )
  7941. : m_caseSensitivity( caseSensitivity ),
  7942. m_pattern( adjustCase( pattern ) )
  7943. {
  7944. if( startsWith( m_pattern, '*' ) ) {
  7945. m_pattern = m_pattern.substr( 1 );
  7946. m_wildcard = WildcardAtStart;
  7947. }
  7948. if( endsWith( m_pattern, '*' ) ) {
  7949. m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
  7950. m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
  7951. }
  7952. }
  7953. bool WildcardPattern::matches( std::string const& str ) const {
  7954. switch( m_wildcard ) {
  7955. case NoWildcard:
  7956. return m_pattern == adjustCase( str );
  7957. case WildcardAtStart:
  7958. return endsWith( adjustCase( str ), m_pattern );
  7959. case WildcardAtEnd:
  7960. return startsWith( adjustCase( str ), m_pattern );
  7961. case WildcardAtBothEnds:
  7962. return contains( adjustCase( str ), m_pattern );
  7963. default:
  7964. CATCH_INTERNAL_ERROR( "Unknown enum" );
  7965. }
  7966. }
  7967. std::string WildcardPattern::adjustCase( std::string const& str ) const {
  7968. return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
  7969. }
  7970. }
  7971. // end catch_wildcard_pattern.cpp
  7972. // start catch_xmlwriter.cpp
  7973. // start catch_xmlwriter.h
  7974. #include <sstream>
  7975. #include <vector>
  7976. namespace Catch {
  7977. class XmlEncode {
  7978. public:
  7979. enum ForWhat { ForTextNodes, ForAttributes };
  7980. XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );
  7981. void encodeTo( std::ostream& os ) const;
  7982. friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );
  7983. private:
  7984. std::string m_str;
  7985. ForWhat m_forWhat;
  7986. };
  7987. class XmlWriter {
  7988. public:
  7989. class ScopedElement {
  7990. public:
  7991. ScopedElement( XmlWriter* writer );
  7992. ScopedElement( ScopedElement&& other ) noexcept;
  7993. ScopedElement& operator=( ScopedElement&& other ) noexcept;
  7994. ~ScopedElement();
  7995. ScopedElement& writeText( std::string const& text, bool indent = true );
  7996. template<typename T>
  7997. ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
  7998. m_writer->writeAttribute( name, attribute );
  7999. return *this;
  8000. }
  8001. private:
  8002. mutable XmlWriter* m_writer = nullptr;
  8003. };
  8004. XmlWriter( std::ostream& os = Catch::cout() );
  8005. ~XmlWriter();
  8006. XmlWriter( XmlWriter const& ) = delete;
  8007. XmlWriter& operator=( XmlWriter const& ) = delete;
  8008. XmlWriter& startElement( std::string const& name );
  8009. ScopedElement scopedElement( std::string const& name );
  8010. XmlWriter& endElement();
  8011. XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );
  8012. XmlWriter& writeAttribute( std::string const& name, bool attribute );
  8013. template<typename T>
  8014. XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
  8015. m_oss.clear();
  8016. m_oss.str(std::string());
  8017. m_oss << attribute;
  8018. return writeAttribute( name, m_oss.str() );
  8019. }
  8020. XmlWriter& writeText( std::string const& text, bool indent = true );
  8021. XmlWriter& writeComment( std::string const& text );
  8022. void writeStylesheetRef( std::string const& url );
  8023. XmlWriter& writeBlankLine();
  8024. void ensureTagClosed();
  8025. private:
  8026. void writeDeclaration();
  8027. void newlineIfNecessary();
  8028. bool m_tagIsOpen = false;
  8029. bool m_needsNewline = false;
  8030. std::vector<std::string> m_tags;
  8031. std::string m_indent;
  8032. std::ostream& m_os;
  8033. std::ostringstream m_oss;
  8034. };
  8035. }
  8036. // end catch_xmlwriter.h
  8037. #include <iomanip>
  8038. namespace Catch {
  8039. XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
  8040. : m_str( str ),
  8041. m_forWhat( forWhat )
  8042. {}
  8043. void XmlEncode::encodeTo( std::ostream& os ) const {
  8044. // Apostrophe escaping not necessary if we always use " to write attributes
  8045. // (see: http://www.w3.org/TR/xml/#syntax)
  8046. for( std::size_t i = 0; i < m_str.size(); ++ i ) {
  8047. char c = m_str[i];
  8048. switch( c ) {
  8049. case '<': os << "&lt;"; break;
  8050. case '&': os << "&amp;"; break;
  8051. case '>':
  8052. // See: http://www.w3.org/TR/xml/#syntax
  8053. if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' )
  8054. os << "&gt;";
  8055. else
  8056. os << c;
  8057. break;
  8058. case '\"':
  8059. if( m_forWhat == ForAttributes )
  8060. os << "&quot;";
  8061. else
  8062. os << c;
  8063. break;
  8064. default:
  8065. // Escape control chars - based on contribution by @espenalb in PR #465 and
  8066. // by @mrpi PR #588
  8067. if ( ( c >= 0 && c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' ) {
  8068. // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
  8069. os << "\\x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
  8070. << static_cast<int>( c );
  8071. }
  8072. else
  8073. os << c;
  8074. }
  8075. }
  8076. }
  8077. std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
  8078. xmlEncode.encodeTo( os );
  8079. return os;
  8080. }
  8081. XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer )
  8082. : m_writer( writer )
  8083. {}
  8084. XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept
  8085. : m_writer( other.m_writer ){
  8086. other.m_writer = nullptr;
  8087. }
  8088. XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept {
  8089. if ( m_writer ) {
  8090. m_writer->endElement();
  8091. }
  8092. m_writer = other.m_writer;
  8093. other.m_writer = nullptr;
  8094. return *this;
  8095. }
  8096. XmlWriter::ScopedElement::~ScopedElement() {
  8097. if( m_writer )
  8098. m_writer->endElement();
  8099. }
  8100. XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, bool indent ) {
  8101. m_writer->writeText( text, indent );
  8102. return *this;
  8103. }
  8104. XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )
  8105. {
  8106. writeDeclaration();
  8107. }
  8108. XmlWriter::~XmlWriter() {
  8109. while( !m_tags.empty() )
  8110. endElement();
  8111. }
  8112. XmlWriter& XmlWriter::startElement( std::string const& name ) {
  8113. ensureTagClosed();
  8114. newlineIfNecessary();
  8115. m_os << m_indent << '<' << name;
  8116. m_tags.push_back( name );
  8117. m_indent += " ";
  8118. m_tagIsOpen = true;
  8119. return *this;
  8120. }
  8121. XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name ) {
  8122. ScopedElement scoped( this );
  8123. startElement( name );
  8124. return scoped;
  8125. }
  8126. XmlWriter& XmlWriter::endElement() {
  8127. newlineIfNecessary();
  8128. m_indent = m_indent.substr( 0, m_indent.size()-2 );
  8129. if( m_tagIsOpen ) {
  8130. m_os << "/>";
  8131. m_tagIsOpen = false;
  8132. }
  8133. else {
  8134. m_os << m_indent << "</" << m_tags.back() << ">";
  8135. }
  8136. m_os << std::endl;
  8137. m_tags.pop_back();
  8138. return *this;
  8139. }
  8140. XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {
  8141. if( !name.empty() && !attribute.empty() )
  8142. m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
  8143. return *this;
  8144. }
  8145. XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {
  8146. m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
  8147. return *this;
  8148. }
  8149. XmlWriter& XmlWriter::writeText( std::string const& text, bool indent ) {
  8150. if( !text.empty() ){
  8151. bool tagWasOpen = m_tagIsOpen;
  8152. ensureTagClosed();
  8153. if( tagWasOpen && indent )
  8154. m_os << m_indent;
  8155. m_os << XmlEncode( text );
  8156. m_needsNewline = true;
  8157. }
  8158. return *this;
  8159. }
  8160. XmlWriter& XmlWriter::writeComment( std::string const& text ) {
  8161. ensureTagClosed();
  8162. m_os << m_indent << "<!--" << text << "-->";
  8163. m_needsNewline = true;
  8164. return *this;
  8165. }
  8166. void XmlWriter::writeStylesheetRef( std::string const& url ) {
  8167. m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
  8168. }
  8169. XmlWriter& XmlWriter::writeBlankLine() {
  8170. ensureTagClosed();
  8171. m_os << '\n';
  8172. return *this;
  8173. }
  8174. void XmlWriter::ensureTagClosed() {
  8175. if( m_tagIsOpen ) {
  8176. m_os << ">" << std::endl;
  8177. m_tagIsOpen = false;
  8178. }
  8179. }
  8180. void XmlWriter::writeDeclaration() {
  8181. m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
  8182. }
  8183. void XmlWriter::newlineIfNecessary() {
  8184. if( m_needsNewline ) {
  8185. m_os << std::endl;
  8186. m_needsNewline = false;
  8187. }
  8188. }
  8189. }
  8190. // end catch_xmlwriter.cpp
  8191. // start catch_reporter_bases.cpp
  8192. #include <cstring>
  8193. #include <cfloat>
  8194. #include <cstdio>
  8195. #include <assert.h>
  8196. #include <memory>
  8197. namespace Catch {
  8198. void prepareExpandedExpression(AssertionResult& result) {
  8199. result.getExpandedExpression();
  8200. }
  8201. // Because formatting using c++ streams is stateful, drop down to C is required
  8202. // Alternatively we could use stringstream, but its performance is... not good.
  8203. std::string getFormattedDuration( double duration ) {
  8204. // Max exponent + 1 is required to represent the whole part
  8205. // + 1 for decimal point
  8206. // + 3 for the 3 decimal places
  8207. // + 1 for null terminator
  8208. const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
  8209. char buffer[maxDoubleSize];
  8210. // Save previous errno, to prevent sprintf from overwriting it
  8211. ErrnoGuard guard;
  8212. #ifdef _MSC_VER
  8213. sprintf_s(buffer, "%.3f", duration);
  8214. #else
  8215. sprintf(buffer, "%.3f", duration);
  8216. #endif
  8217. return std::string(buffer);
  8218. }
  8219. TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)
  8220. :StreamingReporterBase(_config) {}
  8221. void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}
  8222. bool TestEventListenerBase::assertionEnded(AssertionStats const &) {
  8223. return false;
  8224. }
  8225. } // end namespace Catch
  8226. // end catch_reporter_bases.cpp
  8227. // start catch_reporter_compact.cpp
  8228. namespace {
  8229. #ifdef CATCH_PLATFORM_MAC
  8230. const char* failedString() { return "FAILED"; }
  8231. const char* passedString() { return "PASSED"; }
  8232. #else
  8233. const char* failedString() { return "failed"; }
  8234. const char* passedString() { return "passed"; }
  8235. #endif
  8236. // Colour::LightGrey
  8237. Catch::Colour::Code dimColour() { return Catch::Colour::FileName; }
  8238. std::string bothOrAll( std::size_t count ) {
  8239. return count == 1 ? std::string() :
  8240. count == 2 ? "both " : "all " ;
  8241. }
  8242. }
  8243. namespace Catch {
  8244. struct CompactReporter : StreamingReporterBase<CompactReporter> {
  8245. using StreamingReporterBase::StreamingReporterBase;
  8246. ~CompactReporter() override;
  8247. static std::string getDescription() {
  8248. return "Reports test results on a single line, suitable for IDEs";
  8249. }
  8250. ReporterPreferences getPreferences() const override {
  8251. ReporterPreferences prefs;
  8252. prefs.shouldRedirectStdOut = false;
  8253. return prefs;
  8254. }
  8255. void noMatchingTestCases( std::string const& spec ) override {
  8256. stream << "No test cases matched '" << spec << '\'' << std::endl;
  8257. }
  8258. void assertionStarting( AssertionInfo const& ) override {}
  8259. bool assertionEnded( AssertionStats const& _assertionStats ) override {
  8260. AssertionResult const& result = _assertionStats.assertionResult;
  8261. bool printInfoMessages = true;
  8262. // Drop out if result was successful and we're not printing those
  8263. if( !m_config->includeSuccessfulResults() && result.isOk() ) {
  8264. if( result.getResultType() != ResultWas::Warning )
  8265. return false;
  8266. printInfoMessages = false;
  8267. }
  8268. AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
  8269. printer.print();
  8270. stream << std::endl;
  8271. return true;
  8272. }
  8273. void sectionEnded(SectionStats const& _sectionStats) override {
  8274. if (m_config->showDurations() == ShowDurations::Always) {
  8275. stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
  8276. }
  8277. }
  8278. void testRunEnded( TestRunStats const& _testRunStats ) override {
  8279. printTotals( _testRunStats.totals );
  8280. stream << '\n' << std::endl;
  8281. StreamingReporterBase::testRunEnded( _testRunStats );
  8282. }
  8283. private:
  8284. class AssertionPrinter {
  8285. public:
  8286. AssertionPrinter& operator= ( AssertionPrinter const& ) = delete;
  8287. AssertionPrinter( AssertionPrinter const& ) = delete;
  8288. AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
  8289. : stream( _stream )
  8290. , result( _stats.assertionResult )
  8291. , messages( _stats.infoMessages )
  8292. , itMessage( _stats.infoMessages.begin() )
  8293. , printInfoMessages( _printInfoMessages )
  8294. {}
  8295. void print() {
  8296. printSourceInfo();
  8297. itMessage = messages.begin();
  8298. switch( result.getResultType() ) {
  8299. case ResultWas::Ok:
  8300. printResultType( Colour::ResultSuccess, passedString() );
  8301. printOriginalExpression();
  8302. printReconstructedExpression();
  8303. if ( ! result.hasExpression() )
  8304. printRemainingMessages( Colour::None );
  8305. else
  8306. printRemainingMessages();
  8307. break;
  8308. case ResultWas::ExpressionFailed:
  8309. if( result.isOk() )
  8310. printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) );
  8311. else
  8312. printResultType( Colour::Error, failedString() );
  8313. printOriginalExpression();
  8314. printReconstructedExpression();
  8315. printRemainingMessages();
  8316. break;
  8317. case ResultWas::ThrewException:
  8318. printResultType( Colour::Error, failedString() );
  8319. printIssue( "unexpected exception with message:" );
  8320. printMessage();
  8321. printExpressionWas();
  8322. printRemainingMessages();
  8323. break;
  8324. case ResultWas::FatalErrorCondition:
  8325. printResultType( Colour::Error, failedString() );
  8326. printIssue( "fatal error condition with message:" );
  8327. printMessage();
  8328. printExpressionWas();
  8329. printRemainingMessages();
  8330. break;
  8331. case ResultWas::DidntThrowException:
  8332. printResultType( Colour::Error, failedString() );
  8333. printIssue( "expected exception, got none" );
  8334. printExpressionWas();
  8335. printRemainingMessages();
  8336. break;
  8337. case ResultWas::Info:
  8338. printResultType( Colour::None, "info" );
  8339. printMessage();
  8340. printRemainingMessages();
  8341. break;
  8342. case ResultWas::Warning:
  8343. printResultType( Colour::None, "warning" );
  8344. printMessage();
  8345. printRemainingMessages();
  8346. break;
  8347. case ResultWas::ExplicitFailure:
  8348. printResultType( Colour::Error, failedString() );
  8349. printIssue( "explicitly" );
  8350. printRemainingMessages( Colour::None );
  8351. break;
  8352. // These cases are here to prevent compiler warnings
  8353. case ResultWas::Unknown:
  8354. case ResultWas::FailureBit:
  8355. case ResultWas::Exception:
  8356. printResultType( Colour::Error, "** internal error **" );
  8357. break;
  8358. }
  8359. }
  8360. private:
  8361. void printSourceInfo() const {
  8362. Colour colourGuard( Colour::FileName );
  8363. stream << result.getSourceInfo() << ':';
  8364. }
  8365. void printResultType( Colour::Code colour, std::string const& passOrFail ) const {
  8366. if( !passOrFail.empty() ) {
  8367. {
  8368. Colour colourGuard( colour );
  8369. stream << ' ' << passOrFail;
  8370. }
  8371. stream << ':';
  8372. }
  8373. }
  8374. void printIssue( std::string const& issue ) const {
  8375. stream << ' ' << issue;
  8376. }
  8377. void printExpressionWas() {
  8378. if( result.hasExpression() ) {
  8379. stream << ';';
  8380. {
  8381. Colour colour( dimColour() );
  8382. stream << " expression was:";
  8383. }
  8384. printOriginalExpression();
  8385. }
  8386. }
  8387. void printOriginalExpression() const {
  8388. if( result.hasExpression() ) {
  8389. stream << ' ' << result.getExpression();
  8390. }
  8391. }
  8392. void printReconstructedExpression() const {
  8393. if( result.hasExpandedExpression() ) {
  8394. {
  8395. Colour colour( dimColour() );
  8396. stream << " for: ";
  8397. }
  8398. stream << result.getExpandedExpression();
  8399. }
  8400. }
  8401. void printMessage() {
  8402. if ( itMessage != messages.end() ) {
  8403. stream << " '" << itMessage->message << '\'';
  8404. ++itMessage;
  8405. }
  8406. }
  8407. void printRemainingMessages( Colour::Code colour = dimColour() ) {
  8408. if ( itMessage == messages.end() )
  8409. return;
  8410. // using messages.end() directly yields (or auto) compilation error:
  8411. std::vector<MessageInfo>::const_iterator itEnd = messages.end();
  8412. const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
  8413. {
  8414. Colour colourGuard( colour );
  8415. stream << " with " << pluralise( N, "message" ) << ':';
  8416. }
  8417. for(; itMessage != itEnd; ) {
  8418. // If this assertion is a warning ignore any INFO messages
  8419. if( printInfoMessages || itMessage->type != ResultWas::Info ) {
  8420. stream << " '" << itMessage->message << '\'';
  8421. if ( ++itMessage != itEnd ) {
  8422. Colour colourGuard( dimColour() );
  8423. stream << " and";
  8424. }
  8425. }
  8426. }
  8427. }
  8428. private:
  8429. std::ostream& stream;
  8430. AssertionResult const& result;
  8431. std::vector<MessageInfo> messages;
  8432. std::vector<MessageInfo>::const_iterator itMessage;
  8433. bool printInfoMessages;
  8434. };
  8435. // Colour, message variants:
  8436. // - white: No tests ran.
  8437. // - red: Failed [both/all] N test cases, failed [both/all] M assertions.
  8438. // - white: Passed [both/all] N test cases (no assertions).
  8439. // - red: Failed N tests cases, failed M assertions.
  8440. // - green: Passed [both/all] N tests cases with M assertions.
  8441. void printTotals( const Totals& totals ) const {
  8442. if( totals.testCases.total() == 0 ) {
  8443. stream << "No tests ran.";
  8444. }
  8445. else if( totals.testCases.failed == totals.testCases.total() ) {
  8446. Colour colour( Colour::ResultError );
  8447. const std::string qualify_assertions_failed =
  8448. totals.assertions.failed == totals.assertions.total() ?
  8449. bothOrAll( totals.assertions.failed ) : std::string();
  8450. stream <<
  8451. "Failed " << bothOrAll( totals.testCases.failed )
  8452. << pluralise( totals.testCases.failed, "test case" ) << ", "
  8453. "failed " << qualify_assertions_failed <<
  8454. pluralise( totals.assertions.failed, "assertion" ) << '.';
  8455. }
  8456. else if( totals.assertions.total() == 0 ) {
  8457. stream <<
  8458. "Passed " << bothOrAll( totals.testCases.total() )
  8459. << pluralise( totals.testCases.total(), "test case" )
  8460. << " (no assertions).";
  8461. }
  8462. else if( totals.assertions.failed ) {
  8463. Colour colour( Colour::ResultError );
  8464. stream <<
  8465. "Failed " << pluralise( totals.testCases.failed, "test case" ) << ", "
  8466. "failed " << pluralise( totals.assertions.failed, "assertion" ) << '.';
  8467. }
  8468. else {
  8469. Colour colour( Colour::ResultSuccess );
  8470. stream <<
  8471. "Passed " << bothOrAll( totals.testCases.passed )
  8472. << pluralise( totals.testCases.passed, "test case" ) <<
  8473. " with " << pluralise( totals.assertions.passed, "assertion" ) << '.';
  8474. }
  8475. }
  8476. };
  8477. CompactReporter::~CompactReporter() {}
  8478. CATCH_REGISTER_REPORTER( "compact", CompactReporter )
  8479. } // end namespace Catch
  8480. // end catch_reporter_compact.cpp
  8481. // start catch_reporter_console.cpp
  8482. #include <cfloat>
  8483. #include <cstdio>
  8484. namespace Catch {
  8485. namespace {
  8486. std::size_t makeRatio( std::size_t number, std::size_t total ) {
  8487. std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0;
  8488. return ( ratio == 0 && number > 0 ) ? 1 : ratio;
  8489. }
  8490. std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
  8491. if( i > j && i > k )
  8492. return i;
  8493. else if( j > k )
  8494. return j;
  8495. else
  8496. return k;
  8497. }
  8498. struct ColumnInfo {
  8499. enum Justification { Left, Right };
  8500. std::string name;
  8501. int width;
  8502. Justification justification;
  8503. };
  8504. struct ColumnBreak {};
  8505. struct RowBreak {};
  8506. class TablePrinter {
  8507. std::ostream& m_os;
  8508. std::vector<ColumnInfo> m_columnInfos;
  8509. std::ostringstream m_oss;
  8510. int m_currentColumn = -1;
  8511. bool m_isOpen = false;
  8512. public:
  8513. TablePrinter( std::ostream& os, std::vector<ColumnInfo> const& columnInfos )
  8514. : m_os( os ),
  8515. m_columnInfos( columnInfos )
  8516. {}
  8517. auto columnInfos() const -> std::vector<ColumnInfo> const& {
  8518. return m_columnInfos;
  8519. }
  8520. void open() {
  8521. if( !m_isOpen ) {
  8522. m_isOpen = true;
  8523. *this << RowBreak();
  8524. for( auto const& info : m_columnInfos )
  8525. *this << info.name << ColumnBreak();
  8526. *this << RowBreak();
  8527. m_os << Catch::getLineOfChars<'-'>() << "\n";
  8528. }
  8529. }
  8530. void close() {
  8531. if( m_isOpen ) {
  8532. *this << RowBreak();
  8533. m_os << std::endl;
  8534. m_isOpen = false;
  8535. }
  8536. }
  8537. template<typename T>
  8538. friend TablePrinter& operator << ( TablePrinter& tp, T const& value ) {
  8539. tp.m_oss << value;
  8540. return tp;
  8541. }
  8542. friend TablePrinter& operator << ( TablePrinter& tp, ColumnBreak ) {
  8543. auto colStr = tp.m_oss.str();
  8544. // This takes account of utf8 encodings
  8545. auto strSize = Catch::StringRef( colStr ).numberOfCharacters();
  8546. tp.m_oss.str("");
  8547. tp.open();
  8548. if( tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size()-1) ) {
  8549. tp.m_currentColumn = -1;
  8550. tp.m_os << "\n";
  8551. }
  8552. tp.m_currentColumn++;
  8553. auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
  8554. auto padding = ( strSize+2 < static_cast<std::size_t>( colInfo.width ) )
  8555. ? std::string( colInfo.width-(strSize+2), ' ' )
  8556. : std::string();
  8557. if( colInfo.justification == ColumnInfo::Left )
  8558. tp.m_os << colStr << padding << " ";
  8559. else
  8560. tp.m_os << padding << colStr << " ";
  8561. return tp;
  8562. }
  8563. friend TablePrinter& operator << ( TablePrinter& tp, RowBreak ) {
  8564. if( tp.m_currentColumn > 0 ) {
  8565. tp.m_os << "\n";
  8566. tp.m_currentColumn = -1;
  8567. }
  8568. return tp;
  8569. }
  8570. };
  8571. class Duration {
  8572. enum class Unit {
  8573. Auto,
  8574. Nanoseconds,
  8575. Microseconds,
  8576. Milliseconds,
  8577. Seconds,
  8578. Minutes
  8579. };
  8580. static const uint64_t s_nanosecondsInAMicrosecond = 1000;
  8581. static const uint64_t s_nanosecondsInAMillisecond = 1000*s_nanosecondsInAMicrosecond;
  8582. static const uint64_t s_nanosecondsInASecond = 1000*s_nanosecondsInAMillisecond;
  8583. static const uint64_t s_nanosecondsInAMinute = 60*s_nanosecondsInASecond;
  8584. uint64_t m_inNanoseconds;
  8585. Unit m_units;
  8586. public:
  8587. Duration( uint64_t inNanoseconds, Unit units = Unit::Auto )
  8588. : m_inNanoseconds( inNanoseconds ),
  8589. m_units( units )
  8590. {
  8591. if( m_units == Unit::Auto ) {
  8592. if( m_inNanoseconds < s_nanosecondsInAMicrosecond )
  8593. m_units = Unit::Nanoseconds;
  8594. else if( m_inNanoseconds < s_nanosecondsInAMillisecond )
  8595. m_units = Unit::Microseconds;
  8596. else if( m_inNanoseconds < s_nanosecondsInASecond )
  8597. m_units = Unit::Milliseconds;
  8598. else if( m_inNanoseconds < s_nanosecondsInAMinute )
  8599. m_units = Unit::Seconds;
  8600. else
  8601. m_units = Unit::Minutes;
  8602. }
  8603. }
  8604. auto value() const -> double {
  8605. switch( m_units ) {
  8606. case Unit::Microseconds:
  8607. return m_inNanoseconds / static_cast<double>( s_nanosecondsInAMicrosecond );
  8608. case Unit::Milliseconds:
  8609. return m_inNanoseconds / static_cast<double>( s_nanosecondsInAMillisecond );
  8610. case Unit::Seconds:
  8611. return m_inNanoseconds / static_cast<double>( s_nanosecondsInASecond );
  8612. case Unit::Minutes:
  8613. return m_inNanoseconds / static_cast<double>( s_nanosecondsInAMinute );
  8614. default:
  8615. return static_cast<double>( m_inNanoseconds );
  8616. }
  8617. }
  8618. auto unitsAsString() const -> std::string {
  8619. switch( m_units ) {
  8620. case Unit::Nanoseconds:
  8621. return "ns";
  8622. case Unit::Microseconds:
  8623. return "µs";
  8624. case Unit::Milliseconds:
  8625. return "ms";
  8626. case Unit::Seconds:
  8627. return "s";
  8628. case Unit::Minutes:
  8629. return "m";
  8630. default:
  8631. return "** internal error **";
  8632. }
  8633. }
  8634. friend auto operator << ( std::ostream& os, Duration const& duration ) -> std::ostream& {
  8635. return os << duration.value() << " " << duration.unitsAsString();
  8636. }
  8637. };
  8638. } // end anon namespace
  8639. struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {
  8640. TablePrinter m_tablePrinter;
  8641. ConsoleReporter( ReporterConfig const& config )
  8642. : StreamingReporterBase( config ),
  8643. m_tablePrinter( config.stream(),
  8644. {
  8645. { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH-32, ColumnInfo::Left },
  8646. { "iters", 8, ColumnInfo::Right },
  8647. { "elapsed ns", 14, ColumnInfo::Right },
  8648. { "average", 14, ColumnInfo::Right }
  8649. } )
  8650. {}
  8651. ~ConsoleReporter() override;
  8652. static std::string getDescription() {
  8653. return "Reports test results as plain lines of text";
  8654. }
  8655. void noMatchingTestCases( std::string const& spec ) override {
  8656. stream << "No test cases matched '" << spec << '\'' << std::endl;
  8657. }
  8658. void assertionStarting( AssertionInfo const& ) override {
  8659. }
  8660. bool assertionEnded( AssertionStats const& _assertionStats ) override {
  8661. AssertionResult const& result = _assertionStats.assertionResult;
  8662. bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
  8663. // Drop out if result was successful but we're not printing them.
  8664. if( !includeResults && result.getResultType() != ResultWas::Warning )
  8665. return false;
  8666. lazyPrint();
  8667. AssertionPrinter printer( stream, _assertionStats, includeResults );
  8668. printer.print();
  8669. stream << std::endl;
  8670. return true;
  8671. }
  8672. void sectionStarting( SectionInfo const& _sectionInfo ) override {
  8673. m_headerPrinted = false;
  8674. StreamingReporterBase::sectionStarting( _sectionInfo );
  8675. }
  8676. void sectionEnded( SectionStats const& _sectionStats ) override {
  8677. m_tablePrinter.close();
  8678. if( _sectionStats.missingAssertions ) {
  8679. lazyPrint();
  8680. Colour colour( Colour::ResultError );
  8681. if( m_sectionStack.size() > 1 )
  8682. stream << "\nNo assertions in section";
  8683. else
  8684. stream << "\nNo assertions in test case";
  8685. stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
  8686. }
  8687. if( m_config->showDurations() == ShowDurations::Always ) {
  8688. stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
  8689. }
  8690. if( m_headerPrinted ) {
  8691. m_headerPrinted = false;
  8692. }
  8693. StreamingReporterBase::sectionEnded( _sectionStats );
  8694. }
  8695. void benchmarkStarting( BenchmarkInfo const& info ) override {
  8696. lazyPrintWithoutClosingBenchmarkTable();
  8697. auto nameCol = Column( info.name ).width( m_tablePrinter.columnInfos()[0].width-2 );
  8698. bool firstLine = true;
  8699. for( auto line : nameCol ) {
  8700. if( !firstLine )
  8701. m_tablePrinter << ColumnBreak() << ColumnBreak() << ColumnBreak();
  8702. else
  8703. firstLine = false;
  8704. m_tablePrinter << line << ColumnBreak();
  8705. }
  8706. }
  8707. void benchmarkEnded( BenchmarkStats const& stats ) override {
  8708. Duration average( stats.elapsedTimeInNanoseconds/stats.iterations );
  8709. m_tablePrinter
  8710. << stats.iterations << ColumnBreak()
  8711. << stats.elapsedTimeInNanoseconds << ColumnBreak()
  8712. << average << ColumnBreak();
  8713. }
  8714. void testCaseEnded( TestCaseStats const& _testCaseStats ) override {
  8715. m_tablePrinter.close();
  8716. StreamingReporterBase::testCaseEnded( _testCaseStats );
  8717. m_headerPrinted = false;
  8718. }
  8719. void testGroupEnded( TestGroupStats const& _testGroupStats ) override {
  8720. if( currentGroupInfo.used ) {
  8721. printSummaryDivider();
  8722. stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
  8723. printTotals( _testGroupStats.totals );
  8724. stream << '\n' << std::endl;
  8725. }
  8726. StreamingReporterBase::testGroupEnded( _testGroupStats );
  8727. }
  8728. void testRunEnded( TestRunStats const& _testRunStats ) override {
  8729. printTotalsDivider( _testRunStats.totals );
  8730. printTotals( _testRunStats.totals );
  8731. stream << std::endl;
  8732. StreamingReporterBase::testRunEnded( _testRunStats );
  8733. }
  8734. private:
  8735. class AssertionPrinter {
  8736. public:
  8737. AssertionPrinter& operator= ( AssertionPrinter const& ) = delete;
  8738. AssertionPrinter( AssertionPrinter const& ) = delete;
  8739. AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
  8740. : stream( _stream ),
  8741. stats( _stats ),
  8742. result( _stats.assertionResult ),
  8743. colour( Colour::None ),
  8744. message( result.getMessage() ),
  8745. messages( _stats.infoMessages ),
  8746. printInfoMessages( _printInfoMessages )
  8747. {
  8748. switch( result.getResultType() ) {
  8749. case ResultWas::Ok:
  8750. colour = Colour::Success;
  8751. passOrFail = "PASSED";
  8752. //if( result.hasMessage() )
  8753. if( _stats.infoMessages.size() == 1 )
  8754. messageLabel = "with message";
  8755. if( _stats.infoMessages.size() > 1 )
  8756. messageLabel = "with messages";
  8757. break;
  8758. case ResultWas::ExpressionFailed:
  8759. if( result.isOk() ) {
  8760. colour = Colour::Success;
  8761. passOrFail = "FAILED - but was ok";
  8762. }
  8763. else {
  8764. colour = Colour::Error;
  8765. passOrFail = "FAILED";
  8766. }
  8767. if( _stats.infoMessages.size() == 1 )
  8768. messageLabel = "with message";
  8769. if( _stats.infoMessages.size() > 1 )
  8770. messageLabel = "with messages";
  8771. break;
  8772. case ResultWas::ThrewException:
  8773. colour = Colour::Error;
  8774. passOrFail = "FAILED";
  8775. messageLabel = "due to unexpected exception with ";
  8776. if (_stats.infoMessages.size() == 1)
  8777. messageLabel += "message";
  8778. if (_stats.infoMessages.size() > 1)
  8779. messageLabel += "messages";
  8780. break;
  8781. case ResultWas::FatalErrorCondition:
  8782. colour = Colour::Error;
  8783. passOrFail = "FAILED";
  8784. messageLabel = "due to a fatal error condition";
  8785. break;
  8786. case ResultWas::DidntThrowException:
  8787. colour = Colour::Error;
  8788. passOrFail = "FAILED";
  8789. messageLabel = "because no exception was thrown where one was expected";
  8790. break;
  8791. case ResultWas::Info:
  8792. messageLabel = "info";
  8793. break;
  8794. case ResultWas::Warning:
  8795. messageLabel = "warning";
  8796. break;
  8797. case ResultWas::ExplicitFailure:
  8798. passOrFail = "FAILED";
  8799. colour = Colour::Error;
  8800. if( _stats.infoMessages.size() == 1 )
  8801. messageLabel = "explicitly with message";
  8802. if( _stats.infoMessages.size() > 1 )
  8803. messageLabel = "explicitly with messages";
  8804. break;
  8805. // These cases are here to prevent compiler warnings
  8806. case ResultWas::Unknown:
  8807. case ResultWas::FailureBit:
  8808. case ResultWas::Exception:
  8809. passOrFail = "** internal error **";
  8810. colour = Colour::Error;
  8811. break;
  8812. }
  8813. }
  8814. void print() const {
  8815. printSourceInfo();
  8816. if( stats.totals.assertions.total() > 0 ) {
  8817. if( result.isOk() )
  8818. stream << '\n';
  8819. printResultType();
  8820. printOriginalExpression();
  8821. printReconstructedExpression();
  8822. }
  8823. else {
  8824. stream << '\n';
  8825. }
  8826. printMessage();
  8827. }
  8828. private:
  8829. void printResultType() const {
  8830. if( !passOrFail.empty() ) {
  8831. Colour colourGuard( colour );
  8832. stream << passOrFail << ":\n";
  8833. }
  8834. }
  8835. void printOriginalExpression() const {
  8836. if( result.hasExpression() ) {
  8837. Colour colourGuard( Colour::OriginalExpression );
  8838. stream << " ";
  8839. stream << result.getExpressionInMacro();
  8840. stream << '\n';
  8841. }
  8842. }
  8843. void printReconstructedExpression() const {
  8844. if( result.hasExpandedExpression() ) {
  8845. stream << "with expansion:\n";
  8846. Colour colourGuard( Colour::ReconstructedExpression );
  8847. stream << Column( result.getExpandedExpression() ).indent(2) << '\n';
  8848. }
  8849. }
  8850. void printMessage() const {
  8851. if( !messageLabel.empty() )
  8852. stream << messageLabel << ':' << '\n';
  8853. for( auto const& msg : messages ) {
  8854. // If this assertion is a warning ignore any INFO messages
  8855. if( printInfoMessages || msg.type != ResultWas::Info )
  8856. stream << Column( msg.message ).indent(2) << '\n';
  8857. }
  8858. }
  8859. void printSourceInfo() const {
  8860. Colour colourGuard( Colour::FileName );
  8861. stream << result.getSourceInfo() << ": ";
  8862. }
  8863. std::ostream& stream;
  8864. AssertionStats const& stats;
  8865. AssertionResult const& result;
  8866. Colour::Code colour;
  8867. std::string passOrFail;
  8868. std::string messageLabel;
  8869. std::string message;
  8870. std::vector<MessageInfo> messages;
  8871. bool printInfoMessages;
  8872. };
  8873. void lazyPrint() {
  8874. m_tablePrinter.close();
  8875. lazyPrintWithoutClosingBenchmarkTable();
  8876. }
  8877. void lazyPrintWithoutClosingBenchmarkTable() {
  8878. if( !currentTestRunInfo.used )
  8879. lazyPrintRunInfo();
  8880. if( !currentGroupInfo.used )
  8881. lazyPrintGroupInfo();
  8882. if( !m_headerPrinted ) {
  8883. printTestCaseAndSectionHeader();
  8884. m_headerPrinted = true;
  8885. }
  8886. }
  8887. void lazyPrintRunInfo() {
  8888. stream << '\n' << getLineOfChars<'~'>() << '\n';
  8889. Colour colour( Colour::SecondaryText );
  8890. stream << currentTestRunInfo->name
  8891. << " is a Catch v" << libraryVersion() << " host application.\n"
  8892. << "Run with -? for options\n\n";
  8893. if( m_config->rngSeed() != 0 )
  8894. stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
  8895. currentTestRunInfo.used = true;
  8896. }
  8897. void lazyPrintGroupInfo() {
  8898. if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
  8899. printClosedHeader( "Group: " + currentGroupInfo->name );
  8900. currentGroupInfo.used = true;
  8901. }
  8902. }
  8903. void printTestCaseAndSectionHeader() {
  8904. assert( !m_sectionStack.empty() );
  8905. printOpenHeader( currentTestCaseInfo->name );
  8906. if( m_sectionStack.size() > 1 ) {
  8907. Colour colourGuard( Colour::Headers );
  8908. auto
  8909. it = m_sectionStack.begin()+1, // Skip first section (test case)
  8910. itEnd = m_sectionStack.end();
  8911. for( ; it != itEnd; ++it )
  8912. printHeaderString( it->name, 2 );
  8913. }
  8914. SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
  8915. if( !lineInfo.empty() ){
  8916. stream << getLineOfChars<'-'>() << '\n';
  8917. Colour colourGuard( Colour::FileName );
  8918. stream << lineInfo << '\n';
  8919. }
  8920. stream << getLineOfChars<'.'>() << '\n' << std::endl;
  8921. }
  8922. void printClosedHeader( std::string const& _name ) {
  8923. printOpenHeader( _name );
  8924. stream << getLineOfChars<'.'>() << '\n';
  8925. }
  8926. void printOpenHeader( std::string const& _name ) {
  8927. stream << getLineOfChars<'-'>() << '\n';
  8928. {
  8929. Colour colourGuard( Colour::Headers );
  8930. printHeaderString( _name );
  8931. }
  8932. }
  8933. // if string has a : in first line will set indent to follow it on
  8934. // subsequent lines
  8935. void printHeaderString( std::string const& _string, std::size_t indent = 0 ) {
  8936. std::size_t i = _string.find( ": " );
  8937. if( i != std::string::npos )
  8938. i+=2;
  8939. else
  8940. i = 0;
  8941. stream << Column( _string ).indent( indent+i ).initialIndent( indent ) << '\n';
  8942. }
  8943. struct SummaryColumn {
  8944. SummaryColumn( std::string const& _label, Colour::Code _colour )
  8945. : label( _label ),
  8946. colour( _colour )
  8947. {}
  8948. SummaryColumn addRow( std::size_t count ) {
  8949. std::ostringstream oss;
  8950. oss << count;
  8951. std::string row = oss.str();
  8952. for( auto& oldRow : rows ) {
  8953. while( oldRow.size() < row.size() )
  8954. oldRow = ' ' + oldRow;
  8955. while( oldRow.size() > row.size() )
  8956. row = ' ' + row;
  8957. }
  8958. rows.push_back( row );
  8959. return *this;
  8960. }
  8961. std::string label;
  8962. Colour::Code colour;
  8963. std::vector<std::string> rows;
  8964. };
  8965. void printTotals( Totals const& totals ) {
  8966. if( totals.testCases.total() == 0 ) {
  8967. stream << Colour( Colour::Warning ) << "No tests ran\n";
  8968. }
  8969. else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) {
  8970. stream << Colour( Colour::ResultSuccess ) << "All tests passed";
  8971. stream << " ("
  8972. << pluralise( totals.assertions.passed, "assertion" ) << " in "
  8973. << pluralise( totals.testCases.passed, "test case" ) << ')'
  8974. << '\n';
  8975. }
  8976. else {
  8977. std::vector<SummaryColumn> columns;
  8978. columns.push_back( SummaryColumn( "", Colour::None )
  8979. .addRow( totals.testCases.total() )
  8980. .addRow( totals.assertions.total() ) );
  8981. columns.push_back( SummaryColumn( "passed", Colour::Success )
  8982. .addRow( totals.testCases.passed )
  8983. .addRow( totals.assertions.passed ) );
  8984. columns.push_back( SummaryColumn( "failed", Colour::ResultError )
  8985. .addRow( totals.testCases.failed )
  8986. .addRow( totals.assertions.failed ) );
  8987. columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure )
  8988. .addRow( totals.testCases.failedButOk )
  8989. .addRow( totals.assertions.failedButOk ) );
  8990. printSummaryRow( "test cases", columns, 0 );
  8991. printSummaryRow( "assertions", columns, 1 );
  8992. }
  8993. }
  8994. void printSummaryRow( std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row ) {
  8995. for( auto col : cols ) {
  8996. std::string value = col.rows[row];
  8997. if( col.label.empty() ) {
  8998. stream << label << ": ";
  8999. if( value != "0" )
  9000. stream << value;
  9001. else
  9002. stream << Colour( Colour::Warning ) << "- none -";
  9003. }
  9004. else if( value != "0" ) {
  9005. stream << Colour( Colour::LightGrey ) << " | ";
  9006. stream << Colour( col.colour )
  9007. << value << ' ' << col.label;
  9008. }
  9009. }
  9010. stream << '\n';
  9011. }
  9012. void printTotalsDivider( Totals const& totals ) {
  9013. if( totals.testCases.total() > 0 ) {
  9014. std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );
  9015. std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );
  9016. std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );
  9017. while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 )
  9018. findMax( failedRatio, failedButOkRatio, passedRatio )++;
  9019. while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 )
  9020. findMax( failedRatio, failedButOkRatio, passedRatio )--;
  9021. stream << Colour( Colour::Error ) << std::string( failedRatio, '=' );
  9022. stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' );
  9023. if( totals.testCases.allPassed() )
  9024. stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' );
  9025. else
  9026. stream << Colour( Colour::Success ) << std::string( passedRatio, '=' );
  9027. }
  9028. else {
  9029. stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );
  9030. }
  9031. stream << '\n';
  9032. }
  9033. void printSummaryDivider() {
  9034. stream << getLineOfChars<'-'>() << '\n';
  9035. }
  9036. private:
  9037. bool m_headerPrinted = false;
  9038. };
  9039. CATCH_REGISTER_REPORTER( "console", ConsoleReporter )
  9040. ConsoleReporter::~ConsoleReporter() {}
  9041. } // end namespace Catch
  9042. // end catch_reporter_console.cpp
  9043. // start catch_reporter_junit.cpp
  9044. #include <assert.h>
  9045. #include <ctime>
  9046. #include <algorithm>
  9047. namespace Catch {
  9048. namespace {
  9049. std::string getCurrentTimestamp() {
  9050. // Beware, this is not reentrant because of backward compatibility issues
  9051. // Also, UTC only, again because of backward compatibility (%z is C++11)
  9052. time_t rawtime;
  9053. std::time(&rawtime);
  9054. auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
  9055. #ifdef _MSC_VER
  9056. std::tm timeInfo = {};
  9057. gmtime_s(&timeInfo, &rawtime);
  9058. #else
  9059. std::tm* timeInfo;
  9060. timeInfo = std::gmtime(&rawtime);
  9061. #endif
  9062. char timeStamp[timeStampSize];
  9063. const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
  9064. #ifdef _MSC_VER
  9065. std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
  9066. #else
  9067. std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
  9068. #endif
  9069. return std::string(timeStamp);
  9070. }
  9071. std::string fileNameTag(const std::vector<std::string> &tags) {
  9072. auto it = std::find_if(begin(tags),
  9073. end(tags),
  9074. [] (std::string const& tag) {return tag.front() == '#'; });
  9075. if (it != tags.end())
  9076. return it->substr(1);
  9077. return std::string();
  9078. }
  9079. }
  9080. class JunitReporter : public CumulativeReporterBase<JunitReporter> {
  9081. public:
  9082. JunitReporter( ReporterConfig const& _config )
  9083. : CumulativeReporterBase( _config ),
  9084. xml( _config.stream() )
  9085. {
  9086. m_reporterPrefs.shouldRedirectStdOut = true;
  9087. }
  9088. ~JunitReporter() override;
  9089. static std::string getDescription() {
  9090. return "Reports test results in an XML format that looks like Ant's junitreport target";
  9091. }
  9092. void noMatchingTestCases( std::string const& /*spec*/ ) override {}
  9093. void testRunStarting( TestRunInfo const& runInfo ) override {
  9094. CumulativeReporterBase::testRunStarting( runInfo );
  9095. xml.startElement( "testsuites" );
  9096. }
  9097. void testGroupStarting( GroupInfo const& groupInfo ) override {
  9098. suiteTimer.start();
  9099. stdOutForSuite.str("");
  9100. stdErrForSuite.str("");
  9101. unexpectedExceptions = 0;
  9102. CumulativeReporterBase::testGroupStarting( groupInfo );
  9103. }
  9104. void testCaseStarting( TestCaseInfo const& testCaseInfo ) override {
  9105. m_okToFail = testCaseInfo.okToFail();
  9106. }
  9107. bool assertionEnded( AssertionStats const& assertionStats ) override {
  9108. if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
  9109. unexpectedExceptions++;
  9110. return CumulativeReporterBase::assertionEnded( assertionStats );
  9111. }
  9112. void testCaseEnded( TestCaseStats const& testCaseStats ) override {
  9113. stdOutForSuite << testCaseStats.stdOut;
  9114. stdErrForSuite << testCaseStats.stdErr;
  9115. CumulativeReporterBase::testCaseEnded( testCaseStats );
  9116. }
  9117. void testGroupEnded( TestGroupStats const& testGroupStats ) override {
  9118. double suiteTime = suiteTimer.getElapsedSeconds();
  9119. CumulativeReporterBase::testGroupEnded( testGroupStats );
  9120. writeGroup( *m_testGroups.back(), suiteTime );
  9121. }
  9122. void testRunEndedCumulative() override {
  9123. xml.endElement();
  9124. }
  9125. void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
  9126. XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
  9127. TestGroupStats const& stats = groupNode.value;
  9128. xml.writeAttribute( "name", stats.groupInfo.name );
  9129. xml.writeAttribute( "errors", unexpectedExceptions );
  9130. xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
  9131. xml.writeAttribute( "tests", stats.totals.assertions.total() );
  9132. xml.writeAttribute( "hostname", "tbd" ); // !TBD
  9133. if( m_config->showDurations() == ShowDurations::Never )
  9134. xml.writeAttribute( "time", "" );
  9135. else
  9136. xml.writeAttribute( "time", suiteTime );
  9137. xml.writeAttribute( "timestamp", getCurrentTimestamp() );
  9138. // Write test cases
  9139. for( auto const& child : groupNode.children )
  9140. writeTestCase( *child );
  9141. xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false );
  9142. xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false );
  9143. }
  9144. void writeTestCase( TestCaseNode const& testCaseNode ) {
  9145. TestCaseStats const& stats = testCaseNode.value;
  9146. // All test cases have exactly one section - which represents the
  9147. // test case itself. That section may have 0-n nested sections
  9148. assert( testCaseNode.children.size() == 1 );
  9149. SectionNode const& rootSection = *testCaseNode.children.front();
  9150. std::string className = stats.testInfo.className;
  9151. if( className.empty() ) {
  9152. className = fileNameTag(stats.testInfo.tags);
  9153. if ( className.empty() )
  9154. className = "global";
  9155. }
  9156. if ( !m_config->name().empty() )
  9157. className = m_config->name() + "." + className;
  9158. writeSection( className, "", rootSection );
  9159. }
  9160. void writeSection( std::string const& className,
  9161. std::string const& rootName,
  9162. SectionNode const& sectionNode ) {
  9163. std::string name = trim( sectionNode.stats.sectionInfo.name );
  9164. if( !rootName.empty() )
  9165. name = rootName + '/' + name;
  9166. if( !sectionNode.assertions.empty() ||
  9167. !sectionNode.stdOut.empty() ||
  9168. !sectionNode.stdErr.empty() ) {
  9169. XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
  9170. if( className.empty() ) {
  9171. xml.writeAttribute( "classname", name );
  9172. xml.writeAttribute( "name", "root" );
  9173. }
  9174. else {
  9175. xml.writeAttribute( "classname", className );
  9176. xml.writeAttribute( "name", name );
  9177. }
  9178. xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) );
  9179. writeAssertions( sectionNode );
  9180. if( !sectionNode.stdOut.empty() )
  9181. xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
  9182. if( !sectionNode.stdErr.empty() )
  9183. xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
  9184. }
  9185. for( auto const& childNode : sectionNode.childSections )
  9186. if( className.empty() )
  9187. writeSection( name, "", *childNode );
  9188. else
  9189. writeSection( className, name, *childNode );
  9190. }
  9191. void writeAssertions( SectionNode const& sectionNode ) {
  9192. for( auto const& assertion : sectionNode.assertions )
  9193. writeAssertion( assertion );
  9194. }
  9195. void writeAssertion( AssertionStats const& stats ) {
  9196. AssertionResult const& result = stats.assertionResult;
  9197. if( !result.isOk() ) {
  9198. std::string elementName;
  9199. switch( result.getResultType() ) {
  9200. case ResultWas::ThrewException:
  9201. case ResultWas::FatalErrorCondition:
  9202. elementName = "error";
  9203. break;
  9204. case ResultWas::ExplicitFailure:
  9205. elementName = "failure";
  9206. break;
  9207. case ResultWas::ExpressionFailed:
  9208. elementName = "failure";
  9209. break;
  9210. case ResultWas::DidntThrowException:
  9211. elementName = "failure";
  9212. break;
  9213. // We should never see these here:
  9214. case ResultWas::Info:
  9215. case ResultWas::Warning:
  9216. case ResultWas::Ok:
  9217. case ResultWas::Unknown:
  9218. case ResultWas::FailureBit:
  9219. case ResultWas::Exception:
  9220. elementName = "internalError";
  9221. break;
  9222. }
  9223. XmlWriter::ScopedElement e = xml.scopedElement( elementName );
  9224. xml.writeAttribute( "message", result.getExpandedExpression() );
  9225. xml.writeAttribute( "type", result.getTestMacroName() );
  9226. std::ostringstream oss;
  9227. if( !result.getMessage().empty() )
  9228. oss << result.getMessage() << '\n';
  9229. for( auto const& msg : stats.infoMessages )
  9230. if( msg.type == ResultWas::Info )
  9231. oss << msg.message << '\n';
  9232. oss << "at " << result.getSourceInfo();
  9233. xml.writeText( oss.str(), false );
  9234. }
  9235. }
  9236. XmlWriter xml;
  9237. Timer suiteTimer;
  9238. std::ostringstream stdOutForSuite;
  9239. std::ostringstream stdErrForSuite;
  9240. unsigned int unexpectedExceptions = 0;
  9241. bool m_okToFail = false;
  9242. };
  9243. JunitReporter::~JunitReporter() {}
  9244. CATCH_REGISTER_REPORTER( "junit", JunitReporter )
  9245. } // end namespace Catch
  9246. // end catch_reporter_junit.cpp
  9247. // start catch_reporter_multi.cpp
  9248. namespace Catch {
  9249. void MultipleReporters::add( IStreamingReporterPtr&& reporter ) {
  9250. m_reporters.push_back( std::move( reporter ) );
  9251. }
  9252. ReporterPreferences MultipleReporters::getPreferences() const {
  9253. return m_reporters[0]->getPreferences();
  9254. }
  9255. std::set<Verbosity> MultipleReporters::getSupportedVerbosities() {
  9256. return std::set<Verbosity>{ };
  9257. }
  9258. void MultipleReporters::noMatchingTestCases( std::string const& spec ) {
  9259. for( auto const& reporter : m_reporters )
  9260. reporter->noMatchingTestCases( spec );
  9261. }
  9262. void MultipleReporters::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {
  9263. for( auto const& reporter : m_reporters )
  9264. reporter->benchmarkStarting( benchmarkInfo );
  9265. }
  9266. void MultipleReporters::benchmarkEnded( BenchmarkStats const& benchmarkStats ) {
  9267. for( auto const& reporter : m_reporters )
  9268. reporter->benchmarkEnded( benchmarkStats );
  9269. }
  9270. void MultipleReporters::testRunStarting( TestRunInfo const& testRunInfo ) {
  9271. for( auto const& reporter : m_reporters )
  9272. reporter->testRunStarting( testRunInfo );
  9273. }
  9274. void MultipleReporters::testGroupStarting( GroupInfo const& groupInfo ) {
  9275. for( auto const& reporter : m_reporters )
  9276. reporter->testGroupStarting( groupInfo );
  9277. }
  9278. void MultipleReporters::testCaseStarting( TestCaseInfo const& testInfo ) {
  9279. for( auto const& reporter : m_reporters )
  9280. reporter->testCaseStarting( testInfo );
  9281. }
  9282. void MultipleReporters::sectionStarting( SectionInfo const& sectionInfo ) {
  9283. for( auto const& reporter : m_reporters )
  9284. reporter->sectionStarting( sectionInfo );
  9285. }
  9286. void MultipleReporters::assertionStarting( AssertionInfo const& assertionInfo ) {
  9287. for( auto const& reporter : m_reporters )
  9288. reporter->assertionStarting( assertionInfo );
  9289. }
  9290. // The return value indicates if the messages buffer should be cleared:
  9291. bool MultipleReporters::assertionEnded( AssertionStats const& assertionStats ) {
  9292. bool clearBuffer = false;
  9293. for( auto const& reporter : m_reporters )
  9294. clearBuffer |= reporter->assertionEnded( assertionStats );
  9295. return clearBuffer;
  9296. }
  9297. void MultipleReporters::sectionEnded( SectionStats const& sectionStats ) {
  9298. for( auto const& reporter : m_reporters )
  9299. reporter->sectionEnded( sectionStats );
  9300. }
  9301. void MultipleReporters::testCaseEnded( TestCaseStats const& testCaseStats ) {
  9302. for( auto const& reporter : m_reporters )
  9303. reporter->testCaseEnded( testCaseStats );
  9304. }
  9305. void MultipleReporters::testGroupEnded( TestGroupStats const& testGroupStats ) {
  9306. for( auto const& reporter : m_reporters )
  9307. reporter->testGroupEnded( testGroupStats );
  9308. }
  9309. void MultipleReporters::testRunEnded( TestRunStats const& testRunStats ) {
  9310. for( auto const& reporter : m_reporters )
  9311. reporter->testRunEnded( testRunStats );
  9312. }
  9313. void MultipleReporters::skipTest( TestCaseInfo const& testInfo ) {
  9314. for( auto const& reporter : m_reporters )
  9315. reporter->skipTest( testInfo );
  9316. }
  9317. bool MultipleReporters::isMulti() const {
  9318. return true;
  9319. }
  9320. } // end namespace Catch
  9321. // end catch_reporter_multi.cpp
  9322. // start catch_reporter_xml.cpp
  9323. namespace Catch {
  9324. class XmlReporter : public StreamingReporterBase<XmlReporter> {
  9325. public:
  9326. XmlReporter( ReporterConfig const& _config )
  9327. : StreamingReporterBase( _config ),
  9328. m_xml(_config.stream())
  9329. {
  9330. m_reporterPrefs.shouldRedirectStdOut = true;
  9331. }
  9332. ~XmlReporter() override;
  9333. static std::string getDescription() {
  9334. return "Reports test results as an XML document";
  9335. }
  9336. virtual std::string getStylesheetRef() const {
  9337. return std::string();
  9338. }
  9339. void writeSourceInfo( SourceLineInfo const& sourceInfo ) {
  9340. m_xml
  9341. .writeAttribute( "filename", sourceInfo.file )
  9342. .writeAttribute( "line", sourceInfo.line );
  9343. }
  9344. public: // StreamingReporterBase
  9345. void noMatchingTestCases( std::string const& s ) override {
  9346. StreamingReporterBase::noMatchingTestCases( s );
  9347. }
  9348. void testRunStarting( TestRunInfo const& testInfo ) override {
  9349. StreamingReporterBase::testRunStarting( testInfo );
  9350. std::string stylesheetRef = getStylesheetRef();
  9351. if( !stylesheetRef.empty() )
  9352. m_xml.writeStylesheetRef( stylesheetRef );
  9353. m_xml.startElement( "Catch" );
  9354. if( !m_config->name().empty() )
  9355. m_xml.writeAttribute( "name", m_config->name() );
  9356. }
  9357. void testGroupStarting( GroupInfo const& groupInfo ) override {
  9358. StreamingReporterBase::testGroupStarting( groupInfo );
  9359. m_xml.startElement( "Group" )
  9360. .writeAttribute( "name", groupInfo.name );
  9361. }
  9362. void testCaseStarting( TestCaseInfo const& testInfo ) override {
  9363. StreamingReporterBase::testCaseStarting(testInfo);
  9364. m_xml.startElement( "TestCase" )
  9365. .writeAttribute( "name", trim( testInfo.name ) )
  9366. .writeAttribute( "description", testInfo.description )
  9367. .writeAttribute( "tags", testInfo.tagsAsString() );
  9368. writeSourceInfo( testInfo.lineInfo );
  9369. if ( m_config->showDurations() == ShowDurations::Always )
  9370. m_testCaseTimer.start();
  9371. m_xml.ensureTagClosed();
  9372. }
  9373. void sectionStarting( SectionInfo const& sectionInfo ) override {
  9374. StreamingReporterBase::sectionStarting( sectionInfo );
  9375. if( m_sectionDepth++ > 0 ) {
  9376. m_xml.startElement( "Section" )
  9377. .writeAttribute( "name", trim( sectionInfo.name ) )
  9378. .writeAttribute( "description", sectionInfo.description );
  9379. writeSourceInfo( sectionInfo.lineInfo );
  9380. m_xml.ensureTagClosed();
  9381. }
  9382. }
  9383. void assertionStarting( AssertionInfo const& ) override { }
  9384. bool assertionEnded( AssertionStats const& assertionStats ) override {
  9385. AssertionResult const& result = assertionStats.assertionResult;
  9386. bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
  9387. if( includeResults ) {
  9388. // Print any info messages in <Info> tags.
  9389. for( auto const& msg : assertionStats.infoMessages ) {
  9390. if( msg.type == ResultWas::Info ) {
  9391. m_xml.scopedElement( "Info" )
  9392. .writeText( msg.message );
  9393. } else if ( msg.type == ResultWas::Warning ) {
  9394. m_xml.scopedElement( "Warning" )
  9395. .writeText( msg.message );
  9396. }
  9397. }
  9398. }
  9399. // Drop out if result was successful but we're not printing them.
  9400. if( !includeResults && result.getResultType() != ResultWas::Warning )
  9401. return true;
  9402. // Print the expression if there is one.
  9403. if( result.hasExpression() ) {
  9404. m_xml.startElement( "Expression" )
  9405. .writeAttribute( "success", result.succeeded() )
  9406. .writeAttribute( "type", result.getTestMacroName() );
  9407. writeSourceInfo( result.getSourceInfo() );
  9408. m_xml.scopedElement( "Original" )
  9409. .writeText( result.getExpression() );
  9410. m_xml.scopedElement( "Expanded" )
  9411. .writeText( result.getExpandedExpression() );
  9412. }
  9413. // And... Print a result applicable to each result type.
  9414. switch( result.getResultType() ) {
  9415. case ResultWas::ThrewException:
  9416. m_xml.startElement( "Exception" );
  9417. writeSourceInfo( result.getSourceInfo() );
  9418. m_xml.writeText( result.getMessage() );
  9419. m_xml.endElement();
  9420. break;
  9421. case ResultWas::FatalErrorCondition:
  9422. m_xml.startElement( "FatalErrorCondition" );
  9423. writeSourceInfo( result.getSourceInfo() );
  9424. m_xml.writeText( result.getMessage() );
  9425. m_xml.endElement();
  9426. break;
  9427. case ResultWas::Info:
  9428. m_xml.scopedElement( "Info" )
  9429. .writeText( result.getMessage() );
  9430. break;
  9431. case ResultWas::Warning:
  9432. // Warning will already have been written
  9433. break;
  9434. case ResultWas::ExplicitFailure:
  9435. m_xml.startElement( "Failure" );
  9436. writeSourceInfo( result.getSourceInfo() );
  9437. m_xml.writeText( result.getMessage() );
  9438. m_xml.endElement();
  9439. break;
  9440. default:
  9441. break;
  9442. }
  9443. if( result.hasExpression() )
  9444. m_xml.endElement();
  9445. return true;
  9446. }
  9447. void sectionEnded( SectionStats const& sectionStats ) override {
  9448. StreamingReporterBase::sectionEnded( sectionStats );
  9449. if( --m_sectionDepth > 0 ) {
  9450. XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
  9451. e.writeAttribute( "successes", sectionStats.assertions.passed );
  9452. e.writeAttribute( "failures", sectionStats.assertions.failed );
  9453. e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
  9454. if ( m_config->showDurations() == ShowDurations::Always )
  9455. e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
  9456. m_xml.endElement();
  9457. }
  9458. }
  9459. void testCaseEnded( TestCaseStats const& testCaseStats ) override {
  9460. StreamingReporterBase::testCaseEnded( testCaseStats );
  9461. XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
  9462. e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
  9463. if ( m_config->showDurations() == ShowDurations::Always )
  9464. e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
  9465. if( !testCaseStats.stdOut.empty() )
  9466. m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false );
  9467. if( !testCaseStats.stdErr.empty() )
  9468. m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false );
  9469. m_xml.endElement();
  9470. }
  9471. void testGroupEnded( TestGroupStats const& testGroupStats ) override {
  9472. StreamingReporterBase::testGroupEnded( testGroupStats );
  9473. // TODO: Check testGroupStats.aborting and act accordingly.
  9474. m_xml.scopedElement( "OverallResults" )
  9475. .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
  9476. .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
  9477. .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
  9478. m_xml.endElement();
  9479. }
  9480. void testRunEnded( TestRunStats const& testRunStats ) override {
  9481. StreamingReporterBase::testRunEnded( testRunStats );
  9482. m_xml.scopedElement( "OverallResults" )
  9483. .writeAttribute( "successes", testRunStats.totals.assertions.passed )
  9484. .writeAttribute( "failures", testRunStats.totals.assertions.failed )
  9485. .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
  9486. m_xml.endElement();
  9487. }
  9488. private:
  9489. Timer m_testCaseTimer;
  9490. XmlWriter m_xml;
  9491. int m_sectionDepth = 0;
  9492. };
  9493. XmlReporter::~XmlReporter() {}
  9494. CATCH_REGISTER_REPORTER( "xml", XmlReporter )
  9495. } // end namespace Catch
  9496. // end catch_reporter_xml.cpp
  9497. namespace Catch {
  9498. LeakDetector leakDetector;
  9499. }
  9500. #ifdef __clang__
  9501. #pragma clang diagnostic pop
  9502. #endif
  9503. // end catch_impl.hpp
  9504. #endif
  9505. #ifdef CATCH_CONFIG_MAIN
  9506. // start catch_default_main.hpp
  9507. #ifndef __OBJC__
  9508. #if defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
  9509. // Standard C/C++ Win32 Unicode wmain entry point
  9510. extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
  9511. #else
  9512. // Standard C/C++ main entry point
  9513. int main (int argc, char * argv[]) {
  9514. #endif
  9515. return Catch::Session().run( argc, argv );
  9516. }
  9517. #else // __OBJC__
  9518. // Objective-C entry point
  9519. int main (int argc, char * const argv[]) {
  9520. #if !CATCH_ARC_ENABLED
  9521. NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
  9522. #endif
  9523. Catch::registerTestMethods();
  9524. int result = Catch::Session().run( argc, (char**)argv );
  9525. #if !CATCH_ARC_ENABLED
  9526. [pool drain];
  9527. #endif
  9528. return result;
  9529. }
  9530. #endif // __OBJC__
  9531. // end catch_default_main.hpp
  9532. #endif
  9533. #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
  9534. # undef CLARA_CONFIG_MAIN
  9535. #endif
  9536. #if !defined(CATCH_CONFIG_DISABLE)
  9537. //////
  9538. // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
  9539. #ifdef CATCH_CONFIG_PREFIX_ALL
  9540. #define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  9541. #define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  9542. #define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", __VA_ARGS__ )
  9543. #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
  9544. #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
  9545. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  9546. #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
  9547. #endif// CATCH_CONFIG_DISABLE_MATCHERS
  9548. #define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  9549. #define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  9550. #define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  9551. #define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  9552. #define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  9553. #define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
  9554. #define CATCH_CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", __VA_ARGS__ )
  9555. #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
  9556. #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  9557. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  9558. #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  9559. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  9560. #define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  9561. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  9562. #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
  9563. #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
  9564. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  9565. #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
  9566. #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
  9567. #define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) )
  9568. #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
  9569. #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
  9570. #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
  9571. #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
  9572. #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
  9573. #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
  9574. #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  9575. #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  9576. #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
  9577. // "BDD-style" convenience wrappers
  9578. #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
  9579. #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
  9580. #define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc )
  9581. #define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc )
  9582. #define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc )
  9583. #define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc )
  9584. #define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc )
  9585. // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
  9586. #else
  9587. #define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  9588. #define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  9589. #define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  9590. #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
  9591. #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
  9592. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  9593. #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
  9594. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  9595. #define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  9596. #define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  9597. #define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  9598. #define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  9599. #define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  9600. #define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
  9601. #define CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  9602. #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
  9603. #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  9604. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  9605. #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  9606. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  9607. #define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  9608. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  9609. #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
  9610. #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
  9611. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  9612. #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
  9613. #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
  9614. #define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) )
  9615. #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
  9616. #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
  9617. #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
  9618. #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
  9619. #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
  9620. #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
  9621. #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  9622. #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  9623. #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
  9624. #endif
  9625. #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
  9626. // "BDD-style" convenience wrappers
  9627. #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
  9628. #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
  9629. #define GIVEN( desc ) SECTION( std::string(" Given: ") + desc )
  9630. #define WHEN( desc ) SECTION( std::string(" When: ") + desc )
  9631. #define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc )
  9632. #define THEN( desc ) SECTION( std::string(" Then: ") + desc )
  9633. #define AND_THEN( desc ) SECTION( std::string(" And: ") + desc )
  9634. using Catch::Detail::Approx;
  9635. #else
  9636. //////
  9637. // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
  9638. #ifdef CATCH_CONFIG_PREFIX_ALL
  9639. #define CATCH_REQUIRE( ... ) (void)(0)
  9640. #define CATCH_REQUIRE_FALSE( ... ) (void)(0)
  9641. #define CATCH_REQUIRE_THROWS( ... ) (void)(0)
  9642. #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
  9643. #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
  9644. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  9645. #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  9646. #endif// CATCH_CONFIG_DISABLE_MATCHERS
  9647. #define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)
  9648. #define CATCH_CHECK( ... ) (void)(0)
  9649. #define CATCH_CHECK_FALSE( ... ) (void)(0)
  9650. #define CATCH_CHECKED_IF( ... ) if (__VA_ARGS__)
  9651. #define CATCH_CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
  9652. #define CATCH_CHECK_NOFAIL( ... ) (void)(0)
  9653. #define CATCH_CHECK_THROWS( ... ) (void)(0)
  9654. #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
  9655. #define CATCH_CHECK_THROWS_WITH( expr, matcher ) (void)(0)
  9656. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  9657. #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  9658. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  9659. #define CATCH_CHECK_NOTHROW( ... ) (void)(0)
  9660. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  9661. #define CATCH_CHECK_THAT( arg, matcher ) (void)(0)
  9662. #define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
  9663. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  9664. #define CATCH_INFO( msg ) (void)(0)
  9665. #define CATCH_WARN( msg ) (void)(0)
  9666. #define CATCH_CAPTURE( msg ) (void)(0)
  9667. #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  9668. #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  9669. #define CATCH_METHOD_AS_TEST_CASE( method, ... )
  9670. #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
  9671. #define CATCH_SECTION( ... )
  9672. #define CATCH_FAIL( ... ) (void)(0)
  9673. #define CATCH_FAIL_CHECK( ... ) (void)(0)
  9674. #define CATCH_SUCCEED( ... ) (void)(0)
  9675. #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  9676. // "BDD-style" convenience wrappers
  9677. #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  9678. #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 )
  9679. #define CATCH_GIVEN( desc )
  9680. #define CATCH_WHEN( desc )
  9681. #define CATCH_AND_WHEN( desc )
  9682. #define CATCH_THEN( desc )
  9683. #define CATCH_AND_THEN( desc )
  9684. // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
  9685. #else
  9686. #define REQUIRE( ... ) (void)(0)
  9687. #define REQUIRE_FALSE( ... ) (void)(0)
  9688. #define REQUIRE_THROWS( ... ) (void)(0)
  9689. #define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
  9690. #define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
  9691. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  9692. #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  9693. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  9694. #define REQUIRE_NOTHROW( ... ) (void)(0)
  9695. #define CHECK( ... ) (void)(0)
  9696. #define CHECK_FALSE( ... ) (void)(0)
  9697. #define CHECKED_IF( ... ) if (__VA_ARGS__)
  9698. #define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
  9699. #define CHECK_NOFAIL( ... ) (void)(0)
  9700. #define CHECK_THROWS( ... ) (void)(0)
  9701. #define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
  9702. #define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
  9703. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  9704. #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  9705. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  9706. #define CHECK_NOTHROW( ... ) (void)(0)
  9707. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  9708. #define CHECK_THAT( arg, matcher ) (void)(0)
  9709. #define REQUIRE_THAT( arg, matcher ) (void)(0)
  9710. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  9711. #define INFO( msg ) (void)(0)
  9712. #define WARN( msg ) (void)(0)
  9713. #define CAPTURE( msg ) (void)(0)
  9714. #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  9715. #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  9716. #define METHOD_AS_TEST_CASE( method, ... )
  9717. #define REGISTER_TEST_CASE( Function, ... ) (void)(0)
  9718. #define SECTION( ... )
  9719. #define FAIL( ... ) (void)(0)
  9720. #define FAIL_CHECK( ... ) (void)(0)
  9721. #define SUCCEED( ... ) (void)(0)
  9722. #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  9723. #endif
  9724. #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
  9725. // "BDD-style" convenience wrappers
  9726. #define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) )
  9727. #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
  9728. #define GIVEN( desc )
  9729. #define WHEN( desc )
  9730. #define AND_WHEN( desc )
  9731. #define THEN( desc )
  9732. #define AND_THEN( desc )
  9733. using Catch::Detail::Approx;
  9734. #endif
  9735. // start catch_reenable_warnings.h
  9736. #ifdef __clang__
  9737. # ifdef __ICC // icpc defines the __clang__ macro
  9738. # pragma warning(pop)
  9739. # else
  9740. # pragma clang diagnostic pop
  9741. # endif
  9742. #elif defined __GNUC__
  9743. # pragma GCC diagnostic pop
  9744. #endif
  9745. // end catch_reenable_warnings.h
  9746. // end catch.hpp
  9747. #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED