Stop exceptions in generator constructors from aborting the binary

Fixes #2615
This commit is contained in:
Martin Hořeňovský 2023-01-17 11:04:49 +01:00
parent adf43494e1
commit 8359a6b244
No known key found for this signature in database
GPG Key ID: DE48307B8B0D381A
25 changed files with 230 additions and 40 deletions

View File

@ -27,9 +27,16 @@ namespace Detail {
GeneratorUntypedBase::~GeneratorUntypedBase() = default; GeneratorUntypedBase::~GeneratorUntypedBase() = default;
auto acquireGeneratorTracker(StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& { IGeneratorTracker* acquireGeneratorTracker(StringRef generatorName, SourceLineInfo const& lineInfo ) {
return getResultCapture().acquireGeneratorTracker( generatorName, 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 Generators
} // namespace Catch } // namespace Catch

View File

@ -204,18 +204,28 @@ namespace Detail {
return makeGenerators( value( T( CATCH_FORWARD( val ) ) ), CATCH_FORWARD( moreGenerators )... ); 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<typename L> template<typename L>
auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> typename decltype(generatorExpression())::type { auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> typename decltype(generatorExpression())::type {
using UnderlyingType = typename decltype(generatorExpression())::type; using UnderlyingType = typename decltype(generatorExpression())::type;
IGeneratorTracker& tracker = acquireGeneratorTracker( generatorName, lineInfo ); IGeneratorTracker* tracker = acquireGeneratorTracker( generatorName, lineInfo );
if (!tracker.hasGenerator()) { // Creation of tracker is delayed after generator creation, so
tracker.setGenerator(Catch::Detail::make_unique<Generators<UnderlyingType>>(generatorExpression())); // that constructing generator can fail without breaking everything.
if (!tracker) {
tracker = createGeneratorTracker(
generatorName,
lineInfo,
Catch::Detail::make_unique<Generators<UnderlyingType>>(
generatorExpression() ) );
} }
auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() ); auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker->getGenerator() );
return generator.get(); return generator.get();
} }

View File

@ -13,6 +13,7 @@
#include <catch2/internal/catch_stringref.hpp> #include <catch2/internal/catch_stringref.hpp>
#include <catch2/internal/catch_result_type.hpp> #include <catch2/internal/catch_result_type.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
namespace Catch { namespace Catch {
@ -33,6 +34,12 @@ namespace Catch {
template <typename Duration = std::chrono::duration<double, std::nano>> template <typename Duration = std::chrono::duration<double, std::nano>>
struct BenchmarkStats; struct BenchmarkStats;
namespace Generators {
class GeneratorUntypedBase;
using GeneratorBasePtr = Catch::Detail::unique_ptr<GeneratorUntypedBase>;
}
class IResultCapture { class IResultCapture {
public: public:
virtual ~IResultCapture(); virtual ~IResultCapture();
@ -42,7 +49,13 @@ namespace Catch {
virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0; virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0; virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
virtual auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 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 benchmarkPreparing( StringRef name ) = 0;
virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0; virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;

View File

@ -34,7 +34,7 @@ namespace Catch {
{} {}
~GeneratorTracker() override; ~GeneratorTracker() override;
static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) { static GeneratorTracker* acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
GeneratorTracker* tracker; GeneratorTracker* tracker;
ITracker& currentTracker = ctx.currentTracker(); ITracker& currentTracker = ctx.currentTracker();
@ -61,18 +61,14 @@ namespace Catch {
assert( childTracker->isGeneratorTracker() ); assert( childTracker->isGeneratorTracker() );
tracker = static_cast<GeneratorTracker*>( childTracker ); tracker = static_cast<GeneratorTracker*>( childTracker );
} else { } else {
auto newTracker = return nullptr;
Catch::Detail::make_unique<GeneratorTracker>(
nameAndLocation, ctx, &currentTracker );
tracker = newTracker.get();
currentTracker.addChild( CATCH_MOVE(newTracker) );
} }
if( !tracker->isComplete() ) { if( !tracker->isComplete() ) {
tracker->open(); tracker->open();
} }
return *tracker; return tracker;
} }
// TrackerBase interface // TrackerBase interface
@ -141,6 +137,7 @@ namespace Catch {
// has a side-effect, where it consumes generator's current // has a side-effect, where it consumes generator's current
// value, but we do not want to invoke the side-effect if // value, but we do not want to invoke the side-effect if
// this generator is still waiting for any child to start. // this generator is still waiting for any child to start.
assert( m_generator && "Tracker without generator" );
if ( should_wait_for_child || if ( should_wait_for_child ||
( m_runState == CompletedSuccessfully && ( m_runState == CompletedSuccessfully &&
m_generator->countedNext() ) ) { m_generator->countedNext() ) ) {
@ -314,14 +311,39 @@ namespace Catch {
return true; return true;
} }
auto RunContext::acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& { IGeneratorTracker*
RunContext::acquireGeneratorTracker( StringRef generatorName,
SourceLineInfo const& lineInfo ) {
using namespace Generators; using namespace Generators;
GeneratorTracker& tracker = GeneratorTracker::acquire(m_trackerContext, GeneratorTracker* tracker = GeneratorTracker::acquire(
TestCaseTracking::NameAndLocation( static_cast<std::string>(generatorName), lineInfo ) ); m_trackerContext,
TestCaseTracking::NameAndLocation(
static_cast<std::string>( generatorName ), lineInfo ) );
m_lastAssertionInfo.lineInfo = lineInfo; m_lastAssertionInfo.lineInfo = lineInfo;
return tracker; 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) { bool RunContext::testForMissingAssertions(Counts& assertions) {
if (assertions.total() != 0) if (assertions.total() != 0)
return false; return false;

View File

@ -73,7 +73,14 @@ namespace Catch {
void sectionEnded( SectionEndInfo const& endInfo ) override; void sectionEnded( SectionEndInfo const& endInfo ) override;
void sectionEndedEarly( 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 benchmarkPreparing( StringRef name ) override;
void benchmarkStarting( BenchmarkInfo const& info ) override; void benchmarkStarting( BenchmarkInfo const& info ) override;

View File

@ -27,6 +27,10 @@ namespace TestCaseTracking {
return lhs.name == rhs.name return lhs.name == rhs.name
&& lhs.location == rhs.location; && lhs.location == rhs.location;
} }
friend bool operator!=(NameAndLocation const& lhs,
NameAndLocation const& rhs) {
return !( lhs == rhs );
}
}; };
class ITracker; class ITracker;

View File

@ -25,6 +25,7 @@ Nor would this
:test-result: PASS #1954 - 7 arg template test case sig compiles - 5, 3, 1, 1, 1, 0, 0 :test-result: PASS #1954 - 7 arg template test case sig compiles - 5, 3, 1, 1, 1, 0, 0
:test-result: PASS #2152 - ULP checks between differently signed values were wrong - double :test-result: PASS #2152 - ULP checks between differently signed values were wrong - double
:test-result: PASS #2152 - ULP checks between differently signed values were wrong - float :test-result: PASS #2152 - ULP checks between differently signed values were wrong - float
:test-result: XFAIL #2615 - Throwing in constructor generator fails test case but does not abort
:test-result: XFAIL #748 - captures with unexpected exceptions :test-result: XFAIL #748 - captures with unexpected exceptions
:test-result: PASS #809 :test-result: PASS #809
:test-result: PASS #833 :test-result: PASS #833

View File

@ -23,6 +23,7 @@
:test-result: PASS #1954 - 7 arg template test case sig compiles - 5, 3, 1, 1, 1, 0, 0 :test-result: PASS #1954 - 7 arg template test case sig compiles - 5, 3, 1, 1, 1, 0, 0
:test-result: PASS #2152 - ULP checks between differently signed values were wrong - double :test-result: PASS #2152 - ULP checks between differently signed values were wrong - double
:test-result: PASS #2152 - ULP checks between differently signed values were wrong - float :test-result: PASS #2152 - ULP checks between differently signed values were wrong - float
:test-result: XFAIL #2615 - Throwing in constructor generator fails test case but does not abort
:test-result: XFAIL #748 - captures with unexpected exceptions :test-result: XFAIL #748 - captures with unexpected exceptions
:test-result: PASS #809 :test-result: PASS #809
:test-result: PASS #833 :test-result: PASS #833

View File

@ -84,6 +84,7 @@ Matchers.tests.cpp:<line number>: passed: smallest_non_zero, WithinULP( -smalles
Matchers.tests.cpp:<line number>: passed: smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0 not is within 1 ULPs of -4.9406564584124654e-324 ([-9.8813129168249309e-324, -0.0000000000000000e+00]) Matchers.tests.cpp:<line number>: passed: smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0 not is within 1 ULPs of -4.9406564584124654e-324 ([-9.8813129168249309e-324, -0.0000000000000000e+00])
Matchers.tests.cpp:<line number>: passed: smallest_non_zero, WithinULP( -smallest_non_zero, 2 ) for: 0.0f is within 2 ULPs of -1.40129846e-45f ([-4.20389539e-45, 1.40129846e-45]) Matchers.tests.cpp:<line number>: passed: smallest_non_zero, WithinULP( -smallest_non_zero, 2 ) for: 0.0f is within 2 ULPs of -1.40129846e-45f ([-4.20389539e-45, 1.40129846e-45])
Matchers.tests.cpp:<line number>: passed: smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.00000000e+00]) Matchers.tests.cpp:<line number>: passed: smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.00000000e+00])
Generators.tests.cpp:<line number>: failed: unexpected exception with message: 'failure to init'
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42' with 1 message: 'expected exception' Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42' with 1 message: 'expected exception'
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42'; expression was: thisThrows() with 1 message: 'expected exception' Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42'; expression was: thisThrows() with 1 message: 'expected exception'
Exception.tests.cpp:<line number>: passed: thisThrows() with 1 message: 'answer := 42' Exception.tests.cpp:<line number>: passed: thisThrows() with 1 message: 'answer := 42'
@ -2521,7 +2522,7 @@ InternalBenchmark.tests.cpp:<line number>: passed: med == 18. for: 18.0 == 18.0
InternalBenchmark.tests.cpp:<line number>: passed: q3 == 23. for: 23.0 == 23.0 InternalBenchmark.tests.cpp:<line number>: passed: q3 == 23. for: 23.0 == 23.0
Misc.tests.cpp:<line number>: passed: Misc.tests.cpp:<line number>: passed:
Misc.tests.cpp:<line number>: passed: Misc.tests.cpp:<line number>: passed:
test cases: 407 | 308 passed | 84 failed | 5 skipped | 10 failed as expected test cases: 408 | 308 passed | 84 failed | 5 skipped | 11 failed as expected
assertions: 2209 | 2033 passed | 145 failed | 31 failed as expected assertions: 2210 | 2033 passed | 145 failed | 32 failed as expected

View File

@ -82,6 +82,7 @@ Matchers.tests.cpp:<line number>: passed: smallest_non_zero, WithinULP( -smalles
Matchers.tests.cpp:<line number>: passed: smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0 not is within 1 ULPs of -4.9406564584124654e-324 ([-9.8813129168249309e-324, -0.0000000000000000e+00]) Matchers.tests.cpp:<line number>: passed: smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0 not is within 1 ULPs of -4.9406564584124654e-324 ([-9.8813129168249309e-324, -0.0000000000000000e+00])
Matchers.tests.cpp:<line number>: passed: smallest_non_zero, WithinULP( -smallest_non_zero, 2 ) for: 0.0f is within 2 ULPs of -1.40129846e-45f ([-4.20389539e-45, 1.40129846e-45]) Matchers.tests.cpp:<line number>: passed: smallest_non_zero, WithinULP( -smallest_non_zero, 2 ) for: 0.0f is within 2 ULPs of -1.40129846e-45f ([-4.20389539e-45, 1.40129846e-45])
Matchers.tests.cpp:<line number>: passed: smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.00000000e+00]) Matchers.tests.cpp:<line number>: passed: smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.00000000e+00])
Generators.tests.cpp:<line number>: failed: unexpected exception with message: 'failure to init'
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42' with 1 message: 'expected exception' Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42' with 1 message: 'expected exception'
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42'; expression was: thisThrows() with 1 message: 'expected exception' Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42'; expression was: thisThrows() with 1 message: 'expected exception'
Exception.tests.cpp:<line number>: passed: thisThrows() with 1 message: 'answer := 42' Exception.tests.cpp:<line number>: passed: thisThrows() with 1 message: 'answer := 42'
@ -2510,7 +2511,7 @@ InternalBenchmark.tests.cpp:<line number>: passed: med == 18. for: 18.0 == 18.0
InternalBenchmark.tests.cpp:<line number>: passed: q3 == 23. for: 23.0 == 23.0 InternalBenchmark.tests.cpp:<line number>: passed: q3 == 23. for: 23.0 == 23.0
Misc.tests.cpp:<line number>: passed: Misc.tests.cpp:<line number>: passed:
Misc.tests.cpp:<line number>: passed: Misc.tests.cpp:<line number>: passed:
test cases: 407 | 308 passed | 84 failed | 5 skipped | 10 failed as expected test cases: 408 | 308 passed | 84 failed | 5 skipped | 11 failed as expected
assertions: 2209 | 2033 passed | 145 failed | 31 failed as expected assertions: 2210 | 2033 passed | 145 failed | 32 failed as expected

View File

@ -27,6 +27,16 @@ Tricky.tests.cpp:<line number>: FAILED:
explicitly with message: explicitly with message:
1514 1514
-------------------------------------------------------------------------------
#2615 - Throwing in constructor generator fails test case but does not abort
-------------------------------------------------------------------------------
Generators.tests.cpp:<line number>
...............................................................................
Generators.tests.cpp:<line number>: FAILED:
due to unexpected exception with message:
failure to init
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
#748 - captures with unexpected exceptions #748 - captures with unexpected exceptions
outside assertions outside assertions
@ -1523,6 +1533,6 @@ due to unexpected exception with message:
Why would you throw a std::string? Why would you throw a std::string?
=============================================================================== ===============================================================================
test cases: 407 | 322 passed | 69 failed | 6 skipped | 10 failed as expected test cases: 408 | 322 passed | 69 failed | 6 skipped | 11 failed as expected
assertions: 2192 | 2033 passed | 128 failed | 31 failed as expected assertions: 2193 | 2033 passed | 128 failed | 32 failed as expected

View File

@ -761,6 +761,16 @@ with expansion:
0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0. 0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.
00000000e+00]) 00000000e+00])
-------------------------------------------------------------------------------
#2615 - Throwing in constructor generator fails test case but does not abort
-------------------------------------------------------------------------------
Generators.tests.cpp:<line number>
...............................................................................
Generators.tests.cpp:<line number>: FAILED:
due to unexpected exception with message:
failure to init
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
#748 - captures with unexpected exceptions #748 - captures with unexpected exceptions
outside assertions outside assertions
@ -18093,6 +18103,6 @@ Misc.tests.cpp:<line number>
Misc.tests.cpp:<line number>: PASSED: Misc.tests.cpp:<line number>: PASSED:
=============================================================================== ===============================================================================
test cases: 407 | 308 passed | 84 failed | 5 skipped | 10 failed as expected test cases: 408 | 308 passed | 84 failed | 5 skipped | 11 failed as expected
assertions: 2209 | 2033 passed | 145 failed | 31 failed as expected assertions: 2210 | 2033 passed | 145 failed | 32 failed as expected

View File

@ -759,6 +759,16 @@ with expansion:
0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0. 0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.
00000000e+00]) 00000000e+00])
-------------------------------------------------------------------------------
#2615 - Throwing in constructor generator fails test case but does not abort
-------------------------------------------------------------------------------
Generators.tests.cpp:<line number>
...............................................................................
Generators.tests.cpp:<line number>: FAILED:
due to unexpected exception with message:
failure to init
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
#748 - captures with unexpected exceptions #748 - captures with unexpected exceptions
outside assertions outside assertions
@ -18082,6 +18092,6 @@ Misc.tests.cpp:<line number>
Misc.tests.cpp:<line number>: PASSED: Misc.tests.cpp:<line number>: PASSED:
=============================================================================== ===============================================================================
test cases: 407 | 308 passed | 84 failed | 5 skipped | 10 failed as expected test cases: 408 | 308 passed | 84 failed | 5 skipped | 11 failed as expected
assertions: 2209 | 2033 passed | 145 failed | 31 failed as expected assertions: 2210 | 2033 passed | 145 failed | 32 failed as expected

View File

@ -761,6 +761,16 @@ with expansion:
0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0. 0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.
00000000e+00]) 00000000e+00])
-------------------------------------------------------------------------------
#2615 - Throwing in constructor generator fails test case but does not abort
-------------------------------------------------------------------------------
Generators.tests.cpp:<line number>
...............................................................................
Generators.tests.cpp:<line number>: FAILED:
due to unexpected exception with message:
failure to init
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
#748 - captures with unexpected exceptions #748 - captures with unexpected exceptions
outside assertions outside assertions
@ -941,6 +951,6 @@ Condition.tests.cpp:<line number>: FAILED:
CHECK( true != true ) CHECK( true != true )
=============================================================================== ===============================================================================
test cases: 32 | 27 passed | 3 failed | 2 failed as expected test cases: 33 | 27 passed | 3 failed | 3 failed as expected
assertions: 101 | 94 passed | 4 failed | 3 failed as expected assertions: 102 | 94 passed | 4 failed | 4 failed as expected

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<testsuitesloose text artifact <testsuitesloose text artifact
> >
<testsuite name="<exe-name>" errors="17" failures="128" skipped="11" tests="2220" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}"> <testsuite name="<exe-name>" errors="17" failures="128" skipped="11" tests="2221" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<properties> <properties>
<property name="random-seed" value="1"/> <property name="random-seed" value="1"/>
<property name="filters" value="&quot;*&quot; ~[!nonportable] ~[!benchmark] ~[approvals]"/> <property name="filters" value="&quot;*&quot; ~[!nonportable] ~[!benchmark] ~[approvals]"/>
@ -48,6 +48,14 @@ Nor would this
<testcase classname="<exe-name>.global" name="#1954 - 7 arg template test case sig compiles - 5, 3, 1, 1, 1, 0, 0" time="{duration}" status="run"/> <testcase classname="<exe-name>.global" name="#1954 - 7 arg template test case sig compiles - 5, 3, 1, 1, 1, 0, 0" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="#2152 - ULP checks between differently signed values were wrong - double" time="{duration}" status="run"/> <testcase classname="<exe-name>.global" name="#2152 - ULP checks between differently signed values were wrong - double" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="#2152 - ULP checks between differently signed values were wrong - float" time="{duration}" status="run"/> <testcase classname="<exe-name>.global" name="#2152 - ULP checks between differently signed values were wrong - float" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="#2615 - Throwing in constructor generator fails test case but does not abort" time="{duration}" status="run">
<skipped message="TEST_CASE tagged with !mayfail"/>
<error type="TEST_CASE">
FAILED:
failure to init
at Generators.tests.cpp:<line number>
</error>
</testcase>
<testcase classname="<exe-name>.global" name="#748 - captures with unexpected exceptions/outside assertions" time="{duration}" status="run"> <testcase classname="<exe-name>.global" name="#748 - captures with unexpected exceptions/outside assertions" time="{duration}" status="run">
<skipped message="TEST_CASE tagged with !mayfail"/> <skipped message="TEST_CASE tagged with !mayfail"/>
<error type="TEST_CASE"> <error type="TEST_CASE">

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<testsuites> <testsuites>
<testsuite name="<exe-name>" errors="17" failures="128" skipped="11" tests="2220" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}"> <testsuite name="<exe-name>" errors="17" failures="128" skipped="11" tests="2221" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<properties> <properties>
<property name="random-seed" value="1"/> <property name="random-seed" value="1"/>
<property name="filters" value="&quot;*&quot; ~[!nonportable] ~[!benchmark] ~[approvals]"/> <property name="filters" value="&quot;*&quot; ~[!nonportable] ~[!benchmark] ~[approvals]"/>
@ -47,6 +47,14 @@ Nor would this
<testcase classname="<exe-name>.global" name="#1954 - 7 arg template test case sig compiles - 5, 3, 1, 1, 1, 0, 0" time="{duration}" status="run"/> <testcase classname="<exe-name>.global" name="#1954 - 7 arg template test case sig compiles - 5, 3, 1, 1, 1, 0, 0" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="#2152 - ULP checks between differently signed values were wrong - double" time="{duration}" status="run"/> <testcase classname="<exe-name>.global" name="#2152 - ULP checks between differently signed values were wrong - double" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="#2152 - ULP checks between differently signed values were wrong - float" time="{duration}" status="run"/> <testcase classname="<exe-name>.global" name="#2152 - ULP checks between differently signed values were wrong - float" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="#2615 - Throwing in constructor generator fails test case but does not abort" time="{duration}" status="run">
<skipped message="TEST_CASE tagged with !mayfail"/>
<error type="TEST_CASE">
FAILED:
failure to init
at Generators.tests.cpp:<line number>
</error>
</testcase>
<testcase classname="<exe-name>.global" name="#748 - captures with unexpected exceptions/outside assertions" time="{duration}" status="run"> <testcase classname="<exe-name>.global" name="#748 - captures with unexpected exceptions/outside assertions" time="{duration}" status="run">
<skipped message="TEST_CASE tagged with !mayfail"/> <skipped message="TEST_CASE tagged with !mayfail"/>
<error type="TEST_CASE"> <error type="TEST_CASE">

View File

@ -1027,6 +1027,13 @@ at Exception.tests.cpp:<line number>
<file path="tests/<exe-name>/UsageTests/Generators.tests.cpp"> <file path="tests/<exe-name>/UsageTests/Generators.tests.cpp">
<testCase name="#1913 - GENERATE inside a for loop should not keep recreating the generator" duration="{duration}"/> <testCase name="#1913 - GENERATE inside a for loop should not keep recreating the generator" duration="{duration}"/>
<testCase name="#1913 - GENERATEs can share a line" duration="{duration}"/> <testCase name="#1913 - GENERATEs can share a line" duration="{duration}"/>
<testCase name="#2615 - Throwing in constructor generator fails test case but does not abort" duration="{duration}">
<skipped message="TEST_CASE()">
FAILED:
failure to init
at Generators.tests.cpp:<line number>
</skipped>
</testCase>
<testCase name="3x3x3 ints" duration="{duration}"/> <testCase name="3x3x3 ints" duration="{duration}"/>
<testCase name="Copy and then generate a range/from var and iterators" duration="{duration}"/> <testCase name="Copy and then generate a range/from var and iterators" duration="{duration}"/>
<testCase name="Copy and then generate a range/From a temporary container" duration="{duration}"/> <testCase name="Copy and then generate a range/From a temporary container" duration="{duration}"/>

View File

@ -1026,6 +1026,13 @@ at Exception.tests.cpp:<line number>
<file path="tests/<exe-name>/UsageTests/Generators.tests.cpp"> <file path="tests/<exe-name>/UsageTests/Generators.tests.cpp">
<testCase name="#1913 - GENERATE inside a for loop should not keep recreating the generator" duration="{duration}"/> <testCase name="#1913 - GENERATE inside a for loop should not keep recreating the generator" duration="{duration}"/>
<testCase name="#1913 - GENERATEs can share a line" duration="{duration}"/> <testCase name="#1913 - GENERATEs can share a line" duration="{duration}"/>
<testCase name="#2615 - Throwing in constructor generator fails test case but does not abort" duration="{duration}">
<skipped message="TEST_CASE()">
FAILED:
failure to init
at Generators.tests.cpp:<line number>
</skipped>
</testCase>
<testCase name="3x3x3 ints" duration="{duration}"/> <testCase name="3x3x3 ints" duration="{duration}"/>
<testCase name="Copy and then generate a range/from var and iterators" duration="{duration}"/> <testCase name="Copy and then generate a range/from var and iterators" duration="{duration}"/>
<testCase name="Copy and then generate a range/From a temporary container" duration="{duration}"/> <testCase name="Copy and then generate a range/From a temporary container" duration="{duration}"/>

View File

@ -164,6 +164,8 @@ ok {test-number} - smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0
ok {test-number} - smallest_non_zero, WithinULP( -smallest_non_zero, 2 ) for: 0.0f is within 2 ULPs of -1.40129846e-45f ([-4.20389539e-45, 1.40129846e-45]) ok {test-number} - smallest_non_zero, WithinULP( -smallest_non_zero, 2 ) for: 0.0f is within 2 ULPs of -1.40129846e-45f ([-4.20389539e-45, 1.40129846e-45])
# #2152 - ULP checks between differently signed values were wrong - float # #2152 - ULP checks between differently signed values were wrong - float
ok {test-number} - smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.00000000e+00]) ok {test-number} - smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.00000000e+00])
# #2615 - Throwing in constructor generator fails test case but does not abort
not ok {test-number} - unexpected exception with message: 'failure to init'
# #748 - captures with unexpected exceptions # #748 - captures with unexpected exceptions
not ok {test-number} - unexpected exception with message: 'answer := 42' with 1 message: 'expected exception' not ok {test-number} - unexpected exception with message: 'answer := 42' with 1 message: 'expected exception'
# #748 - captures with unexpected exceptions # #748 - captures with unexpected exceptions
@ -4443,5 +4445,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
ok {test-number} - ok {test-number} -
# xmlentitycheck # xmlentitycheck
ok {test-number} - ok {test-number} -
1..2220 1..2221

View File

@ -162,6 +162,8 @@ ok {test-number} - smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0
ok {test-number} - smallest_non_zero, WithinULP( -smallest_non_zero, 2 ) for: 0.0f is within 2 ULPs of -1.40129846e-45f ([-4.20389539e-45, 1.40129846e-45]) ok {test-number} - smallest_non_zero, WithinULP( -smallest_non_zero, 2 ) for: 0.0f is within 2 ULPs of -1.40129846e-45f ([-4.20389539e-45, 1.40129846e-45])
# #2152 - ULP checks between differently signed values were wrong - float # #2152 - ULP checks between differently signed values were wrong - float
ok {test-number} - smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.00000000e+00]) ok {test-number} - smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.00000000e+00])
# #2615 - Throwing in constructor generator fails test case but does not abort
not ok {test-number} - unexpected exception with message: 'failure to init'
# #748 - captures with unexpected exceptions # #748 - captures with unexpected exceptions
not ok {test-number} - unexpected exception with message: 'answer := 42' with 1 message: 'expected exception' not ok {test-number} - unexpected exception with message: 'answer := 42' with 1 message: 'expected exception'
# #748 - captures with unexpected exceptions # #748 - captures with unexpected exceptions
@ -4432,5 +4434,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
ok {test-number} - ok {test-number} -
# xmlentitycheck # xmlentitycheck
ok {test-number} - ok {test-number} -
1..2220 1..2221

View File

@ -52,6 +52,9 @@
##teamcity[testFinished name='#2152 - ULP checks between differently signed values were wrong - double' duration="{duration}"] ##teamcity[testFinished name='#2152 - ULP checks between differently signed values were wrong - double' duration="{duration}"]
##teamcity[testStarted name='#2152 - ULP checks between differently signed values were wrong - float'] ##teamcity[testStarted name='#2152 - ULP checks between differently signed values were wrong - float']
##teamcity[testFinished name='#2152 - ULP checks between differently signed values were wrong - float' duration="{duration}"] ##teamcity[testFinished name='#2152 - ULP checks between differently signed values were wrong - float' duration="{duration}"]
##teamcity[testStarted name='#2615 - Throwing in constructor generator fails test case but does not abort']
##teamcity[testIgnored name='#2615 - Throwing in constructor generator fails test case but does not abort' message='Generators.tests.cpp:<line number>|n...............................................................................|n|nGenerators.tests.cpp:<line number>|nunexpected exception with message:|n "failure to init"- failure ignore as test marked as |'ok to fail|'|n']
##teamcity[testFinished name='#2615 - Throwing in constructor generator fails test case but does not abort' duration="{duration}"]
##teamcity[testStarted name='#748 - captures with unexpected exceptions'] ##teamcity[testStarted name='#748 - captures with unexpected exceptions']
##teamcity[testIgnored name='#748 - captures with unexpected exceptions' message='-------------------------------------------------------------------------------|noutside assertions|n-------------------------------------------------------------------------------|nException.tests.cpp:<line number>|n...............................................................................|n|nException.tests.cpp:<line number>|nunexpected exception with messages:|n "answer := 42"|n "expected exception"- failure ignore as test marked as |'ok to fail|'|n'] ##teamcity[testIgnored name='#748 - captures with unexpected exceptions' message='-------------------------------------------------------------------------------|noutside assertions|n-------------------------------------------------------------------------------|nException.tests.cpp:<line number>|n...............................................................................|n|nException.tests.cpp:<line number>|nunexpected exception with messages:|n "answer := 42"|n "expected exception"- failure ignore as test marked as |'ok to fail|'|n']
##teamcity[testIgnored name='#748 - captures with unexpected exceptions' message='-------------------------------------------------------------------------------|ninside REQUIRE_NOTHROW|n-------------------------------------------------------------------------------|nException.tests.cpp:<line number>|n...............................................................................|n|nException.tests.cpp:<line number>|nunexpected exception with messages:|n "answer := 42"|n "expected exception"|n REQUIRE_NOTHROW( thisThrows() )|nwith expansion:|n thisThrows()|n- failure ignore as test marked as |'ok to fail|'|n'] ##teamcity[testIgnored name='#748 - captures with unexpected exceptions' message='-------------------------------------------------------------------------------|ninside REQUIRE_NOTHROW|n-------------------------------------------------------------------------------|nException.tests.cpp:<line number>|n...............................................................................|n|nException.tests.cpp:<line number>|nunexpected exception with messages:|n "answer := 42"|n "expected exception"|n REQUIRE_NOTHROW( thisThrows() )|nwith expansion:|n thisThrows()|n- failure ignore as test marked as |'ok to fail|'|n']

View File

@ -52,6 +52,9 @@
##teamcity[testFinished name='#2152 - ULP checks between differently signed values were wrong - double' duration="{duration}"] ##teamcity[testFinished name='#2152 - ULP checks between differently signed values were wrong - double' duration="{duration}"]
##teamcity[testStarted name='#2152 - ULP checks between differently signed values were wrong - float'] ##teamcity[testStarted name='#2152 - ULP checks between differently signed values were wrong - float']
##teamcity[testFinished name='#2152 - ULP checks between differently signed values were wrong - float' duration="{duration}"] ##teamcity[testFinished name='#2152 - ULP checks between differently signed values were wrong - float' duration="{duration}"]
##teamcity[testStarted name='#2615 - Throwing in constructor generator fails test case but does not abort']
##teamcity[testIgnored name='#2615 - Throwing in constructor generator fails test case but does not abort' message='Generators.tests.cpp:<line number>|n...............................................................................|n|nGenerators.tests.cpp:<line number>|nunexpected exception with message:|n "failure to init"- failure ignore as test marked as |'ok to fail|'|n']
##teamcity[testFinished name='#2615 - Throwing in constructor generator fails test case but does not abort' duration="{duration}"]
##teamcity[testStarted name='#748 - captures with unexpected exceptions'] ##teamcity[testStarted name='#748 - captures with unexpected exceptions']
##teamcity[testIgnored name='#748 - captures with unexpected exceptions' message='-------------------------------------------------------------------------------|noutside assertions|n-------------------------------------------------------------------------------|nException.tests.cpp:<line number>|n...............................................................................|n|nException.tests.cpp:<line number>|nunexpected exception with messages:|n "answer := 42"|n "expected exception"- failure ignore as test marked as |'ok to fail|'|n'] ##teamcity[testIgnored name='#748 - captures with unexpected exceptions' message='-------------------------------------------------------------------------------|noutside assertions|n-------------------------------------------------------------------------------|nException.tests.cpp:<line number>|n...............................................................................|n|nException.tests.cpp:<line number>|nunexpected exception with messages:|n "answer := 42"|n "expected exception"- failure ignore as test marked as |'ok to fail|'|n']
##teamcity[testIgnored name='#748 - captures with unexpected exceptions' message='-------------------------------------------------------------------------------|ninside REQUIRE_NOTHROW|n-------------------------------------------------------------------------------|nException.tests.cpp:<line number>|n...............................................................................|n|nException.tests.cpp:<line number>|nunexpected exception with messages:|n "answer := 42"|n "expected exception"|n REQUIRE_NOTHROW( thisThrows() )|nwith expansion:|n thisThrows()|n- failure ignore as test marked as |'ok to fail|'|n'] ##teamcity[testIgnored name='#748 - captures with unexpected exceptions' message='-------------------------------------------------------------------------------|ninside REQUIRE_NOTHROW|n-------------------------------------------------------------------------------|nException.tests.cpp:<line number>|n...............................................................................|n|nException.tests.cpp:<line number>|nunexpected exception with messages:|n "answer := 42"|n "expected exception"|n REQUIRE_NOTHROW( thisThrows() )|nwith expansion:|n thisThrows()|n- failure ignore as test marked as |'ok to fail|'|n']

View File

@ -667,6 +667,12 @@ Nor would this
</Expression> </Expression>
<OverallResult success="true" skips="0"/> <OverallResult success="true" skips="0"/>
</TestCase> </TestCase>
<TestCase name="#2615 - Throwing in constructor generator fails test case but does not abort" tags="[!shouldfail]" filename="tests/<exe-name>/UsageTests/Generators.tests.cpp" >
<Exception filename="tests/<exe-name>/UsageTests/Generators.tests.cpp" >
failure to init
</Exception>
<OverallResult success="true" skips="0"/>
</TestCase>
<TestCase name="#748 - captures with unexpected exceptions" tags="[!shouldfail][!throws][.][failing]" filename="tests/<exe-name>/UsageTests/Exception.tests.cpp" > <TestCase name="#748 - captures with unexpected exceptions" tags="[!shouldfail][!throws][.][failing]" filename="tests/<exe-name>/UsageTests/Exception.tests.cpp" >
<Section name="outside assertions" filename="tests/<exe-name>/UsageTests/Exception.tests.cpp" > <Section name="outside assertions" filename="tests/<exe-name>/UsageTests/Exception.tests.cpp" >
<Info> <Info>
@ -21042,6 +21048,6 @@ b1!
</Section> </Section>
<OverallResult success="true" skips="0"/> <OverallResult success="true" skips="0"/>
</TestCase> </TestCase>
<OverallResults successes="2033" failures="145" expectedFailures="31" skips="11"/> <OverallResults successes="2033" failures="145" expectedFailures="32" skips="11"/>
<OverallResultsCases successes="308" failures="84" expectedFailures="10" skips="5"/> <OverallResultsCases successes="308" failures="84" expectedFailures="11" skips="5"/>
</Catch2TestRun> </Catch2TestRun>

View File

@ -667,6 +667,12 @@ Nor would this
</Expression> </Expression>
<OverallResult success="true" skips="0"/> <OverallResult success="true" skips="0"/>
</TestCase> </TestCase>
<TestCase name="#2615 - Throwing in constructor generator fails test case but does not abort" tags="[!shouldfail]" filename="tests/<exe-name>/UsageTests/Generators.tests.cpp" >
<Exception filename="tests/<exe-name>/UsageTests/Generators.tests.cpp" >
failure to init
</Exception>
<OverallResult success="true" skips="0"/>
</TestCase>
<TestCase name="#748 - captures with unexpected exceptions" tags="[!shouldfail][!throws][.][failing]" filename="tests/<exe-name>/UsageTests/Exception.tests.cpp" > <TestCase name="#748 - captures with unexpected exceptions" tags="[!shouldfail][!throws][.][failing]" filename="tests/<exe-name>/UsageTests/Exception.tests.cpp" >
<Section name="outside assertions" filename="tests/<exe-name>/UsageTests/Exception.tests.cpp" > <Section name="outside assertions" filename="tests/<exe-name>/UsageTests/Exception.tests.cpp" >
<Info> <Info>
@ -21041,6 +21047,6 @@ b1!
</Section> </Section>
<OverallResult success="true" skips="0"/> <OverallResult success="true" skips="0"/>
</TestCase> </TestCase>
<OverallResults successes="2033" failures="145" expectedFailures="31" skips="11"/> <OverallResults successes="2033" failures="145" expectedFailures="32" skips="11"/>
<OverallResultsCases successes="308" failures="84" expectedFailures="10" skips="5"/> <OverallResultsCases successes="308" failures="84" expectedFailures="11" skips="5"/>
</Catch2TestRun> </Catch2TestRun>

View File

@ -277,6 +277,37 @@ TEST_CASE("#1913 - GENERATEs can share a line", "[regression][generators]") {
REQUIRE(i != j); REQUIRE(i != j);
} }
namespace {
class test_generator : public Catch::Generators::IGenerator<int> {
public:
[[noreturn]] explicit test_generator() {
// removing the following line will cause the program to terminate
// gracefully.
throw Catch::GeneratorException( "failure to init" );
}
auto get() const -> int const& override {
static constexpr int value = 1;
return value;
}
auto next() -> bool override { return false; }
};
static auto make_test_generator()
-> Catch::Generators::GeneratorWrapper<int> {
return { new test_generator() };
}
} // namespace
TEST_CASE( "#2615 - Throwing in constructor generator fails test case but does not abort", "[!shouldfail]" ) {
// this should fail the test case, but not abort the application
auto sample = GENERATE( make_test_generator() );
// this assertion shouldn't trigger
REQUIRE( sample == 0U );
}
#if defined( __clang__ ) #if defined( __clang__ )
# pragma clang diagnostic pop # pragma clang diagnostic pop
#endif #endif