<feed xmlns='http://www.w3.org/2005/Atom'>
<title>catch3/src/catch2/internal/catch_run_context.cpp, branch docs/describe-catch3</title>
<subtitle>Progmasoft Catch3: an independently maintained C++17 test framework with a parallel runner, property checks, snapshots and structured results.</subtitle>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/'/>
<entry>
<title>End the output capture when a test exits, fail on missing reports</title>
<updated>2026-10-24T09:41:08+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-10-24T09:41:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=e18f19b7dd70c99fbcf2b3fe812ee18dabc92663'/>
<id>e18f19b7dd70c99fbcf2b3fe812ee18dabc92663</id>
<content type='text'>
A test that called exit() crashed its worker with SIGSEGV on Linux and
macOS. The exit hook read Catch2's captured output through a scoped
deactivation, which switched the capture back on; libstdc++ then flushed
std::cout at exit into a capture buffer that static destruction had
already freed. RunContext::endCapture() now ends the capture for good and
returns what it held, so the standard streams are their own again.

A JUnit, JSON or trace report that could not be written was only
reported on stderr, and a run whose tests passed still exited with 0, so a
build server could miss it. Such a run now exits with 1; failed tests
still exit with 42.

Integration tests of the runner's output move their helpers into
RunnerFixtureClient.hpp and cover --version, --help, the listing modes, a
bad option, exit codes 1 to 4, -v, -q, --slowest, colours, --analytics
in text and JSON, and Bazel's test environment.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
A test that called exit() crashed its worker with SIGSEGV on Linux and
macOS. The exit hook read Catch2's captured output through a scoped
deactivation, which switched the capture back on; libstdc++ then flushed
std::cout at exit into a capture buffer that static destruction had
already freed. RunContext::endCapture() now ends the capture for good and
returns what it held, so the standard streams are their own again.

A JUnit, JSON or trace report that could not be written was only
reported on stderr, and a run whose tests passed still exited with 0, so a
build server could miss it. Such a run now exits with 1; failed tests
still exit with 42.

Integration tests of the runner's output move their helpers into
RunnerFixtureClient.hpp and cover --version, --help, the listing modes, a
bad option, exit codes 1 to 4, -v, -q, --slowest, colours, --analytics
in text and JSON, and Bazel's test environment.
</pre>
</div>
</content>
</entry>
<entry>
<title>Replace Catch2's runner with the Catch3 runner</title>
<updated>2026-10-23T20:25:41+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-10-23T20:25:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=93d4e7dbebab867e0a7f59fc25308460a7a76280'/>
<id>93d4e7dbebab867e0a7f59fc25308460a7a76280</id>
<content type='text'>
Catch3 keeps Catch2's API for writing tests (test cases, sections,
assertions, matchers, generators, listeners, benchmarks) and replaces its
session, command line and reporters with a runner of its own.

The runner starts the test binary again as worker processes that take the
next test when they are free. A crash, an exit or a hang ends one test, not
the run. On top of that it adds:

- retries that tell deterministic, flaky and order-dependent failures
  apart, and a bisection that names the test leaving state behind;
- a history of verdicts and durations, kept under a file lock, that drives
  automatic quarantine, adaptive time limits, predictive ordering,
  incremental runs, failure replay and analytics;
- selection by change, past failure or prediction, dependency closure,
  and sharding by a stable hash or by recorded durations;
- tags for serial and isolated tests, shared resources, dependencies,
  time limits and retries;
- a failure category, a signature, an analysis and a replay command for
  every failure;
- console, JUnit XML (with flakyFailure and rerunFailure), JSON and Chrome
  trace reports, and a versioned discovery listing (--list=json);
- a temporary directory per test (TMPDIR, TMP, TEMP and
  TestTemporaryDirectory());
- Bazel's test environment: XML output file, test filter, sharding, seed,
  premature exit file and undeclared outputs.

The command line is parsed by a hand-written, typed parser. Catch::Session
remains as a thin facade over the runner for custom main functions.

The result model in Progmasoft/Catch3/Results.hpp was rewritten around
tests and attempts, and the JUnit writer now writes it. The property
engine's example database is updated under a file lock with an atomic
rename, so parallel workers can write it at the same time.

Removed: Clara, the command-line and reporter-spec parsers, every reporter
and CATCH_REGISTER_REPORTER, listing, text flow, console colour and width,
the JSON and XML writers, sharding in the test registry, approval tests and
their baselines, Conan packaging, and the unused third_party/clara.hpp.
Listeners keep working; reporters' list and skip events are gone.

The Catch2 library is now compiled as C++20; code that includes only
Catch2's headers still needs C++14. Duplicate test cases are still refused
at start-up. Version 0.3.0.

ExtraTests now turn exceptions off for clang-cl with MSVC-style options,
which -fno-exceptions did not do.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Catch3 keeps Catch2's API for writing tests (test cases, sections,
assertions, matchers, generators, listeners, benchmarks) and replaces its
session, command line and reporters with a runner of its own.

The runner starts the test binary again as worker processes that take the
next test when they are free. A crash, an exit or a hang ends one test, not
the run. On top of that it adds:

- retries that tell deterministic, flaky and order-dependent failures
  apart, and a bisection that names the test leaving state behind;
- a history of verdicts and durations, kept under a file lock, that drives
  automatic quarantine, adaptive time limits, predictive ordering,
  incremental runs, failure replay and analytics;
- selection by change, past failure or prediction, dependency closure,
  and sharding by a stable hash or by recorded durations;
- tags for serial and isolated tests, shared resources, dependencies,
  time limits and retries;
- a failure category, a signature, an analysis and a replay command for
  every failure;
- console, JUnit XML (with flakyFailure and rerunFailure), JSON and Chrome
  trace reports, and a versioned discovery listing (--list=json);
- a temporary directory per test (TMPDIR, TMP, TEMP and
  TestTemporaryDirectory());
- Bazel's test environment: XML output file, test filter, sharding, seed,
  premature exit file and undeclared outputs.

The command line is parsed by a hand-written, typed parser. Catch::Session
remains as a thin facade over the runner for custom main functions.

The result model in Progmasoft/Catch3/Results.hpp was rewritten around
tests and attempts, and the JUnit writer now writes it. The property
engine's example database is updated under a file lock with an atomic
rename, so parallel workers can write it at the same time.

Removed: Clara, the command-line and reporter-spec parsers, every reporter
and CATCH_REGISTER_REPORTER, listing, text flow, console colour and width,
the JSON and XML writers, sharding in the test registry, approval tests and
their baselines, Conan packaging, and the unused third_party/clara.hpp.
Listeners keep working; reporters' list and skip events are gone.

The Catch2 library is now compiled as C++20; code that includes only
Catch2's headers still needs C++14. Duplicate test cases are still refused
at start-up. Version 0.3.0.

ExtraTests now turn exceptions off for clang-cl with MSVC-style options,
which -fno-exceptions did not do.
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix --warn InfiniteGenerators firing even if the generator was filtered</title>
<updated>2026-07-07T12:09:11+00:00</updated>
<author>
<name>Martin Hořeňovský</name>
</author>
<published>2026-07-07T12:09:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=dd94b9a780e66651ff686083a66722386c540228'/>
<id>dd94b9a780e66651ff686083a66722386c540228</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Cleanups from static analysis</title>
<updated>2026-04-24T09:21:04+00:00</updated>
<author>
<name>Martin Hořeňovský</name>
</author>
<published>2026-04-24T09:21:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=11a96e186af8b2779d93e550217e9c95d3f89371'/>
<id>11a96e186af8b2779d93e550217e9c95d3f89371</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Rework internals of CATCH_REGISTER_ENUM</title>
<updated>2026-04-08T10:57:09+00:00</updated>
<author>
<name>Martin Hořeňovský</name>
</author>
<published>2026-04-08T08:26:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=47200ddbee03eaf4a9d3d99d18cb692381d8f5bc'/>
<id>47200ddbee03eaf4a9d3d99d18cb692381d8f5bc</id>
<content type='text'>
The old internals reached into the global hub to stash the allocation(s)
for enum value -&gt; string value there, then kept around a potentially
invalid (in case the hub was cleaned up) reference into it, going through
whole bunch of virtual dispatch in the process.

The new internals just store the data in a static variable inside the
`StringMaker` specialization. This avoids potential lifetime issues,
avoids all virtual dispatch and (almost) reduces the include bloat in
the main header path.

The reason for (almost) there is that for full include correctness,
`EnumInfo` needs `&lt;utility&gt;` include for `std::pair`. However, this brings
in things like `std::relops`, because the std headers in C++ are dumb.
As this was not included before, and instead we relied on `std::pair`
existing in an internal stdlib header that we transitively included, the
full include size ends up bigger than before.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The old internals reached into the global hub to stash the allocation(s)
for enum value -&gt; string value there, then kept around a potentially
invalid (in case the hub was cleaned up) reference into it, going through
whole bunch of virtual dispatch in the process.

The new internals just store the data in a static variable inside the
`StringMaker` specialization. This avoids potential lifetime issues,
avoids all virtual dispatch and (almost) reduces the include bloat in
the main header path.

The reason for (almost) there is that for full include correctness,
`EnumInfo` needs `&lt;utility&gt;` include for `std::pair`. However, this brings
in things like `std::relops`, because the std headers in C++ are dumb.
As this was not included before, and instead we relied on `std::pair`
existing in an internal stdlib header that we transitively included, the
full include size ends up bigger than before.
</pre>
</div>
</content>
</entry>
<entry>
<title>Turn IResultCapture::lastAssertionPassed into a free function</title>
<updated>2026-04-07T12:33:39+00:00</updated>
<author>
<name>Martin Hořeňovský</name>
</author>
<published>2026-04-07T11:35:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=77eae8bd2a2c8c3135d30649aa7c51b5bfc0e61e'/>
<id>77eae8bd2a2c8c3135d30649aa7c51b5bfc0e61e</id>
<content type='text'>
The thread-safety changes in assertions &amp; messages turned whether
the last assertion passed or failed into thread-local state,
instead of being member of the `RunContext`. However, this change
was not reflected in the API `CHECKED_IF`/`CHECKED_ELSE` used,
which in turn required `catch_test_macro_impl.hpp` to include
`catch_interfaces_capture.hpp` for it.

Thanks to the combination of this commit and the previous similar
commit for the message stack handling, the main include path does
not need to include `catch_interfaces_capture.hpp` anymore.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The thread-safety changes in assertions &amp; messages turned whether
the last assertion passed or failed into thread-local state,
instead of being member of the `RunContext`. However, this change
was not reflected in the API `CHECKED_IF`/`CHECKED_ELSE` used,
which in turn required `catch_test_macro_impl.hpp` to include
`catch_interfaces_capture.hpp` for it.

Thanks to the combination of this commit and the previous similar
commit for the message stack handling, the main include path does
not need to include `catch_interfaces_capture.hpp` anymore.
</pre>
</div>
</content>
</entry>
<entry>
<title>Turn IResultCapture::{push,pop}*Message into free functions</title>
<updated>2026-04-07T12:28:11+00:00</updated>
<author>
<name>Martin Hořeňovský</name>
</author>
<published>2026-04-07T11:09:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=3ab0d7cef3313d91e652a89870c89b0c42760f9e'/>
<id>3ab0d7cef3313d91e652a89870c89b0c42760f9e</id>
<content type='text'>
The thread-safety changes in assertions &amp; messages turned the message
stacks into thread-local state, instead of it being member of `RunContext`.
The relevant {push,pop}(Un)ScopedMessage functions were turned from member
functions into static functions, but this left `catch_message.hpp` with
dependency on `IResultCapture`'s definition for the functions, and thus
it still had to include `catch_interfaces_capture.hpp`.

With this change, `catch_message.hpp` no longer needs
`catch_interfaces_capture.hpp`.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The thread-safety changes in assertions &amp; messages turned the message
stacks into thread-local state, instead of it being member of `RunContext`.
The relevant {push,pop}(Un)ScopedMessage functions were turned from member
functions into static functions, but this left `catch_message.hpp` with
dependency on `IResultCapture`'s definition for the functions, and thus
it still had to include `catch_interfaces_capture.hpp`.

With this change, `catch_message.hpp` no longer needs
`catch_interfaces_capture.hpp`.
</pre>
</div>
</content>
</entry>
<entry>
<title>Inline SKIP/FAIL in RunContext to fix build failure with prefixed macros</title>
<updated>2026-04-03T08:19:05+00:00</updated>
<author>
<name>Martin Hořeňovský</name>
</author>
<published>2026-04-02T20:58:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=9f1b48a94fdc7a54aa87fc9bd26d6b1b3f560d4c'/>
<id>9f1b48a94fdc7a54aa87fc9bd26d6b1b3f560d4c</id>
<content type='text'>
Closes #3087
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Closes #3087
</pre>
</div>
</content>
</entry>
<entry>
<title>Support filtering on both sections and generators (#3069)</title>
<updated>2026-02-15T19:27:15+00:00</updated>
<author>
<name>Martin Hořeňovský</name>
</author>
<published>2026-02-15T19:27:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=3a0cf7e75fdc571ff9ed25303fb268665f6260c0'/>
<id>3a0cf7e75fdc571ff9ed25303fb268665f6260c0</id>
<content type='text'>
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.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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.
</pre>
</div>
</content>
</entry>
<entry>
<title>Simplify IGeneratorTracker</title>
<updated>2026-02-13T20:17:37+00:00</updated>
<author>
<name>Martin Hořeňovský</name>
</author>
<published>2026-02-12T20:39:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=045ac7acce5205e529a7a6fda155cadc3dfe68e7'/>
<id>045ac7acce5205e529a7a6fda155cadc3dfe68e7</id>
<content type='text'>
* 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.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* 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.
</pre>
</div>
</content>
</entry>
</feed>
