This commit is contained in:
Martin Hořeňovský 2020-06-29 20:50:39 +02:00
parent ee4538c0c6
commit 0f05c034c2
No known key found for this signature in database
GPG Key ID: DE48307B8B0D381A
6 changed files with 113 additions and 44 deletions

View File

@ -14,7 +14,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
endif()
project(Catch2 LANGUAGES CXX VERSION 2.12.2)
project(Catch2 LANGUAGES CXX VERSION 2.12.3)
# Provide path for scripts
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")

View File

@ -5,11 +5,11 @@
[![Build Status](https://travis-ci.org/catchorg/Catch2.svg?branch=master)](https://travis-ci.org/catchorg/Catch2)
[![Build status](https://ci.appveyor.com/api/projects/status/github/catchorg/Catch2?svg=true)](https://ci.appveyor.com/project/catchorg/catch2)
[![codecov](https://codecov.io/gh/catchorg/Catch2/branch/master/graph/badge.svg)](https://codecov.io/gh/catchorg/Catch2)
[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/QdDfqVqDGRuwcduN)
[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/yfl7WhNJBY0IpgtF)
[![Join the chat in Discord: https://discord.gg/4CWS9zD](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/4CWS9zD)
<a href="https://github.com/catchorg/Catch2/releases/download/v2.12.2/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
<a href="https://github.com/catchorg/Catch2/releases/download/v2.12.3/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
## Catch2 is released!

View File

@ -2,6 +2,7 @@
# Release notes
**Contents**<br>
[2.12.3](#2123)<br>
[2.12.2](#2122)<br>
[2.12.1](#2121)<br>
[2.12.0](#2120)<br>
@ -38,6 +39,26 @@
[Even Older versions](#even-older-versions)<br>
## 2.12.3
### Fixes
* `GENERATE` nested in a for loop no longer creates multiple generators (#1913)
* Fixed copy paste error breaking `TEMPLATE_TEST_CASE_SIG` for 6 or more arguments (#1954)
* Fixed potential UB when handling non-ASCII characters in CLI args (#1943)
### Improvements
* There can be multiple calls to `GENERATE` on a single line
* Improved `fno-except` support for platforms that do not provide shims for exception-related std functions (#1950)
* E.g. the Green Hills C++ compiler
* XmlReporter now also reports test-case-level statistics (#1958)
* This is done via a new element, `OverallResultsCases`
### Miscellaneous
* Added `.clang-format` file to the repo (#1182, #1920)
* Rewrote contributing docs
* They should explain the different levels of testing and so on much better
## 2.12.2
### Fixes

View File

@ -11,7 +11,7 @@
#define CATCH_VERSION_MAJOR 2
#define CATCH_VERSION_MINOR 12
#define CATCH_VERSION_PATCH 2
#define CATCH_VERSION_PATCH 3
#ifdef __clang__
# pragma clang system_header

View File

@ -37,7 +37,7 @@ namespace Catch {
}
Version const& libraryVersion() {
static Version version( 2, 12, 2, "", 0 );
static Version version( 2, 12, 3, "", 0 );
return version;
}

View File

@ -1,6 +1,6 @@
/*
* Catch v2.12.2
* Generated: 2020-05-25 15:09:23.791719
* Catch v2.12.3
* Generated: 2020-06-29 20:47:52.374964
* ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly
* Copyright (c) 2020 Two Blue Cubes Ltd. All rights reserved.
@ -15,7 +15,7 @@
#define CATCH_VERSION_MAJOR 2
#define CATCH_VERSION_MINOR 12
#define CATCH_VERSION_PATCH 2
#define CATCH_VERSION_PATCH 3
#ifdef __clang__
# pragma clang system_header
@ -775,7 +775,7 @@ constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) n
#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3)
#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4)
#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5)
#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _4, _5, _6)
#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6)
#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7)
#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8)
#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9)
@ -2468,7 +2468,7 @@ namespace Catch {
virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
virtual auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
virtual void benchmarkPreparing( std::string const& name ) = 0;
@ -4080,16 +4080,16 @@ namespace Generators {
return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
}
auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
auto acquireGeneratorTracker( StringRef generatorName, 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()) {
auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) {
using UnderlyingType = typename decltype(generatorExpression())::type;
IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo );
IGeneratorTracker& tracker = acquireGeneratorTracker( generatorName, lineInfo );
if (!tracker.hasGenerator()) {
tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression()));
}
@ -4102,11 +4102,17 @@ namespace Generators {
} // namespace Catch
#define GENERATE( ... ) \
Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
CATCH_INTERNAL_LINEINFO, \
[ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
#define GENERATE_COPY( ... ) \
Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
CATCH_INTERNAL_LINEINFO, \
[=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
#define GENERATE_REF( ... ) \
Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
CATCH_INTERNAL_LINEINFO, \
[&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
// end catch_generators.hpp
// start catch_generators_generic.hpp
@ -7463,17 +7469,30 @@ namespace TestCaseTracking {
SourceLineInfo location;
NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) {
return lhs.name == rhs.name
&& lhs.location == rhs.location;
}
};
struct ITracker;
class ITracker;
using ITrackerPtr = std::shared_ptr<ITracker>;
struct ITracker {
virtual ~ITracker();
class ITracker {
NameAndLocation m_nameAndLocation;
public:
ITracker(NameAndLocation const& nameAndLoc) :
m_nameAndLocation(nameAndLoc)
{}
// static queries
virtual NameAndLocation const& nameAndLocation() const = 0;
NameAndLocation const& nameAndLocation() const {
return m_nameAndLocation;
}
virtual ~ITracker();
// dynamic queries
virtual bool isComplete() const = 0; // Successfully completed or failed
@ -7534,7 +7553,6 @@ namespace TestCaseTracking {
};
using Children = std::vector<ITrackerPtr>;
NameAndLocation m_nameAndLocation;
TrackerContext& m_ctx;
ITracker* m_parent;
Children m_children;
@ -7543,7 +7561,6 @@ namespace TestCaseTracking {
public:
TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
NameAndLocation const& nameAndLocation() const override;
bool isComplete() const override;
bool isSuccessfullyCompleted() const override;
bool isOpen() const override;
@ -8095,7 +8112,7 @@ namespace Catch {
void sectionEnded( SectionEndInfo const& endInfo ) override;
void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
void benchmarkPreparing( std::string const& name ) override;
@ -9071,7 +9088,7 @@ namespace detail {
}
inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {
std::string srcLC = source;
std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast<char>( std::tolower(c) ); } );
std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( unsigned char c ) { return static_cast<char>( std::tolower(c) ); } );
if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
target = true;
else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
@ -10883,8 +10900,8 @@ namespace Generators {
GeneratorUntypedBase::~GeneratorUntypedBase() {}
auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
return getResultCapture().acquireGeneratorTracker( lineInfo );
auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
return getResultCapture().acquireGeneratorTracker( generatorName, lineInfo );
}
} // namespace Generators
@ -12304,11 +12321,13 @@ namespace Catch {
namespace Catch {
class StartupExceptionRegistry {
#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
public:
void add(std::exception_ptr const& exception) noexcept;
std::vector<std::exception_ptr> const& getExceptions() const noexcept;
private:
std::vector<std::exception_ptr> m_exceptions;
#endif
};
} // end namespace Catch
@ -12391,7 +12410,11 @@ namespace Catch {
m_tagAliasRegistry.add( alias, tag, lineInfo );
}
void registerStartupException() noexcept override {
#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
m_exceptionRegistry.add(std::current_exception());
#else
CATCH_INTERNAL_ERROR("Attempted to register active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
#endif
}
IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override {
return m_enumValuesRegistry;
@ -12495,12 +12518,27 @@ namespace Catch {
std::shared_ptr<GeneratorTracker> tracker;
ITracker& currentTracker = ctx.currentTracker();
if( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
// Under specific circumstances, the generator we want
// to acquire is also the current tracker. If this is
// the case, we have to avoid looking through current
// tracker's children, and instead return the current
// tracker.
// A case where this check is important is e.g.
// for (int i = 0; i < 5; ++i) {
// int n = GENERATE(1, 2);
// }
//
// without it, the code above creates 5 nested generators.
if (currentTracker.nameAndLocation() == nameAndLocation) {
auto thisTracker = currentTracker.parent().findChild(nameAndLocation);
assert(thisTracker);
assert(thisTracker->isGeneratorTracker());
tracker = std::static_pointer_cast<GeneratorTracker>(thisTracker);
} else if ( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
assert( childTracker );
assert( childTracker->isGeneratorTracker() );
tracker = std::static_pointer_cast<GeneratorTracker>( childTracker );
}
else {
} else {
tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, &currentTracker );
currentTracker.addChild( tracker );
}
@ -12656,9 +12694,10 @@ namespace Catch {
return true;
}
auto RunContext::acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
auto RunContext::acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
using namespace Generators;
GeneratorTracker& tracker = GeneratorTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( "generator", lineInfo ) );
GeneratorTracker& tracker = GeneratorTracker::acquire(m_trackerContext,
TestCaseTracking::NameAndLocation( static_cast<std::string>(generatorName), lineInfo ) );
assert( tracker.isOpen() );
m_lastAssertionInfo.lineInfo = lineInfo;
return tracker;
@ -12702,17 +12741,17 @@ namespace Catch {
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
void RunContext::benchmarkPreparing(std::string const& name) {
m_reporter->benchmarkPreparing(name);
}
m_reporter->benchmarkPreparing(name);
}
void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
m_reporter->benchmarkStarting( info );
}
void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) {
m_reporter->benchmarkEnded( stats );
}
void RunContext::benchmarkFailed(std::string const & error) {
m_reporter->benchmarkFailed(error);
}
void RunContext::benchmarkFailed(std::string const & error) {
m_reporter->benchmarkFailed(error);
}
#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
void RunContext::pushScopedMessage(MessageInfo const & message) {
@ -13433,6 +13472,7 @@ namespace Catch {
// end catch_singletons.cpp
// start catch_startup_exception_registry.cpp
#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
namespace Catch {
void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
CATCH_TRY {
@ -13448,6 +13488,7 @@ void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexce
}
} // end namespace Catch
#endif
// end catch_startup_exception_registry.cpp
// start catch_stream.cpp
@ -13632,7 +13673,7 @@ namespace Catch {
namespace {
char toLowerCh(char c) {
return static_cast<char>( std::tolower( c ) );
return static_cast<char>( std::tolower( static_cast<unsigned char>(c) ) );
}
}
@ -14215,15 +14256,12 @@ namespace TestCaseTracking {
m_currentTracker = tracker;
}
TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
: m_nameAndLocation( nameAndLocation ),
TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ):
ITracker(nameAndLocation),
m_ctx( ctx ),
m_parent( parent )
{}
NameAndLocation const& TrackerBase::nameAndLocation() const {
return m_nameAndLocation;
}
bool TrackerBase::isComplete() const {
return m_runState == CompletedSuccessfully || m_runState == Failed;
}
@ -15122,7 +15160,9 @@ namespace Catch {
namespace Catch {
bool uncaught_exceptions() {
#if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
return false;
#elif defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
return std::uncaught_exceptions() > 0;
#else
return std::uncaught_exception();
@ -15162,7 +15202,7 @@ namespace Catch {
}
Version const& libraryVersion() {
static Version version( 2, 12, 2, "", 0 );
static Version version( 2, 12, 3, "", 0 );
return version;
}
@ -17180,6 +17220,10 @@ namespace Catch {
.writeAttribute( "successes", testGroupStats.totals.assertions.passed )
.writeAttribute( "failures", testGroupStats.totals.assertions.failed )
.writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
m_xml.scopedElement( "OverallResultsCases")
.writeAttribute( "successes", testGroupStats.totals.testCases.passed )
.writeAttribute( "failures", testGroupStats.totals.testCases.failed )
.writeAttribute( "expectedFailures", testGroupStats.totals.testCases.failedButOk );
m_xml.endElement();
}
@ -17189,6 +17233,10 @@ namespace Catch {
.writeAttribute( "successes", testRunStats.totals.assertions.passed )
.writeAttribute( "failures", testRunStats.totals.assertions.failed )
.writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
m_xml.scopedElement( "OverallResultsCases")
.writeAttribute( "successes", testRunStats.totals.testCases.passed )
.writeAttribute( "failures", testRunStats.totals.testCases.failed )
.writeAttribute( "expectedFailures", testRunStats.totals.testCases.failedButOk );
m_xml.endElement();
}