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

summaryrefslogtreecommitdiffhomepage
path: root/src/catch2
diff options
context:
space:
mode:
authorMartin Hořeňovský2026-09-10 23:40:24 +0200
committerMartin Hořeňovský2026-09-11 11:27:31 +0200
commit58a5f8bd8c3a40359ed96127ac976f7ddf4b8f01 (patch)
treedf94171e59e3a169e95fdf89dada09d759751647 /src/catch2
parent1767d9fad0bc28e2b80744daa93c3430d0c6d238 (diff)
downloadcatch3-58a5f8bd8c3a40359ed96127ac976f7ddf4b8f01.tar.gz
Don't check tags for being special twice during test case registration
Previously we would check if the tag is special to validate that it isn't reserved, and then to actually get the test case properties. We also did the first check in particularly terrible order, leading to a lot of wasted work. The new implementation does property extraction while checking validity, and is structured to avoid as much work as possible by early checks.
Diffstat (limited to 'src/catch2')
-rw-r--r--src/catch2/catch_test_case_info.cpp50
1 files changed, 22 insertions, 28 deletions
diff --git a/src/catch2/catch_test_case_info.cpp b/src/catch2/catch_test_case_info.cpp
index 4ccc3d52..6c20c93e 100644
--- a/src/catch2/catch_test_case_info.cpp
+++ b/src/catch2/catch_test_case_info.cpp
@@ -48,32 +48,27 @@ namespace Catch {
return tcp != TestCaseProperties::None;
}
- TestCaseProperties parseSpecialTag( StringRef tag ) {
- if( !tag.empty() && tag[0] == '.' )
- return TestCaseProperties::IsHidden;
- else if( tag == "!throws"_sr )
- return TestCaseProperties::Throws;
- else if( tag == "!shouldfail"_sr )
- return TestCaseProperties::ShouldFail;
- else if( tag == "!mayfail"_sr )
- return TestCaseProperties::MayFail;
- else if( tag == "!nonportable"_sr )
- return TestCaseProperties::NonPortable;
- else if( tag == "!benchmark"_sr )
- return TestCaseProperties::Benchmark | TestCaseProperties::IsHidden;
- else
- return TestCaseProperties::None;
- }
- bool isReservedTag( StringRef tag ) {
- return parseSpecialTag( tag ) == TestCaseProperties::None
- && tag.size() > 0
- && !std::isalnum( static_cast<unsigned char>(tag[0]) );
- }
- void enforceNotReservedTag( StringRef tag, SourceLineInfo const& _lineInfo ) {
- CATCH_ENFORCE( !isReservedTag(tag),
- "Tag name: [" << tag << "] is not allowed.\n"
- << "Tag names starting with non alphanumeric characters are reserved\n"
- << _lineInfo );
+ TestCaseProperties propertiesFromTag( StringRef tag, SourceLineInfo const& _lineInfo ) {
+ if ( tag.empty() ) { return TestCaseProperties::None; }
+ // All tags starting with alphanumeric characters are normal.
+ if ( std::isalnum( tag[0] ) ) { return TestCaseProperties::None; }
+
+ // Explicitly check known special tags, and error out if it is not one of them
+ if ( tag[0] == '.' ) { return TestCaseProperties::IsHidden; }
+ else if ( tag == "!throws"_sr ) { return TestCaseProperties::Throws; }
+ else if ( tag == "!shouldfail"_sr ) { return TestCaseProperties::ShouldFail; }
+ else if ( tag == "!mayfail"_sr ) { return TestCaseProperties::MayFail; }
+ else if ( tag == "!nonportable"_sr ) { return TestCaseProperties::NonPortable; }
+ else if ( tag == "!benchmark"_sr ) {
+ return TestCaseProperties::Benchmark |
+ TestCaseProperties::IsHidden;
+ } else {
+ CATCH_RUNTIME_ERROR(
+ "Tag name: [" << tag << "] is not allowed.\n"
+ << "Tag names starting with non-alphanumeric "
+ "characters are reserved.\n"
+ << _lineInfo );
+ }
}
std::string makeDefaultName() {
@@ -182,8 +177,7 @@ namespace Catch {
<< _nameAndTags.name << "' at "
<< _lineInfo );
- enforceNotReservedTag(tagStr, lineInfo);
- properties |= parseSpecialTag(tagStr);
+ properties |= propertiesFromTag(tagStr, _lineInfo);
// When copying a tag to the backing storage, we need to
// check if it is a merged hide tag, such as [.foo], and
// if it is, we need to handle it as if it was [foo].