diff -Nru catch2-2.12.1/BUILD.bazel catch2-2.13.0/BUILD.bazel --- catch2-2.12.1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ catch2-2.13.0/BUILD.bazel 2020-07-12 18:28:38.000000000 +0000 @@ -0,0 +1,10 @@ +# Load the cc_library rule. +load("@rules_cc//cc:defs.bzl", "cc_library") + +# Header-only rule to export catch2/catch.hpp. +cc_library( + name = "catch2", + hdrs = ["single_include/catch2/catch.hpp"], + visibility = ["//visibility:public"], + includes = ["single_include/"], +) diff -Nru catch2-2.12.1/.clang-format catch2-2.13.0/.clang-format --- catch2-2.12.1/.clang-format 1970-01-01 00:00:00.000000000 +0000 +++ catch2-2.13.0/.clang-format 2020-07-12 18:28:38.000000000 +0000 @@ -0,0 +1,25 @@ +--- +AccessModifierOffset: '-4' +AlignEscapedNewlines: Left +AllowAllConstructorInitializersOnNextLine: 'true' +BinPackArguments: 'false' +BinPackParameters: 'false' +BreakConstructorInitializers: AfterColon +ConstructorInitializerAllOnOneLineOrOnePerLine: 'true' +DerivePointerAlignment: 'false' +FixNamespaceComments: 'true' +IncludeBlocks: Regroup +IndentCaseLabels: 'false' +IndentPPDirectives: AfterHash +IndentWidth: '4' +Language: Cpp +NamespaceIndentation: All +PointerAlignment: Left +SpaceBeforeCtorInitializerColon: 'false' +SpaceInEmptyParentheses: 'false' +SpacesInParentheses: 'true' +Standard: Cpp11 +TabWidth: '4' +UseTab: Never + +... diff -Nru catch2-2.12.1/CMakeLists.txt catch2-2.13.0/CMakeLists.txt --- catch2-2.12.1/CMakeLists.txt 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/CMakeLists.txt 2020-07-12 18:28:38.000000000 +0000 @@ -14,7 +14,7 @@ endif() -project(Catch2 LANGUAGES CXX VERSION 2.12.1) +project(Catch2 LANGUAGES CXX VERSION 2.13.0) # Provide path for scripts list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake") diff -Nru catch2-2.12.1/.conan/build.py catch2-2.13.0/.conan/build.py --- catch2-2.12.1/.conan/build.py 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/.conan/build.py 2020-07-12 18:28:38.000000000 +0000 @@ -31,7 +31,7 @@ not match the stable pattern. Otherwise it will upload to stable channel. """ - return os.getenv("CONAN_UPLOAD", "https://api.bintray.com/conan/catchorg/Catch2") + return os.getenv("CONAN_UPLOAD", "https://api.bintray.com/conan/catchorg/catch2") @property def upload_only_when_stable(self): diff -Nru catch2-2.12.1/conanfile.py catch2-2.13.0/conanfile.py --- catch2-2.12.1/conanfile.py 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/conanfile.py 2020-07-12 18:28:38.000000000 +0000 @@ -25,3 +25,6 @@ def package_id(self): self.info.header_only() + + def package_info(self): + self.cpp_info.builddirs.append("lib/cmake/Catch2") diff -Nru catch2-2.12.1/debian/changelog catch2-2.13.0/debian/changelog --- catch2-2.12.1/debian/changelog 2020-05-16 22:37:17.000000000 +0000 +++ catch2-2.13.0/debian/changelog 2020-12-04 17:12:14.000000000 +0000 @@ -1,8 +1,26 @@ -catch2 (2.12.1-1~ubuntu20.04.1~ppa1) focal; urgency=medium +catch2 (2.13.0-1~ubuntu20.04.1~ppa1) focal; urgency=medium * No-change backport to focal - -- jfhovinne Sun, 17 May 2020 00:37:17 +0200 + -- jfhovinne Fri, 04 Dec 2020 18:12:14 +0100 + +catch2 (2.13.0-1) unstable; urgency=medium + + * New upstream release + + -- Mathieu Mirmont Mon, 13 Jul 2020 09:24:41 +0200 + +catch2 (2.12.3-1) unstable; urgency=medium + + * New upstream release + + -- Mathieu Mirmont Wed, 01 Jul 2020 23:14:32 +0200 + +catch2 (2.12.2-1) unstable; urgency=medium + + * New upstream release + + -- Mathieu Mirmont Wed, 27 May 2020 17:18:34 +0200 catch2 (2.12.1-1) unstable; urgency=medium diff -Nru catch2-2.12.1/docs/command-line.md catch2-2.13.0/docs/command-line.md --- catch2-2.12.1/docs/command-line.md 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/docs/command-line.md 2020-07-12 18:28:38.000000000 +0000 @@ -222,6 +222,16 @@ When set to ```yes``` Catch will report the duration of each test case, in milliseconds. Note that it does this regardless of whether a test case passes or fails. Note, also, the certain reporters (e.g. Junit) always report test case durations regardless of this option being set or not. +
-D, --min-duration <value>
+ +> `--min-duration` was [introduced](https://github.com/catchorg/Catch2/pull/1910) in Catch 2.13.0 + +When set, Catch will report the duration of each test case that took more +than <value> seconds, in milliseconds. This option is overriden by both +`-d yes` and `-d no`, so that either all durations are reported, or none +are. + + ## Load test names to run from a file
-f, --input-file <filename>
diff -Nru catch2-2.12.1/docs/contributing.md catch2-2.13.0/docs/contributing.md --- catch2-2.12.1/docs/contributing.md 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/docs/contributing.md 2020-07-12 18:28:38.000000000 +0000 @@ -1,117 +1,119 @@ -# Contributing to Catch +# Contributing to Catch2 **Contents**
-[Branches](#branches)
-[Directory structure](#directory-structure)
+[Using Git(Hub)](#using-github)
[Testing your changes](#testing-your-changes)
-[Documenting your code](#documenting-your-code)
-[Code constructs to watch out for](#code-constructs-to-watch-out-for)
+[Writing documentation](#writing-documentation)
+[Writing code](#writing-code)
+[CoC](#coc)
+ +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 `master` branch for Catch2 v2, and in +`dev-v3` for the next major version, v3. + +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 prefered, 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 +single include. 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. -So you want to contribute something to Catch? 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 and other comments and questions. -If you are contributing to the code base there are a few simple guidelines to keep in mind. This also includes notes to -help you find your way around. As this is liable to drift out of date please raise an issue or, better still, a pull -request for this file, if you notice that. -## Branches - -Ongoing development is currently on _master_. At some point an integration branch will be set-up and PRs should target - that - but for now it's all against master. You may see feature branches come and go from time to time, too. - -## Directory structure - -_Users_ of Catch primarily use the single header version. _Maintainers_ should work with the full source (which is still, -primarily, in headers). This can be found in the `include` folder. There are a set of test files, currently under -`projects/SelfTest`. The test app can be built via CMake from the `CMakeLists.txt` file in the root, or you can generate -project files for Visual Studio, XCode, and others (instructions in the `projects` folder). If you have access to CLion, -it can work with the CMake file directly. - -As well as the runtime test files you'll also see a `SurrogateCpps` directory under `projects/SelfTest`. -This contains a set of .cpp files that each `#include` a single header. -While these files are not essential to compilation they help to keep the implementation headers self-contained. -At time of writing this set is not complete but has reasonable coverage. -If you add additional headers please try to remember to add a surrogate cpp for it. - -The other directories are `scripts` which contains a set of python scripts to help in testing Catch as well as -generating the single include, and `docs`, which contains the documentation as a set of markdown files. - -__When submitting a pull request please do not include changes to the single include, or to the version number file -as these are managed by the scripts!__ +## Testing your changes +_Note: Running Catch2's tests requires Python3_ -## Testing your changes -Obviously all changes to Catch's code should be tested. If you added new -functionality, you should add tests covering and showcasing it. Even if you have -only made changes to Catch internals (i.e. you implemented some performance -improvements), you should still test your changes. +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. + +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. + +There are also two more kinds of tests, examples and "ExtraTests". +Examples serve as a compilation test on the single-header distribution, +and present a small and self-contained snippets of using Catch2 for +writing tests. ExtraTests then are tests that either take a long time +to run, or require separate compilation, e.g. because of testing compile +time configuration options, and take a long time because of that. + +Both of these are compiled against the single-header distribution of +Catch2, and thus might require you to regenerate it manually. This is +done by calling the `generateSingleHeader.py` script in `scripts`. + +Examples and ExtraTests are not compiled by default. To compile them, +add `-DCATCH_BUILD_EXAMPLES=ON` and `-DCATCH_BUILD_EXTRA_TESTS=ON` to +the invocation of CMake configuration step. -This means 2 things +Bringing this all together, the steps below should configure, build, +and run all tests in the `Debug` compilation. -* Compiling Catch's SelfTest project: +1. Regenerate the single header distribution ``` $ cd Catch2 -$ cmake -Bdebug-build -H. -DCMAKE_BUILD_TYPE=Debug +$ ./scripts/generateSingleHeader.py +``` +2. Configure the full test build +``` +$ cmake -Bdebug-build -H. -DCMAKE_BUILD_TYPE=Debug -DCATCH_BUILD_EXAMPLES=ON -DCATCH_BUILD_EXTRA_TESTS=ON +``` +3. Run the actual build +``` $ cmake --build debug-build ``` -because code that does not compile is evidently incorrect. Obviously, -you are not expected to have access to all the compilers and platforms -supported by Catch2, but you should at least smoke test your changes -on your platform. Our CI pipeline will check your PR against most of -the supported platforms, but it takes an hour to finish -- compiling -locally takes just a few minutes. - - -* Running the tests via CTest: +4. Run the tests using CTest ``` $ cd debug-build -$ ctest -j 2 --output-on-failure +$ ctest -j 4 --output-on-failure -C Debug ``` -__Note:__ When running your tests with multi-configuration generators like -Visual Studio, you might get errors "Test not available without configuration." -You then have to pick one configuration (e.g. ` -C Debug`) in the `ctest` call. - -If you added new tests, approval tests are very likely to fail. If they -do not, it means that your changes weren't run as part of them. This -_might_ be intentional, but usually is not. -The approval tests compare current output of the SelfTest binary in various -configurations against known good outputs. The reason it fails is, -_usually_, that you've added new tests but have not yet approved the changes -they introduce. This is done with the `scripts/approve.py` script, but -before you do so, you need to check that the introduced changes are indeed -intentional. - -## Documenting your code +## 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: -* 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 Catch X.Y.Z` - this - placeholder is usually used after a section heading - * `> X (Y and Z) was [introduced](link-to-issue-or-PR) in Catch X.Y.Z` - - this placeholder is used when you need to tag a subpart of something, - e.g. list -* Crosslinks to different pages should target the `top` anchor, like this -`[link to contributing](contributing.md#top)`. * If you have introduced a new document, there is a simple template you -should use. It provides you with the top anchor mentioned above, and also -with a backlink to the top of the documentation: +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 # Cool feature @@ -123,6 +125,23 @@ [Home](Readme.md#top) ``` + +* 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 Catch X.Y.Z` - this + placeholder is usually used after a section heading + * `> X (Y and Z) was [introduced](link-to-issue-or-PR) in Catch 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, @@ -130,21 +149,54 @@ ToC. This can be done either manually, or by running the `updateDocumentToC.py` script in the `scripts/` folder. +### Contents + +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. -Now, for the generic tips: - * Usage examples are good - * Don't be afraid to introduce new pages - * Try to be reasonably consistent with the surrounding documentation +## 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. -## Code constructs to watch out for +### 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. + + +### 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 + +#### Naked exceptions and exceptions-related function If you are throwing an exception, it should be done via `CATCH_ERROR` or `CATCH_RUNTIME_ERROR` in `catch_enforce.h`. These macros will handle @@ -155,7 +207,8 @@ However, if you do, they should be kept behind a `CATCH_CONFIG_DISABLE_EXCEPTIONS` macro. -### Unqualified usage of functions from C's stdlib + +#### Unqualified usage of functions from C's stdlib If you are using a function from C's stdlib, please include the header as `` and call the function qualified. The common knowledge that @@ -163,7 +216,12 @@ include the header as `` and call the function unqualified. ----- +## CoC + +This project has a [CoC](../CODE_OF_CONDUCT.md). Please adhere to it +while contributing to Catch2. + +----------- _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._ diff -Nru catch2-2.12.1/docs/generators.md catch2-2.13.0/docs/generators.md --- catch2-2.12.1/docs/generators.md 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/docs/generators.md 2020-07-12 18:28:38.000000000 +0000 @@ -12,23 +12,88 @@ This is best explained with an example: ```cpp TEST_CASE("Generators") { - auto i = GENERATE(1, 2, 3); - SECTION("one") { - auto j = GENERATE( -3, -2, -1 ); - REQUIRE(j < i); - } + auto i = GENERATE(1, 3, 5); + REQUIRE(is_odd(i)); } ``` -The assertion in this test case will be run 9 times, because there -are 3 possible values for `i` (1, 2, and 3) and there are 3 possible -values for `j` (-3, -2, and -1). +The "Generators" `TEST_CASE` will be entered 3 times, and the value of +`i` will be 1, 3, and 5 in turn. `GENERATE`s can also be used multiple +times at the same scope, in which case the result will be a cartesian +product of all elements in the generators. This means that in the snippet +below, the test case will be run 6 (2\*3) times. +```cpp +TEST_CASE("Generators") { + auto i = GENERATE(1, 2); + auto j = GENERATE(3, 4, 5); +} +``` There are 2 parts to generators in Catch2, the `GENERATE` macro together with the already provided generators, and the `IGenerator` interface that allows users to implement their own generators. + +## Combining `GENERATE` and `SECTION`. + +`GENERATE` can be seen as an implicit `SECTION`, that goes from the place +`GENERATE` is used, to the end of the scope. This can be used for various +effects. The simplest usage is shown below, where the `SECTION` "one" +runs 4 (2\*2) times, and `SECTION` "two" is run 6 times (2\*3). + +``` +TEST_CASE("Generators") { + auto i = GENERATE(1, 2); + SECTION("one") { + auto j = GENERATE(-3, -2); + REQUIRE(j < i); + } + SECTION("two") { + auto k = GENERATE(4, 5, 6); + REQUIRE(j != k); + } +} +``` + +The specific order of the `SECTION`s will be "one", "one", "two", "two", +"two", "one"... + + +The fact that `GENERATE` introduces a virtual `SECTION` can als obe used +to make a generator replay only some `SECTION`s, without having to +explicitly add a `SECTION`. As an example, the code below reports 3 +assertions, because the "first" section is run once, but the "second" +section is run twice. + +```cpp +TEST_CASE("GENERATE between SECTIONs") { + SECTION("first") { REQUIRE(true); } + auto _ = GENERATE(1, 2); + SECTION("second") { REQUIRE(true); } +} +``` + +This can lead to surprisingly complex test flows. As an example, the test +below will report 14 assertions: + +```cpp +TEST_CASE("Complex mix of sections and generates") { + auto i = GENERATE(1, 2); + SECTION("A") { + SUCCEED("A"); + } + auto j = GENERATE(3, 4); + SECTION("B") { + SUCCEED("B"); + } + auto k = GENERATE(5, 6); + SUCCEED(); +} +``` + +> The ability to place `GENERATE` between two `SECTION`s was [introduced](https://github.com/catchorg/Catch2/issues/1938) in Catch 2.13.0. + ## Provided generators Catch2's provided generator functionality consists of three parts, diff -Nru catch2-2.12.1/docs/list-of-examples.md catch2-2.13.0/docs/list-of-examples.md --- catch2-2.12.1/docs/list-of-examples.md 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/docs/list-of-examples.md 2020-07-12 18:28:38.000000000 +0000 @@ -16,6 +16,7 @@ - Configuration: [Provide your own output streams](../examples/231-Cfg-OutputStreams.cpp) - Generators: [Create your own generator](../examples/300-Gen-OwnGenerator.cpp) - Generators: [Use map to convert types in GENERATE expression](../examples/301-Gen-MapTypeConversion.cpp) +- Generators: [Run test with a table of input values](../examples/302-Gen-Table.cpp) - Generators: [Use variables in generator expressions](../examples/310-Gen-VariablesInGenerators.cpp) - Generators: [Use custom variable capture in generator expressions](../examples/311-Gen-CustomCapture.cpp) diff -Nru catch2-2.12.1/docs/own-main.md catch2-2.13.0/docs/own-main.md --- catch2-2.12.1/docs/own-main.md 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/docs/own-main.md 2020-07-12 18:28:38.000000000 +0000 @@ -11,9 +11,9 @@ This is achieved by writing ```#define CATCH_CONFIG_MAIN``` before the ```#include "catch.hpp"``` in *exactly one* source file. -Sometimes, though, you need to write your own version of main(). You can do this by writing ```#define CATCH_CONFIG_RUNNER``` instead. Now you are free to write ```main()``` as normal and call into Catch yourself manually. +Sometimes, though, you need to write your own version of main(). You can do this by writing ```#define CATCH_CONFIG_RUNNER``` instead. Now you are free to write ```main()``` as normal and call into Catch yourself manually. You now have a lot of flexibility - but here are three recipes to get your started: -You now have a lot of flexibility - but here are three recipes to get your started: +**Important note: you can only provide `main` in the same file you defined `CATCH_CONFIG_RUNNER`.** ## Let Catch take full control of args and config diff -Nru catch2-2.12.1/docs/release-notes.md catch2-2.13.0/docs/release-notes.md --- catch2-2.12.1/docs/release-notes.md 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/docs/release-notes.md 2020-07-12 18:28:38.000000000 +0000 @@ -2,6 +2,10 @@ # Release notes **Contents**
+[2.13.0](#2130)
+[2.12.4](#2124)
+[2.12.3](#2123)
+[2.12.2](#2122)
[2.12.1](#2121)
[2.12.0](#2120)
[2.11.3](#2113)
@@ -36,6 +40,58 @@ [Older versions](#older-versions)
[Even Older versions](#even-older-versions)
+## 2.13.0 + +### Improvements +* `GENERATE` can now follow a `SECTION` at the same level of nesting (#1938) + * The `SECTION`(s) before the `GENERATE` will not be run multiple times, the following ones will. +* Added `-D`/`--min-duration` command line flag (#1910) + * If a test takes longer to finish than the provided value, its name and duration will be printed. + * This flag is overriden by setting `-d`/`--duration`. + +### Fixes +* `TAPReporter` no longer skips successful assertions (#1983) + + +## 2.12.4 + +### Improvements +* Added support for MacOS on ARM (#1971) + + +## 2.12.3 + +### Fixes +* `GENERATE` nested in a for loop no longer creates multiple generators (#1913) +* Fixed copy paste error breaking `TEMPLATE_TEST_CASE_SIG` for 6 or more arguments (#1954) +* Fixed potential UB when handling non-ASCII characters in CLI args (#1943) + +### Improvements +* There can be multiple calls to `GENERATE` on a single line +* Improved `fno-except` support for platforms that do not provide shims for exception-related std functions (#1950) + * E.g. the Green Hills C++ compiler +* XmlReporter now also reports test-case-level statistics (#1958) + * This is done via a new element, `OverallResultsCases` + +### Miscellaneous +* Added `.clang-format` file to the repo (#1182, #1920) +* Rewrote contributing docs + * They should explain the different levels of testing and so on much better + + +## 2.12.2 + +### Fixes +* Fixed compilation failure if `is_range` ADL found deleted function (#1929) +* Fixed potential UB in `CAPTURE` if the expression contained non-ASCII characters (#1925) + +### Improvements +* `std::result_of` is not used if `std::invoke_result` is available (#1934) +* JUnit reporter writes out `status` attribute for tests (#1899) +* Suppresed clang-tidy's `hicpp-vararg` warning (#1921) + * Catch2 was already suppressing the `cppcoreguidelines-pro-type-vararg` alias of the warning + + ## 2.12.1 ### Fixes diff -Nru catch2-2.12.1/examples/301-Gen-MapTypeConversion.cpp catch2-2.13.0/examples/301-Gen-MapTypeConversion.cpp --- catch2-2.12.1/examples/301-Gen-MapTypeConversion.cpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/examples/301-Gen-MapTypeConversion.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -1,7 +1,9 @@ // 301-Gen-MapTypeConversion.cpp // Shows how to use map to modify generator's return type. -// TODO +// Specifically we wrap a std::string returning generator with a generator +// that converts the strings using stoi, so the returned type is actually +// an int. #include diff -Nru catch2-2.12.1/examples/302-Gen-Table.cpp catch2-2.13.0/examples/302-Gen-Table.cpp --- catch2-2.12.1/examples/302-Gen-Table.cpp 1970-01-01 00:00:00.000000000 +0000 +++ catch2-2.13.0/examples/302-Gen-Table.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -0,0 +1,54 @@ +// 302-Gen-Table.cpp +// Shows how to use table to run a test many times with different inputs. Lifted from examples on +// issue #850. + +#include +#include + +struct TestSubject { + // this is the method we are going to test. It returns the length of the + // input string. + size_t GetLength( const std::string& input ) const { return input.size(); } +}; + + +TEST_CASE("Table allows pre-computed test inputs and outputs", "[example][generator]") { + using std::make_tuple; + // do setup here as normal + TestSubject subj; + + SECTION("This section is run for each row in the table") { + std::string test_input; + size_t expected_output; + std::tie( test_input, expected_output ) = + GENERATE( table( + { /* In this case one of the parameters to our test case is the + * expected output, but this is not required. There could be + * multiple expected values in the table, which can have any + * (fixed) number of columns. + */ + make_tuple( "one", 3 ), + make_tuple( "two", 3 ), + make_tuple( "three", 5 ), + make_tuple( "four", 4 ) } ) ); + + // run the test + auto result = subj.GetLength(test_input); + // capture the input data to go with the outputs. + CAPTURE(test_input); + // check it matches the pre-calculated data + REQUIRE(result == expected_output); + } // end section +} + +/* Possible simplifications where less legacy toolchain support is needed: + * + * - With libstdc++6 or newer, the make_tuple() calls can be ommitted + * (technically C++17 but does not require -std in GCC/Clang). See + * https://stackoverflow.com/questions/12436586/tuple-vector-and-initializer-list + * + * - In C++17 mode std::tie() and the preceeding variable delcarations can be + * replaced by structured bindings: auto [test_input, expected] = GENERATE( + * table({ ... + */ +// Compiling and running this file will result in 4 successful assertions diff -Nru catch2-2.12.1/examples/311-Gen-CustomCapture.cpp catch2-2.13.0/examples/311-Gen-CustomCapture.cpp --- catch2-2.12.1/examples/311-Gen-CustomCapture.cpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/examples/311-Gen-CustomCapture.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -23,11 +23,11 @@ })); auto r2(r1); - + // This will take r1 by reference and r2 by value. // Note that there are no advantages for doing so in this example, // it is done only for expository purposes. - auto number = Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, + auto number = Catch::Generators::generate( "custom capture generator", CATCH_INTERNAL_LINEINFO, [&r1, r2]{ using namespace Catch::Generators; return makeGenerators(take(50, random(std::get<0>(r1), std::get<1>(r2)))); diff -Nru catch2-2.12.1/examples/CMakeLists.txt catch2-2.13.0/examples/CMakeLists.txt --- catch2-2.12.1/examples/CMakeLists.txt 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/examples/CMakeLists.txt 2020-07-12 18:28:38.000000000 +0000 @@ -46,6 +46,7 @@ 210-Evt-EventListeners.cpp 300-Gen-OwnGenerator.cpp 301-Gen-MapTypeConversion.cpp + 302-Gen-Table.cpp 310-Gen-VariablesInGenerators.cpp 311-Gen-CustomCapture.cpp ) diff -Nru catch2-2.12.1/.github/FUNDING.yml catch2-2.13.0/.github/FUNDING.yml --- catch2-2.12.1/.github/FUNDING.yml 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/.github/FUNDING.yml 2020-07-12 18:28:38.000000000 +0000 @@ -1 +1 @@ -patreon: horenmar +custom: "https://www.paypal.me/horenmar" diff -Nru catch2-2.12.1/.gitignore catch2-2.13.0/.gitignore --- catch2-2.12.1/.gitignore 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/.gitignore 2020-07-12 18:28:38.000000000 +0000 @@ -28,3 +28,4 @@ cmake-build-* benchmark-dir .conan/test_package/build +bazel-* diff -Nru catch2-2.12.1/include/catch.hpp catch2-2.13.0/include/catch.hpp --- catch2-2.12.1/include/catch.hpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/catch.hpp 2020-07-12 18:28:38.000000000 +0000 @@ -10,8 +10,8 @@ #define TWOBLUECUBES_CATCH_HPP_INCLUDED #define CATCH_VERSION_MAJOR 2 -#define CATCH_VERSION_MINOR 12 -#define CATCH_VERSION_PATCH 1 +#define CATCH_VERSION_MINOR 13 +#define CATCH_VERSION_PATCH 0 #ifdef __clang__ # pragma clang system_header diff -Nru catch2-2.12.1/include/external/clara.hpp catch2-2.13.0/include/external/clara.hpp --- catch2-2.12.1/include/external/clara.hpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/external/clara.hpp 2020-07-12 18:28:38.000000000 +0000 @@ -667,7 +667,7 @@ } inline auto convertInto( std::string const &source, bool &target ) -> ParserResult { std::string srcLC = source; - std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast( std::tolower(c) ); } ); + std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( unsigned char c ) { return static_cast( std::tolower(c) ); } ); if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on") target = true; else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off") diff -Nru catch2-2.12.1/include/internal/benchmark/detail/catch_complete_invoke.hpp catch2-2.13.0/include/internal/benchmark/detail/catch_complete_invoke.hpp --- catch2-2.12.1/include/internal/benchmark/detail/catch_complete_invoke.hpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/benchmark/detail/catch_complete_invoke.hpp 2020-07-12 18:28:38.000000000 +0000 @@ -12,6 +12,7 @@ #define TWOBLUECUBES_CATCH_DETAIL_COMPLETE_INVOKE_HPP_INCLUDED #include "../../catch_enforce.h" +#include "../../catch_meta.hpp" #include #include @@ -42,20 +43,18 @@ return {}; } }; - template - using ResultOf_t = typename std::result_of::type; // invoke and not return void :( template - CompleteType_t> complete_invoke(Fun&& fun, Args&&... args) { - return CompleteInvoker>::invoke(std::forward(fun), std::forward(args)...); + CompleteType_t> complete_invoke(Fun&& fun, Args&&... args) { + return CompleteInvoker>::invoke(std::forward(fun), std::forward(args)...); } const std::string benchmarkErrorMsg = "a benchmark failed to run successfully"; } // namespace Detail template - Detail::CompleteType_t> user_code(Fun&& fun) { + Detail::CompleteType_t> user_code(Fun&& fun) { CATCH_TRY{ return Detail::complete_invoke(std::forward(fun)); } CATCH_CATCH_ALL{ diff -Nru catch2-2.12.1/include/internal/benchmark/detail/catch_measure.hpp catch2-2.13.0/include/internal/benchmark/detail/catch_measure.hpp --- catch2-2.12.1/include/internal/benchmark/detail/catch_measure.hpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/benchmark/detail/catch_measure.hpp 2020-07-12 18:28:38.000000000 +0000 @@ -21,7 +21,7 @@ namespace Benchmark { namespace Detail { template - TimingOf measure(Fun&& fun, Args&&... args) { + TimingOf measure(Fun&& fun, Args&&... args) { auto start = Clock::now(); auto&& r = Detail::complete_invoke(fun, std::forward(args)...); auto end = Clock::now(); diff -Nru catch2-2.12.1/include/internal/benchmark/detail/catch_run_for_at_least.hpp catch2-2.13.0/include/internal/benchmark/detail/catch_run_for_at_least.hpp --- catch2-2.12.1/include/internal/benchmark/detail/catch_run_for_at_least.hpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/benchmark/detail/catch_run_for_at_least.hpp 2020-07-12 18:28:38.000000000 +0000 @@ -25,11 +25,11 @@ namespace Benchmark { namespace Detail { template - TimingOf measure_one(Fun&& fun, int iters, std::false_type) { + TimingOf measure_one(Fun&& fun, int iters, std::false_type) { return Detail::measure(fun, iters); } template - TimingOf measure_one(Fun&& fun, int iters, std::true_type) { + TimingOf measure_one(Fun&& fun, int iters, std::true_type) { Detail::ChronometerModel meter; auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters)); @@ -46,7 +46,7 @@ }; template - TimingOf)> run_for_at_least(ClockDuration how_long, int seed, Fun&& fun) { + TimingOf> run_for_at_least(ClockDuration how_long, int seed, Fun&& fun) { auto iters = seed; while (iters < (1 << 30)) { auto&& Timing = measure_one(fun, iters, is_callable()); diff -Nru catch2-2.12.1/include/internal/benchmark/detail/catch_timing.hpp catch2-2.13.0/include/internal/benchmark/detail/catch_timing.hpp --- catch2-2.12.1/include/internal/benchmark/detail/catch_timing.hpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/benchmark/detail/catch_timing.hpp 2020-07-12 18:28:38.000000000 +0000 @@ -25,8 +25,8 @@ Result result; int iterations; }; - template - using TimingOf = Timing, Detail::CompleteType_t>>; + template + using TimingOf = Timing, Detail::CompleteType_t>>; } // namespace Benchmark } // namespace Catch diff -Nru catch2-2.12.1/include/internal/catch_commandline.cpp catch2-2.13.0/include/internal/catch_commandline.cpp --- catch2-2.12.1/include/internal/catch_commandline.cpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_commandline.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -170,6 +170,9 @@ | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" ) ["-d"]["--durations"] ( "show test durations" ) + | Opt( config.minDuration, "seconds" ) + ["-D"]["--min-duration"] + ( "show test durations for tests taking at least the given number of seconds" ) | Opt( loadTestNamesFromFile, "filename" ) ["-f"]["--input-file"] ( "load test names to run from a file" ) diff -Nru catch2-2.12.1/include/internal/catch_compiler_capabilities.h catch2-2.13.0/include/internal/catch_compiler_capabilities.h --- catch2-2.12.1/include/internal/catch_compiler_capabilities.h 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_compiler_capabilities.h 2020-07-12 18:28:38.000000000 +0000 @@ -70,7 +70,7 @@ // // Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. # if !defined(__ibmxl__) -# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg) */ +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ # endif diff -Nru catch2-2.12.1/include/internal/catch_config.cpp catch2-2.13.0/include/internal/catch_config.cpp --- catch2-2.12.1/include/internal/catch_config.cpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_config.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -64,6 +64,7 @@ bool Config::warnAboutMissingAssertions() const { return !!(m_data.warnings & WarnAbout::NoAssertions); } bool Config::warnAboutNoTests() const { return !!(m_data.warnings & WarnAbout::NoTests); } ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; } + double Config::minDuration() const { return m_data.minDuration; } RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; } unsigned int Config::rngSeed() const { return m_data.rngSeed; } UseColour::YesOrNo Config::useColour() const { return m_data.useColour; } diff -Nru catch2-2.12.1/include/internal/catch_config.hpp catch2-2.13.0/include/internal/catch_config.hpp --- catch2-2.12.1/include/internal/catch_config.hpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_config.hpp 2020-07-12 18:28:38.000000000 +0000 @@ -52,6 +52,7 @@ Verbosity verbosity = Verbosity::Normal; WarnAbout::What warnings = WarnAbout::Nothing; ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter; + double minDuration = -1; RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder; UseColour::YesOrNo useColour = UseColour::Auto; WaitForKeypress::When waitForKeypress = WaitForKeypress::Never; @@ -103,6 +104,7 @@ bool warnAboutMissingAssertions() const override; bool warnAboutNoTests() const override; ShowDurations::OrNot showDurations() const override; + double minDuration() const override; RunTests::InWhatOrder runOrder() const override; unsigned int rngSeed() const override; UseColour::YesOrNo useColour() const override; diff -Nru catch2-2.12.1/include/internal/catch_debugger.h catch2-2.13.0/include/internal/catch_debugger.h --- catch2-2.12.1/include/internal/catch_debugger.h 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_debugger.h 2020-07-12 18:28:38.000000000 +0000 @@ -17,7 +17,11 @@ #ifdef CATCH_PLATFORM_MAC - #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */ + #if defined(__i386__) || defined(__x86_64__) + #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */ + #elif defined(__aarch64__) + #define CATCH_TRAP() __asm__(".inst 0xd4200000") + #endif #elif defined(CATCH_PLATFORM_IPHONE) diff -Nru catch2-2.12.1/include/internal/catch_generators.cpp catch2-2.13.0/include/internal/catch_generators.cpp --- catch2-2.12.1/include/internal/catch_generators.cpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_generators.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -24,8 +24,8 @@ GeneratorUntypedBase::~GeneratorUntypedBase() {} - auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& { - return getResultCapture().acquireGeneratorTracker( lineInfo ); + auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& { + return getResultCapture().acquireGeneratorTracker( generatorName, lineInfo ); } } // namespace Generators diff -Nru catch2-2.12.1/include/internal/catch_generators.hpp catch2-2.13.0/include/internal/catch_generators.hpp --- catch2-2.12.1/include/internal/catch_generators.hpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_generators.hpp 2020-07-12 18:28:38.000000000 +0000 @@ -10,6 +10,7 @@ #include "catch_interfaces_generatortracker.h" #include "catch_common.h" #include "catch_enforce.h" +#include "catch_stringref.h" #include #include @@ -181,16 +182,16 @@ return makeGenerators( value( T( std::forward( val ) ) ), std::forward( moreGenerators )... ); } - auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&; + auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker&; template // Note: The type after -> is weird, because VS2015 cannot parse // the expression used in the typedef inside, when it is in // return type. Yeah. - auto generate( SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval().get()) { + auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval().get()) { using UnderlyingType = typename decltype(generatorExpression())::type; - IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo ); + IGeneratorTracker& tracker = acquireGeneratorTracker( generatorName, lineInfo ); if (!tracker.hasGenerator()) { tracker.setGenerator(pf::make_unique>(generatorExpression())); } @@ -203,10 +204,16 @@ } // namespace Catch #define GENERATE( ... ) \ - Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) + Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \ + CATCH_INTERNAL_LINEINFO, \ + [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) #define GENERATE_COPY( ... ) \ - Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) + Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \ + CATCH_INTERNAL_LINEINFO, \ + [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) #define GENERATE_REF( ... ) \ - Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) + Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \ + CATCH_INTERNAL_LINEINFO, \ + [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) #endif // TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED diff -Nru catch2-2.12.1/include/internal/catch_interfaces_capture.h catch2-2.13.0/include/internal/catch_interfaces_capture.h --- catch2-2.12.1/include/internal/catch_interfaces_capture.h 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_interfaces_capture.h 2020-07-12 18:28:38.000000000 +0000 @@ -44,7 +44,7 @@ virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0; virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0; - virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0; + virtual auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0; #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) virtual void benchmarkPreparing( std::string const& name ) = 0; diff -Nru catch2-2.12.1/include/internal/catch_interfaces_config.h catch2-2.13.0/include/internal/catch_interfaces_config.h --- catch2-2.12.1/include/internal/catch_interfaces_config.h 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_interfaces_config.h 2020-07-12 18:28:38.000000000 +0000 @@ -69,6 +69,7 @@ virtual int abortAfter() const = 0; virtual bool showInvisibles() const = 0; virtual ShowDurations::OrNot showDurations() const = 0; + virtual double minDuration() const = 0; virtual TestSpec const& testSpec() const = 0; virtual bool hasTestFilters() const = 0; virtual std::vector const& getTestsOrTags() const = 0; diff -Nru catch2-2.12.1/include/internal/catch_matchers_vector.h catch2-2.13.0/include/internal/catch_matchers_vector.h --- catch2-2.12.1/include/internal/catch_matchers_vector.h 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_matchers_vector.h 2020-07-12 18:28:38.000000000 +0000 @@ -131,8 +131,6 @@ struct UnorderedEqualsMatcher : MatcherBase> { UnorderedEqualsMatcher(std::vector const& target) : m_target(target) {} bool match(std::vector const& vec) const override { - // Note: This is a reimplementation of std::is_permutation, - // because I don't want to include inside the common path if (m_target.size() != vec.size()) { return false; } diff -Nru catch2-2.12.1/include/internal/catch_message.cpp catch2-2.13.0/include/internal/catch_message.cpp --- catch2-2.12.1/include/internal/catch_message.cpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_message.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -69,10 +69,10 @@ Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) { auto trimmed = [&] (size_t start, size_t end) { - while (names[start] == ',' || isspace(names[start])) { + while (names[start] == ',' || isspace(static_cast(names[start]))) { ++start; } - while (names[end] == ',' || isspace(names[end])) { + while (names[end] == ',' || isspace(static_cast(names[end]))) { --end; } return names.substr(start, end - start + 1); diff -Nru catch2-2.12.1/include/internal/catch_meta.hpp catch2-2.13.0/include/internal/catch_meta.hpp --- catch2-2.12.1/include/internal/catch_meta.hpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_meta.hpp 2020-07-12 18:28:38.000000000 +0000 @@ -32,13 +32,13 @@ #if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703 // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is - // replaced with std::invoke_result here. Also *_t format is preferred over - // typename *::type format. - template - using FunctionReturnType = std::remove_reference_t>>; + // replaced with std::invoke_result here. + template + using FunctionReturnType = std::remove_reference_t>>; #else - template - using FunctionReturnType = typename std::remove_reference::type>::type>::type; + // Keep ::type here because we still support C++11 + template + using FunctionReturnType = typename std::remove_reference::type>::type>::type; #endif } // namespace Catch diff -Nru catch2-2.12.1/include/internal/catch_preprocessor.hpp catch2-2.13.0/include/internal/catch_preprocessor.hpp --- catch2-2.12.1/include/internal/catch_preprocessor.hpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_preprocessor.hpp 2020-07-12 18:28:38.000000000 +0000 @@ -1,3 +1,4 @@ + /* * Created by Jozef on 12/11/2018. * Copyright 2017 Two Blue Cubes Ltd. All rights reserved. @@ -90,7 +91,7 @@ #define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3) #define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4) #define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5) -#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _4, _5, _6) +#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6) #define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7) #define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8) #define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9) diff -Nru catch2-2.12.1/include/internal/catch_registry_hub.cpp catch2-2.13.0/include/internal/catch_registry_hub.cpp --- catch2-2.12.1/include/internal/catch_registry_hub.cpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_registry_hub.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -59,7 +59,11 @@ m_tagAliasRegistry.add( alias, tag, lineInfo ); } void registerStartupException() noexcept override { +#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) m_exceptionRegistry.add(std::current_exception()); +#else + CATCH_INTERNAL_ERROR("Attempted to register active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!"); +#endif } IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override { return m_enumValuesRegistry; diff -Nru catch2-2.12.1/include/internal/catch_run_context.cpp catch2-2.13.0/include/internal/catch_run_context.cpp --- catch2-2.12.1/include/internal/catch_run_context.cpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_run_context.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -25,17 +25,32 @@ std::shared_ptr tracker; ITracker& currentTracker = ctx.currentTracker(); - if( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) { + // Under specific circumstances, the generator we want + // to acquire is also the current tracker. If this is + // the case, we have to avoid looking through current + // tracker's children, and instead return the current + // tracker. + // A case where this check is important is e.g. + // for (int i = 0; i < 5; ++i) { + // int n = GENERATE(1, 2); + // } + // + // without it, the code above creates 5 nested generators. + if (currentTracker.nameAndLocation() == nameAndLocation) { + auto thisTracker = currentTracker.parent().findChild(nameAndLocation); + assert(thisTracker); + assert(thisTracker->isGeneratorTracker()); + tracker = std::static_pointer_cast(thisTracker); + } else if ( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) { assert( childTracker ); assert( childTracker->isGeneratorTracker() ); tracker = std::static_pointer_cast( childTracker ); - } - else { + } else { tracker = std::make_shared( nameAndLocation, ctx, ¤tTracker ); currentTracker.addChild( tracker ); } - if( !ctx.completedCycle() && !tracker->isComplete() ) { + if( !tracker->isComplete() ) { tracker->open(); } @@ -49,8 +64,28 @@ } void close() override { TrackerBase::close(); - // Generator interface only finds out if it has another item on atual move - if (m_runState == CompletedSuccessfully && m_generator->next()) { + // If a generator has a child (it is followed by a section) + // and none of its children have started, then we must wait + // until later to start consuming its values. + // This catches cases where `GENERATE` is placed between two + // `SECTION`s. + // **The check for m_children.empty cannot be removed**. + // doing so would break `GENERATE` _not_ followed by `SECTION`s. + const bool should_wait_for_child = + !m_children.empty() && + std::find_if( m_children.begin(), + m_children.end(), + []( TestCaseTracking::ITrackerPtr tracker ) { + return tracker->hasStarted(); + } ) == m_children.end(); + + // This check is a bit tricky, because m_generator->next() + // has a side-effect, where it consumes generator's current + // value, but we do not want to invoke the side-effect if + // this generator is still waiting for any child to start. + if ( should_wait_for_child || + ( m_runState == CompletedSuccessfully && + m_generator->next() ) ) { m_children.clear(); m_runState = Executing; } @@ -187,10 +222,10 @@ return true; } - auto RunContext::acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& { + auto RunContext::acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& { using namespace Generators; - GeneratorTracker& tracker = GeneratorTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( "generator", lineInfo ) ); - assert( tracker.isOpen() ); + GeneratorTracker& tracker = GeneratorTracker::acquire(m_trackerContext, + TestCaseTracking::NameAndLocation( static_cast(generatorName), lineInfo ) ); m_lastAssertionInfo.lineInfo = lineInfo; return tracker; } @@ -233,17 +268,17 @@ #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) void RunContext::benchmarkPreparing(std::string const& name) { - m_reporter->benchmarkPreparing(name); - } + m_reporter->benchmarkPreparing(name); + } void RunContext::benchmarkStarting( BenchmarkInfo const& info ) { m_reporter->benchmarkStarting( info ); } void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) { m_reporter->benchmarkEnded( stats ); } - void RunContext::benchmarkFailed(std::string const & error) { - m_reporter->benchmarkFailed(error); - } + void RunContext::benchmarkFailed(std::string const & error) { + m_reporter->benchmarkFailed(error); + } #endif // CATCH_CONFIG_ENABLE_BENCHMARKING void RunContext::pushScopedMessage(MessageInfo const & message) { diff -Nru catch2-2.12.1/include/internal/catch_run_context.h catch2-2.13.0/include/internal/catch_run_context.h --- catch2-2.12.1/include/internal/catch_run_context.h 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_run_context.h 2020-07-12 18:28:38.000000000 +0000 @@ -80,7 +80,7 @@ void sectionEnded( SectionEndInfo const& endInfo ) override; void sectionEndedEarly( SectionEndInfo const& endInfo ) override; - auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override; + auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override; #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) void benchmarkPreparing( std::string const& name ) override; diff -Nru catch2-2.12.1/include/internal/catch_startup_exception_registry.cpp catch2-2.13.0/include/internal/catch_startup_exception_registry.cpp --- catch2-2.12.1/include/internal/catch_startup_exception_registry.cpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_startup_exception_registry.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -9,6 +9,7 @@ #include "catch_startup_exception_registry.h" #include "catch_compiler_capabilities.h" +#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) namespace Catch { void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept { CATCH_TRY { @@ -24,3 +25,4 @@ } } // end namespace Catch +#endif diff -Nru catch2-2.12.1/include/internal/catch_startup_exception_registry.h catch2-2.13.0/include/internal/catch_startup_exception_registry.h --- catch2-2.12.1/include/internal/catch_startup_exception_registry.h 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_startup_exception_registry.h 2020-07-12 18:28:38.000000000 +0000 @@ -15,11 +15,13 @@ namespace Catch { class StartupExceptionRegistry { +#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) public: void add(std::exception_ptr const& exception) noexcept; std::vector const& getExceptions() const noexcept; private: std::vector m_exceptions; +#endif }; } // end namespace Catch diff -Nru catch2-2.12.1/include/internal/catch_string_manip.cpp catch2-2.13.0/include/internal/catch_string_manip.cpp --- catch2-2.12.1/include/internal/catch_string_manip.cpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_string_manip.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -18,7 +18,7 @@ namespace { char toLowerCh(char c) { - return static_cast( std::tolower( c ) ); + return static_cast( std::tolower( static_cast(c) ) ); } } diff -Nru catch2-2.12.1/include/internal/catch_test_case_tracker.cpp catch2-2.13.0/include/internal/catch_test_case_tracker.cpp --- catch2-2.12.1/include/internal/catch_test_case_tracker.cpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_test_case_tracker.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -65,15 +65,12 @@ } - TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) - : m_nameAndLocation( nameAndLocation ), + TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ): + ITracker(nameAndLocation), m_ctx( ctx ), m_parent( parent ) {} - NameAndLocation const& TrackerBase::nameAndLocation() const { - return m_nameAndLocation; - } bool TrackerBase::isComplete() const { return m_runState == CompletedSuccessfully || m_runState == Failed; } @@ -190,7 +187,8 @@ bool SectionTracker::isComplete() const { bool complete = true; - if ((m_filters.empty() || m_filters[0] == "") + if (m_filters.empty() + || m_filters[0] == "" || std::find(m_filters.begin(), m_filters.end(), m_trimmed_name) != m_filters.end()) { complete = TrackerBase::isComplete(); } diff -Nru catch2-2.12.1/include/internal/catch_test_case_tracker.h catch2-2.13.0/include/internal/catch_test_case_tracker.h --- catch2-2.12.1/include/internal/catch_test_case_tracker.h 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_test_case_tracker.h 2020-07-12 18:28:38.000000000 +0000 @@ -23,23 +23,39 @@ SourceLineInfo location; NameAndLocation( std::string const& _name, SourceLineInfo const& _location ); + friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) { + return lhs.name == rhs.name + && lhs.location == rhs.location; + } }; - struct ITracker; + class ITracker; using ITrackerPtr = std::shared_ptr; - struct ITracker { - virtual ~ITracker(); + class ITracker { + NameAndLocation m_nameAndLocation; + + public: + ITracker(NameAndLocation const& nameAndLoc) : + m_nameAndLocation(nameAndLoc) + {} + // static queries - virtual NameAndLocation const& nameAndLocation() const = 0; + NameAndLocation const& nameAndLocation() const { + return m_nameAndLocation; + } + + virtual ~ITracker(); + // dynamic queries virtual bool isComplete() const = 0; // Successfully completed or failed virtual bool isSuccessfullyCompleted() const = 0; virtual bool isOpen() const = 0; // Started but not complete virtual bool hasChildren() const = 0; + virtual bool hasStarted() const = 0; virtual ITracker& parent() = 0; @@ -94,7 +110,6 @@ }; using Children = std::vector; - NameAndLocation m_nameAndLocation; TrackerContext& m_ctx; ITracker* m_parent; Children m_children; @@ -103,12 +118,13 @@ public: TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); - NameAndLocation const& nameAndLocation() const override; bool isComplete() const override; bool isSuccessfullyCompleted() const override; bool isOpen() const override; bool hasChildren() const override; - + bool hasStarted() const override { + return m_runState != NotStarted; + } void addChild( ITrackerPtr const& child ) override; diff -Nru catch2-2.12.1/include/internal/catch_tostring.h catch2-2.13.0/include/internal/catch_tostring.h --- catch2-2.12.1/include/internal/catch_tostring.h 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_tostring.h 2020-07-12 18:28:38.000000000 +0000 @@ -469,20 +469,27 @@ #endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER namespace Catch { - struct not_this_one {}; // Tag type for detecting which begin/ end are being selected - - // Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace + // Import begin/ end from std here using std::begin; using std::end; - not_this_one begin( ... ); - not_this_one end( ... ); + namespace detail { + template + struct void_type { + using type = void; + }; + + template + struct is_range_impl : std::false_type { + }; + + template + struct is_range_impl()))>::type> : std::true_type { + }; + } // namespace detail template - struct is_range { - static const bool value = - !std::is_same())), not_this_one>::value && - !std::is_same())), not_this_one>::value; + struct is_range : detail::is_range_impl { }; #if defined(_MANAGED) // Managed types are never ranges diff -Nru catch2-2.12.1/include/internal/catch_uncaught_exceptions.cpp catch2-2.13.0/include/internal/catch_uncaught_exceptions.cpp --- catch2-2.12.1/include/internal/catch_uncaught_exceptions.cpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_uncaught_exceptions.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -12,7 +12,9 @@ namespace Catch { bool uncaught_exceptions() { -#if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) +#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) + return false; +#elif defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) return std::uncaught_exceptions() > 0; #else return std::uncaught_exception(); diff -Nru catch2-2.12.1/include/internal/catch_version.cpp catch2-2.13.0/include/internal/catch_version.cpp --- catch2-2.12.1/include/internal/catch_version.cpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/internal/catch_version.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -37,7 +37,7 @@ } Version const& libraryVersion() { - static Version version( 2, 12, 1, "", 0 ); + static Version version( 2, 13, 0, "", 0 ); return version; } diff -Nru catch2-2.12.1/include/reporters/catch_reporter_bases.cpp catch2-2.13.0/include/reporters/catch_reporter_bases.cpp --- catch2-2.12.1/include/reporters/catch_reporter_bases.cpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/reporters/catch_reporter_bases.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -41,6 +41,17 @@ return std::string(buffer); } + bool shouldShowDuration( IConfig const& config, double duration ) { + if ( config.showDurations() == ShowDurations::Always ) { + return true; + } + if ( config.showDurations() == ShowDurations::Never ) { + return false; + } + const double min = config.minDuration(); + return min >= 0 && duration >= min; + } + std::string serializeFilters( std::vector const& container ) { ReusableStringStream oss; bool first = true; diff -Nru catch2-2.12.1/include/reporters/catch_reporter_bases.hpp catch2-2.13.0/include/reporters/catch_reporter_bases.hpp --- catch2-2.12.1/include/reporters/catch_reporter_bases.hpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/reporters/catch_reporter_bases.hpp 2020-07-12 18:28:38.000000000 +0000 @@ -25,6 +25,9 @@ // Returns double formatted as %.3f (format expected on output) std::string getFormattedDuration( double duration ); + //! Should the reporter show + bool shouldShowDuration( IConfig const& config, double duration ); + std::string serializeFilters( std::vector const& container ); template @@ -52,7 +55,7 @@ void noMatchingTestCases(std::string const&) override {} void reportInvalidArguments(std::string const&) override {} - + void testRunStarting(TestRunInfo const& _testRunInfo) override { currentTestRunInfo = _testRunInfo; } diff -Nru catch2-2.12.1/include/reporters/catch_reporter_compact.cpp catch2-2.13.0/include/reporters/catch_reporter_compact.cpp --- catch2-2.12.1/include/reporters/catch_reporter_compact.cpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/reporters/catch_reporter_compact.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -245,10 +245,6 @@ return "Reports test results on a single line, suitable for IDEs"; } - ReporterPreferences CompactReporter::getPreferences() const { - return m_reporterPrefs; - } - void CompactReporter::noMatchingTestCases( std::string const& spec ) { stream << "No test cases matched '" << spec << '\'' << std::endl; } @@ -275,8 +271,9 @@ } void CompactReporter::sectionEnded(SectionStats const& _sectionStats) { - if (m_config->showDurations() == ShowDurations::Always) { - stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl; + double dur = _sectionStats.durationInSeconds; + if ( shouldShowDuration( *m_config, dur ) ) { + stream << getFormattedDuration( dur ) << " s: " << _sectionStats.sectionInfo.name << std::endl; } } diff -Nru catch2-2.12.1/include/reporters/catch_reporter_compact.h catch2-2.13.0/include/reporters/catch_reporter_compact.h --- catch2-2.12.1/include/reporters/catch_reporter_compact.h 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/reporters/catch_reporter_compact.h 2020-07-12 18:28:38.000000000 +0000 @@ -22,8 +22,6 @@ static std::string getDescription(); - ReporterPreferences getPreferences() const override; - void noMatchingTestCases(std::string const& spec) override; void assertionStarting(AssertionInfo const&) override; diff -Nru catch2-2.12.1/include/reporters/catch_reporter_console.cpp catch2-2.13.0/include/reporters/catch_reporter_console.cpp --- catch2-2.12.1/include/reporters/catch_reporter_console.cpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/reporters/catch_reporter_console.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -418,8 +418,9 @@ stream << "\nNo assertions in test case"; stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl; } - if (m_config->showDurations() == ShowDurations::Always) { - stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl; + double dur = _sectionStats.durationInSeconds; + if (shouldShowDuration(*m_config, dur)) { + stream << getFormattedDuration(dur) << " s: " << _sectionStats.sectionInfo.name << std::endl; } if (m_headerPrinted) { m_headerPrinted = false; diff -Nru catch2-2.12.1/include/reporters/catch_reporter_junit.cpp catch2-2.13.0/include/reporters/catch_reporter_junit.cpp --- catch2-2.12.1/include/reporters/catch_reporter_junit.cpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/reporters/catch_reporter_junit.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -193,6 +193,11 @@ xml.writeAttribute( "name", name ); } xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) ); + // This is not ideal, but it should be enough to mimic gtest's + // junit output. + // Ideally the JUnit reporter would also handle `skipTest` + // events and write those out appropriately. + xml.writeAttribute( "status", "run" ); writeAssertions( sectionNode ); diff -Nru catch2-2.12.1/include/reporters/catch_reporter_tap.hpp catch2-2.13.0/include/reporters/catch_reporter_tap.hpp --- catch2-2.12.1/include/reporters/catch_reporter_tap.hpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/reporters/catch_reporter_tap.hpp 2020-07-12 18:28:38.000000000 +0000 @@ -23,16 +23,17 @@ using StreamingReporterBase::StreamingReporterBase; + TAPReporter( ReporterConfig const& config ): + StreamingReporterBase( config ) { + m_reporterPrefs.shouldReportAllAssertions = true; + } + ~TAPReporter() override; static std::string getDescription() { return "Reports test results in TAP format, suitable for test harnesses"; } - ReporterPreferences getPreferences() const override { - return m_reporterPrefs; - } - void noMatchingTestCases( std::string const& spec ) override { stream << "# No test cases matched '" << spec << "'" << std::endl; } @@ -203,16 +204,15 @@ return; } - // using messages.end() directly (or auto) yields compilation error: - std::vector::const_iterator itEnd = messages.end(); - const std::size_t N = static_cast( std::distance( itMessage, itEnd ) ); + const auto itEnd = messages.cend(); + const auto N = static_cast( std::distance( itMessage, itEnd ) ); { Colour colourGuard( colour ); stream << " with " << pluralise( N, "message" ) << ":"; } - for(; itMessage != itEnd; ) { + while( itMessage != itEnd ) { // If this assertion is a warning ignore any INFO messages if( printInfoMessages || itMessage->type != ResultWas::Info ) { stream << " '" << itMessage->message << "'"; @@ -220,7 +220,9 @@ Colour colourGuard( dimColour() ); stream << " and"; } + continue; } + ++itMessage; } } @@ -234,10 +236,9 @@ }; void printTotals( const Totals& totals ) const { + stream << "1.." << totals.assertions.total(); if( totals.testCases.total() == 0 ) { - stream << "1..0 # Skipped: No tests ran."; - } else { - stream << "1.." << counter; + stream << " # Skipped: No tests ran."; } } }; diff -Nru catch2-2.12.1/include/reporters/catch_reporter_xml.cpp catch2-2.13.0/include/reporters/catch_reporter_xml.cpp --- catch2-2.12.1/include/reporters/catch_reporter_xml.cpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/include/reporters/catch_reporter_xml.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -207,6 +207,10 @@ .writeAttribute( "successes", testGroupStats.totals.assertions.passed ) .writeAttribute( "failures", testGroupStats.totals.assertions.failed ) .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk ); + m_xml.scopedElement( "OverallResultsCases") + .writeAttribute( "successes", testGroupStats.totals.testCases.passed ) + .writeAttribute( "failures", testGroupStats.totals.testCases.failed ) + .writeAttribute( "expectedFailures", testGroupStats.totals.testCases.failedButOk ); m_xml.endElement(); } @@ -216,6 +220,10 @@ .writeAttribute( "successes", testRunStats.totals.assertions.passed ) .writeAttribute( "failures", testRunStats.totals.assertions.failed ) .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk ); + m_xml.scopedElement( "OverallResultsCases") + .writeAttribute( "successes", testRunStats.totals.testCases.passed ) + .writeAttribute( "failures", testRunStats.totals.testCases.failed ) + .writeAttribute( "expectedFailures", testRunStats.totals.testCases.failedButOk ); m_xml.endElement(); } diff -Nru catch2-2.12.1/projects/CMakeLists.txt catch2-2.13.0/projects/CMakeLists.txt --- catch2-2.12.1/projects/CMakeLists.txt 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/projects/CMakeLists.txt 2020-07-12 18:28:38.000000000 +0000 @@ -27,6 +27,7 @@ ${SELF_TEST_DIR}/IntrospectiveTests/StringManip.tests.cpp ${SELF_TEST_DIR}/IntrospectiveTests/Xml.tests.cpp ${SELF_TEST_DIR}/IntrospectiveTests/ToString.tests.cpp + ${SELF_TEST_DIR}/TimingTests/Sleep.tests.cpp ${SELF_TEST_DIR}/UsageTests/Approx.tests.cpp ${SELF_TEST_DIR}/UsageTests/BDD.tests.cpp ${SELF_TEST_DIR}/UsageTests/Benchmark.tests.cpp diff -Nru catch2-2.12.1/projects/ExtraTests/CMakeLists.txt catch2-2.13.0/projects/ExtraTests/CMakeLists.txt --- catch2-2.12.1/projects/ExtraTests/CMakeLists.txt 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/projects/ExtraTests/CMakeLists.txt 2020-07-12 18:28:38.000000000 +0000 @@ -10,6 +10,40 @@ message( STATUS "Extra tests included" ) +# The MinDuration reporting tests do not need separate compilation, but +# they have non-trivial execution time, so they are categorized as +# extra tests, so that they are run less. +add_test(NAME MinDuration::SimpleThreshold COMMAND $ --min-duration 0.22 [min_duration_test]) +set_tests_properties( + MinDuration::SimpleThreshold + PROPERTIES + PASS_REGULAR_EXPRESSION "s: sleep_for_250ms" + FAIL_REGULAR_EXPRESSION "sleep_for_100ms" + RUN_SERIAL ON # The test is timing sensitive, so we want to run it + # serially to avoid false positives on oversubscribed machines +) + +# -d yes overrides the threshold, so we should see the faster test even +# with a ridiculous high min duration threshold +add_test(NAME MinDuration::DurationOverrideYes COMMAND $ --min-duration 1.0 -d yes [min_duration_test]) +set_tests_properties( + MinDuration::DurationOverrideYes + PROPERTIES + PASS_REGULAR_EXPRESSION "s: sleep_for_100ms" +) + +# -d no overrides the threshold, so we should never see any tests even +# with ridiculously low min duration threshold +add_test(NAME MinDuration::DurationOverrideNo COMMAND $ --min-duration 0.0001 -d no [min_duration_test]) +set_tests_properties( + MinDuration::DurationOverrideNo + PROPERTIES + FAIL_REGULAR_EXPRESSION "sleep_for_250ms" +) + + +# ------------ end of duration reporting tests + # define folders used: set( TESTS_DIR ${CATCH_DIR}/projects/ExtraTests ) diff -Nru catch2-2.12.1/projects/SelfTest/Baselines/compact.sw.approved.txt catch2-2.13.0/projects/SelfTest/Baselines/compact.sw.approved.txt --- catch2-2.12.1/projects/SelfTest/Baselines/compact.sw.approved.txt 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/projects/SelfTest/Baselines/compact.sw.approved.txt 2020-07-12 18:28:38.000000000 +0000 @@ -30,6 +30,57 @@ CmdLine.tests.cpp:: passed: spec.matches(fakeTestCase(R"(spec [a] char)")) for: true CmdLine.tests.cpp:: passed: !(spec.matches(fakeTestCase("differs but has similar tag", "[a]"))) for: !false CmdLine.tests.cpp:: passed: spec.matches(fakeTestCase(R"(spec \ char)")) for: true +Generators.tests.cpp:: passed: counter < 7 for: 3 < 7 +Generators.tests.cpp:: passed: counter < 7 for: 6 < 7 +Generators.tests.cpp:: passed: i != j for: 1 != 3 +Generators.tests.cpp:: passed: i != j for: 1 != 4 +Generators.tests.cpp:: passed: i != j for: 2 != 3 +Generators.tests.cpp:: passed: i != j for: 2 != 4 +PartTracker.tests.cpp:: passed: with 1 message: 'A' +PartTracker.tests.cpp:: passed: m for: 1 +PartTracker.tests.cpp:: passed: m for: 2 +PartTracker.tests.cpp:: passed: m for: 3 +PartTracker.tests.cpp:: passed: 1 +PartTracker.tests.cpp:: passed: m for: 2 +PartTracker.tests.cpp:: passed: m for: 3 +PartTracker.tests.cpp:: passed: m for: 1 +PartTracker.tests.cpp:: passed: m for: 2 +PartTracker.tests.cpp:: passed: m for: 3 +PartTracker.tests.cpp:: passed: with 1 message: 'A' +PartTracker.tests.cpp:: passed: with 3 messages: 'i := 1' and 'j := 3' and 'k := 5' +PartTracker.tests.cpp:: passed: with 1 message: 'B' +PartTracker.tests.cpp:: passed: with 3 messages: 'i := 1' and 'j := 3' and 'k := 6' +PartTracker.tests.cpp:: passed: with 1 message: 'B' +PartTracker.tests.cpp:: passed: with 3 messages: 'i := 1' and 'j := 4' and 'k := 5' +PartTracker.tests.cpp:: passed: with 3 messages: 'i := 1' and 'j := 4' and 'k := 6' +PartTracker.tests.cpp:: passed: with 1 message: 'A' +PartTracker.tests.cpp:: passed: with 3 messages: 'i := 2' and 'j := 3' and 'k := 5' +PartTracker.tests.cpp:: passed: with 1 message: 'B' +PartTracker.tests.cpp:: passed: with 3 messages: 'i := 2' and 'j := 3' and 'k := 6' +PartTracker.tests.cpp:: passed: with 1 message: 'B' +PartTracker.tests.cpp:: passed: with 3 messages: 'i := 2' and 'j := 4' and 'k := 5' +PartTracker.tests.cpp:: passed: with 3 messages: 'i := 2' and 'j := 4' and 'k := 6' +PartTracker.tests.cpp:: passed: m for: 1 +PartTracker.tests.cpp:: passed: n for: 1 +PartTracker.tests.cpp:: passed: m for: 1 +PartTracker.tests.cpp:: passed: n for: 2 +PartTracker.tests.cpp:: passed: m for: 1 +PartTracker.tests.cpp:: passed: n for: 3 +PartTracker.tests.cpp:: passed: m for: 2 +PartTracker.tests.cpp:: passed: n for: 1 +PartTracker.tests.cpp:: passed: m for: 2 +PartTracker.tests.cpp:: passed: n for: 2 +PartTracker.tests.cpp:: passed: m for: 2 +PartTracker.tests.cpp:: passed: n for: 3 +PartTracker.tests.cpp:: passed: m for: 3 +PartTracker.tests.cpp:: passed: n for: 1 +PartTracker.tests.cpp:: passed: m for: 3 +PartTracker.tests.cpp:: passed: n for: 2 +PartTracker.tests.cpp:: passed: m for: 3 +PartTracker.tests.cpp:: passed: n for: 3 +Misc.tests.cpp:: passed: +Misc.tests.cpp:: passed: +Misc.tests.cpp:: passed: Exception.tests.cpp:: failed: unexpected exception with message: 'answer := 42' with 1 message: 'expected exception' Exception.tests.cpp:: failed: unexpected exception with message: 'answer := 42'; expression was: thisThrows() with 1 message: 'expected exception' Exception.tests.cpp:: passed: thisThrows() with 1 message: 'answer := 42' @@ -326,6 +377,12 @@ Condition.tests.cpp:: passed: (std::numeric_limits::max)() > ul for: 4294967295 (0x) > 4 Matchers.tests.cpp:: passed: testStringForMatching2(), !composed1 for: "some completely different text that contains one common word" not ( contains: "string" or contains: "random" ) Matchers.tests.cpp:: passed: testStringForMatching2(), composed2 for: "some completely different text that contains one common word" ( contains: "string" or contains: "random" or contains: "different" ) +Matchers.tests.cpp:: passed: 1, !(first && second) for: 1 not ( CheckedTestingMatcher set to fail and CheckedTestingMatcher set to fail ) +Matchers.tests.cpp:: passed: first.matchCalled for: true +Matchers.tests.cpp:: passed: !second.matchCalled for: true +Matchers.tests.cpp:: passed: 1, first || second for: 1 ( CheckedTestingMatcher set to succeed or CheckedTestingMatcher set to fail ) +Matchers.tests.cpp:: passed: first.matchCalled for: true +Matchers.tests.cpp:: passed: !second.matchCalled for: true Matchers.tests.cpp:: failed: testStringForMatching(), Contains("not there", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" contains: "not there" (case insensitive) Matchers.tests.cpp:: failed: testStringForMatching(), Contains("STRING") for: "this string contains 'abc' as a substring" contains: "STRING" Generators.tests.cpp:: passed: elem % 2 == 1 for: 1 == 1 diff -Nru catch2-2.12.1/projects/SelfTest/Baselines/console.std.approved.txt catch2-2.13.0/projects/SelfTest/Baselines/console.std.approved.txt --- catch2-2.12.1/projects/SelfTest/Baselines/console.std.approved.txt 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/projects/SelfTest/Baselines/console.std.approved.txt 2020-07-12 18:28:38.000000000 +0000 @@ -1380,6 +1380,6 @@ Why would you throw a std::string? =============================================================================== -test cases: 310 | 236 passed | 70 failed | 4 failed as expected -assertions: 1701 | 1549 passed | 131 failed | 21 failed as expected +test cases: 321 | 247 passed | 70 failed | 4 failed as expected +assertions: 1758 | 1606 passed | 131 failed | 21 failed as expected diff -Nru catch2-2.12.1/projects/SelfTest/Baselines/console.swa4.approved.txt catch2-2.13.0/projects/SelfTest/Baselines/console.swa4.approved.txt --- catch2-2.12.1/projects/SelfTest/Baselines/console.swa4.approved.txt 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/projects/SelfTest/Baselines/console.swa4.approved.txt 2020-07-12 18:28:38.000000000 +0000 @@ -244,6 +244,514 @@ true ------------------------------------------------------------------------------- +#1913 - GENERATE inside a for loop should not keep recreating the generator +------------------------------------------------------------------------------- +Generators.tests.cpp: +............................................................................... + +Generators.tests.cpp:: PASSED: + REQUIRE( counter < 7 ) +with expansion: + 3 < 7 + +------------------------------------------------------------------------------- +#1913 - GENERATE inside a for loop should not keep recreating the generator +------------------------------------------------------------------------------- +Generators.tests.cpp: +............................................................................... + +Generators.tests.cpp:: PASSED: + REQUIRE( counter < 7 ) +with expansion: + 6 < 7 + +------------------------------------------------------------------------------- +#1913 - GENERATEs can share a line +------------------------------------------------------------------------------- +Generators.tests.cpp: +............................................................................... + +Generators.tests.cpp:: PASSED: + REQUIRE( i != j ) +with expansion: + 1 != 3 + +------------------------------------------------------------------------------- +#1913 - GENERATEs can share a line +------------------------------------------------------------------------------- +Generators.tests.cpp: +............................................................................... + +Generators.tests.cpp:: PASSED: + REQUIRE( i != j ) +with expansion: + 1 != 4 + +------------------------------------------------------------------------------- +#1913 - GENERATEs can share a line +------------------------------------------------------------------------------- +Generators.tests.cpp: +............................................................................... + +Generators.tests.cpp:: PASSED: + REQUIRE( i != j ) +with expansion: + 2 != 3 + +------------------------------------------------------------------------------- +#1913 - GENERATEs can share a line +------------------------------------------------------------------------------- +Generators.tests.cpp: +............................................................................... + +Generators.tests.cpp:: PASSED: + REQUIRE( i != j ) +with expansion: + 2 != 4 + +------------------------------------------------------------------------------- +#1938 - GENERATE after a section + A +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with message: + A + +------------------------------------------------------------------------------- +#1938 - GENERATE after a section + B +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 1 + +------------------------------------------------------------------------------- +#1938 - GENERATE after a section + B +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 2 + +------------------------------------------------------------------------------- +#1938 - GENERATE after a section + B +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 3 + +------------------------------------------------------------------------------- +#1938 - Section followed by flat generate + A +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( 1 ) + +------------------------------------------------------------------------------- +#1938 - Section followed by flat generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 2 + +------------------------------------------------------------------------------- +#1938 - Section followed by flat generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 3 + +------------------------------------------------------------------------------- +#1938 - flat generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 1 + +------------------------------------------------------------------------------- +#1938 - flat generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 2 + +------------------------------------------------------------------------------- +#1938 - flat generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 3 + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates + A +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with message: + A + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with messages: + i := 1 + j := 3 + k := 5 + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates + B +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with message: + B + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with messages: + i := 1 + j := 3 + k := 6 + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates + B +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with message: + B + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with messages: + i := 1 + j := 4 + k := 5 + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with messages: + i := 1 + j := 4 + k := 6 + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates + A +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with message: + A + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with messages: + i := 2 + j := 3 + k := 5 + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates + B +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with message: + B + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with messages: + i := 2 + j := 3 + k := 6 + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates + B +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with message: + B + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with messages: + i := 2 + j := 4 + k := 5 + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with messages: + i := 2 + j := 4 + k := 6 + +------------------------------------------------------------------------------- +#1938 - nested generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 1 + +PartTracker.tests.cpp:: PASSED: + REQUIRE( n ) +with expansion: + 1 + +------------------------------------------------------------------------------- +#1938 - nested generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 1 + +PartTracker.tests.cpp:: PASSED: + REQUIRE( n ) +with expansion: + 2 + +------------------------------------------------------------------------------- +#1938 - nested generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 1 + +PartTracker.tests.cpp:: PASSED: + REQUIRE( n ) +with expansion: + 3 + +------------------------------------------------------------------------------- +#1938 - nested generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 2 + +PartTracker.tests.cpp:: PASSED: + REQUIRE( n ) +with expansion: + 1 + +------------------------------------------------------------------------------- +#1938 - nested generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 2 + +PartTracker.tests.cpp:: PASSED: + REQUIRE( n ) +with expansion: + 2 + +------------------------------------------------------------------------------- +#1938 - nested generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 2 + +PartTracker.tests.cpp:: PASSED: + REQUIRE( n ) +with expansion: + 3 + +------------------------------------------------------------------------------- +#1938 - nested generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 3 + +PartTracker.tests.cpp:: PASSED: + REQUIRE( n ) +with expansion: + 1 + +------------------------------------------------------------------------------- +#1938 - nested generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 3 + +PartTracker.tests.cpp:: PASSED: + REQUIRE( n ) +with expansion: + 2 + +------------------------------------------------------------------------------- +#1938 - nested generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 3 + +PartTracker.tests.cpp:: PASSED: + REQUIRE( n ) +with expansion: + 3 + +------------------------------------------------------------------------------- +#1954 - 7 arg template test case sig compiles - 1, 1, 1, 1, 1, 0, 0 +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + +------------------------------------------------------------------------------- +#1954 - 7 arg template test case sig compiles - 5, 1, 1, 1, 1, 0, 0 +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + +------------------------------------------------------------------------------- +#1954 - 7 arg template test case sig compiles - 5, 3, 1, 1, 1, 0, 0 +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + +------------------------------------------------------------------------------- #748 - captures with unexpected exceptions outside assertions ------------------------------------------------------------------------------- @@ -423,6 +931,6 @@ CHECK( true != true ) =============================================================================== -test cases: 21 | 16 passed | 3 failed | 2 failed as expected -assertions: 49 | 42 passed | 4 failed | 3 failed as expected +test cases: 31 | 26 passed | 3 failed | 2 failed as expected +assertions: 100 | 93 passed | 4 failed | 3 failed as expected diff -Nru catch2-2.12.1/projects/SelfTest/Baselines/console.sw.approved.txt catch2-2.13.0/projects/SelfTest/Baselines/console.sw.approved.txt --- catch2-2.12.1/projects/SelfTest/Baselines/console.sw.approved.txt 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/projects/SelfTest/Baselines/console.sw.approved.txt 2020-07-12 18:28:38.000000000 +0000 @@ -244,6 +244,514 @@ true ------------------------------------------------------------------------------- +#1913 - GENERATE inside a for loop should not keep recreating the generator +------------------------------------------------------------------------------- +Generators.tests.cpp: +............................................................................... + +Generators.tests.cpp:: PASSED: + REQUIRE( counter < 7 ) +with expansion: + 3 < 7 + +------------------------------------------------------------------------------- +#1913 - GENERATE inside a for loop should not keep recreating the generator +------------------------------------------------------------------------------- +Generators.tests.cpp: +............................................................................... + +Generators.tests.cpp:: PASSED: + REQUIRE( counter < 7 ) +with expansion: + 6 < 7 + +------------------------------------------------------------------------------- +#1913 - GENERATEs can share a line +------------------------------------------------------------------------------- +Generators.tests.cpp: +............................................................................... + +Generators.tests.cpp:: PASSED: + REQUIRE( i != j ) +with expansion: + 1 != 3 + +------------------------------------------------------------------------------- +#1913 - GENERATEs can share a line +------------------------------------------------------------------------------- +Generators.tests.cpp: +............................................................................... + +Generators.tests.cpp:: PASSED: + REQUIRE( i != j ) +with expansion: + 1 != 4 + +------------------------------------------------------------------------------- +#1913 - GENERATEs can share a line +------------------------------------------------------------------------------- +Generators.tests.cpp: +............................................................................... + +Generators.tests.cpp:: PASSED: + REQUIRE( i != j ) +with expansion: + 2 != 3 + +------------------------------------------------------------------------------- +#1913 - GENERATEs can share a line +------------------------------------------------------------------------------- +Generators.tests.cpp: +............................................................................... + +Generators.tests.cpp:: PASSED: + REQUIRE( i != j ) +with expansion: + 2 != 4 + +------------------------------------------------------------------------------- +#1938 - GENERATE after a section + A +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with message: + A + +------------------------------------------------------------------------------- +#1938 - GENERATE after a section + B +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 1 + +------------------------------------------------------------------------------- +#1938 - GENERATE after a section + B +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 2 + +------------------------------------------------------------------------------- +#1938 - GENERATE after a section + B +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 3 + +------------------------------------------------------------------------------- +#1938 - Section followed by flat generate + A +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( 1 ) + +------------------------------------------------------------------------------- +#1938 - Section followed by flat generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 2 + +------------------------------------------------------------------------------- +#1938 - Section followed by flat generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 3 + +------------------------------------------------------------------------------- +#1938 - flat generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 1 + +------------------------------------------------------------------------------- +#1938 - flat generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 2 + +------------------------------------------------------------------------------- +#1938 - flat generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 3 + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates + A +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with message: + A + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with messages: + i := 1 + j := 3 + k := 5 + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates + B +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with message: + B + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with messages: + i := 1 + j := 3 + k := 6 + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates + B +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with message: + B + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with messages: + i := 1 + j := 4 + k := 5 + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with messages: + i := 1 + j := 4 + k := 6 + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates + A +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with message: + A + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with messages: + i := 2 + j := 3 + k := 5 + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates + B +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with message: + B + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with messages: + i := 2 + j := 3 + k := 6 + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates + B +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with message: + B + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with messages: + i := 2 + j := 4 + k := 5 + +------------------------------------------------------------------------------- +#1938 - mixed sections and generates +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: +with messages: + i := 2 + j := 4 + k := 6 + +------------------------------------------------------------------------------- +#1938 - nested generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 1 + +PartTracker.tests.cpp:: PASSED: + REQUIRE( n ) +with expansion: + 1 + +------------------------------------------------------------------------------- +#1938 - nested generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 1 + +PartTracker.tests.cpp:: PASSED: + REQUIRE( n ) +with expansion: + 2 + +------------------------------------------------------------------------------- +#1938 - nested generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 1 + +PartTracker.tests.cpp:: PASSED: + REQUIRE( n ) +with expansion: + 3 + +------------------------------------------------------------------------------- +#1938 - nested generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 2 + +PartTracker.tests.cpp:: PASSED: + REQUIRE( n ) +with expansion: + 1 + +------------------------------------------------------------------------------- +#1938 - nested generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 2 + +PartTracker.tests.cpp:: PASSED: + REQUIRE( n ) +with expansion: + 2 + +------------------------------------------------------------------------------- +#1938 - nested generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 2 + +PartTracker.tests.cpp:: PASSED: + REQUIRE( n ) +with expansion: + 3 + +------------------------------------------------------------------------------- +#1938 - nested generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 3 + +PartTracker.tests.cpp:: PASSED: + REQUIRE( n ) +with expansion: + 1 + +------------------------------------------------------------------------------- +#1938 - nested generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 3 + +PartTracker.tests.cpp:: PASSED: + REQUIRE( n ) +with expansion: + 2 + +------------------------------------------------------------------------------- +#1938 - nested generate +------------------------------------------------------------------------------- +PartTracker.tests.cpp: +............................................................................... + +PartTracker.tests.cpp:: PASSED: + REQUIRE( m ) +with expansion: + 3 + +PartTracker.tests.cpp:: PASSED: + REQUIRE( n ) +with expansion: + 3 + +------------------------------------------------------------------------------- +#1954 - 7 arg template test case sig compiles - 1, 1, 1, 1, 1, 0, 0 +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + +------------------------------------------------------------------------------- +#1954 - 7 arg template test case sig compiles - 5, 1, 1, 1, 1, 0, 0 +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + +------------------------------------------------------------------------------- +#1954 - 7 arg template test case sig compiles - 5, 3, 1, 1, 1, 0, 0 +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + +------------------------------------------------------------------------------- #748 - captures with unexpected exceptions outside assertions ------------------------------------------------------------------------------- @@ -2495,6 +3003,52 @@ "string" or contains: "random" or contains: "different" ) ------------------------------------------------------------------------------- +Composed matchers shortcircuit + && +------------------------------------------------------------------------------- +Matchers.tests.cpp: +............................................................................... + +Matchers.tests.cpp:: PASSED: + CHECK_THAT( 1, !(first && second) ) +with expansion: + 1 not ( CheckedTestingMatcher set to fail and CheckedTestingMatcher set to + fail ) + +Matchers.tests.cpp:: PASSED: + REQUIRE( first.matchCalled ) +with expansion: + true + +Matchers.tests.cpp:: PASSED: + REQUIRE( !second.matchCalled ) +with expansion: + true + +------------------------------------------------------------------------------- +Composed matchers shortcircuit + || +------------------------------------------------------------------------------- +Matchers.tests.cpp: +............................................................................... + +Matchers.tests.cpp:: PASSED: + CHECK_THAT( 1, first || second ) +with expansion: + 1 ( CheckedTestingMatcher set to succeed or CheckedTestingMatcher set to fail + ) + +Matchers.tests.cpp:: PASSED: + REQUIRE( first.matchCalled ) +with expansion: + true + +Matchers.tests.cpp:: PASSED: + REQUIRE( !second.matchCalled ) +with expansion: + true + +------------------------------------------------------------------------------- Contains string matcher ------------------------------------------------------------------------------- Matchers.tests.cpp: @@ -13573,6 +14127,6 @@ Misc.tests.cpp:: PASSED: =============================================================================== -test cases: 310 | 220 passed | 86 failed | 4 failed as expected -assertions: 1718 | 1549 passed | 148 failed | 21 failed as expected +test cases: 321 | 231 passed | 86 failed | 4 failed as expected +assertions: 1775 | 1606 passed | 148 failed | 21 failed as expected diff -Nru catch2-2.12.1/projects/SelfTest/Baselines/junit.sw.approved.txt catch2-2.13.0/projects/SelfTest/Baselines/junit.sw.approved.txt --- catch2-2.12.1/projects/SelfTest/Baselines/junit.sw.approved.txt 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/projects/SelfTest/Baselines/junit.sw.approved.txt 2020-07-12 18:28:38.000000000 +0000 @@ -1,22 +1,22 @@ - + - - - - - - - - - - - + + + + + + + + + + + FAILED: 1514 @@ -29,11 +29,25 @@ Nor would this - - - - - + + + + + + + + + + + + + + + + + + + FAILED: expected exception @@ -41,7 +55,7 @@ Exception.tests.cpp: - + FAILED: REQUIRE_NOTHROW( thisThrows() ) @@ -50,10 +64,10 @@ Exception.tests.cpp: - - - - + + + + FAILED: CHECK( f() == 0 ) @@ -62,13 +76,13 @@ Misc.tests.cpp: - - - - - - - + + + + + + + FAILED: CHECK( false != false ) @@ -120,14 +134,14 @@ Condition.tests.cpp: - - - - - - - - + + + + + + + + FAILED: REQUIRE( s == "world" ) @@ -136,8 +150,8 @@ Class.tests.cpp: - - + + FAILED: REQUIRE( Template_Fixture_2<TestType>::m_a.size() == 1 ) @@ -146,7 +160,7 @@ Class.tests.cpp: - + FAILED: REQUIRE( Template_Fixture_2<TestType>::m_a.size() == 1 ) @@ -155,7 +169,7 @@ Class.tests.cpp: - + FAILED: REQUIRE( Template_Fixture_2<TestType>::m_a.size() == 1 ) @@ -164,7 +178,7 @@ Class.tests.cpp: - + FAILED: REQUIRE( Template_Fixture_2<TestType>::m_a.size() == 1 ) @@ -173,11 +187,11 @@ Class.tests.cpp: - - - - - + + + + + FAILED: REQUIRE( Template_Fixture_2<TestType>{}.m_a.size() < 2 ) @@ -186,7 +200,7 @@ Class.tests.cpp: - + FAILED: REQUIRE( Template_Fixture_2<TestType>{}.m_a.size() < 2 ) @@ -195,7 +209,7 @@ Class.tests.cpp: - + FAILED: REQUIRE( Template_Fixture_2<TestType>{}.m_a.size() < 2 ) @@ -204,7 +218,7 @@ Class.tests.cpp: - + FAILED: REQUIRE( Template_Fixture_2<TestType>{}.m_a.size() < 2 ) @@ -213,11 +227,11 @@ Class.tests.cpp: - - - - - + + + + + FAILED: REQUIRE( Template_Fixture<TestType>::m_a == 2 ) @@ -226,7 +240,7 @@ Class.tests.cpp: - + FAILED: REQUIRE( Template_Fixture<TestType>::m_a == 2 ) @@ -235,7 +249,7 @@ Class.tests.cpp: - + FAILED: REQUIRE( Template_Fixture<TestType>::m_a == 2 ) @@ -244,10 +258,10 @@ Class.tests.cpp: - - - - + + + + FAILED: REQUIRE( Nttp_Fixture<V>::value == 0 ) @@ -256,7 +270,7 @@ Class.tests.cpp: - + FAILED: REQUIRE( Nttp_Fixture<V>::value == 0 ) @@ -265,7 +279,7 @@ Class.tests.cpp: - + FAILED: REQUIRE( Nttp_Fixture<V>::value == 0 ) @@ -274,10 +288,10 @@ Class.tests.cpp: - - - - + + + + FAILED: REQUIRE( m_a == 2 ) @@ -286,25 +300,25 @@ Class.tests.cpp: - - - - - - - - - - - + + + + + + + + + + + FAILED: to infinity and beyond Misc.tests.cpp: - - + + FAILED: CHECK( &o1 == &o2 ) @@ -320,9 +334,9 @@ Tricky.tests.cpp: - - - + + + FAILED: {Unknown expression after the reported line} @@ -330,38 +344,40 @@ Exception.tests.cpp: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FAILED: CHECK_THAT( testStringForMatching(), Contains("not there", Catch::CaseSensitive::No) ) @@ -378,10 +394,10 @@ Matchers.tests.cpp: - - - - + + + + FAILED: REQUIRE_NOTHROW( throwCustom() ) @@ -389,7 +405,7 @@ Exception.tests.cpp: - + FAILED: REQUIRE_THROWS_AS( throwCustom(), std::exception ) @@ -397,16 +413,16 @@ Exception.tests.cpp: - + FAILED: custom std exception Exception.tests.cpp: - - - + + + FAILED: CHECK_THAT( testStringForMatching(), EndsWith("Substring") ) @@ -423,10 +439,10 @@ Matchers.tests.cpp: - - - - + + + + FAILED: CHECK( data.int_seven == 6 ) @@ -519,9 +535,9 @@ Condition.tests.cpp: - - - + + + FAILED: CHECK_THAT( testStringForMatching(), Equals("this string contains 'ABC' as a substring") ) @@ -539,8 +555,8 @@ Matchers.tests.cpp: - - + + FAILED: CHECK_THROWS_MATCHES( doesNotThrow(), SpecialException, ExceptionMatcher{1} ) @@ -552,7 +568,7 @@ Matchers.tests.cpp: - + FAILED: CHECK_THROWS_MATCHES( throwsAsInt(1), SpecialException, ExceptionMatcher{1} ) @@ -566,7 +582,7 @@ Matchers.tests.cpp: - + FAILED: CHECK_THROWS_MATCHES( throwsSpecialException(3), SpecialException, ExceptionMatcher{1} ) @@ -582,12 +598,12 @@ Matchers.tests.cpp: - - - - - - + + + + + + FAILED: CHECK_THROWS_AS( thisThrows(), std::string ) @@ -606,77 +622,77 @@ Exception.tests.cpp: - + FAILED: This is a failure Message.tests.cpp: - + FAILED: Message.tests.cpp: - + FAILED: This is a failure Message.tests.cpp: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FAILED: REQUIRE( a == 1 ) @@ -687,7 +703,7 @@ Message.tests.cpp: - + FAILED: CHECK( a == 1 ) @@ -708,7 +724,7 @@ Message.tests.cpp: - + FAILED: REQUIRE( i < 10 ) @@ -719,7 +735,7 @@ Message.tests.cpp: - + FAILED: CHECK( data.int_seven != 7 ) @@ -756,14 +772,14 @@ Condition.tests.cpp: - - - - - - - - + + + + + + + + FAILED: CHECK_THAT( testStringForMatching(), (Contains("string") || Contains("different")) && Contains("random") ) @@ -773,8 +789,8 @@ Matchers.tests.cpp: - - + + FAILED: CHECK_THAT( testStringForMatching(), !Contains("substring") ) @@ -783,7 +799,7 @@ Matchers.tests.cpp: - + FAILED: REQUIRE_THROWS_WITH( thisThrows(), "should fail" ) @@ -792,18 +808,18 @@ Exception.tests.cpp: - - - + + + FAILED: custom exception Exception.tests.cpp: - - - + + + FAILED: CHECK( data.int_seven > 7 ) @@ -938,98 +954,98 @@ Condition.tests.cpp: - - - - + + + + FAILED: Message from section one Message.tests.cpp: - + FAILED: Message from section two Message.tests.cpp: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FAILED: CHECK( truthy(false) ) @@ -1038,7 +1054,7 @@ Decomposition.tests.cpp: - + FAILED: CHECK_THAT( testStringForMatching(), Matches("this STRING contains 'abc' as a substring") ) @@ -1064,19 +1080,19 @@ Matchers.tests.cpp: - - - - - - - - - - - - - + + + + + + + + + + + + + A string sent directly to stdout @@ -1085,14 +1101,14 @@ A string sent to stderr via clog - - + + Message from section one Message from section two - + FAILED: CHECK_THAT( testStringForMatching(), StartsWith("This String") ) @@ -1109,31 +1125,31 @@ Matchers.tests.cpp: - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + FAILED: CHECK( s1 == s2 ) @@ -1149,103 +1165,103 @@ Misc.tests.cpp: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FAILED: For some reason someone is throwing a string literal! Exception.tests.cpp: - - - - - - - - - - - - + + + + + + + + + + + + FAILED: 3.14 Exception.tests.cpp: - - - - - - - + + + + + + + FAILED: CHECK_THAT( empty, Approx(t1) ) @@ -1254,7 +1270,7 @@ Matchers.tests.cpp: - + FAILED: CHECK_THAT( v1, Approx(v2) ) @@ -1263,12 +1279,12 @@ Matchers.tests.cpp: - - - - - - + + + + + + FAILED: CHECK_THAT( v, VectorContains(-1) ) @@ -1284,7 +1300,7 @@ Matchers.tests.cpp: - + FAILED: CHECK_THAT( empty, Contains(v) ) @@ -1300,7 +1316,7 @@ Matchers.tests.cpp: - + FAILED: CHECK_THAT( v, Equals(v2) ) @@ -1330,7 +1346,7 @@ Matchers.tests.cpp: - + FAILED: CHECK_THAT( v, UnorderedEquals(empty) ) @@ -1360,15 +1376,15 @@ Matchers.tests.cpp: - - + + FAILED: unexpected exception Exception.tests.cpp: - + FAILED: CHECK( thisThrows() == 0 ) @@ -1376,7 +1392,7 @@ Exception.tests.cpp: - + FAILED: REQUIRE( thisThrows() == 0 ) @@ -1384,7 +1400,7 @@ Exception.tests.cpp: - + FAILED: CHECK( thisThrows() == 0 ) @@ -1392,33 +1408,33 @@ Exception.tests.cpp: - + FAILED: unexpected exception Exception.tests.cpp: - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + FAILED: CHECKED_ELSE( flag ) @@ -1434,8 +1450,8 @@ Misc.tests.cpp: - - + + FAILED: CHECKED_IF( flag ) @@ -1451,27 +1467,27 @@ Misc.tests.cpp: - - - - - - + + + + + + FAILED: Previous info should not be seen Message.tests.cpp: - + FAILED: previous unscoped info SHOULD not be seen Message.tests.cpp: - - + + FAILED: CHECK( b > a ) @@ -1480,7 +1496,7 @@ Misc.tests.cpp: - + FAILED: CHECK( b > a ) @@ -1489,15 +1505,15 @@ Misc.tests.cpp: - - - - - - - - - + + + + + + + + + FAILED: CHECK( ( fib[i] % 2 ) == 0 ) @@ -1547,8 +1563,8 @@ Misc.tests.cpp: - - + + FAILED: REQUIRE( a == b ) @@ -1557,14 +1573,14 @@ Misc.tests.cpp: - - - - - - - - + + + + + + + + FAILED: REQUIRE( false ) @@ -1572,15 +1588,15 @@ Message.tests.cpp: - - - - - - - - - + + + + + + + + + FAILED: REQUIRE( false ) @@ -1589,7 +1605,7 @@ Message.tests.cpp: - + FAILED: CHECK( false ) @@ -1597,16 +1613,16 @@ Message.tests.cpp: - - - - - - - - - - + + + + + + + + + + FAILED: REQUIRE( false ) @@ -1614,7 +1630,7 @@ Misc.tests.cpp: - + FAILED: REQUIRE( false ) @@ -1623,9 +1639,9 @@ Message.tests.cpp: - - - + + + FAILED: CHECK( false ) @@ -1645,16 +1661,16 @@ Message.tests.cpp: - - - - - - - - - - + + + + + + + + + + FAILED: REQUIRE( std::string( "first" ) == "second" ) @@ -1663,51 +1679,51 @@ Tricky.tests.cpp: - - - - - - - - - - - - + + + + + + + + + + + + FAILED: Why would you throw a std::string? Exception.tests.cpp: - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + This would not be caught previously A string sent directly to stdout diff -Nru catch2-2.12.1/projects/SelfTest/Baselines/sonarqube.sw.approved.txt catch2-2.13.0/projects/SelfTest/Baselines/sonarqube.sw.approved.txt --- catch2-2.12.1/projects/SelfTest/Baselines/sonarqube.sw.approved.txt 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/projects/SelfTest/Baselines/sonarqube.sw.approved.txt 2020-07-12 18:28:38.000000000 +0000 @@ -99,6 +99,15 @@ + + + + + + + + + @@ -875,6 +884,8 @@ + + @@ -900,6 +911,8 @@ + + FAILED: @@ -1350,6 +1363,9 @@ + + + FAILED: diff -Nru catch2-2.12.1/projects/SelfTest/Baselines/xml.sw.approved.txt catch2-2.13.0/projects/SelfTest/Baselines/xml.sw.approved.txt --- catch2-2.12.1/projects/SelfTest/Baselines/xml.sw.approved.txt 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/projects/SelfTest/Baselines/xml.sw.approved.txt 2020-07-12 18:28:38.000000000 +0000 @@ -264,6 +264,405 @@ + + + + counter < 7 + + + 3 < 7 + + + + + counter < 7 + + + 6 < 7 + + + + + + + + i != j + + + 1 != 3 + + + + + i != j + + + 1 != 4 + + + + + i != j + + + 2 != 3 + + + + + i != j + + + 2 != 4 + + + + + +
+ +
+
+ + + m + + + 1 + + + +
+
+ + + m + + + 2 + + + +
+
+ + + m + + + 3 + + + +
+ +
+ +
+ + + 1 + + + 1 + + + +
+ + + m + + + 2 + + + + + m + + + 3 + + + +
+ + + + m + + + 1 + + + + + m + + + 2 + + + + + m + + + 3 + + + + + +
+ +
+ + i := 1 + + + j := 3 + + + k := 5 + +
+ +
+ + i := 1 + + + j := 3 + + + k := 6 + +
+ +
+ + i := 1 + + + j := 4 + + + k := 5 + + + i := 1 + + + j := 4 + + + k := 6 + +
+ +
+ + i := 2 + + + j := 3 + + + k := 5 + +
+ +
+ + i := 2 + + + j := 3 + + + k := 6 + +
+ +
+ + i := 2 + + + j := 4 + + + k := 5 + + + i := 2 + + + j := 4 + + + k := 6 + + +
+ + + + m + + + 1 + + + + + n + + + 1 + + + + + m + + + 1 + + + + + n + + + 2 + + + + + m + + + 1 + + + + + n + + + 3 + + + + + m + + + 2 + + + + + n + + + 1 + + + + + m + + + 2 + + + + + n + + + 2 + + + + + m + + + 2 + + + + + n + + + 3 + + + + + m + + + 3 + + + + + n + + + 1 + + + + + m + + + 3 + + + + + n + + + 2 + + + + + m + + + 3 + + + + + n + + + 3 + + + + + + + + + + + + +
@@ -2962,6 +3361,63 @@ + +
+ + + 1, !(first && second) + + + 1 not ( CheckedTestingMatcher set to fail and CheckedTestingMatcher set to fail ) + + + + + first.matchCalled + + + true + + + + + !second.matchCalled + + + true + + + +
+
+ + + 1, first || second + + + 1 ( CheckedTestingMatcher set to succeed or CheckedTestingMatcher set to fail ) + + + + + first.matchCalled + + + true + + + + + !second.matchCalled + + + true + + + +
+ +
@@ -16255,7 +16711,9 @@
- + + - + + diff -Nru catch2-2.12.1/projects/SelfTest/IntrospectiveTests/PartTracker.tests.cpp catch2-2.13.0/projects/SelfTest/IntrospectiveTests/PartTracker.tests.cpp --- catch2-2.12.1/projects/SelfTest/IntrospectiveTests/PartTracker.tests.cpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/projects/SelfTest/IntrospectiveTests/PartTracker.tests.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -204,3 +204,50 @@ SECTION("2") SUCCEED(); } } + +// #1938 required a rework on how generator tracking works, so that `GENERATE` +// supports being sandwiched between two `SECTION`s. The following tests check +// various other scenarios through checking output in approval tests. +TEST_CASE("#1938 - GENERATE after a section", "[.][regression][generators]") { + SECTION("A") { + SUCCEED("A"); + } + auto m = GENERATE(1, 2, 3); + SECTION("B") { + REQUIRE(m); + } +} + +TEST_CASE("#1938 - flat generate", "[.][regression][generators]") { + auto m = GENERATE(1, 2, 3); + REQUIRE(m); +} + +TEST_CASE("#1938 - nested generate", "[.][regression][generators]") { + auto m = GENERATE(1, 2, 3); + auto n = GENERATE(1, 2, 3); + REQUIRE(m); + REQUIRE(n); +} + +TEST_CASE("#1938 - mixed sections and generates", "[.][regression][generators]") { + auto i = GENERATE(1, 2); + SECTION("A") { + SUCCEED("A"); + } + auto j = GENERATE(3, 4); + SECTION("B") { + SUCCEED("B"); + } + auto k = GENERATE(5, 6); + CAPTURE(i, j, k); + SUCCEED(); +} + +TEST_CASE("#1938 - Section followed by flat generate", "[.][regression][generators]") { + SECTION("A") { + REQUIRE(1); + } + auto m = GENERATE(2, 3); + REQUIRE(m); +} diff -Nru catch2-2.12.1/projects/SelfTest/TimingTests/Sleep.tests.cpp catch2-2.13.0/projects/SelfTest/TimingTests/Sleep.tests.cpp --- catch2-2.12.1/projects/SelfTest/TimingTests/Sleep.tests.cpp 1970-01-01 00:00:00.000000000 +0000 +++ catch2-2.13.0/projects/SelfTest/TimingTests/Sleep.tests.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -0,0 +1,23 @@ +/* + * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include "catch.hpp" + +#include +#include + +TEST_CASE( "sleep_for_100ms", "[.min_duration_test][approvals]" ) +{ + std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + CHECK( true ); +} + +TEST_CASE( "sleep_for_250ms", "[.min_duration_test][approvals]" ) +{ + std::this_thread::sleep_for( std::chrono::milliseconds( 250 ) ); + CHECK( true ); +} diff -Nru catch2-2.12.1/projects/SelfTest/UsageTests/Generators.tests.cpp catch2-2.13.0/projects/SelfTest/UsageTests/Generators.tests.cpp --- catch2-2.12.1/projects/SelfTest/UsageTests/Generators.tests.cpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/projects/SelfTest/UsageTests/Generators.tests.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -251,6 +251,23 @@ } } +TEST_CASE("#1913 - GENERATE inside a for loop should not keep recreating the generator", "[regression][generators]") { + static int counter = 0; + for (int i = 0; i < 3; ++i) { + int _ = GENERATE(1, 2); + (void)_; + ++counter; + } + // There should be at most 6 (3 * 2) counter increments + REQUIRE(counter < 7); +} + +TEST_CASE("#1913 - GENERATEs can share a line", "[regression][generators]") { + int i = GENERATE(1, 2); int j = GENERATE(3, 4); + REQUIRE(i != j); +} + + #if defined(__clang__) #pragma clang diagnostic pop #endif diff -Nru catch2-2.12.1/projects/SelfTest/UsageTests/Matchers.tests.cpp catch2-2.13.0/projects/SelfTest/UsageTests/Matchers.tests.cpp --- catch2-2.12.1/projects/SelfTest/UsageTests/Matchers.tests.cpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/projects/SelfTest/UsageTests/Matchers.tests.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -628,6 +628,45 @@ REQUIRE_THAT(testStringForMatching2(), composed2); } + struct CheckedTestingMatcher : Catch::MatcherBase { + mutable bool matchCalled = false; + bool matchSucceeds = false; + + bool match(int const&) const override { + matchCalled = true; + return matchSucceeds; + } + std::string describe() const override { + return "CheckedTestingMatcher set to " + (matchSucceeds ? std::string("succeed") : std::string("fail")); + } + }; + + TEST_CASE("Composed matchers shortcircuit", "[matchers][composed]") { + // Check that if first returns false, second is not touched + CheckedTestingMatcher first, second; + SECTION("&&") { + first.matchSucceeds = false; + // This assertion doesn't actually test anything, we just + // want the composed matcher's `match` being called. + CHECK_THAT(1, !(first && second)); + + // These two assertions are the important ones + REQUIRE(first.matchCalled); + REQUIRE(!second.matchCalled); + } + // Check that if first returns true, second is not touched + SECTION("||") { + first.matchSucceeds = true; + // This assertion doesn't actually test anything, we just + // want the composed matcher's `match` being called. + CHECK_THAT(1, first || second); + + // These two assertions are the important ones + REQUIRE(first.matchCalled); + REQUIRE(!second.matchCalled); + } + } + } } // namespace MatchersTests #endif // CATCH_CONFIG_DISABLE_MATCHERS diff -Nru catch2-2.12.1/projects/SelfTest/UsageTests/Misc.tests.cpp catch2-2.13.0/projects/SelfTest/UsageTests/Misc.tests.cpp --- catch2-2.12.1/projects/SelfTest/UsageTests/Misc.tests.cpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/projects/SelfTest/UsageTests/Misc.tests.cpp 2020-07-12 18:28:38.000000000 +0000 @@ -484,4 +484,10 @@ SUCCEED(); } +TEMPLATE_TEST_CASE_SIG("#1954 - 7 arg template test case sig compiles", "[regression][.compilation]", + ((int Tnx, int Tnu, int Tny, int Tph, int Tch, int Tineq, int Teq), Tnx, Tnu, Tny, Tph, Tch, Tineq, Teq), + (1, 1, 1, 1, 1, 0, 0), (5, 1, 1, 1, 1, 0, 0), (5, 3, 1, 1, 1, 0, 0)) { + SUCCEED(); +} + }} // namespace MiscTests diff -Nru catch2-2.12.1/projects/TestScripts/testRandomOrder.py catch2-2.13.0/projects/TestScripts/testRandomOrder.py --- catch2-2.12.1/projects/TestScripts/testRandomOrder.py 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/projects/TestScripts/testRandomOrder.py 2020-07-12 18:28:38.000000000 +0000 @@ -15,9 +15,9 @@ def list_tests(self_test_exe, tags, rng_seed): cmd = [self_test_exe, '--list-test-names-only', '--order', 'rand', '--rng-seed', str(rng_seed)] - tags_arg = ','.join('[{}]'.format(t) for t in tags) + tags_arg = ','.join('[{}]~[.]'.format(t) for t in tags) if tags_arg: - cmd.append(tags_arg + '~[.]') + cmd.append(tags_arg) process = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = process.communicate() diff -Nru catch2-2.12.1/README.md catch2-2.13.0/README.md --- catch2-2.12.1/README.md 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/README.md 2020-07-12 18:28:38.000000000 +0000 @@ -5,11 +5,11 @@ [![Build Status](https://travis-ci.org/catchorg/Catch2.svg?branch=master)](https://travis-ci.org/catchorg/Catch2) [![Build status](https://ci.appveyor.com/api/projects/status/github/catchorg/Catch2?svg=true)](https://ci.appveyor.com/project/catchorg/catch2) [![codecov](https://codecov.io/gh/catchorg/Catch2/branch/master/graph/badge.svg)](https://codecov.io/gh/catchorg/Catch2) -[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/DQL97fLLJLZXwB8d) +[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/aavJBzemrxUgGV9S) [![Join the chat in Discord: https://discord.gg/4CWS9zD](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/4CWS9zD) -The latest version of the single header can be downloaded directly using this link +The latest version of the single header can be downloaded directly using this link ## Catch2 is released! diff -Nru catch2-2.12.1/single_include/catch2/catch.hpp catch2-2.13.0/single_include/catch2/catch.hpp --- catch2-2.12.1/single_include/catch2/catch.hpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/single_include/catch2/catch.hpp 2020-07-12 18:28:38.000000000 +0000 @@ -1,6 +1,6 @@ /* - * Catch v2.12.1 - * Generated: 2020-04-21 19:29:20.964532 + * Catch v2.13.0 + * Generated: 2020-07-12 20:07:49.015950 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly * Copyright (c) 2020 Two Blue Cubes Ltd. All rights reserved. @@ -14,8 +14,8 @@ #define CATCH_VERSION_MAJOR 2 -#define CATCH_VERSION_MINOR 12 -#define CATCH_VERSION_PATCH 1 +#define CATCH_VERSION_MINOR 13 +#define CATCH_VERSION_PATCH 0 #ifdef __clang__ # pragma clang system_header @@ -163,7 +163,7 @@ // // Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. # if !defined(__ibmxl__) -# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg) */ +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ # endif # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ @@ -775,7 +775,7 @@ #define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3) #define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4) #define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5) -#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _4, _5, _6) +#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6) #define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7) #define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8) #define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9) @@ -944,13 +944,13 @@ #if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703 // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is - // replaced with std::invoke_result here. Also *_t format is preferred over - // typename *::type format. - template - using FunctionReturnType = std::remove_reference_t>>; + // replaced with std::invoke_result here. + template + using FunctionReturnType = std::remove_reference_t>>; #else - template - using FunctionReturnType = typename std::remove_reference::type>::type>::type; + // Keep ::type here because we still support C++11 + template + using FunctionReturnType = typename std::remove_reference::type>::type>::type; #endif } // namespace Catch @@ -1988,20 +1988,27 @@ #endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER namespace Catch { - struct not_this_one {}; // Tag type for detecting which begin/ end are being selected - - // Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace + // Import begin/ end from std here using std::begin; using std::end; - not_this_one begin( ... ); - not_this_one end( ... ); + namespace detail { + template + struct void_type { + using type = void; + }; + + template + struct is_range_impl : std::false_type { + }; + + template + struct is_range_impl()))>::type> : std::true_type { + }; + } // namespace detail template - struct is_range { - static const bool value = - !std::is_same())), not_this_one>::value && - !std::is_same())), not_this_one>::value; + struct is_range : detail::is_range_impl { }; #if defined(_MANAGED) // Managed types are never ranges @@ -2461,7 +2468,7 @@ virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0; virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0; - virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0; + virtual auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0; #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) virtual void benchmarkPreparing( std::string const& name ) = 0; @@ -3714,8 +3721,6 @@ struct UnorderedEqualsMatcher : MatcherBase> { UnorderedEqualsMatcher(std::vector const& target) : m_target(target) {} bool match(std::vector const& vec) const override { - // Note: This is a reimplementation of std::is_permutation, - // because I don't want to include inside the common path if (m_target.size() != vec.size()) { return false; } @@ -4075,16 +4080,16 @@ return makeGenerators( value( T( std::forward( val ) ) ), std::forward( moreGenerators )... ); } - auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&; + auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker&; template // Note: The type after -> is weird, because VS2015 cannot parse // the expression used in the typedef inside, when it is in // return type. Yeah. - auto generate( SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval().get()) { + auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval().get()) { using UnderlyingType = typename decltype(generatorExpression())::type; - IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo ); + IGeneratorTracker& tracker = acquireGeneratorTracker( generatorName, lineInfo ); if (!tracker.hasGenerator()) { tracker.setGenerator(pf::make_unique>(generatorExpression())); } @@ -4097,11 +4102,17 @@ } // namespace Catch #define GENERATE( ... ) \ - Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) + Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \ + CATCH_INTERNAL_LINEINFO, \ + [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) #define GENERATE_COPY( ... ) \ - Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) + Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \ + CATCH_INTERNAL_LINEINFO, \ + [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) #define GENERATE_REF( ... ) \ - Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) + Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \ + CATCH_INTERNAL_LINEINFO, \ + [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) // end catch_generators.hpp // start catch_generators_generic.hpp @@ -4511,6 +4522,7 @@ virtual int abortAfter() const = 0; virtual bool showInvisibles() const = 0; virtual ShowDurations::OrNot showDurations() const = 0; + virtual double minDuration() const = 0; virtual TestSpec const& testSpec() const = 0; virtual bool hasTestFilters() const = 0; virtual std::vector const& getTestsOrTags() const = 0; @@ -5283,6 +5295,7 @@ Verbosity verbosity = Verbosity::Normal; WarnAbout::What warnings = WarnAbout::Nothing; ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter; + double minDuration = -1; RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder; UseColour::YesOrNo useColour = UseColour::Auto; WaitForKeypress::When waitForKeypress = WaitForKeypress::Never; @@ -5333,6 +5346,7 @@ bool warnAboutMissingAssertions() const override; bool warnAboutNoTests() const override; ShowDurations::OrNot showDurations() const override; + double minDuration() const override; RunTests::InWhatOrder runOrder() const override; unsigned int rngSeed() const override; UseColour::YesOrNo useColour() const override; @@ -5710,6 +5724,9 @@ // Returns double formatted as %.3f (format expected on output) std::string getFormattedDuration( double duration ); + //! Should the reporter show + bool shouldShowDuration( IConfig const& config, double duration ); + std::string serializeFilters( std::vector const& container ); template @@ -6103,8 +6120,6 @@ static std::string getDescription(); - ReporterPreferences getPreferences() const override; - void noMatchingTestCases(std::string const& spec) override; void assertionStarting(AssertionInfo const&) override; @@ -6552,20 +6567,18 @@ return {}; } }; - template - using ResultOf_t = typename std::result_of::type; // invoke and not return void :( template - CompleteType_t> complete_invoke(Fun&& fun, Args&&... args) { - return CompleteInvoker>::invoke(std::forward(fun), std::forward(args)...); + CompleteType_t> complete_invoke(Fun&& fun, Args&&... args) { + return CompleteInvoker>::invoke(std::forward(fun), std::forward(args)...); } const std::string benchmarkErrorMsg = "a benchmark failed to run successfully"; } // namespace Detail template - Detail::CompleteType_t> user_code(Fun&& fun) { + Detail::CompleteType_t> user_code(Fun&& fun) { CATCH_TRY{ return Detail::complete_invoke(std::forward(fun)); } CATCH_CATCH_ALL{ @@ -6810,8 +6823,8 @@ Result result; int iterations; }; - template - using TimingOf = Timing, Detail::CompleteType_t>>; + template + using TimingOf = Timing, Detail::CompleteType_t>>; } // namespace Benchmark } // namespace Catch @@ -6822,7 +6835,7 @@ namespace Benchmark { namespace Detail { template - TimingOf measure(Fun&& fun, Args&&... args) { + TimingOf measure(Fun&& fun, Args&&... args) { auto start = Clock::now(); auto&& r = Detail::complete_invoke(fun, std::forward(args)...); auto end = Clock::now(); @@ -6841,11 +6854,11 @@ namespace Benchmark { namespace Detail { template - TimingOf measure_one(Fun&& fun, int iters, std::false_type) { + TimingOf measure_one(Fun&& fun, int iters, std::false_type) { return Detail::measure(fun, iters); } template - TimingOf measure_one(Fun&& fun, int iters, std::true_type) { + TimingOf measure_one(Fun&& fun, int iters, std::true_type) { Detail::ChronometerModel meter; auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters)); @@ -6862,7 +6875,7 @@ }; template - TimingOf)> run_for_at_least(ClockDuration how_long, int seed, Fun&& fun) { + TimingOf> run_for_at_least(ClockDuration how_long, int seed, Fun&& fun) { auto iters = seed; while (iters < (1 << 30)) { auto&& Timing = measure_one(fun, iters, is_callable()); @@ -7460,23 +7473,37 @@ SourceLineInfo location; NameAndLocation( std::string const& _name, SourceLineInfo const& _location ); + friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) { + return lhs.name == rhs.name + && lhs.location == rhs.location; + } }; - struct ITracker; + class ITracker; using ITrackerPtr = std::shared_ptr; - struct ITracker { - virtual ~ITracker(); + class ITracker { + NameAndLocation m_nameAndLocation; + + public: + ITracker(NameAndLocation const& nameAndLoc) : + m_nameAndLocation(nameAndLoc) + {} // static queries - virtual NameAndLocation const& nameAndLocation() const = 0; + NameAndLocation const& nameAndLocation() const { + return m_nameAndLocation; + } + + virtual ~ITracker(); // dynamic queries virtual bool isComplete() const = 0; // Successfully completed or failed virtual bool isSuccessfullyCompleted() const = 0; virtual bool isOpen() const = 0; // Started but not complete virtual bool hasChildren() const = 0; + virtual bool hasStarted() const = 0; virtual ITracker& parent() = 0; @@ -7531,7 +7558,6 @@ }; using Children = std::vector; - NameAndLocation m_nameAndLocation; TrackerContext& m_ctx; ITracker* m_parent; Children m_children; @@ -7540,11 +7566,13 @@ public: TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); - NameAndLocation const& nameAndLocation() const override; bool isComplete() const override; bool isSuccessfullyCompleted() const override; bool isOpen() const override; bool hasChildren() const override; + bool hasStarted() const override { + return m_runState != NotStarted; + } void addChild( ITrackerPtr const& child ) override; @@ -7907,7 +7935,11 @@ #ifdef CATCH_PLATFORM_MAC - #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */ + #if defined(__i386__) || defined(__x86_64__) + #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */ + #elif defined(__aarch64__) + #define CATCH_TRAP() __asm__(".inst 0xd4200000") + #endif #elif defined(CATCH_PLATFORM_IPHONE) @@ -8092,7 +8124,7 @@ void sectionEnded( SectionEndInfo const& endInfo ) override; void sectionEndedEarly( SectionEndInfo const& endInfo ) override; - auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override; + auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override; #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) void benchmarkPreparing( std::string const& name ) override; @@ -9068,7 +9100,7 @@ } inline auto convertInto( std::string const &source, bool &target ) -> ParserResult { std::string srcLC = source; - std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast( std::tolower(c) ); } ); + std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( unsigned char c ) { return static_cast( std::tolower(c) ); } ); if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on") target = true; else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off") @@ -9837,6 +9869,9 @@ | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" ) ["-d"]["--durations"] ( "show test durations" ) + | Opt( config.minDuration, "seconds" ) + ["-D"]["--min-duration"] + ( "show test durations for tests taking at least the given number of seconds" ) | Opt( loadTestNamesFromFile, "filename" ) ["-f"]["--input-file"] ( "load test names to run from a file" ) @@ -9984,6 +10019,7 @@ bool Config::warnAboutMissingAssertions() const { return !!(m_data.warnings & WarnAbout::NoAssertions); } bool Config::warnAboutNoTests() const { return !!(m_data.warnings & WarnAbout::NoTests); } ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; } + double Config::minDuration() const { return m_data.minDuration; } RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; } unsigned int Config::rngSeed() const { return m_data.rngSeed; } UseColour::YesOrNo Config::useColour() const { return m_data.useColour; } @@ -10880,8 +10916,8 @@ GeneratorUntypedBase::~GeneratorUntypedBase() {} - auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& { - return getResultCapture().acquireGeneratorTracker( lineInfo ); + auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& { + return getResultCapture().acquireGeneratorTracker( generatorName, lineInfo ); } } // namespace Generators @@ -11768,10 +11804,10 @@ Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) { auto trimmed = [&] (size_t start, size_t end) { - while (names[start] == ',' || isspace(names[start])) { + while (names[start] == ',' || isspace(static_cast(names[start]))) { ++start; } - while (names[end] == ',' || isspace(names[end])) { + while (names[end] == ',' || isspace(static_cast(names[end]))) { --end; } return names.substr(start, end - start + 1); @@ -12301,11 +12337,13 @@ namespace Catch { class StartupExceptionRegistry { +#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) public: void add(std::exception_ptr const& exception) noexcept; std::vector const& getExceptions() const noexcept; private: std::vector m_exceptions; +#endif }; } // end namespace Catch @@ -12388,7 +12426,11 @@ m_tagAliasRegistry.add( alias, tag, lineInfo ); } void registerStartupException() noexcept override { +#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) m_exceptionRegistry.add(std::current_exception()); +#else + CATCH_INTERNAL_ERROR("Attempted to register active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!"); +#endif } IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override { return m_enumValuesRegistry; @@ -12492,17 +12534,32 @@ std::shared_ptr tracker; ITracker& currentTracker = ctx.currentTracker(); - if( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) { + // Under specific circumstances, the generator we want + // to acquire is also the current tracker. If this is + // the case, we have to avoid looking through current + // tracker's children, and instead return the current + // tracker. + // A case where this check is important is e.g. + // for (int i = 0; i < 5; ++i) { + // int n = GENERATE(1, 2); + // } + // + // without it, the code above creates 5 nested generators. + if (currentTracker.nameAndLocation() == nameAndLocation) { + auto thisTracker = currentTracker.parent().findChild(nameAndLocation); + assert(thisTracker); + assert(thisTracker->isGeneratorTracker()); + tracker = std::static_pointer_cast(thisTracker); + } else if ( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) { assert( childTracker ); assert( childTracker->isGeneratorTracker() ); tracker = std::static_pointer_cast( childTracker ); - } - else { + } else { tracker = std::make_shared( nameAndLocation, ctx, ¤tTracker ); currentTracker.addChild( tracker ); } - if( !ctx.completedCycle() && !tracker->isComplete() ) { + if( !tracker->isComplete() ) { tracker->open(); } @@ -12516,8 +12573,28 @@ } void close() override { TrackerBase::close(); - // Generator interface only finds out if it has another item on atual move - if (m_runState == CompletedSuccessfully && m_generator->next()) { + // If a generator has a child (it is followed by a section) + // and none of its children have started, then we must wait + // until later to start consuming its values. + // This catches cases where `GENERATE` is placed between two + // `SECTION`s. + // **The check for m_children.empty cannot be removed**. + // doing so would break `GENERATE` _not_ followed by `SECTION`s. + const bool should_wait_for_child = + !m_children.empty() && + std::find_if( m_children.begin(), + m_children.end(), + []( TestCaseTracking::ITrackerPtr tracker ) { + return tracker->hasStarted(); + } ) == m_children.end(); + + // This check is a bit tricky, because m_generator->next() + // has a side-effect, where it consumes generator's current + // value, but we do not want to invoke the side-effect if + // this generator is still waiting for any child to start. + if ( should_wait_for_child || + ( m_runState == CompletedSuccessfully && + m_generator->next() ) ) { m_children.clear(); m_runState = Executing; } @@ -12653,10 +12730,10 @@ return true; } - auto RunContext::acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& { + auto RunContext::acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& { using namespace Generators; - GeneratorTracker& tracker = GeneratorTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( "generator", lineInfo ) ); - assert( tracker.isOpen() ); + GeneratorTracker& tracker = GeneratorTracker::acquire(m_trackerContext, + TestCaseTracking::NameAndLocation( static_cast(generatorName), lineInfo ) ); m_lastAssertionInfo.lineInfo = lineInfo; return tracker; } @@ -12699,17 +12776,17 @@ #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) void RunContext::benchmarkPreparing(std::string const& name) { - m_reporter->benchmarkPreparing(name); - } + m_reporter->benchmarkPreparing(name); + } void RunContext::benchmarkStarting( BenchmarkInfo const& info ) { m_reporter->benchmarkStarting( info ); } void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) { m_reporter->benchmarkEnded( stats ); } - void RunContext::benchmarkFailed(std::string const & error) { - m_reporter->benchmarkFailed(error); - } + void RunContext::benchmarkFailed(std::string const & error) { + m_reporter->benchmarkFailed(error); + } #endif // CATCH_CONFIG_ENABLE_BENCHMARKING void RunContext::pushScopedMessage(MessageInfo const & message) { @@ -13430,6 +13507,7 @@ // end catch_singletons.cpp // start catch_startup_exception_registry.cpp +#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) namespace Catch { void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept { CATCH_TRY { @@ -13445,6 +13523,7 @@ } } // end namespace Catch +#endif // end catch_startup_exception_registry.cpp // start catch_stream.cpp @@ -13629,7 +13708,7 @@ namespace { char toLowerCh(char c) { - return static_cast( std::tolower( c ) ); + return static_cast( std::tolower( static_cast(c) ) ); } } @@ -14212,15 +14291,12 @@ m_currentTracker = tracker; } - TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) - : m_nameAndLocation( nameAndLocation ), + TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ): + ITracker(nameAndLocation), m_ctx( ctx ), m_parent( parent ) {} - NameAndLocation const& TrackerBase::nameAndLocation() const { - return m_nameAndLocation; - } bool TrackerBase::isComplete() const { return m_runState == CompletedSuccessfully || m_runState == Failed; } @@ -14336,7 +14412,8 @@ bool SectionTracker::isComplete() const { bool complete = true; - if ((m_filters.empty() || m_filters[0] == "") + if (m_filters.empty() + || m_filters[0] == "" || std::find(m_filters.begin(), m_filters.end(), m_trimmed_name) != m_filters.end()) { complete = TrackerBase::isComplete(); } @@ -15119,7 +15196,9 @@ namespace Catch { bool uncaught_exceptions() { -#if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) +#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) + return false; +#elif defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) return std::uncaught_exceptions() > 0; #else return std::uncaught_exception(); @@ -15159,7 +15238,7 @@ } Version const& libraryVersion() { - static Version version( 2, 12, 1, "", 0 ); + static Version version( 2, 13, 0, "", 0 ); return version; } @@ -15561,6 +15640,17 @@ return std::string(buffer); } + bool shouldShowDuration( IConfig const& config, double duration ) { + if ( config.showDurations() == ShowDurations::Always ) { + return true; + } + if ( config.showDurations() == ShowDurations::Never ) { + return false; + } + const double min = config.minDuration(); + return min >= 0 && duration >= min; + } + std::string serializeFilters( std::vector const& container ) { ReusableStringStream oss; bool first = true; @@ -15827,10 +15917,6 @@ return "Reports test results on a single line, suitable for IDEs"; } - ReporterPreferences CompactReporter::getPreferences() const { - return m_reporterPrefs; - } - void CompactReporter::noMatchingTestCases( std::string const& spec ) { stream << "No test cases matched '" << spec << '\'' << std::endl; } @@ -15857,8 +15943,9 @@ } void CompactReporter::sectionEnded(SectionStats const& _sectionStats) { - if (m_config->showDurations() == ShowDurations::Always) { - stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl; + double dur = _sectionStats.durationInSeconds; + if ( shouldShowDuration( *m_config, dur ) ) { + stream << getFormattedDuration( dur ) << " s: " << _sectionStats.sectionInfo.name << std::endl; } } @@ -16278,8 +16365,9 @@ stream << "\nNo assertions in test case"; stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl; } - if (m_config->showDurations() == ShowDurations::Always) { - stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl; + double dur = _sectionStats.durationInSeconds; + if (shouldShowDuration(*m_config, dur)) { + stream << getFormattedDuration(dur) << " s: " << _sectionStats.sectionInfo.name << std::endl; } if (m_headerPrinted) { m_headerPrinted = false; @@ -16738,6 +16826,11 @@ xml.writeAttribute( "name", name ); } xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) ); + // This is not ideal, but it should be enough to mimic gtest's + // junit output. + // Ideally the JUnit reporter would also handle `skipTest` + // events and write those out appropriately. + xml.writeAttribute( "status", "run" ); writeAssertions( sectionNode ); @@ -17172,6 +17265,10 @@ .writeAttribute( "successes", testGroupStats.totals.assertions.passed ) .writeAttribute( "failures", testGroupStats.totals.assertions.failed ) .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk ); + m_xml.scopedElement( "OverallResultsCases") + .writeAttribute( "successes", testGroupStats.totals.testCases.passed ) + .writeAttribute( "failures", testGroupStats.totals.testCases.failed ) + .writeAttribute( "expectedFailures", testGroupStats.totals.testCases.failedButOk ); m_xml.endElement(); } @@ -17181,6 +17278,10 @@ .writeAttribute( "successes", testRunStats.totals.assertions.passed ) .writeAttribute( "failures", testRunStats.totals.assertions.failed ) .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk ); + m_xml.scopedElement( "OverallResultsCases") + .writeAttribute( "successes", testRunStats.totals.testCases.passed ) + .writeAttribute( "failures", testRunStats.totals.testCases.failed ) + .writeAttribute( "expectedFailures", testRunStats.totals.testCases.failedButOk ); m_xml.endElement(); } diff -Nru catch2-2.12.1/single_include/catch2/catch_reporter_tap.hpp catch2-2.13.0/single_include/catch2/catch_reporter_tap.hpp --- catch2-2.12.1/single_include/catch2/catch_reporter_tap.hpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/single_include/catch2/catch_reporter_tap.hpp 2020-07-12 18:28:38.000000000 +0000 @@ -23,16 +23,17 @@ using StreamingReporterBase::StreamingReporterBase; + TAPReporter( ReporterConfig const& config ): + StreamingReporterBase( config ) { + m_reporterPrefs.shouldReportAllAssertions = true; + } + ~TAPReporter() override; static std::string getDescription() { return "Reports test results in TAP format, suitable for test harnesses"; } - ReporterPreferences getPreferences() const override { - return m_reporterPrefs; - } - void noMatchingTestCases( std::string const& spec ) override { stream << "# No test cases matched '" << spec << "'" << std::endl; } @@ -203,16 +204,15 @@ return; } - // using messages.end() directly (or auto) yields compilation error: - std::vector::const_iterator itEnd = messages.end(); - const std::size_t N = static_cast( std::distance( itMessage, itEnd ) ); + const auto itEnd = messages.cend(); + const auto N = static_cast( std::distance( itMessage, itEnd ) ); { Colour colourGuard( colour ); stream << " with " << pluralise( N, "message" ) << ":"; } - for(; itMessage != itEnd; ) { + while( itMessage != itEnd ) { // If this assertion is a warning ignore any INFO messages if( printInfoMessages || itMessage->type != ResultWas::Info ) { stream << " '" << itMessage->message << "'"; @@ -220,7 +220,9 @@ Colour colourGuard( dimColour() ); stream << " and"; } + continue; } + ++itMessage; } } @@ -234,10 +236,9 @@ }; void printTotals( const Totals& totals ) const { + stream << "1.." << totals.assertions.total(); if( totals.testCases.total() == 0 ) { - stream << "1..0 # Skipped: No tests ran."; - } else { - stream << "1.." << counter; + stream << " # Skipped: No tests ran."; } } }; diff -Nru catch2-2.12.1/third_party/clara.hpp catch2-2.13.0/third_party/clara.hpp --- catch2-2.12.1/third_party/clara.hpp 2020-04-21 17:30:38.000000000 +0000 +++ catch2-2.13.0/third_party/clara.hpp 2020-07-12 18:28:38.000000000 +0000 @@ -667,7 +667,7 @@ } inline auto convertInto( std::string const &source, bool &target ) -> ParserResult { std::string srcLC = source; - std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast( ::tolower(c) ); } ); + std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( unsigned char c ) { return static_cast( ::tolower( c ) ); } ); if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on") target = true; else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")