diff --git a/CMakeLists.txt b/CMakeLists.txt
index 01024e5c..5087361d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -37,7 +37,7 @@ endif()
project(Catch2
- VERSION 3.0.0 # CML version placeholder, don't delete
+ VERSION 3.0.1 # CML version placeholder, don't delete
LANGUAGES CXX
HOMEPAGE_URL "https://github.com/catchorg/Catch2"
DESCRIPTION "A modern, C++-native, unit test framework."
diff --git a/docs/command-line.md b/docs/command-line.md
index 4b9ec7a0..86b06aa0 100644
--- a/docs/command-line.md
+++ b/docs/command-line.md
@@ -145,7 +145,7 @@ hardcoded into Catch2. Currently there are only 2,
_Note that the reporter might still check the X-prefixed options for
validity, and throw an error if they are wrong._
-> Support for passing arguments to reporters through the `-r`, `--reporter` flag was introduced in Catch2 X.Y.Z
+> Support for passing arguments to reporters through the `-r`, `--reporter` flag was introduced in Catch2 3.0.1
There are multiple built-in reporters, you can see what they do by using the
[`--list-reporter`](command-line.md#listing-available-tests-tags-or-reporters)
@@ -160,7 +160,7 @@ reporter can be provided without the output-file part of reporter spec.
This reporter will use the "default" output destination, based on
the [`-o`, `--out`](#sending-output-to-a-file) option.
-> Support for using multiple different reporters at the same time was [introduced](https://github.com/catchorg/Catch2/pull/2183) in Catch2 X.Y.Z
+> Support for using multiple different reporters at the same time was [introduced](https://github.com/catchorg/Catch2/pull/2183) in Catch2 3.0.1
_Note: There is currently no way to escape `::` in the reporter spec,
@@ -204,9 +204,9 @@ Sometimes this results in a flood of failure messages and you'd rather just see
--list-listeners
```
-> The `--list*` options became customizable through reporters in Catch2 X.Y.Z
+> The `--list*` options became customizable through reporters in Catch2 3.0.1
-> The `--list-listeners` option was added in Catch2 X.Y.Z
+> The `--list-listeners` option was added in Catch2 3.0.1
`--list-tests` lists all registered tests matching specified test spec.
Usually this listing also includes tags, and potentially also other
@@ -230,7 +230,7 @@ Use this option to send all output to a file, instead of stdout. You can
use `-` as the filename to explicitly send the output to stdout (this is
useful e.g. when using multiple reporters).
-> Support for `-` as the filename was introduced in Catch2 X.Y.Z
+> Support for `-` as the filename was introduced in Catch2 3.0.1
Filenames starting with "%" (percent symbol) are reserved by Catch2 for
meta purposes, e.g. using `%debug` as the filename opens stream that
@@ -242,7 +242,7 @@ Catch2 currently recognizes 3 meta streams:
* `%stdout` - writes to stdout
* `%stderr` - writes to stderr
-> Support for `%stdout` and `%stderr` was introduced in Catch2 X.Y.Z
+> Support for `%stdout` and `%stderr` was introduced in Catch2 3.0.1
@@ -290,7 +290,7 @@ There are currently two warnings implemented:
// not match any tests.
```
-> `UnmatchedTestSpec` was introduced in Catch2 X.Y.Z.
+> `UnmatchedTestSpec` was introduced in Catch2 3.0.1.
@@ -388,7 +388,7 @@ either before running any tests, after running all tests - or both, depending on
## Skip all benchmarks
--skip-benchmarks
-> [Introduced](https://github.com/catchorg/Catch2/issues/2408) in Catch X.Y.Z.
+> [Introduced](https://github.com/catchorg/Catch2/issues/2408) in Catch2 3.0.1.
This flag tells Catch2 to skip running all benchmarks. Benchmarks in this
case mean code blocks in `BENCHMARK` and `BENCHMARK_ADVANCED` macros, not
@@ -507,7 +507,7 @@ So, for example, tests within the file `~\Dev\MyProject\Ferrets.cpp` would be t
## Override output colouring
--colour-mode <ansi|win32|none|default>
-> The `--colour-mode` option replaced the old `--colour` option in Catch2 X.Y.Z
+> The `--colour-mode` option replaced the old `--colour` option in Catch2 3.0.1
Catch2 support two different ways of colouring terminal output, and by
@@ -531,7 +531,7 @@ when writing to a file
## Test Sharding
--shard-count <#number of shards>, --shard-index <#shard index to run>
-> [Introduced](https://github.com/catchorg/Catch2/pull/2257) in Catch2 X.Y.Z.
+> [Introduced](https://github.com/catchorg/Catch2/pull/2257) in Catch2 3.0.1.
When `--shard-count <#number of shards>` is used, the tests to execute will be split evenly in to the given number of sets,
identified by indicies starting at 0. The tests in the set given by `--shard-index <#shard index to run>` will be executed.
@@ -544,7 +544,7 @@ This is useful when you want to split test execution across multiple processes,
## Allow running the binary without tests
--allow-running-no-tests
-> Introduced in Catch2 X.Y.Z.
+> Introduced in Catch2 3.0.1.
By default, Catch2 test binaries return non-0 exit code if no tests were
run, e.g. if the binary was compiled with no tests, or the provided test
diff --git a/docs/configuration.md b/docs/configuration.md
index dc7178c7..d5463343 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -101,7 +101,7 @@ is equivalent with the out-of-the-box experience.
When `CATCH_CONFIG_BAZEL_SUPPORT` is defined, Catch2 will register a `JUnit`
reporter writing to a path pointed by `XML_OUTPUT_FILE` provided by Bazel.
-> `CATCH_CONFIG_BAZEL_SUPPORT` was [introduced](https://github.com/catchorg/Catch2/pull/2399) in Catch2 X.Y.Z.
+> `CATCH_CONFIG_BAZEL_SUPPORT` was [introduced](https://github.com/catchorg/Catch2/pull/2399) in Catch2 3.0.1.
## C++11 toggles
diff --git a/docs/matchers.md b/docs/matchers.md
index e76d8490..3d0f8f11 100644
--- a/docs/matchers.md
+++ b/docs/matchers.md
@@ -248,7 +248,7 @@ Note that `DerivedException` in the example above has to derive from
### Generic range Matchers
-> Generic range matchers were introduced in Catch2 X.Y.Z
+> Generic range matchers were introduced in Catch2 3.0.1
Catch2 also provides some matchers that use the new style matchers
definitions to handle generic range-like types. These are:
@@ -350,7 +350,7 @@ style matchers arbitrarily.
## Writing custom matchers (new style)
-> New style matchers were introduced in Catch2 X.Y.Z
+> New style matchers were introduced in Catch2 3.0.1
To create a new-style matcher, you have to create your own type that
derives from `Catch::Matchers::MatcherGenericBase`. Your type has to
diff --git a/docs/other-macros.md b/docs/other-macros.md
index ce33c1d8..24a0fb6e 100644
--- a/docs/other-macros.md
+++ b/docs/other-macros.md
@@ -15,7 +15,7 @@ stringification machinery to the _expr_ and records the result. As with
evaluates to `true`. `CHECKED_ELSE( expr )` work similarly, but the block
is entered only if the _expr_ evaluated to `false`.
-> `CHECKED_X` macros were changed to not count as failure in Catch2 X.Y.Z.
+> `CHECKED_X` macros were changed to not count as failure in Catch2 3.0.1.
Example:
```cpp
@@ -77,7 +77,7 @@ TEST_CASE("STATIC_REQUIRE showcase", "[traits]") {
}
```
-> `STATIC_CHECK` was [introduced](https://github.com/catchorg/Catch2/pull/2318) in Catch2 X.Y.Z.
+> `STATIC_CHECK` was [introduced](https://github.com/catchorg/Catch2/pull/2318) in Catch2 3.0.1.
`STATIC_CHECK( expr )` is equivalent to `STATIC_REQUIRE( expr )`, with the
difference that when `CATCH_CONFIG_RUNTIME_STATIC_REQUIRE` is defined, it
diff --git a/docs/release-notes.md b/docs/release-notes.md
index 1b0188b4..3a5de276 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -2,7 +2,7 @@
# Release notes
**Contents**
-[3.0.1 (in progress)](#301-in-progress)
+[3.0.1](#301)
[2.13.7](#2137)
[2.13.6](#2136)
[2.13.5](#2135)
@@ -49,7 +49,7 @@
[Even Older versions](#even-older-versions)
-## 3.0.1 (in progress)
+## 3.0.1
**Catch2 now uses statically compiled library as its distribution model.
This also means that to get all of Catch2's functionality in a test file,
@@ -206,6 +206,7 @@ v3 releases.
* The cumulative reporter base stores benchmark results alongside assertion results
* Catch2's SE handling should no longer interferes with ASan on Windows (#2334)
* Fixed Windows console colour handling for tests that redirect stdout (#2345)
+* Fixed issue with the `random` generators returning the same value over and over again
### Other changes
@@ -230,6 +231,7 @@ v3 releases.
* `-DCATCH_CONFIG_ANDROID_LOGWRITE=OFF` does nothing (the define will not exist)
+
## 2.13.7
### Fixes
diff --git a/docs/reporter-events.md b/docs/reporter-events.md
index 3641656a..7adae53c 100644
--- a/docs/reporter-events.md
+++ b/docs/reporter-events.md
@@ -56,7 +56,7 @@ are handled by a different event.
### `testCasePartial` events
-> Introduced in Catch2 X.Y.Z
+> Introduced in Catch2 3.0.1
```cpp
void testCasePartialStarting( TestCaseInfo const& testInfo, uint64_t partNumber );
@@ -135,7 +135,7 @@ benchmarking itself fails.
## Listings events
-> Introduced in Catch2 X.Y.Z.
+> Introduced in Catch2 3.0.1.
Listings events are events that correspond to the test binary being
invoked with `--list-foo` flag.
diff --git a/docs/reporters.md b/docs/reporters.md
index 5f86b02e..496c61a9 100644
--- a/docs/reporters.md
+++ b/docs/reporters.md
@@ -30,7 +30,7 @@ reporters](#multiple-reporters) to avoid any surprises from doing so.
## Using multiple reporters
-> Support for having multiple parallel reporters was [introduced](https://github.com/catchorg/Catch2/pull/2183) in Catch2 X.Y.Z
+> Support for having multiple parallel reporters was [introduced](https://github.com/catchorg/Catch2/pull/2183) in Catch2 3.0.1
Catch2 supports using multiple reporters at the same time while having
them write into different destinations. The two main uses of this are
@@ -169,7 +169,7 @@ Currently there are two customization options:
### Per-reporter configuration
-> Per-reporter configuration was introduced in Catch2 X.Y.Z
+> Per-reporter configuration was introduced in Catch2 3.0.1
Catch2 supports some configuration to happen per reporter. The configuration
options fall into one of two categories:
diff --git a/extras/catch_amalgamated.cpp b/extras/catch_amalgamated.cpp
index 58a1c7d5..bd8c8119 100644
--- a/extras/catch_amalgamated.cpp
+++ b/extras/catch_amalgamated.cpp
@@ -5,8 +5,8 @@
// SPDX-License-Identifier: BSL-1.0
-// Catch v3.0.0-preview.5
-// Generated: 2022-04-20 23:45:15.004945
+// Catch v3.0.1
+// Generated: 2022-05-17 22:08:47.054486
// ----------------------------------------------------------
// This file is an amalgamation of multiple different files.
// You probably shouldn't edit it directly.
@@ -145,6 +145,15 @@ namespace Catch {
namespace Benchmark {
namespace Detail {
+#if defined( __GNUC__ ) || defined( __clang__ )
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+ bool directCompare( double lhs, double rhs ) { return lhs == rhs; }
+#if defined( __GNUC__ ) || defined( __clang__ )
+# pragma GCC diagnostic pop
+#endif
+
double weighted_average_quantile(int k, int q, std::vector::iterator first, std::vector::iterator last) {
auto count = last - first;
double idx = (count - 1) * k / static_cast(q);
@@ -152,7 +161,9 @@ namespace Catch {
double g = idx - j;
std::nth_element(first, first + j, last);
auto xj = first[j];
- if (g == 0) return xj;
+ if ( directCompare( g, 0 ) ) {
+ return xj;
+ }
auto xj1 = *std::min_element(first + (j + 1), last);
return xj + g * (xj1 - xj);
@@ -594,6 +605,7 @@ namespace Catch {
bool Config::listTests() const { return m_data.listTests; }
bool Config::listTags() const { return m_data.listTags; }
bool Config::listReporters() const { return m_data.listReporters; }
+ bool Config::listListeners() const { return m_data.listListeners; }
std::vector const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
std::vector const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
@@ -635,6 +647,7 @@ namespace Catch {
bool Config::showInvisibles() const { return m_data.showInvisibles; }
Verbosity Config::verbosity() const { return m_data.verbosity; }
+ bool Config::skipBenchmarks() const { return m_data.skipBenchmarks; }
bool Config::benchmarkNoAnalysis() const { return m_data.benchmarkNoAnalysis; }
unsigned int Config::benchmarkSamples() const { return m_data.benchmarkSamples; }
double Config::benchmarkConfidenceInterval() const { return m_data.benchmarkConfidenceInterval; }
@@ -1215,7 +1228,7 @@ namespace Catch {
else if( tag == "!nonportable"_sr )
return TestCaseProperties::NonPortable;
else if( tag == "!benchmark"_sr )
- return static_cast(TestCaseProperties::Benchmark | TestCaseProperties::IsHidden );
+ return TestCaseProperties::Benchmark | TestCaseProperties::IsHidden;
else
return TestCaseProperties::None;
}
@@ -1860,13 +1873,19 @@ namespace Catch {
}
Version const& libraryVersion() {
- static Version version( 3, 0, 0, "preview", 5 );
+ static Version version( 3, 0, 1, "", 0 );
return version;
}
}
+
+
+
+std::uint32_t Catch::Generators::Detail::getSeed() { return sharedRng()(); }
+
+
/** \file
* This is a special TU that combines what would otherwise be a very
* small generator-related TUs into one bigger TU.
@@ -2001,6 +2020,32 @@ namespace Catch {
+#include
+
+namespace Catch {
+ namespace Generators {
+
+ bool GeneratorUntypedBase::countedNext() {
+ auto ret = next();
+ if ( ret ) {
+ m_stringReprCache.clear();
+ ++m_currentElementIndex;
+ }
+ return ret;
+ }
+
+ StringRef GeneratorUntypedBase::currentElementAsString() const {
+ if ( m_stringReprCache.empty() ) {
+ m_stringReprCache = stringifyImpl();
+ }
+ return m_stringReprCache;
+ }
+
+ } // namespace Generators
+} // namespace Catch
+
+
+
#include
#include
#include
@@ -2412,7 +2457,7 @@ namespace Catch {
return Detail::InternalParseResult::runtimeError(
"Expected argument following " +
token.token);
- auto result = valueRef->setValue(argToken.token);
+ const auto result = valueRef->setValue(argToken.token);
if (!result)
return Detail::InternalParseResult(result);
if (result.value() ==
@@ -3109,7 +3154,10 @@ namespace Catch {
( "list all/matching tags" )
| Opt( config.listReporters )
["--list-reporters"]
- ( "list all reporters" )
+ ( "list all available reporters" )
+ | Opt( config.listListeners )
+ ["--list-listeners"]
+ ( "list all listeners" )
| Opt( setTestOrder, "decl|lex|rand" )
["--order"]
( "test case order (defaults to decl)" )
@@ -3125,6 +3173,9 @@ namespace Catch {
| Opt( setWaitForKeypress, "never|start|exit|both" )
["--wait-for-keypress"]
( "waits for a keypress before exiting" )
+ | Opt( config.skipBenchmarks)
+ ["--skip-benchmarks"]
+ ( "disable running benchmarks")
| Opt( config.benchmarkSamples, "samples" )
["--benchmark-samples"]
( "number of samples to collect (default: 100)" )
@@ -3230,7 +3281,6 @@ namespace Catch {
class NoColourImpl : public ColourImpl {
public:
NoColourImpl( IStream* stream ): ColourImpl( stream ) {}
- static bool useColourOnPlatform() { return true; }
private:
void use( Colour::Code ) const override {}
@@ -3257,7 +3307,7 @@ namespace {
originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
}
- static bool useColourOnPlatform(IStream const& stream) {
+ static bool useImplementationForStream(IStream const& stream) {
// Win32 text colour APIs can only be used on console streams
// We cannot check that the output hasn't been redirected,
// so we just check that the original stream is console stream.
@@ -3316,7 +3366,7 @@ namespace {
public:
ANSIColourImpl( IStream* stream ): ColourImpl( stream ) {}
- static bool useColourOnPlatform(IStream const& stream) {
+ static bool useImplementationForStream(IStream const& stream) {
// This is kinda messy due to trying to support a bunch of
// different platforms at once.
// The basic idea is that if we are asked to do autodetection (as
@@ -3390,13 +3440,13 @@ namespace Catch {
// todo: check win32 eligibility under ifdef, otherwise ansi
if ( implSelection == ColourMode::PlatformDefault) {
#if defined (CATCH_CONFIG_COLOUR_WIN32)
- if ( Win32ColourImpl::useColourOnPlatform( *stream ) ) {
+ if ( Win32ColourImpl::useImplementationForStream( *stream ) ) {
return Detail::make_unique( stream );
} else {
return Detail::make_unique( stream );
}
#endif
- if ( ANSIColourImpl::useColourOnPlatform( *stream ) ) {
+ if ( ANSIColourImpl::useImplementationForStream( *stream ) ) {
return Detail::make_unique( stream );
}
return Detail::make_unique( stream );
@@ -3475,7 +3525,7 @@ namespace Catch {
Context::~Context() = default;
- SimplePcg32& rng() {
+ SimplePcg32& sharedRng() {
static SimplePcg32 s_rng;
return s_rng;
}
@@ -4079,7 +4129,7 @@ namespace Detail {
setp( data, data + sizeof(data) );
}
- ~StreamBufImpl() noexcept {
+ ~StreamBufImpl() noexcept override {
StreamBufImpl::sync();
}
@@ -4250,6 +4300,19 @@ namespace Catch {
reporter.listReporters(descriptions);
}
+ void listListeners(IEventListener& reporter) {
+ std::vector descriptions;
+
+ auto const& factories =
+ getRegistryHub().getReporterRegistry().getListeners();
+ descriptions.reserve( factories.size() );
+ for ( auto const& fac : factories ) {
+ descriptions.push_back( { fac->getName(), fac->getDescription() } );
+ }
+
+ reporter.listListeners( descriptions );
+ }
+
} // end anonymous namespace
void TagInfo::add( StringRef spelling ) {
@@ -4287,6 +4350,10 @@ namespace Catch {
listed = true;
listReporters(reporter);
}
+ if ( config.listListeners() ) {
+ listed = true;
+ listListeners( reporter );
+ }
return listed;
}
@@ -4297,7 +4364,7 @@ namespace Catch {
namespace Catch {
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
- LeakDetector leakDetector;
+ static LeakDetector leakDetector;
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
}
@@ -4581,7 +4648,8 @@ namespace Catch {
void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr factory ) {
CATCH_ENFORCE( name.find( "::" ) == name.npos,
"'::' is not allowed in reporter name: '" + name + '\'' );
- m_factories.emplace(name, CATCH_MOVE(factory));
+ auto ret = m_factories.emplace(name, CATCH_MOVE(factory));
+ CATCH_ENFORCE( ret.second, "reporter using '" + name + "' as name was already registered" );
}
void ReporterRegistry::registerListener(
Detail::unique_ptr factory ) {
@@ -4851,7 +4919,7 @@ namespace Catch {
GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
: TrackerBase( nameAndLocation, ctx, parent )
{}
- ~GeneratorTracker();
+ ~GeneratorTracker() override;
static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
GeneratorTracker* tracker;
@@ -4962,7 +5030,7 @@ namespace Catch {
// this generator is still waiting for any child to start.
if ( should_wait_for_child ||
( m_runState == CompletedSuccessfully &&
- m_generator->next() ) ) {
+ m_generator->countedNext() ) ) {
m_children.clear();
m_runState = Executing;
}
@@ -5012,6 +5080,39 @@ namespace Catch {
assert(rootTracker.isSectionTracker());
static_cast(rootTracker).addInitialFilters(m_config->getSectionsToRun());
+ // We intentionally only seed the internal RNG once per test case,
+ // before it is first invoked. The reason for that is a complex
+ // interplay of generator/section implementation details and the
+ // Random*Generator types.
+ //
+ // The issue boils down to us needing to seed the Random*Generators
+ // with different seed each, so that they return different sequences
+ // of random numbers. We do this by giving them a number from the
+ // shared RNG instance as their seed.
+ //
+ // However, this runs into an issue if the reseeding happens each
+ // time the test case is entered (as opposed to first time only),
+ // because multiple generators could get the same seed, e.g. in
+ // ```cpp
+ // TEST_CASE() {
+ // auto i = GENERATE(take(10, random(0, 100));
+ // SECTION("A") {
+ // auto j = GENERATE(take(10, random(0, 100));
+ // }
+ // SECTION("B") {
+ // auto k = GENERATE(take(10, random(0, 100));
+ // }
+ // }
+ // ```
+ // `i` and `j` would properly return values from different sequences,
+ // but `i` and `k` would return the same sequence, because their seed
+ // would be the same.
+ // (The reason their seeds would be the same is that the generator
+ // for k would be initialized when the test case is entered the second
+ // time, after the shared RNG instance was reset to the same value
+ // it had when the generator for i was initialized.)
+ seedRng( *m_config );
+
uint64_t testRuns = 0;
do {
m_trackerContext.startCycle();
@@ -5241,8 +5342,6 @@ namespace Catch {
m_shouldReportUnexpected = true;
m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };
- seedRng(*m_config);
-
Timer timer;
CATCH_TRY {
if (m_reporter->getPreferences().shouldRedirectStdOut) {
@@ -5417,10 +5516,7 @@ namespace Catch {
}
void seedRng(IConfig const& config) {
- if (config.rngSeed() != 0) {
- std::srand(config.rngSeed());
- rng().seed(config.rngSeed());
- }
+ sharedRng().seed(config.rngSeed());
}
unsigned int rngSeed() {
@@ -5642,7 +5738,7 @@ namespace Catch {
namespace Catch {
StringRef::StringRef( char const* rawChars ) noexcept
- : StringRef( rawChars, static_cast(std::strlen(rawChars) ) )
+ : StringRef( rawChars, std::strlen(rawChars) )
{}
auto StringRef::operator == ( StringRef other ) const noexcept -> bool {
@@ -7213,14 +7309,26 @@ namespace Detail {
ret << " ([";
if (m_type == Detail::FloatingPointKind::Double) {
- write(ret, step(m_target, static_cast(-INFINITY), m_ulps));
+ write( ret,
+ step( m_target,
+ -std::numeric_limits::infinity(),
+ m_ulps ) );
ret << ", ";
- write(ret, step(m_target, static_cast( INFINITY), m_ulps));
+ write( ret,
+ step( m_target,
+ std::numeric_limits::infinity(),
+ m_ulps ) );
} else {
// We have to cast INFINITY to float because of MinGW, see #1782
- write(ret, step(static_cast(m_target), static_cast(-INFINITY), m_ulps));
+ write( ret,
+ step( static_cast( m_target ),
+ -std::numeric_limits::infinity(),
+ m_ulps ) );
ret << ", ";
- write(ret, step(static_cast(m_target), static_cast( INFINITY), m_ulps));
+ write( ret,
+ step( static_cast( m_target ),
+ std::numeric_limits::infinity(),
+ m_ulps ) );
}
ret << "])";
@@ -7706,6 +7814,33 @@ namespace Catch {
out << '\n' << std::flush;
}
+ void defaultListListeners( std::ostream& out,
+ std::vector const& descriptions ) {
+ const auto maxNameLen =
+ std::max_element( descriptions.begin(),
+ descriptions.end(),
+ []( ListenerDescription const& lhs,
+ ListenerDescription const& rhs ) {
+ return lhs.name.size() < rhs.name.size();
+ } )
+ ->name.size();
+
+ out << "Registered listeners:\n";
+ for ( auto const& desc : descriptions ) {
+ out << TextFlow::Column( static_cast( desc.name ) +
+ ':' )
+ .indent( 2 )
+ .width( maxNameLen + 5 ) +
+ TextFlow::Column( desc.description )
+ .initialIndent( 0 )
+ .indent( 2 )
+ .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen - 8 )
+ << '\n';
+ }
+
+ out << '\n' << std::flush;
+ }
+
void defaultListTags( std::ostream& out,
std::vector const& tags,
bool isFiltered ) {
@@ -7786,6 +7921,8 @@ namespace Catch {
void EventListenerBase::assertionEnded( AssertionStats const& ) {}
void EventListenerBase::listReporters(
std::vector const& ) {}
+ void EventListenerBase::listListeners(
+ std::vector const& ) {}
void EventListenerBase::listTests( std::vector const& ) {}
void EventListenerBase::listTags( std::vector const& ) {}
void EventListenerBase::noMatchingTestCases( StringRef ) {}
@@ -7822,6 +7959,11 @@ namespace Catch {
defaultListReporters(m_stream, descriptions, m_config->verbosity());
}
+ void ReporterBase::listListeners(
+ std::vector const& descriptions ) {
+ defaultListListeners( m_stream, descriptions );
+ }
+
void ReporterBase::listTests(std::vector const& tests) {
defaultListTests(m_stream,
m_colour.get(),
@@ -9415,6 +9557,13 @@ namespace Catch {
}
}
+ void MultiReporter::listListeners(
+ std::vector const& descriptions ) {
+ for ( auto& reporterish : m_reporterLikes ) {
+ reporterish->listListeners( descriptions );
+ }
+ }
+
void MultiReporter::listTests(std::vector const& tests) {
for (auto& reporterish : m_reporterLikes) {
reporterish->listTests(tests);
@@ -9432,6 +9581,29 @@ namespace Catch {
+
+namespace Catch {
+ namespace Detail {
+
+ void registerReporterImpl( std::string const& name,
+ IReporterFactoryPtr reporterPtr ) {
+ CATCH_TRY {
+ getMutableRegistryHub().registerReporter(
+ name, CATCH_MOVE( reporterPtr ) );
+ }
+ CATCH_CATCH_ALL {
+ // Do not throw when constructing global objects, instead
+ // register the exception to be processed later
+ getMutableRegistryHub().registerStartupException();
+ }
+ }
+
+ } // namespace Detail
+} // namespace Catch
+
+
+
+
#include