When using catch_discover_tests() with DISCOVERY_MODE PRE_TEST and a
multi-config generator (e.g. Ninja Multi-Config), if a test target has
zero discoverable tests (e.g. all tests tagged with [.]), ctest fails:
CMake Error: include could not find requested file:
.../test-hidden-b12d07c_tests-Release.cmake
The early return added in #2962 (76f70b14) correctly prevented a JSON
parsing crash for zero tests, but skipped writing the ctest file. The
PRE_TEST include script unconditionally includes this file, so the
missing file causes a hard error that aborts all test discovery.
Write an empty file before returning early so the include always
succeeds.
For line-wrapping bytes were counted instead of codepoints. This
resulted in line-breaks being inserted at the wrong position and also
breaking UTF-8 characters.
Fixes#1022.
Ideally we could suppress the warning locally in the `UNIQUE_NAME` macro,
but that runs into at least 2 issues:
1) Clang actually does not consider the warning as coming from inside the
`UNIQUE_NAME` macro, even though it correctly points to its expansion
as the problem. This means that adding `_Pragma`s inside the macro
around the __COUNTER__ usage does not actually silence the warning.
2) Adding the local suppressions anyway breaks the expansion of
`MAKE_NAMESPACE` macro inside the templated test case macros. This can
be fixed for the newest clang version by removing its use and using
the uniqued `TestName` for the namespace name directly, but this breaks
compilation on GCC, and older Clang versions.
Because of these issues, we introduce global warning suppression for
`-Wc2y-extensions` to be done with it. We should revisit this if Clang 23
fixes the local pragma based suppression, when it might be worth the effort
to rework the templated test case macros to support it.
Closes#3076
Previously the mapping was eager on construction and calls to
`next()`. This was fine when generators were always exhausted fully,
but with the new generator filtering, we might not want to call
the map function eagerly; rather we want to call it only once,
after the generator is moved to the target element.
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.
* Removed `IGeneratorTracker::hasGenerator`, as it was never used.
* Removed `IGeneratorTracker::setGenerator`, as actually using it
after the tracker was used would lead to inconsistent behaviour.
Instead, the tracker is given the generator it guards during
construction.
* Add validation for --benchmark-samples to prevent crash with zero samples
* Add automated test for benchmark samples validation
* Update baselines for benchmark-samples validation
* Add missing test for benchmark samples validation
---------
Co-authored-by: Chan Aung <chan@Thinkpad.localdomain>
Suppress `Global initializer calls a non-constexpr function 'Catch::makeTestInvoker' (i.22).`,
which is issued when using macro `TEST_CASE` for windows/MSVC builds.
---------
Co-authored-by: Martin Hořeňovský <martin.horenovsky@gmail.com>
The original implementation of `UNSCOPED_X` message macros used a
clever hack to make the original implementation simpler: construct
an instance of `ScopedMessage` to manage its lifetime, but store
it in a vector, so its lifetime is not actually scope-based, and
we can manage it through the vector instance.
This hack made it so that the lifetime of the vector that manages
the fake `ScopedMessage`s must be outlived by the vector with the
actual messages. Originally this wasn't a problem, because they both
lived inside the run context instance. However, since then these
vectors became globals and thread-local. When this happened, it
still wasn't a problem; the two globals were declared in the right
order, so they were destroyed in the right order as well.
Then, in f80956a43a, these globals
were turned into magic static globals to improve their behaviour
in MSVC's Debug build mode. This caused their lifetimes to be
runtime-dependent; if a specific test thread added its first scoped
message before it added first unscoped message, the lifetimes
would be correct. If it instead added first unscoped message
before adding first scoped message, then there **might** be
invalid reads during thread destruction.
The fix is simple: do things properly and manage the lifetime of
messages in `UNSCOPED_X` explicitly. Then we don't have to deal
with the destruction of fake `ScopedMessage`s while the thread is
being destroyed, and the lifetime of the two vectors is no longer
tied together.
I also threw them both into a new type, to encapsulate some of the
unscoped message logic.
This avoids calling the global's constructor on threads that will
never interact with them. Calling the constructor can have surprising
overhead, as e.g. MSVC's Debug mode `std::vector` will allocate in
the default constructor.
Closes#3050