externals: Update catch to 2.7.0
Keeps the unit testing library up to date.
This commit is contained in:
parent
d32d6fe598
commit
e1aca18944
1 changed files with 437 additions and 200 deletions
637
externals/catch/catch.hpp
vendored
637
externals/catch/catch.hpp
vendored
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Catch v2.6.1
|
* Catch v2.7.0
|
||||||
* Generated: 2019-02-12 19:52:52.262497
|
* 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.
|
||||||
|
@ -14,8 +14,8 @@
|
||||||
|
|
||||||
|
|
||||||
#define CATCH_VERSION_MAJOR 2
|
#define CATCH_VERSION_MAJOR 2
|
||||||
#define CATCH_VERSION_MINOR 6
|
#define CATCH_VERSION_MINOR 7
|
||||||
#define CATCH_VERSION_PATCH 1
|
#define CATCH_VERSION_PATCH 0
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
# pragma clang system_header
|
# pragma clang system_header
|
||||||
|
@ -711,6 +711,16 @@ struct is_unique<T0, T1, Rest...> : std::integral_constant
|
||||||
#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__)
|
||||||
|
|
||||||
|
@ -725,7 +735,7 @@ struct is_unique<T0, T1, Rest...> : std::integral_constant
|
||||||
#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))
|
||||||
|
@ -736,65 +746,59 @@ struct is_unique<T0, T1, Rest...> : std::integral_constant
|
||||||
|
|
||||||
#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
|
, typename...E1
|
||||||
, template<typename...> class L2
|
, template<typename...> class L2
|
||||||
, typename...E2
|
, typename...E2
|
||||||
>
|
>
|
||||||
struct append< L1<E1...>, L2<E2...> >
|
struct append< L1<E1...>, L2<E2...> > {
|
||||||
{
|
using type = L1<E1..., E2...>;
|
||||||
using type = L1<E1..., E2...>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template< template<typename...> class L1
|
template< template<typename...> class L1
|
||||||
, typename...E1
|
, typename...E1
|
||||||
, template<typename...> class L2
|
, template<typename...> class L2
|
||||||
, typename...E2
|
, typename...E2
|
||||||
, typename...Rest
|
, typename...Rest
|
||||||
>
|
>
|
||||||
struct append< L1<E1...>, L2<E2...>, Rest...>
|
struct append< L1<E1...>, L2<E2...>, Rest...> {
|
||||||
{
|
using type = typename append< L1<E1..., E2...>, Rest... >::type;
|
||||||
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
|
, template<typename...> class List
|
||||||
, typename...elems
|
, typename...elems
|
||||||
>
|
>
|
||||||
struct rewrap<Container, List<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
|
, template<typename...> class List
|
||||||
, class...Elems
|
, class...Elems
|
||||||
, typename...Elements>
|
, typename...Elements>
|
||||||
struct rewrap<Container, List<Elems...>, 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;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -803,6 +807,8 @@ struct combine
|
||||||
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 {
|
||||||
|
|
||||||
|
@ -949,11 +955,14 @@ struct AutoReg : NonCopyable {
|
||||||
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; \
|
||||||
|
@ -1014,11 +1023,14 @@ struct AutoReg : NonCopyable {
|
||||||
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;\
|
||||||
|
@ -2062,6 +2074,7 @@ namespace Catch {
|
||||||
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;
|
||||||
|
@ -2088,6 +2101,8 @@ namespace Catch {
|
||||||
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
|
||||||
|
@ -2251,9 +2266,12 @@ namespace Catch {
|
||||||
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 {
|
||||||
|
@ -2316,7 +2334,7 @@ namespace Catch {
|
||||||
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 &&.
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -2397,6 +2415,10 @@ namespace Catch {
|
||||||
#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, ... ) \
|
||||||
|
@ -3642,6 +3664,36 @@ namespace Generators {
|
||||||
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;
|
||||||
|
@ -3810,31 +3862,297 @@ namespace Generators {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
|
template <typename T>
|
||||||
|
class ChunkGenerator final : public IGenerator<std::vector<T>> {
|
||||||
template<typename L>
|
std::vector<T> m_chunk;
|
||||||
// Note: The type after -> is weird, because VS2015 cannot parse
|
size_t m_chunk_size;
|
||||||
// the expression used in the typedef inside, when it is in
|
GeneratorWrapper<T> m_generator;
|
||||||
// return type. Yeah, ¯\_(ツ)_/¯
|
bool m_used_up = false;
|
||||||
auto generate( SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) {
|
public:
|
||||||
using UnderlyingType = typename decltype(generatorExpression())::type;
|
ChunkGenerator(size_t size, GeneratorWrapper<T> generator) :
|
||||||
|
m_chunk_size(size), m_generator(std::move(generator))
|
||||||
IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo );
|
{
|
||||||
if (!tracker.hasGenerator()) {
|
m_chunk.reserve(m_chunk_size);
|
||||||
tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression()));
|
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() );
|
template <typename T>
|
||||||
return generator.get();
|
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( ... ) \
|
// end catch_generators_generic.hpp
|
||||||
Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, []{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
|
// 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
|
||||||
|
@ -4321,79 +4639,6 @@ namespace Catch {
|
||||||
#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>
|
||||||
|
@ -4673,8 +4918,8 @@ namespace Catch {
|
||||||
|
|
||||||
AssertionStats( AssertionStats const& ) = default;
|
AssertionStats( AssertionStats const& ) = default;
|
||||||
AssertionStats( AssertionStats && ) = default;
|
AssertionStats( AssertionStats && ) = default;
|
||||||
AssertionStats& operator = ( AssertionStats const& ) = default;
|
AssertionStats& operator = ( AssertionStats const& ) = delete;
|
||||||
AssertionStats& operator = ( AssertionStats && ) = default;
|
AssertionStats& operator = ( AssertionStats && ) = delete;
|
||||||
virtual ~AssertionStats();
|
virtual ~AssertionStats();
|
||||||
|
|
||||||
AssertionResult assertionResult;
|
AssertionResult assertionResult;
|
||||||
|
@ -5758,58 +6003,6 @@ std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx co
|
||||||
// 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 {
|
||||||
|
@ -5996,6 +6189,8 @@ 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;
|
||||||
|
@ -6043,6 +6238,7 @@ namespace Catch {
|
||||||
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;
|
||||||
|
@ -6679,6 +6875,7 @@ inline auto Column::operator + (Column const& other) -> Columns {
|
||||||
// ----------- 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>
|
||||||
|
@ -6971,7 +7168,7 @@ namespace detail {
|
||||||
}
|
}
|
||||||
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")
|
||||||
|
@ -9374,14 +9571,20 @@ namespace Catch {
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9489,6 +9692,22 @@ namespace Catch {
|
||||||
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
|
||||||
|
@ -9580,6 +9799,16 @@ namespace Catch {
|
||||||
{}
|
{}
|
||||||
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)
|
||||||
|
@ -10161,6 +10390,9 @@ namespace Catch {
|
||||||
// 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;
|
||||||
|
@ -10215,6 +10447,7 @@ namespace Catch {
|
||||||
|
|
||||||
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) {
|
||||||
|
@ -10241,6 +10474,10 @@ namespace Catch {
|
||||||
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
|
||||||
|
@ -10301,6 +10538,7 @@ namespace Catch {
|
||||||
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 {
|
||||||
|
@ -10322,13 +10560,10 @@ namespace Catch {
|
||||||
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;
|
RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr);
|
||||||
RedirectedStdErr redirectedStdErr;
|
|
||||||
|
|
||||||
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();
|
||||||
|
@ -10355,6 +10590,7 @@ namespace Catch {
|
||||||
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);
|
||||||
|
@ -10762,9 +10998,9 @@ namespace Catch {
|
||||||
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"
|
||||||
|
@ -12429,7 +12665,7 @@ namespace Catch {
|
||||||
}
|
}
|
||||||
|
|
||||||
Version const& libraryVersion() {
|
Version const& libraryVersion() {
|
||||||
static Version version( 2, 6, 1, "", 0 );
|
static Version version( 2, 7, 0, "", 0 );
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12781,7 +13017,7 @@ namespace Catch {
|
||||||
#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);
|
||||||
}
|
}
|
||||||
|
@ -13315,7 +13551,7 @@ public:
|
||||||
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:
|
||||||
|
@ -14464,6 +14700,7 @@ int main (int argc, char * const argv[]) {
|
||||||
#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__ )
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue