diff --git a/CMakeLists.txt b/CMakeLists.txt
index 42c8a031..94f90d9f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,7 +6,7 @@ if(NOT DEFINED PROJECT_NAME)
set(NOT_SUBPROJECT ON)
endif()
-project(Catch2 LANGUAGES CXX VERSION 2.2.3)
+project(Catch2 LANGUAGES CXX VERSION 2.3.0)
# Provide path for scripts
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
diff --git a/README.md b/README.md
index 15ed9045..386f8534 100644
--- a/README.md
+++ b/README.md
@@ -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/u7qF77qgv9YqOr55)
+[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/Gcuv2Xx3wmWIPNzy)
[![Join the chat in Discord: https://discord.gg/4CWS9zD](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/4CWS9zD)
-The latest version of the single header can be downloaded directly using this link
+The latest version of the single header can be downloaded directly using this link
## Catch2 is released!
diff --git a/conanfile.py b/conanfile.py
index 9fea1525..76053959 100644
--- a/conanfile.py
+++ b/conanfile.py
@@ -4,7 +4,7 @@ from conans import ConanFile, CMake
class CatchConan(ConanFile):
name = "Catch"
- version = "2.2.3"
+ version = "2.3.0"
description = "A modern, C++-native, header-only, framework for unit-tests, TDD and BDD"
author = "philsquared"
generators = "cmake"
diff --git a/docs/release-notes.md b/docs/release-notes.md
index 6ebe4d03..e40be99c 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -1,5 +1,36 @@
+# 2.3.0
+
+**This release changes the include paths provided by our CMake and
+pkg-config integration. The proper include path for the single-header
+when using one of the above is now ``. This change
+also necessitated changes to paths inside the repository, so that the
+single-header version is now at `single_include/catch2/catch.hpp`, rather
+than `single_include/catch.hpp`.**
+
+
+
+## Fixes
+* Fixed Objective-C++ build
+* `-Wunused-variable` suppression no longer leaks from Catch's header under Clang
+* Implementation of the experimental new output capture can now be disabled (#1335)
+ * This allows building Catch2 on platforms that do not provide things like `dup` or `tmpfile`.
+* The JUnit and XML reporters will no longer skip over successful tests when running without `-s` (#1264, #1267, #1310)
+ * See improvements for more details
+
+## Improvements
+* pkg-config and CMake integration has been rewritten
+ * If you use them, the new include path is `#include `
+ * CMake installation now also installs scripts from `contrib/`
+ * For details see the [new documentation](cmake-integration.md#top)
+* Reporters now have a new customization point, `ReporterPreferences::shouldReportAllAssertions`
+ * When this is set to `false` and the tests are run without `-s`, passing assertions are not sent to the reporter.
+ * Defaults to `false`.
+* Added `DYNAMIC_SECTION`, a section variant that constructs its name using stream
+ * This means that you can do `DYNAMIC_SECTION("For X := " << x)`.
+
+
# 2.2.3
**To fix some of the bugs, some behavior had to change in potentially breaking manner.**
diff --git a/include/catch.hpp b/include/catch.hpp
index b4a05845..0a49cb31 100644
--- a/include/catch.hpp
+++ b/include/catch.hpp
@@ -10,8 +10,8 @@
#define TWOBLUECUBES_CATCH_HPP_INCLUDED
#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__
# pragma clang system_header
diff --git a/include/internal/catch_version.cpp b/include/internal/catch_version.cpp
index 94e11e08..1585ff7a 100644
--- a/include/internal/catch_version.cpp
+++ b/include/internal/catch_version.cpp
@@ -37,7 +37,7 @@ namespace Catch {
}
Version const& libraryVersion() {
- static Version version( 2, 2, 3, "", 0 );
+ static Version version( 2, 3, 0, "", 0 );
return version;
}
diff --git a/single_include/catch2/catch.hpp b/single_include/catch2/catch.hpp
index 6fac1e7c..bdc2f74a 100644
--- a/single_include/catch2/catch.hpp
+++ b/single_include/catch2/catch.hpp
@@ -1,6 +1,6 @@
/*
- * Catch v2.2.3
- * Generated: 2018-06-11 22:16:30.128800
+ * 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
* Copyright (c) 2018 Two Blue Cubes Ltd. All rights reserved.
@@ -14,8 +14,8 @@
#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__
# pragma clang system_header
@@ -30,13 +30,15 @@
# pragma warning(push)
# pragma warning(disable: 161 1682)
# else // __ICC
-# pragma clang diagnostic ignored "-Wunused-variable"
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wpadded"
# pragma clang diagnostic ignored "-Wswitch-enum"
# pragma clang diagnostic ignored "-Wcovered-switch-default"
# endif
#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 push
# pragma GCC diagnostic ignored "-Wunused-variable"
@@ -55,7 +57,9 @@
# if defined(CATCH_CONFIG_DISABLE_MATCHERS)
# undef CATCH_CONFIG_DISABLE_MATCHERS
# endif
-# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
+# if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
+# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
+# endif
#endif
#if !defined(CATCH_CONFIG_IMPL_ONLY)
@@ -145,6 +149,12 @@ namespace Catch {
# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
_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__
////////////////////////////////////////////////////////////////////////////////
@@ -176,6 +186,12 @@ namespace Catch {
# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
#endif
+////////////////////////////////////////////////////////////////////////////////
+// PS4
+#if defined(__ORBIS__)
+# define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
+#endif
+
////////////////////////////////////////////////////////////////////////////////
// Cygwin
#ifdef __CYGWIN__
@@ -245,6 +261,14 @@ namespace Catch {
# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
#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)
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
@@ -253,6 +277,10 @@ namespace Catch {
# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
#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
#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
@@ -551,7 +579,7 @@ struct AutoReg : NonCopyable {
#define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
static void TestName(); \
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 \
static void TestName()
#define INTERNAL_CATCH_TESTCASE( ... ) \
@@ -580,7 +608,7 @@ struct AutoReg : NonCopyable {
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
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
// end catch_test_registry.h
@@ -1776,7 +1804,7 @@ namespace Catch {
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
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() ); \
INTERNAL_CATCH_REACT( catchAssertionHandler ) \
} while( false )
@@ -1848,19 +1876,22 @@ namespace Catch {
namespace Catch {
struct SectionInfo {
+ SectionInfo
+ ( SourceLineInfo const& _lineInfo,
+ std::string const& _name );
+
+ // Deprecated
SectionInfo
( SourceLineInfo const& _lineInfo,
std::string const& _name,
- std::string const& _description = std::string() );
+ std::string const& ) : SectionInfo( _lineInfo, _name ) {}
std::string name;
- std::string description;
+ std::string description; // !Deprecated: this will always be empty
SourceLineInfo lineInfo;
};
struct SectionEndInfo {
- SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds );
-
SectionInfo sectionInfo;
Counts prevAssertions;
double durationInSeconds;
@@ -1914,8 +1945,15 @@ 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
// start catch_benchmark.h
@@ -2102,6 +2140,8 @@ namespace Detail {
static Approx custom();
+ Approx operator-() const;
+
template ::value>::type>
Approx operator()( T const& value ) {
Approx approx( static_cast(value) );
@@ -2197,7 +2237,12 @@ namespace Detail {
double m_scale;
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<>
struct StringMaker {
@@ -2962,7 +3007,7 @@ namespace Catch {
std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
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++;
}
}
@@ -3586,6 +3631,7 @@ namespace Catch {
struct ReporterPreferences {
bool shouldRedirectStdOut = false;
+ bool shouldReportAllAssertions = false;
};
template
@@ -4676,6 +4722,12 @@ namespace Detail {
return Approx( 0 );
}
+ Approx Approx::operator-() const {
+ auto temp(*this);
+ temp.m_value = -temp.m_value;
+ return temp;
+ }
+
std::string Approx::toString() const {
ReusableStringStream rss;
rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
@@ -4690,6 +4742,15 @@ 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::convert(Catch::Detail::Approx const& value) {
return value.toString();
}
@@ -4998,9 +5059,11 @@ namespace Catch {
// end catch_run_context.h
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 )
@@ -7530,8 +7593,11 @@ namespace Catch {
using Reporters = std::vector;
Reporters m_listeners;
IStreamingReporterPtr m_reporter = nullptr;
+ ReporterPreferences m_preferences;
public:
+ ListeningReporter();
+
void addListener( IStreamingReporterPtr&& listener );
void addReporter( IStreamingReporterPtr&& reporter );
@@ -8260,6 +8326,8 @@ namespace Catch {
auto str() const -> std::string;
};
+#if defined(CATCH_CONFIG_NEW_CAPTURE)
+
// Windows's implementation of std::tmpfile is terrible (it tries
// to create a file inside system folder, thus requiring elevated
// privileges for the binary), so we have to use tmpnam(_s) and
@@ -8303,6 +8371,8 @@ namespace Catch {
std::string& m_stderrDest;
};
+#endif
+
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
@@ -8313,13 +8383,15 @@ namespace Catch {
#include
#include
-#if defined(_MSC_VER)
-#include //_dup and _dup2
-#define dup _dup
-#define dup2 _dup2
-#define fileno _fileno
-#else
-#include // dup and dup2
+#if defined(CATCH_CONFIG_NEW_CAPTURE)
+ #if defined(_MSC_VER)
+ #include //_dup and _dup2
+ #define dup _dup
+ #define dup2 _dup2
+ #define fileno _fileno
+ #else
+ #include // dup and dup2
+ #endif
#endif
namespace Catch {
@@ -8345,6 +8417,8 @@ namespace Catch {
{}
auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }
+#if defined(CATCH_CONFIG_NEW_CAPTURE)
+
#if defined(_MSC_VER)
TempFile::TempFile() {
if (tmpnam_s(m_buffer)) {
@@ -8417,12 +8491,16 @@ namespace Catch {
m_stderrDest += m_stderrFile.getContents();
}
+#endif // CATCH_CONFIG_NEW_CAPTURE
+
} // 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
// end catch_output_redirect.cpp
// start catch_random_number_generator.cpp
@@ -8430,53 +8508,36 @@ namespace Catch {
// start catch_random_number_generator.h
#include
+#include
namespace Catch {
struct IConfig;
+ std::mt19937& rng();
void seedRng( IConfig const& config );
-
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
- static void shuffle( V& vector ) {
- RandomNumberGenerator rng;
- std::shuffle( vector.begin(), vector.end(), rng );
- }
- };
-
}
// end catch_random_number_generator.h
-#include
-
namespace Catch {
- void seedRng( IConfig const& config ) {
- if( config.rngSeed() != 0 )
- std::srand( config.rngSeed() );
+ std::mt19937& rng() {
+ static std::mt19937 s_rng;
+ return s_rng;
}
+
+ void seedRng( IConfig const& config ) {
+ if( config.rngSeed() != 0 ) {
+ std::srand( config.rngSeed() );
+ rng().seed( config.rngSeed() );
+ }
+ }
+
unsigned int 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
// start catch_registry_hub.cpp
@@ -8759,7 +8820,7 @@ namespace Catch {
m_config(_config),
m_reporter(std::move(reporter)),
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.setConfig(m_config);
@@ -8949,7 +9010,7 @@ namespace Catch {
// Recreate section for test case (as we will lose the one that was in scope)
auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
- SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);
+ SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
Counts assertions;
assertions.failed = 1;
@@ -8987,7 +9048,7 @@ namespace Catch {
void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
- SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);
+ SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
m_reporter->sectionStarting(testCaseSection);
Counts prevAssertions = m_totals.assertions;
double duration = 0;
@@ -9182,7 +9243,7 @@ namespace Catch {
Section::~Section() {
if( m_sectionIncluded ) {
- SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
+ SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };
if( uncaught_exceptions() )
getResultCapture().sectionEndedEarly( endInfo );
else
@@ -9203,17 +9264,11 @@ namespace Catch {
SectionInfo::SectionInfo
( SourceLineInfo const& _lineInfo,
- std::string const& _name,
- std::string const& _description )
+ std::string const& _name )
: name( _name ),
- description( _description ),
lineInfo( _lineInfo )
{}
- SectionEndInfo::SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
- : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
- {}
-
} // end namespace Catch
// end catch_section_info.cpp
// start catch_session.cpp
@@ -9774,6 +9829,12 @@ namespace Catch {
namespace Catch {
+ namespace {
+ char toLowerCh(char c) {
+ return static_cast( std::tolower( c ) );
+ }
+ }
+
bool startsWith( std::string const& s, std::string const& prefix ) {
return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
}
@@ -9789,9 +9850,6 @@ namespace Catch {
bool contains( std::string const& s, std::string const& infix ) {
return s.find( infix ) != std::string::npos;
}
- char toLowerCh(char c) {
- return static_cast( std::tolower( c ) );
- }
void toLowerInPlace( std::string& s ) {
std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
}
@@ -10033,31 +10091,33 @@ 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::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(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::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(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,
@@ -10205,7 +10265,7 @@ namespace Catch {
break;
case RunTests::InRandomOrder:
seedRng( config );
- RandomNumberGenerator::shuffle( sorted );
+ std::shuffle( sorted.begin(), sorted.end(), rng() );
break;
case RunTests::InDeclarationOrder:
// already in declaration order
@@ -10348,8 +10408,8 @@ namespace TestCaseTracking {
TrackerBase::TrackerHasName::TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {}
bool TrackerBase::TrackerHasName::operator ()( ITrackerPtr const& tracker ) const {
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 )
@@ -10733,34 +10793,36 @@ namespace Catch {
return std::chrono::duration_cast( 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 {
static auto s_resolution = estimateClockResolution();
@@ -11004,8 +11066,8 @@ std::string StringMaker::convert(double value) {
std::string ratio_string::symbol() { return "a"; }
std::string ratio_string::symbol() { return "f"; }
-std::string ratio_string::symbol() { return "p"; }
-std::string ratio_string::symbol() { return "n"; }
+std::string ratio_string::symbol() { return "p"; }
+std::string ratio_string::symbol() { return "n"; }
std::string ratio_string::symbol() { return "u"; }
std::string ratio_string::symbol() { return "m"; }
@@ -11117,7 +11179,7 @@ namespace Catch {
}
Version const& libraryVersion() {
- static Version version( 2, 2, 3, "", 0 );
+ static Version version( 2, 3, 0, "", 0 );
return version;
}
@@ -11719,9 +11781,7 @@ private:
}
ReporterPreferences CompactReporter::getPreferences() const {
- ReporterPreferences prefs;
- prefs.shouldRedirectStdOut = false;
- return prefs;
+ return m_reporterPrefs;
}
void CompactReporter::noMatchingTestCases( std::string const& spec ) {
@@ -12436,6 +12496,7 @@ namespace Catch {
xml( _config.stream() )
{
m_reporterPrefs.shouldRedirectStdOut = true;
+ m_reporterPrefs.shouldReportAllAssertions = true;
}
JunitReporter::~JunitReporter() {}
@@ -12626,6 +12687,11 @@ 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 ) {
m_listeners.push_back( std::move( listener ) );
}
@@ -12633,10 +12699,11 @@ namespace Catch {
void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {
assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
m_reporter = std::move( reporter );
+ m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
}
ReporterPreferences ListeningReporter::getPreferences() const {
- return m_reporter->getPreferences();
+ return m_preferences;
}
std::set ListeningReporter::getSupportedVerbosities() {
@@ -12762,6 +12829,7 @@ namespace Catch {
m_xml(_config.stream())
{
m_reporterPrefs.shouldRedirectStdOut = true;
+ m_reporterPrefs.shouldReportAllAssertions = true;
}
XmlReporter::~XmlReporter() = default;
@@ -12818,8 +12886,7 @@ namespace Catch {
StreamingReporterBase::sectionStarting( sectionInfo );
if( m_sectionDepth++ > 0 ) {
m_xml.startElement( "Section" )
- .writeAttribute( "name", trim( sectionInfo.name ) )
- .writeAttribute( "description", sectionInfo.description );
+ .writeAttribute( "name", trim( sectionInfo.name ) );
writeSourceInfo( sectionInfo.lineInfo );
m_xml.ensureTagClosed();
}
@@ -13061,6 +13128,7 @@ int main (int argc, char * const argv[]) {
#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_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_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__ )
@@ -13070,11 +13138,11 @@ int main (int argc, char * const argv[]) {
// "BDD-style" convenience wrappers
#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_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
#else
@@ -13119,6 +13187,7 @@ int main (int argc, char * const argv[]) {
#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 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_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__ )
@@ -13132,15 +13201,16 @@ int main (int argc, char * const argv[]) {
#define SCENARIO( ... ) TEST_CASE( "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;
-#else
+#else // CATCH_CONFIG_DISABLE
+
//////
// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
#ifdef CATCH_CONFIG_PREFIX_ALL
@@ -13185,6 +13255,7 @@ using Catch::Detail::Approx;
#define CATCH_METHOD_AS_TEST_CASE( method, ... )
#define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
#define CATCH_SECTION( ... )
+#define CATCH_DYNAMIC_SECTION( ... )
#define CATCH_FAIL( ... ) (void)(0)
#define CATCH_FAIL_CHECK( ... ) (void)(0)
#define CATCH_SUCCEED( ... ) (void)(0)
@@ -13243,6 +13314,7 @@ using Catch::Detail::Approx;
#define METHOD_AS_TEST_CASE( method, ... )
#define REGISTER_TEST_CASE( Function, ... ) (void)(0)
#define SECTION( ... )
+#define DYNAMIC_SECTION( ... )
#define FAIL( ... ) (void)(0)
#define FAIL_CHECK( ... ) (void)(0)
#define SUCCEED( ... ) (void)(0)
diff --git a/single_include/catch2/catch_reporter_tap.hpp b/single_include/catch2/catch_reporter_tap.hpp
index 19e54ed1..ccc4051b 100644
--- a/single_include/catch2/catch_reporter_tap.hpp
+++ b/single_include/catch2/catch_reporter_tap.hpp
@@ -30,9 +30,7 @@ namespace Catch {
}
ReporterPreferences getPreferences() const override {
- ReporterPreferences prefs;
- prefs.shouldRedirectStdOut = false;
- return prefs;
+ return m_reporterPrefs;
}
void noMatchingTestCases( std::string const& spec ) override {
diff --git a/test_package/conanfile.py b/test_package/conanfile.py
index 7ed77b5c..b9fc6f91 100644
--- a/test_package/conanfile.py
+++ b/test_package/conanfile.py
@@ -10,7 +10,7 @@ class CatchConanTest(ConanFile):
settings = "os", "compiler", "arch", "build_type"
username = getenv("CONAN_USERNAME", "philsquared")
channel = getenv("CONAN_CHANNEL", "testing")
- requires = "Catch/2.2.3@%s/%s" % (username, channel)
+ requires = "Catch/2.3.0@%s/%s" % (username, channel)
def build(self):
cmake = CMake(self)