/ externals / catch / docs / contributing.md
contributing.md
  1  <a id="top"></a>
  2  # Contributing to Catch2
  3  
  4  **Contents**<br>
  5  [Using Git(Hub)](#using-github)<br>
  6  [Testing your changes](#testing-your-changes)<br>
  7  [Writing documentation](#writing-documentation)<br>
  8  [Writing code](#writing-code)<br>
  9  [CoC](#coc)<br>
 10  
 11  So you want to contribute something to Catch2? That's great! Whether it's
 12  a bug fix, a new feature, support for additional compilers - or just
 13  a fix to the documentation - all contributions are very welcome and very
 14  much appreciated. Of course so are bug reports, other comments, and
 15  questions, but generally it is a better idea to ask questions in our
 16  [Discord](https://discord.gg/4CWS9zD), than in the issue tracker.
 17  
 18  
 19  This page covers some guidelines and helpful tips for contributing
 20  to the codebase itself.
 21  
 22  ## Using Git(Hub)
 23  
 24  Ongoing development happens in the `devel` branch for Catch2 v3, and in
 25  `v2.x` for maintenance updates to the v2 versions.
 26  
 27  Commits should be small and atomic. A commit is atomic when, after it is
 28  applied, the codebase, tests and all, still works as expected. Small
 29  commits are also preferred, as they make later operations with git history,
 30  whether it is bisecting, reverting, or something else, easier.
 31  
 32  _When submitting a pull request please do not include changes to the
 33  amalgamated distribution files. This means do not include them in your
 34  git commits!_
 35  
 36  When addressing review comments in a MR, please do not rebase/squash the
 37  commits immediately. Doing so makes it harder to review the new changes,
 38  slowing down the process of merging a MR. Instead, when addressing review
 39  comments, you should append new commits to the branch and only squash
 40  them into other commits when the MR is ready to be merged. We recommend
 41  creating new commits with `git commit --fixup` (or `--squash`) and then
 42  later squashing them with `git rebase --autosquash` to make things easier.
 43  
 44  
 45  
 46  ## Testing your changes
 47  
 48  _Note: Running Catch2's tests requires Python3_
 49  
 50  
 51  Catch2 has multiple layers of tests that are then run as part of our CI.
 52  The most obvious one are the unit tests compiled into the `SelfTest`
 53  binary. These are then used in "Approval tests", which run (almost) all
 54  tests from `SelfTest` through a specific reporter and then compare the
 55  generated output with a known good output ("Baseline"). By default, new
 56  tests should be placed here.
 57  
 58  To configure a Catch2 build with just the basic tests, use the `basic-tests`
 59  preset, like so:
 60  
 61  ```
 62  # Assuming you are in Catch2's root folder
 63  
 64  cmake -B basic-test-build -S . -DCMAKE_BUILD_TYPE=Debug --preset basic-tests
 65  ```
 66  
 67  However, not all tests can be written as plain unit tests. For example,
 68  checking that Catch2 orders tests randomly when asked to, and that this
 69  random ordering is subset-invariant, is better done as an integration
 70  test using an external check script. Catch2 integration tests are written
 71  using CTest, either as a direct command invocation + pass/fail regex,
 72  or by delegating the check to a Python script.
 73  
 74  Catch2 is slowly gaining more and more types of tests, currently Catch2
 75  project also has buildable examples, "ExtraTests", and CMake config tests.
 76  Examples present a small and self-contained snippets of code that
 77  use Catch2's facilities for specific purpose. Currently they are assumed
 78  passing if they compile.
 79  
 80  ExtraTests then are expensive tests, that we do not want to run all the
 81  time. This can be either because they take a long time to run, or because
 82  they take a long time to compile, e.g. because they test compile time
 83  configuration and require separate compilation.
 84  
 85  Finally, CMake config tests test that you set Catch2's compile-time
 86  configuration options through CMake, using CMake options of the same name.
 87  
 88  These test categories can be enabled one by one, by passing
 89  `-DCATCH_BUILD_EXAMPLES=ON`, `-DCATCH_BUILD_EXTRA_TESTS=ON`, and
 90  `-DCATCH_ENABLE_CONFIGURE_TESTS=ON` when configuring the build.
 91  
 92  Catch2 also provides a preset that promises to enable _all_ test types,
 93  `all-tests`.
 94  
 95  The snippet below will build & run all tests, in `Debug` compilation mode.
 96  
 97  <!-- snippet: catch2-build-and-test -->
 98  <a id='snippet-catch2-build-and-test'></a>
 99  ```sh
100  # 1. Regenerate the amalgamated distribution (some tests are built against it)
101  ./tools/scripts/generateAmalgamatedFiles.py
102  
103  # 2. Configure the full test build
104  cmake -B debug-build -S . -DCMAKE_BUILD_TYPE=Debug --preset all-tests
105  
106  # 3. Run the actual build
107  cmake --build debug-build
108  
109  # 4. Run the tests using CTest
110  cd debug-build
111  ctest -j 4 --output-on-failure -C Debug
112  ```
113  <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>
114  <!-- endSnippet -->
115  
116  For convenience, the above commands are in the script `tools/scripts/buildAndTest.sh`, and can be run like this:
117  
118  ```bash
119  cd Catch2
120  ./tools/scripts/buildAndTest.sh
121  ```
122  
123  A Windows version of the script is available at `tools\scripts\buildAndTest.cmd`.
124  
125  If you added new tests, you will likely see `ApprovalTests` failure.
126  After you check that the output difference is expected, you should
127  run `tools/scripts/approve.py` to confirm them, and include these changes
128  in your commit.
129  
130  
131  ## Writing documentation
132  
133  If you have added new feature to Catch2, it needs documentation, so that
134  other people can use it as well. This section collects some technical
135  information that you will need for updating Catch2's documentation, and
136  possibly some generic advise as well.
137  
138  
139  ### Technicalities
140  
141  First, the technicalities:
142  
143  * If you have introduced a new document, there is a simple template you
144  should use. It provides you with the top anchor mentioned to link to
145  (more below), and also with a backlink to the top of the documentation:
146  ```markdown
147  <a id="top"></a>
148  # Cool feature
149  
150  > [Introduced](https://github.com/catchorg/Catch2/pull/123456) in Catch2 X.Y.Z
151  
152  Text that explains how to use the cool feature.
153  
154  
155  ---
156  
157  [Home](Readme.md#top)
158  ```
159  
160  * Crosslinks to different pages should target the `top` anchor, like this
161  `[link to contributing](contributing.md#top)`.
162  
163  * We introduced version tags to the documentation, which show users in
164  which version a specific feature was introduced. This means that newly
165  written documentation should be tagged with a placeholder, that will
166  be replaced with the actual version upon release. There are 2 styles
167  of placeholders used through the documentation, you should pick one that
168  fits your text better (if in doubt, take a look at the existing version
169  tags for other features).
170    * `> [Introduced](link-to-issue-or-PR) in Catch2 X.Y.Z` - this
171    placeholder is usually used after a section heading
172    * `> X (Y and Z) was [introduced](link-to-issue-or-PR) in Catch2 X.Y.Z`
173    - this placeholder is used when you need to tag a subpart of something,
174    e.g. a list
175  
176  * For pages with more than 4 subheadings, we provide a table of contents
177  (ToC) at the top of the page. Because GitHub markdown does not support
178  automatic generation of ToC, it has to be handled semi-manually. Thus,
179  if you've added a new subheading to some page, you should add it to the
180  ToC. This can be done either manually, or by running the
181  `updateDocumentToC.py` script in the `scripts/` folder.
182  
183  ### Contents
184  
185  Now, for some content tips:
186  
187  * Usage examples are good. However, having large code snippets inline
188  can make the documentation less readable, and so the inline snippets
189  should be kept reasonably short. To provide more complex compilable
190  examples, consider adding new .cpp file to `examples/`.
191  
192  * Don't be afraid to introduce new pages. The current documentation
193  tends towards long pages, but a lot of that is caused by legacy, and
194  we know that some of the pages are overly big and unfocused.
195  
196  * When adding information to an existing page, please try to keep your
197  formatting, style and changes consistent with the rest of the page.
198  
199  * Any documentation has multiple different audiences, that desire
200  different information from the text. The 3 basic user-types to try and
201  cover are:
202    * A beginner to Catch2, who requires closer guidance for the usage of Catch2.
203    * Advanced user of Catch2, who want to customize their usage.
204    * Experts, looking for full reference of Catch2's capabilities.
205  
206  
207  ## Writing code
208  
209  If want to contribute code, this section contains some simple rules
210  and tips on things like code formatting, code constructions to avoid,
211  and so on.
212  
213  ### C++ standard version
214  
215  Catch2 currently targets C++14 as the minimum supported C++ version.
216  Features from higher language versions should be used only sparingly,
217  when the benefits from using them outweigh the maintenance overhead.
218  
219  Example of good use of polyfilling features is our use of `conjunction`,
220  where if available we use `std::conjunction` and otherwise provide our
221  own implementation. The reason it is good is that the surface area for
222  maintenance is quite small, and `std::conjunction` can directly use
223  compiler built-ins, thus providing significant compilation benefits.
224  
225  Example of bad use of polyfilling features would be to keep around two
226  sets of metaprogramming in the stringification implementation, once
227  using C++14 compliant TMP and once using C++17's `if constexpr`. While
228  the C++17 would provide significant compilation speedups, the maintenance
229  cost would be too high.
230  
231  
232  ### Formatting
233  
234  To make code formatting simpler for the contributors, Catch2 provides
235  its own config for `clang-format`. However, because it is currently
236  impossible to replicate existing Catch2's formatting in clang-format,
237  using it to reformat a whole file would cause massive diffs. To keep
238  the size of your diffs reasonable, you should only use clang-format
239  on the newly changed code.
240  
241  
242  ### Code constructs to watch out for
243  
244  This section is a (sadly incomplete) listing of various constructs that
245  are problematic and are not always caught by our CI infrastructure.
246  
247  
248  #### Naked exceptions and exceptions-related function
249  
250  If you are throwing an exception, it should be done via `CATCH_ERROR`
251  or `CATCH_RUNTIME_ERROR` in `internal/catch_enforce.hpp`. These macros will handle
252  the differences between compilation with or without exceptions for you.
253  However, some platforms (IAR) also have problems with exceptions-related
254  functions, such as `std::current_exceptions`. We do not have IAR in our
255  CI, but luckily there should not be too many reasons to use these.
256  However, if you do, they should be kept behind a
257  `CATCH_CONFIG_DISABLE_EXCEPTIONS` macro.
258  
259  
260  #### Avoid `std::move` and `std::forward`
261  
262  `std::move` and `std::forward` provide nice semantic name for a specific
263  `static_cast`. However, being function templates they have surprisingly
264  high cost during compilation, and can also have a negative performance
265  impact for low-optimization builds.
266  
267  You should be using `CATCH_MOVE` and `CATCH_FORWARD` macros from
268  `internal/catch_move_and_forward.hpp` instead. They expand into the proper
269  `static_cast`, and avoid the overhead of `std::move` and `std::forward`.
270  
271  
272  #### Unqualified usage of functions from C's stdlib
273  
274  If you are using a function from C's stdlib, please include the header
275  as `<cfoo>` and call the function qualified. The common knowledge that
276  there is no difference is wrong, QNX and VxWorks won't compile if you
277  include the header as `<cfoo>` and call the function unqualified.
278  
279  
280  #### User-Defined Literals (UDL) for Catch2' types
281  
282  Due to messy standardese and ... not great ... implementation of
283  `-Wreserved-identifier` in Clang, avoid declaring UDLs as
284  ```cpp
285  Approx operator "" _a(long double);
286  ```
287  and instead declare them as
288  ```cpp
289  Approx operator ""_a(long double);
290  ```
291  
292  Notice that the second version does not have a space between the `""` and
293  the literal suffix.
294  
295  
296  
297  ### New source file template
298  
299  If you are adding new source file, there is a template you should use.
300  Specifically, every source file should start with the licence header:
301  ```cpp
302  
303      //              Copyright Catch2 Authors
304      // Distributed under the Boost Software License, Version 1.0.
305      //   (See accompanying file LICENSE.txt or copy at
306      //        https://www.boost.org/LICENSE_1_0.txt)
307  
308      // SPDX-License-Identifier: BSL-1.0
309  ```
310  
311  The include guards for header files should follow the pattern `{FILENAME}_INCLUDED`.
312  This means that for file `catch_matchers_foo.hpp`, the include guard should
313  be `CATCH_MATCHERS_FOO_HPP_INCLUDED`, for `catch_generators_bar.hpp`, the include
314  guard should be `CATCH_GENERATORS_BAR_HPP_INCLUDED`, and so on.
315  
316  
317  ### Adding new `CATCH_CONFIG` option
318  
319  When adding new `CATCH_CONFIG` option, there are multiple places to edit:
320    * `CMake/CatchConfigOptions.cmake` - this is used to generate the
321      configuration options in CMake, so that CMake frontends know about them.
322    * `docs/configuration.md` - this is where the options are documented
323    * `src/catch2/catch_user_config.hpp.in` - this is template for generating
324      `catch_user_config.hpp` which contains the materialized configuration
325    * `BUILD.bazel` - Bazel does not have configuration support like CMake,
326      and all expansions need to be done manually
327    * other files as needed, e.g. `catch2/internal/catch_config_foo.hpp`
328      for the logic that guards the configuration
329  
330  
331  ## CoC
332  
333  This project has a [CoC](../CODE_OF_CONDUCT.md). Please adhere to it
334  while contributing to Catch2.
335  
336  -----------
337  
338  _This documentation will always be in-progress as new information comes
339  up, but we are trying to keep it as up to date as possible._
340  
341  ---
342  
343  [Home](Readme.md#top)