mirror of
https://github.com/catchorg/Catch2
synced 2026-02-23 16:22:10 +00:00
Add --warn InfiniteGenerators
This commit is contained in:
@@ -358,10 +358,13 @@ There are currently two warnings implemented:
|
||||
// (e.g. `REQUIRE`) is encountered.
|
||||
UnmatchedTestSpec // Fail test run if any of the CLI test specs did
|
||||
// not match any tests.
|
||||
InfiniteGenerators // Fail if GENERATE would run infinitely
|
||||
```
|
||||
|
||||
> `UnmatchedTestSpec` was introduced in Catch2 3.0.1.
|
||||
|
||||
> `InfiniteGenerators` was introduced in Catch2 vX.Y.Z
|
||||
|
||||
|
||||
<a id="reporting-timings"></a>
|
||||
## Reporting timings
|
||||
|
||||
@@ -197,6 +197,9 @@ namespace Catch {
|
||||
bool Config::warnAboutUnmatchedTestSpecs() const {
|
||||
return !!( m_data.warnings & WarnAbout::UnmatchedTestSpec );
|
||||
}
|
||||
bool Config::warnAboutInfiniteGenerators() const {
|
||||
return !!( m_data.warnings & WarnAbout::InfiniteGenerator );
|
||||
}
|
||||
bool Config::zeroTestsCountAsSuccess() const { return m_data.allowZeroTests; }
|
||||
ShowDurations Config::showDurations() const { return m_data.showDurations; }
|
||||
double Config::minDuration() const { return m_data.minDuration; }
|
||||
|
||||
@@ -124,6 +124,7 @@ namespace Catch {
|
||||
bool includeSuccessfulResults() const override;
|
||||
bool warnAboutMissingAssertions() const override;
|
||||
bool warnAboutUnmatchedTestSpecs() const override;
|
||||
bool warnAboutInfiniteGenerators() const override;
|
||||
bool zeroTestsCountAsSuccess() const override;
|
||||
ShowDurations showDurations() const override;
|
||||
double minDuration() const override;
|
||||
|
||||
@@ -29,6 +29,8 @@ namespace Catch {
|
||||
NoAssertions = 0x01,
|
||||
//! A command line test spec matched no test cases
|
||||
UnmatchedTestSpec = 0x02,
|
||||
//! The resulting generator in GENERATE is infinite
|
||||
InfiniteGenerator = 0x04,
|
||||
}; };
|
||||
|
||||
enum class ShowDurations {
|
||||
@@ -71,6 +73,7 @@ namespace Catch {
|
||||
virtual bool shouldDebugBreak() const = 0;
|
||||
virtual bool warnAboutMissingAssertions() const = 0;
|
||||
virtual bool warnAboutUnmatchedTestSpecs() const = 0;
|
||||
virtual bool warnAboutInfiniteGenerators() const = 0;
|
||||
virtual bool zeroTestsCountAsSuccess() const = 0;
|
||||
virtual int abortAfter() const = 0;
|
||||
virtual bool showInvisibles() const = 0;
|
||||
|
||||
@@ -32,6 +32,9 @@ namespace Catch {
|
||||
} else if ( warning == "UnmatchedTestSpec" ) {
|
||||
config.warnings = static_cast<WarnAbout::What>(config.warnings | WarnAbout::UnmatchedTestSpec);
|
||||
return ParserResult::ok( ParseResultType::Matched );
|
||||
} else if ( warning == "InfiniteGenerators" ) {
|
||||
config.warnings = static_cast<WarnAbout::What>(config.warnings | WarnAbout::InfiniteGenerator);
|
||||
return ParserResult::ok( ParseResultType::Matched );
|
||||
}
|
||||
|
||||
return ParserResult ::runtimeError(
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
#include <catch2/internal/catch_assertion_handler.hpp>
|
||||
#include <catch2/internal/catch_test_failure_exception.hpp>
|
||||
#include <catch2/internal/catch_thread_local.hpp>
|
||||
#include <catch2/internal/catch_unreachable.hpp>
|
||||
#include <catch2/internal/catch_result_type.hpp>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
@@ -495,6 +497,11 @@ namespace Catch {
|
||||
currentTracker.addChild( CATCH_MOVE( newTracker ) );
|
||||
|
||||
ret->setGenerator( CATCH_MOVE( generator ) );
|
||||
if ( m_config->warnAboutInfiniteGenerators() &&
|
||||
!ret->getGenerator()->isFinite() ) {
|
||||
// TBD: Would it be better to expand this macro inline?
|
||||
FAIL( "GENERATE() would run infinitely" );
|
||||
}
|
||||
ret->open();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ if(CATCH_ENABLE_COVERAGE)
|
||||
endif()
|
||||
|
||||
# configure unit tests via CTest
|
||||
add_test(NAME RunTests COMMAND $<TARGET_FILE:SelfTest> --order rand --rng-seed time)
|
||||
add_test(NAME RunTests COMMAND $<TARGET_FILE:SelfTest> --order rand --rng-seed time --warn InfiniteGenerators)
|
||||
set_tests_properties(RunTests PROPERTIES
|
||||
FAIL_REGULAR_EXPRESSION "Filters:"
|
||||
COST 15
|
||||
|
||||
@@ -589,3 +589,16 @@ set_tests_properties(ThreadSafetyTests::UnscopedMessagesAndAssertions
|
||||
PASS_REGULAR_EXPRESSION "assertions: 401 \\| 401 failed as expected"
|
||||
RUN_SERIAL ON
|
||||
)
|
||||
|
||||
add_executable(InfiniteGenerators ${TESTS_DIR}/X95-InfiniteGenerators.cpp)
|
||||
target_link_libraries(InfiniteGenerators PRIVATE Catch2::Catch2WithMain)
|
||||
|
||||
add_test(
|
||||
NAME Warnings::InfiniteGenerators
|
||||
COMMAND $<TARGET_FILE:InfiniteGenerators> --warn InfiniteGenerators
|
||||
)
|
||||
set_tests_properties(Warnings::InfiniteGenerators
|
||||
PROPERTIES
|
||||
PASS_REGULAR_EXPRESSION "test cases: 1 \\| 1 failed"
|
||||
TIMEOUT 5
|
||||
)
|
||||
|
||||
36
tests/ExtraTests/X95-InfiniteGenerators.cpp
Normal file
36
tests/ExtraTests/X95-InfiniteGenerators.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
|
||||
// Copyright Catch2 Authors
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE.txt or copy at
|
||||
// https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
|
||||
/**\file
|
||||
* Checks that GENERATE over infinite generator errors out when the tests are
|
||||
* run with `-warn InfiniteGenerators`
|
||||
*/
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <catch2/generators/catch_generators.hpp>
|
||||
|
||||
namespace {
|
||||
static int ONE = 1;
|
||||
class infinite_generator : public Catch::Generators::IGenerator<int> {
|
||||
public:
|
||||
|
||||
int const& get() const override { return ONE; }
|
||||
bool next() override { return true; }
|
||||
auto isFinite() const -> bool override { return false; }
|
||||
};
|
||||
|
||||
static auto make_infinite_generator()
|
||||
-> Catch::Generators::GeneratorWrapper<int> {
|
||||
return { new infinite_generator() };
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_CASE() {
|
||||
auto _ = GENERATE( make_infinite_generator() );
|
||||
}
|
||||
@@ -1446,8 +1446,8 @@ TestSpecParser.tests.cpp:<line number>: passed: spec.matches( testCase ) for: tr
|
||||
CmdLine.tests.cpp:<line number>: passed: cli.parse( { "test", "-w", "NoAssertions" } ) for: {?}
|
||||
CmdLine.tests.cpp:<line number>: passed: config.warnings == WarnAbout::NoAssertions for: 1 == 1
|
||||
CmdLine.tests.cpp:<line number>: passed: !(cli.parse( { "test", "-w", "NoTests" } )) for: !{?}
|
||||
CmdLine.tests.cpp:<line number>: passed: cli.parse( { "test", "--warn", "NoAssertions", "--warn", "UnmatchedTestSpec" } ) for: {?}
|
||||
CmdLine.tests.cpp:<line number>: passed: config.warnings == ( WarnAbout::NoAssertions | WarnAbout::UnmatchedTestSpec ) for: 3 == 3
|
||||
CmdLine.tests.cpp:<line number>: passed: cli.parse( { "test", "--warn", "NoAssertions", "--warn", "UnmatchedTestSpec", "--warn", "InfiniteGenerators" } ) for: {?}
|
||||
CmdLine.tests.cpp:<line number>: passed: config.warnings == ( WarnAbout::NoAssertions | WarnAbout::UnmatchedTestSpec | WarnAbout::InfiniteGenerator ) for: 7 == 7
|
||||
Condition.tests.cpp:<line number>: passed: p == 0 for: 0 == 0
|
||||
Condition.tests.cpp:<line number>: passed: p == pNULL for: 0 == 0
|
||||
Condition.tests.cpp:<line number>: passed: p != 0 for: 0x<hex digits> != 0
|
||||
|
||||
@@ -1444,8 +1444,8 @@ TestSpecParser.tests.cpp:<line number>: passed: spec.matches( testCase ) for: tr
|
||||
CmdLine.tests.cpp:<line number>: passed: cli.parse( { "test", "-w", "NoAssertions" } ) for: {?}
|
||||
CmdLine.tests.cpp:<line number>: passed: config.warnings == WarnAbout::NoAssertions for: 1 == 1
|
||||
CmdLine.tests.cpp:<line number>: passed: !(cli.parse( { "test", "-w", "NoTests" } )) for: !{?}
|
||||
CmdLine.tests.cpp:<line number>: passed: cli.parse( { "test", "--warn", "NoAssertions", "--warn", "UnmatchedTestSpec" } ) for: {?}
|
||||
CmdLine.tests.cpp:<line number>: passed: config.warnings == ( WarnAbout::NoAssertions | WarnAbout::UnmatchedTestSpec ) for: 3 == 3
|
||||
CmdLine.tests.cpp:<line number>: passed: cli.parse( { "test", "--warn", "NoAssertions", "--warn", "UnmatchedTestSpec", "--warn", "InfiniteGenerators" } ) for: {?}
|
||||
CmdLine.tests.cpp:<line number>: passed: config.warnings == ( WarnAbout::NoAssertions | WarnAbout::UnmatchedTestSpec | WarnAbout::InfiniteGenerator ) for: 7 == 7
|
||||
Condition.tests.cpp:<line number>: passed: p == 0 for: 0 == 0
|
||||
Condition.tests.cpp:<line number>: passed: p == pNULL for: 0 == 0
|
||||
Condition.tests.cpp:<line number>: passed: p != 0 for: 0x<hex digits> != 0
|
||||
|
||||
@@ -9425,14 +9425,14 @@ CmdLine.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
CmdLine.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( cli.parse( { "test", "--warn", "NoAssertions", "--warn", "UnmatchedTestSpec" } ) )
|
||||
REQUIRE( cli.parse( { "test", "--warn", "NoAssertions", "--warn", "UnmatchedTestSpec", "--warn", "InfiniteGenerators" } ) )
|
||||
with expansion:
|
||||
{?}
|
||||
|
||||
CmdLine.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( config.warnings == ( WarnAbout::NoAssertions | WarnAbout::UnmatchedTestSpec ) )
|
||||
REQUIRE( config.warnings == ( WarnAbout::NoAssertions | WarnAbout::UnmatchedTestSpec | WarnAbout::InfiniteGenerator ) )
|
||||
with expansion:
|
||||
3 == 3
|
||||
7 == 7
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Pointers can be compared to null
|
||||
|
||||
@@ -9423,14 +9423,14 @@ CmdLine.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
CmdLine.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( cli.parse( { "test", "--warn", "NoAssertions", "--warn", "UnmatchedTestSpec" } ) )
|
||||
REQUIRE( cli.parse( { "test", "--warn", "NoAssertions", "--warn", "UnmatchedTestSpec", "--warn", "InfiniteGenerators" } ) )
|
||||
with expansion:
|
||||
{?}
|
||||
|
||||
CmdLine.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( config.warnings == ( WarnAbout::NoAssertions | WarnAbout::UnmatchedTestSpec ) )
|
||||
REQUIRE( config.warnings == ( WarnAbout::NoAssertions | WarnAbout::UnmatchedTestSpec | WarnAbout::InfiniteGenerator ) )
|
||||
with expansion:
|
||||
3 == 3
|
||||
7 == 7
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Pointers can be compared to null
|
||||
|
||||
@@ -2371,9 +2371,9 @@ ok {test-number} - config.warnings == WarnAbout::NoAssertions for: 1 == 1
|
||||
# Parsing warnings
|
||||
ok {test-number} - !(cli.parse( { "test", "-w", "NoTests" } )) for: !{?}
|
||||
# Parsing warnings
|
||||
ok {test-number} - cli.parse( { "test", "--warn", "NoAssertions", "--warn", "UnmatchedTestSpec" } ) for: {?}
|
||||
ok {test-number} - cli.parse( { "test", "--warn", "NoAssertions", "--warn", "UnmatchedTestSpec", "--warn", "InfiniteGenerators" } ) for: {?}
|
||||
# Parsing warnings
|
||||
ok {test-number} - config.warnings == ( WarnAbout::NoAssertions | WarnAbout::UnmatchedTestSpec ) for: 3 == 3
|
||||
ok {test-number} - config.warnings == ( WarnAbout::NoAssertions | WarnAbout::UnmatchedTestSpec | WarnAbout::InfiniteGenerator ) for: 7 == 7
|
||||
# Pointers can be compared to null
|
||||
ok {test-number} - p == 0 for: 0 == 0
|
||||
# Pointers can be compared to null
|
||||
|
||||
@@ -2369,9 +2369,9 @@ ok {test-number} - config.warnings == WarnAbout::NoAssertions for: 1 == 1
|
||||
# Parsing warnings
|
||||
ok {test-number} - !(cli.parse( { "test", "-w", "NoTests" } )) for: !{?}
|
||||
# Parsing warnings
|
||||
ok {test-number} - cli.parse( { "test", "--warn", "NoAssertions", "--warn", "UnmatchedTestSpec" } ) for: {?}
|
||||
ok {test-number} - cli.parse( { "test", "--warn", "NoAssertions", "--warn", "UnmatchedTestSpec", "--warn", "InfiniteGenerators" } ) for: {?}
|
||||
# Parsing warnings
|
||||
ok {test-number} - config.warnings == ( WarnAbout::NoAssertions | WarnAbout::UnmatchedTestSpec ) for: 3 == 3
|
||||
ok {test-number} - config.warnings == ( WarnAbout::NoAssertions | WarnAbout::UnmatchedTestSpec | WarnAbout::InfiniteGenerator ) for: 7 == 7
|
||||
# Pointers can be compared to null
|
||||
ok {test-number} - p == 0 for: 0 == 0
|
||||
# Pointers can be compared to null
|
||||
|
||||
@@ -11291,7 +11291,7 @@ Approx( 1.21999999999999997 )
|
||||
<Section name="Combining multiple warnings" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Original>
|
||||
cli.parse( { "test", "--warn", "NoAssertions", "--warn", "UnmatchedTestSpec" } )
|
||||
cli.parse( { "test", "--warn", "NoAssertions", "--warn", "UnmatchedTestSpec", "--warn", "InfiniteGenerators" } )
|
||||
</Original>
|
||||
<Expanded>
|
||||
{?}
|
||||
@@ -11299,10 +11299,10 @@ Approx( 1.21999999999999997 )
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Original>
|
||||
config.warnings == ( WarnAbout::NoAssertions | WarnAbout::UnmatchedTestSpec )
|
||||
config.warnings == ( WarnAbout::NoAssertions | WarnAbout::UnmatchedTestSpec | WarnAbout::InfiniteGenerator )
|
||||
</Original>
|
||||
<Expanded>
|
||||
3 == 3
|
||||
7 == 7
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0" skipped="false"/>
|
||||
|
||||
@@ -11291,7 +11291,7 @@ Approx( 1.21999999999999997 )
|
||||
<Section name="Combining multiple warnings" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Original>
|
||||
cli.parse( { "test", "--warn", "NoAssertions", "--warn", "UnmatchedTestSpec" } )
|
||||
cli.parse( { "test", "--warn", "NoAssertions", "--warn", "UnmatchedTestSpec", "--warn", "InfiniteGenerators" } )
|
||||
</Original>
|
||||
<Expanded>
|
||||
{?}
|
||||
@@ -11299,10 +11299,10 @@ Approx( 1.21999999999999997 )
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||
<Original>
|
||||
config.warnings == ( WarnAbout::NoAssertions | WarnAbout::UnmatchedTestSpec )
|
||||
config.warnings == ( WarnAbout::NoAssertions | WarnAbout::UnmatchedTestSpec | WarnAbout::InfiniteGenerator )
|
||||
</Original>
|
||||
<Expanded>
|
||||
3 == 3
|
||||
7 == 7
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0" skipped="false"/>
|
||||
|
||||
@@ -413,9 +413,10 @@ TEST_CASE( "Parsing warnings", "[cli][warnings]" ) {
|
||||
SECTION( "Combining multiple warnings" ) {
|
||||
REQUIRE( cli.parse( { "test",
|
||||
"--warn", "NoAssertions",
|
||||
"--warn", "UnmatchedTestSpec" } ) );
|
||||
"--warn", "UnmatchedTestSpec",
|
||||
"--warn", "InfiniteGenerators" } ) );
|
||||
|
||||
REQUIRE( config.warnings == ( WarnAbout::NoAssertions | WarnAbout::UnmatchedTestSpec ) );
|
||||
REQUIRE( config.warnings == ( WarnAbout::NoAssertions | WarnAbout::UnmatchedTestSpec | WarnAbout::InfiniteGenerator ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user