Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

11661 lines
395KB

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