Browse Source

Catch updated to v2.2.2.

main
offa 6 years ago
parent
commit
0d36d053d2
1 changed files with 239 additions and 41 deletions
  1. +239
    -41
      test/catch/catch.hpp

+ 239
- 41
test/catch/catch.hpp View File

/* /*
* Catch v2.2.1
* Generated: 2018-03-11 12:01:31.654719
* Catch v2.2.2
* Generated: 2018-04-06 12:05:03.186665
* ---------------------------------------------------------- * ----------------------------------------------------------
* 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_MINOR 2
#define CATCH_VERSION_PATCH 1
#define CATCH_VERSION_PATCH 2


#ifdef __clang__ #ifdef __clang__
# pragma clang system_header # pragma clang system_header
# pragma clang diagnostic ignored "-Wcovered-switch-default" # pragma clang diagnostic ignored "-Wcovered-switch-default"
# endif # endif
#elif defined __GNUC__ #elif defined __GNUC__
# pragma GCC diagnostic ignored "-Wunused-variable"
# 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 "-Wpadded" # pragma GCC diagnostic ignored "-Wpadded"
#endif #endif
// end catch_suppress_warnings.h // end catch_suppress_warnings.h
return convertUnknownEnumToString( value ); return convertUnknownEnumToString( value );
} }


#if defined(_MANAGED)
//! Convert a CLR string to a utf8 std::string
template<typename T>
std::string clrReferenceToString( T^ ref ) {
if (ref == nullptr)
return std::string("null");
auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
cli::pin_ptr<System::Byte> p = &bytes[0];
return std::string(reinterpret_cast<char const *>(p), bytes->Length);
}
#endif

} // namespace Detail } // namespace Detail


// If we decide for C++14, change these to enable_if_ts // If we decide for C++14, change these to enable_if_ts
return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e)); return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
} }


#if defined(_MANAGED)
template <typename T>
std::string stringify( T^ e ) {
return ::Catch::StringMaker<T^>::convert(e);
}
#endif

} // namespace Detail } // namespace Detail


// Some predefined specializations // Some predefined specializations
struct StringMaker<char *> { struct StringMaker<char *> {
static std::string convert(char * str); static std::string convert(char * str);
}; };

#ifdef CATCH_CONFIG_WCHAR #ifdef CATCH_CONFIG_WCHAR
template<> template<>
struct StringMaker<wchar_t const *> { struct StringMaker<wchar_t const *> {
}; };
#endif #endif


// TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
// while keeping string semantics?
template<int SZ> template<int SZ>
struct StringMaker<char[SZ]> { struct StringMaker<char[SZ]> {
static std::string convert(const char* str) {
static std::string convert(char const* str) {
return ::Catch::Detail::stringify(std::string{ str }); return ::Catch::Detail::stringify(std::string{ str });
} }
}; };
template<int SZ> template<int SZ>
struct StringMaker<signed char[SZ]> { struct StringMaker<signed char[SZ]> {
static std::string convert(const char* str) {
return ::Catch::Detail::stringify(std::string{ str });
static std::string convert(signed char const* str) {
return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
} }
}; };
template<int SZ> template<int SZ>
struct StringMaker<unsigned char[SZ]> { struct StringMaker<unsigned char[SZ]> {
static std::string convert(const char* str) {
return ::Catch::Detail::stringify(std::string{ str });
static std::string convert(unsigned char const* str) {
return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
} }
}; };


} }
}; };


#if defined(_MANAGED)
template <typename T>
struct StringMaker<T^> {
static std::string convert( T^ ref ) {
return ::Catch::Detail::clrReferenceToString(ref);
}
};
#endif

namespace Detail { namespace Detail {
template<typename InputIterator> template<typename InputIterator>
std::string rangeToString(InputIterator first, InputIterator last) { std::string rangeToString(InputIterator first, InputIterator last) {
!std::is_same<decltype(end(std::declval<T>())), not_this_one>::value; !std::is_same<decltype(end(std::declval<T>())), not_this_one>::value;
}; };


#if defined(_MANAGED) // Managed types are never ranges
template <typename T>
struct is_range<T^> {
static const bool value = false;
};
#endif

template<typename Range> template<typename Range>
std::string rangeToString( Range const& range ) { std::string rangeToString( Range const& range ) {
return ::Catch::Detail::rangeToString( begin( range ), end( range ) ); return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
} // namespace Catch } // namespace Catch


// end catch_matchers_floating.h // end catch_matchers_floating.h
// start catch_matchers_generic.hpp

#include <functional>
#include <string>

namespace Catch {
namespace Matchers {
namespace Generic {

namespace Detail {
std::string finalizeDescription(const std::string& desc);
}

template <typename T>
class PredicateMatcher : public MatcherBase<T> {
std::function<bool(T const&)> m_predicate;
std::string m_description;
public:

PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr)
:m_predicate(std::move(elem)),
m_description(Detail::finalizeDescription(descr))
{}

bool match( T const& item ) const override {
return m_predicate(item);
}

std::string describe() const override {
return m_description;
}
};

} // namespace Generic

// The following functions create the actual matcher objects.
// The user has to explicitly specify type to the function, because
// infering std::function<bool(T const&)> is hard (but possible) and
// requires a lot of TMP.
template<typename T>
Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") {
return Generic::PredicateMatcher<T>(predicate, description);
}

} // namespace Matchers
} // namespace Catch

// end catch_matchers_generic.hpp
// start catch_matchers_string.h // start catch_matchers_string.h


#include <string> #include <string>


public: public:
// !TBD We need to do this another way! // !TBD We need to do this another way!
bool aborting() const override;
bool aborting() const final;


private: private:


// Performs equivalent check of std::fabs(lhs - rhs) <= margin // Performs equivalent check of std::fabs(lhs - rhs) <= margin
// But without the subtraction to allow for INFINITY in comparison // But without the subtraction to allow for INFINITY in comparison
bool WithinAbsMatcher::match(double const& matchee) const { bool WithinAbsMatcher::match(double const& matchee) const {
return (matchee + m_margin >= m_target) && (m_target + m_margin >= m_margin);
return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);
} }


std::string WithinAbsMatcher::describe() const { std::string WithinAbsMatcher::describe() const {
} // namespace Catch } // namespace Catch


// end catch_matchers_floating.cpp // end catch_matchers_floating.cpp
// start catch_matchers_generic.cpp

std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) {
if (desc.empty()) {
return "matches undescribed predicate";
} else {
return "matches predicate: \"" + desc + '"';
}
}
// end catch_matchers_generic.cpp
// start catch_matchers_string.cpp // start catch_matchers_string.cpp


#include <regex> #include <regex>


#include <chrono> #include <chrono>


static const uint64_t nanosecondsInSecond = 1000000000;

namespace Catch { namespace Catch {


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


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 ticks;
uint64_t baseTicks = getCurrentNanosecondsSinceEpoch(); uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
do { do {
ticks = getCurrentNanosecondsSinceEpoch(); ticks = getCurrentNanosecondsSinceEpoch();
}
while( ticks == baseTicks );
} while( ticks == baseTicks );


auto delta = ticks - baseTicks; auto delta = ticks - baseTicks;
sum += delta; 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;
}
} }


// We're just taking the mean, here. To do better we could take the std. dev and exclude outliers // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
} }


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




#include <iomanip> #include <iomanip>


using uchar = unsigned char;

namespace Catch { namespace Catch {


namespace {

size_t trailingBytes(unsigned char c) {
if ((c & 0xE0) == 0xC0) {
return 2;
}
if ((c & 0xF0) == 0xE0) {
return 3;
}
if ((c & 0xF8) == 0xF0) {
return 4;
}
CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
}

uint32_t headerValue(unsigned char c) {
if ((c & 0xE0) == 0xC0) {
return c & 0x1F;
}
if ((c & 0xF0) == 0xE0) {
return c & 0x0F;
}
if ((c & 0xF8) == 0xF0) {
return c & 0x07;
}
CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
}

void hexEscapeChar(std::ostream& os, unsigned char c) {
os << "\\x"
<< std::uppercase << std::hex << std::setfill('0') << std::setw(2)
<< static_cast<int>(c);
}

} // anonymous namespace

XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat ) XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
: m_str( str ), : m_str( str ),
m_forWhat( forWhat ) m_forWhat( forWhat )
{} {}


void XmlEncode::encodeTo( std::ostream& os ) const { void XmlEncode::encodeTo( std::ostream& os ) const {

// Apostrophe escaping not necessary if we always use " to write attributes // Apostrophe escaping not necessary if we always use " to write attributes
// (see: http://www.w3.org/TR/xml/#syntax) // (see: http://www.w3.org/TR/xml/#syntax)


for( std::size_t i = 0; i < m_str.size(); ++ i ) {
char c = m_str[i];
switch( c ) {
case '<': os << "&lt;"; break;
case '&': os << "&amp;"; break;
for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
uchar c = m_str[idx];
switch (c) {
case '<': os << "&lt;"; break;
case '&': os << "&amp;"; break;


case '>':
// See: http://www.w3.org/TR/xml/#syntax
if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' )
os << "&gt;";
else
os << c;
case '>':
// See: http://www.w3.org/TR/xml/#syntax
if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
os << "&gt;";
else
os << c;
break;

case '\"':
if (m_forWhat == ForAttributes)
os << "&quot;";
else
os << c;
break;

default:
// Check for control characters and invalid utf-8

// Escape control characters in standard ascii
// see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
hexEscapeChar(os, c);
break; break;
}


case '\"':
if( m_forWhat == ForAttributes )
os << "&quot;";
else
os << c;
// Plain ASCII: Write it to stream
if (c < 0x7F) {
os << c;
break; break;
}


default:
// Escape control chars - based on contribution by @espenalb in PR #465 and
// by @mrpi PR #588
if ( ( c >= 0 && c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' ) {
// see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
os << "\\x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
<< static_cast<int>( c );
}
else
os << c;
// UTF-8 territory
// Check if the encoding is valid and if it is not, hex escape bytes.
// Important: We do not check the exact decoded values for validity, only the encoding format
// First check that this bytes is a valid lead byte:
// This means that it is not encoded as 1111 1XXX
// Or as 10XX XXXX
if (c < 0xC0 ||
c >= 0xF8) {
hexEscapeChar(os, c);
break;
}

auto encBytes = trailingBytes(c);
// Are there enough bytes left to avoid accessing out-of-bounds memory?
if (idx + encBytes - 1 >= m_str.size()) {
hexEscapeChar(os, c);
break;
}
// The header is valid, check data
// The next encBytes bytes must together be a valid utf-8
// This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
bool valid = true;
uint32_t value = headerValue(c);
for (std::size_t n = 1; n < encBytes; ++n) {
uchar nc = m_str[idx + n];
valid &= ((nc & 0xC0) == 0x80);
value = (value << 6) | (nc & 0x3F);
}

if (
// Wrong bit pattern of following bytes
(!valid) ||
// Overlong encodings
(value < 0x80) ||
(0x80 <= value && value < 0x800 && encBytes > 2) ||
(0x800 < value && value < 0x10000 && encBytes > 3) ||
// Encoded value out of range
(value >= 0x110000)
) {
hexEscapeChar(os, c);
break;
}

// If we got here, this is in fact a valid(ish) utf-8 sequence
for (std::size_t n = 0; n < encBytes; ++n) {
os << m_str[idx + n];
}
idx += encBytes - 1;
break;
} }
} }
} }

Loading…
Cancel
Save