Browse Source

Catch updated to v2.3.0.

main
offa 6 years ago
parent
commit
eddff6657e
1 changed files with 214 additions and 142 deletions
  1. +214
    -142
      test/catch/catch.hpp

+ 214
- 142
test/catch/catch.hpp View File

/* /*
* Catch v2.2.3
* Generated: 2018-06-06 23:11:57.601416
* Catch v2.3.0
* Generated: 2018-07-23 10:09:14.936841
* ---------------------------------------------------------- * ----------------------------------------------------------
* 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) 2018 Two Blue Cubes Ltd. All rights reserved. * Copyright (c) 2018 Two Blue Cubes Ltd. All rights reserved.




#define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MAJOR 2
#define CATCH_VERSION_MINOR 2
#define CATCH_VERSION_PATCH 3
#define CATCH_VERSION_MINOR 3
#define CATCH_VERSION_PATCH 0


#ifdef __clang__ #ifdef __clang__
# pragma clang system_header # pragma clang system_header
# pragma warning(push) # pragma warning(push)
# pragma warning(disable: 161 1682) # pragma warning(disable: 161 1682)
# else // __ICC # else // __ICC
# pragma clang diagnostic ignored "-Wunused-variable"
# pragma clang diagnostic push # pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wpadded" # pragma clang diagnostic ignored "-Wpadded"
# pragma clang diagnostic ignored "-Wswitch-enum" # pragma clang diagnostic ignored "-Wswitch-enum"
# pragma clang diagnostic ignored "-Wcovered-switch-default" # pragma clang diagnostic ignored "-Wcovered-switch-default"
# endif # endif
#elif defined __GNUC__ #elif defined __GNUC__
// GCC likes to warn on REQUIREs, and we cannot suppress them
// locally because g++'s support for _Pragma is lacking in older,
// still supported, versions
# pragma GCC diagnostic ignored "-Wparentheses" # pragma GCC diagnostic ignored "-Wparentheses"
# pragma GCC diagnostic push # pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-variable" # pragma GCC diagnostic ignored "-Wunused-variable"
# if defined(CATCH_CONFIG_DISABLE_MATCHERS) # if defined(CATCH_CONFIG_DISABLE_MATCHERS)
# undef CATCH_CONFIG_DISABLE_MATCHERS # undef CATCH_CONFIG_DISABLE_MATCHERS
# endif # endif
# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
# if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
# endif
#endif #endif


#if !defined(CATCH_CONFIG_IMPL_ONLY) #if !defined(CATCH_CONFIG_IMPL_ONLY)
# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ # define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
_Pragma( "clang diagnostic pop" ) _Pragma( "clang diagnostic pop" )


# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
_Pragma( "clang diagnostic push" ) \
_Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
# define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS \
_Pragma( "clang diagnostic pop" )

#endif // __clang__ #endif // __clang__


//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH # define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
#endif #endif


////////////////////////////////////////////////////////////////////////////////
// PS4
#if defined(__ORBIS__)
# define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
#endif

//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Cygwin // Cygwin
#ifdef __CYGWIN__ #ifdef __CYGWIN__
# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS # define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
#endif #endif


#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
#endif

#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)
# define CATCH_CONFIG_NEW_CAPTURE
#endif

#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS # define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS # define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
#endif #endif
#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
# define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
#endif


// end catch_compiler_capabilities.h // end catch_compiler_capabilities.h
#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
#define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \ #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
static void TestName(); \ static void TestName(); \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
static void TestName() static void TestName()
#define INTERNAL_CATCH_TESTCASE( ... ) \ #define INTERNAL_CATCH_TESTCASE( ... ) \
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \ #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS


// end catch_test_registry.h // end catch_test_registry.h
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \ #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
do { \ do { \
Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \ catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
INTERNAL_CATCH_REACT( catchAssertionHandler ) \ INTERNAL_CATCH_REACT( catchAssertionHandler ) \
} while( false ) } while( false )
namespace Catch { namespace Catch {


struct SectionInfo { struct SectionInfo {
SectionInfo
( SourceLineInfo const& _lineInfo,
std::string const& _name );

// Deprecated
SectionInfo SectionInfo
( SourceLineInfo const& _lineInfo, ( SourceLineInfo const& _lineInfo,
std::string const& _name, std::string const& _name,
std::string const& _description = std::string() );
std::string const& ) : SectionInfo( _lineInfo, _name ) {}


std::string name; std::string name;
std::string description;
std::string description; // !Deprecated: this will always be empty
SourceLineInfo lineInfo; SourceLineInfo lineInfo;
}; };


struct SectionEndInfo { struct SectionEndInfo {
SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds );

SectionInfo sectionInfo; SectionInfo sectionInfo;
Counts prevAssertions; Counts prevAssertions;
double durationInSeconds; double durationInSeconds;


} // end namespace Catch } // end namespace Catch


#define INTERNAL_CATCH_SECTION( ... ) \
if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
#define INTERNAL_CATCH_SECTION( ... ) \
CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS

#define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS


// end catch_section.h // end catch_section.h
// start catch_benchmark.h // start catch_benchmark.h


static Approx custom(); static Approx custom();


Approx operator-() const;

template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
Approx operator()( T const& value ) { Approx operator()( T const& value ) {
Approx approx( static_cast<double>(value) ); Approx approx( static_cast<double>(value) );
double m_scale; double m_scale;
double m_value; double m_value;
}; };
}
} // end namespace Detail

namespace literals {
Detail::Approx operator "" _a(long double val);
Detail::Approx operator "" _a(unsigned long long val);
} // end namespace literals


template<> template<>
struct StringMaker<Catch::Detail::Approx> { struct StringMaker<Catch::Detail::Approx> {
std::string desc = Detail::getAnnotation( cls, "Description", testCaseName ); std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
const char* className = class_getName( cls ); const char* className = class_getName( cls );


getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo("",0) ) );
getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo("",0) ) );
noTestMethods++; noTestMethods++;
} }
} }


struct ReporterPreferences { struct ReporterPreferences {
bool shouldRedirectStdOut = false; bool shouldRedirectStdOut = false;
bool shouldReportAllAssertions = false;
}; };


template<typename T> template<typename T>
return Approx( 0 ); return Approx( 0 );
} }


Approx Approx::operator-() const {
auto temp(*this);
temp.m_value = -temp.m_value;
return temp;
}

std::string Approx::toString() const { std::string Approx::toString() const {
ReusableStringStream rss; ReusableStringStream rss;
rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )"; rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";


} // end namespace Detail } // end namespace Detail


namespace literals {
Detail::Approx operator "" _a(long double val) {
return Detail::Approx(val);
}
Detail::Approx operator "" _a(unsigned long long val) {
return Detail::Approx(val);
}
} // end namespace literals

std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) { std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
return value.toString(); return value.toString();
} }
// end catch_run_context.h // end catch_run_context.h
namespace Catch { namespace Catch {


auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
expr.streamReconstructedExpression( os );
return os;
namespace {
auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
expr.streamReconstructedExpression( os );
return os;
}
} }


LazyExpression::LazyExpression( bool isNegated ) LazyExpression::LazyExpression( bool isNegated )
using Reporters = std::vector<IStreamingReporterPtr>; using Reporters = std::vector<IStreamingReporterPtr>;
Reporters m_listeners; Reporters m_listeners;
IStreamingReporterPtr m_reporter = nullptr; IStreamingReporterPtr m_reporter = nullptr;
ReporterPreferences m_preferences;


public: public:
ListeningReporter();

void addListener( IStreamingReporterPtr&& listener ); void addListener( IStreamingReporterPtr&& listener );
void addReporter( IStreamingReporterPtr&& reporter ); void addReporter( IStreamingReporterPtr&& reporter );


auto str() const -> std::string; auto str() const -> std::string;
}; };


#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
// to create a file inside system folder, thus requiring elevated // to create a file inside system folder, thus requiring elevated
// privileges for the binary), so we have to use tmpnam(_s) and // privileges for the binary), so we have to use tmpnam(_s) and
std::string& m_stderrDest; std::string& m_stderrDest;
}; };


#endif

} // end namespace Catch } // end namespace Catch


#endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H #endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>


#if defined(_MSC_VER)
#include <io.h> //_dup and _dup2
#define dup _dup
#define dup2 _dup2
#define fileno _fileno
#else
#include <unistd.h> // dup and dup2
#if defined(CATCH_CONFIG_NEW_CAPTURE)
#if defined(_MSC_VER)
#include <io.h> //_dup and _dup2
#define dup _dup
#define dup2 _dup2
#define fileno _fileno
#else
#include <unistd.h> // dup and dup2
#endif
#endif #endif


namespace Catch { namespace Catch {
{} {}
auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); } auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }


#if defined(CATCH_CONFIG_NEW_CAPTURE)

#if defined(_MSC_VER) #if defined(_MSC_VER)
TempFile::TempFile() { TempFile::TempFile() {
if (tmpnam_s(m_buffer)) { if (tmpnam_s(m_buffer)) {
m_stderrDest += m_stderrFile.getContents(); m_stderrDest += m_stderrFile.getContents();
} }


#endif // CATCH_CONFIG_NEW_CAPTURE

} // namespace Catch } // namespace Catch


#if defined(_MSC_VER)
#undef dup
#undef dup2
#undef fileno
#if defined(CATCH_CONFIG_NEW_CAPTURE)
#if defined(_MSC_VER)
#undef dup
#undef dup2
#undef fileno
#endif
#endif #endif
// end catch_output_redirect.cpp // end catch_output_redirect.cpp
// start catch_random_number_generator.cpp // start catch_random_number_generator.cpp
// start catch_random_number_generator.h // start catch_random_number_generator.h


#include <algorithm> #include <algorithm>
#include <random>


namespace Catch { namespace Catch {


struct IConfig; struct IConfig;


std::mt19937& rng();
void seedRng( IConfig const& config ); void seedRng( IConfig const& config );

unsigned int rngSeed(); unsigned int rngSeed();


struct RandomNumberGenerator {
using result_type = unsigned int;

static constexpr result_type (min)() { return 0; }
static constexpr result_type (max)() { return 1000000; }

result_type operator()( result_type n ) const;
result_type operator()() const;

template<typename V>
static void shuffle( V& vector ) {
RandomNumberGenerator rng;
std::shuffle( vector.begin(), vector.end(), rng );
}
};

} }


// end catch_random_number_generator.h // end catch_random_number_generator.h
#include <cstdlib>

namespace Catch { namespace Catch {


std::mt19937& rng() {
static std::mt19937 s_rng;
return s_rng;
}

void seedRng( IConfig const& config ) { void seedRng( IConfig const& config ) {
if( config.rngSeed() != 0 )
if( config.rngSeed() != 0 ) {
std::srand( config.rngSeed() ); std::srand( config.rngSeed() );
rng().seed( config.rngSeed() );
}
} }

unsigned int rngSeed() { unsigned int rngSeed() {
return getCurrentContext().getConfig()->rngSeed(); return getCurrentContext().getConfig()->rngSeed();
} }

RandomNumberGenerator::result_type RandomNumberGenerator::operator()( result_type n ) const {
return std::rand() % n;
}
RandomNumberGenerator::result_type RandomNumberGenerator::operator()() const {
return std::rand() % (max)();
}

} }
// end catch_random_number_generator.cpp // end catch_random_number_generator.cpp
// start catch_registry_hub.cpp // start catch_registry_hub.cpp
m_config(_config), m_config(_config),
m_reporter(std::move(reporter)), m_reporter(std::move(reporter)),
m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal }, m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
m_includeSuccessfulResults( m_config->includeSuccessfulResults() )
m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
{ {
m_context.setRunner(this); m_context.setRunner(this);
m_context.setConfig(m_config); m_context.setConfig(m_config);


// Recreate section for test case (as we will lose the one that was in scope) // Recreate section for test case (as we will lose the one that was in scope)
auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);
SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);


Counts assertions; Counts assertions;
assertions.failed = 1; assertions.failed = 1;


void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) { void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);
SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
m_reporter->sectionStarting(testCaseSection); m_reporter->sectionStarting(testCaseSection);
Counts prevAssertions = m_totals.assertions; Counts prevAssertions = m_totals.assertions;
double duration = 0; double duration = 0;


Section::~Section() { Section::~Section() {
if( m_sectionIncluded ) { if( m_sectionIncluded ) {
SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };
if( uncaught_exceptions() ) if( uncaught_exceptions() )
getResultCapture().sectionEndedEarly( endInfo ); getResultCapture().sectionEndedEarly( endInfo );
else else


SectionInfo::SectionInfo SectionInfo::SectionInfo
( SourceLineInfo const& _lineInfo, ( SourceLineInfo const& _lineInfo,
std::string const& _name,
std::string const& _description )
std::string const& _name )
: name( _name ), : name( _name ),
description( _description ),
lineInfo( _lineInfo ) lineInfo( _lineInfo )
{} {}


SectionEndInfo::SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
: sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
{}

} // end namespace Catch } // end namespace Catch
// end catch_section_info.cpp // end catch_section_info.cpp
// start catch_session.cpp // start catch_session.cpp


namespace Catch { namespace Catch {


namespace {
char toLowerCh(char c) {
return static_cast<char>( std::tolower( c ) );
}
}

bool startsWith( std::string const& s, std::string const& prefix ) { bool startsWith( std::string const& s, std::string const& prefix ) {
return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin()); return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
} }
bool contains( std::string const& s, std::string const& infix ) { bool contains( std::string const& s, std::string const& infix ) {
return s.find( infix ) != std::string::npos; return s.find( infix ) != std::string::npos;
} }
char toLowerCh(char c) {
return static_cast<char>( std::tolower( c ) );
}
void toLowerInPlace( std::string& s ) { void toLowerInPlace( std::string& s ) {
std::transform( s.begin(), s.end(), s.begin(), toLowerCh ); std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
} }


namespace Catch { namespace Catch {


TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
if( startsWith( tag, '.' ) ||
tag == "!hide" )
return TestCaseInfo::IsHidden;
else if( tag == "!throws" )
return TestCaseInfo::Throws;
else if( tag == "!shouldfail" )
return TestCaseInfo::ShouldFail;
else if( tag == "!mayfail" )
return TestCaseInfo::MayFail;
else if( tag == "!nonportable" )
return TestCaseInfo::NonPortable;
else if( tag == "!benchmark" )
return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );
else
return TestCaseInfo::None;
}
bool isReservedTag( std::string const& tag ) {
return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );
}
void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
CATCH_ENFORCE( !isReservedTag(tag),
"Tag name: [" << tag << "] is not allowed.\n"
<< "Tag names starting with non alpha-numeric characters are reserved\n"
<< _lineInfo );
namespace {
TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
if( startsWith( tag, '.' ) ||
tag == "!hide" )
return TestCaseInfo::IsHidden;
else if( tag == "!throws" )
return TestCaseInfo::Throws;
else if( tag == "!shouldfail" )
return TestCaseInfo::ShouldFail;
else if( tag == "!mayfail" )
return TestCaseInfo::MayFail;
else if( tag == "!nonportable" )
return TestCaseInfo::NonPortable;
else if( tag == "!benchmark" )
return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );
else
return TestCaseInfo::None;
}
bool isReservedTag( std::string const& tag ) {
return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );
}
void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
CATCH_ENFORCE( !isReservedTag(tag),
"Tag name: [" << tag << "] is not allowed.\n"
<< "Tag names starting with non alpha-numeric characters are reserved\n"
<< _lineInfo );
}
} }


TestCase makeTestCase( ITestInvoker* _testCase, TestCase makeTestCase( ITestInvoker* _testCase,
break; break;
case RunTests::InRandomOrder: case RunTests::InRandomOrder:
seedRng( config ); seedRng( config );
RandomNumberGenerator::shuffle( sorted );
std::shuffle( sorted.begin(), sorted.end(), rng() );
break; break;
case RunTests::InDeclarationOrder: case RunTests::InDeclarationOrder:
// already in declaration order // already in declaration order
TrackerBase::TrackerHasName::TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {} TrackerBase::TrackerHasName::TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {}
bool TrackerBase::TrackerHasName::operator ()( ITrackerPtr const& tracker ) const { bool TrackerBase::TrackerHasName::operator ()( ITrackerPtr const& tracker ) const {
return return
tracker->nameAndLocation().name == m_nameAndLocation.name &&
tracker->nameAndLocation().location == m_nameAndLocation.location;
tracker->nameAndLocation().location == m_nameAndLocation.location &&
tracker->nameAndLocation().name == m_nameAndLocation.name;
} }


TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count(); return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
} }


auto estimateClockResolution() -> uint64_t {
uint64_t sum = 0;
static const uint64_t iterations = 1000000;
namespace {
auto estimateClockResolution() -> uint64_t {
uint64_t sum = 0;
static const uint64_t iterations = 1000000;


auto startTime = getCurrentNanosecondsSinceEpoch();
auto startTime = getCurrentNanosecondsSinceEpoch();


for( std::size_t i = 0; i < iterations; ++i ) {
for( std::size_t i = 0; i < iterations; ++i ) {


uint64_t ticks;
uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
do {
ticks = getCurrentNanosecondsSinceEpoch();
} while( ticks == baseTicks );
uint64_t ticks;
uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
do {
ticks = getCurrentNanosecondsSinceEpoch();
} while( ticks == baseTicks );


auto delta = ticks - baseTicks;
sum += delta;
auto delta = ticks - baseTicks;
sum += delta;


// If we have been calibrating for over 3 seconds -- the clock
// is terrible and we should move on.
// TBD: How to signal that the measured resolution is probably wrong?
if (ticks > startTime + 3 * nanosecondsInSecond) {
return sum / i;
// If we have been calibrating for over 3 seconds -- the clock
// is terrible and we should move on.
// TBD: How to signal that the measured resolution is probably wrong?
if (ticks > startTime + 3 * nanosecondsInSecond) {
return sum / i;
}
} }
}


// We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
// - and potentially do more iterations if there's a high variance.
return sum/iterations;
// We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
// - and potentially do more iterations if there's a high variance.
return sum/iterations;
}
} }
auto getEstimatedClockResolution() -> uint64_t { auto getEstimatedClockResolution() -> uint64_t {
static auto s_resolution = estimateClockResolution(); static auto s_resolution = estimateClockResolution();


std::string ratio_string<std::atto>::symbol() { return "a"; } std::string ratio_string<std::atto>::symbol() { return "a"; }
std::string ratio_string<std::femto>::symbol() { return "f"; } std::string ratio_string<std::femto>::symbol() { return "f"; }
std::string ratio_string<std::pico>::symbol() { return "p"; }
std::string ratio_string<std::nano>::symbol() { return "n"; }
std::string ratio_string<std::pico>::symbol() { return "p"; }
std::string ratio_string<std::nano>::symbol() { return "n"; }
std::string ratio_string<std::micro>::symbol() { return "u"; } std::string ratio_string<std::micro>::symbol() { return "u"; }
std::string ratio_string<std::milli>::symbol() { return "m"; } std::string ratio_string<std::milli>::symbol() { return "m"; }


} }


Version const& libraryVersion() { Version const& libraryVersion() {
static Version version( 2, 2, 3, "", 0 );
static Version version( 2, 3, 0, "", 0 );
return version; return version;
} }


} }


ReporterPreferences CompactReporter::getPreferences() const { ReporterPreferences CompactReporter::getPreferences() const {
ReporterPreferences prefs;
prefs.shouldRedirectStdOut = false;
return prefs;
return m_reporterPrefs;
} }


void CompactReporter::noMatchingTestCases( std::string const& spec ) { void CompactReporter::noMatchingTestCases( std::string const& spec ) {
xml( _config.stream() ) xml( _config.stream() )
{ {
m_reporterPrefs.shouldRedirectStdOut = true; m_reporterPrefs.shouldRedirectStdOut = true;
m_reporterPrefs.shouldReportAllAssertions = true;
} }


JunitReporter::~JunitReporter() {} JunitReporter::~JunitReporter() {}


namespace Catch { namespace Catch {


ListeningReporter::ListeningReporter() {
// We will assume that listeners will always want all assertions
m_preferences.shouldReportAllAssertions = true;
}

void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) { void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {
m_listeners.push_back( std::move( listener ) ); m_listeners.push_back( std::move( listener ) );
} }
void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) { void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {
assert(!m_reporter && "Listening reporter can wrap only 1 real reporter"); assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
m_reporter = std::move( reporter ); m_reporter = std::move( reporter );
m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
} }


ReporterPreferences ListeningReporter::getPreferences() const { ReporterPreferences ListeningReporter::getPreferences() const {
return m_reporter->getPreferences();
return m_preferences;
} }


std::set<Verbosity> ListeningReporter::getSupportedVerbosities() { std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {
m_xml(_config.stream()) m_xml(_config.stream())
{ {
m_reporterPrefs.shouldRedirectStdOut = true; m_reporterPrefs.shouldRedirectStdOut = true;
m_reporterPrefs.shouldReportAllAssertions = true;
} }


XmlReporter::~XmlReporter() = default; XmlReporter::~XmlReporter() = default;
StreamingReporterBase::sectionStarting( sectionInfo ); StreamingReporterBase::sectionStarting( sectionInfo );
if( m_sectionDepth++ > 0 ) { if( m_sectionDepth++ > 0 ) {
m_xml.startElement( "Section" ) m_xml.startElement( "Section" )
.writeAttribute( "name", trim( sectionInfo.name ) )
.writeAttribute( "description", sectionInfo.description );
.writeAttribute( "name", trim( sectionInfo.name ) );
writeSourceInfo( sectionInfo.lineInfo ); writeSourceInfo( sectionInfo.lineInfo );
m_xml.ensureTagClosed(); m_xml.ensureTagClosed();
} }
#define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
#define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
#define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
#define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
#define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
// "BDD-style" convenience wrappers // "BDD-style" convenience wrappers
#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ ) #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
#define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc )
#define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc )
#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc )
#define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc )
#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc )
#define CATCH_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
#define CATCH_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
#define CATCH_AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And when: " << desc )
#define CATCH_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
#define CATCH_AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )


// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
#else #else
#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
#define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
#define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ ) #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )


#define GIVEN( desc ) SECTION( std::string(" Given: ") + desc )
#define WHEN( desc ) SECTION( std::string(" When: ") + desc )
#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc )
#define THEN( desc ) SECTION( std::string(" Then: ") + desc )
#define AND_THEN( desc ) SECTION( std::string(" And: ") + desc )
#define GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
#define WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
#define AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And when: " << desc )
#define THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
#define AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )


using Catch::Detail::Approx; using Catch::Detail::Approx;


#else
#else // CATCH_CONFIG_DISABLE

////// //////
// If this config identifier is defined then all CATCH macros are prefixed with CATCH_ // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
#ifdef CATCH_CONFIG_PREFIX_ALL #ifdef CATCH_CONFIG_PREFIX_ALL
#define CATCH_METHOD_AS_TEST_CASE( method, ... ) #define CATCH_METHOD_AS_TEST_CASE( method, ... )
#define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0) #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
#define CATCH_SECTION( ... ) #define CATCH_SECTION( ... )
#define CATCH_DYNAMIC_SECTION( ... )
#define CATCH_FAIL( ... ) (void)(0) #define CATCH_FAIL( ... ) (void)(0)
#define CATCH_FAIL_CHECK( ... ) (void)(0) #define CATCH_FAIL_CHECK( ... ) (void)(0)
#define CATCH_SUCCEED( ... ) (void)(0) #define CATCH_SUCCEED( ... ) (void)(0)
#define METHOD_AS_TEST_CASE( method, ... ) #define METHOD_AS_TEST_CASE( method, ... )
#define REGISTER_TEST_CASE( Function, ... ) (void)(0) #define REGISTER_TEST_CASE( Function, ... ) (void)(0)
#define SECTION( ... ) #define SECTION( ... )
#define DYNAMIC_SECTION( ... )
#define FAIL( ... ) (void)(0) #define FAIL( ... ) (void)(0)
#define FAIL_CHECK( ... ) (void)(0) #define FAIL_CHECK( ... ) (void)(0)
#define SUCCEED( ... ) (void)(0) #define SUCCEED( ... ) (void)(0)

Loading…
Cancel
Save