Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/src/catch2/internal/catch_commandline.cpp
diff options
context:
space:
mode:
authorMartin Hořeňovský2026-02-15 20:27:15 +0100
committerGitHub2026-02-15 20:27:15 +0100
commit3a0cf7e75fdc571ff9ed25303fb268665f6260c0 (patch)
tree25cd180f4419e0ef2f6fbe3664f91b548c59d8c2 /src/catch2/internal/catch_commandline.cpp
parentb6c7b217d4bcb5030ce1e04180f35d02bcf5d93f (diff)
downloadcatch3-3a0cf7e75fdc571ff9ed25303fb268665f6260c0.tar.gz
Support filtering on both sections and generators (#3069)
Not being able to filter generators to specific element has been regularly causing problems. It was possible to use a dynamic section to run tests for specific element in a generator, at least if the element had a nice string representation, but the test case would still run once per element in the generator. With this change, it is possible to have the generator return only one specific element, and do so based on the index, rather than the string representation of the element. This enables simple debugging of tests that fail for specific generator element.
Diffstat (limited to 'src/catch2/internal/catch_commandline.cpp')
-rw-r--r--src/catch2/internal/catch_commandline.cpp45
1 files changed, 44 insertions, 1 deletions
diff --git a/src/catch2/internal/catch_commandline.cpp b/src/catch2/internal/catch_commandline.cpp
index 34bda5e2..4ce42397 100644
--- a/src/catch2/internal/catch_commandline.cpp
+++ b/src/catch2/internal/catch_commandline.cpp
@@ -216,6 +216,43 @@ namespace Catch {
return ParserResult::ok( ParseResultType::Matched );
};
+ auto const setSectionFilter = [&]( std::string const& sectionFilter ) {
+ config.pathFilters.emplace_back( PathFilter::For::Section, trim(sectionFilter) );
+ return ParserResult::ok( ParseResultType::Matched );
+ };
+ auto const setGeneratorFilter = [&]( std::string const& generatorFilter ) {
+ if (generatorFilter != "*") {
+ // TODO: avoid re-parsing the index?
+ auto parsedIndex = parseUInt( generatorFilter );
+ if ( !parsedIndex ) {
+ return ParserResult::runtimeError( "Could not parse '" +
+ generatorFilter +
+ "' as generator index" );
+ }
+ }
+ config.useNewPathFilteringBehaviour = true;
+ config.pathFilters.emplace_back( PathFilter::For::Generator, trim(generatorFilter) );
+ return ParserResult::ok( ParseResultType::Matched );
+ };
+ // Copy-capturing other `setFoo` functions enables calling them later,
+ // as the config ref remains valid, but the local lambda vars won't.
+ auto const setPathFilter = [=, &config]( std::string const& pathFilter ) {
+ config.useNewPathFilteringBehaviour = true;
+ if ( pathFilter.size() < 3 ) {
+ return ParserResult::runtimeError(
+ "Path filter '" + pathFilter + "' is too short" );
+ }
+ if ( startsWith( pathFilter, "g:" ) ) {
+ return setGeneratorFilter( pathFilter.substr( 2 ) );
+ }
+ if ( startsWith( pathFilter, "c:" ) ) {
+ return setSectionFilter( pathFilter.substr( 2 ) );
+ }
+ return ParserResult::runtimeError( "Path filter '" + pathFilter +
+ "' has unknown type prefix" );
+ };
+
+
auto cli
= ExeName( config.processName )
| Help( config.showHelp )
@@ -261,9 +298,15 @@ namespace Catch {
| Opt( config.filenamesAsTags )
["-#"]["--filenames-as-tags"]
( "adds a tag for the filename" )
- | Opt( config.sectionsToRun, "section name" )
+ | Opt( accept_many, setSectionFilter, "section name" )
["-c"]["--section"]
( "specify section to run" )
+ | Opt( accept_many, setGeneratorFilter, "index spec" )
+ ["-g"]["--generator-index"]
+ ( "specify generator elements to try" )
+ | Opt( accept_many, setPathFilter, "path filter spec" )
+ ["-p"]["--path-filter"]
+ ( "qualified path filter" )
| Opt( setVerbosity, "quiet|normal|high" )
["-v"]["--verbosity"]
( "set output verbosity" )