diff options
| author | Leitwolf | 2026-10-24 20:29:24 +0300 |
|---|---|---|
| committer | GitHub | 2026-10-24 20:29:24 +0300 |
| commit | 13f81a480a93807c14dddb5abdb97355ced4d4c5 (patch) | |
| tree | cd2055cb2eeb0bdef1d5bed1d39d9569df6f5b97 /docs/contributing.md | |
| parent | 4f1c759cffcb14bd6511e1d7c5fbace682e24f2d (diff) | |
| parent | a2edf60b9f410d26485ac7c0492870a0905f9545 (diff) | |
| download | catch3-13f81a480a93807c14dddb5abdb97355ced4d4c5.tar.gz | |
Merge pull request #16 from Progmasoft/chore/remove-upstream-leftovers
Remove what Catch2's maintainers left that is not ours
Diffstat (limited to 'docs/contributing.md')
| -rw-r--r-- | docs/contributing.md | 396 |
1 files changed, 59 insertions, 337 deletions
diff --git a/docs/contributing.md b/docs/contributing.md index e67ea237..ba8fe371 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -1,378 +1,100 @@ <a id="top"></a> - -> **Upstream history:** This page is retained from Catch2 for provenance and compatibility. It does not describe Catch3 release policy or Progmasoft support. See [Catch3 documentation](Readme.md#top) for current guidance. - -# Contributing to Catch2 +# Contributing to Catch3 **Contents**<br> -[Using Git(Hub)](#using-github)<br> -[Testing your changes](#testing-your-changes)<br> -[Writing documentation](#writing-documentation)<br> -[Writing code](#writing-code)<br> -[CoC](#coc)<br> -[Using LLMs when contributing](#using-llms-when-contributing)<br> - - -So you want to contribute something to Catch2? That's great! Whether it's -a bug fix, a new feature, support for additional compilers - or just -a fix to the documentation - all contributions are very welcome and very -much appreciated. Of course so are bug reports, other comments, and -questions, but generally it is a better idea to ask questions in our -[Discord](https://discord.gg/4CWS9zD), than in the issue tracker. - - -This page covers some guidelines and helpful tips for contributing -to the codebase itself. - -## Using Git(Hub) - -Ongoing development happens in the `devel` branch for Catch2 v3, and in -`v2.x` for maintenance updates to the v2 versions. - -Commits should be small and atomic. A commit is atomic when, after it is -applied, the codebase, tests and all, still works as expected. Small -commits are also preferred, as they make later operations with git history, -whether it is bisecting, reverting, or something else, easier. - -_When submitting a pull request please do not include changes to the -amalgamated distribution files. This means do not include them in your -git commits!_ - -When addressing review comments in a MR, please do not rebase/squash the -commits immediately. Doing so makes it harder to review the new changes, -slowing down the process of merging a MR. Instead, when addressing review -comments, you should append new commits to the branch and only squash -them into other commits when the MR is ready to be merged. We recommend -creating new commits with `git commit --fixup` (or `--squash`) and then -later squashing them with `git rebase --autosquash` to make things easier. +[Where to start](#where-to-start)<br> +[Building and testing](#building-and-testing)<br> +[Two parts, two sets of rules](#two-parts-two-sets-of-rules)<br> +[Tests](#tests)<br> +[Documentation](#documentation)<br> +[Code of Conduct](#code-of-conduct)<br> +Progmasoft maintains Catch3. Issues and pull requests are welcome on +[Progmasoft/catch3](https://github.com/Progmasoft/catch3); pull requests go +to the `devel` branch. Report security problems privately, as described in +[SECURITY.md](../SECURITY.md), not in a public issue. -## Testing your changes +## Where to start -_Note: Running Catch2's tests requires Python3_ +Open an issue before a large change, so that the direction can be agreed +first. A pull request should do one thing, say why in its description and +come with the tests that show it works. -Catch2 has multiple layers of tests that are then run as part of our CI. -The most obvious one are the unit tests compiled into the `SelfTest` -binary. These are then used in "Approval tests", which run (almost) all -tests from `SelfTest` through a specific reporter and then compare the -generated output with a known good output ("Baseline"). By default, new -tests should be placed here. +## Building and testing -To configure a Catch2 build with just the basic tests, use the `basic-tests` -preset, like so: +Bazel is the main build. With [Bazelisk](https://github.com/bazelbuild/bazelisk): ``` -# Assuming you are in Catch2's root folder - -cmake -B basic-test-build -S . -DCMAKE_BUILD_TYPE=Debug --preset basic-tests +bazelisk test //tests/... ``` -However, not all tests can be written as plain unit tests. For example, -checking that Catch2 orders tests randomly when asked to, and that this -random ordering is subset-invariant, is better done as an integration -test using an external check script. Catch2 integration tests are written -using CTest, either as a direct command invocation + pass/fail regex, -or by delegating the check to a Python script. - -Catch2 is slowly gaining more and more types of tests, currently Catch2 -project also has buildable examples, "ExtraTests", and CMake config tests. -Examples present a small and self-contained snippets of code that -use Catch2's facilities for specific purpose. Currently they are assumed -passing if they compile. - -ExtraTests then are expensive tests, that we do not want to run all the -time. This can be either because they take a long time to run, or because -they take a long time to compile, e.g. because they test compile time -configuration and require separate compilation. - -Finally, CMake config tests test that you set Catch2's compile-time -configuration options through CMake, using CMake options of the same name. - -These test categories can be enabled one by one, by passing -`-DCATCH_BUILD_EXAMPLES=ON`, `-DCATCH_BUILD_EXTRA_TESTS=ON`, and -`-DCATCH_ENABLE_CONFIGURE_TESTS=ON` when configuring the build. - -Catch2 also provides a preset that promises to enable _all_ test types, -`all-tests`. - -The snippet below will build & run all tests, in `Debug` compilation mode. - -<!-- snippet: catch2-build-and-test --> -<a id='snippet-catch2-build-and-test'></a> -```sh -# 1. Regenerate the amalgamated distribution (some tests are built against it) -./tools/scripts/generateAmalgamatedFiles.py - -# 2. Configure the full test build -cmake -B debug-build -S . -DCMAKE_BUILD_TYPE=Debug --preset all-tests - -# 3. Run the actual build -cmake --build debug-build +On Windows, point Bazel at Git's bash first: +`BAZEL_SH="C:\Program Files\Git\usr\bin\bash.exe"`. -# 4. Run the tests using CTest -ctest -j 4 --output-on-failure -C Debug --test-dir debug-build -``` -<sup><a href='/tools/scripts/buildAndTest.sh#L6-L19' title='File snippet `catch2-build-and-test` was extracted from'>snippet source</a> | <a href='#snippet-catch2-build-and-test' title='Navigate to start of snippet `catch2-build-and-test`'>anchor</a></sup> -<!-- endSnippet --> - -For convenience, the above commands are in the script `tools/scripts/buildAndTest.sh`, and can be run like this: +CMake builds every test, including the extra tests that check compile-time +configurations: -```bash -cd Catch2 -./tools/scripts/buildAndTest.sh ``` - -A Windows version of the script is available at `tools\scripts\buildAndTest.cmd`. - -If you added new tests, you will likely see `ApprovalTests` failure. -After you check that the output difference is expected, you should -run `tools/scripts/approve.py` to confirm them, and include these changes -in your commit. - - -## Writing documentation - -If you have added new feature to Catch2, it needs documentation, so that -other people can use it as well. This section collects some technical -information that you will need for updating Catch2's documentation, and -possibly some generic advise as well. - - -### Technicalities - -First, the technicalities: - -* If you have introduced a new document, there is a simple template you -should use. It provides you with the top anchor mentioned to link to -(more below), and also with a backlink to the top of the documentation: -```markdown -<a id="top"></a> -# Cool feature - -> [Introduced](https://github.com/catchorg/Catch2/pull/123456) in Catch2 X.Y.Z - -Text that explains how to use the cool feature. - - ---- - -[Home](Readme.md#top) +cmake --preset basic-tests -GNinja -DCATCH_BUILD_EXTRA_TESTS=ON -DCATCH_BUILD_EXAMPLES=ON +cmake --build build +ctest --test-dir build -j ``` -* Crosslinks to different pages should target the `top` anchor, like this -`[link to contributing](contributing.md#top)`. - -* We introduced version tags to the documentation, which show users in -which version a specific feature was introduced. This means that newly -written documentation should be tagged with a placeholder, that will -be replaced with the actual version upon release. There are 2 styles -of placeholders used through the documentation, you should pick one that -fits your text better (if in doubt, take a look at the existing version -tags for other features). - * `> [Introduced](link-to-issue-or-PR) in Catch2 X.Y.Z` - this - placeholder is usually used after a section heading - * `> X (Y and Z) was [introduced](link-to-issue-or-PR) in Catch2 X.Y.Z` - - this placeholder is used when you need to tag a subpart of something, - e.g. a list - -* For pages with more than 4 subheadings, we provide a table of contents -(ToC) at the top of the page. Because GitHub markdown does not support -automatic generation of ToC, it has to be handled semi-manually. Thus, -if you've added a new subheading to some page, you should add it to the -ToC. This can be done either manually, or by running the -`updateDocumentToC.py` script in the `scripts/` folder. +Meson, Xmake and Premake builds exist as well and are checked in CI. -### Contents +Before you push, run the repository checks: -Now, for some content tips: - -* Usage examples are good. However, having large code snippets inline -can make the documentation less readable, and so the inline snippets -should be kept reasonably short. To provide more complex compilable -examples, consider adding new .cpp file to `examples/`. - -* Don't be afraid to introduce new pages. The current documentation -tends towards long pages, but a lot of that is caused by legacy, and -we know that some of the pages are overly big and unfocused. - -* When adding information to an existing page, please try to keep your -formatting, style and changes consistent with the rest of the page. - -* Any documentation has multiple different audiences, that desire -different information from the text. The 3 basic user-types to try and -cover are: - * A beginner to Catch2, who requires closer guidance for the usage of Catch2. - * Advanced user of Catch2, who want to customize their usage. - * Experts, looking for full reference of Catch2's capabilities. - - -## Writing code - -If want to contribute code, this section contains some simple rules -and tips on things like code formatting, code constructions to avoid, -and so on. - -### C++ standard version - -Catch2 currently targets C++14 as the minimum supported C++ version. -Features from higher language versions should be used only sparingly, -when the benefits from using them outweigh the maintenance overhead. - -Example of good use of polyfilling features is our use of `conjunction`, -where if available we use `std::conjunction` and otherwise provide our -own implementation. The reason it is good is that the surface area for -maintenance is quite small, and `std::conjunction` can directly use -compiler built-ins, thus providing significant compilation benefits. - -Example of bad use of polyfilling features would be to keep around two -sets of metaprogramming in the stringification implementation, once -using C++14 compliant TMP and once using C++17's `if constexpr`. While -the C++17 would provide significant compilation speedups, the maintenance -cost would be too high. - - -### Formatting - -To make code formatting simpler for the contributors, Catch2 provides -its own config for `clang-format`. However, because it is currently -impossible to replicate existing Catch2's formatting in clang-format, -using it to reformat a whole file would cause massive diffs. To keep -the size of your diffs reasonable, you should only use clang-format -on the newly changed code. - - -### Progmasoft-authored code - -The code under `src/Progmasoft/` and `tests/Progmasoft/` is not derived -from Catch2 and follows -[Progmasoft C++ Style](https://github.com/Progmasoft/progmasoft-cpp): -its naming, its formatting profile, its language and documentation -rules. The code derived from Catch2 keeps the upstream style described -on this page, so that changes from upstream still apply cleanly. - -Progmasoft-authored code deviates from the guide where the Catch2 API -requires it: - -* It lives in the namespace `Progmasoft::Catch3`, with helpers in - `Progmasoft::Catch3::Detail`. -* It may throw, because a failed assertion is reported by an exception, - as everywhere in Catch2. Exceptions stay inside the library and never - cross into the code under test. - - -### Code constructs to watch out for - -This section is a (sadly incomplete) listing of various constructs that -are problematic and are not always caught by our CI infrastructure. - - -#### Naked exceptions and exceptions-related function - -If you are throwing an exception, it should be done via `CATCH_ERROR` -or `CATCH_RUNTIME_ERROR` in `internal/catch_enforce.hpp`. These macros will handle -the differences between compilation with or without exceptions for you. -However, some platforms (IAR) also have problems with exceptions-related -functions, such as `std::current_exceptions`. We do not have IAR in our -CI, but luckily there should not be too many reasons to use these. -However, if you do, they should be kept behind a -`CATCH_CONFIG_DISABLE_EXCEPTIONS` macro. - - -#### Avoid `std::move` and `std::forward` - -`std::move` and `std::forward` provide nice semantic name for a specific -`static_cast`. However, being function templates they have surprisingly -high cost during compilation, and can also have a negative performance -impact for low-optimization builds. - -You should be using `CATCH_MOVE` and `CATCH_FORWARD` macros from -`internal/catch_move_and_forward.hpp` instead. They expand into the proper -`static_cast`, and avoid the overhead of `std::move` and `std::forward`. - - -#### Unqualified usage of functions from C's stdlib - -If you are using a function from C's stdlib, please include the header -as `<cfoo>` and call the function qualified. The common knowledge that -there is no difference is wrong, QNX and VxWorks won't compile if you -include the header as `<cfoo>` and call the function unqualified. - - -#### User-Defined Literals (UDL) for Catch2' types - -Due to messy standardese and ... not great ... implementation of -`-Wreserved-identifier` in Clang, avoid declaring UDLs as -```cpp -Approx operator "" _a(long double); ``` -and instead declare them as -```cpp -Approx operator ""_a(long double); +python tools/scripts/checkLicense.py +python tools/scripts/checkConvenienceHeaders.py +python tools/scripts/checkDuplicateFilenames.py ``` -Notice that the second version does not have a space between the `""` and -the literal suffix. - - - -### New source file template - -If you are adding new source file, there is a template you should use. -Specifically, every source file should start with the licence header: -```cpp - - // Copyright Catch2 Authors - // Distributed under the Boost Software License, Version 1.0. - // (See accompanying file LICENSE.txt or copy at - // https://www.boost.org/LICENSE_1_0.txt) - - // SPDX-License-Identifier: BSL-1.0 -``` +A change to anything under `src/` also regenerates the single-file +distribution with `python tools/scripts/generateAmalgamatedFiles.py`. -The include guards for header files should follow the pattern `{FILENAME}_INCLUDED`. -This means that for file `catch_matchers_foo.hpp`, the include guard should -be `CATCH_MATCHERS_FOO_HPP_INCLUDED`, for `catch_generators_bar.hpp`, the include -guard should be `CATCH_GENERATORS_BAR_HPP_INCLUDED`, and so on. +## Two parts, two sets of rules -### Adding new `CATCH_CONFIG` option +`src/catch2` is the compatibility engine taken from Catch2. Its public API is +what Catch3 promises to keep: code that compiles against Catch2's headers +must keep compiling. It stays under the Boost Software License 1.0, keeps the +`Catch2 Authors` header and follows the style of the surrounding Catch2 code. +Code that includes only its headers needs C++14. -When adding new `CATCH_CONFIG` option, there are multiple places to edit: - * `CMake/CatchConfigOptions.cmake` - this is used to generate the - configuration options in CMake, so that CMake frontends know about them. - * `docs/configuration.md` - this is where the options are documented - * `src/catch2/catch_user_config.hpp.in` - this is template for generating - `catch_user_config.hpp` which contains the materialized configuration - * `BUILD.bazel` - Bazel does not have configuration support like CMake, - and all expansions need to be done manually - * other files as needed, e.g. `catch2/internal/catch_config_foo.hpp` - for the logic that guards the configuration +`src/Progmasoft` holds what Progmasoft adds: the runner, the results model, +property testing and snapshots. It is licensed `MPL-2.0 WITH +AdditionRef-Progmasoft-Exception-1.1`, follows the +[Progmasoft C++ Style](https://github.com/Progmasoft/progmasoft-cpp), is +C++20, reports recoverable errors with `Expected` rather than exceptions, and +is formatted with the `.clang-format` beside it. +`tools/scripts/checkLicense.py` checks that every source file carries the +header of its part. -## CoC -This project has a [CoC](../CODE_OF_CONDUCT.md). Please adhere to it -while contributing to Catch2. +## Tests +`tests/SelfTest` tests the compatibility engine; `tests/ExtraTests` tests +compile-time configurations and the runner's behaviour around them; +`tests/Progmasoft` tests the Progmasoft code, and the runner's integration +tests there start a fixture binary whose tests misbehave on purpose. A bug fix +comes with a test that fails without it. -## Using LLMs when contributing -I do not care whether you used LLM for your contribution. What I care -about is the quality of the contribution, not whether you made it through -prompting LLM, letting GAs run wild, dictated it into the computer, wrote -it using your nose or used butterflies to flip the correct bits. +## Documentation -The flipside of this is that I am also not going to iterate your LLM for -you. If a PR looks LLM generated and does not pass the muster to be merged -as-is, I am going to close it. +User documentation lives in `docs/`. A new page is linked from +[the documentation index](Readme.md#top), and a page with sections gets a table +of contents; `python tools/scripts/updateDocumentToC.py` keeps them current. +A user-visible change gets a line in [the release notes](release-notes.md#top). ------------ +## Code of Conduct -_This documentation will always be in-progress as new information comes -up, but we are trying to keep it as up to date as possible._ +Everyone who takes part follows the [Code of Conduct](../CODE_OF_CONDUCT.md). --- |