diff options
| author | Martin Hořeňovský | 2023-07-13 13:37:30 +0200 |
|---|---|---|
| committer | Martin Hořeňovský | 2023-07-13 13:37:30 +0200 |
| commit | 6e79e682b726f524310d55dec8ddac4e9c52fb5f (patch) | |
| tree | f399bdefd6361f173bb36f611d14ee5665e81383 | |
| parent | 683c85772f65a8779e3baf45d3402098db58bb8d (diff) | |
| download | catch3-3.4.0.tar.gz | |
v3.4.0v3.4.0
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | docs/configuration.md | 2 | ||||
| -rw-r--r-- | docs/release-notes.md | 28 | ||||
| -rw-r--r-- | extras/catch_amalgamated.cpp | 1052 | ||||
| -rw-r--r-- | extras/catch_amalgamated.hpp | 2517 | ||||
| -rw-r--r-- | meson.build | 2 | ||||
| -rw-r--r-- | src/catch2/catch_version.cpp | 2 | ||||
| -rw-r--r-- | src/catch2/catch_version_macros.hpp | 4 |
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); |