Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMartin Hořeňovský2023-07-13 13:37:30 +0200
committerMartin Hořeňovský2023-07-13 13:37:30 +0200
commit6e79e682b726f524310d55dec8ddac4e9c52fb5f (patch)
treef399bdefd6361f173bb36f611d14ee5665e81383
parent683c85772f65a8779e3baf45d3402098db58bb8d (diff)
downloadcatch3-3.4.0.tar.gz
v3.4.0v3.4.0
-rw-r--r--CMakeLists.txt2
-rw-r--r--docs/configuration.md2
-rw-r--r--docs/release-notes.md28
-rw-r--r--extras/catch_amalgamated.cpp1052
-rw-r--r--extras/catch_amalgamated.hpp2517
-rw-r--r--meson.build2
-rw-r--r--src/catch2/catch_version.cpp2
-rw-r--r--src/catch2/catch_version_macros.hpp4
8 files changed, 1974 insertions, 1635 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5ef06de7..42f65237 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -32,7 +32,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
endif()
project(Catch2
- VERSION 3.3.2 # CML version placeholder, don't delete
+ VERSION 3.4.0 # CML version placeholder, don't delete
LANGUAGES CXX
# HOMEPAGE_URL is not supported until CMake version 3.12, which
# we do not target yet.
diff --git a/docs/configuration.md b/docs/configuration.md
index d6e159e5..49b8ed9d 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -267,7 +267,7 @@ must compile and must break into debugger.
## Static analysis support
-> Introduced in Catch2 X.Y.Z.
+> Introduced in Catch2 3.4.0.
Some parts of Catch2, e.g. `SECTION`s, can be hard for static analysis
tools to reason about. Catch2 can change its internals to help static
diff --git a/docs/release-notes.md b/docs/release-notes.md
index 8b413b15..a5911862 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -57,6 +57,34 @@
+## 3.4.0
+
+### Improvements
+* `VectorEquals` supports elements that provide only `==` and not `!=` (#2648)
+* Catch2 supports compiling with IAR compiler (#2651)
+* Various small internal performance improvements
+* Various small internal compilation time improvements
+* XMLReporter now reports location info for INFO and WARN (#1251)
+ * This bumps up the xml format version to 3
+* Documented that `SKIP` in generator constructor can be used to handle empty generator (#1593)
+* Added experimental static analysis support to `TEST_CASE` and `SECTION` macros (#2681)
+ * The two macros are redefined in a way that helps the SA tools reason about the possible paths through a test case with sections.
+ * The support is controlled by the `CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT` option and autodetects clang-tidy and Coverity.
+* `*_THROWS`, `*_THROWS_AS`, etc now suppress warning coming from `__attribute__((warn_unused_result))` on GCC (#2691)
+ * Unlike plain `[[nodiscard]]`, this warning is not silenced by void cast. WTF GCC?
+
+### Fixes
+* Fixed `assertionStarting` events being sent after the expr is evaluated (#2678)
+* Errors in `TEST_CASE` tags are now reported nicely (#2650)
+
+### Miscellaneous
+* Bunch of improvements to `catch_discover_tests`
+ * Added DISCOVERY_MODE option, so the discovery can happen either post build or pre-run.
+ * Fixed handling of semicolons and backslashes in test names (#2674, #2676)
+* meson build can disable building tests (#2693)
+* meson build properly sets meson version 0.54.1 as the minimal supported version (#2688)
+
+
## 3.3.2
### Improvements
diff --git a/extras/catch_amalgamated.cpp b/extras/catch_amalgamated.cpp
index a81b1b6a..eba3f00a 100644
--- a/extras/catch_amalgamated.cpp
+++ b/extras/catch_amalgamated.cpp
@@ -5,8 +5,8 @@
// SPDX-License-Identifier: BSL-1.0
-// Catch v3.3.2
-// Generated: 2023-02-26 10:28:48.270752
+// Catch v3.4.0
+// Generated: 2023-07-13 13:23:09.554273
// ----------------------------------------------------------
// This file is an amalgamation of multiple different files.
// You probably shouldn't edit it directly.
@@ -60,6 +60,7 @@ namespace Catch {
+
#include <exception>
namespace Catch {
@@ -88,7 +89,7 @@ namespace Catch {
#include <cassert>
#include <cstddef>
-#include <iterator>
+#include <numeric>
#include <random>
@@ -96,117 +97,172 @@ namespace Catch {
#include <future>
#endif
-namespace {
+namespace Catch {
+ namespace Benchmark {
+ namespace Detail {
+ namespace {
+
+ template <typename URng, typename Estimator>
+ static sample
+ resample( URng& rng,
+ unsigned int resamples,
+ std::vector<double>::const_iterator first,
+ std::vector<double>::const_iterator last,
+ Estimator& estimator ) {
+ auto n = static_cast<size_t>( last - first );
+ std::uniform_int_distribution<decltype( n )> dist( 0,
+ n - 1 );
+
+ sample out;
+ out.reserve( resamples );
+ // We allocate the vector outside the loop to avoid realloc
+ // per resample
+ std::vector<double> resampled;
+ resampled.reserve( n );
+ for ( size_t i = 0; i < resamples; ++i ) {
+ resampled.clear();
+ for ( size_t s = 0; s < n; ++s ) {
+ resampled.push_back(
+ first[static_cast<std::ptrdiff_t>(
+ dist( rng ) )] );
+ }
+ const auto estimate =
+ estimator( resampled.begin(), resampled.end() );
+ out.push_back( estimate );
+ }
+ std::sort( out.begin(), out.end() );
+ return out;
+ }
-using Catch::Benchmark::Detail::sample;
-
- template <typename URng, typename Estimator>
- sample resample(URng& rng, unsigned int resamples, std::vector<double>::iterator first, std::vector<double>::iterator last, Estimator& estimator) {
- auto n = static_cast<size_t>(last - first);
- std::uniform_int_distribution<decltype(n)> dist(0, n - 1);
-
- sample out;
- out.reserve(resamples);
- std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] {
- std::vector<double> resampled;
- resampled.reserve(n);
- std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[static_cast<std::ptrdiff_t>(dist(rng))]; });
- return estimator(resampled.begin(), resampled.end());
- });
- std::sort(out.begin(), out.end());
- return out;
- }
-
-
- double erf_inv(double x) {
- // Code accompanying the article "Approximating the erfinv function" in GPU Computing Gems, Volume 2
- double w, p;
-
- w = -log((1.0 - x) * (1.0 + x));
-
- if (w < 6.250000) {
- w = w - 3.125000;
- p = -3.6444120640178196996e-21;
- p = -1.685059138182016589e-19 + p * w;
- p = 1.2858480715256400167e-18 + p * w;
- p = 1.115787767802518096e-17 + p * w;
- p = -1.333171662854620906e-16 + p * w;
- p = 2.0972767875968561637e-17 + p * w;
- p = 6.6376381343583238325e-15 + p * w;
- p = -4.0545662729752068639e-14 + p * w;
- p = -8.1519341976054721522e-14 + p * w;
- p = 2.6335093153082322977e-12 + p * w;
- p = -1.2975133253453532498e-11 + p * w;
- p = -5.4154120542946279317e-11 + p * w;
- p = 1.051212273321532285e-09 + p * w;
- p = -4.1126339803469836976e-09 + p * w;
- p = -2.9070369957882005086e-08 + p * w;
- p = 4.2347877827932403518e-07 + p * w;
- p = -1.3654692000834678645e-06 + p * w;
- p = -1.3882523362786468719e-05 + p * w;
- p = 0.0001867342080340571352 + p * w;
- p = -0.00074070253416626697512 + p * w;
- p = -0.0060336708714301490533 + p * w;
- p = 0.24015818242558961693 + p * w;
- p = 1.6536545626831027356 + p * w;
- } else if (w < 16.000000) {
- w = sqrt(w) - 3.250000;
- p = 2.2137376921775787049e-09;
- p = 9.0756561938885390979e-08 + p * w;
- p = -2.7517406297064545428e-07 + p * w;
- p = 1.8239629214389227755e-08 + p * w;
- p = 1.5027403968909827627e-06 + p * w;
- p = -4.013867526981545969e-06 + p * w;
- p = 2.9234449089955446044e-06 + p * w;
- p = 1.2475304481671778723e-05 + p * w;
- p = -4.7318229009055733981e-05 + p * w;
- p = 6.8284851459573175448e-05 + p * w;
- p = 2.4031110387097893999e-05 + p * w;
- p = -0.0003550375203628474796 + p * w;
- p = 0.00095328937973738049703 + p * w;
- p = -0.0016882755560235047313 + p * w;
- p = 0.0024914420961078508066 + p * w;
- p = -0.0037512085075692412107 + p * w;
- p = 0.005370914553590063617 + p * w;
- p = 1.0052589676941592334 + p * w;
- p = 3.0838856104922207635 + p * w;
- } else {
- w = sqrt(w) - 5.000000;
- p = -2.7109920616438573243e-11;
- p = -2.5556418169965252055e-10 + p * w;
- p = 1.5076572693500548083e-09 + p * w;
- p = -3.7894654401267369937e-09 + p * w;
- p = 7.6157012080783393804e-09 + p * w;
- p = -1.4960026627149240478e-08 + p * w;
- p = 2.9147953450901080826e-08 + p * w;
- p = -6.7711997758452339498e-08 + p * w;
- p = 2.2900482228026654717e-07 + p * w;
- p = -9.9298272942317002539e-07 + p * w;
- p = 4.5260625972231537039e-06 + p * w;
- p = -1.9681778105531670567e-05 + p * w;
- p = 7.5995277030017761139e-05 + p * w;
- p = -0.00021503011930044477347 + p * w;
- p = -0.00013871931833623122026 + p * w;
- p = 1.0103004648645343977 + p * w;
- p = 4.8499064014085844221 + p * w;
- }
- return p * x;
- }
-
- double standard_deviation(std::vector<double>::iterator first, std::vector<double>::iterator last) {
- auto m = Catch::Benchmark::Detail::mean(first, last);
- double variance = std::accumulate( first,
- last,
- 0.,
- [m]( double a, double b ) {
- double diff = b - m;
- return a + diff * diff;
- } ) /
- ( last - first );
- return std::sqrt( variance );
- }
+ static double outlier_variance( Estimate<double> mean,
+ Estimate<double> stddev,
+ int n ) {
+ double sb = stddev.point;
+ double mn = mean.point / n;
+ double mg_min = mn / 2.;
+ double sg = (std::min)( mg_min / 4., sb / std::sqrt( n ) );
+ double sg2 = sg * sg;
+ double sb2 = sb * sb;
+
+ auto c_max = [n, mn, sb2, sg2]( double x ) -> double {
+ double k = mn - x;
+ double d = k * k;
+ double nd = n * d;
+ double k0 = -n * nd;
+ double k1 = sb2 - n * sg2 + nd;
+ double det = k1 * k1 - 4 * sg2 * k0;
+ return static_cast<int>( -2. * k0 /
+ ( k1 + std::sqrt( det ) ) );
+ };
+
+ auto var_out = [n, sb2, sg2]( double c ) {
+ double nc = n - c;
+ return ( nc / n ) * ( sb2 - nc * sg2 );
+ };
+
+ return (std::min)( var_out( 1 ),
+ var_out(
+ (std::min)( c_max( 0. ),
+ c_max( mg_min ) ) ) ) /
+ sb2;
+ }
-}
+ static double erf_inv( double x ) {
+ // Code accompanying the article "Approximating the erfinv
+ // function" in GPU Computing Gems, Volume 2
+ double w, p;
+
+ w = -log( ( 1.0 - x ) * ( 1.0 + x ) );
+
+ if ( w < 6.250000 ) {
+ w = w - 3.125000;
+ p = -3.6444120640178196996e-21;
+ p = -1.685059138182016589e-19 + p * w;
+ p = 1.2858480715256400167e-18 + p * w;
+ p = 1.115787767802518096e-17 + p * w;
+ p = -1.333171662854620906e-16 + p * w;
+ p = 2.0972767875968561637e-17 + p * w;
+ p = 6.6376381343583238325e-15 + p * w;
+ p = -4.0545662729752068639e-14 + p * w;
+ p = -8.1519341976054721522e-14 + p * w;
+ p = 2.6335093153082322977e-12 + p * w;
+ p = -1.2975133253453532498e-11 + p * w;
+ p = -5.4154120542946279317e-11 + p * w;
+ p = 1.051212273321532285e-09 + p * w;
+ p = -4.1126339803469836976e-09 + p * w;
+ p = -2.9070369957882005086e-08 + p * w;
+ p = 4.2347877827932403518e-07 + p * w;
+ p = -1.3654692000834678645e-06 + p * w;
+ p = -1.3882523362786468719e-05 + p * w;
+ p = 0.0001867342080340571352 + p * w;
+ p = -0.00074070253416626697512 + p * w;
+ p = -0.0060336708714301490533 + p * w;
+ p = 0.24015818242558961693 + p * w;
+ p = 1.6536545626831027356 + p * w;
+ } else if ( w < 16.000000 ) {
+ w = sqrt( w ) - 3.250000;
+ p = 2.2137376921775787049e-09;
+ p = 9.0756561938885390979e-08 + p * w;
+ p = -2.7517406297064545428e-07 + p * w;
+ p = 1.8239629214389227755e-08 + p * w;
+ p = 1.5027403968909827627e-06 + p * w;
+ p = -4.013867526981545969e-06 + p * w;
+ p = 2.9234449089955446044e-06 + p * w;
+ p = 1.2475304481671778723e-05 + p * w;
+ p = -4.7318229009055733981e-05 + p * w;
+ p = 6.8284851459573175448e-05 + p * w;
+ p = 2.4031110387097893999e-05 + p * w;
+ p = -0.0003550375203628474796 + p * w;
+ p = 0.00095328937973738049703 + p * w;
+ p = -0.0016882755560235047313 + p * w;
+ p = 0.0024914420961078508066 + p * w;
+ p = -0.0037512085075692412107 + p * w;
+ p = 0.005370914553590063617 + p * w;
+ p = 1.0052589676941592334 + p * w;
+ p = 3.0838856104922207635 + p * w;
+ } else {
+ w = sqrt( w ) - 5.000000;
+ p = -2.7109920616438573243e-11;
+ p = -2.5556418169965252055e-10 + p * w;
+ p = 1.5076572693500548083e-09 + p * w;
+ p = -3.7894654401267369937e-09 + p * w;
+ p = 7.6157012080783393804e-09 + p * w;
+ p = -1.4960026627149240478e-08 + p * w;
+ p = 2.9147953450901080826e-08 + p * w;
+ p = -6.7711997758452339498e-08 + p * w;
+ p = 2.2900482228026654717e-07 + p * w;
+ p = -9.9298272942317002539e-07 + p * w;
+ p = 4.5260625972231537039e-06 + p * w;
+ p = -1.9681778105531670567e-05 + p * w;
+ p = 7.5995277030017761139e-05 + p * w;
+ p = -0.00021503011930044477347 + p * w;
+ p = -0.00013871931833623122026 + p * w;
+ p = 1.0103004648645343977 + p * w;
+ p = 4.8499064014085844221 + p * w;
+ }
+ return p * x;
+ }
+
+ static double
+ standard_deviation( std::vector<double>::const_iterator first,
+ std::vector<double>::const_iterator last ) {
+ auto m = Catch::Benchmark::Detail::mean( first, last );
+ double variance =
+ std::accumulate( first,
+ last,
+ 0.,
+ [m]( double a, double b ) {
+ double diff = b - m;
+ return a + diff * diff;
+ } ) /
+ ( last - first );
+ return std::sqrt( variance );
+ }
+
+ } // namespace
+ } // namespace Detail
+ } // namespace Benchmark
+} // namespace Catch
namespace Catch {
namespace Benchmark {
@@ -236,6 +292,47 @@ namespace Catch {
return xj + g * (xj1 - xj);
}
+ OutlierClassification
+ classify_outliers( std::vector<double>::const_iterator first,
+ std::vector<double>::const_iterator last ) {
+ std::vector<double> copy( first, last );
+
+ auto q1 = weighted_average_quantile( 1, 4, copy.begin(), copy.end() );
+ auto q3 = weighted_average_quantile( 3, 4, copy.begin(), copy.end() );
+ auto iqr = q3 - q1;
+ auto los = q1 - ( iqr * 3. );
+ auto lom = q1 - ( iqr * 1.5 );
+ auto him = q3 + ( iqr * 1.5 );
+ auto his = q3 + ( iqr * 3. );
+
+ OutlierClassification o;
+ for ( ; first != last; ++first ) {
+ const double t = *first;
+ if ( t < los ) {
+ ++o.low_severe;
+ } else if ( t < lom ) {
+ ++o.low_mild;
+ } else if ( t > his ) {
+ ++o.high_severe;
+ } else if ( t > him ) {
+ ++o.high_mild;
+ }
+ ++o.samples_seen;
+ }
+ return o;
+ }
+
+ double mean( std::vector<double>::const_iterator first,
+ std::vector<double>::const_iterator last ) {
+ auto count = last - first;
+ double sum = 0.;
+ while (first != last) {
+ sum += *first;
+ ++first;
+ }
+ return sum / static_cast<double>(count);
+ }
+
double erfc_inv(double x) {
return erf_inv(1.0 - x);
@@ -257,35 +354,10 @@ namespace Catch {
return result;
}
-
- double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n) {
- double sb = stddev.point;
- double mn = mean.point / n;
- double mg_min = mn / 2.;
- double sg = (std::min)(mg_min / 4., sb / std::sqrt(n));
- double sg2 = sg * sg;
- double sb2 = sb * sb;
-
- auto c_max = [n, mn, sb2, sg2](double x) -> double {
- double k = mn - x;
- double d = k * k;
- double nd = n * d;
- double k0 = -n * nd;
- double k1 = sb2 - n * sg2 + nd;
- double det = k1 * k1 - 4 * sg2 * k0;
- return static_cast<int>(-2. * k0 / (k1 + std::sqrt(det)));
- };
-
- auto var_out = [n, sb2, sg2](double c) {
- double nc = n - c;
- return (nc / n) * (sb2 - nc * sg2);
- };
-
- return (std::min)(var_out(1), var_out((std::min)(c_max(0.), c_max(mg_min)))) / sb2;
- }
-
-
- bootstrap_analysis analyse_samples(double confidence_level, unsigned int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) {
+ bootstrap_analysis analyse_samples(double confidence_level,
+ unsigned int n_resamples,
+ std::vector<double>::iterator first,
+ std::vector<double>::iterator last) {
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
static std::random_device entropy;
@@ -293,11 +365,12 @@ namespace Catch {
auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++
- auto mean = &Detail::mean<std::vector<double>::iterator>;
+ auto mean = &Detail::mean;
auto stddev = &standard_deviation;
#if defined(CATCH_CONFIG_USE_ASYNC)
- auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
+ auto Estimate = [=](double(*f)(std::vector<double>::const_iterator,
+ std::vector<double>::const_iterator)) {
auto seed = entropy();
return std::async(std::launch::async, [=] {
std::mt19937 rng(seed);
@@ -312,7 +385,8 @@ namespace Catch {
auto mean_estimate = mean_future.get();
auto stddev_estimate = stddev_future.get();
#else
- auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
+ auto Estimate = [=](double(*f)(std::vector<double>::const_iterator,
+ std::vector<double>::const_iterator)) {
auto seed = entropy();
std::mt19937 rng(seed);
auto resampled = resample(rng, n_resamples, first, last, f);
@@ -596,7 +670,7 @@ namespace Catch {
elem = trim(elem);
}
- // Insert the default reporter if user hasn't asked for a specfic one
+ // Insert the default reporter if user hasn't asked for a specific one
if ( m_data.reporterSpecifications.empty() ) {
m_data.reporterSpecifications.push_back( {
#if defined( CATCH_CONFIG_DEFAULT_REPORTER )
@@ -775,7 +849,11 @@ namespace Catch {
}
- Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {
+ Capturer::Capturer( StringRef macroName,
+ SourceLineInfo const& lineInfo,
+ ResultWas::OfType resultType,
+ StringRef names ):
+ m_resultCapture( getResultCapture() ) {
auto trimmed = [&] (size_t start, size_t end) {
while (names[start] == ',' || isspace(static_cast<unsigned char>(names[start]))) {
++start;
@@ -852,6 +930,8 @@ namespace Catch {
+#include <exception>
+
namespace Catch {
namespace {
@@ -862,7 +942,7 @@ namespace Catch {
public: // IRegistryHub
RegistryHub() = default;
- IReporterRegistry const& getReporterRegistry() const override {
+ ReporterRegistry const& getReporterRegistry() const override {
return m_reporterRegistry;
}
ITestCaseRegistry const& getTestCaseRegistry() const override {
@@ -938,6 +1018,7 @@ namespace Catch {
#include <algorithm>
#include <cassert>
+#include <exception>
#include <iomanip>
#include <set>
@@ -1420,12 +1501,20 @@ namespace Catch {
for (size_t idx = 0; idx < originalTags.size(); ++idx) {
auto c = originalTags[idx];
if (c == '[') {
- assert(!inTag);
+ CATCH_ENFORCE(
+ !inTag,
+ "Found '[' inside a tag while registering test case '"
+ << _nameAndTags.name << "' at " << _lineInfo );
+
inTag = true;
tagStart = idx;
}
if (c == ']') {
- assert(inTag);
+ CATCH_ENFORCE(
+ inTag,
+ "Found unmatched ']' while registering test case '"
+ << _nameAndTags.name << "' at " << _lineInfo );
+
inTag = false;
tagEnd = idx;
assert(tagStart < tagEnd);
@@ -1434,7 +1523,11 @@ namespace Catch {
// it over to backing storage and actually reference the
// backing storage in the saved tags
StringRef tagStr = originalTags.substr(tagStart+1, tagEnd - tagStart - 1);
- CATCH_ENFORCE(!tagStr.empty(), "Empty tags are not allowed");
+ CATCH_ENFORCE( !tagStr.empty(),
+ "Found an empty tag while registering test case '"
+ << _nameAndTags.name << "' at "
+ << _lineInfo );
+
enforceNotReservedTag(tagStr, lineInfo);
properties |= parseSpecialTag(tagStr);
// When copying a tag to the backing storage, we need to
@@ -1448,8 +1541,12 @@ namespace Catch {
// the tags.
internalAppendTag(tagStr);
}
- (void)inTag; // Silence "set-but-unused" warning in release mode.
}
+ CATCH_ENFORCE( !inTag,
+ "Found an unclosed tag while registering test case '"
+ << _nameAndTags.name << "' at " << _lineInfo );
+
+
// Add [.] if relevant
if (isHidden()) {
internalAppendTag("."_sr);
@@ -1625,16 +1722,18 @@ namespace Catch {
return std::any_of( m_filters.begin(), m_filters.end(), [&]( Filter const& f ){ return f.matches( testCase ); } );
}
- TestSpec::Matches TestSpec::matchesByFilter( std::vector<TestCaseHandle> const& testCases, IConfig const& config ) const
- {
- Matches matches( m_filters.size() );
- std::transform( m_filters.begin(), m_filters.end(), matches.begin(), [&]( Filter const& filter ){
+ TestSpec::Matches TestSpec::matchesByFilter( std::vector<TestCaseHandle> const& testCases, IConfig const& config ) const {
+ Matches matches;
+ matches.reserve( m_filters.size() );
+ for ( auto const& filter : m_filters ) {
std::vector<TestCaseHandle const*> currentMatches;
- for( auto const& test : testCases )
- if( isThrowSafe( test, config ) && filter.matches( test.getTestCaseInfo() ) )
+ for ( auto const& test : testCases )
+ if ( isThrowSafe( test, config ) &&
+ filter.matches( test.getTestCaseInfo() ) )
currentMatches.emplace_back( &test );
- return FilterMatch{ extractFilterName(filter), currentMatches };
- } );
+ matches.push_back(
+ FilterMatch{ extractFilterName( filter ), currentMatches } );
+ }
return matches;
}
@@ -1991,6 +2090,19 @@ namespace Catch {
}
+
+
+namespace Catch {
+ namespace Detail {
+ void registerTranslatorImpl(
+ Detail::unique_ptr<IExceptionTranslator>&& translator ) {
+ getMutableRegistryHub().registerTranslator(
+ CATCH_MOVE( translator ) );
+ }
+ } // namespace Detail
+} // namespace Catch
+
+
#include <ostream>
namespace Catch {
@@ -2021,7 +2133,7 @@ namespace Catch {
}
Version const& libraryVersion() {
- static Version version( 3, 3, 2, "", 0 );
+ static Version version( 3, 4, 0, "", 0 );
return version;
}
@@ -2172,8 +2284,6 @@ namespace Catch {
infoMessages( _infoMessages ),
totals( _totals )
{
- assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;
-
if( assertionResult.hasMessage() ) {
// Copy message into messages list.
// !TBD This should have been done earlier, somewhere
@@ -2232,14 +2342,6 @@ namespace Catch {
namespace Catch {
- IReporterRegistry::~IReporterRegistry() = default;
-}
-
-
-
-
-namespace Catch {
- ITestInvoker::~ITestInvoker() = default;
ITestCaseRegistry::~ITestCaseRegistry() = default;
}
@@ -2254,7 +2356,9 @@ namespace Catch {
ResultDisposition::Flags resultDisposition )
: m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
m_resultCapture( getResultCapture() )
- {}
+ {
+ m_resultCapture.notifyAssertionStarted( m_assertionInfo );
+ }
void AssertionHandler::handleExpr( ITransientExpression const& expr ) {
m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );
@@ -2268,7 +2372,7 @@ namespace Catch {
}
void AssertionHandler::complete() {
- setCompleted();
+ m_completed = true;
if( m_reaction.shouldDebugBreak ) {
// If you find your debugger stopping you here then go one level up on the
@@ -2281,16 +2385,9 @@ namespace Catch {
throw_test_failure_exception();
}
if ( m_reaction.shouldSkip ) {
-#if !defined( CATCH_CONFIG_DISABLE_EXCEPTIONS )
- throw Catch::TestSkipException();
-#else
- CATCH_ERROR( "Explicitly skipping tests during runtime requires exceptions" );
-#endif
+ throw_test_skip_exception();
}
}
- void AssertionHandler::setCompleted() {
- m_completed = true;
- }
void AssertionHandler::handleUnexpectedInflightException() {
m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );
@@ -2917,7 +3014,7 @@ namespace Catch {
auto const& reporterSpec = *parsed;
- IReporterRegistry::FactoryMap const& factories =
+ auto const& factories =
getRegistryHub().getReporterRegistry().getFactories();
auto result = factories.find( reporterSpec.name() );
@@ -3155,7 +3252,7 @@ namespace Catch {
namespace {
//! A do-nothing implementation of colour, used as fallback for unknown
//! platforms, and when the user asks to deactivate all colours.
- class NoColourImpl : public ColourImpl {
+ class NoColourImpl final : public ColourImpl {
public:
NoColourImpl( IStream* stream ): ColourImpl( stream ) {}
@@ -3173,7 +3270,7 @@ namespace Catch {
namespace Catch {
namespace {
- class Win32ColourImpl : public ColourImpl {
+ class Win32ColourImpl final : public ColourImpl {
public:
Win32ColourImpl(IStream* stream):
ColourImpl(stream) {
@@ -3239,7 +3336,7 @@ namespace {
namespace Catch {
namespace {
- class ANSIColourImpl : public ColourImpl {
+ class ANSIColourImpl final : public ColourImpl {
public:
ANSIColourImpl( IStream* stream ): ColourImpl( stream ) {}
@@ -3355,49 +3452,27 @@ namespace Catch {
namespace Catch {
- class Context : public IMutableContext, private Detail::NonCopyable {
-
- public: // IContext
- IResultCapture* getResultCapture() override {
- return m_resultCapture;
- }
-
- IConfig const* getConfig() const override {
- return m_config;
- }
-
- ~Context() override;
-
- public: // IMutableContext
- void setResultCapture( IResultCapture* resultCapture ) override {
- m_resultCapture = resultCapture;
- }
- void setConfig( IConfig const* config ) override {
- m_config = config;
- }
-
- friend IMutableContext& getCurrentMutableContext();
-
- private:
- IConfig const* m_config = nullptr;
- IResultCapture* m_resultCapture = nullptr;
- };
-
- IMutableContext *IMutableContext::currentContext = nullptr;
+ Context* Context::currentContext = nullptr;
- void IMutableContext::createContext()
- {
+ void cleanUpContext() {
+ delete Context::currentContext;
+ Context::currentContext = nullptr;
+ }
+ void Context::createContext() {
currentContext = new Context();
}
- void cleanUpContext() {
- delete IMutableContext::currentContext;
- IMutableContext::currentContext = nullptr;
+ Context& getCurrentMutableContext() {
+ if ( !Context::currentContext ) { Context::createContext(); }
+ // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
+ return *Context::currentContext;
+ }
+
+ void Context::setResultCapture( IResultCapture* resultCapture ) {
+ m_resultCapture = resultCapture;
}
- IContext::~IContext() = default;
- IMutableContext::~IMutableContext() = default;
- Context::~Context() = default;
+ void Context::setConfig( IConfig const* config ) { m_config = config; }
SimplePcg32& sharedRng() {
static SimplePcg32 s_rng;
@@ -3680,8 +3755,24 @@ namespace Catch {
+#include <exception>
+
namespace Catch {
+ namespace {
+ static std::string tryTranslators(
+ std::vector<
+ Detail::unique_ptr<IExceptionTranslator const>> const& translators ) {
+ if ( translators.empty() ) {
+ std::rethrow_exception( std::current_exception() );
+ } else {
+ return translators[0]->translate( translators.begin() + 1,
+ translators.end() );
+ }
+ }
+
+ }
+
ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
}
@@ -3706,7 +3797,7 @@ namespace Catch {
// First we try user-registered translators. If none of them can
// handle the exception, it will be rethrown handled by our defaults.
try {
- return tryTranslators();
+ return tryTranslators(m_translators);