This commit is contained in:
Martin Hořeňovský 2023-01-22 19:43:11 +01:00
parent 8359a6b244
commit c837cb4a8a
No known key found for this signature in database
GPG key ID: DE48307B8B0D381A
9 changed files with 574 additions and 205 deletions

View file

@ -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 <limits>
#include <stdexcept>
namespace Catch {
@ -4538,11 +4565,14 @@ namespace Catch {
return {};
}
return static_cast<unsigned int>(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<GeneratorTracker*>( childTracker );
} else {
auto newTracker =
Catch::Detail::make_unique<GeneratorTracker>(
nameAndLocation, ctx, &currentTracker );
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<std::string>(generatorName), lineInfo ) );
GeneratorTracker* tracker = GeneratorTracker::acquire(
m_trackerContext,
TestCaseTracking::NameAndLocation(
static_cast<std::string>( generatorName ), lineInfo ) );
m_lastAssertionInfo.lineInfo = lineInfo;
return tracker;
}
IGeneratorTracker* RunContext::createGeneratorTracker(
StringRef generatorName,
SourceLineInfo lineInfo,
Generators::GeneratorBasePtr&& generator ) {
auto nameAndLoc = TestCaseTracking::NameAndLocation( static_cast<std::string>( 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<Generators::GeneratorTracker>(
nameAndLoc, m_trackerContext, &currentTracker );
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<std::string>(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 <cstdint>
#include <iomanip>
#include <type_traits>
@ -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<std::size_t>(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<SummaryColumn> 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();
}