diff --git a/CMakeLists.txt b/CMakeLists.txt
index d5a6b67a..cf35c0e4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -31,7 +31,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
endif()
project(Catch2
- VERSION 3.2.1 # CML version placeholder, don't delete
+ VERSION 3.3.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/matchers.md b/docs/matchers.md
index eba76c84..dda49110 100644
--- a/docs/matchers.md
+++ b/docs/matchers.md
@@ -195,6 +195,8 @@ These are:
* `Message(std::string message)`.
* `MessageMatches(Matcher matcher)`.
+> `MessageMatches` was [introduced](https://github.com/catchorg/Catch2/pull/2570) in Catch2 3.3.0
+
`Message` checks that the exception's
message, as returned from `what` is exactly equal to `message`.
@@ -238,7 +240,7 @@ definitions to handle generic range-like types. These are:
> `All/Any/NoneTrue` were introduced in Catch2 3.1.0
-> `RangeEquals` and `UnorderedRangeEquals` matchers were [introduced](https://github.com/catchorg/Catch2/pull/2377) in Catch2 X.Y.Z
+> `RangeEquals` and `UnorderedRangeEquals` matchers were [introduced](https://github.com/catchorg/Catch2/pull/2377) in Catch2 3.3.0
`IsEmpty` should be self-explanatory. It successfully matches objects
that are empty according to either `std::empty`, or ADL-found `empty`
diff --git a/docs/release-notes.md b/docs/release-notes.md
index 7659404b..449ca7f9 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -2,6 +2,7 @@
# Release notes
**Contents**
+[3.3.0](#330)
[3.2.1](#321)
[3.2.0](#320)
[3.1.1](#311)
@@ -54,6 +55,35 @@
+## 3.3.0
+
+### Improvements
+
+* Added `MessageMatches` exception matcher (#2570)
+* Added `RangeEquals` and `UnorderedRangeEquals` generic range matchers (#2377)
+* Added `SKIP` macro for skipping tests from within the test body (#2360)
+ * All built-in reporters have been extended to handle it properly, whether your custom reporter needs changes depends on how it was written
+ * `skipTest` reporter event **is unrelated** to this, and has been deprecated since it has practically no uses
+* Restored support for PPC Macs in the break-into-debugger functionality (#2619)
+* Made our warning suppression compatible with CUDA toolkit pre 11.5 (#2626)
+* Cleaned out some static analysis complaints
+
+
+### Fixes
+
+* Fixed macro redefinition warning when NVCC was reporting as MSVC (#2603)
+* Fixed throws in generator constructor causing the whole binary to abort (#2615)
+ * Now it just fails the test
+* Fixed missing transitive include with libstdc++13 (#2611)
+
+
+### Miscellaneous
+
+* Improved support for dynamic library build with non-MSVC compilers on Windows (#2630)
+* When used as a subproject, Catch2 keeps its generated header in a separate directory from the main project (#2604)
+
+
+
## 3.2.1
### Improvements
diff --git a/docs/skipping-passing-failing.md b/docs/skipping-passing-failing.md
index 72c9f775..4300d9d3 100644
--- a/docs/skipping-passing-failing.md
+++ b/docs/skipping-passing-failing.md
@@ -3,7 +3,7 @@
## Skipping Test Cases at Runtime
-> [Introduced](https://github.com/catchorg/Catch2/pull/2360) in Catch2 X.Y.Z.
+> [Introduced](https://github.com/catchorg/Catch2/pull/2360) in Catch2 3.3.0.
In some situations it may not be possible to meaningfully execute a test case,
for example when the system under test is missing certain hardware capabilities.
diff --git a/extras/catch_amalgamated.cpp b/extras/catch_amalgamated.cpp
index b27c4ec8..0722b491 100644
--- a/extras/catch_amalgamated.cpp
+++ b/extras/catch_amalgamated.cpp
@@ -5,8 +5,8 @@
// SPDX-License-Identifier: BSL-1.0
-// Catch v3.2.1
-// Generated: 2022-12-09 23:01:15.713081
+// Catch v3.3.0
+// Generated: 2023-01-22 19:46:24.251531
// ----------------------------------------------------------
// This file is an amalgamation of multiple different files.
// You probably shouldn't edit it directly.
@@ -1253,6 +1253,12 @@ namespace Catch {
return 2;
}
+ if ( totals.testCases.total() > 0 &&
+ totals.testCases.total() == totals.testCases.skipped
+ && !m_config->zeroTestsCountAsSuccess() ) {
+ return 4;
+ }
+
// Note that on unices only the lower 8 bits are usually used, clamping
// the return value to 255 prevents false negative when some multiple
// of 256 tests has failed
@@ -1935,6 +1941,7 @@ namespace Catch {
diff.passed = passed - other.passed;
diff.failed = failed - other.failed;
diff.failedButOk = failedButOk - other.failedButOk;
+ diff.skipped = skipped - other.skipped;
return diff;
}
@@ -1942,14 +1949,15 @@ namespace Catch {
passed += other.passed;
failed += other.failed;
failedButOk += other.failedButOk;
+ skipped += other.skipped;
return *this;
}
std::uint64_t Counts::total() const {
- return passed + failed + failedButOk;
+ return passed + failed + failedButOk + skipped;
}
bool Counts::allPassed() const {
- return failed == 0 && failedButOk == 0;
+ return failed == 0 && failedButOk == 0 && skipped == 0;
}
bool Counts::allOk() const {
return failed == 0;
@@ -1974,6 +1982,8 @@ namespace Catch {
++diff.testCases.failed;
else if( diff.assertions.failedButOk > 0 )
++diff.testCases.failedButOk;
+ else if ( diff.assertions.skipped > 0 )
+ ++ diff.testCases.skipped;
else
++diff.testCases.passed;
return diff;
@@ -2012,7 +2022,7 @@ namespace Catch {
}
Version const& libraryVersion() {
- static Version version( 3, 2, 1, "", 0 );
+ static Version version( 3, 3, 0, "", 0 );
return version;
}
@@ -2048,10 +2058,17 @@ namespace Detail {
GeneratorUntypedBase::~GeneratorUntypedBase() = default;
- auto acquireGeneratorTracker(StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
+ IGeneratorTracker* acquireGeneratorTracker(StringRef generatorName, SourceLineInfo const& lineInfo ) {
return getResultCapture().acquireGeneratorTracker( generatorName, lineInfo );
}
+ IGeneratorTracker* createGeneratorTracker( StringRef generatorName,
+ SourceLineInfo lineInfo,
+ GeneratorBasePtr&& generator ) {
+ return getResultCapture().createGeneratorTracker(
+ generatorName, lineInfo, CATCH_MOVE( generator ) );
+ }
+
} // namespace Generators
} // namespace Catch
@@ -2265,6 +2282,13 @@ namespace Catch {
if (m_reaction.shouldThrow) {
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
+ }
}
void AssertionHandler::setCompleted() {
m_completed = true;
@@ -3691,6 +3715,9 @@ namespace Catch {
catch( TestFailureException& ) {
std::rethrow_exception(std::current_exception());
}
+ catch( TestSkipException& ) {
+ std::rethrow_exception(std::current_exception());
+ }
catch( std::exception const& ex ) {
return ex.what();
}
@@ -4509,8 +4536,8 @@ namespace Catch {
-
#include
+#include
namespace Catch {
@@ -4538,11 +4565,14 @@ namespace Catch {
return {};
}
return static_cast(ret);
- } CATCH_CATCH_ANON( std::exception const& ) {
- // There was a larger issue with the input, e.g. the parsed
- // number would be too large to fit within ull.
- return {};
}
+ CATCH_CATCH_ANON( std::invalid_argument const& ) {
+ // no conversion could be performed
+ }
+ CATCH_CATCH_ANON( std::out_of_range const& ) {
+ // the input does not fit into an unsigned long long
+ }
+ return {};
}
} // namespace Catch
@@ -4968,7 +4998,7 @@ namespace Catch {
{}
~GeneratorTracker() override;
- static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
+ static GeneratorTracker* acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
GeneratorTracker* tracker;
ITracker& currentTracker = ctx.currentTracker();
@@ -4995,18 +5025,14 @@ namespace Catch {
assert( childTracker->isGeneratorTracker() );
tracker = static_cast( childTracker );
} else {
- auto newTracker =
- Catch::Detail::make_unique(
- nameAndLocation, ctx, ¤tTracker );
- tracker = newTracker.get();
- currentTracker.addChild( CATCH_MOVE(newTracker) );
+ return nullptr;
}
if( !tracker->isComplete() ) {
tracker->open();
}
- return *tracker;
+ return tracker;
}
// TrackerBase interface
@@ -5075,6 +5101,7 @@ namespace Catch {
// has a side-effect, where it consumes generator's current
// value, but we do not want to invoke the side-effect if
// this generator is still waiting for any child to start.
+ assert( m_generator && "Tracker without generator" );
if ( should_wait_for_child ||
( m_runState == CompletedSuccessfully &&
m_generator->countedNext() ) ) {
@@ -5204,6 +5231,9 @@ namespace Catch {
if (result.getResultType() == ResultWas::Ok) {
m_totals.assertions.passed++;
m_lastAssertionPassed = true;
+ } else if (result.getResultType() == ResultWas::ExplicitSkip) {
+ m_totals.assertions.skipped++;
+ m_lastAssertionPassed = true;
} else if (!result.succeeded()) {
m_lastAssertionPassed = false;
if (result.isOk()) {
@@ -5245,14 +5275,39 @@ namespace Catch {
return true;
}
- auto RunContext::acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
+ IGeneratorTracker*
+ RunContext::acquireGeneratorTracker( StringRef generatorName,
+ SourceLineInfo const& lineInfo ) {
using namespace Generators;
- GeneratorTracker& tracker = GeneratorTracker::acquire(m_trackerContext,
- TestCaseTracking::NameAndLocation( static_cast(generatorName), lineInfo ) );
+ GeneratorTracker* tracker = GeneratorTracker::acquire(
+ m_trackerContext,
+ TestCaseTracking::NameAndLocation(
+ static_cast( generatorName ), lineInfo ) );
m_lastAssertionInfo.lineInfo = lineInfo;
return tracker;
}
+ IGeneratorTracker* RunContext::createGeneratorTracker(
+ StringRef generatorName,
+ SourceLineInfo lineInfo,
+ Generators::GeneratorBasePtr&& generator ) {
+
+ auto nameAndLoc = TestCaseTracking::NameAndLocation( static_cast( generatorName ), lineInfo );
+ auto& currentTracker = m_trackerContext.currentTracker();
+ assert(
+ currentTracker.nameAndLocation() != nameAndLoc &&
+ "Trying to create tracker for a genreator that already has one" );
+
+ auto newTracker = Catch::Detail::make_unique(
+ nameAndLoc, m_trackerContext, ¤tTracker );
+ auto ret = newTracker.get();
+ currentTracker.addChild( CATCH_MOVE( newTracker ) );
+
+ ret->setGenerator( CATCH_MOVE( generator ) );
+ ret->open();
+ return ret;
+ }
+
bool RunContext::testForMissingAssertions(Counts& assertions) {
if (assertions.total() != 0)
return false;
@@ -5409,6 +5464,8 @@ namespace Catch {
duration = timer.getElapsedSeconds();
} CATCH_CATCH_ANON (TestFailureException&) {
// This just means the test was aborted due to failure
+ } CATCH_CATCH_ANON (TestSkipException&) {
+ // This just means the test was explicitly skipped
} CATCH_CATCH_ALL {
// Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
// are reported without translation at the point of origin.
@@ -5505,8 +5562,13 @@ namespace Catch {
data.message = static_cast(message);
AssertionResult assertionResult{ m_lastAssertionInfo, data };
assertionEnded( assertionResult );
- if( !assertionResult.isOk() )
+ if ( !assertionResult.isOk() ) {
populateReaction( reaction );
+ } else if ( resultType == ResultWas::ExplicitSkip ) {
+ // TODO: Need to handle this explicitly, as ExplicitSkip is
+ // considered "OK"
+ reaction.shouldSkip = true;
+ }
}
void RunContext::handleUnexpectedExceptionNotThrown(
AssertionInfo const& info,
@@ -6935,6 +6997,7 @@ namespace Catch {
// while in /permissive- mode. No, I don't know why.
// Tested on VS 2019, 18.{3, 4}.x
+#include
#include
#include
@@ -7750,7 +7813,9 @@ namespace Catch {
void AutomakeReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
// Possible values to emit are PASS, XFAIL, SKIP, FAIL, XPASS and ERROR.
m_stream << ":test-result: ";
- if (_testCaseStats.totals.assertions.allPassed()) {
+ if ( _testCaseStats.totals.testCases.skipped > 0 ) {
+ m_stream << "SKIP";
+ } else if (_testCaseStats.totals.assertions.allPassed()) {
m_stream << "PASS";
} else if (_testCaseStats.totals.assertions.allOk()) {
m_stream << "XFAIL";
@@ -7899,6 +7964,11 @@ public:
printIssue("explicitly");
printRemainingMessages(Colour::None);
break;
+ case ResultWas::ExplicitSkip:
+ printResultType(Colour::Skip, "skipped"_sr);
+ printMessage();
+ printRemainingMessages();
+ break;
// These cases are here to prevent compiler warnings
case ResultWas::Unknown:
case ResultWas::FailureBit:
@@ -8014,7 +8084,7 @@ private:
// Drop out if result was successful and we're not printing those
if( !m_config->includeSuccessfulResults() && result.isOk() ) {
- if( result.getResultType() != ResultWas::Warning )
+ if( result.getResultType() != ResultWas::Warning && result.getResultType() != ResultWas::ExplicitSkip )
return;
printInfoMessages = false;
}
@@ -8135,6 +8205,14 @@ public:
if (_stats.infoMessages.size() > 1)
messageLabel = "explicitly with messages";
break;
+ case ResultWas::ExplicitSkip:
+ colour = Colour::Skip;
+ passOrFail = "SKIPPED"_sr;
+ if (_stats.infoMessages.size() == 1)
+ messageLabel = "explicitly with message";
+ if (_stats.infoMessages.size() > 1)
+ messageLabel = "explicitly with messages";
+ break;
// These cases are here to prevent compiler warnings
case ResultWas::Unknown:
case ResultWas::FailureBit:
@@ -8209,13 +8287,16 @@ std::size_t makeRatio( std::uint64_t number, std::uint64_t total ) {
return (ratio == 0 && number > 0) ? 1 : static_cast(ratio);
}
-std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
- if (i > j && i > k)
+std::size_t&
+findMax( std::size_t& i, std::size_t& j, std::size_t& k, std::size_t& l ) {
+ if (i > j && i > k && i > l)
return i;
- else if (j > k)
+ else if (j > k && j > l)
return j;
- else
+ else if (k > l)
return k;
+ else
+ return l;
}
enum class Justification { Left, Right };
@@ -8424,7 +8505,8 @@ void ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
// Drop out if result was successful but we're not printing them.
- if (!includeResults && result.getResultType() != ResultWas::Warning)
+ // TODO: Make configurable whether skips should be printed
+ if (!includeResults && result.getResultType() != ResultWas::Warning && result.getResultType() != ResultWas::ExplicitSkip)
return;
lazyPrint();
@@ -8627,10 +8709,11 @@ void ConsoleReporter::printTotalsDivider(Totals const& totals) {
std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());
- while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
- findMax(failedRatio, failedButOkRatio, passedRatio)++;
+ std::size_t skippedRatio = makeRatio(totals.testCases.skipped, totals.testCases.total());
+ while (failedRatio + failedButOkRatio + passedRatio + skippedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
+ findMax(failedRatio, failedButOkRatio, passedRatio, skippedRatio)++;
while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
- findMax(failedRatio, failedButOkRatio, passedRatio)--;
+ findMax(failedRatio, failedButOkRatio, passedRatio, skippedRatio)--;
m_stream << m_colour->guardColour( Colour::Error )
<< std::string( failedRatio, '=' )
@@ -8643,6 +8726,8 @@ void ConsoleReporter::printTotalsDivider(Totals const& totals) {
m_stream << m_colour->guardColour( Colour::Success )
<< std::string( passedRatio, '=' );
}
+ m_stream << m_colour->guardColour( Colour::Skip )
+ << std::string( skippedRatio, '=' );
} else {
m_stream << m_colour->guardColour( Colour::Warning )
<< std::string( CATCH_CONFIG_CONSOLE_WIDTH - 1, '=' );
@@ -9147,15 +9232,22 @@ namespace Catch {
}
std::vector columns;
+ // Don't include "skipped assertions" in total count
+ const auto totalAssertionCount =
+ totals.assertions.total() - totals.assertions.skipped;
columns.push_back( SummaryColumn( "", Colour::None )
.addRow( totals.testCases.total() )
- .addRow( totals.assertions.total() ) );
+ .addRow( totalAssertionCount ) );
columns.push_back( SummaryColumn( "passed", Colour::Success )
.addRow( totals.testCases.passed )
.addRow( totals.assertions.passed ) );
columns.push_back( SummaryColumn( "failed", Colour::ResultError )
.addRow( totals.testCases.failed )
.addRow( totals.assertions.failed ) );
+ columns.push_back( SummaryColumn( "skipped", Colour::Skip )
+ .addRow( totals.testCases.skipped )
+ // Don't print "skipped assertions"
+ .addRow( 0 ) );
columns.push_back(
SummaryColumn( "failed as expected", Colour::ResultExpectedFailure )
.addRow( totals.testCases.failedButOk )
@@ -9285,6 +9377,7 @@ namespace Catch {
xml.writeAttribute( "name"_sr, stats.runInfo.name );
xml.writeAttribute( "errors"_sr, unexpectedExceptions );
xml.writeAttribute( "failures"_sr, stats.totals.assertions.failed-unexpectedExceptions );
+ xml.writeAttribute( "skipped"_sr, stats.totals.assertions.skipped );
xml.writeAttribute( "tests"_sr, stats.totals.assertions.total() );
xml.writeAttribute( "hostname"_sr, "tbd"_sr ); // !TBD
if( m_config->showDurations() == ShowDurations::Never )
@@ -9397,7 +9490,8 @@ namespace Catch {
void JunitReporter::writeAssertion( AssertionStats const& stats ) {
AssertionResult const& result = stats.assertionResult;
- if( !result.isOk() ) {
+ if ( !result.isOk() ||
+ result.getResultType() == ResultWas::ExplicitSkip ) {
std::string elementName;
switch( result.getResultType() ) {
case ResultWas::ThrewException:
@@ -9409,7 +9503,9 @@ namespace Catch {
case ResultWas::DidntThrowException:
elementName = "failure";
break;
-
+ case ResultWas::ExplicitSkip:
+ elementName = "skipped";
+ break;
// We should never see these here:
case ResultWas::Info:
case ResultWas::Warning:
@@ -9427,7 +9523,9 @@ namespace Catch {
xml.writeAttribute( "type"_sr, result.getTestMacroName() );
ReusableStringStream rss;
- if (stats.totals.assertions.total() > 0) {
+ if ( result.getResultType() == ResultWas::ExplicitSkip ) {
+ rss << "SKIPPED\n";
+ } else {
rss << "FAILED" << ":\n";
if (result.hasExpression()) {
rss << " ";
@@ -9438,8 +9536,6 @@ namespace Catch {
rss << "with expansion:\n";
rss << TextFlow::Column(result.getExpandedExpression()).indent(2) << '\n';
}
- } else {
- rss << '\n';
}
if( !result.getMessage().empty() )
@@ -9753,7 +9849,8 @@ namespace Catch {
void SonarQubeReporter::writeAssertion(AssertionStats const& stats, bool okToFail) {
AssertionResult const& result = stats.assertionResult;
- if (!result.isOk()) {
+ if ( !result.isOk() ||
+ result.getResultType() == ResultWas::ExplicitSkip ) {
std::string elementName;
if (okToFail) {
elementName = "skipped";
@@ -9764,15 +9861,13 @@ namespace Catch {
elementName = "error";
break;
case ResultWas::ExplicitFailure:
- elementName = "failure";
- break;
case ResultWas::ExpressionFailed:
- elementName = "failure";
- break;
case ResultWas::DidntThrowException:
elementName = "failure";
break;
-
+ case ResultWas::ExplicitSkip:
+ elementName = "skipped";
+ break;
// We should never see these here:
case ResultWas::Info:
case ResultWas::Warning:
@@ -9792,7 +9887,9 @@ namespace Catch {
xml.writeAttribute("message"_sr, messageRss.str());
ReusableStringStream textRss;
- if (stats.totals.assertions.total() > 0) {
+ if ( result.getResultType() == ResultWas::ExplicitSkip ) {
+ textRss << "SKIPPED\n";
+ } else {
textRss << "FAILED:\n";
if (result.hasExpression()) {
textRss << '\t' << result.getExpressionInMacro() << '\n';
@@ -9922,6 +10019,12 @@ namespace Catch {
printIssue("explicitly"_sr);
printRemainingMessages(Colour::None);
break;
+ case ResultWas::ExplicitSkip:
+ printResultType(tapPassedString);
+ printIssue(" # SKIP"_sr);
+ printMessage();
+ printRemainingMessages();
+ break;
// These cases are here to prevent compiler warnings
case ResultWas::Unknown:
case ResultWas::FailureBit:
@@ -10093,7 +10196,8 @@ namespace Catch {
void TeamCityReporter::assertionEnded(AssertionStats const& assertionStats) {
AssertionResult const& result = assertionStats.assertionResult;
- if (!result.isOk()) {
+ if ( !result.isOk() ||
+ result.getResultType() == ResultWas::ExplicitSkip ) {
ReusableStringStream msg;
if (!m_headerPrintedForThisSection)
@@ -10118,6 +10222,9 @@ namespace Catch {
case ResultWas::ExplicitFailure:
msg << "explicit failure";
break;
+ case ResultWas::ExplicitSkip:
+ msg << "explicit skip";
+ break;
// We shouldn't get here because of the isOk() test
case ResultWas::Ok:
@@ -10145,18 +10252,16 @@ namespace Catch {
" " << result.getExpandedExpression() << '\n';
}
- if (currentTestCaseInfo->okToFail()) {
+ if ( result.getResultType() == ResultWas::ExplicitSkip ) {
+ m_stream << "##teamcity[testIgnored";
+ } else if ( currentTestCaseInfo->okToFail() ) {
msg << "- failure ignore as test marked as 'ok to fail'\n";
- m_stream << "##teamcity[testIgnored"
- << " name='" << escape(currentTestCaseInfo->name) << '\''
- << " message='" << escape(msg.str()) << '\''
- << "]\n";
+ m_stream << "##teamcity[testIgnored";
} else {
- m_stream << "##teamcity[testFailed"
- << " name='" << escape(currentTestCaseInfo->name) << '\''
- << " message='" << escape(msg.str()) << '\''
- << "]\n";
+ m_stream << "##teamcity[testFailed";
}
+ m_stream << " name='" << escape( currentTestCaseInfo->name ) << '\''
+ << " message='" << escape( msg.str() ) << '\'' << "]\n";
}
m_stream.flush();
}
@@ -10303,9 +10408,10 @@ namespace Catch {
}
// Drop out if result was successful but we're not printing them.
- if( !includeResults && result.getResultType() != ResultWas::Warning )
+ if ( !includeResults && result.getResultType() != ResultWas::Warning &&
+ result.getResultType() != ResultWas::ExplicitSkip ) {
return;
-
+ }
// Print the expression if there is one.
if( result.hasExpression() ) {
@@ -10348,6 +10454,12 @@ namespace Catch {
m_xml.writeText( result.getMessage() );
m_xml.endElement();
break;
+ case ResultWas::ExplicitSkip:
+ m_xml.startElement( "Skip" );
+ writeSourceInfo( result.getSourceInfo() );
+ m_xml.writeText( result.getMessage() );
+ m_xml.endElement();
+ break;
default:
break;
}
@@ -10358,15 +10470,18 @@ namespace Catch {
void XmlReporter::sectionEnded( SectionStats const& sectionStats ) {
StreamingReporterBase::sectionEnded( sectionStats );
- if( --m_sectionDepth > 0 ) {
- XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
- e.writeAttribute( "successes"_sr, sectionStats.assertions.passed );
- e.writeAttribute( "failures"_sr, sectionStats.assertions.failed );
- e.writeAttribute( "expectedFailures"_sr, sectionStats.assertions.failedButOk );
-
- if ( m_config->showDurations() == ShowDurations::Always )
- e.writeAttribute( "durationInSeconds"_sr, sectionStats.durationInSeconds );
+ if ( --m_sectionDepth > 0 ) {
+ {
+ XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
+ e.writeAttribute( "successes"_sr, sectionStats.assertions.passed );
+ e.writeAttribute( "failures"_sr, sectionStats.assertions.failed );
+ e.writeAttribute( "expectedFailures"_sr, sectionStats.assertions.failedButOk );
+ e.writeAttribute( "skipped"_sr, sectionStats.assertions.skipped > 0 );
+ if ( m_config->showDurations() == ShowDurations::Always )
+ e.writeAttribute( "durationInSeconds"_sr, sectionStats.durationInSeconds );
+ }
+ // Ends assertion tag
m_xml.endElement();
}
}
@@ -10375,6 +10490,7 @@ namespace Catch {
StreamingReporterBase::testCaseEnded( testCaseStats );
XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
e.writeAttribute( "success"_sr, testCaseStats.totals.assertions.allOk() );
+ e.writeAttribute( "skips"_sr, testCaseStats.totals.assertions.skipped );
if ( m_config->showDurations() == ShowDurations::Always )
e.writeAttribute( "durationInSeconds"_sr, m_testCaseTimer.getElapsedSeconds() );
@@ -10392,11 +10508,13 @@ namespace Catch {
m_xml.scopedElement( "OverallResults" )
.writeAttribute( "successes"_sr, testRunStats.totals.assertions.passed )
.writeAttribute( "failures"_sr, testRunStats.totals.assertions.failed )
- .writeAttribute( "expectedFailures"_sr, testRunStats.totals.assertions.failedButOk );
+ .writeAttribute( "expectedFailures"_sr, testRunStats.totals.assertions.failedButOk )
+ .writeAttribute( "skips"_sr, testRunStats.totals.assertions.skipped );
m_xml.scopedElement( "OverallResultsCases")
.writeAttribute( "successes"_sr, testRunStats.totals.testCases.passed )
.writeAttribute( "failures"_sr, testRunStats.totals.testCases.failed )
- .writeAttribute( "expectedFailures"_sr, testRunStats.totals.testCases.failedButOk );
+ .writeAttribute( "expectedFailures"_sr, testRunStats.totals.testCases.failedButOk )
+ .writeAttribute( "skips"_sr, testRunStats.totals.testCases.skipped );
m_xml.endElement();
}
diff --git a/extras/catch_amalgamated.hpp b/extras/catch_amalgamated.hpp
index e91734a4..25928e4e 100644
--- a/extras/catch_amalgamated.hpp
+++ b/extras/catch_amalgamated.hpp
@@ -5,8 +5,8 @@
// SPDX-License-Identifier: BSL-1.0
-// Catch v3.2.1
-// Generated: 2022-12-09 23:01:14.526666
+// Catch v3.3.0
+// Generated: 2023-01-22 19:46:23.163056
// ----------------------------------------------------------
// This file is an amalgamation of multiple different files.
// You probably shouldn't edit it directly.
@@ -372,9 +372,14 @@ namespace Catch {
#endif
#if defined(__CUDACC__) && !defined(__clang__)
+# ifdef __NVCC_DIAG_PRAGMA_SUPPORT__
+// New pragmas introduced in CUDA 11.5+
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "nv_diagnostic push" )
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "nv_diagnostic pop" )
# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS _Pragma( "nv_diag_suppress 177" )
+# else
+# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS _Pragma( "diag_suppress 177" )
+# endif
#endif
// clang-cl defines _MSC_VER as well as __clang__, which could cause the
@@ -492,8 +497,14 @@ namespace Catch {
// Visual C++
#if defined(_MSC_VER)
-# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
-# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) )
+// We want to defer to nvcc-specific warning suppression if we are compiled
+// with nvcc masquerading for MSVC.
+# if !defined( __CUDACC__ )
+# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+ __pragma( warning( push ) )
+# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
+ __pragma( warning( pop ) )
+# endif
// Universal Windows platform does not support SEH
// Or console colours (or console at all...)
@@ -850,6 +861,7 @@ namespace Catch {
std::uint64_t passed = 0;
std::uint64_t failed = 0;
std::uint64_t failedButOk = 0;
+ std::uint64_t skipped = 0;
};
struct Totals {
@@ -916,6 +928,8 @@ namespace Catch {
Ok = 0,
Info = 1,
Warning = 2,
+ // TODO: Should explicit skip be considered "not OK" (cf. isOk)? I.e., should it have the failure bit?
+ ExplicitSkip = 4,
FailureBit = 0x10,
@@ -1062,116 +1076,6 @@ namespace Catch {
#include
-namespace Catch {
-
- class AssertionResult;
- struct AssertionInfo;
- struct SectionInfo;
- struct SectionEndInfo;
- struct MessageInfo;
- struct MessageBuilder;
- struct Counts;
- struct AssertionReaction;
- struct SourceLineInfo;
-
- class ITransientExpression;
- class IGeneratorTracker;
-
- struct BenchmarkInfo;
- template >
- struct BenchmarkStats;
-
- class IResultCapture {
- public:
- virtual ~IResultCapture();
-
- virtual bool sectionStarted( SectionInfo const& sectionInfo,
- Counts& assertions ) = 0;
- virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
- virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
-
- virtual auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
-
- virtual void benchmarkPreparing( StringRef name ) = 0;
- virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
- virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0;
- virtual void benchmarkFailed( StringRef error ) = 0;
-
- virtual void pushScopedMessage( MessageInfo const& message ) = 0;
- virtual void popScopedMessage( MessageInfo const& message ) = 0;
-
- virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0;
-
- virtual void handleFatalErrorCondition( StringRef message ) = 0;
-
- virtual void handleExpr
- ( AssertionInfo const& info,
- ITransientExpression const& expr,
- AssertionReaction& reaction ) = 0;
- virtual void handleMessage
- ( AssertionInfo const& info,
- ResultWas::OfType resultType,
- StringRef message,
- AssertionReaction& reaction ) = 0;
- virtual void handleUnexpectedExceptionNotThrown
- ( AssertionInfo const& info,
- AssertionReaction& reaction ) = 0;
- virtual void handleUnexpectedInflightException
- ( AssertionInfo const& info,
- std::string const& message,
- AssertionReaction& reaction ) = 0;
- virtual void handleIncomplete
- ( AssertionInfo const& info ) = 0;
- virtual void handleNonExpr
- ( AssertionInfo const &info,
- ResultWas::OfType resultType,
- AssertionReaction &reaction ) = 0;
-
-
-
- virtual bool lastAssertionPassed() = 0;
- virtual void assertionPassed() = 0;
-
- // Deprecated, do not use:
- virtual std::string getCurrentTestName() const = 0;
- virtual const AssertionResult* getLastResult() const = 0;
- virtual void exceptionEarlyReported() = 0;
- };
-
- IResultCapture& getResultCapture();
-}
-
-#endif // CATCH_INTERFACES_CAPTURE_HPP_INCLUDED
-
-#include
-
-namespace Catch {
-
- struct MessageInfo {
- MessageInfo( StringRef _macroName,
- SourceLineInfo const& _lineInfo,
- ResultWas::OfType _type );
-
- StringRef macroName;
- std::string message;
- SourceLineInfo lineInfo;
- ResultWas::OfType type;
- unsigned int sequence;
-
- bool operator == (MessageInfo const& other) const {
- return sequence == other.sequence;
- }
- bool operator < (MessageInfo const& other) const {
- return sequence < other.sequence;
- }
- private:
- static unsigned int globalCount;
- };
-
-} // end namespace Catch
-
-#endif // CATCH_MESSAGE_INFO_HPP_INCLUDED
-
#ifndef CATCH_UNIQUE_PTR_HPP_INCLUDED
#define CATCH_UNIQUE_PTR_HPP_INCLUDED
@@ -1284,6 +1188,128 @@ namespace Detail {
#endif // CATCH_UNIQUE_PTR_HPP_INCLUDED
+namespace Catch {
+
+ class AssertionResult;
+ struct AssertionInfo;
+ struct SectionInfo;
+ struct SectionEndInfo;
+ struct MessageInfo;
+ struct MessageBuilder;
+ struct Counts;
+ struct AssertionReaction;
+ struct SourceLineInfo;
+
+ class ITransientExpression;
+ class IGeneratorTracker;
+
+ struct BenchmarkInfo;
+ template >
+ struct BenchmarkStats;
+
+ namespace Generators {
+ class GeneratorUntypedBase;
+ using GeneratorBasePtr = Catch::Detail::unique_ptr;
+ }
+
+
+ class IResultCapture {
+ public:
+ virtual ~IResultCapture();
+
+ virtual bool sectionStarted( SectionInfo const& sectionInfo,
+ Counts& assertions ) = 0;
+ virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
+ virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
+
+ virtual IGeneratorTracker*
+ acquireGeneratorTracker( StringRef generatorName,
+ SourceLineInfo const& lineInfo ) = 0;
+ virtual IGeneratorTracker*
+ createGeneratorTracker( StringRef generatorName,
+ SourceLineInfo lineInfo,
+ Generators::GeneratorBasePtr&& generator ) = 0;
+
+ virtual void benchmarkPreparing( StringRef name ) = 0;
+ virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
+ virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0;
+ virtual void benchmarkFailed( StringRef error ) = 0;
+
+ virtual void pushScopedMessage( MessageInfo const& message ) = 0;
+ virtual void popScopedMessage( MessageInfo const& message ) = 0;
+
+ virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0;
+
+ virtual void handleFatalErrorCondition( StringRef message ) = 0;
+
+ virtual void handleExpr
+ ( AssertionInfo const& info,
+ ITransientExpression const& expr,
+ AssertionReaction& reaction ) = 0;
+ virtual void handleMessage
+ ( AssertionInfo const& info,
+ ResultWas::OfType resultType,
+ StringRef message,
+ AssertionReaction& reaction ) = 0;
+ virtual void handleUnexpectedExceptionNotThrown
+ ( AssertionInfo const& info,
+ AssertionReaction& reaction ) = 0;
+ virtual void handleUnexpectedInflightException
+ ( AssertionInfo const& info,
+ std::string const& message,
+ AssertionReaction& reaction ) = 0;
+ virtual void handleIncomplete
+ ( AssertionInfo const& info ) = 0;
+ virtual void handleNonExpr
+ ( AssertionInfo const &info,
+ ResultWas::OfType resultType,
+ AssertionReaction &reaction ) = 0;
+
+
+
+ virtual bool lastAssertionPassed() = 0;
+ virtual void assertionPassed() = 0;
+
+ // Deprecated, do not use:
+ virtual std::string getCurrentTestName() const = 0;
+ virtual const AssertionResult* getLastResult() const = 0;
+ virtual void exceptionEarlyReported() = 0;
+ };
+
+ IResultCapture& getResultCapture();
+}
+
+#endif // CATCH_INTERFACES_CAPTURE_HPP_INCLUDED
+
+#include
+
+namespace Catch {
+
+ struct MessageInfo {
+ MessageInfo( StringRef _macroName,
+ SourceLineInfo const& _lineInfo,
+ ResultWas::OfType _type );
+
+ StringRef macroName;
+ std::string message;
+ SourceLineInfo lineInfo;
+ ResultWas::OfType type;
+ unsigned int sequence;
+
+ bool operator == (MessageInfo const& other) const {
+ return sequence == other.sequence;
+ }
+ bool operator < (MessageInfo const& other) const {
+ return sequence < other.sequence;
+ }
+ private:
+ static unsigned int globalCount;
+ };
+
+} // end namespace Catch
+
+#endif // CATCH_MESSAGE_INFO_HPP_INCLUDED
+
// Adapted from donated nonius code.
@@ -1557,7 +1583,12 @@ namespace Catch {
*/
virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
- //! Called with test cases that are skipped due to the test run aborting
+ /**
+ * Called with test cases that are skipped due to the test run aborting.
+ * NOT called for test cases that are explicitly skipped using the `SKIP` macro.
+ *
+ * Deprecated - will be removed in the next major release.
+ */
virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
//! Called if a fatal error (signal/structured exception) occured
@@ -1748,6 +1779,9 @@ namespace Catch {
*/
[[noreturn]] void throw_test_failure_exception();
+ //! Used to signal that the remainder of a test should be skipped
+ struct TestSkipException{};
+
} // namespace Catch
#endif // CATCH_TEST_FAILURE_EXCEPTION_HPP_INCLUDED
@@ -4058,6 +4092,7 @@ namespace Catch {
Error = BrightRed,
Success = Green,
+ Skip = LightGrey,
OriginalExpression = Cyan,
ReconstructedExpression = BrightYellow,
@@ -5811,6 +5846,7 @@ namespace Catch {
struct AssertionReaction {
bool shouldDebugBreak = false;
bool shouldThrow = false;
+ bool shouldSkip = false;
};
class AssertionHandler {
@@ -6183,7 +6219,7 @@ struct AutoReg : Detail::NonCopyable {
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
- namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
+ namespace{ const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
static void TestName()
#define INTERNAL_CATCH_TESTCASE( ... ) \
@@ -6194,7 +6230,7 @@ struct AutoReg : Detail::NonCopyable {
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
- namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
+ namespace{ const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
///////////////////////////////////////////////////////////////////////////////
@@ -6206,7 +6242,7 @@ struct AutoReg : Detail::NonCopyable {
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
void test(); \
}; \
- Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
+ const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
} \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
void TestName::test()
@@ -6260,6 +6296,7 @@ struct AutoReg : Detail::NonCopyable {
#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__ )
+ #define CATCH_SKIP( ... ) INTERNAL_CATCH_MSG( "SKIP", Catch::ResultWas::ExplicitSkip, Catch::ResultDisposition::Normal, __VA_ARGS__ )
#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
@@ -6313,6 +6350,7 @@ struct AutoReg : Detail::NonCopyable {
#define CATCH_FAIL( ... ) (void)(0)
#define CATCH_FAIL_CHECK( ... ) (void)(0)
#define CATCH_SUCCEED( ... ) (void)(0)
+ #define CATCH_SKIP( ... ) (void)(0)
#define CATCH_STATIC_REQUIRE( ... ) (void)(0)
#define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)
@@ -6357,6 +6395,7 @@ struct AutoReg : Detail::NonCopyable {
#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__ )
+ #define SKIP( ... ) INTERNAL_CATCH_MSG( "SKIP", Catch::ResultWas::ExplicitSkip, Catch::ResultDisposition::Normal, __VA_ARGS__ )
#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
@@ -6409,6 +6448,7 @@ struct AutoReg : Detail::NonCopyable {
#define FAIL( ... ) (void)(0)
#define FAIL_CHECK( ... ) (void)(0)
#define SUCCEED( ... ) (void)(0)
+ #define SKIP( ... ) (void)(0)
#define STATIC_REQUIRE( ... ) (void)(0)
#define STATIC_REQUIRE_FALSE( ... ) (void)(0)
@@ -7098,6 +7138,7 @@ struct AutoReg : Detail::NonCopyable {
+#include
#include
#include
@@ -7357,8 +7398,8 @@ namespace Catch {
#define CATCH_VERSION_MACROS_HPP_INCLUDED
#define CATCH_VERSION_MAJOR 3
-#define CATCH_VERSION_MINOR 2
-#define CATCH_VERSION_PATCH 1
+#define CATCH_VERSION_MINOR 3
+#define CATCH_VERSION_PATCH 0
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
@@ -7682,21 +7723,28 @@ namespace Detail {
return makeGenerators( value( T( CATCH_FORWARD( val ) ) ), CATCH_FORWARD( moreGenerators )... );
}
- auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
+ IGeneratorTracker* acquireGeneratorTracker( StringRef generatorName,
+ SourceLineInfo const& lineInfo );
+ IGeneratorTracker* createGeneratorTracker( StringRef generatorName,
+ SourceLineInfo lineInfo,
+ GeneratorBasePtr&& generator );
template
- // Note: The type after -> is weird, because VS2015 cannot parse
- // the expression used in the typedef inside, when it is in
- // return type. Yeah.
- auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval().get()) {
+ auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> typename decltype(generatorExpression())::type {
using UnderlyingType = typename decltype(generatorExpression())::type;
- IGeneratorTracker& tracker = acquireGeneratorTracker( generatorName, lineInfo );
- if (!tracker.hasGenerator()) {
- tracker.setGenerator(Catch::Detail::make_unique>(generatorExpression()));
+ IGeneratorTracker* tracker = acquireGeneratorTracker( generatorName, lineInfo );
+ // Creation of tracker is delayed after generator creation, so
+ // that constructing generator can fail without breaking everything.
+ if (!tracker) {
+ tracker = createGeneratorTracker(
+ generatorName,
+ lineInfo,
+ Catch::Detail::make_unique>(
+ generatorExpression() ) );
}
- auto const& generator = static_cast const&>( *tracker.getGenerator() );
+ auto const& generator = static_cast const&>( *tracker->getGenerator() );
return generator.get();
}
@@ -8515,7 +8563,10 @@ namespace Catch {
#if defined(__i386__) || defined(__x86_64__)
#define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
#elif defined(__aarch64__)
- #define CATCH_TRAP() __asm__(".inst 0xd43e0000")
+ #define CATCH_TRAP() __asm__(".inst 0xd43e0000")
+ #elif defined(__POWERPC__)
+ #define CATCH_TRAP() __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
+ : : : "memory","r0","r3","r4" ) /* NOLINT */
#endif
#elif defined(CATCH_PLATFORM_IPHONE)
@@ -9148,6 +9199,10 @@ namespace TestCaseTracking {
return lhs.name == rhs.name
&& lhs.location == rhs.location;
}
+ friend bool operator!=(NameAndLocation const& lhs,
+ NameAndLocation const& rhs) {
+ return !( lhs == rhs );
+ }
};
class ITracker;
@@ -9370,7 +9425,14 @@ namespace Catch {
void sectionEnded( SectionEndInfo const& endInfo ) override;
void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
- auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
+ IGeneratorTracker*
+ acquireGeneratorTracker( StringRef generatorName,
+ SourceLineInfo const& lineInfo ) override;
+ IGeneratorTracker* createGeneratorTracker(
+ StringRef generatorName,
+ SourceLineInfo lineInfo,
+ Generators::GeneratorBasePtr&& generator ) override;
+
void benchmarkPreparing( StringRef name ) override;
void benchmarkStarting( BenchmarkInfo const& info ) override;
@@ -9568,6 +9630,7 @@ namespace Catch {
#define CATCH_STRING_MANIP_HPP_INCLUDED
+#include
#include
#include
#include
@@ -10960,6 +11023,32 @@ public:
//! Creates a matcher that checks whether a std derived exception has the provided message
ExceptionMessageMatcher Message(std::string const& message);
+template
+class ExceptionMessageMatchesMatcher final
+ : public MatcherBase {
+ StringMatcherType m_matcher;
+
+public:
+ ExceptionMessageMatchesMatcher( StringMatcherType matcher ):
+ m_matcher( CATCH_MOVE( matcher ) ) {}
+
+ bool match( std::exception const& ex ) const override {
+ return m_matcher.match( ex.what() );
+ }
+
+ std::string describe() const override {
+ return " matches \"" + m_matcher.describe() + '"';
+ }
+};
+
+//! Creates a matcher that checks whether a message from an std derived
+//! exception matches a provided matcher
+template
+ExceptionMessageMatchesMatcher
+MessageMatches( StringMatcherType&& matcher ) {
+ return { CATCH_FORWARD( matcher ) };
+}
+
} // namespace Matchers
} // namespace Catch
@@ -11247,6 +11336,136 @@ namespace Catch {
#endif // CATCH_MATCHERS_QUANTIFIERS_HPP_INCLUDED
+#ifndef CATCH_MATCHERS_RANGE_EQUALS_HPP_INCLUDED
+#define CATCH_MATCHERS_RANGE_EQUALS_HPP_INCLUDED
+
+#include
+#include
+
+namespace Catch {
+ namespace Matchers {
+
+ /**
+ * Matcher for checking that an element contains the same
+ * elements in the same order
+ */
+ template
+ class RangeEqualsMatcher final : public MatcherGenericBase {
+ TargetRangeLike m_desired;
+ Equality m_predicate;
+
+ public:
+ template
+ RangeEqualsMatcher( TargetRangeLike2&& range,
+ Equality2&& predicate ):
+ m_desired( CATCH_FORWARD( range ) ),
+ m_predicate( CATCH_FORWARD( predicate ) ) {}
+
+ template
+ bool match( RangeLike&& rng ) const {
+ using std::begin;
+ using std::end;
+ return std::equal( begin(m_desired),
+ end(m_desired),
+ begin(rng),
+ end(rng),
+ m_predicate );
+ }
+
+ std::string describe() const override {
+ return "elements are " + Catch::Detail::stringify( m_desired );
+ }
+ };
+
+ /**
+ * Matcher for checking that an element contains the same
+ * elements (but not necessarily in the same order)
+ */
+ template
+ class UnorderedRangeEqualsMatcher final : public MatcherGenericBase {
+ TargetRangeLike m_desired;
+ Equality m_predicate;
+
+ public:
+ template
+ UnorderedRangeEqualsMatcher( TargetRangeLike2&& range,
+ Equality2&& predicate ):
+ m_desired( CATCH_FORWARD( range ) ),
+ m_predicate( CATCH_FORWARD( predicate ) ) {}
+
+ template
+ bool match( RangeLike&& rng ) const {
+ using std::begin;
+ using std::end;
+ return std::is_permutation( begin( m_desired ),
+ end( m_desired ),
+ begin( rng ),
+ end( rng ),
+ m_predicate );
+ }
+
+ std::string describe() const override {
+ return "unordered elements are " +
+ ::Catch::Detail::stringify( m_desired );
+ }
+ };
+
+ /**
+ * Creates a matcher that checks if all elements in a range are equal
+ * to all elements in another range.
+ *
+ * Uses `std::equal_to` to do the comparison
+ */
+ template
+ std::enable_if_t::value,
+ RangeEqualsMatcher>>
+ RangeEquals( RangeLike&& range ) {
+ return { CATCH_FORWARD( range ), std::equal_to<>{} };
+ }
+
+ /**
+ * Creates a matcher that checks if all elements in a range are equal
+ * to all elements in another range.
+ *
+ * Uses to provided predicate `predicate` to do the comparisons
+ */
+ template
+ RangeEqualsMatcher
+ RangeEquals( RangeLike&& range, Equality&& predicate ) {
+ return { CATCH_FORWARD( range ), CATCH_FORWARD( predicate ) };
+ }
+
+ /**
+ * Creates a matcher that checks if all elements in a range are equal
+ * to all elements in another range, in some permutation
+ *
+ * Uses `std::equal_to` to do the comparison
+ */
+ template
+ std::enable_if_t<
+ !Detail::is_matcher::value,
+ UnorderedRangeEqualsMatcher>>
+ UnorderedRangeEquals( RangeLike&& range ) {
+ return { CATCH_FORWARD( range ), std::equal_to<>{} };
+ }
+
+ /**
+ * Creates a matcher that checks if all elements in a range are equal
+ * to all elements in another range, in some permuation.
+ *
+ * Uses to provided predicate `predicate` to do the comparisons
+ */
+ template
+ UnorderedRangeEqualsMatcher
+ UnorderedRangeEquals( RangeLike&& range, Equality&& predicate ) {
+ return { CATCH_FORWARD( range ), CATCH_FORWARD( predicate ) };
+ }
+ } // namespace Matchers
+} // namespace Catch
+
+#endif // CATCH_MATCHERS_RANGE_EQUALS_HPP_INCLUDED
+
+
#ifndef CATCH_MATCHERS_STRING_HPP_INCLUDED
#define CATCH_MATCHERS_STRING_HPP_INCLUDED
diff --git a/meson.build b/meson.build
index 0cab573e..f5b4c9e1 100644
--- a/meson.build
+++ b/meson.build
@@ -8,7 +8,7 @@
project(
'catch2',
'cpp',
- version: '3.2.1', # CML version placeholder, don't delete
+ version: '3.3.0', # CML version placeholder, don't delete
license: 'BSL-1.0',
meson_version: '>=0.50.0',
)
diff --git a/src/catch2/catch_version.cpp b/src/catch2/catch_version.cpp
index b6b818a0..26fe92c7 100644
--- a/src/catch2/catch_version.cpp
+++ b/src/catch2/catch_version.cpp
@@ -36,7 +36,7 @@ namespace Catch {
}
Version const& libraryVersion() {
- static Version version( 3, 2, 1, "", 0 );
+ static Version version( 3, 3, 0, "", 0 );
return version;
}
diff --git a/src/catch2/catch_version_macros.hpp b/src/catch2/catch_version_macros.hpp
index f61d999d..d8c11d3f 100644
--- a/src/catch2/catch_version_macros.hpp
+++ b/src/catch2/catch_version_macros.hpp
@@ -9,7 +9,7 @@
#define CATCH_VERSION_MACROS_HPP_INCLUDED
#define CATCH_VERSION_MAJOR 3
-#define CATCH_VERSION_MINOR 2
-#define CATCH_VERSION_PATCH 1
+#define CATCH_VERSION_MINOR 3
+#define CATCH_VERSION_PATCH 0
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED