<feed xmlns='http://www.w3.org/2005/Atom'>
<title>catch3/src/catch2/catch_registry_hub.cpp, branch feature/cpp-tools</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>Give Catch3 its own build names and headers</title>
<updated>2026-10-24T23:37:35+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-10-24T23:37:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=126dc333564cb72b5115d9a9242d66694694b6d0'/>
<id>126dc333564cb72b5115d9a9242d66694694b6d0</id>
<content type='text'>
Catch2 compatibility means the API tests are written in: the macros, such
as TEST_CASE and REQUIRE, and the Catch:: namespace. It does not mean
Catch2's build names or header paths. find_package(Catch2) found Catch3,
and a project using both frameworks met two packages, two sets of targets,
two Catch.cmake modules and two catch2/ header trees with the same names.

Build names:
- CMake: project and package Catch3, targets Catch3::Catch3 and
  Catch3::Catch3WithMain, libraries Catch3 and Catch3Main, options
  CATCH3_*, lib/cmake/Catch3 with Catch3Config, and pkg-config catch3 and
  catch3-with-main. The version is Catch3's, 0.3.0, compatible within a
  minor version.
- The CMake scripts are Catch3.cmake (catch3_discover_tests),
  Catch3AddTests.cmake and Catch3ShardTests.cmake
  (catch3_add_sharded_tests); the helpers they define at ctest time have a
  catch3_ prefix. ParseAndAddCatchTests.cmake, deprecated upstream, is gone.
- Bazel //:catch3 and //:catch3_main, Meson catch3 and catch3-with-main
  (with override_dependency), Xmake catch3 and catch3_main, Premake Catch3
  and Catch3WithMain. Visual Studio projects get GUIDs of their own.
- The Progmasoft::Catch3 target and package are gone: property testing
  and snapshots are part of Catch3::Catch3. Their sources now build with
  the library's warning flags, so property failures are built field by
  field (no missing initializers) and the default property name is a
  thread-local pointer to the name its scope owns (no global destructor).

Headers: the engine moved from src/catch2 to src/Progmasoft/Catch3 with
Progmasoft names, so &lt;catch2/catch_test_macros.hpp&gt; is
&lt;Progmasoft/Catch3/TestMacros.hpp&gt;, &lt;catch2/matchers/catch_matchers_string.hpp&gt;
is &lt;Progmasoft/Catch3/Matchers/String.hpp&gt;, and interface headers are named
after their interface, such as Interfaces/IConfig.hpp. Include guards
became #pragma once. The installed headers go to include/Progmasoft.
src/Progmasoft/Context.cpp is StrategyContext.cpp, so no two sources share
a file name.

tools/scripts/upstreamFiles.txt lists the files that come from Catch2.
The license check expects BSL-1.0 on them and Progmasoft's header on the
rest of src/Progmasoft; the convenience-header check, the amalgamation
script and the surrogate tests take the engine's headers from it. The
amalgamated files are regenerated. The header-guard workflow checks for
#pragma once instead of checkguard.

Documents, the README and the release notes describe the new names.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Catch2 compatibility means the API tests are written in: the macros, such
as TEST_CASE and REQUIRE, and the Catch:: namespace. It does not mean
Catch2's build names or header paths. find_package(Catch2) found Catch3,
and a project using both frameworks met two packages, two sets of targets,
two Catch.cmake modules and two catch2/ header trees with the same names.

Build names:
- CMake: project and package Catch3, targets Catch3::Catch3 and
  Catch3::Catch3WithMain, libraries Catch3 and Catch3Main, options
  CATCH3_*, lib/cmake/Catch3 with Catch3Config, and pkg-config catch3 and
  catch3-with-main. The version is Catch3's, 0.3.0, compatible within a
  minor version.
- The CMake scripts are Catch3.cmake (catch3_discover_tests),
  Catch3AddTests.cmake and Catch3ShardTests.cmake
  (catch3_add_sharded_tests); the helpers they define at ctest time have a
  catch3_ prefix. ParseAndAddCatchTests.cmake, deprecated upstream, is gone.
- Bazel //:catch3 and //:catch3_main, Meson catch3 and catch3-with-main
  (with override_dependency), Xmake catch3 and catch3_main, Premake Catch3
  and Catch3WithMain. Visual Studio projects get GUIDs of their own.
- The Progmasoft::Catch3 target and package are gone: property testing
  and snapshots are part of Catch3::Catch3. Their sources now build with
  the library's warning flags, so property failures are built field by
  field (no missing initializers) and the default property name is a
  thread-local pointer to the name its scope owns (no global destructor).

Headers: the engine moved from src/catch2 to src/Progmasoft/Catch3 with
Progmasoft names, so &lt;catch2/catch_test_macros.hpp&gt; is
&lt;Progmasoft/Catch3/TestMacros.hpp&gt;, &lt;catch2/matchers/catch_matchers_string.hpp&gt;
is &lt;Progmasoft/Catch3/Matchers/String.hpp&gt;, and interface headers are named
after their interface, such as Interfaces/IConfig.hpp. Include guards
became #pragma once. The installed headers go to include/Progmasoft.
src/Progmasoft/Context.cpp is StrategyContext.cpp, so no two sources share
a file name.

tools/scripts/upstreamFiles.txt lists the files that come from Catch2.
The license check expects BSL-1.0 on them and Progmasoft's header on the
rest of src/Progmasoft; the convenience-header check, the amalgamation
script and the surrogate tests take the engine's headers from it. The
amalgamated files are regenerated. The header-guard workflow checks for
#pragma once instead of checkguard.

Documents, the README and the release notes describe the new names.
</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>Don't store extra copy of all `TestCaseInfo*` in `TestRegistry`</title>
<updated>2026-08-22T21:28:11+00:00</updated>
<author>
<name>Martin Hořeňovský</name>
</author>
<published>2026-08-22T21:28:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=ef3a728265292e6a1dbec727b0099d3d8b3f6420'/>
<id>ef3a728265292e6a1dbec727b0099d3d8b3f6420</id>
<content type='text'>
We used to store a full vector of "views" of the registered test infos,
so that it can be retrieved externally. However, the only user of that
interface left was `Session`, specifically `Session::applyFilenameAsTags`.

By moving the adding of the filename tags into the `ITestCaseRegistry`
interface, we avoid storing the vector and make the initial test registration
faster.

The new code is ugly and shows a design/layering issue, but no worse than
the previous approach did.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
We used to store a full vector of "views" of the registered test infos,
so that it can be retrieved externally. However, the only user of that
interface left was `Session`, specifically `Session::applyFilenameAsTags`.

By moving the adding of the filename tags into the `ITestCaseRegistry`
interface, we avoid storing the vector and make the initial test registration
faster.

The new code is ugly and shows a design/layering issue, but no worse than
the previous approach did.
</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>Keep the main Context instance as static value, not pointer</title>
<updated>2025-09-27T11:24:44+00:00</updated>
<author>
<name>Martin Hořeňovský</name>
</author>
<published>2025-09-23T09:32:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=a2e41916f2cc0adbd27fc3d9cb89e9615fea1ad8'/>
<id>a2e41916f2cc0adbd27fc3d9cb89e9615fea1ad8</id>
<content type='text'>
This allows us to remove the lazy init checks, improving the inlining
potential when retrieving current context, thus slightly improving
the performance of assertions.

**runtime difference**

| --------- | Debug | Release |
|:----------|------:|--------:|
| Slow path |  1.01 |    0.98 |
| Fast path |  1.02 |    1.02 |

There is small slowdown in case of Release build + assertions taking
the slow path, but

1) going through the slow path is rare
2) Given the code change, I believe this to be artifact of the
   optimizer in the old GCC version I am using locally.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This allows us to remove the lazy init checks, improving the inlining
potential when retrieving current context, thus slightly improving
the performance of assertions.

**runtime difference**

| --------- | Debug | Release |
|:----------|------:|--------:|
| Slow path |  1.01 |    0.98 |
| Fast path |  1.02 |    1.02 |

There is small slowdown in case of Release build + assertions taking
the slow path, but

1) going through the slow path is rare
2) Given the code change, I believe this to be artifact of the
   optimizer in the old GCC version I am using locally.
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix various useful clang-tidy warnings</title>
<updated>2024-03-01T20:24:45+00:00</updated>
<author>
<name>Martin Jeřábek</name>
</author>
<published>2024-03-01T10:15:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=cde35096641d55b4aa0f743bb03e04703fbb5e9c'/>
<id>cde35096641d55b4aa0f743bb03e04703fbb5e9c</id>
<content type='text'>
* bugprone-branch-clone
* bugprone-copy-constructor-init
* bugprone-empty-catch
* bugprone-sizeof-expression
* bugprone-switch-missing-default-case
* bugprone-unused-local-non-trivial-variable
* clang-analyzer-core.uninitialized.Assign
* clang-analyzer-cplusplus.Move
* clang-analyzer-optin.cplusplus.VirtualCall
* modernize-loop-convert
* modernize-raw-string-literal
* modernize-use-equals-default
* modernize-use-override
* modernize-use-using
* performance-avoid-endl
* performance-inefficient-string-concatenation
* performance-inefficient-vector-operation
* performance-noexcept-move-constructor
* performance-unnecessary-value-param (and improve generator example)
* readability-duplicate-include
* readability-inconsistent-declaration-parameter-name
* readability-non-const-parameter
* readability-redundant-casting
* readability-redundant-member-init
* readability-redundant-smartptr-get
* readability-static-accessed-through-instance
* unused variable in amalgamted tests
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* bugprone-branch-clone
* bugprone-copy-constructor-init
* bugprone-empty-catch
* bugprone-sizeof-expression
* bugprone-switch-missing-default-case
* bugprone-unused-local-non-trivial-variable
* clang-analyzer-core.uninitialized.Assign
* clang-analyzer-cplusplus.Move
* clang-analyzer-optin.cplusplus.VirtualCall
* modernize-loop-convert
* modernize-raw-string-literal
* modernize-use-equals-default
* modernize-use-override
* modernize-use-using
* performance-avoid-endl
* performance-inefficient-string-concatenation
* performance-inefficient-vector-operation
* performance-noexcept-move-constructor
* performance-unnecessary-value-param (and improve generator example)
* readability-duplicate-include
* readability-inconsistent-declaration-parameter-name
* readability-non-const-parameter
* readability-redundant-casting
* readability-redundant-member-init
* readability-redundant-smartptr-get
* readability-static-accessed-through-instance
* unused variable in amalgamted tests
</pre>
</div>
</content>
</entry>
<entry>
<title>🛠 Add &lt;exception&gt; header where strictly necessary</title>
<updated>2023-05-16T16:18:57+00:00</updated>
<author>
<name>ThePhD</name>
</author>
<published>2023-05-16T16:13:49+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=05d7eb5a0028906e4c6270b2340ae0d88d3cfa2a'/>
<id>05d7eb5a0028906e4c6270b2340ae0d88d3cfa2a</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Unify IReporterRegistry and ReporterRegistry</title>
<updated>2023-03-22T22:58:44+00:00</updated>
<author>
<name>Martin Hořeňovský</name>
</author>
<published>2023-03-12T23:03:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=d0f70fdfd661b50c1b8721ae70d49656dc68929b'/>
<id>d0f70fdfd661b50c1b8721ae70d49656dc68929b</id>
<content type='text'>
To keep the compilation firewall effect, the implementations
are hidden behind a PIMPL. In this case it is probably not
worth it, but we can inline it later if needed.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
To keep the compilation firewall effect, the implementations
are hidden behind a PIMPL. In this case it is probably not
worth it, but we can inline it later if needed.
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix references to license file</title>
<updated>2022-10-28T09:30:15+00:00</updated>
<author>
<name>Lars Toenning</name>
</author>
<published>2022-10-28T09:22:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=f1084fb30990fe40c8f5b70034970c7eb4e1da72'/>
<id>f1084fb30990fe40c8f5b70034970c7eb4e1da72</id>
<content type='text'>
The license file was renamed with 6a502cc2f5fedd59b3495b58708f0d6d987ed9e1
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The license file was renamed with 6a502cc2f5fedd59b3495b58708f0d6d987ed9e1
</pre>
</div>
</content>
</entry>
<entry>
<title>Event listeners no longer take reporter config in constructor</title>
<updated>2022-03-17T23:36:18+00:00</updated>
<author>
<name>Martin Hořeňovský</name>
</author>
<published>2022-03-14T14:04:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=4acc520f763f7a104d11d57afb8d3bab0bfa6ebc'/>
<id>4acc520f763f7a104d11d57afb8d3bab0bfa6ebc</id>
<content type='text'>
This also required splitting out Listener factory from
the reporter factory hierarchy. In return, the listener
factories only need to take in `IConfig const*`, which
opens up further refactorings down the road in the colour
selection and implementation.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This also required splitting out Listener factory from
the reporter factory hierarchy. In return, the listener
factories only need to take in `IConfig const*`, which
opens up further refactorings down the road in the colour
selection and implementation.
</pre>
</div>
</content>
</entry>
</feed>
