| /* | /* | ||||
| * Catch v2.6.1 | |||||
| * Generated: 2019-02-12 19:52:52.262497 | |||||
| * Catch v2.7.0 | |||||
| * Generated: 2019-03-07 21:34:30.252164 | |||||
| * ---------------------------------------------------------- | * ---------------------------------------------------------- | ||||
| * This file has been merged from multiple headers. Please don't edit it directly | * This file has been merged from multiple headers. Please don't edit it directly | ||||
| * Copyright (c) 2019 Two Blue Cubes Ltd. All rights reserved. | * Copyright (c) 2019 Two Blue Cubes Ltd. All rights reserved. | ||||
| #define CATCH_VERSION_MAJOR 2 | #define CATCH_VERSION_MAJOR 2 | ||||
| #define CATCH_VERSION_MINOR 6 | |||||
| #define CATCH_VERSION_PATCH 1 | |||||
| #define CATCH_VERSION_MINOR 7 | |||||
| #define CATCH_VERSION_PATCH 0 | |||||
| #ifdef __clang__ | #ifdef __clang__ | ||||
| # pragma clang system_header | # pragma clang system_header | ||||
| #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ | #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ | ||||
| #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ | #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ | ||||
| #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF | #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF | ||||
| #define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__) | |||||
| #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR | |||||
| #define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__ | |||||
| #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) | |||||
| #else | |||||
| // MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF | |||||
| #define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__) | |||||
| #define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__ | |||||
| #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1) | |||||
| #endif | |||||
| #define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__) | #define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__) | ||||
| #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME1(Name, INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))) | #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME1(Name, INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))) | ||||
| #endif | #endif | ||||
| #define INTERNAL_CATCH_MAKE_TYPE_LIST(types) TypeList<INTERNAL_CATCH_REMOVE_PARENS(types)> | |||||
| #define INTERNAL_CATCH_MAKE_TYPE_LIST(types) Catch::TypeList<INTERNAL_CATCH_REMOVE_PARENS(types)> | |||||
| #define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(types)\ | #define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(types)\ | ||||
| CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,INTERNAL_CATCH_REMOVE_PARENS(types)) | CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,INTERNAL_CATCH_REMOVE_PARENS(types)) | ||||
| #include <type_traits> | #include <type_traits> | ||||
| namespace Catch { | |||||
| template< typename... > | template< typename... > | ||||
| struct TypeList{}; | |||||
| struct TypeList {}; | |||||
| template< typename... > | template< typename... > | ||||
| struct append; | struct append; | ||||
| template< template<typename...> class L1 | template< template<typename...> class L1 | ||||
| , typename...E1 | |||||
| , template<typename...> class L2 | |||||
| , typename...E2 | |||||
| > | |||||
| struct append< L1<E1...>, L2<E2...> > | |||||
| { | |||||
| using type = L1<E1..., E2...>; | |||||
| , typename...E1 | |||||
| , template<typename...> class L2 | |||||
| , typename...E2 | |||||
| > | |||||
| struct append< L1<E1...>, L2<E2...> > { | |||||
| using type = L1<E1..., E2...>; | |||||
| }; | }; | ||||
| template< template<typename...> class L1 | template< template<typename...> class L1 | ||||
| , typename...E1 | |||||
| , template<typename...> class L2 | |||||
| , typename...E2 | |||||
| , typename...Rest | |||||
| > | |||||
| struct append< L1<E1...>, L2<E2...>, Rest...> | |||||
| { | |||||
| using type = typename append< L1<E1..., E2...>, Rest... >::type; | |||||
| , typename...E1 | |||||
| , template<typename...> class L2 | |||||
| , typename...E2 | |||||
| , typename...Rest | |||||
| > | |||||
| struct append< L1<E1...>, L2<E2...>, Rest...> { | |||||
| using type = typename append< L1<E1..., E2...>, Rest... >::type; | |||||
| }; | }; | ||||
| template< template<typename...> class | template< template<typename...> class | ||||
| , typename... | |||||
| > | |||||
| , typename... | |||||
| > | |||||
| struct rewrap; | struct rewrap; | ||||
| template< template<typename...> class Container | template< template<typename...> class Container | ||||
| , template<typename...> class List | |||||
| , typename...elems | |||||
| > | |||||
| struct rewrap<Container, List<elems...>> | |||||
| { | |||||
| , template<typename...> class List | |||||
| , typename...elems | |||||
| > | |||||
| struct rewrap<Container, List<elems...>> { | |||||
| using type = TypeList< Container< elems... > >; | using type = TypeList< Container< elems... > >; | ||||
| }; | }; | ||||
| template< template<typename...> class Container | template< template<typename...> class Container | ||||
| , template<typename...> class List | |||||
| , class...Elems | |||||
| , typename...Elements> | |||||
| struct rewrap<Container, List<Elems...>, Elements...> | |||||
| { | |||||
| , template<typename...> class List | |||||
| , class...Elems | |||||
| , typename...Elements> | |||||
| struct rewrap<Container, List<Elems...>, Elements...> { | |||||
| using type = typename append<TypeList<Container<Elems...>>, typename rewrap<Container, Elements...>::type>::type; | using type = typename append<TypeList<Container<Elems...>>, typename rewrap<Container, Elements...>::type>::type; | ||||
| }; | }; | ||||
| template< template<typename...> class...Containers > | template< template<typename...> class...Containers > | ||||
| struct combine | |||||
| { | |||||
| struct combine { | |||||
| template< typename...Types > | template< typename...Types > | ||||
| struct with_types | |||||
| { | |||||
| struct with_types { | |||||
| template< template <typename...> class Final > | template< template <typename...> class Final > | ||||
| struct into | |||||
| { | |||||
| struct into { | |||||
| using type = typename append<Final<>, typename rewrap<Containers, Types...>::type...>::type; | using type = typename append<Final<>, typename rewrap<Containers, Types...>::type...>::type; | ||||
| }; | }; | ||||
| }; | }; | ||||
| template<typename T> | template<typename T> | ||||
| struct always_false : std::false_type {}; | struct always_false : std::false_type {}; | ||||
| } // namespace Catch | |||||
| // end catch_meta.hpp | // end catch_meta.hpp | ||||
| namespace Catch { | namespace Catch { | ||||
| CATCH_INTERNAL_CHECK_UNIQUE_TYPES(Types...) \ | CATCH_INTERNAL_CHECK_UNIQUE_TYPES(Types...) \ | ||||
| int index = 0; \ | int index = 0; \ | ||||
| using expander = int[]; \ | using expander = int[]; \ | ||||
| (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + Catch::StringMaker<int>::convert(index++), Tags } ), 0)... };/* NOLINT */ \ | |||||
| constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\ | |||||
| constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\ | |||||
| constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\ | |||||
| (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */\ | |||||
| } \ | } \ | ||||
| }; \ | }; \ | ||||
| static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \ | static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \ | ||||
| using TestInit = combine<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)> \ | |||||
| using TestInit = Catch::combine<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)> \ | |||||
| ::with_types<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(TypesList)>::into<TestName>::type; \ | ::with_types<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(TypesList)>::into<TestName>::type; \ | ||||
| TestInit(); \ | TestInit(); \ | ||||
| return 0; \ | return 0; \ | ||||
| CATCH_INTERNAL_CHECK_UNIQUE_TYPES(Types...)\ | CATCH_INTERNAL_CHECK_UNIQUE_TYPES(Types...)\ | ||||
| int index = 0;\ | int index = 0;\ | ||||
| using expander = int[];\ | using expander = int[];\ | ||||
| (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + Catch::StringMaker<int>::convert(index++), Tags } ), 0)... };/* NOLINT */ \ | |||||
| constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\ | |||||
| constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\ | |||||
| constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\ | |||||
| (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */ \ | |||||
| }\ | }\ | ||||
| };\ | };\ | ||||
| static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ | static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ | ||||
| using TestInit = combine<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>\ | |||||
| using TestInit = Catch::combine<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>\ | |||||
| ::with_types<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(TypesList)>::into<TestNameClass>::type;\ | ::with_types<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(TypesList)>::into<TestNameClass>::type;\ | ||||
| TestInit();\ | TestInit();\ | ||||
| return 0;\ | return 0;\ | ||||
| struct SectionInfo; | struct SectionInfo; | ||||
| struct SectionEndInfo; | struct SectionEndInfo; | ||||
| struct MessageInfo; | struct MessageInfo; | ||||
| struct MessageBuilder; | |||||
| struct Counts; | struct Counts; | ||||
| struct BenchmarkInfo; | struct BenchmarkInfo; | ||||
| struct BenchmarkStats; | struct BenchmarkStats; | ||||
| virtual void pushScopedMessage( MessageInfo const& message ) = 0; | virtual void pushScopedMessage( MessageInfo const& message ) = 0; | ||||
| virtual void popScopedMessage( MessageInfo const& message ) = 0; | virtual void popScopedMessage( MessageInfo const& message ) = 0; | ||||
| virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0; | |||||
| virtual void handleFatalErrorCondition( StringRef message ) = 0; | virtual void handleFatalErrorCondition( StringRef message ) = 0; | ||||
| virtual void handleExpr | virtual void handleExpr | ||||
| class ScopedMessage { | class ScopedMessage { | ||||
| public: | public: | ||||
| explicit ScopedMessage( MessageBuilder const& builder ); | explicit ScopedMessage( MessageBuilder const& builder ); | ||||
| ScopedMessage( ScopedMessage& duplicate ) = delete; | |||||
| ScopedMessage( ScopedMessage&& old ); | |||||
| ~ScopedMessage(); | ~ScopedMessage(); | ||||
| MessageInfo m_info; | MessageInfo m_info; | ||||
| bool m_moved; | |||||
| }; | }; | ||||
| class Capturer { | class Capturer { | ||||
| CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ | CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ | ||||
| } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \ | } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \ | ||||
| INTERNAL_CATCH_REACT( catchAssertionHandler ) \ | INTERNAL_CATCH_REACT( catchAssertionHandler ) \ | ||||
| } while( (void)0, false && static_cast<bool>( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look | |||||
| } while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look | |||||
| // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&. | // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&. | ||||
| /////////////////////////////////////////////////////////////////////////////// | /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CATCH_INFO( macroName, log ) \ | #define INTERNAL_CATCH_INFO( macroName, log ) \ | ||||
| Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log ); | Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log ); | ||||
| /////////////////////////////////////////////////////////////////////////////// | |||||
| #define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \ | |||||
| Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log ) | |||||
| /////////////////////////////////////////////////////////////////////////////// | /////////////////////////////////////////////////////////////////////////////// | ||||
| // Although this is matcher-based, it can be used with just a string | // Although this is matcher-based, it can be used with just a string | ||||
| #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \ | #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \ | ||||
| return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... ); | return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... ); | ||||
| } | } | ||||
| auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&; | |||||
| template<typename L> | |||||
| // Note: The type after -> is weird, because VS2015 cannot parse | |||||
| // the expression used in the typedef inside, when it is in | |||||
| // return type. Yeah. | |||||
| auto generate( SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) { | |||||
| using UnderlyingType = typename decltype(generatorExpression())::type; | |||||
| IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo ); | |||||
| if (!tracker.hasGenerator()) { | |||||
| tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression())); | |||||
| } | |||||
| auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() ); | |||||
| return generator.get(); | |||||
| } | |||||
| } // namespace Generators | |||||
| } // namespace Catch | |||||
| #define GENERATE( ... ) \ | |||||
| Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, []{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) | |||||
| // end catch_generators.hpp | |||||
| // start catch_generators_generic.hpp | |||||
| namespace Catch { | |||||
| namespace Generators { | |||||
| template <typename T> | template <typename T> | ||||
| class TakeGenerator : public IGenerator<T> { | class TakeGenerator : public IGenerator<T> { | ||||
| GeneratorWrapper<T> m_generator; | GeneratorWrapper<T> m_generator; | ||||
| ); | ); | ||||
| } | } | ||||
| auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&; | |||||
| template<typename L> | |||||
| // Note: The type after -> is weird, because VS2015 cannot parse | |||||
| // the expression used in the typedef inside, when it is in | |||||
| // return type. Yeah, ¯\_(ツ)_/¯ | |||||
| auto generate( SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) { | |||||
| using UnderlyingType = typename decltype(generatorExpression())::type; | |||||
| IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo ); | |||||
| if (!tracker.hasGenerator()) { | |||||
| tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression())); | |||||
| template <typename T> | |||||
| class ChunkGenerator final : public IGenerator<std::vector<T>> { | |||||
| std::vector<T> m_chunk; | |||||
| size_t m_chunk_size; | |||||
| GeneratorWrapper<T> m_generator; | |||||
| bool m_used_up = false; | |||||
| public: | |||||
| ChunkGenerator(size_t size, GeneratorWrapper<T> generator) : | |||||
| m_chunk_size(size), m_generator(std::move(generator)) | |||||
| { | |||||
| m_chunk.reserve(m_chunk_size); | |||||
| m_chunk.push_back(m_generator.get()); | |||||
| for (size_t i = 1; i < m_chunk_size; ++i) { | |||||
| if (!m_generator.next()) { | |||||
| Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk")); | |||||
| } | |||||
| m_chunk.push_back(m_generator.get()); | |||||
| } | |||||
| } | } | ||||
| std::vector<T> const& get() const override { | |||||
| return m_chunk; | |||||
| } | |||||
| bool next() override { | |||||
| m_chunk.clear(); | |||||
| for (size_t idx = 0; idx < m_chunk_size; ++idx) { | |||||
| if (!m_generator.next()) { | |||||
| return false; | |||||
| } | |||||
| m_chunk.push_back(m_generator.get()); | |||||
| } | |||||
| return true; | |||||
| } | |||||
| }; | |||||
| auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() ); | |||||
| return generator.get(); | |||||
| template <typename T> | |||||
| GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T>&& generator) { | |||||
| return GeneratorWrapper<std::vector<T>>( | |||||
| pf::make_unique<ChunkGenerator<T>>(size, std::move(generator)) | |||||
| ); | |||||
| } | } | ||||
| } // namespace Generators | } // namespace Generators | ||||
| } // namespace Catch | } // namespace Catch | ||||
| #define GENERATE( ... ) \ | |||||
| Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, []{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) | |||||
| // end catch_generators_generic.hpp | |||||
| // start catch_generators_specific.hpp | |||||
| // end catch_generators.hpp | |||||
| // start catch_context.h | |||||
| #include <memory> | |||||
| namespace Catch { | |||||
| struct IResultCapture; | |||||
| struct IRunner; | |||||
| struct IConfig; | |||||
| struct IMutableContext; | |||||
| using IConfigPtr = std::shared_ptr<IConfig const>; | |||||
| struct IContext | |||||
| { | |||||
| virtual ~IContext(); | |||||
| virtual IResultCapture* getResultCapture() = 0; | |||||
| virtual IRunner* getRunner() = 0; | |||||
| virtual IConfigPtr const& getConfig() const = 0; | |||||
| }; | |||||
| struct IMutableContext : IContext | |||||
| { | |||||
| virtual ~IMutableContext(); | |||||
| virtual void setResultCapture( IResultCapture* resultCapture ) = 0; | |||||
| virtual void setRunner( IRunner* runner ) = 0; | |||||
| virtual void setConfig( IConfigPtr const& config ) = 0; | |||||
| private: | |||||
| static IMutableContext *currentContext; | |||||
| friend IMutableContext& getCurrentMutableContext(); | |||||
| friend void cleanUpContext(); | |||||
| static void createContext(); | |||||
| }; | |||||
| inline IMutableContext& getCurrentMutableContext() | |||||
| { | |||||
| if( !IMutableContext::currentContext ) | |||||
| IMutableContext::createContext(); | |||||
| return *IMutableContext::currentContext; | |||||
| } | |||||
| inline IContext& getCurrentContext() | |||||
| { | |||||
| return getCurrentMutableContext(); | |||||
| } | |||||
| void cleanUpContext(); | |||||
| } | |||||
| // end catch_context.h | |||||
| // start catch_interfaces_config.h | |||||
| #include <iosfwd> | |||||
| #include <string> | |||||
| #include <vector> | |||||
| #include <memory> | |||||
| namespace Catch { | |||||
| enum class Verbosity { | |||||
| Quiet = 0, | |||||
| Normal, | |||||
| High | |||||
| }; | |||||
| struct WarnAbout { enum What { | |||||
| Nothing = 0x00, | |||||
| NoAssertions = 0x01, | |||||
| NoTests = 0x02 | |||||
| }; }; | |||||
| struct ShowDurations { enum OrNot { | |||||
| DefaultForReporter, | |||||
| Always, | |||||
| Never | |||||
| }; }; | |||||
| struct RunTests { enum InWhatOrder { | |||||
| InDeclarationOrder, | |||||
| InLexicographicalOrder, | |||||
| InRandomOrder | |||||
| }; }; | |||||
| struct UseColour { enum YesOrNo { | |||||
| Auto, | |||||
| Yes, | |||||
| No | |||||
| }; }; | |||||
| struct WaitForKeypress { enum When { | |||||
| Never, | |||||
| BeforeStart = 1, | |||||
| BeforeExit = 2, | |||||
| BeforeStartAndExit = BeforeStart | BeforeExit | |||||
| }; }; | |||||
| class TestSpec; | |||||
| struct IConfig : NonCopyable { | |||||
| virtual ~IConfig(); | |||||
| virtual bool allowThrows() const = 0; | |||||
| virtual std::ostream& stream() const = 0; | |||||
| virtual std::string name() const = 0; | |||||
| virtual bool includeSuccessfulResults() const = 0; | |||||
| virtual bool shouldDebugBreak() const = 0; | |||||
| virtual bool warnAboutMissingAssertions() const = 0; | |||||
| virtual bool warnAboutNoTests() const = 0; | |||||
| virtual int abortAfter() const = 0; | |||||
| virtual bool showInvisibles() const = 0; | |||||
| virtual ShowDurations::OrNot showDurations() const = 0; | |||||
| virtual TestSpec const& testSpec() const = 0; | |||||
| virtual bool hasTestFilters() const = 0; | |||||
| virtual RunTests::InWhatOrder runOrder() const = 0; | |||||
| virtual unsigned int rngSeed() const = 0; | |||||
| virtual int benchmarkResolutionMultiple() const = 0; | |||||
| virtual UseColour::YesOrNo useColour() const = 0; | |||||
| virtual std::vector<std::string> const& getSectionsToRun() const = 0; | |||||
| virtual Verbosity verbosity() const = 0; | |||||
| }; | |||||
| using IConfigPtr = std::shared_ptr<IConfig const>; | |||||
| } | |||||
| // end catch_interfaces_config.h | |||||
| #include <random> | |||||
| namespace Catch { | |||||
| namespace Generators { | |||||
| template <typename Float> | |||||
| class RandomFloatingGenerator final : public IGenerator<Float> { | |||||
| // FIXME: What is the right seed? | |||||
| std::minstd_rand m_rand; | |||||
| std::uniform_real_distribution<Float> m_dist; | |||||
| Float m_current_number; | |||||
| public: | |||||
| RandomFloatingGenerator(Float a, Float b): | |||||
| m_rand(getCurrentContext().getConfig()->rngSeed()), | |||||
| m_dist(a, b) { | |||||
| static_cast<void>(next()); | |||||
| } | |||||
| Float const& get() const override { | |||||
| return m_current_number; | |||||
| } | |||||
| bool next() override { | |||||
| m_current_number = m_dist(m_rand); | |||||
| return true; | |||||
| } | |||||
| }; | |||||
| template <typename Integer> | |||||
| class RandomIntegerGenerator final : public IGenerator<Integer> { | |||||
| std::minstd_rand m_rand; | |||||
| std::uniform_int_distribution<Integer> m_dist; | |||||
| Integer m_current_number; | |||||
| public: | |||||
| RandomIntegerGenerator(Integer a, Integer b): | |||||
| m_rand(getCurrentContext().getConfig()->rngSeed()), | |||||
| m_dist(a, b) { | |||||
| static_cast<void>(next()); | |||||
| } | |||||
| Integer const& get() const override { | |||||
| return m_current_number; | |||||
| } | |||||
| bool next() override { | |||||
| m_current_number = m_dist(m_rand); | |||||
| return true; | |||||
| } | |||||
| }; | |||||
| // TODO: Ideally this would be also constrained against the various char types, | |||||
| // but I don't expect users to run into that in practice. | |||||
| template <typename T> | |||||
| typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value, | |||||
| GeneratorWrapper<T>>::type | |||||
| random(T a, T b) { | |||||
| return GeneratorWrapper<T>( | |||||
| pf::make_unique<RandomIntegerGenerator<T>>(a, b) | |||||
| ); | |||||
| } | |||||
| template <typename T> | |||||
| typename std::enable_if<std::is_floating_point<T>::value, | |||||
| GeneratorWrapper<T>>::type | |||||
| random(T a, T b) { | |||||
| return GeneratorWrapper<T>( | |||||
| pf::make_unique<RandomFloatingGenerator<T>>(a, b) | |||||
| ); | |||||
| } | |||||
| template <typename T> | |||||
| class RangeGenerator final : public IGenerator<T> { | |||||
| T m_current; | |||||
| T m_end; | |||||
| T m_step; | |||||
| bool m_positive; | |||||
| public: | |||||
| RangeGenerator(T const& start, T const& end, T const& step): | |||||
| m_current(start), | |||||
| m_end(end), | |||||
| m_step(step), | |||||
| m_positive(m_step > T(0)) | |||||
| { | |||||
| assert(m_current != m_end && "Range start and end cannot be equal"); | |||||
| assert(m_step != T(0) && "Step size cannot be zero"); | |||||
| assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && "Step moves away from end"); | |||||
| } | |||||
| RangeGenerator(T const& start, T const& end): | |||||
| RangeGenerator(start, end, (start < end) ? T(1) : T(-1)) | |||||
| {} | |||||
| T const& get() const override { | |||||
| return m_current; | |||||
| } | |||||
| bool next() override { | |||||
| m_current += m_step; | |||||
| return (m_positive) ? (m_current < m_end) : (m_current > m_end); | |||||
| } | |||||
| }; | |||||
| template <typename T> | |||||
| GeneratorWrapper<T> range(T const& start, T const& end, T const& step) { | |||||
| static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer"); | |||||
| return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end, step)); | |||||
| } | |||||
| template <typename T> | |||||
| GeneratorWrapper<T> range(T const& start, T const& end) { | |||||
| static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer"); | |||||
| return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end)); | |||||
| } | |||||
| } // namespace Generators | |||||
| } // namespace Catch | |||||
| // end catch_generators_specific.hpp | |||||
| // These files are included here so the single_include script doesn't put them | // These files are included here so the single_include script doesn't put them | ||||
| // in the conditionally compiled sections | // in the conditionally compiled sections | ||||
| #endif | #endif | ||||
| // end catch_test_spec_parser.h | // end catch_test_spec_parser.h | ||||
| // start catch_interfaces_config.h | |||||
| #include <iosfwd> | |||||
| #include <string> | |||||
| #include <vector> | |||||
| #include <memory> | |||||
| namespace Catch { | |||||
| enum class Verbosity { | |||||
| Quiet = 0, | |||||
| Normal, | |||||
| High | |||||
| }; | |||||
| struct WarnAbout { enum What { | |||||
| Nothing = 0x00, | |||||
| NoAssertions = 0x01, | |||||
| NoTests = 0x02 | |||||
| }; }; | |||||
| struct ShowDurations { enum OrNot { | |||||
| DefaultForReporter, | |||||
| Always, | |||||
| Never | |||||
| }; }; | |||||
| struct RunTests { enum InWhatOrder { | |||||
| InDeclarationOrder, | |||||
| InLexicographicalOrder, | |||||
| InRandomOrder | |||||
| }; }; | |||||
| struct UseColour { enum YesOrNo { | |||||
| Auto, | |||||
| Yes, | |||||
| No | |||||
| }; }; | |||||
| struct WaitForKeypress { enum When { | |||||
| Never, | |||||
| BeforeStart = 1, | |||||
| BeforeExit = 2, | |||||
| BeforeStartAndExit = BeforeStart | BeforeExit | |||||
| }; }; | |||||
| class TestSpec; | |||||
| struct IConfig : NonCopyable { | |||||
| virtual ~IConfig(); | |||||
| virtual bool allowThrows() const = 0; | |||||
| virtual std::ostream& stream() const = 0; | |||||
| virtual std::string name() const = 0; | |||||
| virtual bool includeSuccessfulResults() const = 0; | |||||
| virtual bool shouldDebugBreak() const = 0; | |||||
| virtual bool warnAboutMissingAssertions() const = 0; | |||||
| virtual bool warnAboutNoTests() const = 0; | |||||
| virtual int abortAfter() const = 0; | |||||
| virtual bool showInvisibles() const = 0; | |||||
| virtual ShowDurations::OrNot showDurations() const = 0; | |||||
| virtual TestSpec const& testSpec() const = 0; | |||||
| virtual bool hasTestFilters() const = 0; | |||||
| virtual RunTests::InWhatOrder runOrder() const = 0; | |||||
| virtual unsigned int rngSeed() const = 0; | |||||
| virtual int benchmarkResolutionMultiple() const = 0; | |||||
| virtual UseColour::YesOrNo useColour() const = 0; | |||||
| virtual std::vector<std::string> const& getSectionsToRun() const = 0; | |||||
| virtual Verbosity verbosity() const = 0; | |||||
| }; | |||||
| using IConfigPtr = std::shared_ptr<IConfig const>; | |||||
| } | |||||
| // end catch_interfaces_config.h | |||||
| // Libstdc++ doesn't like incomplete classes for unique_ptr | // Libstdc++ doesn't like incomplete classes for unique_ptr | ||||
| #include <memory> | #include <memory> | ||||
| AssertionStats( AssertionStats const& ) = default; | AssertionStats( AssertionStats const& ) = default; | ||||
| AssertionStats( AssertionStats && ) = default; | AssertionStats( AssertionStats && ) = default; | ||||
| AssertionStats& operator = ( AssertionStats const& ) = default; | |||||
| AssertionStats& operator = ( AssertionStats && ) = default; | |||||
| AssertionStats& operator = ( AssertionStats const& ) = delete; | |||||
| AssertionStats& operator = ( AssertionStats && ) = delete; | |||||
| virtual ~AssertionStats(); | virtual ~AssertionStats(); | ||||
| AssertionResult assertionResult; | AssertionResult assertionResult; | ||||
| // end catch_approx.cpp | // end catch_approx.cpp | ||||
| // start catch_assertionhandler.cpp | // start catch_assertionhandler.cpp | ||||
| // start catch_context.h | |||||
| #include <memory> | |||||
| namespace Catch { | |||||
| struct IResultCapture; | |||||
| struct IRunner; | |||||
| struct IConfig; | |||||
| struct IMutableContext; | |||||
| using IConfigPtr = std::shared_ptr<IConfig const>; | |||||
| struct IContext | |||||
| { | |||||
| virtual ~IContext(); | |||||
| virtual IResultCapture* getResultCapture() = 0; | |||||
| virtual IRunner* getRunner() = 0; | |||||
| virtual IConfigPtr const& getConfig() const = 0; | |||||
| }; | |||||
| struct IMutableContext : IContext | |||||
| { | |||||
| virtual ~IMutableContext(); | |||||
| virtual void setResultCapture( IResultCapture* resultCapture ) = 0; | |||||
| virtual void setRunner( IRunner* runner ) = 0; | |||||
| virtual void setConfig( IConfigPtr const& config ) = 0; | |||||
| private: | |||||
| static IMutableContext *currentContext; | |||||
| friend IMutableContext& getCurrentMutableContext(); | |||||
| friend void cleanUpContext(); | |||||
| static void createContext(); | |||||
| }; | |||||
| inline IMutableContext& getCurrentMutableContext() | |||||
| { | |||||
| if( !IMutableContext::currentContext ) | |||||
| IMutableContext::createContext(); | |||||
| return *IMutableContext::currentContext; | |||||
| } | |||||
| inline IContext& getCurrentContext() | |||||
| { | |||||
| return getCurrentMutableContext(); | |||||
| } | |||||
| void cleanUpContext(); | |||||
| } | |||||
| // end catch_context.h | |||||
| // start catch_debugger.h | // start catch_debugger.h | ||||
| namespace Catch { | namespace Catch { | ||||
| void pushScopedMessage( MessageInfo const& message ) override; | void pushScopedMessage( MessageInfo const& message ) override; | ||||
| void popScopedMessage( MessageInfo const& message ) override; | void popScopedMessage( MessageInfo const& message ) override; | ||||
| void emplaceUnscopedMessage( MessageBuilder const& builder ) override; | |||||
| std::string getCurrentTestName() const override; | std::string getCurrentTestName() const override; | ||||
| const AssertionResult* getLastResult() const override; | const AssertionResult* getLastResult() const override; | ||||
| Totals m_totals; | Totals m_totals; | ||||
| IStreamingReporterPtr m_reporter; | IStreamingReporterPtr m_reporter; | ||||
| std::vector<MessageInfo> m_messages; | std::vector<MessageInfo> m_messages; | ||||
| std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */ | |||||
| AssertionInfo m_lastAssertionInfo; | AssertionInfo m_lastAssertionInfo; | ||||
| std::vector<SectionEndInfo> m_unfinishedSections; | std::vector<SectionEndInfo> m_unfinishedSections; | ||||
| std::vector<ITracker*> m_activeSections; | std::vector<ITracker*> m_activeSections; | ||||
| // ----------- end of #include from clara_textflow.hpp ----------- | // ----------- end of #include from clara_textflow.hpp ----------- | ||||
| // ........... back in clara.hpp | // ........... back in clara.hpp | ||||
| #include <cctype> | |||||
| #include <string> | #include <string> | ||||
| #include <memory> | #include <memory> | ||||
| #include <set> | #include <set> | ||||
| } | } | ||||
| inline auto convertInto( std::string const &source, bool &target ) -> ParserResult { | inline auto convertInto( std::string const &source, bool &target ) -> ParserResult { | ||||
| std::string srcLC = source; | std::string srcLC = source; | ||||
| std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast<char>( ::tolower(c) ); } ); | |||||
| std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast<char>( std::tolower(c) ); } ); | |||||
| if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on") | if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on") | ||||
| target = true; | target = true; | ||||
| else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off") | else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off") | ||||
| //////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////// | ||||
| ScopedMessage::ScopedMessage( MessageBuilder const& builder ) | ScopedMessage::ScopedMessage( MessageBuilder const& builder ) | ||||
| : m_info( builder.m_info ) | |||||
| : m_info( builder.m_info ), m_moved() | |||||
| { | { | ||||
| m_info.message = builder.m_stream.str(); | m_info.message = builder.m_stream.str(); | ||||
| getResultCapture().pushScopedMessage( m_info ); | getResultCapture().pushScopedMessage( m_info ); | ||||
| } | } | ||||
| ScopedMessage::ScopedMessage( ScopedMessage&& old ) | |||||
| : m_info( old.m_info ), m_moved() | |||||
| { | |||||
| old.m_moved = true; | |||||
| } | |||||
| ScopedMessage::~ScopedMessage() { | ScopedMessage::~ScopedMessage() { | ||||
| if ( !uncaught_exceptions() ){ | |||||
| if ( !uncaught_exceptions() && !m_moved ){ | |||||
| getResultCapture().popScopedMessage(m_info); | getResultCapture().popScopedMessage(m_info); | ||||
| } | } | ||||
| } | } | ||||
| auto str() const -> std::string; | auto str() const -> std::string; | ||||
| }; | }; | ||||
| class RedirectedStreams { | |||||
| public: | |||||
| RedirectedStreams(RedirectedStreams const&) = delete; | |||||
| RedirectedStreams& operator=(RedirectedStreams const&) = delete; | |||||
| RedirectedStreams(RedirectedStreams&&) = delete; | |||||
| RedirectedStreams& operator=(RedirectedStreams&&) = delete; | |||||
| RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr); | |||||
| ~RedirectedStreams(); | |||||
| private: | |||||
| std::string& m_redirectedCout; | |||||
| std::string& m_redirectedCerr; | |||||
| RedirectedStdOut m_redirectedStdOut; | |||||
| RedirectedStdErr m_redirectedStdErr; | |||||
| }; | |||||
| #if defined(CATCH_CONFIG_NEW_CAPTURE) | #if defined(CATCH_CONFIG_NEW_CAPTURE) | ||||
| // Windows's implementation of std::tmpfile is terrible (it tries | // Windows's implementation of std::tmpfile is terrible (it tries | ||||
| {} | {} | ||||
| auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); } | auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); } | ||||
| RedirectedStreams::RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr) | |||||
| : m_redirectedCout(redirectedCout), | |||||
| m_redirectedCerr(redirectedCerr) | |||||
| {} | |||||
| RedirectedStreams::~RedirectedStreams() { | |||||
| m_redirectedCout += m_redirectedStdOut.str(); | |||||
| m_redirectedCerr += m_redirectedStdErr.str(); | |||||
| } | |||||
| #if defined(CATCH_CONFIG_NEW_CAPTURE) | #if defined(CATCH_CONFIG_NEW_CAPTURE) | ||||
| #if defined(_MSC_VER) | #if defined(_MSC_VER) | ||||
| // and should be let to clear themselves out. | // and should be let to clear themselves out. | ||||
| static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals))); | static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals))); | ||||
| if (result.getResultType() != ResultWas::Warning) | |||||
| m_messageScopes.clear(); | |||||
| // Reset working state | // Reset working state | ||||
| resetAssertionInfo(); | resetAssertionInfo(); | ||||
| m_lastResult = result; | m_lastResult = result; | ||||
| m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions)); | m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions)); | ||||
| m_messages.clear(); | m_messages.clear(); | ||||
| m_messageScopes.clear(); | |||||
| } | } | ||||
| void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) { | void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) { | ||||
| m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end()); | m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end()); | ||||
| } | } | ||||
| void RunContext::emplaceUnscopedMessage( MessageBuilder const& builder ) { | |||||
| m_messageScopes.emplace_back( builder ); | |||||
| } | |||||
| std::string RunContext::getCurrentTestName() const { | std::string RunContext::getCurrentTestName() const { | ||||
| return m_activeTestCase | return m_activeTestCase | ||||
| ? m_activeTestCase->getTestCaseInfo().name | ? m_activeTestCase->getTestCaseInfo().name | ||||
| m_lastAssertionPassed = true; | m_lastAssertionPassed = true; | ||||
| ++m_totals.assertions.passed; | ++m_totals.assertions.passed; | ||||
| resetAssertionInfo(); | resetAssertionInfo(); | ||||
| m_messageScopes.clear(); | |||||
| } | } | ||||
| bool RunContext::aborting() const { | bool RunContext::aborting() const { | ||||
| CATCH_TRY { | CATCH_TRY { | ||||
| if (m_reporter->getPreferences().shouldRedirectStdOut) { | if (m_reporter->getPreferences().shouldRedirectStdOut) { | ||||
| #if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) | #if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) | ||||
| RedirectedStdOut redirectedStdOut; | |||||
| RedirectedStdErr redirectedStdErr; | |||||
| RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr); | |||||
| timer.start(); | timer.start(); | ||||
| invokeActiveTestCase(); | invokeActiveTestCase(); | ||||
| redirectedCout += redirectedStdOut.str(); | |||||
| redirectedCerr += redirectedStdErr.str(); | |||||
| #else | #else | ||||
| OutputRedirect r(redirectedCout, redirectedCerr); | OutputRedirect r(redirectedCout, redirectedCerr); | ||||
| timer.start(); | timer.start(); | ||||
| m_testCaseTracker->close(); | m_testCaseTracker->close(); | ||||
| handleUnfinishedSections(); | handleUnfinishedSections(); | ||||
| m_messages.clear(); | m_messages.clear(); | ||||
| m_messageScopes.clear(); | |||||
| SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions); | SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions); | ||||
| m_reporter->sectionEnded(testCaseSectionStats); | m_reporter->sectionEnded(testCaseSectionStats); | ||||
| return 1; | return 1; | ||||
| auto result = m_cli.parse( clara::Args( argc, argv ) ); | auto result = m_cli.parse( clara::Args( argc, argv ) ); | ||||
| config(); | |||||
| getCurrentMutableContext().setConfig( m_config ); | |||||
| if( !result ) { | if( !result ) { | ||||
| config(); | |||||
| getCurrentMutableContext().setConfig(m_config); | |||||
| Catch::cerr() | Catch::cerr() | ||||
| << Colour( Colour::Red ) | << Colour( Colour::Red ) | ||||
| << "\nError(s) in input:\n" | << "\nError(s) in input:\n" | ||||
| } | } | ||||
| Version const& libraryVersion() { | Version const& libraryVersion() { | ||||
| static Version version( 2, 6, 1, "", 0 ); | |||||
| static Version version( 2, 7, 0, "", 0 ); | |||||
| return version; | return version; | ||||
| } | } | ||||
| #ifdef _MSC_VER | #ifdef _MSC_VER | ||||
| sprintf_s(buffer, "%.3f", duration); | sprintf_s(buffer, "%.3f", duration); | ||||
| #else | #else | ||||
| sprintf(buffer, "%.3f", duration); | |||||
| std::sprintf(buffer, "%.3f", duration); | |||||
| #endif | #endif | ||||
| return std::string(buffer); | return std::string(buffer); | ||||
| } | } | ||||
| case Unit::Nanoseconds: | case Unit::Nanoseconds: | ||||
| return "ns"; | return "ns"; | ||||
| case Unit::Microseconds: | case Unit::Microseconds: | ||||
| return "µs"; | |||||
| return "us"; | |||||
| case Unit::Milliseconds: | case Unit::Milliseconds: | ||||
| return "ms"; | return "ms"; | ||||
| case Unit::Seconds: | case Unit::Seconds: | ||||
| #endif // CATCH_CONFIG_DISABLE_MATCHERS | #endif // CATCH_CONFIG_DISABLE_MATCHERS | ||||
| #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg ) | #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg ) | ||||
| #define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg ) | |||||
| #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) | #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) | ||||
| #define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ ) | #define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ ) | ||||