Skip to content
Open
12 changes: 12 additions & 0 deletions docs/filtering-execution-path.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,18 @@ things:
that if you specify path filters without a test case filter, Catch2
will try to apply the path filters inside every registered test case.

When path filters are active, the console and compact reporters print them
under a `Path filters:` heading (right after the usual `Filters:` line),
so it is clear which section/generator selection was requested even if the
combination runs no assertions:

```
Filters: "Scenario: Create and train model on entire dataset"
Path filters:
- Section: "Given: a fresh dataset"
- Generator: "0"
```

## Old behaviour

> The old behaviour was deprecated in Catch2 3.13.0
Expand Down
2 changes: 2 additions & 0 deletions docs/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@
* Fixed typo in the "Could not jump to the Nth element" exception message (#3181)

### Improvements
* Console and compact reporters print active section/generator path filters
(`-c`/`-g`/`-p`) under a `Path filters:` heading. (#3099)
* `catch_discover_tests` registers tests in deterministic (alphabetical) order.
* `catch_discover_tests` has been rewritten to be massively faster.
* Preparing the actual CTest script is significantly faster.
Expand Down
1 change: 1 addition & 0 deletions src/catch2/reporters/catch_reporter_compact.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ class AssertionPrinter {
<< m_config->testSpec()
<< '\n';
}
printPathFilters( m_stream, m_colour.get(), m_config->getPathFilters() );
m_stream << "RNG seed: " << getSeed() << '\n'
<< std::flush;
}
Expand Down
1 change: 1 addition & 0 deletions src/catch2/reporters/catch_reporter_console.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,7 @@ void ConsoleReporter::testRunStarting(TestRunInfo const& _testRunInfo) {
m_stream << m_colour->guardColour( Colour::BrightYellow ) << "Filters: "
<< m_config->testSpec() << '\n';
}
printPathFilters( m_stream, m_colour.get(), m_config->getPathFilters() );
m_stream << "Randomness seeded to: " << getSeed() << '\n'
<< std::flush;
}
Expand Down
23 changes: 23 additions & 0 deletions src/catch2/reporters/catch_reporter_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,29 @@ namespace Catch {
return serialized;
}

void printPathFilters( std::ostream& stream,
ColourImpl* streamColour,
std::vector<PathFilter> const& pathFilters ) {
if ( pathFilters.empty() ) {
return;
}

stream << streamColour->guardColour( Colour::BrightYellow )
<< "Path filters:\n";
for ( auto const& pathFilter : pathFilters ) {
stream << " - ";
switch ( pathFilter.type ) {
case PathFilter::For::Section:
stream << "Section: ";
break;
case PathFilter::For::Generator:
stream << "Generator: ";
break;
}
stream << '"' << pathFilter.filter << "\"\n";
}
}

std::ostream& operator<<( std::ostream& out, lineOfChars value ) {
for ( size_t idx = 0; idx < CATCH_CONFIG_CONSOLE_WIDTH - 1; ++idx ) {
out.put( value.c );
Expand Down
11 changes: 11 additions & 0 deletions src/catch2/reporters/catch_reporter_helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <vector>

#include <catch2/internal/catch_list.hpp>
#include <catch2/internal/catch_path_filter.hpp>
#include <catch2/interfaces/catch_interfaces_config.hpp>
#include <catch2/catch_totals.hpp>

Expand All @@ -30,6 +31,16 @@ namespace Catch {

std::string serializeFilters( std::vector<std::string> const& filters );

/**
* Prints active section/generator path filters in a readable list.
*
* Used by the console and compact reporters so CLI path selection
* (-c/-g/-p) is visible even when the selection runs no assertions.
*/
void printPathFilters( std::ostream& stream,
ColourImpl* streamColour,
std::vector<PathFilter> const& pathFilters );

struct lineOfChars {
char c;
constexpr lineOfChars( char c_ ): c( c_ ) {}
Expand Down
17 changes: 17 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ set(TEST_SOURCES
${SELF_TEST_DIR}/IntrospectiveTests/Details.tests.cpp
${SELF_TEST_DIR}/IntrospectiveTests/FloatingPoint.tests.cpp
${SELF_TEST_DIR}/IntrospectiveTests/GeneratorsImpl.tests.cpp
${SELF_TEST_DIR}/IntrospectiveTests/GeneratorFilterParser.tests.cpp
${SELF_TEST_DIR}/IntrospectiveTests/Integer.tests.cpp
${SELF_TEST_DIR}/IntrospectiveTests/InternalBenchmark.tests.cpp
${SELF_TEST_DIR}/IntrospectiveTests/Json.tests.cpp
Expand Down Expand Up @@ -726,6 +727,22 @@ foreach(reporterName # "Automake" - the simple .trs format does not support any
)
endforeach()

foreach(reporterName "compact" "console")
add_test(NAME "Reporters:PathFilters:${reporterName}"
COMMAND
$<TARGET_FILE:SelfTest> "Generators -- simple"
-c one -g 0
--reporter ${reporterName}
)
set_tests_properties("Reporters:PathFilters:${reporterName}"
PROPERTIES
PASS_REGULAR_EXPRESSION
"Path filters:"
"Section: \"one\""
"Generator: \"0\""
)
endforeach()

add_test(NAME "Bazel::RngSeedEnvVar::JustEnv"
COMMAND
$<TARGET_FILE:SelfTest> "Factorials are computed"
Expand Down
29 changes: 29 additions & 0 deletions tests/SelfTest/IntrospectiveTests/Reporters.tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,3 +330,32 @@ TEST_CASE("Registering multiple reporters with the same name fails",
Catch::Detail::make_unique<TestReporterFactory>() ),
"reporter using 'some-reporter-name' as name was already registered" );
}

TEST_CASE( "printPathFilters lists section and generator selections",
"[reporters][reporter-helpers]" ) {
using Catch::Matchers::ContainsSubstring;
using Catch::PathFilter;
using namespace std::string_literals;

StringIStream sstream;
auto colour = Catch::makeColourImpl( Catch::ColourMode::None, &sstream );

SECTION( "empty path filters print nothing" ) {
Catch::printPathFilters( sstream.stream(), colour.get(), {} );
REQUIRE( sstream.str().empty() );
}
SECTION( "mixed section and generator filters" ) {
std::vector<PathFilter> filters{
PathFilter( PathFilter::For::Section, "Given: a fresh dataset" ),
PathFilter( PathFilter::For::Generator, "0" ),
};
Catch::printPathFilters( sstream.stream(), colour.get(), filters );

auto listingString = sstream.str();
REQUIRE_THAT( listingString, ContainsSubstring( "Path filters:"s ) );
REQUIRE_THAT( listingString,
ContainsSubstring( "Section: \"Given: a fresh dataset\""s ) );
REQUIRE_THAT( listingString,
ContainsSubstring( "Generator: \"0\""s ) );
}
}