Compare commits

...

237 Commits

Author SHA1 Message Date
Benoit Blanchon
908c370f24 Fix error: ISO C++ forbids in-class initialization of non-const static member 'm_started' 2023-01-18 11:10:26 +01:00
Golubchikov Mihail
6c6cfe126a Backport fix for SIGSTKSZ 2022-07-15 16:13:12 +02:00
Martin Hořeňovský
72df457bab Merge pull request #2151 from fxcoudert/patch-1
Update catch_debugger.h for Apple Silicon
2021-01-13 18:16:54 +01:00
FX Coudert
bb6d08323f Update catch_debugger.h 2021-01-11 12:22:22 +01:00
Vadim Zeitlin
64a533551d Enable variadic macros support for MSVS 2005 as it has them
Fix the test for MSVC version: variadic macros support is available
since MSVS 2005, a.k.a. MSVC 8, using _MSC_VER=1400.
2019-09-06 11:45:32 +02:00
Mapping Suite
c32f275a00 Fix link to catch.hpp in tutorial.md 2018-12-18 18:19:29 +01:00
Martin Hořeňovský
6860c8def0 v1.12.2 2018-05-14 15:15:28 +02:00
Martin Hořeňovský
3255ee6312 Add missing <cassert> includes
Until recently we were probably getting it from some transitive
include, but it broke. Because all files should include what
they use anyway, adding `#include <cassert>` to all files that
use `assert()` without including it is the best solution.

Fixes #1249
2018-04-22 20:36:41 +02:00
Martin Hořeňovský
74effafca7 v1.12.1 2018-03-02 21:22:10 +01:00
Martin Hořeňovský
7d0cfd27ce Fix deprecation warning in ~ScopedMessage 2018-02-25 21:29:01 +01:00
Martin Hořeňovský
3fe4d394a5 Wrap all uses in min and max in extra parentheses
This prevents `min` and `max` macros from windows headers (!@#$)
from breaking compilation.

Related to #1191
2018-02-23 13:06:52 +01:00
Martin Hořeňovský
b97e9a2f8b Update path for catch-classic vcpkg's portfile 2018-01-12 11:06:09 +01:00
Martin Hořeňovský
34f7cfe046 v1.12.0 2018-01-12 09:59:21 +01:00
Martin Hořeňovský
07b9bda1d2 Revert backport of new evaluate layer to fix C++98 compilation
The backport fixed some bugs (ie #981), but caused strict C++98
(and MSVC 9) compilers to fail. This means that we will
reintroduce some issues but get back compatibility with obsolete
compilers. People using newer ones can keep using Catch2.

This reverts commit b6e7c9bd7a.
This reverts commit b7bd52cc98.

Should fix #1103
2017-12-07 20:02:47 +01:00
Phil Nash
84e8b696b1 Include Info messages in xml reporter even without -s 2017-12-06 16:11:12 +00:00
Pfiffikus
2d91035404 Update assertions.md
scale more detailed explained; have to be adapted to PR #1068 if necessary
2017-11-01 13:32:08 +01:00
Martin Hořeňovský
2a3606f8e3 v1.11.0 2017-10-31 13:55:48 +01:00
Martin Hořeňovský
a6cf19abff Make Approx::margin inclusive
Fixes #952, related to #980
2017-10-30 21:33:29 +01:00
Pfiffikus
06586b7180 Update test-cases-and-sections.md
some clarification and typo correction
2017-10-26 13:57:18 +02:00
Clare Macrae
93b3d2cb8f Fix very minor typo
it's -> its
2017-10-24 20:00:27 +02:00
Pfiffikus
a90473df28 Update build-systems.md
typo correction
2017-10-24 19:59:59 +02:00
Sebastian Grottel
c9d9699ca8 adds flushes to the output stream of teamcity reporter, making the test output more responsive. 2017-10-17 16:42:05 +02:00
Sebastian Grottel
296955c437 RandomNumberGenerator::result_type should be unsigned (#1050)
`result_type` must be unsigned:
http://en.cppreference.com/w/cpp/concept/UniformRandomBitGenerator

Using a signed type causes an infinite loop working with MS Visual Studio 2017, targetting: v140, WindowsTargetPlatformVersion 10.0.15063.0, Debug, x64
2017-10-15 18:30:40 +02:00
dvirtz
664cbf702c added PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS option 2017-10-15 17:58:39 +02:00
Martin Hořeňovský
fb6700df54 Fix documentation crosslink in configuration.md 2017-10-14 08:36:44 +02:00
Phil Nash
da6c2a6914 Fixed expansion of _FALSE binary expression
- see #1051
2017-10-13 19:44:20 +01:00
Dmitry Kozhevnikov
9c07718b5f Update handling of __JETBRAINS_IDE__ macro
1. Use it to conditionally define CATCH_INTERNAL_CONFIG_COUNTER, not
   CATCH_CONFIG_COUNTER, as __JETBRAINS_IDE__ is similar to
   compiler-provided macros, not to user-provided ones.

2. Since __COUNTER__ will work starting with CLion 2017.3, use it
   when possible (and hopefully remove this check altogether
   at some point).
2017-09-07 18:00:04 +02:00
solvingj
5ca44b6872 Minor - added header-only flag in conan
See header-only guidelines: 
http://conanio.readthedocs.io/en/latest/howtos/header_only.html?highlight=header%20only
Its borderline cosmetic, but it does have a purpose.
2017-08-28 12:18:54 +02:00
Sam Bristow
a04bd6d436 Remove duplicate CLI option
The "use-colour" option was accidentally duplicated as part of commit
feaf355 (Implemented libidentify support).
2017-08-28 12:16:23 +02:00
Martin Hořeňovský
784f6dfb34 Fix updateVcpkgPackage 2017-08-27 11:43:55 +02:00
Martin Hořeňovský
7818e2666d v1.10.0 2017-08-26 15:34:18 +02:00
Martin Hořeňovský
cd30dd1a70 Workaround raw string literal bug in VS2017 2017-08-26 15:14:27 +02:00
Phil Nash
8e8c0c1675 Tweaked how failedButOk assertions are recorded
- fixes issue where sections in !shouldfail or !mayfail test cases that have failing assertions where marked as failed instead of failedButOk
2017-08-25 11:37:49 +01:00
Phil Nash
b6e7c9bd7a Specialise removeConst for nullptr 2017-08-24 23:07:44 +02:00
Phil Nash
180d9242f5 Suppress more signed/ unsigned mismatches during Evaluator calls on MSVC 2017-08-24 23:07:03 +02:00
Phil Nash
b7bd52cc98 Cherry-picked "evaluate" refactoring from dev-modernize branch
- fixed up NULL comparisons to allow for NULL being a long
- should address #981
2017-08-24 23:07:03 +02:00
Martin Hořeňovský
b07a2bdf87 Refactor release scripts, automatically update Wandbox on release 2017-08-24 21:59:06 +02:00
Martin Hořeňovský
c03e8fce92 Explicitly ignore return value of getchar
This silences MSVC warning about ignored return value
2017-08-22 22:06:37 +02:00
Phil Nash
27640a5a96 Added Clara and TextFlowCpp to open source users 2017-08-17 10:49:56 +01:00
Phil Nash
dd3867bbcd Create CODE_OF_CONDUCT.md 2017-08-17 07:45:12 +01:00
Phil Nash
387f8d254d Removed unnecessary single quotes 2017-08-15 19:41:46 +01:00
Phil Nash
c65eccd68e Added --libidentify and --wait-for-keypress to docs 2017-08-15 19:39:38 +01:00
Phil Nash
61c5675c11 Removed inadvertent use of auto merged from dev-modernise 2017-08-15 19:34:10 +01:00
Phil Nash
70e4af9d44 Implemented wait-for-keypress option 2017-08-15 14:12:11 +01:00
Monocasual
8f41bdb92d Add open-source user 2017-08-13 17:55:50 +02:00
Phil Nash
7fa5d9ca94 Removed redundant processName argument from libIdentify call 2017-08-11 22:03:09 +01:00
Phil Nash
feaf355489 Implemented libidentify support
- see https://github.com/janwilmans/LibIdentify
2017-08-11 19:55:55 +01:00
Martin Hořeňovský
2ce6c74f8f v1.9.7 2017-08-11 00:01:20 +02:00
Phil Nash
9688891868 Fix issue with fatal errors and non-failing assertions
Fixes #990
2017-08-10 21:44:54 +02:00
Martin Hořeňovský
4f21bb72ff Add tests for #961 2017-08-10 21:38:07 +02:00
Martin Hořeňovský
b435e0d7c7 Make default reporter configurable at compile time
Closes #978
2017-08-10 16:45:38 +02:00
Martin Hořeňovský
ba0a09fd9e Update documentation with changes from 7e4038d 2017-08-10 16:43:17 +02:00
Martin Hořeňovský
7e4038d848 Capture std::clog writes and combine them with std::cerr writes (#989)
This also introduces Catch::clog() method to allow embedded targets
to override std::clog usage with their own stream (presumably null-sink),
similarly to how Catch::cout() and Catch::cerr() are used.

Fixes #989
2017-08-09 15:28:40 +02:00
Martin Hořeňovský
92d714ee12 Update updateVcpkgPackage script for the new port format 2017-08-08 23:04:39 +02:00
Martin Hořeňovský
705a1bf527 Add wandbox to release process documentation
Also some formatting and wording changes.
2017-08-08 23:04:10 +02:00
Cody Han
d5613fb18a Update matchers docs to reflect namespace usage 2017-08-03 19:11:21 +02:00
Martin Hořeňovský
62875c857e Add a landing page link to wandbox with catch preloaded
Idea shamelessly stolen from nlohmann/json
2017-08-01 23:45:35 +02:00
Danila Sukharev
ec2074e558 Adding more flexibility into the cmake catch parsing script (#971)
* Adding more flexibility into the cmake catch parsing script
2017-08-01 17:33:53 +02:00
Martin Hořeňovský
7575749e56 Fix compilation error on older compilers 2017-08-01 17:21:06 +02:00
Martin Hořeňovský
8a2ff20982 Address some of the Resharper finds for Catch 1
Closes #957 as the other findings are mostly noise that is pointless
to fix in a branch that will be soon EoLd.
2017-07-31 12:31:45 +02:00
Anton Vorobyev
d3377c791d Initial support for native IBM i ILE C++ (#976)
* - Initial support for native IBM i ILE C++

Signed-off-by: zeromem <zeromem2@gmail.com>
2017-07-31 10:47:42 +02:00
Martin Hořeňovský
c5dfa73d56 Disable build broken by travis changes
It should be reenabled later, but I don't have time to investigate
right now.
2017-07-29 08:45:52 +02:00
Fran García Salomón
d65091fa06 Fix for JUnit reporter when using dynamically generated sections (#963)
* BySectionInfo should also take into account the section name in addition to the source code line
2017-07-23 17:13:44 +02:00
Martin Hořeňovský
7a22bad763 Addressed some static analysis warnings
Based on findings in #957
2017-07-19 09:50:08 +02:00
Phil Nash
8ebe94ca2e Added NOLINT annotations to selectively suppress clang_tidy warnings 2017-07-10 18:43:07 +01:00
Martin Hořeňovský
106d7e2a74 Initialize JunitReporter::unexpectedExceptions in constructor
This is not needed for correctness, but will prevent PVS warning
from triggering, and there is basically no performance difference.

Closes #951
2017-07-10 10:30:17 +02:00
Neal Coombes
a53ea30723 Eliminate some work when results won't be reported. 2017-07-07 01:34:12 +02:00
Ivan Kush
8d380a7399 added 'args' argument parser library 2017-07-05 15:55:28 +02:00
Martin Hořeňovský
3083de9ea6 Fix typo in README 2017-07-05 15:54:38 +02:00
Phil Nash
431e8d06e7 Added survey monkey link 2017-07-04 09:10:36 +01:00
Markus Werle
6f32db35af Update tutorial.md 2017-06-28 20:54:31 +02:00
Uilian Ries
7013e388f7 #926 Update Conan test version by release
Signed-off-by: Uilian Ries <uilianries@gmail.com>
2017-06-28 16:45:42 +01:00
Phil Nash
0270afb21b Updated license 2017-06-28 16:44:46 +01:00
Phil Nash
df7c5622b9 Merge branch 'feature/conan' of https://github.com/uilianries/Catch 2017-06-27 11:48:55 +01:00
Martin Hořeňovský
ee67ac6b7c v1.9.6 2017-06-27 12:21:48 +02:00
Baruch Burstein
8a14af701e If --list-extra-info is specified with --list-test-names-only, only output one list 2017-06-25 17:12:29 +02:00
Martin Hořeňovský
07c6bfc3b9 --extra-info -> --list-extra-info, behaves like other --list-* flags 2017-06-25 17:12:29 +02:00
Baruch Burstein
616f7235ef add --extra-info flag
this will add line info to test lists, and test descriptions to the long
form of the test list
2017-06-25 17:12:29 +02:00
Neal Coombes
396ecf6021 Cache std::ostringstream between assertions.
This is not thread safe, but I think that was already true of Catch.
The construction/destruction of the std::ostringstream is where the
vast majority of time is spent per assertion.  A simple test of
100000000 CHECK()s is reduced from around 60s to 7.4s
2017-06-25 15:53:59 +02:00
Uilian Ries
3491804598 #926 Update Conan version by release
- Update release scripts to increment Conan version

Signed-off-by: Uilian Ries <uilianries@gmail.com>
2017-06-23 16:03:36 -03:00
Uilian Ries
6234e3d54d #926 Conan recipe for Catch single header
- Insert catch.hpp (single header) to package
- Copy BDDTests and TrickyTest to validate Catch package

Signed-off-by: Uilian Ries <uilianries@gmail.com>
2017-06-23 10:34:56 -03:00
Martin Hořeňovský
a6cdcd43aa Added "How to test changes in PR" section to documentation
Also linked it from PR template.

Closes #936
2017-06-22 18:56:10 +02:00
Neal Coombes
dcab8a5971 Performance improvement in AssertionInfo.
By using char const * instead of std::string we avoid significant
copying per assertion.  In a simple loop with 10000000 CHECKS on
my system, this reduces the run time from 9.8s to 6s.
2017-06-22 18:03:47 +02:00
Martin Hořeňovský
017a63da62 v1.9.5 2017-06-15 13:08:26 +02:00
Martin Hořeňovský
b90d0b7267 Disable deprecation warning of std::uncaught_exception
We might prefer to use `std::uncaught_exceptions` in the future, but I
would prefer not to bring in more configuration into Catch Classic

Closes #927
2017-06-15 11:43:31 +02:00
Martin Hořeňovský
efba988ccc Fix how GCC version is detected when checking for __COUNTER__
Fixes #928
2017-06-13 18:20:59 +02:00
Phil Nash
004228efb2 Merge pull request #855 from kainjow/objc-tostring-link
Fix Catch::toString() linker error when main() is compiled as C++
2017-06-11 23:06:38 +01:00
Martin Hořeňovský
e0aaba6cf8 Actually link #923 from the documentation 2017-06-06 16:46:46 +02:00
Martin Hořeňovský
a09bef23ed Refer to #923 in reporter documentation 2017-06-06 16:43:14 +02:00
Martin Hořeňovský
3e018ef131 Add link to external gcov/lcov example to documentation
An alternate take on #916, that better slots into the existing
documentation.

Closes #916
2017-06-04 12:17:59 +02:00
Martin Hořeňovský
adb66f55a7 Don't include warning headers from catch_xmlwriter.hpp
This prevents Catch from disabling `Wpadded` for Clang inside test files
(files that do not define either `CATCH_CONFIG_MAIN` or
`CATCH_CONFIG_RUNNER`).

catch_suppress_warnings.h and catch_reenable_warnings.h should be
included only once*, so that the stitching script includes them as the
first and last header respectively, since it only includes each header
once. This caused a bug, where the first one was included properly, but
the second one was included prematurely, from catch_xmlwriter.hpp, and
thus was guarded by `CATCH_IMPL`.

* At least until the stitching script is changed to accomodate common
warning disabling header.

Fixes #871
2017-06-02 19:10:57 +02:00
Martin Hořeňovský
377c9a746d Cosmetic fixes (whitespace and spelling) 2017-05-27 14:42:54 +02:00
Martin Hořeňovský
ea48ae0f75 Add test for #914 (stringify truthy exprs in standard way) 2017-05-27 14:42:05 +02:00
twhittock
2d1739b429 ExpressionLhs reconstruction based on value, not truthiness (#914)
Types which are truthy, but have more information than the truthiness in their string conversion were showing up as 'true' or 'false' instead of showing the underlying type's string value.
2017-05-27 14:09:43 +02:00
Martin Hořeňovský
1c59034be4 Merge pull request #911 from dvirtz/master
CTest integration script enhancements
2017-05-27 13:52:55 +02:00
Martin Hořeňovský
52a84788e0 Add Inscopix to commercial users
Closes #918
2017-05-27 12:23:35 +02:00
Martin Hořeňovský
3e328f55fc Merge pull request #913 from Carrotstrip/master
fixed spelling error in tutorial.md
2017-05-21 11:17:25 +02:00
Austin L Wolfgram
b18e67522f fixed spelling error 2017-05-20 15:10:42 -04:00
dvirtz
4b086bd5b5 added target name to test name and labels 2017-05-18 16:00:18 +03:00
dvirtz
aac594aae3 add option to print debug messages 2017-05-18 15:53:35 +03:00
dvirtz
a49fa0edbe use absolute path to test files - accroding to CMake docs EXISTS behavior is well-defined only for full paths. 2017-05-18 15:51:44 +03:00
Martin Hořeňovský
d271683c14 Added release process notes/checklist/explanation 2017-05-16 21:33:58 +02:00
Martin Hořeňovský
0bb8e1247e Merge branch 'master' of https://github.com/awglyde/Catch 2017-05-16 16:09:51 +02:00
Martin Hořeňovský
32d97caf42 Fixed missing ` in tag documentation 2017-05-16 15:45:44 +02:00
Martin Hořeňovský
bc93b29789 Expanded tag documentation
It now mentions that most characters are valid as part of tag and other
details.

Closes  #909
2017-05-16 15:28:53 +02:00
Martin Hořeňovský
df5cf2d323 Minor fixup in updateVcpkgPackage.py 2017-05-16 14:34:55 +02:00
Martin Hořeňovský
b62c0256b2 Merge branch 'master' of https://github.com/philsquared/Catch 2017-05-16 14:34:27 +02:00
Martin Hořeňovský
1ea84cb734 Expanded logging documentation
Closes #884
2017-05-16 14:34:20 +02:00
Martin Hořeňovský
2a5d3736e8 Merge pull request #908 from pJunger/patch-1
Typo: Added namespace in method testCaseEnded
2017-05-16 14:05:31 +02:00
Martin Hořeňovský
3dcc923351 v1.9.4 2017-05-16 13:59:29 +02:00
Martin Hořeňovský
589c40077b Typo fix
Somehow I made that in 5ffc8a84cd without noticing
2017-05-16 13:51:17 +02:00
Patrick Junger
d4e0b1d093 Added namespace in method testCaseEnded
Did not compile as is
2017-05-14 14:11:47 +02:00
Antonio Di Monaco
b8443e67da Added Win32 UNICODE wmain support (#903)
* Added wmain support
* Added appveyor.yml wmain configuration
* Added wmain configuration flag to CMake
2017-05-11 13:00:03 +02:00
Martin Hořeňovský
5604ec7266 Updated toString documentation
It will need another update when Catch 2 goes live.

Closes #741
2017-05-03 21:09:27 +02:00
Benjamin R. Jack
6f012f2d1d Added warning if source file cannot be found
If source files are defined using relative paths, CMake will compile the tests, but this script will (sometimes) fail to find and parse the tests from the source files.  I have added an explicit warning when ParseAndAddCatchTests fails to find a source file.
2017-05-01 19:55:17 +02:00
Martin Hořeňovský
98e61c31df Approval tests now see different line endings as ok
This is mostly to deal with WSL, where git will checkout file with CRLF,
but code that uses formatted output will be writing LFs.
2017-04-29 18:06:36 +02:00
Martin Hořeňovský
e641485132 Updated approval tests 2017-04-29 17:54:10 +02:00
Martin Hořeňovský
a3ceb8f007 Approval tests now can deal with different expansions of errno 2017-04-29 17:52:12 +02:00
Martin Hořeňovský
b819432271 Don't clear out all messages upon printing an assertion.
Previously, this would not print out any messages for the last CHECK
```cpp
TEST_CASE("Foo") {
INFO("Test case start");
for (int i = 0; i < 2; ++i) {
INFO("The number is " << i);
CHECK(i == 0);
}
CHECK(false);
}
```

now it does.
2017-04-29 17:50:03 +02:00
Martin Hořeňovský
9ceae8f51f CMake binaries are now conditionally enabled
Defining NO_SELFTEST=1 when cmake configuration is being done now turns
off SelfTest and Benchmark executables. This is for projects that
consume Catch using ExternalProject_Add and don't want to build our
selftest binaries for their unit test suite.

Closes #897
2017-04-28 20:27:10 +02:00
Martin Hořeňovský
5ffc8a84cd Fix order of arguments in CATCH_FAIL and nonvariadic INTERNAL_CATCH_MSG
Fixes #896
2017-04-28 18:30:04 +02:00
JayAndCatchFire
6e0fa4be68 Update opensource-users.md
Fixed broken link to LICENSE
2017-04-27 10:29:58 +02:00
Phil Nash
a0ada2e935 v1.9.3 2017-04-25 14:23:06 +00:00
Phil Nash
e4694f58da Removed errant uses of uint64_t
fixes #894
2017-04-25 14:15:59 +00:00
Martin Hořeňovský
fc7f0a02b8 v1.9.2 2017-04-25 11:08:02 +02:00
Phil Nash
211b330346 Don’t unconditionally #include <stdint.h> (as earlier MSVC don’t have it) 2017-04-25 08:43:14 +01:00
Phil Nash
d36fe214a6 Further tweaked alignment hack for Option 2017-04-25 08:38:25 +01:00
Martin Hořeňovský
a34c053f0a All of Approx's member functions now accept strong typedefs
Previously `Approx::operator()`, `Approx::epsilon`, `Approx::margin` and
`Approx::scale` didn't.

Closes #888
2017-04-24 22:01:45 +02:00
Martin Hořeňovský
4cdb203ec3 Improve documentation about using Catch with CMake
Also added a note about the `contrib/ParseAndAddCatchTests.cmake`
script.

Closes #882
2017-04-24 16:27:43 +02:00
Ernst Maurer
8014bf1124 cmake script to generate ctest definitions from catch tests: fix for test case body bracket 2017-04-24 13:33:04 +02:00
Alexander Batischev
49d87cf182 Add Newsbeuter to OSS users list (#891) 2017-04-22 16:02:55 +02:00
Phil Nash
eedcc82d31 Tweaked storage alignment "workaround" a bit more in Option. 2017-04-21 07:19:39 +01:00
Martin Hořeňovský
8e8259091c Fix .travis.yml syntax 2017-04-20 22:54:17 +02:00
Martin Hořeňovský
7869e5b007 Enable C++11 and C++14 on OSX on Travis 2017-04-20 22:52:41 +02:00
Martin Hořeňovský
a49af4648c Minor .travis.yml cleanup
Still could use someone more experienced to clean it up properly...
2017-04-20 22:50:07 +02:00
Martin Hořeňovský
417b2bcf5c Enable C++14 on Linux on Travis 2017-04-20 22:47:05 +02:00
Martin Hořeňovský
8f0feaa6d2 Enable /std:c++latest (C++17) for AppVeyor VS 2017 2017-04-20 21:32:50 +02:00
Martin Hořeňovský
b95163bd3a Don't enable POSIX signals under QNX
Fixes #889
2017-04-20 21:02:25 +02:00
Phil Nash
2809be87cc “fixed” alignment in Option 2017-04-20 14:39:07 +01:00
Martin Hořeňovský
ac369b7b83 Add script that helps with updating the Vcpkg package.
Kind of a hackjob, that assumes vcpkg is already checked out
and is next to the Catch's directory.
2017-04-11 17:25:04 +02:00
Ernst Maurer
1aa3e4abfa Add CMake script to generate ctest definitions from Catch tests (#879)
Added cmake script to parse the source files containing Catch's test and generate ctest definitions.

It generates one ctest test per `TEST_CASE` and labels them, using the `TEST_CASE`'s tags.

Closes #719.
2017-04-11 16:51:02 +02:00
Phil Nash
e5c5a636a9 junit reporter does not count exceptions as failures if ok-to-fail 2017-04-11 15:47:42 +01:00
Phil Nash
2bf30e9e5a Use (locally defined) UInt64 instead of uint64_t
- typedefs long long for MSVC
- typedefs uint64_t otherwise

Should probably do finer grained compiler checking - but this should at least be better than what was there before
2017-04-11 15:06:25 +01:00
Phil Nash
b591cb9a03 Added note about thread safety in assertions
- closes #875
2017-04-11 14:25:19 +01:00
Phil Nash
714d01c07c approved tests that were correct the first time (previous approvals were erroneous) 2017-04-09 20:40:11 +01:00
Martin Hořeňovský
c6990cdf91 v1.9.1 release 2017-04-09 21:25:20 +02:00
Martin Hořeňovský
da8786b8fd Unexpected exception are no longer ignored by default
What an embarassing bug, I'll have to look into why it wasn't caught by
any of Catch's self-tests.

Fixes #885 and closes #887 (duplicate)
2017-04-09 21:20:58 +02:00
Phil Nash
5577322062 Added Nonius to open-sources users 2017-04-08 22:47:13 +01:00
Martin Hořeňovský
1b03c5ab6a v1.9.0 release 2017-04-07 22:56:36 +02:00
Phil Nash
7dd3c19027 Added NASA to commercial users list 2017-04-07 19:12:13 +01:00
Phil Nash
29d26d3179 Commented out unused argument 2017-04-07 11:36:54 +01:00
Phil Nash
ca764ec8d9 TeamCity reporter “ignores” failures in tests marked “ok to fail”
- also don’t report hidden/ not-selected tests
2017-04-07 11:15:37 +01:00
Phil Nash
250f0ee7fb Added approvals for “failed as expected” tests 2017-04-07 09:33:19 +01:00
Martin Hořeňovský
09e4830199 Added VS2017 to AppVeyor matrix 2017-04-06 11:01:49 +02:00
Martin Hořeňovský
8f85d08e9f Give up on _Pragma for gcc, force disable Wparentheses in all TUs 2017-04-05 21:37:27 +02:00
Martin Hořeňovský
3ae076ce8d Updated REQUIRE* documentation under FAST_COMPILE 2017-04-05 10:26:19 +02:00
Sergey Semushin
94425ad59b Add opt-in c++11 stream insertable check. (#877)
* Add opt-in c++11 stream insertable check.

To opt-in, define CATCH_CONFIG_CPP11_STREAM_INSERTABLE_CHECK.

Opt-in fixes #872 and should fix #757 as well.
2017-04-05 09:53:10 +02:00
Martin Hořeňovský
0354d50278 Added templated constructor to C++11 Approx
When using C++11, comparison operators are already templated to take
anything that can be explicitly converted to double, but constructor
took only doubles. This lead to warnings when an `Approx` was
constructed from floats, which was problematic for some users.

Since just adding float constructor would be a large breaking change, as
suddenly `Approx( 1 )` would become ambiguous, I added a templated
constructor that will take anything that is explicitly convertible to
double. This has the added benefit of allowing constructing `Approx`
instances from instances of strong typedefs, ie allowing
`calculated_temp == Approx( known_temp)`.

Closes #873
2017-04-04 15:19:15 +02:00
Martin Hořeňovský
cdd83c2e15 Fmt and tag fixup for #876
Github wouldn't let me push to the PR, probably because it was made from
fork of a fork...
2017-04-04 11:31:13 +02:00
dvirtz
9a07dde16d print messages when unexpected exceptions are thrown 2017-04-04 11:27:19 +02:00
Martin Hořeňovský
6e091d3991 Reset the UnexpectedException report state 2017-04-03 11:48:50 +02:00
Martin Hořeňovský
95d85fb186 Fixed up CATCH_CONFIG_FAST_COMPILE for REQUIREs
Unexpected exceptions no longer cause abort and there should be no more
potential for false negatives.

The trade-off now is that exceptions are no longer translated.
2017-04-03 11:36:55 +02:00
Martin Hořeňovský
3a3f152979 Updated documentation of CATCH_CONFIG_FAST_COMPILE 2017-03-29 21:13:51 +02:00
Martin Hořeňovský
4fe2432e05 Rework of REQUIRE* changes in CATCH_CONFIG_FAST_COMPILE
`ResultBuilder`s destructor now checks for exceptions, preventing false
negatives. The speedup should remain the same give or take a tiny bit.
2017-03-29 21:12:06 +02:00
Martin Hořeňovský
c3a41e26a7 Suppress -Wexit-time-destructors in Catch code
This is another warning that follows test macros, making it painful to
suppress without leaking outside. Luckily clang's `_Pragma`
implementation works.

Should fix #308
2017-03-29 20:30:59 +02:00
Phil Nash
4838039b65 Merge pull request #869 from mloskot/patch-1
Add nanodbc library to Catch users
2017-03-27 07:43:27 +01:00
Mateusz Łoskot
2a221b8fcd Add nanodbc library to Catch users 2017-03-26 21:26:08 +02:00
Rian Quinn
79ce6930a2 remove redundant "/"
This "/" is not needed as CMake adds this automatically
2017-03-23 21:18:07 +01:00
Martin Hořeňovský
d762a7ca6c Expanded documentation about THROWS_AS assertions 2017-03-23 21:16:52 +01:00
Martin Hořeňovský
f23b6b8b85 Don't sanitize exception type in REQUIRE_THROWS_AS
Effectively a revert of previous commit, fixing #542, where this was
added to stop linters complaining about `REQUIRE_THROWS_AS` used like
`REQUIRE_THROWS_AS(expr, std::exception);`, which would be slicing the
caught exception. Now it is user's responsibility to pass us proper
exception type.

Closes #833 which wanted to add `typename`, so that the construct works
in a template, but that would not work with MSVC and older GCC's, as
having `typename` outside of a template is allowed only from C++11
onward.
2017-03-23 21:11:21 +01:00
Martin Hořeňovský
4597b43912 Throw instead of calling exit in RegistrarForTagAliases constructor
Caries a problem vis-a-vis Windows, just like previous commit, but that
can be fixed later on.

Closes #866
2017-03-22 18:40:07 +01:00
Martin Hořeňovský
f64d914bff Throw instead of calling exit in enforceNotReservedTag
Closes #865
2017-03-22 17:53:22 +01:00
Martin Hořeňovský
d07999ddff Version struct now uses char* for holding branch name
Since the info is constant, and the only use is to write it out during
runtime, there is no need for `std::string`.
2017-03-22 17:45:36 +01:00
Kevin Ushey
e04dc5105b use inline 'libraryVersion()' function (closes #858) 2017-03-22 15:51:02 +01:00
Phil Nash
cffb031ce1 Added polymorphic_value to OSS users 2017-03-22 10:33:52 +00:00
Phil Nash
f3ec843ba6 Changed all internal forwarding macro usages to put macro name as first argument
(and ‘expression’, if any, last)
This is a first step towards allowing expression arguments to become variadic
2017-03-21 13:23:35 +00:00
Martin Hořeňovský
55ed17f97b Removed stray define 2017-03-20 10:53:32 +01:00
Martin Hořeňovský
6a502cc2f5 Renamed licence file, license should now be detected by github 2017-03-20 08:59:25 +01:00
Martin Hořeňovský
6a009fabcb Documented REQUIRE under CATCH_CONFIG_FAST_COMPILE 2017-03-17 17:02:39 +01:00
Martin Hořeňovský
7a8a0205b4 CATCH_CONFIG_FAST_COMPILE now disables trys in REQUIRE*
This seems to give about 15% speedup when compiling tests using GCC.

The tradeoff is that under certain circumstances, there is a chance for
false negative result, when the expression under test throws exception
and the test code catches it before it gets to the test runner.

Example:
``` cpp
TEST_CASE("False negative") {
try {
REQUIRE(throws() == "");
} catch (...) {}
}
```
This test case will succeed, reporting no assertions checked, instead of
failing as it would with `CATCH_CONFIG_FAST_COMPILE` disabled. However,
just removing the try-catch block inside client's code will fix this, so
it is worthwhile.

This change does not apply to CHECK* macros, because these are currently
specified as continuing on exception and thus need the local try-catch
to work as intended.
2017-03-17 13:21:40 +01:00
Mickey Rose
4dc06bdb70 Use bulk vector::insert rather than back_inserter 2017-03-15 15:19:38 +00:00
Phil Nash
08b597b3e2 Merge pull request #856 from lightmare/script-exec-perm
Set execute permission on runnable python scripts
2017-03-15 11:44:40 +00:00
Mickey Rose
46d166406d Set execute permission on runnable python scripts 2017-03-15 12:24:18 +01:00
Phil Nash
4ec8d53e91 Tag Alias registry is part of registry hub instead of it’s own singleton
- should now be cleaned up properly
2017-03-15 09:45:37 +00:00
Phil Nash
e7984e3711 Reorganised the readme/ ref docs TOC and added link to reporters docs 2017-03-15 09:08:20 +00:00
Phil Nash
90d89377ea Added docs on reporters 2017-03-15 09:07:23 +00:00
Phil Nash
0692317bc5 Added Obj-C bindings fix to release notes 2017-03-15 09:04:09 +00:00
Kevin Wojniak
e8b31108d6 Fix Catch::toString() linker error when main() is compiled as C++
Fixes #278
2017-03-14 11:54:14 -07:00
Martin Hořeňovský
95fc8d62a2 Fixed up old documentation links in release notes 2017-03-13 21:31:26 +01:00
Martin Hořeňovský
0c015aa887 v1.8.2 release 2017-03-13 21:29:30 +01:00
Phil Nash
f69f821853 Updatecd [!shouldFail] docs with extra explanatory note, 2017-03-13 19:35:17 +00:00
Phil Nash
485dbdc0e7 Added link to event listeners docs 2017-03-13 19:27:18 +00:00
Phil Nash
0afd52b98d Fix Objective-C Matchers
Fixes #854
2017-03-13 15:40:21 +00:00
Phil Nash
38b05f1400 Don’t assume first CL arg (exe name) is present
Fixes #729
2017-03-13 11:00:58 +00:00
Phil Nash
db9866677e Don’t ref past end of string
fixes #830
2017-03-13 10:22:02 +00:00
Phil Nash
4101ff314a #include <ctype> for std::to lower 2017-03-10 19:25:00 +00:00
Phil Nash
68da5a6d19 Docs for Listeners 2017-03-10 19:17:25 +00:00
Phil Nash
e4a25ad5ff Added CATCH_REGISTER_LISTENER without the INTERNAL_ prefix 2017-03-10 19:15:03 +00:00
Phil Nash
5d6c744d38 Qualified std::tolower in Clara.
Fixes #543
2017-03-10 18:38:52 +00:00
Phil Nash
5dd0639520 Added FAIL_CHECK
Works like FAIL, but does not abort test.
As proposed in #765
2017-03-08 15:42:11 +00:00
Phil Nash
a2515755c3 Merge pull request #846 from m0ppers/patch-1
Add ArangoDB
2017-03-07 11:34:07 +00:00
m0ppers
807941eb31 Add ArangoDB 2017-03-07 12:29:13 +01:00
Martin Hořeňovský
a2e20b07f8 "Fix" build by annotating the new test as !shouldfail
The quick test under ctest checks only for no tests failing, not for the
expected output.
2017-03-07 10:17:59 +01:00
Martin Hořeňovský
ace70407a2 Add tests for #835
Also add ErrnoGuard before `isatty` call, because apparently it can set
errno to 25 (ENOTTY).
2017-03-06 22:07:33 +01:00
Martin Hořeňovský
613e1466f9 Save errno before using sprintf, ifstream.
std::ifstream in libstdc++ contains a bug, where it sets errno to zero.
To work around it, we manually save the errno before using std::ifstream
in debugger check, and reset it after we are done.

We also preventively save errno before using sprintf.

Fixes #835
2017-03-06 21:51:22 +01:00
Alex Glyde
d8f45cd5f1 changing tabs to spaces 2017-03-06 10:55:00 -05:00
Alex Glyde
3afd077b55 teamcity reporter should time durations explicitly 2017-03-06 10:35:03 -05:00
Martin Hořeňovský
e95bf48445 Take std::string by const-ref where possible
Most places already do, this brings over some forgotten places.

Also close #842
2017-03-06 13:16:43 +01:00
Martin Hořeňovský
932a405e18 /Wx -> /WX (stupid typo) 2017-03-06 11:29:57 +01:00
Martin Hořeňovský
9a037204fa Enable /Wx (Warnings as error) for SelfTest builds 2017-03-06 11:21:35 +01:00
Martin Hořeňovský
374c050a42 benchmarkCompile.py fixup 2017-03-06 10:59:17 +01:00
Martin Hořeňovský
8b8e3ee117 Disable C4702 in Exception tests self tests
VS 2015 in Release mode sees through our indirection and complains.
There is no reason to make the indirectoin harder to reason about,
instead of just disabling the warning.
2017-03-06 10:52:21 +01:00
Martin Hořeňovský
af1ed708e4 Copied release note fixes to documentation 2017-03-06 10:46:21 +01:00
Phil Nash
041498b221 Fixed unintentional tabs 2017-03-06 09:23:31 +00:00
philsquared
d5a5883a10 Fixed mssing virtual destructor warnings
In Visual Studio with warning 4265 enabled
Closes #844
2017-03-06 08:59:52 +00:00
philsquared
6fea473414 Fixed CMake generation of MSVC warning levels 2017-03-06 08:35:14 +00:00
Phil Nash
68e7fdce20 Added 4265 to specific warnings in VS 2017-03-06 08:21:52 +00:00
Phil Nash
b4c9bf5802 Removed version # from readme
- and script that updates it (as it’s now automatically in a badge)
2017-03-03 15:40:32 +00:00
Phil Nash
e952fa8946 Added release badge 2017-03-03 15:25:58 +00:00
Phil Nash
84a178f0b0 Add AppVeyor status 2017-03-03 14:38:20 +00:00
Phil Nash
f9db24a824 Refactored console reporter include logic to match Xml Reporter’s 2017-03-03 14:19:41 +00:00
Phil Nash
9bee606dd6 Tweaked Xml Reporter to follow same success/ info behaviour as Console reporter 2017-03-03 14:12:47 +00:00
Martin Hořeňovský
be4f6ab8e1 Change reporting of CAPTURE'd variables
Info is not changed, intentionally.

Closes #639
2017-03-03 14:34:50 +01:00
Martin Hořeňovský
fd6c7aee6d Fixed compile benchmark script
Now it no longer attempts to enter a directory before creating it...
2017-03-02 18:27:31 +01:00
Martin Hořeňovský
cd6de9cd34 Don't reconstruct expression on encountering fatal error
In some cases, like when given

```cpp
std::vector<char>* str =
reinterpret_cast<std::vector<char>*>(0x1234458);
CHECK(*str == std::vector<char>());
```

reconstructing the expression to report it would cause another fatal
error. Instead we just put together an AssertionResult without
reconstructing the expression fully.

This should fully fix #810
2017-03-02 18:18:28 +01:00
Martin Hořeňovský
40f6a5b8a4 Added duration reporting to compact reporter
Also made the duration formatting code available to all reporters.

Closes #780
2017-03-02 16:16:17 +01:00
Martin Hořeňovský
95b0eb2b6c TAP reporter now behaves as if -s was always set
This should fulfill the TAP specification better.
2017-03-02 15:54:08 +01:00
Martin Hořeňovský
0b28d3daf2 Merge branch 'tap-count-success' of https://github.com/gahr/Catch 2017-03-02 15:23:46 +01:00
Phil Nash
8435dcbb61 Resized main logo again 2017-03-01 17:00:33 +00:00
Phil Nash
99347df70e Updated artwork 2017-03-01 16:47:04 +00:00
Phil Nash
658b5f63ef Updated release notes 2017-03-01 16:06:48 +00:00
Phil Nash
c6535a080e v1.8.1 release 2017-03-01 16:04:44 +00:00
Phil Nash
673ec550f5 Moved definition of _BSD_SOURCE earlier 2017-03-01 15:59:10 +00:00
Phil Nash
ff78e7c45a Fixed typo in test name 2017-03-01 15:59:10 +00:00
Pietro Cerutti
da023b2f9a TAP Reporter: count success tests even if not printed
This fixes a bug whereas running the TAP reporter without the -s switch
causes the reporter to print 1..0.
2017-03-01 09:24:58 +00:00
Phil Nash
470561cbbd Update release-notes.md
Removed speed up time placeholder
2017-03-01 08:24:16 +00:00
Phil Nash
417202b743 Update release-notes.md
Fixed docs/ paths
2017-03-01 08:22:38 +00:00
124 changed files with 4685 additions and 1421 deletions

View File

@@ -2,6 +2,9 @@
Please do not submit pull requests changing the `version.hpp`
or the single-include `catch.hpp` file, these are changed
only when a new release is made.
Before submitting a PR you should probably read the contributor documentation
at docs/contributing.md. It will tell you how to properly test your changes.
-->

View File

@@ -11,25 +11,25 @@ matrix:
apt:
sources: ['llvm-toolchain-precise', 'ubuntu-toolchain-r-test']
packages: ['clang']
env: COMPILER='clang++' BUILD_TYPE='Release' CPP11=0
env: COMPILER='clang++' BUILD_TYPE='Release'
- os: linux
compiler: clang
addons: *clang34
env: COMPILER='clang++' BUILD_TYPE='Debug' CPP11=0
env: COMPILER='clang++' BUILD_TYPE='Debug'
- os: linux
compiler: clang
addons: &clang35
apt:
sources: ['llvm-toolchain-precise-3.5', 'ubuntu-toolchain-r-test']
packages: ['clang-3.5']
env: COMPILER='clang++-3.5' BUILD_TYPE='Release' CPP11=0
env: COMPILER='clang++-3.5' BUILD_TYPE='Release'
- os: linux
compiler: clang
addons: *clang35
env: COMPILER='clang++-3.5' BUILD_TYPE='Debug' CPP11=0
env: COMPILER='clang++-3.5' BUILD_TYPE='Debug'
- os: linux
@@ -38,12 +38,12 @@ matrix:
apt:
sources: ['llvm-toolchain-precise-3.6', 'ubuntu-toolchain-r-test']
packages: ['clang-3.6']
env: COMPILER='clang++-3.6' BUILD_TYPE='Release' CPP11=0
env: COMPILER='clang++-3.6' BUILD_TYPE='Release'
- os: linux
compiler: clang
addons: *clang36
env: COMPILER='clang++-3.6' BUILD_TYPE='Debug' CPP11=0
env: COMPILER='clang++-3.6' BUILD_TYPE='Debug'
- os: linux
@@ -52,12 +52,12 @@ matrix:
apt:
sources: ['llvm-toolchain-precise-3.7', 'ubuntu-toolchain-r-test']
packages: ['clang-3.7']
env: COMPILER='clang++-3.7' BUILD_TYPE='Release' CPP11=0
env: COMPILER='clang++-3.7' BUILD_TYPE='Release'
- os: linux
compiler: clang
addons: *clang37
env: COMPILER='clang++-3.7' BUILD_TYPE='Debug' CPP11=0
env: COMPILER='clang++-3.7' BUILD_TYPE='Debug'
- os: linux
@@ -66,12 +66,12 @@ matrix:
apt:
sources: ['llvm-toolchain-precise-3.8', 'ubuntu-toolchain-r-test']
packages: ['clang-3.8']
env: COMPILER='clang++-3.8' BUILD_TYPE='Release' CPP11=0
env: COMPILER='clang++-3.8' BUILD_TYPE='Release'
- os: linux
compiler: clang
addons: *clang38
env: COMPILER='clang++-3.8' BUILD_TYPE='Debug' CPP11=0
env: COMPILER='clang++-3.8' BUILD_TYPE='Debug'
# 2/ Linux GCC Builds
@@ -81,12 +81,12 @@ matrix:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.4']
env: COMPILER='g++-4.4' BUILD_TYPE='Release' CPP11=0
env: COMPILER='g++-4.4' BUILD_TYPE='Release'
- os: linux
compiler: gcc
addons: *gcc44
env: COMPILER='g++-4.4' BUILD_TYPE='Debug' CPP11=0
env: COMPILER='g++-4.4' BUILD_TYPE='Debug'
- os: linux
@@ -95,12 +95,12 @@ matrix:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.7']
env: COMPILER='g++-4.7' BUILD_TYPE='Release' CPP11=0
env: COMPILER='g++-4.7' BUILD_TYPE='Release'
- os: linux
compiler: gcc
addons: *gcc47
env: COMPILER='g++-4.7' BUILD_TYPE='Debug' CPP11=0
env: COMPILER='g++-4.7' BUILD_TYPE='Debug'
- os: linux
@@ -109,12 +109,12 @@ matrix:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.8']
env: COMPILER='g++-4.8' BUILD_TYPE='Release' CPP11=0
env: COMPILER='g++-4.8' BUILD_TYPE='Release'
- os: linux
compiler: gcc
addons: *gcc48
env: COMPILER='g++-4.8' BUILD_TYPE='Debug' CPP11=0
env: COMPILER='g++-4.8' BUILD_TYPE='Debug'
- os: linux
@@ -123,12 +123,12 @@ matrix:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.9']
env: COMPILER='g++-4.9' BUILD_TYPE='Release' CPP11=0
env: COMPILER='g++-4.9' BUILD_TYPE='Release'
- os: linux
compiler: gcc
addons: *gcc49
env: COMPILER='g++-4.9' BUILD_TYPE='Debug' CPP11=0
env: COMPILER='g++-4.9' BUILD_TYPE='Debug'
- os: linux
@@ -137,12 +137,12 @@ matrix:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-5']
env: COMPILER='g++-5' BUILD_TYPE='Release' CPP11=0
env: COMPILER='g++-5' BUILD_TYPE='Release'
- os: linux
compiler: gcc
addons: *gcc5
env: COMPILER='g++-5' BUILD_TYPE='Debug' CPP11=0
env: COMPILER='g++-5' BUILD_TYPE='Debug'
- os: linux
@@ -151,20 +151,17 @@ matrix:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-6']
env: COMPILER='g++-6' BUILD_TYPE='Release' CPP11=0
env: COMPILER='g++-6' BUILD_TYPE='Release'
- os: linux
compiler: gcc
addons: *gcc6
env: COMPILER='g++-6' BUILD_TYPE='Debug' CPP11=0
env: COMPILER='g++-6' BUILD_TYPE='Debug'
# 3a/ Linux C++11 GCC builds
- os: linux
compiler: gcc
addons: &gcc48
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.8']
addons: *gcc48
env: COMPILER='g++-4.8' BUILD_TYPE='Release' CPP11=1
- os: linux
@@ -175,10 +172,7 @@ matrix:
# 3b/ Linux C++11 Clang builds
- os: linux
compiler: clang
addons: &clang38
apt:
sources: ['llvm-toolchain-precise-3.8', 'ubuntu-toolchain-r-test']
packages: ['clang-3.8']
addons: *clang38
env: COMPILER='clang++-3.8' BUILD_TYPE='Release' CPP11=1
- os: linux
@@ -186,27 +180,69 @@ matrix:
addons: *clang38
env: COMPILER='clang++-3.8' BUILD_TYPE='Debug' CPP11=1
# 4a/ Linux C++14 GCC builds
- os: linux
compiler: gcc
addons: *gcc6
env: COMPILER='g++-6' BUILD_TYPE='Release' CPP14=1
# 4/ OSX Clang Builds
- os: linux
compiler: gcc
addons: *gcc6
env: COMPILER='g++-6' BUILD_TYPE='Debug' CPP14=1
# 4b/ Linux C++14 Clang builds
# - os: linux
# compiler: clang
# addons: *clang38
# env: COMPILER='clang++-3.8' BUILD_TYPE='Release' CPP14=1
#
# - os: linux
# compiler: clang
# addons: *clang38
# env: COMPILER='clang++-3.8' BUILD_TYPE='Debug' CPP14=1
# 5/ OSX Clang Builds
- os: osx
osx_image: xcode7.3
compiler: clang
env: COMPILER='clang++' BUILD_TYPE='Debug' CPP11=0
env: COMPILER='clang++' BUILD_TYPE='Debug'
- os: osx
osx_image: xcode7.3
compiler: clang
env: COMPILER='clang++' BUILD_TYPE='Release' CPP11=0
env: COMPILER='clang++' BUILD_TYPE='Release'
- os: osx
osx_image: xcode8
compiler: clang
env: COMPILER='clang++' BUILD_TYPE='Debug' CPP11=0
env: COMPILER='clang++' BUILD_TYPE='Debug'
- os: osx
osx_image: xcode8
compiler: clang
env: COMPILER='clang++' BUILD_TYPE='Release' CPP11=0
env: COMPILER='clang++' BUILD_TYPE='Release'
- os: osx
osx_image: xcode8
compiler: clang
env: COMPILER='clang++' BUILD_TYPE='Debug' USE_CPP11=1
- os: osx
osx_image: xcode8
compiler: clang
env: COMPILER='clang++' BUILD_TYPE='Release' USE_CPP11=1
- os: osx
osx_image: xcode8
compiler: clang
env: COMPILER='clang++' BUILD_TYPE='Debug' USE_CPP14=1
- os: osx
osx_image: xcode8
compiler: clang
env: COMPILER='clang++' BUILD_TYPE='Release' USE_CPP14=1
install:
@@ -218,13 +254,13 @@ install:
mkdir cmake && travis_retry wget --no-check-certificate --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake
export PATH=${DEPS_DIR}/cmake/bin:${PATH}
elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
which cmake || brew install cmake
which cmake || brew install cmake
fi
before_script:
- export CXX=${COMPILER}
- cd ${TRAVIS_BUILD_DIR}
- cmake -H. -BBuild -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -Wdev -DUSE_CPP11=${CPP11}
- cmake -H. -BBuild -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -Wdev -DUSE_CPP11=${CPP11} -DUSE_CPP14=${CPP14}
- cd Build
script:

View File

@@ -19,6 +19,10 @@ elseif(USE_CPP14)
set(CMAKE_CXX_FLAGS "-std=c++14 ${CMAKE_CXX_FLAGS}")
endif()
if(USE_WMAIN)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ENTRY:wmainCRTStartup")
endif()
#checks that the given hard-coded list contains all headers + sources in the given folder
function(CheckFileList LIST_VAR FOLDER)
set(MESSAGE " should be added to the variable ${LIST_VAR}")
@@ -55,6 +59,7 @@ set(TEST_SOURCES
${SELF_TEST_DIR}/CmdLineTests.cpp
${SELF_TEST_DIR}/CompilationTests.cpp
${SELF_TEST_DIR}/ConditionTests.cpp
${SELF_TEST_DIR}/DecompositionTests.cpp
${SELF_TEST_DIR}/EnumToString.cpp
${SELF_TEST_DIR}/ExceptionTests.cpp
${SELF_TEST_DIR}/GeneratorTests.cpp
@@ -135,6 +140,7 @@ set(INTERNAL_HEADERS
${HEADER_DIR}/internal/catch_debugger.h
${HEADER_DIR}/internal/catch_debugger.hpp
${HEADER_DIR}/internal/catch_default_main.hpp
${HEADER_DIR}/internal/catch_errno_guard.hpp
${HEADER_DIR}/internal/catch_evaluate.hpp
${HEADER_DIR}/internal/catch_exception_translator_registry.hpp
${HEADER_DIR}/internal/catch_expression_lhs.hpp
@@ -244,28 +250,35 @@ SOURCE_GROUP("Benchmarks" FILES ${BENCH_SOURCES})
# configure the executable
include_directories(${HEADER_DIR})
add_executable(SelfTest ${TEST_SOURCES} ${IMPL_SOURCES} ${HEADERS})
add_executable(Benchmark ${BENCH_SOURCES} ${HEADERS})
# Add desired warnings
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
target_compile_options( SelfTest PRIVATE -Wall -Wextra )
target_compile_options( Benchmark PRIVATE -Wall -Wextra )
endif()
if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
target_compile_options( SelfTest PRIVATE /W4 )
target_compile_options( Benchmark PRIVATE /W4 )
endif()
# Projects consuming Catch via ExternalProject_Add might want to use install step
# without building all of our selftests.
if (NOT NO_SELFTEST)
add_executable(SelfTest ${TEST_SOURCES} ${IMPL_SOURCES} ${HEADERS})
add_executable(Benchmark ${BENCH_SOURCES} ${HEADERS})
# Add desired warnings
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
target_compile_options( SelfTest PRIVATE -Wall -Wextra )
target_compile_options( Benchmark PRIVATE -Wall -Wextra )
endif()
if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
target_compile_options( SelfTest PRIVATE /W4 /w44265 /WX )
target_compile_options( Benchmark PRIVATE /W4 )
endif()
# configure unit tests via CTest
enable_testing()
add_test(NAME RunTests COMMAND SelfTest)
# configure unit tests via CTest
enable_testing()
add_test(NAME RunTests COMMAND SelfTest)
add_test(NAME ListTests COMMAND SelfTest --list-tests)
set_tests_properties(ListTests PROPERTIES PASS_REGULAR_EXPRESSION "[0-9]+ test cases")
add_test(NAME ListTests COMMAND SelfTest --list-tests)
set_tests_properties(ListTests PROPERTIES PASS_REGULAR_EXPRESSION "[0-9]+ test cases")
add_test(NAME ListTags COMMAND SelfTest --list-tags)
set_tests_properties(ListTags PROPERTIES PASS_REGULAR_EXPRESSION "[0-9]+ tags")
add_test(NAME ListTags COMMAND SelfTest --list-tags)
set_tests_properties(ListTags PROPERTIES PASS_REGULAR_EXPRESSION "[0-9]+ tags")
install(DIRECTORY "single_include/" DESTINATION "include/catch/")
endif() # !NO_SELFTEST
install(DIRECTORY "single_include/" DESTINATION "include/catch")

46
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,46 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at github@philnash.me. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

View File

@@ -1,10 +1,11 @@
![catch logo](catch-logo-small.png)
*v1.8.0*
[![Github Releases](https://img.shields.io/github/release/philsquared/catch.svg)](https://github.com/philsquared/catch/releases)
[![Build Status](https://travis-ci.org/philsquared/Catch.svg?branch=master)](https://travis-ci.org/philsquared/Catch)
[![Build status](https://ci.appveyor.com/api/projects/status/hrtk60hv6tw6fght/branch/master?svg=true)](https://ci.appveyor.com/project/philsquared/catch/branch/master)
[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/jG7wnHX9VAcxpSHy)
Build status (on Travis CI) [![Build Status](https://travis-ci.org/philsquared/Catch.svg?branch=master)](https://travis-ci.org/philsquared/Catch)
<a href="https://github.com/philsquared/Catch/releases/download/v1.8.0/catch.hpp">The latest, single header, version can be downloaded directly using this link</a>
<a href="https://github.com/philsquared/Catch/releases/download/v1.12.2/catch.hpp">The latest, single header, version can be downloaded directly using this link</a>
## What's the Catch?
@@ -21,3 +22,7 @@ This documentation comprises these three parts:
* Issues and bugs can be raised on the [Issue tracker on GitHub](https://github.com/philsquared/Catch/issues)
* For discussion or questions please use [the dedicated Google Groups forum](https://groups.google.com/forum/?fromgroups#!forum/catch-forum)
* See [who else is using Catch](docs/opensource-users.md)
## Help us out
We're currently running [a survey](https://www.surveymonkey.co.uk/r/TLLYQJW) to help us shape the future of Catch.
Please take a few moments to fill it out (there's only ten questions).

View File

@@ -1,14 +1,30 @@
# version string format -- This will be overwritten later anyway
version: "{build}"
# Disable the dead branch for v2 development
branches:
except:
- develop-v2
os:
- Visual Studio 2013
- Visual Studio 2017
- Visual Studio 2015
- Visual Studio 2013
environment:
matrix:
- additional_flags: "/permissive- /std:c++latest"
wmain: 0
- additional_flags: ""
wmain: 0
- additional_flags: "/D_UNICODE /DUNICODE"
wmain: 1
matrix:
exclude:
-
additional_flags: "/permissive- /std:c++latest"
os: Visual Studio 2015
-
additional_flags: "/permissive- /std:c++latest"
os: Visual Studio 2013
init:
- git config --global core.autocrlf input
@@ -31,8 +47,8 @@ configuration:
#Cmake will autodetect the compiler, but we set the arch
before_build:
- echo Running cmake...
- cmake -H. -BBuild -A%PLATFORM%
- set CXXFLAGS=%additional_flags%
- cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain%
# build with MSBuild
build:

BIN
catch-hand-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
catch-icon-tiny.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

19
conanfile.py Normal file
View File

@@ -0,0 +1,19 @@
#!/usr/bin/env python
from conans import ConanFile
class CatchConan(ConanFile):
name = "Catch"
version = "1.12.2"
description = "A modern, C++-native, header-only, framework for unit-tests, TDD and BDD"
author = "philsquared"
generators = "cmake"
exports_sources = "single_include/*"
url = "https://github.com/philsquared/Catch"
license = "Boost Software License - Version 1.0. http://www.boost.org/LICENSE_1_0.txt"
def package(self):
self.copy(pattern="catch.hpp", src="single_include", dst="include")
def package_id(self):
self.info.header_only()

View File

@@ -0,0 +1,185 @@
#==================================================================================================#
# supported macros #
# - TEST_CASE, #
# - SCENARIO, #
# - TEST_CASE_METHOD, #
# - CATCH_TEST_CASE, #
# - CATCH_SCENARIO, #
# - CATCH_TEST_CASE_METHOD. #
# #
# Usage #
# 1. make sure this module is in the path or add this otherwise: #
# set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake.modules/") #
# 2. make sure that you've enabled testing option for the project by the call: #
# enable_testing() #
# 3. add the lines to the script for testing target (sample CMakeLists.txt): #
# project(testing_target) #
# set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake.modules/") #
# enable_testing() #
# #
# find_path(CATCH_INCLUDE_DIR "catch.hpp") #
# include_directories(${INCLUDE_DIRECTORIES} ${CATCH_INCLUDE_DIR}) #
# #
# file(GLOB SOURCE_FILES "*.cpp") #
# add_executable(${PROJECT_NAME} ${SOURCE_FILES}) #
# #
# include(ParseAndAddCatchTests) #
# ParseAndAddCatchTests(${PROJECT_NAME}) #
# #
# The following variables affect the behavior of the script: #
# #
# PARSE_CATCH_TESTS_VERBOSE (Default OFF) #
# -- enables debug messages #
# PARSE_CATCH_TESTS_NO_HIDDEN_TESTS (Default OFF) #
# -- excludes tests marked with [!hide], [.] or [.foo] tags #
# PARSE_CATCH_TESTS_ADD_FIXTURE_IN_TEST_NAME (Default ON) #
# -- adds fixture class name to the test name #
# PARSE_CATCH_TESTS_ADD_TARGET_IN_TEST_NAME (Default ON) #
# -- adds cmake target name to the test name #
# PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS (Default OFF) #
# -- causes CMake to rerun when file with tests changes so that new tests will be discovered #
# #
#==================================================================================================#
cmake_minimum_required(VERSION 2.8.8)
option(PARSE_CATCH_TESTS_VERBOSE "Print Catch to CTest parser debug messages" OFF)
option(PARSE_CATCH_TESTS_NO_HIDDEN_TESTS "Exclude tests with [!hide], [.] or [.foo] tags" OFF)
option(PARSE_CATCH_TESTS_ADD_FIXTURE_IN_TEST_NAME "Add fixture class name to the test name" ON)
option(PARSE_CATCH_TESTS_ADD_TARGET_IN_TEST_NAME "Add target name to the test name" ON)
option(PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS "Add test file to CMAKE_CONFIGURE_DEPENDS property" OFF)
function(PrintDebugMessage)
if(PARSE_CATCH_TESTS_VERBOSE)
message(STATUS "ParseAndAddCatchTests: ${ARGV}")
endif()
endfunction()
# This removes the contents between
# - block comments (i.e. /* ... */)
# - full line comments (i.e. // ... )
# contents have been read into '${CppCode}'.
# !keep partial line comments
function(RemoveComments CppCode)
string(ASCII 2 CMakeBeginBlockComment)
string(ASCII 3 CMakeEndBlockComment)
string(REGEX REPLACE "/\\*" "${CMakeBeginBlockComment}" ${CppCode} "${${CppCode}}")
string(REGEX REPLACE "\\*/" "${CMakeEndBlockComment}" ${CppCode} "${${CppCode}}")
string(REGEX REPLACE "${CMakeBeginBlockComment}[^${CMakeEndBlockComment}]*${CMakeEndBlockComment}" "" ${CppCode} "${${CppCode}}")
string(REGEX REPLACE "\n[ \t]*//+[^\n]+" "\n" ${CppCode} "${${CppCode}}")
set(${CppCode} "${${CppCode}}" PARENT_SCOPE)
endfunction()
# Worker function
function(ParseFile SourceFile TestTarget)
# According to CMake docs EXISTS behavior is well-defined only for full paths.
get_filename_component(SourceFile ${SourceFile} ABSOLUTE)
if(NOT EXISTS ${SourceFile})
message(WARNING "Cannot find source file: ${SourceFile}")
return()
endif()
PrintDebugMessage("parsing ${SourceFile}")
file(STRINGS ${SourceFile} Contents NEWLINE_CONSUME)
# Remove block and fullline comments
RemoveComments(Contents)
# Find definition of test names
string(REGEX MATCHALL "[ \t]*(CATCH_)?(TEST_CASE_METHOD|SCENARIO|TEST_CASE)[ \t]*\\([^\)]+\\)+[ \t\n]*{+[ \t]*(//[^\n]*[Tt][Ii][Mm][Ee][Oo][Uu][Tt][ \t]*[0-9]+)*" Tests "${Contents}")
if(PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS AND Tests)
PrintDebugMessage("Adding ${SourceFile} to CMAKE_CONFIGURE_DEPENDS property")
set_property(
DIRECTORY
APPEND
PROPERTY CMAKE_CONFIGURE_DEPENDS ${SourceFile}
)
endif()
foreach(TestName ${Tests})
# Strip newlines
string(REGEX REPLACE "\\\\\n|\n" "" TestName "${TestName}")
# Get test type and fixture if applicable
string(REGEX MATCH "(CATCH_)?(TEST_CASE_METHOD|SCENARIO|TEST_CASE)[ \t]*\\([^,^\"]*" TestTypeAndFixture "${TestName}")
string(REGEX MATCH "(CATCH_)?(TEST_CASE_METHOD|SCENARIO|TEST_CASE)" TestType "${TestTypeAndFixture}")
string(REPLACE "${TestType}(" "" TestFixture "${TestTypeAndFixture}")
# Get string parts of test definition
string(REGEX MATCHALL "\"+([^\\^\"]|\\\\\")+\"+" TestStrings "${TestName}")
# Strip wrapping quotation marks
string(REGEX REPLACE "^\"(.*)\"$" "\\1" TestStrings "${TestStrings}")
string(REPLACE "\";\"" ";" TestStrings "${TestStrings}")
# Validate that a test name and tags have been provided
list(LENGTH TestStrings TestStringsLength)
if(TestStringsLength GREATER 2 OR TestStringsLength LESS 1)
message(FATAL_ERROR "You must provide a valid test name and tags for all tests in ${SourceFile}")
endif()
# Assign name and tags
list(GET TestStrings 0 Name)
if("${TestType}" STREQUAL "SCENARIO")
set(Name "Scenario: ${Name}")
endif()
if(PARSE_CATCH_TESTS_ADD_FIXTURE_IN_TEST_NAME AND TestFixture)
set(CTestName "${TestFixture}:${Name}")
else()
set(CTestName "${Name}")
endif()
if(PARSE_CATCH_TESTS_ADD_TARGET_IN_TEST_NAME)
set(CTestName "${TestTarget}:${CTestName}")
endif()
# add target to labels to enable running all tests added from this target
set(Labels ${TestTarget})
if(TestStringsLength EQUAL 2)
list(GET TestStrings 1 Tags)
string(TOLOWER "${Tags}" Tags)
# remove target from labels if the test is hidden
if("${Tags}" MATCHES ".*\\[!?(hide|\\.)\\].*")
list(REMOVE_ITEM Labels ${TestTarget})
endif()
string(REPLACE "]" ";" Tags "${Tags}")
string(REPLACE "[" "" Tags "${Tags}")
endif()
list(APPEND Labels ${Tags})
list(FIND Labels "!hide" IndexOfHideLabel)
set(HiddenTagFound OFF)
foreach(label ${Labels})
string(REGEX MATCH "^!hide|^\\." result ${label})
if(result)
set(HiddenTagFound ON)
break()
endif(result)
endforeach(label)
if(PARSE_CATCH_TESTS_NO_HIDDEN_TESTS AND ${HiddenTagFound})
PrintDebugMessage("Skipping test \"${CTestName}\" as it has [!hide], [.] or [.foo] label")
else()
PrintDebugMessage("Adding test \"${CTestName}\"")
if(Labels)
PrintDebugMessage("Setting labels to ${Labels}")
endif()
# Add the test and set its properties
add_test(NAME "\"${CTestName}\"" COMMAND ${TestTarget} ${Name} ${AdditionalCatchParameters})
set_tests_properties("\"${CTestName}\"" PROPERTIES FAIL_REGULAR_EXPRESSION "No tests ran"
LABELS "${Labels}")
endif()
endforeach()
endfunction()
# entry point
function(ParseAndAddCatchTests TestTarget)
PrintDebugMessage("Started parsing ${TestTarget}")
get_target_property(SourceFiles ${TestTarget} SOURCES)
PrintDebugMessage("Found the following sources: ${SourceFiles}")
foreach(SourceFile ${SourceFiles})
ParseFile(${SourceFile} ${TestTarget})
endforeach()
PrintDebugMessage("Finished parsing ${TestTarget}")
endfunction()

View File

@@ -1,22 +1,29 @@
These are the currently documented areas of the framework. There is more to come.
Before looking at this material be sure to read the [tutorial](tutorial.md)
To get the most out of Catch, start with the [tutorial](tutorial.md).
Once you're up and running consider the following reference material.
Writing tests:
* [Assertion macros](assertions.md)
* [Matchers](matchers.md)
* [Logging macros](logging.md)
* [Test cases and sections](test-cases-and-sections.md)
* [Test fixtures](test-fixtures.md)
* [Command line](command-line.md)
* [Build systems](build-systems.md)
* [Reporters](reporters.md)
* [Event Listeners](event-listeners.md)
Fine tuning:
* [Supplying your own main()](own-main.md)
* [Configuration](configuration.md)
* [Compile-time configuration](configuration.md)
* [String Conversions](tostring.md)
Running:
* [Command line](command-line.md)
* [CI and Build system integration](build-systems.md)
FAQ:
* [Why are my tests slow to compile?](slow-compiles.md)
* [Known limitations](limitations.md)
Other
Other:
* [Why Catch?](why-catch.md)
* [Open Source Projects using Catch](opensource-users.md)
* [Contributing](contributing.md)

View File

@@ -57,7 +57,7 @@ This way `Approx` is constructed with reasonable defaults, covering most simple
* __epsilon__ - epsilon serves to set the percentage by which a result can be erroneous, before it is rejected. By default set to `std::numeric_limits<float>::epsilon()*100`.
* __margin__ - margin serves to set the the absolute value by which a result can be erroneous before it is rejected. By default set to `0.0`.
* __scale__ - scale serves to adjust the base for comparison used by epsilon, can be used when By default set to `1.0`.
* __scale__ - scale serves to adjust the base for comparison used by epsilon. By default set to `1.0`.
#### epsilon example
```cpp
@@ -77,7 +77,7 @@ Approx target = Approx(100).margin(5);
```
#### scale
Scale can be useful if the computation leading to the result worked on different scale, than is used by the results (and thus expected errors are on a different scale than would be expected based on the results alone).
Scale can be useful if the computation leading to the result worked on different scale, than is used by the results (and thus expected errors are on a different scale than would be expected based on the results alone), i.e. an additional not scaling difference will be accepted, because | current - target | < eps_rel + eps_abs (while eps_rel = max(current, target) * epsilon, eps_abs = epsilon * scale) will be checked.
## Exceptions
@@ -95,7 +95,7 @@ Expects that an exception (of any type) is be thrown during evaluation of the ex
* **REQUIRE_THROWS_AS(** _expression_, _exception type_ **)** and
* **CHECK_THROWS_AS(** _expression_, _exception type_ **)**
Expects that an exception of the _specified type_ is thrown during evaluation of the expression.
Expects that an exception of the _specified type_ is thrown during evaluation of the expression. Note that the _exception type_ is used verbatim and you should include (const) reference.
* **REQUIRE_THROWS_WITH(** _expression_, _string or string matcher_ **)** and
* **CHECK_THROWS_WITH(** _expression_, _string or string matcher_ **)**
@@ -131,6 +131,11 @@ To support Matchers a slightly different form is used. Matchers have [their own
Matchers can be composed using `&&`, `||` and `!` operators.
## Thread Safety
Currently assertions in Catch are not thread safe.
For more details, along with workarounds, see the section on [the limitations page](limitations.md#thread-safe-assertions).
---
[Home](Readme.md)
[Home](Readme.md)

View File

@@ -1,4 +1,4 @@
# Integration with build systems
# CI and build system integration
Build Systems may refer to low-level tools, like CMake, or larger systems that run on servers, like Jenkins or TeamCity. This page will talk about both.
@@ -15,7 +15,7 @@ The XML Reporter writes in an XML format that is specific to Catch.
The advantage of this format is that it corresponds well to the way Catch works (especially the more unusual features, such as nested sections) and is a fully streaming format - that is it writes output as it goes, without having to store up all its results before it can start writing.
The disadvantage is that, being specific to Catch, no existing build servers understand the format natively. It can be used as input to an XSLT transformation that could covert it to, say, HTML - although this loses the streaming advantage, of course.
The disadvantage is that, being specific to Catch, no existing build servers understand the format natively. It can be used as input to an XSLT transformation that could convert it to, say, HTML - although this loses the streaming advantage, of course.
## JUnit Reporter
```-r junit```
@@ -56,8 +56,26 @@ Because of the incremental nature of Catch's test suites and ability to run spec
## CMake
You can use the following CMake script to automatically fetch Catch from github and configure it as an external project:
In general we recommend "vendoring" Catch's single-include releases inside your own repository. If you do this, the following example shows a minimal CMake project:
```CMake
cmake_minimum_required(VERSION 3.0)
project(cmake_test)
# Prepare "Catch" library for other executables
set(CATCH_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/catch)
add_library(Catch INTERFACE)
target_include_directories(Catch INTERFACE ${CATCH_INCLUDE_DIR})
# Make test executable
set(TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)
add_executable(tests ${TEST_SOURCES})
target_link_libraries(tests Catch)
```
Note that it assumes that the path to the Catch's header is `catch/catch.hpp` from the `CMakeLists.txt` file.
You can also use the following CMake snippet to automatically fetch the entire Catch repository from github and configure it as an external project:
```CMake
cmake_minimum_required(VERSION 2.8.8)
project(catch_builder CXX)
@@ -90,6 +108,36 @@ include_directories(${CATCH_INCLUDE_DIR} ${COMMON_INCLUDES})
enable_testing(true) # Enables unit-testing.
```
The advantage of this approach is that you can always automatically update Catch to the latest release. The disadvantage is that it means bringing in lot more than you need.
### Automatic test registration
If you are also using ctest, `contrib/ParseAndAddCatchTests.cmake` is a CMake script that attempts to parse your test files and automatically register all test cases, using tags as labels. This means that these
```cpp
TEST_CASE("Test1", "[unit]") {
int a = 1;
int b = 2;
REQUIRE(a == b);
}
TEST_CASE("Test2") {
int a = 1;
int b = 2;
REQUIRE(a == b);
}
TEST_CASE("Test3", "[a][b][c]") {
int a = 1;
int b = 2;
REQUIRE(a == b);
}
```
would be registered as 3 tests, `Test1`, `Test2` and `Test3`, and ctest 4 labels would be created, `a`, `b`, `c` and `unit`.
### CodeCoverage module (GCOV, LCOV...)
If you are using GCOV tool to get testing coverage of your code, and are not sure how to integrate it with CMake and Catch, there should be an external example over at https://github.com/fkromer/catch_cmake_coverage
---
[Home](Readme.md)
[Home](Readme.md)

View File

@@ -27,6 +27,8 @@ Click one of the followings links to take you straight to that option - or scrol
<a href="#listing-available-tests-tags-or-reporters"> ` --list-reporters`</a><br />
<a href="#order"> ` --order`</a><br />
<a href="#rng-seed"> ` --rng-seed`</a><br />
<a href="#libidentify"> ` --libidentify`</a><br />
<a href="#wait-for-keypress"> ` --wait-for-keypress`</a><br />
</br>
@@ -213,6 +215,20 @@ Alternatively if the keyword ```time``` is provided then the result of calling `
In either case the actual value for the seed is printed as part of Catch's output so if an issue is discovered that is sensitive to test ordering the ordering can be reproduced - even if it was originally seeded from ```std::time(0)```.
<a id="libidentify"></a>
## Identify framework and version according to the libIdentify standard
<pre>--libidentify</pre>
See [The LibIdentify repo for more information and examples](https://github.com/janwilmans/LibIdentify).
<a id="wait-for-keypress"></a>
## Wait for key before continuing
<pre>--wait-for-keypress &lt;start|exit|both&gt;</pre>
Will cause the executable to print a message and wait until the return/ enter key is pressed before continuing -
either before running any tests, after running all tests - or both, depending on the argument.
<a id="usage"></a>
## Usage
<pre>-h, -?, --help</pre>

View File

@@ -1,12 +1,16 @@
# Commercial users of Catch
As well as [Open Source](opensource-users.md) users Catch is widely used within proprietary code bases too. Many companies like to keep this
information internal, and that's fine, but if you're more open it would be great if we could list the names of as
many organisations as possible that use Catch somewhere in their codebase. Enterprise environments often tend to be
far more conservative in their tool adoption - and being aware that other companies are using Catch can ease the
path in.
As well as [Open Source](opensource-users.md) users Catch is widely used within proprietary code bases too.
Many organisations like to keep this information internal, and that's fine,
but if you're more open it would be great if we could list the names of as
many organisations as possible that use Catch somewhere in their codebase.
Enterprise environments often tend to be far more conservative in their tool adoption -
and being aware that other companies are using Catch can ease the path in.
So if you are aware of Catch usage in your organisation, and are fairly confident there is no issue with sharing this
fact then please let us know - either directly, via a PR or [issue](https://github.com/philsquared/Catch/issues), or on the [forums](https://groups.google.com/forum/?fromgroups#!forum/catch-forum).
fact then please let us know - either directly, via a PR or
[issue](https://github.com/philsquared/Catch/issues), or on the [forums](https://groups.google.com/forum/?fromgroups#!forum/catch-forum).
- Bloomberg
- NASA
- [Inscopix Inc.](https://www.inscopix.com/)

View File

@@ -43,26 +43,34 @@ By default a console width of 80 is assumed but this can be controlled by defini
CATCH_CONFIG_NOSTDOUT
Catch does not use ```std::cout``` and ```std::cerr``` directly but gets them from ```Catch::cout()``` and ```Catch::cerr()``` respectively. If the above identifier is defined these functions are left unimplemented and you must implement them yourself. Their signatures are:
Catch does not use ```std::cout```, ```std::cerr``` and ```std::clog``` directly but gets them from ```Catch::cout()```, ```Catch::cerr()``` and ```Catch::clog``` respectively. If the above identifier is defined these functions are left unimplemented and you must implement them yourself. Their signatures are:
std::ostream& cout();
std::ostream& cerr();
std::ostream& clog();
This can be useful on certain platforms that do not provide ```std::cout``` and ```std::cerr```, such as certain embedded systems.
This can be useful on certain platforms that do not provide the standard iostreams, such as certain embedded systems.
# Default reporter
CATCH_CONFIG_DEFAULT_REPORTER <reporter>
The default reporter (reporter used when no reporters are explicitly specified) can be overriden during compilation time by using the above macro. Note that desired value of the macro is a C string and quotes have to be escaped during compilation: `clang++ test.cpp -DCATCH_CONFIG_DEFAULT_REPORTER=\"xml\"`.
# C++ conformance toggles
CATCH_CONFIG_CPP11_NULLPTR // nullptr is supported?
CATCH_CONFIG_CPP11_NOEXCEPT // noexcept is supported?
CATCH_CONFIG_CPP11_GENERATED_METHODS // delete and default keywords for methods
CATCH_CONFIG_CPP11_IS_ENUM // std::is_enum is supported?
CATCH_CONFIG_CPP11_TUPLE // std::tuple is supported
CATCH_CONFIG_VARIADIC_MACROS // Usually pre-C++11 compiler extensions are sufficient
CATCH_CONFIG_CPP11_LONG_LONG // generates overloads for the long long type
CATCH_CONFIG_CPP11_OVERRIDE // CATCH_OVERRIDE expands to override (for virtual function implementations)
CATCH_CONFIG_CPP11_UNIQUE_PTR // Use std::unique_ptr instead of std::auto_ptr
CATCH_CONFIG_CPP11_SHUFFLE // Use std::shuffle instead of std::random_shuffle
CATCH_CONFIG_CPP11_TYPE_TRAITS // Use std::enable_if and <type_traits>
CATCH_CONFIG_CPP11_NULLPTR // nullptr is supported?
CATCH_CONFIG_CPP11_NOEXCEPT // noexcept is supported?
CATCH_CONFIG_CPP11_GENERATED_METHODS // delete and default keywords for methods
CATCH_CONFIG_CPP11_IS_ENUM // std::is_enum is supported?
CATCH_CONFIG_CPP11_TUPLE // std::tuple is supported
CATCH_CONFIG_VARIADIC_MACROS // Usually pre-C++11 compiler extensions are sufficient
CATCH_CONFIG_CPP11_LONG_LONG // generates overloads for the long long type
CATCH_CONFIG_CPP11_OVERRIDE // CATCH_OVERRIDE expands to override (for virtual function implementations)
CATCH_CONFIG_CPP11_UNIQUE_PTR // Use std::unique_ptr instead of std::auto_ptr
CATCH_CONFIG_CPP11_SHUFFLE // Use std::shuffle instead of std::random_shuffle
CATCH_CONFIG_CPP11_TYPE_TRAITS // Use std::enable_if and <type_traits>
CATCH_CONFIG_CPP11_STREAM_INSERTABLE_CHECK // Use C++11 expression SFINAE to check if class can be inserted to std::ostream
Catch has some basic compiler detection that will attempt to select the appropriate mix of these macros. However being incomplete - and often without access to the respective compilers - this detection tends to be conservative.
So overriding control is given to the user. If a compiler supports a feature (and Catch does not already detect it) then one or more of these may be defined to enable it (or suppress it, in some cases). If you do do this please raise an issue, specifying your compiler version (ideally with an idea of how to detect it) and stating that it has such support.
@@ -70,24 +78,56 @@ You may also suppress any of these features by using the `_NO_` form, e.g. `CATC
All C++11 support can be disabled with `CATCH_CONFIG_NO_CPP11`
## `CATCH_CONFIG_CPP11_STREAM_INSERTABLE_CHECK`
This flag is off by default, but allows you to resolve problems caused by types with private base class that are streamable, but the classes themselves are not. Without it, the following code will cause a compilation error:
```cpp
#define CATCH_CONFIG_MAIN
#include <catch.hpp>
struct A {};
std::ostream &operator<< (std::ostream &o, const A &v) { return o << 0; }
struct B : private A {
bool operator==(int){ return true;}
};
B f ();
std::ostream g ();
TEST_CASE ("Error in streamable check") {
B x;
REQUIRE (x == 4);
}
```
# Other toggles
CATCH_CONFIG_COUNTER // Use __COUNTER__ to generate unique names for test cases
CATCH_CONFIG_WINDOWS_SEH // Enable SEH handling on Windows
CATCH_CONFIG_FAST_COMPILE // Sacrifices some (extremely minor) features for compilation speed
CATCH_CONFIG_FAST_COMPILE // Sacrifices some (rather minor) features for compilation speed
CATCH_CONFIG_POSIX_SIGNALS // Enable handling POSIX signals
CATCH_CONFIG_WINDOWS_CRTDBG // Enable leak checking using Windows's CRT Debug Heap
CATCH_CONFIG_DISABLE_STRINGIFICATION // Disable stringifying the original expression
Currently Catch enables `CATCH_CONFIG_WINDOWS_SEH` only when compiled with MSVC, because some versions of MinGW do not have the necessary Win32 API support.
At this moment, `CATCH_CONFIG_FAST_COMPILE` changes only the behaviour of the `-b` (`--break`) flag, making it break into debugger in a stack frame *below* the actual test, unlike the default behaviour, where the break into debugger occurs in the same stack frame as the actual test. `CATCH_CONFIG_FAST_COMPILE` has to be either defined, or not defined, in all translation units that are linked into single test binary, or the behaviour of setting `-b` flag will be unpredictable.
`CATCH_CONFIG_POSIX_SIGNALS` is on by default, except when Catch is compiled under `Cygwin`, where it is disabled by default (but can be force-enabled by defining `CATCH_CONFIG_POSIX_SIGNALS`).
`CATCH_CONFIG_WINDOWS_CRTDBG` is off by default. If enabled, Windows's CRT is used to check for memory leaks, and displays them after the tests finish running.
Just as with the C++11 conformance toggles, these toggles can be disabled by using `_NO_` form of the toggle, e.g. `CATCH_CONFIG_NO_WINDOWS_SEH`.
## `CATCH_CONFIG_FAST_COMPILE`
Defining this flag speeds up compilation of test files by ~20%, by making 2 changes:
* The `-b` (`--break`) flag no longer makes Catch break into debugger in the same stack frame as the failed test, but rather in a stack frame *below*.
* The `REQUIRE` family of macros (`REQUIRE`, `REQUIRE_FALSE` and `REQUIRE_THAT`) no longer uses local try-catch block. This disables exception translation, but should not lead to false negatives.
`CATCH_CONFIG_FAST_COMPILE` has to be either defined, or not defined, in all translation units that are linked into single test binary, or the behaviour of setting `-b` flag and throwing unexpected exceptions will be unpredictable.
## `CATCH_CONFIG_DISABLE_STRINGIFICATION`
This toggle enables a workaround for VS 2017 bug. For details see
[known limitations](limitations.md#visual-studio-2017----raw-string-literal-in-assert-fails-to-compile).
# Windows header clutter
On Windows Catch includes `windows.h`. To minimize global namespace clutter in the implementation file, it defines `NOMINMAX` and `WIN32_LEAN_AND_MEAN` before including it. You can control this behaviour via two macros:

View File

@@ -18,8 +18,8 @@ Ongoing development is currently on _master_. At some point an integration branc
_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
that can work with the CMake file directly.
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.
@@ -34,6 +34,25 @@ __When submitting a pull request please do not include changes to the single inc
as these are managed by the scripts!__
## 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 (ie you implemented some performance improvements),
you should still test your changes.
This means 3 things
* Compiling Catch's SelfTest project -- code that does not compile is evidently incorrect. Obviously, you are not expected to
have access to all compilers and platforms Catch supports, Catch's CI pipeline will compile your code using supported compilers
once you open a PR.
* Running the SelfTest binary. There should be no unexpected failures on simple run.
* Running Catch's approval tests. Approval tests compare current output of the SelfTest binary in various configurations against
known good output. Catch's repository provides utility scripts `approvalTests.py` to help you with this. It needs to be passed
the SelfTest binary compiled with your changes, like so: `$ ./scripts/approvalTests.py clang-build/SelfTest`. The output should
be fairly self-explanatory.
*this document is still in-progress...*
---

73
docs/event-listeners.md Normal file
View File

@@ -0,0 +1,73 @@
# Event Listeners
A `Listener` is a class you can register with Catch that will then be passed events,
such as a test case starting or ending, as they happen during a test run.
`Listeners` are actually types of `Reporters`, with a few small differences:
1. Once registered in code they are automatically used - you don't need to specify them on the command line
2. They are called in addition to (just before) any reporters, and you can register multiple listeners.
3. They derive from `Catch::TestEventListenerBase`, which has default stubs for all the events,
so you are not forced to implement events you're not interested in.
4. You register a listener with `CATCH_REGISTER_LISTENER`
## Implementing a Listener
In your main source file (i.e. the one that has the `#define` for `CATCH_CONFIG_MAIN` or `CATCH_CONFIG_RUNNER`),
simply derive a class from `Catch::TestEventListenerBase` and implement the methods you are interested in.
Then register it using `INTERNAL_CATCH_REGISTER_LISTENER`.
For example:
```c++
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
struct MyListener : Catch::TestEventListenerBase {
using TestEventListenerBase::TestEventListenerBase; // inherit constructor
virtual void testCaseStarting( Catch::TestCaseInfo const& testInfo ) override {
// Perform some setup before a test case is run
}
virtual void testCaseEnded( Catch::TestCaseStats const& testCaseStats ) override {
// Tear-down after a test case is run
}
};
CATCH_REGISTER_LISTENER( MyListener )
```
_Note that you should not use any assertion macros within a Listener!_
## Events that can be hooked
The following are the methods that can be overriden in the Listener:
```c++
// The whole test run, starting and ending
virtual void testRunStarting( TestRunInfo const& testRunInfo );
virtual void testRunEnded( TestRunStats const& testRunStats );
// Test cases starting and ending
virtual void testCaseStarting( TestCaseInfo const& testInfo );
virtual void testCaseEnded( TestCaseStats const& testCaseStats );
// Sections starting and ending
virtual void sectionStarting( SectionInfo const& sectionInfo );
virtual void sectionEnded( SectionStats const& sectionStats );
// Assertions before/ after
virtual void assertionStarting( AssertionInfo const& assertionInfo );
virtual bool assertionEnded( AssertionStats const& assertionStats );
// A test is being skipped (because it is "hidden")
virtual void skipTest( TestCaseInfo const& testInfo );
```
More information about the events (e.g. name of the test case) is contained in the structs passed as arguments -
just look in the source code to see what fields are available.
---
[Home](Readme.md)

View File

@@ -50,6 +50,38 @@ Both of these solutions have their problems, but should let you wring parallelis
## 3rd party bugs
This section outlines known bugs in 3rd party components (this means compilers, standard libraries, standard runtimes).
### Visual Studio 2017 -- raw string literal in assert fails to compile
There is a known bug in Visual Studio 2017 (VC 15), that causes compilation error when preprocessor attempts to stringize a raw string literal (`#` preprocessor is applied to it). This snippet is sufficient to trigger the compilation error:
```cpp
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
TEST_CASE("test") {
CHECK(std::string(R"("\)") == "\"\\");
}
```
Catch provides a workaround, it is possible to disable stringification of original expressions by defining `CATCH_CONFIG_DISABLE_STRINGIFICATION`:
```cpp
#define CATCH_CONFIG_FAST_COMPILE
#define CATCH_CONFIG_DISABLE_STRINGIFICATION
#include "catch.hpp"
TEST_CASE("test") {
CHECK(std::string(R"("\)") == "\"\\");
}
```
_Do note that this changes the output somewhat_
```
catchwork\test1.cpp(6):
PASSED:
CHECK( Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION )
with expansion:
""\" == ""\"
```
### Visual Studio 2013 -- do-while loop withing range based for fails to compile (C2059)
There is a known bug in Visual Studio 2013 (VC 12), that causes compilation error if range based for is followed by an assertion macro, without enclosing the block in braces. This snippet is sufficient to trigger the error
```cpp

View File

@@ -1,6 +1,32 @@
# Logging macros
Additional messages can be logged during a test case.
Additional messages can be logged during a test case. Note that the messages are scoped and thus will not be reported if failure occurs in scope preceding the message declaration. An example:
```cpp
TEST_CASE("Foo") {
INFO("Test case start");
for (int i = 0; i < 2; ++i) {
INFO("The number is " << i);
CHECK(i == 0);
}
}
TEST_CASE("Bar") {
INFO("Test case start");
for (int i = 0; i < 2; ++i) {
INFO("The number is " << i);
CHECK(i == i);
}
CHECK(false);
}
```
When the `CHECK` fails in the "Foo" test case, then two messages will be printed.
```
Test case start
The number is 1
```
When the last `CHECK` fails in the "Bar" test case, then only one message will be printed: `Test case start`.
## Streaming macros
@@ -26,6 +52,10 @@ The message is always reported but does not fail the test.
The message is reported and the test case fails.
**FAIL_CHECK(** _message expression_ **)**
AS `FAIL`, but does not abort the test
## Quickly capture a variable value
**CAPTURE(** _expression_ **)**

View File

@@ -13,6 +13,7 @@ which consists of either a single matcher or one or more matchers combined using
For example, to assert that a string ends with a certain substring:
```c++
using Catch::Matchers::EndsWith; // or Catch::EndsWith
std::string str = getStringFromSomewhere();
REQUIRE_THAT( str, EndsWith( "as a service" ) );
```
@@ -34,7 +35,7 @@ REQUIRE_THAT( str,
```
## Built in matchers
Currently Catch has some string matchers and some vector matchers.
Currently Catch has some string matchers and some vector matchers. They are in the `Catch::Matchers` and `Catch` namespaces.
The string matchers are `StartsWith`, `EndsWith`, `Contains` and `Equals`. Each of them also takes an optional second argument, that decides case sensitivity (by-default, they are case sensitive).
The vector matchers are `Contains`, `VectorContains` and `Equals`. `VectorContains` looks for a single element in the matched vector, `Contains` looks for a set (vector) of elements inside the matched vector.

View File

@@ -1,6 +1,6 @@
# Open Source projects using Catch
Catch is great for open source. With it's [liberal license](../LICENSE_1_0.txt) and single-header, dependency-free, distribution
Catch is great for open source. With its [liberal license](../LICENSE.txt) and single-header, dependency-free, distribution
it's easy to just drop the header into your project and start writing tests - what's not to like?
As a result Catch is now being used in many Open Source projects, including some quite well known ones.
@@ -25,6 +25,9 @@ The core part of the Chakra Javascript engine that powers Microsoft Edge
### [ChaiScript](https://github.com/ChaiScript/ChaiScript)
A, header-only, embedded scripting language designed from the ground up to directly target C++ and take advantage of modern C++ development techniques
### [Clara](https://github.com/philsquared/Clara)
A, single-header-only, type-safe, command line parser - which also prints formatted usage strings.
### [Couchbase-lite-core](https://github.com/couchbase/couchbase-lite-core)
The next-generation core storage and query engine for Couchbase Lite/
@@ -34,23 +37,47 @@ A, single-header, JSON parsing library that takes advantage of what C++ has to o
### [MNMLSTC Core](https://github.com/mnmlstc/core)
a small and easy to use C++11 library that adds a functionality set that will be available in C++14 and later, as well as some useful additions
### [nanodbc](https://github.com/lexicalunit/nanodbc/)
A small C++ library wrapper for the native C ODBC API.
### [Nonius](https://github.com/libnonius/nonius)
A header-only framework for benchmarking small snippets of C++ code.
### [SOCI](https://github.com/SOCI/soci)
The C++ Database Access Library
### [polymorphic_value](https://github.com/jbcoe/polymorphic_value)
A polymorphic value-type for C++
### [Ppconsul](https://github.com/oliora/ppconsul)
A C++ client library for Consul. Consul is a distributed tool for discovering and configuring services in your infrastructure
### [Reactive-Extensions/ RxCpp](https://github.com/Reactive-Extensions/RxCpp)
A library of algorithms for values-distributed-in-time
### [TextFlowCpp](https://github.com/philsquared/textflowcpp)
A small, single-header-only, library for wrapping and composing columns of text
### [Trompeloeil](https://github.com/rollbear/trompeloeil)
A thread safe header only mocking framework for C++14
### [args](https://github.com/Taywee/args)
A simple header-only C++ argument parser library.
## Applications & Tools
### [ArangoDB](https://github.com/arangodb/arangodb)
ArangoDB is a native multi-model database with flexible data models for documents, graphs, and key-values.
### [Giada - Your Hardcore Loop Machine](https://github.com/monocasual/giada)
Minimal, open-source and cross-platform audio tool for live music production.
### [MAME](https://github.com/mamedev/mame)
MAME originally stood for Multiple Arcade Machine Emulator
### [Newsbeuter](https://github.com/akrennmair/newsbeuter)
Newsbeuter is an open-source RSS/Atom feed reader for text terminals.
### [Standardese](https://github.com/foonathan/standardese)
Standardese aims to be a nextgen Doxygen

View File

@@ -1,24 +1,245 @@
# 1.12.2
### Fixes
* Fixed missing <cassert> include
# 1.12.1
### Fixes
* Fixed deprecation warning in `ScopedMessage::~ScopedMessage`
* All uses of `min` or `max` identifiers are now wrapped in parentheses
* This avoids problems when Windows headers define `min` and `max` macros
# 1.12.0
### Fixes
* Fixed compilation for strict C++98 mode (ie not gnu++98) and older compilers (#1103)
* `INFO` messages are included in the `xml` reporter output even without `-s` specified.
# 1.11.0
### Fixes
* The original expression in `REQUIRE_FALSE( expr )` is now reporter properly as `!( expr )` (#1051)
* Previously the parentheses were missing and `x != y` would be expanded as `!x != x`
* `Approx::Margin` is now inclusive (#952)
* Previously it was meant and documented as inclusive, but the check itself wasn't
* This means that `REQUIRE( 0.25f == Approx( 0.0f ).margin( 0.25f ) )` passes, instead of fails
* `RandomNumberGenerator::result_type` is now unsigned (#1050)
### Improvements
* `__JETBRAINS_IDE__` macro handling is now CLion version specific (#1017)
* When CLion 2017.3 or newer is detected, `__COUNTER__` is used instead of
* TeamCity reporter now explicitly flushes output stream after each report (#1057)
* On some platforms, output from redirected streams would show up only after the tests finished running
* `ParseAndAddCatchTests` now can add test files as dependency to CMake configuration
* This means you do not have to manually rerun CMake configuration step to detect new tests
# 1.10.0
### Fixes
* Evaluation layer has been rewritten (backported from Catch 2)
* The new layer is much simpler and fixes some issues (#981)
* Implemented workaround for VS 2017 raw string literal stringification bug (#995)
* Fixed interaction between `[!shouldfail]` and `[!mayfail]` tags and sections
* Previously sections with failing assertions would be marked as failed, not failed-but-ok
### Improvements
* Added [libidentify](https://github.com/janwilmans/LibIdentify) support
* Added "wait-for-keypress" option
# 1.9.7
### Fixes
* Various warnings from clang-tidy, Resharper-C++ and PVS Studio have been addressed (#957)
* Dynamically generated sections are now properly reported (#963)
* Writes to `std::clog` are redirected for reporters (#989)
* Previously only `std::cerr` writes were redirected
* Interleaved writes to `std::cerr` and `std::clog` are combined properly
* Assertions failed before signals/structured exceptions fails test case are properly reported as failed (#990)
### Improvements
* Catch's runtime overhead has been decreased further (#940)
* Added support for IBM i ILE c++ compiler (#976)
* This means that AS/400 is now supported.
* The default reporter can be configured at compile time (#978)
* That is, the reporter used if no reporter is explicitly specified
### Other
* `ParseAndAddCatchTests` cmake script has couple new customization options
# 1.9.6
### Improvements
* Catch's runtime overhead has been significantly decreased (#937, #939)
* Added `--list-extra-info` cli option (#934).
* It lists all tests together with extra information, ie filename, line number and description.
# 1.9.5
### Fixes
* Truthy expressions are now reconstructed properly, not as booleans (#914)
* Various warnings are no longer erroneously suppressed in test files (files that include `catch.hpp`, but do not define `CATCH_CONFIG_MAIN` or `CATCH_CONFIG_RUNNER`) (#871)
* Catch no longer fails to link when main is compiled as C++, but linked against Objective-C (#855)
* Fixed incorrect gcc version detection when deciding to use `__COUNTER__` (#928)
* Previously any GCC with minor version less than 3 would be incorrectly classified as not supporting `__COUNTER__`.
* Suppressed C4996 warning caused by upcoming updated to MSVC 2017, marking `std::uncaught_exception` as deprecated. (#927)
### Improvements
* CMake integration script now incorporates debug messages and registers tests in an improved way (#911)
* Various documentation improvements
# 1.9.4
### Fixes
* `CATCH_FAIL` macro no longer causes compilation error without variadic macro support
* `INFO` messages are no longer cleared after being reported once
### Improvements and minor changes
* Catch now uses `wmain` when compiled under Windows and `UNICODE` is defined.
* Note that Catch still officially supports only ASCII
# 1.9.3
### Fixes
* Completed the fix for (lack of) uint64_t in earlier Visual Studios
# 1.9.2
### Improvements and minor changes
* All of `Approx`'s member functions now accept strong typedefs in C++11 mode (#888)
* Previously `Approx::scale`, `Approx::epsilon`, `Approx::margin` and `Approx::operator()` didn't.
### Fixes
* POSIX signals are now disabled by default under QNX (#889)
* QNX does not support current enough (2001) POSIX specification
* JUnit no longer counts exceptions as failures if given test case is marked as ok to fail.
* `Catch::Option` should now have its storage properly aligned.
* Catch no longer attempts to define `uint64_t` on windows (#862)
* This was causing trouble when compiled under Cygwin
### Other
* Catch is now compiled under MSVC 2017 using `std:c++latest` (C++17 mode) in CI
* We now provide cmake script that autoregisters Catch tests into ctest.
* See `contrib` folder.
# 1.9.1
### Fixes
* Unexpected exceptions are no longer ignored by default (#885, #887)
# 1.9.0
### Improvements and minor changes
* Catch no longer attempts to ensure the exception type passed by user in `REQUIRE_THROWS_AS` is a constant reference.
* It was causing trouble when `REQUIRE_THROWS_AS` was used inside templated functions
* This actually reverts changes made in v1.7.2
* Catch's `Version` struct should no longer be double freed when multiple instances of Catch tests are loaded into single program (#858)
* It is now a static variable in an inline function instead of being an `extern`ed struct.
* Attempt to register invalid tag or tag alias now throws instead of calling `exit()`.
* Because this happen before entering main, it still aborts execution
* Further improvements to this are coming
* `CATCH_CONFIG_FAST_COMPILE` now speeds-up compilation of `REQUIRE*` assertions by further ~15%.
* The trade-off is disabling translation of unexpected exceptions into text.
* When Catch is compiled using C++11, `Approx` is now constructible with anything that can be explicitly converted to `double`.
* Captured messages are now printed on unexpected exceptions
### Fixes:
* Clang's `-Wexit-time-destructors` should be suppressed for Catch's internals
* GCC's `-Wparentheses` is now suppressed for all TU's that include `catch.hpp`.
* This is functionally a revert of changes made in 1.8.0, where we tried using `_Pragma` based suppression. This should have kept the suppression local to Catch's assertions, but bugs in GCC's handling of `_Pragma`s in C++ mode meant that it did not always work.
* You can now tell Catch to use C++11-based check when checking whether a type can be streamed to output.
* This fixes cases when an unstreamable type has streamable private base (#877)
* [Details can be found in documentation](configuration.md#catch_config_cpp11_stream_insertable_check)
### Other notes:
* We have added VS 2017 to our CI
* Work on Catch 2 should start soon
# 1.8.2
### Improvements and minor changes
* TAP reporter now behaves as if `-s` was always set
* This should be more consistent with the protocol desired behaviour.
* Compact reporter now obeys `-d yes` argument (#780)
* The format is "XXX.123 s: <section-name>" (3 decimal places are always present).
* Before it did not report the durations at all.
* XML reporter now behaves the same way as Console reporter in regards to `INFO`
* This means it reports `INFO` messages on success, if output on success (`-s`) is enabled.
* Previously it only reported `INFO` messages on failure.
* `CAPTURE(expr)` now stringifies `expr` in the same way assertion macros do (#639)
* Listeners are now finally [documented](event-listeners.md).
* Listeners provide a way to hook into events generated by running your tests, including start and end of run, every test case, every section and every assertion.
### Fixes:
* Catch no longer attempts to reconstruct expression that led to a fatal error (#810)
* This fixes possible signal/SEH loop when processing expressions, where the signal was triggered by expression decomposition.
* Fixed (C4265) missing virtual destructor warning in Matchers (#844)
* `std::string`s are now taken by `const&` everywhere (#842).
* Previously some places were taking them by-value.
* Catch should no longer change errno (#835).
* This was caused by libstdc++ bug that we now work around.
* Catch now provides `FAIL_CHECK( ... )` macro (#765).
* Same as `FAIL( ... )`, but does not abort the test.
* Functions like `fabs`, `tolower`, `memset`, `isalnum` are now used with `std::` qualification (#543).
* Clara no longer assumes first argument (binary name) is always present (#729)
* If it is missing, empty string is used as default.
* Clara no longer reads 1 character past argument string (#830)
* Regression in Objective-C bindings (Matchers) fixed (#854)
### Other notes:
* We have added VS 2013 and 2015 to our CI
* Catch Classic (1.x.x) now contains its own, forked, version of Clara (the argument parser).
# 1.8.1
### Fixes
Cygwin issue with `gettimeofday` - `#define` was not early enough
# 1.8.0
### New features/ minor changes
* Matchers have new, simpler (and documented) interface.
* Catch provides string and vector matchers.
* For details see [Matchers documentation](docs/matchers.md).
* For details see [Matchers documentation](matchers.md).
* Changed console reporter test duration reporting format (#322)
* Old format: `Some simple comparisons between doubles completed in 0.000123s`
* New format: `xxx.123s: Some simple comparisons between doubles` _(There will always be exactly 3 decimal places)_
* Added opt-in leak detection under MSVC + Windows (#439)
* Enable it by compiling Catch's main with `CATCH_CONFIG_WINDOWS_CRTDBG`
* Introduced new compile-time flag, `CATCH_CONFIG_FAST_COMPILE`, trading features for compilation speed.
* Moves debug breaks out of tests and into implementation, speeding up compilation time by ~XX%
* Moves debug breaks out of tests and into implementation, speeding up test compilation time (~10% on linux).
* _More changes are coming_
* Added [TAP (Test Anything Protocol)](https://testanything.org/) and [Automake](https://www.gnu.org/software/automake/manual/html_node/Log-files-generation-and-test-results-recording.html#Log-files-generation-and-test-results-recording) reporters.
* These are not present in the default single-include header and need to be downloaded from GitHub separately.
* For details see [documentation about integrating with build systems](docs/build-systems.md).
* For details see [documentation about integrating with build systems](build-systems.md).
* XML reporter now reports filename as part of the `Section` and `TestCase` tags.
* `Approx` now supports an optional margin of absolute error
* It has also received [new documentation]().
* It has also received [new documentation](assertions.md).
### Fixes
* Silenced C4312 ("conversion from int to 'ClassName *") warnings in the evaluate layer.
@@ -61,7 +282,7 @@ Other:
### Fixes:
* Fixed inconsistency in defining `NOMINMAX` and `WIN32_LEAN_AND_MEAN` inside `catch.hpp`.
* Fixed SEH-related compilation error under older MinGW compilers, by making Windows SEH handling opt-in for compilers other than MSVC.
* For specifics, look into the [documentation](docs/configuration.md).
* For specifics, look into the [documentation](configuration.md).
* Fixed compilation error under MinGW caused by improper compiler detection.
* Fixed XML reporter sometimes leaving an empty output file when a test ends with signal/structured exception.
* Fixed XML reporter not reporting captured stdout/stderr.
@@ -75,7 +296,7 @@ Other:
* Microbenchmark focused on Catch's overhead went from ~3.4s to ~0.7s.
* Real world test using [JSON for Modern C++](https://github.com/nlohmann/json)'s test suite went from ~6m 25s to ~4m 14s.
* Catch can now run specific sections within test cases.
* For now the support is only basic (no wildcards or tags), for details see the [documentation](docs/command-line.md).
* For now the support is only basic (no wildcards or tags), for details see the [documentation](command-line.md).
* Catch now supports SEH on Windows as well as signals on Linux.
* After receiving a signal, Catch reports failing assertion and then passes the signal onto the previous handler.
* Approx can be used to compare values against strong typedefs (available in C++11 mode only).
@@ -112,7 +333,7 @@ Other:
* Approval tests can now be run on Windows
* CMake will now warn if a file is present in the `include` folder but not is not enumerated as part of the project
* Catch now defines `NOMINMAX` and `WIN32_LEAN_AND_MEAN` before including `windows.h`
* This can be disabled if needed, see [documentation](docs/configuration.md) for details.
* This can be disabled if needed, see [documentation](configuration.md) for details.
## 1.6.0

63
docs/release-process.md Normal file
View File

@@ -0,0 +1,63 @@
# How to release
When enough changes have accumulated, it is time to release new version of Catch. This document describes the proces in doing so, that no steps are forgotten. Note that all referenced scripts can be found in the `scripts/` directory.
## Neccessary steps
These steps are neccessary and have to be performed before each new release. They serve to make sure that the new release is correct and linked-to from the standard places.
### Approval testing
Catch's releases are primarily validated against output from previous release, stored in `projects/SelfTest/Baselines`. To validate current sources, build the SelfTest binary and pass it to the `approvalTests.py` script: `approvalTests.py <path/to/SelfTest>`.
There should be no differences, as Approval tests should be updated when changes to Catch are made, but if there are, then they need to be manually reviewed and either approved (using `approve.py`) or Catch requires other fixes.
### Incrementing version number
Catch uses a variant of [semantic versioning](http://semver.org/), with breaking API changes (and thus major version increments) being very rare. Thus, the release will usually increment the patch version, when it only contains couple of bugfixes, or minor version, when it contains new functionality, or larger changes in implementation of current functionality.
After deciding which part of version number should be incremented, you can use one of the `*Release.py` scripts to perform the required changes to Catch.
### Generate updated single-include header
After updating version number, regenerate single-include header using `generateSingleHeader.py`.
### Release notes
Once a release is ready, release notes need to be written. They should summarize changes done since last release. For rough idea of expected notes see previous releases. Once written, release notes should be placed in `docs/release-notes.md`.
### Commit and push update to GitHub
After version number is incremented, single-include header is regenerated and release notes are updated, changes should be commited and pushed to GitHub.
### Release on GitHub
After pushing changes to GitHub, GitHub release *needs* to be created. Tag version and release title should be same as the new version, description should contain the release notes for the current release. Single header version of `catch.hpp` *needs* to be attached as a binary, as that is where the official download link links to. Preferably it should use linux line endings.
## Optional steps
The following steps are optional, and do not have to be performed when releasing new version of Catch. However, they are *should* happen, but they can happen the next day without losing anything significant.
### vcpkg update
Catch is maintaining its own port in Microsoft's package manager [vcpkg](https://github.com/Microsoft/vcpkg). This means that when new version of Catch is released, it should be posted there as well. `updateVcpkgPackage.py` can do a lot of neccessary work for you, it creates a branch and commits neccessary changes. You should review these changes, push and open a PR against vcpkg's upstream.
Note that the script assumes you have your fork of vcpkg checked out in a directory next to the directory where you have checked out Catch, like so:
```
GitHub
Catch
vcpkg
```
### Wandbox update
Recently we also included a link to wandbox with preloaded Catch on the main page. Strictly speaking it is unneccessary to update this after every release, Catch usually does not change that much between versions, but it should be kept up to date anyway.

45
docs/reporters.md Normal file
View File

@@ -0,0 +1,45 @@
# Reporters
Catch has a modular reporting system and comes bundled with a handful of useful reporters built in.
You can also write your own reporters.
## Using different reporters
The reporter to use can easily be controlled from the command line.
To specify a reporter use [`-r` or `--reporter`](command-line.md#choosing-a-reporter-to-use), followed by the name of the reporter, e.g.:
```
-r xml
```
If you don't specify a reporter then the console reporter is used by default.
There are four reporters built in to the single include:
* `console` writes as lines of text, formatted to a typical terminal width, with colours if a capable terminal is detected.
* `compact` similar to `console` but optimised for minimal output - each entry on one line
* `junit` writes xml that corresponds to Ant's [junitreport](http://help.catchsoftware.com/display/ET/JUnit+Format) target. Useful for build systems that understand Junit. If you are using Jenkins with Catch 1.x, you can improve quality of output by applying changes in [#923](https://github.com/philsquared/Catch/pull/923).
Because of the way the junit format is structured the run must complete before anything is written.
* `xml` writes an xml format tailored to Catch. Unlike `junit` this is a streaming format so results are delivered progressively.
There are a few additional reporters, for specific build systems, in the Catch repository (in `include\reporters`) which you can `#include` in your project if you would like to make use of them.
Do this in one source file - typically the same one you have `CATCH_CONFIG_MAIN` or `CATCH_CONFIG_RUNNER`.
* `teamcity` writes the native, streaming, format that [TeamCity](https://www.jetbrains.com/teamcity/) understands.
Use this when building as part of a TeamCity build to see results as they happen.
* `tap` writes in the TAP ([Test Anything Protocol](https://en.wikipedia.org/wiki/Test_Anything_Protocol)) format.
* `automake` writes in a format that correspond to [automake .trs](https://www.gnu.org/software/automake/manual/html_node/Log-files-generation-and-test-results-recording.html) files
You see what reporters are available from the command line by running with `--list-reporters`.
By default all these reports are written to stdout, but can be redirected to a file with [`-o` or `--out`](command-line.md#sending-output-to-a-file)
## Writing your own reporter
You can write your own custom reporter and register it with Catch.
At time of writing the interface is subject to some changes so is not, yet, documented here.
If you are determined you shouldn't have too much trouble working it out from the existing implementations -
but do keep in mind upcoming changes (these will be minor, simplifying, changes such as not needing to forward calls to the base class).
---
[Home](Readme.md)

View File

@@ -28,7 +28,7 @@ The tag expression, ```"[widget]"``` selects A, B & D. ```"[gadget]"``` selects
For more detail on command line selection see [the command line docs](command-line.md#specifying-which-tests-to-run)
Tag names are not case sensitive.
Tag names are not case sensitive and can contain any ASCII characters. This means that tags `[tag with spaces]` and `[I said "good day"]` are both allowed tags and can be filtered on. Escapes are not supported however and `[\]]` is not a valid tag.
### Special Tags
@@ -38,19 +38,19 @@ All tag names beginning with non-alphanumeric characters are reserved by Catch.
* `[!throws]` - lets Catch know that this test is likely to throw an exception even if successful. This causes the test to be excluded when running with `-e` or `--nothrow`.
* `[!shouldfail]` - reverse the failing logic of the test: if the test is successful if it fails, and vice-versa.
* `[!mayfail]` - doesn't fail the test if any given assertion fails (but still reports it). This can be useful to flag a work-in-progress, or a known issue that you don't want to immediately fix but still want to track in your tests.
* `[!mayfail]` - doesn't fail the test if any given assertion fails (but still reports it). This can be useful to flag a work-in-progress, or a known issue that you don't want to immediately fix but still want to track in the your tests.
* `[!shouldfail]` - like `[!mayfail]` but *fails* the test if it *passes*. This can be useful if you want to be notified of accidental, or third-party, fixes.
* `[!nonportable]` - Indicates that behaviour may vary between platforms or compilers.
* `[#<filename>]` - running with `-#` or `--filenames-as-tags` causes Catch to add the filename, prefixed with `#` (and with any extension stripped) as a tag. e.g. tests in testfile.cpp would all be tagged `[#testfile]`.
* `[#<filename>]` - running with `-#` or `--filenames-as-tags` causes Catch to add the filename, prefixed with `#` (and with any extension stripped), as a tag to all contained tests, e.g. tests in testfile.cpp would all be tagged `[#testfile]`.
* `[@<alias>]` - tag aliases all begin with `@` (see below).
## Tag aliases
Between tag expressions and wildcarded test names (as well as combinations of the two) quite complex patterns can be constructed to direct which test cases are run. If a complex pattern is used often it is convenient to be able to create an alias for the expression. this can be done, in code, using the following form:
Between tag expressions and wildcarded test names (as well as combinations of the two) quite complex patterns can be constructed to direct which test cases are run. If a complex pattern is used often it is convenient to be able to create an alias for the expression. This can be done, in code, using the following form:
CATCH_REGISTER_TAG_ALIAS( <alias string>, <tag expression> )

View File

@@ -16,16 +16,7 @@ std::ostream& operator << ( std::ostream& os, T const& value ) {
(where ```T``` is your type and ```convertMyTypeToString``` is where you'll write whatever code is necessary to make your type printable - it doesn't have to be in another function).
You should put this function in the same namespace as your type.
Alternatively you may prefer to write it as a member function:
```
std::ostream& T::operator << ( std::ostream& os ) const {
os << convertMyTypeToString( *this );
return os;
}
```
You should put this function in the same namespace as your type and it has to be declared before including Catch's header.
## Catch::toString overload
@@ -39,11 +30,12 @@ namespace Catch {
}
```
Again ```T``` is your type and ```convertMyTypeToString``` is where you'll write whatever code is necessary to make your type printable. Note that the function must be in the Catch namespace, which itself must be in the global namespace.
Again ```T``` is your type and ```convertMyTypeToString``` is where you'll write whatever code is necessary to make your type printable. Note that the function must be in the Catch namespace, which itself must be in the global namespace and must be declared _before_ Catch's header is included.
**Please note that overloading `Catch::toString` is currently considered legacy and will not be supported in the next major version of Catch.**
## Catch::StringMaker<T> specialisation
There are some cases where overloading toString does not work as expected. Specialising StringMaker<T> gives you more precise, and reliable, control - but at the cost of slightly more code and complexity:
Another way of telling Catch how to convert a type to string is specialising `Catch::StringMaker` template. This allows you to have separate way of stringifying types for Catch, than you have for writing it to a stream and also doesn't require you to declare it before including Catch's header.
```
namespace Catch {

View File

@@ -1,6 +1,6 @@
# Getting Catch
The simplest way to get Catch is to download the latest [single header version](https://raw.githubusercontent.com/philsquared/Catch/master/single_include/catch.hpp). The single header is generated by merging a set of individual headers but it is still just normal source code in a header file.
The simplest way to get Catch is to download the latest [single header version](https://github.com/philsquared/Catch/releases/download/v1.12.2/catch.hpp). The single header is generated by merging a set of individual headers but it is still just normal source code in a header file.
The full source for Catch, including test projects, documentation, and other things, is hosted on GitHub. [http://catch-lib.net](http://catch-lib.net) will redirect you there.
@@ -68,7 +68,7 @@ with expansion:
0 == 1
```
Note that we get the actual return value of Factorial(0) printed for us (0) - even though we used a natural expression with the == operator. That let's us immediately see what the problem is.
Note that we get the actual return value of Factorial(0) printed for us (0) - even though we used a natural expression with the == operator. That lets us immediately see what the problem is.
Let's change the factorial function to:
@@ -80,7 +80,7 @@ unsigned int Factorial( unsigned int number ) {
Now all the tests pass.
Of course there are still more issues to do deal with. For example we'll hit problems when the return value starts to exceed the range of an unsigned int. With factorials that can happen quite quickly. You might want to add tests for such cases and decide how to handle them. We'll stop short of doing that here.
Of course there are still more issues to deal with. For example we'll hit problems when the return value starts to exceed the range of an unsigned int. With factorials that can happen quite quickly. You might want to add tests for such cases and decide how to handle them. We'll stop short of doing that here.
## What did we do here?

View File

@@ -57,16 +57,16 @@
#include <crtdbg.h>
class LeakDetector {
public:
LeakDetector() {
int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
flag |= _CRTDBG_LEAK_CHECK_DF;
flag |= _CRTDBG_ALLOC_MEM_DF;
_CrtSetDbgFlag(flag);
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
// Change this to leaking allocation's number to break there
_CrtSetBreakAlloc(-1);
}
LeakDetector() {
int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
flag |= _CRTDBG_LEAK_CHECK_DF;
flag |= _CRTDBG_ALLOC_MEM_DF;
_CrtSetDbgFlag(flag);
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
// Change this to leaking allocation's number to break there
_CrtSetBreakAlloc(-1);
}
};
#else
class LeakDetector {};
@@ -91,33 +91,44 @@ LeakDetector leakDetector;
// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
#ifdef CATCH_CONFIG_PREFIX_ALL
#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" )
#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" )
#if defined(CATCH_CONFIG_FAST_COMPILE)
#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, expr )
#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr )
#else
#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, expr )
#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr )
#endif
#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "CATCH_REQUIRE_THROWS" )
#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" )
#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "CATCH_REQUIRE_THROWS_WITH" )
#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" )
#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", expr )
#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, expr )
#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" )
#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" )
#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" )
#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" )
#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" )
#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, expr )
#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, expr )
#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, expr )
#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, expr )
#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, expr )
#define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "", "CATCH_CHECK_THROWS" )
#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" )
#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CATCH_CHECK_THROWS_WITH" )
#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" )
#define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", expr )
#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, expr )
#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" )
#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" )
#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg )
#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
#if defined(CATCH_CONFIG_FAST_COMPILE)
#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
#else
#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
#endif
#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << Catch::toString(msg) )
#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << Catch::toString(msg) )
#ifdef CATCH_CONFIG_VARIADIC_MACROS
#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
@@ -125,16 +136,18 @@ LeakDetector leakDetector;
#define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
#define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
#define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ )
#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ )
#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
#define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#else
#define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
#define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
#define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
#define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description )
#define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
#define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg )
#define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg )
#define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, msg )
#define CATCH_FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, msg )
#define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, msg )
#endif
#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
@@ -160,50 +173,64 @@ LeakDetector leakDetector;
// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
#else
#define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" )
#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" )
#if defined(CATCH_CONFIG_FAST_COMPILE)
#define REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "REQUIRE", Catch::ResultDisposition::Normal, expr )
#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr )
#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "REQUIRE_THROWS" )
#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" )
#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "REQUIRE_THROWS_WITH" )
#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" )
#else
#define REQUIRE( expr ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, expr )
#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr )
#endif
#define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" )
#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" )
#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" )
#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" )
#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" )
#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", expr )
#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, expr )
#define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "", "CHECK_THROWS" )
#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CHECK_THROWS_WITH" )
#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
#define CHECK( expr ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, expr )
#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, expr )
#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, expr )
#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, expr )
#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, expr )
#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" )
#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" )
#define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", expr )
#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, expr )
#define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
#define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg )
#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
#define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
#if defined(CATCH_CONFIG_FAST_COMPILE)
#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
#else
#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
#endif
#define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
#define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
#define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << Catch::toString(msg) )
#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << Catch::toString(msg) )
#ifdef CATCH_CONFIG_VARIADIC_MACROS
#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
#define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ )
#define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ )
#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
#define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#else
#define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
#define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
#define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
#define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
#define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description )
#define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
#define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg )
#define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg )
#define FAIL( msg ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, msg )
#define FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, msg )
#define SUCCEED( msg ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, msg )
#endif
#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )

View File

@@ -31,10 +31,14 @@ namespace Catch {
return reporter;
}
#if !defined(CATCH_CONFIG_DEFAULT_REPORTER)
#define CATCH_CONFIG_DEFAULT_REPORTER "console"
#endif
Ptr<IStreamingReporter> makeReporter( Ptr<Config> const& config ) {
std::vector<std::string> reporters = config->getReporterNames();
if( reporters.empty() )
reporters.push_back( "console" );
reporters.push_back( CATCH_CONFIG_DEFAULT_REPORTER );
Ptr<IStreamingReporter> reporter;
for( std::vector<std::string>::const_iterator it = reporters.begin(), itEnd = reporters.end();
@@ -95,11 +99,11 @@ namespace Catch {
if( lastSlash != std::string::npos )
filename = filename.substr( lastSlash+1 );
std::string::size_type lastDot = filename.find_last_of( "." );
std::string::size_type lastDot = filename.find_last_of( '.' );
if( lastDot != std::string::npos )
filename = filename.substr( 0, lastDot );
tags.insert( "#" + filename );
tags.insert( '#' + filename );
setTags( test, tags );
}
}
@@ -125,11 +129,18 @@ namespace Catch {
}
void showHelp( std::string const& processName ) {
Catch::cout() << "\nCatch v" << libraryVersion << "\n";
Catch::cout() << "\nCatch v" << libraryVersion() << "\n";
m_cli.usage( Catch::cout(), processName );
Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
}
void libIdentify() {
Catch::cout()
<< std::left << std::setw(16) << "description: " << "A Catch test executable\n"
<< std::left << std::setw(16) << "category: " << "testframework\n"
<< std::left << std::setw(16) << "framework: " << "Catch Test\n"
<< std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
}
int applyCommandLine( int argc, char const* const* const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
try {
@@ -137,6 +148,8 @@ namespace Catch {
m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData );
if( m_configData.showHelp )
showHelp( m_configData.processName );
if( m_configData.libIdentify )
libIdentify();
m_config.reset();
}
catch( std::exception& ex ) {
@@ -166,8 +179,63 @@ namespace Catch {
return returnCode;
}
#if defined(WIN32) && defined(UNICODE)
int run( int argc, wchar_t const* const* const argv ) {
char **utf8Argv = new char *[ argc ];
for ( int i = 0; i < argc; ++i ) {
int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL );
utf8Argv[ i ] = new char[ bufSize ];
WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
}
int returnCode = applyCommandLine( argc, utf8Argv );
if( returnCode == 0 )
returnCode = run();
for ( int i = 0; i < argc; ++i )
delete [] utf8Argv[ i ];
delete [] utf8Argv;
return returnCode;
}
#endif
int run() {
if( m_configData.showHelp )
if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
static_cast<void>(std::getchar());
}
int exitCode = runInternal();
if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {
Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
static_cast<void>(std::getchar());
}
return exitCode;
}
Clara::CommandLine<ConfigData> const& cli() const {
return m_cli;
}
std::vector<Clara::Parser::Token> const& unusedTokens() const {
return m_unusedTokens;
}
ConfigData& configData() {
return m_configData;
}
Config& config() {
if( !m_config )
m_config = new Config( m_configData );
return *m_config;
}
private:
int runInternal() {
if( m_configData.showHelp || m_configData.libIdentify )
return 0;
try
@@ -191,21 +259,6 @@ namespace Catch {
}
}
Clara::CommandLine<ConfigData> const& cli() const {
return m_cli;
}
std::vector<Clara::Parser::Token> const& unusedTokens() const {
return m_unusedTokens;
}
ConfigData& configData() {
return m_configData;
}
Config& config() {
if( !m_config )
m_config = new Config( m_configData );
return *m_config;
}
private:
Clara::CommandLine<ConfigData> m_cli;
std::vector<Clara::Parser::Token> m_unusedTokens;
ConfigData m_configData;

View File

@@ -41,6 +41,7 @@
#include <vector>
#include <sstream>
#include <algorithm>
#include <cctype>
// Use optional outer namespace
#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
@@ -150,7 +151,7 @@ namespace Tbc {
return oss.str();
}
inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
it != itEnd; ++it ) {
if( it != _text.begin() )
@@ -397,7 +398,7 @@ namespace Clara {
_dest = _source;
}
char toLowerCh(char c) {
return static_cast<char>( ::tolower( c ) );
return static_cast<char>( std::tolower( c ) );
}
inline void convertInto( std::string const& _source, bool& _dest ) {
std::string sourceLC = _source;
@@ -553,12 +554,13 @@ namespace Clara {
}
void parseIntoTokens( std::string const& arg, std::vector<Token>& tokens ) {
for( std::size_t i = 0; i <= arg.size(); ++i ) {
for( std::size_t i = 0; i < arg.size(); ++i ) {
char c = arg[i];
if( c == '"' )
inQuotes = !inQuotes;
mode = handleMode( i, c, arg, tokens );
}
mode = handleMode( arg.size(), '\0', arg, tokens );
}
Mode handleMode( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
switch( mode ) {
@@ -591,6 +593,7 @@ namespace Clara {
default: from = i; return ShortOpt;
}
}
Mode handleOpt( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
if( std::string( ":=\0", 3 ).find( c ) == std::string::npos )
return mode;
@@ -924,7 +927,7 @@ namespace Clara {
}
std::vector<Parser::Token> parseInto( std::vector<std::string> const& args, ConfigT& config ) const {
std::string processName = args[0];
std::string processName = args.empty() ? std::string() : args[0];
std::size_t lastSlash = processName.find_last_of( "/\\" );
if( lastSlash != std::string::npos )
processName = processName.substr( lastSlash+1 );

View File

@@ -29,26 +29,26 @@ namespace Detail {
m_value( value )
{}
Approx( Approx const& other )
: m_epsilon( other.m_epsilon ),
m_margin( other.m_margin ),
m_scale( other.m_scale ),
m_value( other.m_value )
{}
static Approx custom() {
return Approx( 0 );
}
Approx operator()( double value ) {
Approx approx( value );
#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
Approx operator()( T value ) {
Approx approx( static_cast<double>(value) );
approx.epsilon( m_epsilon );
approx.margin( m_margin );
approx.scale( m_scale );
return approx;
}
#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
explicit Approx( T value ): Approx(static_cast<double>(value))
{}
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
friend bool operator == ( const T& lhs, Approx const& rhs ) {
// Thanks to Richard Harris for his help refining this formula
@@ -57,7 +57,8 @@ namespace Detail {
if (relativeOK) {
return true;
}
return std::fabs(lhs_v - rhs.m_value) < rhs.m_margin;
return std::fabs(lhs_v - rhs.m_value) <= rhs.m_margin;
}
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
@@ -76,36 +77,61 @@ namespace Detail {
}
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
friend bool operator <= ( T lhs, Approx const& rhs )
{
return double(lhs) < rhs.m_value || lhs == rhs;
friend bool operator <= ( T lhs, Approx const& rhs ) {
return double(lhs) < rhs.m_value || lhs == rhs;
}
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
friend bool operator <= ( Approx const& lhs, T rhs )
{
return lhs.m_value < double(rhs) || lhs == rhs;
friend bool operator <= ( Approx const& lhs, T rhs ) {
return lhs.m_value < double(rhs) || lhs == rhs;
}
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
friend bool operator >= ( T lhs, Approx const& rhs )
{
return double(lhs) > rhs.m_value || lhs == rhs;
friend bool operator >= ( T lhs, Approx const& rhs ) {
return double(lhs) > rhs.m_value || lhs == rhs;
}
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
friend bool operator >= ( Approx const& lhs, T rhs )
{
return lhs.m_value > double(rhs) || lhs == rhs;
friend bool operator >= ( Approx const& lhs, T rhs ) {
return lhs.m_value > double(rhs) || lhs == rhs;
}
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
Approx& epsilon( T newEpsilon ) {
m_epsilon = double(newEpsilon);
return *this;
}
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
Approx& margin( T newMargin ) {
m_margin = double(newMargin);
return *this;
}
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
Approx& scale( T newScale ) {
m_scale = double(newScale);
return *this;
}
#else
Approx operator()( double value ) {
Approx approx( value );
approx.epsilon( m_epsilon );
approx.margin( m_margin );
approx.scale( m_scale );
return approx;
}
friend bool operator == ( double lhs, Approx const& rhs ) {
// Thanks to Richard Harris for his help refining this formula
bool relativeOK = std::fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( std::fabs(lhs), std::fabs(rhs.m_value) ) );
if (relativeOK) {
return true;
}
return std::fabs(lhs - rhs.m_value) < rhs.m_margin;
return std::fabs(lhs - rhs.m_value) <= rhs.m_margin;
}
friend bool operator == ( Approx const& lhs, double rhs ) {
@@ -120,26 +146,21 @@ namespace Detail {
return !operator==( rhs, lhs );
}
friend bool operator <= ( double lhs, Approx const& rhs )
{
return lhs < rhs.m_value || lhs == rhs;
friend bool operator <= ( double lhs, Approx const& rhs ) {
return lhs < rhs.m_value || lhs == rhs;
}
friend bool operator <= ( Approx const& lhs, double rhs )
{
return lhs.m_value < rhs || lhs == rhs;
friend bool operator <= ( Approx const& lhs, double rhs ) {
return lhs.m_value < rhs || lhs == rhs;
}
friend bool operator >= ( double lhs, Approx const& rhs )
{
return lhs > rhs.m_value || lhs == rhs;
friend bool operator >= ( double lhs, Approx const& rhs ) {
return lhs > rhs.m_value || lhs == rhs;
}
friend bool operator >= ( Approx const& lhs, double rhs )
{
return lhs.m_value > rhs || lhs == rhs;
friend bool operator >= ( Approx const& lhs, double rhs ) {
return lhs.m_value > rhs || lhs == rhs;
}
#endif
Approx& epsilon( double newEpsilon ) {
m_epsilon = newEpsilon;
@@ -155,6 +176,7 @@ namespace Detail {
m_scale = newScale;
return *this;
}
#endif
std::string toString() const {
std::ostringstream oss;

View File

@@ -33,22 +33,24 @@ namespace Catch {
template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( T const& );
template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( T const& );
private:
DecomposedExpression& operator = (DecomposedExpression const&);
private:
DecomposedExpression& operator = (DecomposedExpression const&);
};
struct AssertionInfo
{
AssertionInfo() {}
AssertionInfo( std::string const& _macroName,
AssertionInfo();
AssertionInfo( char const * _macroName,
SourceLineInfo const& _lineInfo,
std::string const& _capturedExpression,
ResultDisposition::Flags _resultDisposition );
char const * _capturedExpression,
ResultDisposition::Flags _resultDisposition,
char const * _secondArg = "");
std::string macroName;
char const * macroName;
SourceLineInfo lineInfo;
std::string capturedExpression;
char const * capturedExpression;
ResultDisposition::Flags resultDisposition;
char const * secondArg;
};
struct AssertionResultData

View File

@@ -13,14 +13,18 @@
namespace Catch {
AssertionInfo::AssertionInfo( std::string const& _macroName,
AssertionInfo::AssertionInfo():macroName(""), capturedExpression(""), resultDisposition(ResultDisposition::Normal), secondArg(""){}
AssertionInfo::AssertionInfo( char const * _macroName,
SourceLineInfo const& _lineInfo,
std::string const& _capturedExpression,
ResultDisposition::Flags _resultDisposition )
char const * _capturedExpression,
ResultDisposition::Flags _resultDisposition,
char const * _secondArg)
: macroName( _macroName ),
lineInfo( _lineInfo ),
capturedExpression( _capturedExpression ),
resultDisposition( _resultDisposition )
resultDisposition( _resultDisposition ),
secondArg( _secondArg )
{}
AssertionResult::AssertionResult() {}
@@ -47,24 +51,30 @@ namespace Catch {
}
bool AssertionResult::hasExpression() const {
return !m_info.capturedExpression.empty();
return m_info.capturedExpression[0] != 0;
}
bool AssertionResult::hasMessage() const {
return !m_resultData.message.empty();
}
std::string capturedExpressionWithSecondArgument( char const * capturedExpression, char const * secondArg ) {
return (secondArg[0] == 0 || secondArg[0] == '"' && secondArg[1] == '"')
? capturedExpression
: std::string(capturedExpression) + ", " + secondArg;
}
std::string AssertionResult::getExpression() const {
if( isFalseTest( m_info.resultDisposition ) )
return '!' + m_info.capturedExpression;
return "!(" + capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg) + ")";
else
return m_info.capturedExpression;
return capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg);
}
std::string AssertionResult::getExpressionInMacro() const {
if( m_info.macroName.empty() )
return m_info.capturedExpression;
if( m_info.macroName[0] == 0 )
return capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg);
else
return m_info.macroName + "( " + m_info.capturedExpression + " )";
return std::string(m_info.macroName) + "( " + capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg) + " )";
}
bool AssertionResult::hasExpandedExpression() const {

View File

@@ -16,9 +16,14 @@
#include "catch_tostring.h"
#include "catch_interfaces_runner.h"
#include "catch_compiler_capabilities.h"
#include "catch_type_traits.hpp"
#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
# define CATCH_INTERNAL_STRINGIFY(expr) #expr
#else
# define CATCH_INTERNAL_STRINGIFY(expr) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
#endif
#if defined(CATCH_CONFIG_FAST_COMPILE)
///////////////////////////////////////////////////////////////////////////////
// We can speedup compilation significantly by breaking into debugger lower in
@@ -26,6 +31,33 @@
// macro in each assertion
#define INTERNAL_CATCH_REACT( resultBuilder ) \
resultBuilder.react();
///////////////////////////////////////////////////////////////////////////////
// Another way to speed-up compilation is to omit local try-catch for REQUIRE*
// macros.
// This can potentially cause false negative, if the test code catches
// the exception before it propagates back up to the runner.
#define INTERNAL_CATCH_TEST_NO_TRY( macroName, resultDisposition, expr ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \
__catchResult.setExceptionGuard(); \
CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
( __catchResult <= expr ).endExpression(); \
CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
__catchResult.unsetExceptionGuard(); \
INTERNAL_CATCH_REACT( __catchResult ) \
} while( Catch::isTrue( false && static_cast<bool>( !!(expr) ) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
// The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
#define INTERNAL_CHECK_THAT_NO_TRY( macroName, matcher, resultDisposition, arg ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
__catchResult.setExceptionGuard(); \
__catchResult.captureMatch( arg, matcher, CATCH_INTERNAL_STRINGIFY(matcher) ); \
__catchResult.unsetExceptionGuard(); \
INTERNAL_CATCH_REACT( __catchResult ) \
} while( Catch::alwaysFalse() )
#else
///////////////////////////////////////////////////////////////////////////////
// In the event of a failure works out if the debugger needs to be invoked
@@ -34,14 +66,14 @@
// source code rather than in Catch library code
#define INTERNAL_CATCH_REACT( resultBuilder ) \
if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
resultBuilder.react();
resultBuilder.react();
#endif
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \
#define INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \
try { \
CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
( __catchResult <= expr ).endExpression(); \
@@ -55,19 +87,19 @@
// The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
if( Catch::getResultCapture().getLastResult()->succeeded() )
#define INTERNAL_CATCH_IF( macroName, resultDisposition, expr ) \
INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \
if( Catch::getResultCapture().lastAssertionPassed() )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \
INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
if( !Catch::getResultCapture().getLastResult()->succeeded() )
#define INTERNAL_CATCH_ELSE( macroName, resultDisposition, expr ) \
INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \
if( !Catch::getResultCapture().lastAssertionPassed() )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \
#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, expr ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \
try { \
static_cast<void>(expr); \
__catchResult.captureResult( Catch::ResultWas::Ok ); \
@@ -79,9 +111,9 @@
} while( Catch::alwaysFalse() )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_THROWS( expr, resultDisposition, matcher, macroName ) \
#define INTERNAL_CATCH_THROWS( macroName, resultDisposition, matcher, expr ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition, CATCH_INTERNAL_STRINGIFY(matcher) ); \
if( __catchResult.allowThrows() ) \
try { \
static_cast<void>(expr); \
@@ -96,15 +128,15 @@
} while( Catch::alwaysFalse() )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
#define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr ", " #exceptionType, resultDisposition ); \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
if( __catchResult.allowThrows() ) \
try { \
static_cast<void>(expr); \
__catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
} \
catch( Catch::add_const<Catch::add_lvalue_reference<exceptionType>::type>::type ) { \
catch( exceptionType ) { \
__catchResult.captureResult( Catch::ResultWas::Ok ); \
} \
catch( ... ) { \
@@ -118,7 +150,7 @@
///////////////////////////////////////////////////////////////////////////////
#ifdef CATCH_CONFIG_VARIADIC_MACROS
#define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \
#define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
__catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
@@ -126,7 +158,7 @@
INTERNAL_CATCH_REACT( __catchResult ) \
} while( Catch::alwaysFalse() )
#else
#define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \
#define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, log ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
__catchResult << log + ::Catch::StreamEndStop(); \
@@ -136,15 +168,15 @@
#endif
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_INFO( log, macroName ) \
#define INTERNAL_CATCH_INFO( macroName, log ) \
Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
#define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
try { \
__catchResult.captureMatch( arg, matcher, #matcher ); \
__catchResult.captureMatch( arg, matcher, CATCH_INTERNAL_STRINGIFY(matcher) ); \
} catch( ... ) { \
__catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
} \

View File

@@ -76,6 +76,19 @@ namespace Catch {
else
throw std::runtime_error( "colour mode must be one of: auto, yes or no" );
}
inline void setWaitForKeypress( ConfigData& config, std::string const& keypress ) {
std::string keypressLc = toLower( keypress );
if( keypressLc == "start" )
config.waitForKeypress = WaitForKeypress::BeforeStart;
else if( keypressLc == "exit" )
config.waitForKeypress = WaitForKeypress::BeforeExit;
else if( keypressLc == "both" )
config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
else
throw std::runtime_error( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" );
};
inline void forceColour( ConfigData& config ) {
config.useColour = UseColour::Yes;
}
@@ -187,6 +200,10 @@ namespace Catch {
.describe( "list all/matching test cases names only" )
.bind( &ConfigData::listTestNamesOnly );
cli["--list-extra-info"]
.describe( "list all/matching test cases with more info" )
.bind( &ConfigData::listExtraInfo );
cli["--list-reporters"]
.describe( "list all reporters" )
.bind( &ConfigData::listReporters );
@@ -207,6 +224,14 @@ namespace Catch {
.describe( "should output be colourised" )
.bind( &setUseColour, "yes|no" );
cli["--libidentify"]
.describe( "report name and version according to libidentify standard" )
.bind( &ConfigData::libIdentify );
cli["--wait-for-keypress"]
.describe( "waits for a keypress before exiting" )
.bind( &setWaitForKeypress, "start|exit|both" );
return cli;
}

View File

@@ -61,14 +61,14 @@ namespace Catch {
};
template<typename ContainerT>
inline void deleteAll( ContainerT& container ) {
void deleteAll( ContainerT& container ) {
typename ContainerT::const_iterator it = container.begin();
typename ContainerT::const_iterator itEnd = container.end();
for(; it != itEnd; ++it )
delete *it;
}
template<typename AssociativeContainerT>
inline void deleteAllValues( AssociativeContainerT& container ) {
void deleteAllValues( AssociativeContainerT& container ) {
typename AssociativeContainerT::const_iterator it = container.begin();
typename AssociativeContainerT::const_iterator itEnd = container.end();
for(; it != itEnd; ++it )

View File

@@ -63,6 +63,12 @@
# endif
# if defined(CATCH_CPP11_OR_GREATER)
# define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
_Pragma( "clang diagnostic push" ) \
_Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" )
# define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
_Pragma( "clang diagnostic pop" )
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
_Pragma( "clang diagnostic push" ) \
_Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
@@ -74,13 +80,28 @@
////////////////////////////////////////////////////////////////////////////////
// Cygwin
#ifdef __CYGWIN__
// We know some environments not to support full POSIX signals
#if defined(__CYGWIN__) || defined(__QNX__)
# if !defined(CATCH_CONFIG_POSIX_SIGNALS)
# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
# endif
#endif
#ifdef __OS400__
# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
# define CATCH_CONFIG_COLOUR_NONE
#endif
////////////////////////////////////////////////////////////////////////////////
// Cygwin
#ifdef __CYGWIN__
// Required for some versions of Cygwin to declare gettimeofday
// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
# define _BSD_SOURCE
#endif // __CYGWIN__
////////////////////////////////////////////////////////////////////////////////
@@ -108,23 +129,10 @@
// GCC
#ifdef __GNUC__
# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
# define CATCH_GCC_HAS_NEW_PRAGMA
# endif
# if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
# endif
# if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) && defined(CATCH_GCC_HAS_NEW_PRAGMA)
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
_Pragma( "GCC diagnostic push" ) \
_Pragma( "GCC diagnostic ignored \"-Wparentheses\"" )
# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
_Pragma( "GCC diagnostic pop" )
# endif
// - otherwise more recent versions define __cplusplus >= 201103L
// and will get picked up below
@@ -155,7 +163,7 @@
////////////////////////////////////////////////////////////////////////////////
// Use variadic macros if the compiler supports them
#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
#if ( defined _MSC_VER && _MSC_VER >= 1400 && !defined __EDGE__) || \
( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
( defined __GNUC__ && __GNUC__ >= 3 ) || \
( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
@@ -166,10 +174,15 @@
// Use __COUNTER__ if the compiler supports it
#if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \
( defined __GNUC__ && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 ) || \
( defined __GNUC__ && ( __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3 )) ) || \
( defined __clang__ && __clang_major__ >= 3 )
#define CATCH_INTERNAL_CONFIG_COUNTER
// Use of __COUNTER__ is suppressed during code analysis in CLion/AppCode 2017.2.x and former,
// because __COUNTER__ is not properly handled by it.
// This does not affect compilation
#if ( !defined __JETBRAINS_IDE__ || __JETBRAINS_IDE__ >= 20170300L )
#define CATCH_INTERNAL_CONFIG_COUNTER
#endif
#endif
@@ -250,10 +263,7 @@
#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)
# define CATCH_CONFIG_CPP11_UNIQUE_PTR
#endif
// Use of __COUNTER__ is suppressed if __JETBRAINS_IDE__ is #defined (meaning we're being parsed by a JetBrains IDE for
// analytics) because, at time of writing, __COUNTER__ is not properly handled by it.
// This does not affect compilation
#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) && !defined(__JETBRAINS_IDE__)
#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
# define CATCH_CONFIG_COUNTER
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_NO_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_NO_CPP11)
@@ -266,7 +276,7 @@
# define CATCH_CONFIG_WINDOWS_SEH
#endif
// This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
#if !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
#if !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
# define CATCH_CONFIG_POSIX_SIGNALS
#endif
@@ -274,6 +284,10 @@
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
#endif
#if !defined(CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS)
# define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS
# define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
#endif
// noexcept support:
#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)

View File

@@ -31,25 +31,29 @@ namespace Catch {
listTags( false ),
listReporters( false ),
listTestNamesOnly( false ),
listExtraInfo( false ),
showSuccessfulTests( false ),
shouldDebugBreak( false ),
noThrow( false ),
showHelp( false ),
showInvisibles( false ),
filenamesAsTags( false ),
libIdentify( false ),
abortAfter( -1 ),
rngSeed( 0 ),
verbosity( Verbosity::Normal ),
warnings( WarnAbout::Nothing ),
showDurations( ShowDurations::DefaultForReporter ),
runOrder( RunTests::InDeclarationOrder ),
useColour( UseColour::Auto )
useColour( UseColour::Auto ),
waitForKeypress( WaitForKeypress::Never )
{}
bool listTests;
bool listTags;
bool listReporters;
bool listTestNamesOnly;
bool listExtraInfo;
bool showSuccessfulTests;
bool shouldDebugBreak;
@@ -57,6 +61,7 @@ namespace Catch {
bool showHelp;
bool showInvisibles;
bool filenamesAsTags;
bool libIdentify;
int abortAfter;
unsigned int rngSeed;
@@ -66,6 +71,7 @@ namespace Catch {
ShowDurations::OrNot showDurations;
RunTests::InWhatOrder runOrder;
UseColour::YesOrNo useColour;
WaitForKeypress::When waitForKeypress;
std::string outputFilename;
std::string name;
@@ -109,6 +115,7 @@ namespace Catch {
bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
bool listTags() const { return m_data.listTags; }
bool listReporters() const { return m_data.listReporters; }
bool listExtraInfo() const { return m_data.listExtraInfo; }
std::string getProcessName() const { return m_data.processName; }

View File

@@ -9,6 +9,7 @@
#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
#include "catch_console_colour.hpp"
#include "catch_errno_guard.hpp"
namespace Catch {
namespace {
@@ -148,6 +149,7 @@ namespace {
};
IColourImpl* platformColourInstance() {
ErrnoGuard guard;
Ptr<IConfig const> config = getCurrentContext().getConfig();
UseColour::YesOrNo colourMode = config
? config->useColour()

View File

@@ -26,9 +26,12 @@ namespace Catch{
#if defined(__ppc64__) || defined(__ppc__)
#define CATCH_TRAP() \
__asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
: : : "memory","r0","r3","r4" )
: : : "memory","r0","r3","r4" ) /* NOLINT */
#elif defined(__aarch64__)
// Backport of https://github.com/catchorg/Catch2/commit/a25c1a24af8bffd35727a888a307ff0280cf9387
#define CATCH_TRAP() __asm__(".inst 0xd4200000")
#else
#define CATCH_TRAP() __asm__("int $3\n" : : )
#define CATCH_TRAP() __asm__("int $3\n" : : /* NOLINT */ )
#endif
#elif defined(CATCH_PLATFORM_LINUX)
@@ -36,7 +39,7 @@ namespace Catch{
// directly at the location of the failing check instead of breaking inside
// raise() called from it, i.e. one stack frame below.
#if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
#define CATCH_TRAP() asm volatile ("int $3")
#define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
#else // Fall back to the generic way.
#include <signal.h>

View File

@@ -10,6 +10,7 @@
#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
#include "catch_debugger.h"
#include "catch_errno_guard.hpp"
#ifdef CATCH_PLATFORM_MAC
@@ -72,6 +73,9 @@
// be strace, for example) in /proc/$PID/status, so just get it from
// there instead.
bool isDebuggerActive(){
// Libstdc++ has a bug, where std::ifstream sets errno to 0
// This way our users can properly assert over errno values
ErrnoGuard guard;
std::ifstream in("/proc/self/status");
for( std::string line; std::getline(in, line); ) {
static const int PREFIX_LEN = 11;

View File

@@ -10,9 +10,15 @@
#ifndef __OBJC__
#if defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
// Standard C/C++ Win32 Unicode wmain entry point
extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
#else
// Standard C/C++ main entry point
int main (int argc, char * argv[]) {
int result = Catch::Session().run( argc, argv );
#endif
int result = Catch::Session().run( argc, argv );
return ( result < 0xff ? result : 0xff );
}

View File

@@ -0,0 +1,25 @@
/*
* Created by Martin on 06/03/2017.
*
* 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)
*/
#ifndef TWOBLUECUBES_CATCH_ERRNO_GUARD_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_ERRNO_GUARD_HPP_INCLUDED
#include <cerrno>
namespace Catch {
class ErrnoGuard {
public:
ErrnoGuard():m_oldErrno(errno){}
~ErrnoGuard() { errno = m_oldErrno; }
private:
int m_oldErrno;
};
}
#endif // TWOBLUECUBES_CATCH_ERRNO_GUARD_HPP_INCLUDED

View File

@@ -11,6 +11,7 @@
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
#pragma warning(disable:4018) // more "signed/unsigned mismatch"
#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
#endif
@@ -37,7 +38,7 @@ namespace Internal {
template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
template<typename T>
inline T& opCast(T const& t) { return const_cast<T&>(t); }
T& opCast(T const& t) { return const_cast<T&>(t); }
// nullptr_t support based on pull request #154 from Konstantin Baumann
#ifdef CATCH_CONFIG_CPP11_NULLPTR
@@ -48,7 +49,7 @@ namespace Internal {
// So the compare overloads can be operator agnostic we convey the operator as a template
// enum, which is used to specialise an Evaluator for doing the comparison.
template<typename T1, typename T2, Operator Op>
class Evaluator{};
struct Evaluator{};
template<typename T1, typename T2>
struct Evaluator<T1, T2, IsEqualTo> {

View File

@@ -81,7 +81,7 @@ public:
}
virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE {
dest = Catch::toString( m_truthy );
dest = Catch::toString( m_lhs );
}
private:

View File

@@ -9,10 +9,12 @@
#ifndef TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
#include <cassert>
#include <stdexcept>
namespace Catch {
// Report the error condition
//! Signals fatal error message to the run context
inline void reportFatal( std::string const& message ) {
IContext& context = Catch::getCurrentContext();
IResultCapture* resultCapture = context.getResultCapture();
@@ -27,8 +29,31 @@ namespace Catch {
# if !defined ( CATCH_CONFIG_WINDOWS_SEH )
namespace Catch {
struct FatalConditionHandler {
void reset() {}
class FatalConditionHandler {
bool m_started;
// Install/disengage implementation for specific platform.
// Should be if-defed to work on current platform, can assume
// engage-disengage 1:1 pairing.
void engage_platform() {}
void disengage_platform() {}
public:
// Should also have platform-specific implementations as needed
FatalConditionHandler() : m_started(false) {}
~FatalConditionHandler() {}
void engage() {
assert(!m_started && "Handler cannot be installed twice.");
m_started = true;
engage_platform();
}
void disengage() {
assert(m_started && "Handler cannot be uninstalled without being installed first");
m_started = false;
disengage_platform();
}
};
}
@@ -48,54 +73,72 @@ namespace Catch {
{ EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" },
};
struct FatalConditionHandler {
static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
reset();
reportFatal(signalDefs[i].name);
}
static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
reportFatal(signalDefs[i].name);
}
// If its not an exception we care about, pass it along.
// This stops us from eating debugger breaks etc.
return EXCEPTION_CONTINUE_SEARCH;
}
// If its not an exception we care about, pass it along.
// This stops us from eating debugger breaks etc.
return EXCEPTION_CONTINUE_SEARCH;
}
FatalConditionHandler() {
isSet = true;
// 32k seems enough for Catch to handle stack overflow,
// but the value was found experimentally, so there is no strong guarantee
guaranteeSize = 32 * 1024;
exceptionHandlerHandle = CATCH_NULL;
// Since we do not support multiple instantiations, we put these
// into global variables and rely on cleaning them up in outlined
// constructors/destructors
static PVOID exceptionHandlerHandle = CATCH_NULL;
class FatalConditionHandler {
bool m_started;
// Install/disengage implementation for specific platform.
// Should be if-defed to work on current platform, can assume
// engage-disengage 1:1 pairing.
void engage_platform() {
// Register as first handler in current chain
exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
// Pass in guarantee size to be filled
SetThreadStackGuarantee(&guaranteeSize);
}
static void reset() {
if (isSet) {
// Unregister handler and restore the old guarantee
RemoveVectoredExceptionHandler(exceptionHandlerHandle);
SetThreadStackGuarantee(&guaranteeSize);
exceptionHandlerHandle = CATCH_NULL;
isSet = false;
if (!exceptionHandlerHandle) {
throw std::runtime_error("Could not register vectored exception handler");
}
}
~FatalConditionHandler() {
reset();
void disengage_platform() {
if (!RemoveVectoredExceptionHandler(exceptionHandlerHandle)) {
throw std::runtime_error("Could not unregister vectored exception handler");
}
exceptionHandlerHandle = CATCH_NULL;
}
private:
static bool isSet;
static ULONG guaranteeSize;
static PVOID exceptionHandlerHandle;
};
bool FatalConditionHandler::isSet = false;
ULONG FatalConditionHandler::guaranteeSize = 0;
PVOID FatalConditionHandler::exceptionHandlerHandle = CATCH_NULL;
public:
FatalConditionHandler() : m_started(false) {
ULONG guaranteeSize = static_cast<ULONG>(32 * 1024);
if (!SetThreadStackGuarantee(&guaranteeSize)) {
// We do not want to fully error out, because needing
// the stack reserve should be rare enough anyway.
Catch::cerr()
<< "Failed to reserve piece of stack."
<< " Stack overflows will not be reported successfully.";
}
}
// We do not attempt to unset the stack guarantee, because
// Windows does not support lowering the stack size guarantee.
~FatalConditionHandler() {}
void engage() {
assert(!m_started && "Handler cannot be installed twice.");
m_started = true;
engage_platform();
}
void disengage() {
assert(m_started && "Handler cannot be uninstalled without being installed first");
m_started = false;
disengage_platform();
}
};
} // namespace Catch
@@ -106,8 +149,31 @@ namespace Catch {
# if !defined(CATCH_CONFIG_POSIX_SIGNALS)
namespace Catch {
struct FatalConditionHandler {
void reset() {}
class FatalConditionHandler {
bool m_started;
// Install/disengage implementation for specific platform.
// Should be if-defed to work on current platform, can assume
// engage-disengage 1:1 pairing.
void engage_platform() {}
void disengage_platform() {}
public:
// Should also have platform-specific implementations as needed
FatalConditionHandler() : m_started(false) {}
~FatalConditionHandler() {}
void engage() {
assert(!m_started && "Handler cannot be installed twice.");
m_started = true;
engage_platform();
}
void disengage() {
assert(m_started && "Handler cannot be uninstalled without being installed first");
m_started = false;
disengage_platform();
}
};
}
@@ -132,29 +198,56 @@ namespace Catch {
{ SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
};
struct FatalConditionHandler {
// Older GCCs trigger -Wmissing-field-initializers for T foo = {}
// which is zero initialization, but not explicit. We want to avoid
// that.
#if defined(__GNUC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#endif
static bool isSet;
static struct sigaction oldSigActions [sizeof(signalDefs)/sizeof(SignalDefs)];
static stack_t oldSigStack;
static char altStackMem[SIGSTKSZ];
static char* altStackMem = CATCH_NULL;
static std::size_t altStackSize = 0;
static stack_t oldSigStack;
static struct sigaction oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)];
static void handleSignal( int sig ) {
std::string name = "<unknown signal>";
for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
SignalDefs &def = signalDefs[i];
if (sig == def.id) {
name = def.name;
break;
}
}
reset();
reportFatal(name);
raise( sig );
static void restorePreviousSignalHandlers() {
// We set signal handlers back to the previous ones. Hopefully
// nobody overwrote them in the meantime, and doesn't expect
// their signal handlers to live past ours given that they
// installed them after ours..
for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
sigaction(signalDefs[i].id, &oldSigActions[i], CATCH_NULL);
}
// Return the old stack
sigaltstack(&oldSigStack, CATCH_NULL);
}
FatalConditionHandler() {
isSet = true;
static void handleSignal( int sig ) {
char const * name = "<unknown signal>";
for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
SignalDefs &def = signalDefs[i];
if (sig == def.id) {
name = def.name;
break;
}
}
// We need to restore previous signal handlers and let them do
// their thing, so that the users can have the debugger break
// when a signal is raised, and so on.
restorePreviousSignalHandlers();
reportFatal( name );
raise( sig );
}
class FatalConditionHandler {
bool m_started;
// Install/disengage implementation for specific platform.
// Should be if-defed to work on current platform, can assume
// engage-disengage 1:1 pairing.
void engage_platform() {
stack_t sigStack;
sigStack.ss_sp = altStackMem;
sigStack.ss_size = SIGSTKSZ;
@@ -169,28 +262,42 @@ namespace Catch {
}
}
void disengage_platform() {
restorePreviousSignalHandlers();
}
public:
FatalConditionHandler() : m_started(false) {
assert(!altStackMem && "Cannot initialize POSIX signal handler when one already exists");
if (altStackSize == 0) {
altStackSize = SIGSTKSZ;
}
altStackMem = new char[altStackSize]();
}
~FatalConditionHandler() {
reset();
delete[] altStackMem;
// We signal that another instance can be constructed by zeroing
// out the pointer.
altStackMem = CATCH_NULL;
}
static void reset() {
if( isSet ) {
// Set signals back to previous values -- hopefully nobody overwrote them in the meantime
for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
sigaction(signalDefs[i].id, &oldSigActions[i], CATCH_NULL);
}
// Return the old stack
sigaltstack(&oldSigStack, CATCH_NULL);
isSet = false;
}
void engage() {
assert(!m_started && "Handler cannot be installed twice.");
m_started = true;
engage_platform();
}
void disengage() {
assert(m_started && "Handler cannot be uninstalled without being installed first");
m_started = false;
disengage_platform();
}
};
bool FatalConditionHandler::isSet = false;
struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
stack_t FatalConditionHandler::oldSigStack = {};
char FatalConditionHandler::altStackMem[SIGSTKSZ] = {};
#if defined(__GNUC__)
# pragma GCC diagnostic pop
#endif
} // namespace Catch
@@ -198,4 +305,21 @@ namespace Catch {
#endif // not Windows
namespace Catch {
//! Simple RAII guard for (dis)engaging the FatalConditionHandler
class FatalConditionHandlerGuard {
FatalConditionHandler* m_handler;
public:
FatalConditionHandlerGuard(FatalConditionHandler* handler):
m_handler(handler) {
m_handler->engage();
}
~FatalConditionHandlerGuard() {
m_handler->disengage();
}
};
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED

View File

@@ -10,7 +10,6 @@
#include "catch_context.h"
#include <iterator>
#include <vector>
#include <string>
#include <stdlib.h>
@@ -124,7 +123,7 @@ public:
private:
void move( CompositeGenerator& other ) {
std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
m_composed.insert( m_composed.end(), other.m_composed.begin(), other.m_composed.end() );
m_totalSize += other.m_totalSize;
other.m_composed.clear();
}

View File

@@ -91,6 +91,7 @@ namespace Catch {
TestSpec::NamePattern::~NamePattern() {}
TestSpec::TagPattern::~TagPattern() {}
TestSpec::ExcludedPattern::~ExcludedPattern() {}
Matchers::Impl::MatcherUntypedBase::~MatcherUntypedBase() {}
void Config::dummy() {}

View File

@@ -38,7 +38,13 @@ namespace Catch {
virtual std::string getCurrentTestName() const = 0;
virtual const AssertionResult* getLastResult() const = 0;
virtual void exceptionEarlyReported() = 0;
virtual void handleFatalErrorCondition( std::string const& message ) = 0;
virtual bool lastAssertionPassed() = 0;
virtual void assertionPassed() = 0;
virtual void assertionRun() = 0;
};
IResultCapture& getResultCapture();

View File

@@ -42,6 +42,12 @@ namespace Catch {
Yes,
No
}; };
struct WaitForKeypress { enum When {
Never,
BeforeStart = 1,
BeforeExit = 2,
BeforeStartAndExit = BeforeStart | BeforeExit
}; };
class TestSpec;

View File

@@ -20,12 +20,15 @@ namespace Catch {
struct IExceptionTranslator;
struct IReporterRegistry;
struct IReporterFactory;
struct ITagAliasRegistry;
struct IRegistryHub {
virtual ~IRegistryHub();
virtual IReporterRegistry const& getReporterRegistry() const = 0;
virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
};
@@ -35,6 +38,7 @@ namespace Catch {
virtual void registerListener( Ptr<IReporterFactory> const& factory ) = 0;
virtual void registerTest( TestCase const& testInfo ) = 0;
virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
};
IRegistryHub& getRegistryHub();

View File

@@ -30,8 +30,9 @@ namespace Catch {
}
std::size_t matchedTests = 0;
TextAttributes nameAttr, tagsAttr;
TextAttributes nameAttr, descAttr, tagsAttr;
nameAttr.setInitialIndent( 2 ).setIndent( 4 );
descAttr.setIndent( 4 );
tagsAttr.setIndent( 6 );
std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
@@ -46,6 +47,13 @@ namespace Catch {
Colour colourGuard( colour );
Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl;
if( config.listExtraInfo() ) {
Catch::cout() << " " << testCaseInfo.lineInfo << std::endl;
std::string description = testCaseInfo.description;
if( description.empty() )
description = "(NO DESCRIPTION)";
Catch::cout() << Text( description, descAttr ) << std::endl;
}
if( !testCaseInfo.tags.empty() )
Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;
}
@@ -69,9 +77,12 @@ namespace Catch {
matchedTests++;
TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
if( startsWith( testCaseInfo.name, '#' ) )
Catch::cout() << '"' << testCaseInfo.name << '"' << std::endl;
Catch::cout() << '"' << testCaseInfo.name << '"';
else
Catch::cout() << testCaseInfo.name << std::endl;
Catch::cout() << testCaseInfo.name;
if ( config.listExtraInfo() )
Catch::cout() << "\t@" << testCaseInfo.lineInfo;
Catch::cout() << std::endl;
}
return matchedTests;
}
@@ -163,7 +174,7 @@ namespace Catch {
inline Option<std::size_t> list( Config const& config ) {
Option<std::size_t> listedCount;
if( config.listTests() )
if( config.listTests() || ( config.listExtraInfo() && !config.listTestNamesOnly() ) )
listedCount = listedCount.valueOr(0) + listTests( config );
if( config.listTestNamesOnly() )
listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );

View File

@@ -27,16 +27,25 @@ namespace Matchers {
}
protected:
virtual ~MatcherUntypedBase();
virtual std::string describe() const = 0;
mutable std::string m_cachedToString;
private:
MatcherUntypedBase& operator = ( MatcherUntypedBase const& );
};
template<typename ObjectT, typename ComparatorT = ObjectT>
struct MatcherBase : MatcherUntypedBase {
template<typename ObjectT>
struct MatcherMethod {
virtual bool match( ObjectT const& arg ) const = 0;
};
template<typename PtrT>
struct MatcherMethod<PtrT*> {
virtual bool match( PtrT* arg ) const = 0;
};
template<typename ObjectT, typename ComparatorT = ObjectT>
struct MatcherBase : MatcherUntypedBase, MatcherMethod<ObjectT> {
MatchAllOf<ComparatorT> operator && ( MatcherBase const& other ) const;
MatchAnyOf<ComparatorT> operator || ( MatcherBase const& other ) const;
@@ -138,23 +147,23 @@ namespace Matchers {
// This allows the types to be inferred
// - deprecated: prefer ||, && and !
template<typename T>
inline Impl::MatchNotOf<T> Not( Impl::MatcherBase<T> const& underlyingMatcher ) {
Impl::MatchNotOf<T> Not( Impl::MatcherBase<T> const& underlyingMatcher ) {
return Impl::MatchNotOf<T>( underlyingMatcher );
}
template<typename T>
inline Impl::MatchAllOf<T> AllOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2 ) {
Impl::MatchAllOf<T> AllOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2 ) {
return Impl::MatchAllOf<T>() && m1 && m2;
}
template<typename T>
inline Impl::MatchAllOf<T> AllOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2, Impl::MatcherBase<T> const& m3 ) {
Impl::MatchAllOf<T> AllOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2, Impl::MatcherBase<T> const& m3 ) {
return Impl::MatchAllOf<T>() && m1 && m2 && m3;
}
template<typename T>
inline Impl::MatchAnyOf<T> AnyOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2 ) {
Impl::MatchAnyOf<T> AnyOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2 ) {
return Impl::MatchAnyOf<T>() || m1 || m2;
}
template<typename T>
inline Impl::MatchAnyOf<T> AnyOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2, Impl::MatcherBase<T> const& m3 ) {
Impl::MatchAnyOf<T> AnyOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2, Impl::MatcherBase<T> const& m3 ) {
return Impl::MatchAnyOf<T>() || m1 || m2 || m3;
}

View File

@@ -26,7 +26,7 @@ namespace Matchers {
};
struct StringMatcherBase : MatcherBase<std::string> {
StringMatcherBase( std::string operation, CasedString const& comparator );
StringMatcherBase( std::string const& operation, CasedString const& comparator );
virtual std::string describe() const CATCH_OVERRIDE;
CasedString m_comparator;

View File

@@ -29,7 +29,7 @@ namespace Matchers {
}
StringMatcherBase::StringMatcherBase( std::string operation, CasedString const& comparator )
StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )
: m_comparator( comparator ),
m_operation( operation ) {
}

View File

@@ -37,9 +37,18 @@ namespace Catch {
: m_info( other.m_info )
{}
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17
#endif
ScopedMessage::~ScopedMessage() {
getResultCapture().popScopedMessage( m_info );
if ( !std::uncaught_exception() ){
getResultCapture().popScopedMessage(m_info);
}
}
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
} // end namespace Catch

View File

@@ -16,7 +16,6 @@ namespace Catch {
{
public:
NotImplementedException( SourceLineInfo const& lineInfo );
NotImplementedException( NotImplementedException const& ) {}
virtual ~NotImplementedException() CATCH_NOEXCEPT {}

View File

@@ -105,64 +105,67 @@ namespace Catch {
namespace Impl {
namespace NSStringMatchers {
template<typename MatcherT>
struct StringHolder : MatcherImpl<MatcherT, NSString*>{
struct StringHolder : MatcherBase<NSString*>{
StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
StringHolder() {
arcSafeRelease( m_substr );
}
virtual bool match( NSString* arg ) const CATCH_OVERRIDE {
return false;
}
NSString* m_substr;
};
struct Equals : StringHolder<Equals> {
struct Equals : StringHolder {
Equals( NSString* substr ) : StringHolder( substr ){}
virtual bool match( ExpressionType const& str ) const {
virtual bool match( NSString* str ) const CATCH_OVERRIDE {
return (str != nil || m_substr == nil ) &&
[str isEqualToString:m_substr];
}
virtual std::string toString() const {
virtual std::string describe() const CATCH_OVERRIDE {
return "equals string: " + Catch::toString( m_substr );
}
};
struct Contains : StringHolder<Contains> {
struct Contains : StringHolder {
Contains( NSString* substr ) : StringHolder( substr ){}
virtual bool match( ExpressionType const& str ) const {
virtual bool match( NSString* str ) const {
return (str != nil || m_substr == nil ) &&
[str rangeOfString:m_substr].location != NSNotFound;
}
virtual std::string toString() const {
virtual std::string describe() const CATCH_OVERRIDE {
return "contains string: " + Catch::toString( m_substr );
}
};
struct StartsWith : StringHolder<StartsWith> {
struct StartsWith : StringHolder {
StartsWith( NSString* substr ) : StringHolder( substr ){}
virtual bool match( ExpressionType const& str ) const {
virtual bool match( NSString* str ) const {
return (str != nil || m_substr == nil ) &&
[str rangeOfString:m_substr].location == 0;
}
virtual std::string toString() const {
virtual std::string describe() const CATCH_OVERRIDE {
return "starts with: " + Catch::toString( m_substr );
}
};
struct EndsWith : StringHolder<EndsWith> {
struct EndsWith : StringHolder {
EndsWith( NSString* substr ) : StringHolder( substr ){}
virtual bool match( ExpressionType const& str ) const {
virtual bool match( NSString* str ) const {
return (str != nil || m_substr == nil ) &&
[str rangeOfString:m_substr].location == [str length] - [m_substr length];
}
virtual std::string toString() const {
virtual std::string describe() const CATCH_OVERRIDE {
return "ends with: " + Catch::toString( m_substr );
}
};

View File

@@ -66,8 +66,18 @@ namespace Catch {
}
private:
T* nullableValue;
char storage[sizeof(T)];
T *nullableValue;
union {
char storage[sizeof(T)];
// These are here to force alignment for the storage
long double dummy1;
void (*dummy2)();
long double dummy3;
#ifdef CATCH_CONFIG_CPP11_LONG_LONG
long long dummy4;
#endif
};
};
} // end namespace Catch

View File

@@ -13,6 +13,7 @@
#include "catch_test_case_registry_impl.hpp"
#include "catch_reporter_registry.hpp"
#include "catch_exception_translator_registry.hpp"
#include "catch_tag_alias_registry.h"
namespace Catch {
@@ -35,6 +36,10 @@ namespace Catch {
virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE {
return m_exceptionTranslatorRegistry;
}
virtual ITagAliasRegistry const& getTagAliasRegistry() const CATCH_OVERRIDE {
return m_tagAliasRegistry;
}
public: // IMutableRegistryHub
virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
@@ -49,11 +54,15 @@ namespace Catch {
virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE {
m_exceptionTranslatorRegistry.registerTranslator( translator );
}
virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) CATCH_OVERRIDE {
m_tagAliasRegistry.add( alias, tag, lineInfo );
}
private:
TestRegistry m_testCaseRegistry;
ReporterRegistry m_reporterRegistry;
ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
TagAliasRegistry m_tagAliasRegistry;
};
// Single, global, instance

View File

@@ -92,7 +92,11 @@ namespace Catch {
#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
// Deprecated - use the form without INTERNAL_
#define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \
namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
#define CATCH_REGISTER_LISTENER( listenerType ) \
namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
#endif // TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED

View File

@@ -39,6 +39,7 @@ namespace Catch {
char const* capturedExpression,
ResultDisposition::Flags resultDisposition,
char const* secondArg = "" );
~ResultBuilder();
template<typename T>
ExpressionLhs<T const&> operator <= ( T const& operand );
@@ -46,7 +47,7 @@ namespace Catch {
template<typename T>
ResultBuilder& operator << ( T const& value ) {
m_stream.oss << value;
stream().oss << value;
return *this;
}
@@ -73,13 +74,33 @@ namespace Catch {
template<typename ArgT, typename MatcherT>
void captureMatch( ArgT const& arg, MatcherT const& matcher, char const* matcherString );
void setExceptionGuard();
void unsetExceptionGuard();
private:
AssertionInfo m_assertionInfo;
AssertionResultData m_data;
CopyableStream m_stream;
CopyableStream &stream()
{
if(!m_usedStream)
{
m_usedStream = true;
m_stream().oss.str("");
}
return m_stream();
}
static CopyableStream &m_stream()
{
static CopyableStream s;
return s;
}
bool m_shouldDebugBreak;
bool m_shouldThrow;
bool m_guardException;
bool m_usedStream;
};
} // namespace Catch
@@ -90,7 +111,7 @@ namespace Catch {
namespace Catch {
template<typename T>
inline ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) {
ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) {
return ExpressionLhs<T const&>( *this, operand );
}
@@ -99,7 +120,7 @@ namespace Catch {
}
template<typename ArgT, typename MatcherT>
inline void ResultBuilder::captureMatch( ArgT const& arg, MatcherT const& matcher,
void ResultBuilder::captureMatch( ArgT const& arg, MatcherT const& matcher,
char const* matcherString ) {
MatchExpression<ArgT const&, MatcherT const&> expr( arg, matcher, matcherString );
setResultType( matcher.match( arg ) );

View File

@@ -16,23 +16,32 @@
#include "catch_interfaces_registry_hub.h"
#include "catch_wildcard_pattern.hpp"
#include <cassert>
namespace Catch {
std::string capturedExpressionWithSecondArgument( std::string const& capturedExpression, std::string const& secondArg ) {
return secondArg.empty() || secondArg == "\"\""
? capturedExpression
: capturedExpression + ", " + secondArg;
}
ResultBuilder::ResultBuilder( char const* macroName,
SourceLineInfo const& lineInfo,
char const* capturedExpression,
ResultDisposition::Flags resultDisposition,
char const* secondArg )
: m_assertionInfo( macroName, lineInfo, capturedExpressionWithSecondArgument( capturedExpression, secondArg ), resultDisposition ),
: m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition, secondArg ),
m_shouldDebugBreak( false ),
m_shouldThrow( false )
m_shouldThrow( false ),
m_guardException( false ),
m_usedStream( false )
{}
ResultBuilder::~ResultBuilder() {
#if defined(CATCH_CONFIG_FAST_COMPILE)
if ( m_guardException ) {
stream().oss << "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
captureResult( ResultWas::ThrewException );
getCurrentContext().getResultCapture()->exceptionEarlyReported();
}
#endif
}
ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) {
m_data.resultType = result;
return *this;
@@ -43,13 +52,25 @@ namespace Catch {
}
void ResultBuilder::endExpression( DecomposedExpression const& expr ) {
AssertionResult result = build( expr );
handleResult( result );
// Flip bool results if FalseTest flag is set
if( isFalseTest( m_assertionInfo.resultDisposition ) ) {
m_data.negate( expr.isBinaryExpression() );
}
getResultCapture().assertionRun();
if(getCurrentContext().getConfig()->includeSuccessfulResults() || m_data.resultType != ResultWas::Ok)
{
AssertionResult result = build( expr );
handleResult( result );
}
else
getResultCapture().assertionPassed();
}
void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {
m_assertionInfo.resultDisposition = resultDisposition;
m_stream.oss << Catch::translateActiveException();
stream().oss << Catch::translateActiveException();
captureResult( ResultWas::ThrewException );
}
@@ -71,7 +92,7 @@ namespace Catch {
assert( !isFalseTest( m_assertionInfo.resultDisposition ) );
AssertionResultData data = m_data;
data.resultType = ResultWas::Ok;
data.reconstructedExpression = m_assertionInfo.capturedExpression;
data.reconstructedExpression = capturedExpressionWithSecondArgument(m_assertionInfo.capturedExpression, m_assertionInfo.secondArg);
std::string actualMessage = Catch::translateActiveException();
if( !matcher.match( actualMessage ) ) {
@@ -132,18 +153,21 @@ namespace Catch {
assert( m_data.resultType != ResultWas::Unknown );
AssertionResultData data = m_data;
// Flip bool results if FalseTest flag is set
if( isFalseTest( m_assertionInfo.resultDisposition ) ) {
data.negate( expr.isBinaryExpression() );
}
data.message = m_stream.oss.str();
if(m_usedStream)
data.message = m_stream().oss.str();
data.decomposedExpression = &expr; // for lazy reconstruction
return AssertionResult( m_assertionInfo, data );
}
void ResultBuilder::reconstructExpression( std::string& dest ) const {
dest = m_assertionInfo.capturedExpression;
dest = capturedExpressionWithSecondArgument(m_assertionInfo.capturedExpression, m_assertionInfo.secondArg);
}
void ResultBuilder::setExceptionGuard() {
m_guardException = true;
}
void ResultBuilder::unsetExceptionGuard() {
m_guardException = false;
}
} // end namespace Catch

View File

@@ -22,6 +22,7 @@
#include "catch_result_builder.h"
#include "catch_fatal_condition.hpp"
#include <cassert>
#include <set>
#include <string>
@@ -50,6 +51,29 @@ namespace Catch {
std::string& m_targetString;
};
// StdErr has two constituent streams in C++, std::cerr and std::clog
// This means that we need to redirect 2 streams into 1 to keep proper
// order of writes and cannot use StreamRedirect on its own
class StdErrRedirect {
public:
StdErrRedirect(std::string& targetString)
:m_cerrBuf( cerr().rdbuf() ), m_clogBuf(clog().rdbuf()),
m_targetString(targetString){
cerr().rdbuf(m_oss.rdbuf());
clog().rdbuf(m_oss.rdbuf());
}
~StdErrRedirect() {
m_targetString += m_oss.str();
cerr().rdbuf(m_cerrBuf);
clog().rdbuf(m_clogBuf);
}
private:
std::streambuf* m_cerrBuf;
std::streambuf* m_clogBuf;
std::ostringstream m_oss;
std::string& m_targetString;
};
///////////////////////////////////////////////////////////////////////////
class RunContext : public IResultCapture, public IRunner {
@@ -64,7 +88,8 @@ namespace Catch {
m_context( getCurrentMutableContext() ),
m_activeTestCase( CATCH_NULL ),
m_config( _config ),
m_reporter( reporter )
m_reporter( reporter ),
m_shouldReportUnexpected ( true )
{
m_context.setRunner( this );
m_context.setConfig( m_config );
@@ -141,17 +166,38 @@ namespace Catch {
m_totals.assertions.passed++;
}
else if( !result.isOk() ) {
m_totals.assertions.failed++;
if( m_activeTestCase->getTestCaseInfo().okToFail() )
m_totals.assertions.failedButOk++;
else
m_totals.assertions.failed++;
}
if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) )
m_messages.clear();
// We have no use for the return value (whether messages should be cleared), because messages were made scoped
// and should be let to clear themselves out.
static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
// Reset working state
m_lastAssertionInfo = AssertionInfo( std::string(), m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
m_lastResult = result;
}
virtual bool lastAssertionPassed()
{
return m_totals.assertions.passed == (m_prevPassed + 1);
}
virtual void assertionPassed()
{
m_totals.assertions.passed++;
m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}";
m_lastAssertionInfo.macroName = "";
}
virtual void assertionRun()
{
m_prevPassed = m_totals.assertions.passed;
}
virtual bool sectionStarted (
SectionInfo const& sectionInfo,
Counts& assertions
@@ -223,11 +269,19 @@ namespace Catch {
return &m_lastResult;
}
virtual void exceptionEarlyReported() {
m_shouldReportUnexpected = false;
}
virtual void handleFatalErrorCondition( std::string const& message ) {
ResultBuilder resultBuilder = makeUnexpectedResultBuilder();
resultBuilder.setResultType( ResultWas::FatalErrorCondition );
resultBuilder << message;
resultBuilder.captureExpression();
// Don't rebuild the result -- the stringification itself can cause more fatal errors
// Instead, fake a result data.
AssertionResultData tempResult;
tempResult.resultType = ResultWas::FatalErrorCondition;
tempResult.message = message;
AssertionResult result(m_lastAssertionInfo, tempResult);
getResultCapture().assertionEnded(result);
handleUnfinishedSections();
@@ -244,6 +298,7 @@ namespace Catch {
Totals deltaTotals;
deltaTotals.testCases.failed = 1;
deltaTotals.assertions.failed = 1;
m_reporter->testCaseEnded( TestCaseStats( testInfo,
deltaTotals,
std::string(),
@@ -268,8 +323,9 @@ namespace Catch {
m_reporter->sectionStarting( testCaseSection );
Counts prevAssertions = m_totals.assertions;
double duration = 0;
m_shouldReportUnexpected = true;
try {
m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, std::string(), ResultDisposition::Normal );
m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
seedRng( *m_config );
@@ -277,7 +333,7 @@ namespace Catch {
timer.start();
if( m_reporter->getPreferences().shouldRedirectStdOut ) {
StreamRedirect coutRedir( Catch::cout(), redirectedCout );
StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr );
StdErrRedirect errRedir( redirectedCerr );
invokeActiveTestCase();
}
else {
@@ -289,7 +345,11 @@ namespace Catch {
// This just means the test was aborted due to failure
}
catch(...) {
makeUnexpectedResultBuilder().useActiveException();
// Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
// are reported without translation at the point of origin.
if (m_shouldReportUnexpected) {
makeUnexpectedResultBuilder().useActiveException();
}
}
m_testCaseTracker->close();
handleUnfinishedSections();
@@ -298,28 +358,21 @@ namespace Catch {
Counts assertions = m_totals.assertions - prevAssertions;
bool missingAssertions = testForMissingAssertions( assertions );
if( testCaseInfo.okToFail() ) {
std::swap( assertions.failedButOk, assertions.failed );
m_totals.assertions.failed -= assertions.failedButOk;
m_totals.assertions.failedButOk += assertions.failedButOk;
}
SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
m_reporter->sectionEnded( testCaseSectionStats );
}
void invokeActiveTestCase() {
FatalConditionHandler fatalConditionHandler; // Handle signals
FatalConditionHandlerGuard _(&m_fatalConditionhandler);
m_activeTestCase->invoke();
fatalConditionHandler.reset();
}
private:
ResultBuilder makeUnexpectedResultBuilder() const {
return ResultBuilder( m_lastAssertionInfo.macroName.c_str(),
return ResultBuilder( m_lastAssertionInfo.macroName,
m_lastAssertionInfo.lineInfo,
m_lastAssertionInfo.capturedExpression.c_str(),
m_lastAssertionInfo.capturedExpression,
m_lastAssertionInfo.resultDisposition );
}
@@ -349,6 +402,9 @@ namespace Catch {
std::vector<SectionEndInfo> m_unfinishedSections;
std::vector<ITracker*> m_activeSections;
TrackerContext m_trackerContext;
FatalConditionHandler m_fatalConditionhandler;
size_t m_prevPassed;
bool m_shouldReportUnexpected;
};
IResultCapture& getResultCapture() {

View File

@@ -30,6 +30,10 @@ namespace Catch {
m_timer.start();
}
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17
#endif
Section::~Section() {
if( m_sectionIncluded ) {
SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
@@ -39,6 +43,9 @@ namespace Catch {
getResultCapture().sectionEnded( endInfo );
}
}
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
// This indicates whether the section should be executed or not
Section::operator bool() const {

View File

@@ -21,6 +21,7 @@ namespace Catch {
std::ostream& cout();
std::ostream& cerr();
std::ostream& clog();
struct IStream {

View File

@@ -103,6 +103,9 @@ namespace Catch {
std::ostream& cerr() {
return std::cerr;
}
std::ostream& clog() {
return std::clog;
}
#endif
}

View File

@@ -24,11 +24,7 @@
#elif defined __GNUC__
# pragma GCC diagnostic ignored "-Wvariadic-macros"
# pragma GCC diagnostic ignored "-Wunused-variable"
// For newer version we can use __Pragma to disable the warnings locally
# if __GNUC__ == 4 && __GNUC_MINOR__ >= 4 && __GNUC_MINOR__ <= 7
# pragma GCC diagnostic ignored "-Wparentheses"
# endif
# pragma GCC diagnostic ignored "-Wparentheses"
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wpadded"

View File

@@ -15,7 +15,7 @@
namespace Catch {
struct TagAlias {
TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
TagAlias( std::string const& _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
std::string tag;
SourceLineInfo lineInfo;

View File

@@ -19,8 +19,7 @@ namespace Catch {
virtual ~TagAliasRegistry();
virtual Option<TagAlias> find( std::string const& alias ) const;
virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;
void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
static TagAliasRegistry& get();
void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
private:
std::map<std::string, TagAlias> m_registry;

View File

@@ -10,6 +10,8 @@
#include "catch_tag_alias_registry.h"
#include "catch_console_colour.hpp"
#include "catch_interfaces_registry_hub.h"
#include "catch_stream.h"
namespace Catch {
@@ -38,41 +40,36 @@ namespace Catch {
return expandedTestSpec;
}
void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {
if( !startsWith( alias, "[@" ) || !endsWith( alias, ']' ) ) {
std::ostringstream oss;
oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo;
oss << Colour( Colour::Red )
<< "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n"
<< Colour( Colour::FileName )
<< lineInfo << '\n';
throw std::domain_error( oss.str().c_str() );
}
if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {
std::ostringstream oss;
oss << "error: tag alias, \"" << alias << "\" already registered.\n"
<< "\tFirst seen at " << find(alias)->lineInfo << '\n'
<< "\tRedefined at " << lineInfo;
oss << Colour( Colour::Red )
<< "error: tag alias, \"" << alias << "\" already registered.\n"
<< "\tFirst seen at "
<< Colour( Colour::Red ) << find(alias)->lineInfo << '\n'
<< Colour( Colour::Red ) << "\tRedefined at "
<< Colour( Colour::FileName) << lineInfo << '\n';
throw std::domain_error( oss.str().c_str() );
}
}
TagAliasRegistry& TagAliasRegistry::get() {
static TagAliasRegistry instance;
return instance;
ITagAliasRegistry::~ITagAliasRegistry() {}
ITagAliasRegistry const& ITagAliasRegistry::get() {
return getRegistryHub().getTagAliasRegistry();
}
ITagAliasRegistry::~ITagAliasRegistry() {}
ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); }
RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
try {
TagAliasRegistry::get().add( alias, tag, lineInfo );
}
catch( std::exception& ex ) {
Colour colourGuard( Colour::Red );
Catch::cerr() << ex.what() << std::endl;
exit(1);
}
getMutableRegistryHub().registerTagAlias( alias, tag, lineInfo );
}
} // end namespace Catch

View File

@@ -38,17 +38,13 @@ namespace Catch {
}
inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
if( isReservedTag( tag ) ) {
{
Colour colourGuard( Colour::Red );
Catch::cerr()
<< "Tag name [" << tag << "] not allowed.\n"
<< "Tag names starting with non alpha-numeric characters are reserved\n";
}
{
Colour colourGuard( Colour::FileName );
Catch::cerr() << _lineInfo << std::endl;
}
exit(1);
std::ostringstream ss;
ss << Colour(Colour::Red)
<< "Tag name [" << tag << "] not allowed.\n"
<< "Tag names starting with non alpha-numeric characters are reserved\n"
<< Colour(Colour::FileName)
<< _lineInfo << '\n';
throw std::runtime_error(ss.str());
}
}

View File

@@ -22,14 +22,14 @@
namespace Catch {
struct RandomNumberGenerator {
typedef std::ptrdiff_t result_type;
typedef unsigned int result_type;
result_type operator()( result_type n ) const { return std::rand() % n; }
#ifdef CATCH_CONFIG_CPP11_SHUFFLE
static constexpr result_type min() { return 0; }
static constexpr result_type max() { return 1000000; }
result_type operator()() const { return std::rand() % max(); }
static constexpr result_type (min)() { return 0; }
static constexpr result_type (max)() { return 1000000; }
result_type operator()() const { return std::rand() % (max)(); }
#endif
template<typename V>
static void shuffle( V& vector ) {

View File

@@ -11,13 +11,14 @@
#include "catch_compiler_capabilities.h"
#include "catch_ptr.hpp"
#include <map>
#include <algorithm>
#include <string>
#include <assert.h>
#include <vector>
#include <iterator>
#include <stdexcept>
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS
namespace Catch {
namespace TestCaseTracking {
@@ -290,12 +291,12 @@ namespace TestCaseTracking {
if( !filters.empty() ) {
m_filters.push_back(""); // Root - should never be consulted
m_filters.push_back(""); // Test Case - not a section filter
std::copy( filters.begin(), filters.end(), std::back_inserter( m_filters ) );
m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
}
}
void addNextFilters( std::vector<std::string> const& filters ) {
if( filters.size() > 1 )
std::copy( filters.begin()+1, filters.end(), std::back_inserter( m_filters ) );
m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() );
}
};
@@ -365,4 +366,6 @@ using TestCaseTracking::IndexTracker;
} // namespace Catch
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
#endif // TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED

View File

@@ -87,59 +87,76 @@ void registerTestCaseFunction
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
static void TestName(); \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); } /* NOLINT */ \
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
static void TestName()
#define INTERNAL_CATCH_TESTCASE( ... ) \
INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); } /* NOLINT */ \
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
namespace{ \
struct TestName : ClassName{ \
void test(); \
}; \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); /* NOLINT */ \
} \
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
void TestName::test()
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) );
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); /* NOLINT */ \
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
#else
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \
static void TestName(); \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); } /* NOLINT */ \
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
static void TestName()
#define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); } /* NOLINT */ \
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
namespace{ \
struct TestCaseName : ClassName{ \
void test(); \
}; \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); /* NOLINT */ \
} \
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
void TestCaseName::test()
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \
Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) );
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); /* NOLINT */ \
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
#endif
#endif // TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED

View File

@@ -30,7 +30,7 @@ namespace Catch {
ITagAliasRegistry const* m_tagAliases;
public:
TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
TestSpecParser( ITagAliasRegistry const& tagAliases ) :m_mode(None), m_exclusion(false), m_start(0), m_pos(0), m_tagAliases( &tagAliases ) {}
TestSpecParser& parse( std::string const& arg ) {
m_mode = None;

View File

@@ -10,14 +10,20 @@
#include "catch_platform.h"
#ifdef CATCH_PLATFORM_WINDOWS
typedef unsigned long long uint64_t;
#else
#include <stdint.h>
#endif
#ifdef _MSC_VER
namespace Catch {
typedef unsigned long long UInt64;
}
#else
#include <stdint.h>
namespace Catch {
typedef uint64_t UInt64;
}
#endif
namespace Catch {
class Timer {
public:
Timer() : m_ticks( 0 ) {}
@@ -27,7 +33,7 @@ namespace Catch {
double getElapsedSeconds() const;
private:
uint64_t m_ticks;
UInt64 m_ticks;
};
} // namespace Catch

View File

@@ -20,34 +20,29 @@
#else
// Required for some versions of Cygwin to declare gettimeofday
// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
# ifdef __CYGWIN__
# define _BSD_SOURCE
# endif
#include <sys/time.h>
#endif
namespace Catch {
namespace {
#ifdef CATCH_PLATFORM_WINDOWS
uint64_t getCurrentTicks() {
static uint64_t hz=0, hzo=0;
UInt64 getCurrentTicks() {
static UInt64 hz=0, hzo=0;
if (!hz) {
QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );
QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );
}
uint64_t t;
UInt64 t;
QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );
return ((t-hzo)*1000000)/hz;
}
#else
uint64_t getCurrentTicks() {
UInt64 getCurrentTicks() {
timeval t;
gettimeofday(&t,CATCH_NULL);
return static_cast<uint64_t>( t.tv_sec ) * 1000000ull + static_cast<uint64_t>( t.tv_usec );
return static_cast<UInt64>( t.tv_sec ) * 1000000ull + static_cast<UInt64>( t.tv_usec );
}
#endif
}

View File

@@ -63,7 +63,7 @@ std::string toString( std::nullptr_t );
#ifdef __OBJC__
std::string toString( NSString const * const& nsstring );
std::string toString( NSString * CATCH_ARC_STRONG const& nsstring );
std::string toString( NSString * CATCH_ARC_STRONG & nsstring );
std::string toString( NSObject* const& nsObject );
#endif
@@ -72,6 +72,7 @@ namespace Detail {
extern const std::string unprintableString;
#if !defined(CATCH_CONFIG_CPP11_STREAM_INSERTABLE_CHECK)
struct BorgType {
template<typename T> BorgType( T const& );
};
@@ -90,6 +91,20 @@ namespace Detail {
static T const&t;
enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
};
#else
template<typename T>
class IsStreamInsertable {
template<typename SS, typename TT>
static auto test(int)
-> decltype( std::declval<SS&>() << std::declval<TT>(), std::true_type() );
template<typename, typename>
static auto test(...) -> std::false_type;
public:
static const bool value = decltype(test<std::ostream,const T&>(0))::value;
};
#endif
#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
template<typename T,
@@ -138,7 +153,7 @@ namespace Detail {
std::string rawMemoryToString( const void *object, std::size_t size );
template<typename T>
inline std::string rawMemoryToString( const T& object ) {
std::string rawMemoryToString( const T& object ) {
return rawMemoryToString( &object, sizeof(object) );
}

View File

@@ -198,7 +198,7 @@ std::string toString( std::nullptr_t ) {
return "nil";
return "@" + toString([nsstring UTF8String]);
}
std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) {
std::string toString( NSString * CATCH_ARC_STRONG & nsstring ) {
if( !nsstring )
return "nil";
return "@" + toString([nsstring UTF8String]);

View File

@@ -25,7 +25,7 @@ namespace Catch {
#else
template <typename T>
struct add_const {
struct add_const {
typedef const T type;
};

View File

@@ -15,7 +15,7 @@ namespace Catch {
Version( unsigned int _majorVersion,
unsigned int _minorVersion,
unsigned int _patchNumber,
std::string const& _branchName,
char const * const _branchName,
unsigned int _buildNumber );
unsigned int const majorVersion;
@@ -23,7 +23,7 @@ namespace Catch {
unsigned int const patchNumber;
// buildNumber is only used if branchName is not null
std::string const branchName;
char const * const branchName;
unsigned int const buildNumber;
friend std::ostream& operator << ( std::ostream& os, Version const& version );
@@ -32,7 +32,7 @@ namespace Catch {
void operator=( Version const& );
};
extern Version libraryVersion;
inline Version libraryVersion();
}
#endif // TWOBLUECUBES_CATCH_VERSION_H_INCLUDED

View File

@@ -16,7 +16,7 @@ namespace Catch {
( unsigned int _majorVersion,
unsigned int _minorVersion,
unsigned int _patchNumber,
std::string const& _branchName,
char const * const _branchName,
unsigned int _buildNumber )
: majorVersion( _majorVersion ),
minorVersion( _minorVersion ),
@@ -29,15 +29,18 @@ namespace Catch {
os << version.majorVersion << '.'
<< version.minorVersion << '.'
<< version.patchNumber;
if( !version.branchName.empty() ) {
os << '-' << version.branchName
<< '.' << version.buildNumber;
// branchName is never null -> 0th char is \0 if it is empty
if (version.branchName[0]) {
os << '-' << version.branchName
<< '.' << version.buildNumber;
}
return os;
}
Version libraryVersion( 1, 8, 0, "", 0 );
inline Version libraryVersion() {
static Version version( 1, 12, 2, "", 0 );
return version;
}
}

View File

@@ -10,7 +10,6 @@
#include "catch_stream.h"
#include "catch_compiler_capabilities.h"
#include "catch_suppress_warnings.h"
#include <sstream>
#include <string>
@@ -241,6 +240,5 @@ namespace Catch {
};
}
#include "catch_reenable_warnings.h"
#endif // TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED

View File

@@ -9,12 +9,38 @@
#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
#include "../internal/catch_interfaces_reporter.h"
#include "../internal/catch_errno_guard.hpp"
#include <cstring>
#include <cfloat>
#include <cstdio>
#include <assert.h>
namespace Catch {
namespace {
// Because formatting using c++ streams is stateful, drop down to C is required
// Alternatively we could use stringstream, but its performance is... not good.
std::string getFormattedDuration( double duration ) {
// Max exponent + 1 is required to represent the whole part
// + 1 for decimal point
// + 3 for the 3 decimal places
// + 1 for null terminator
const size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
char buffer[maxDoubleSize];
// Save previous errno, to prevent sprintf from overwriting it
ErrnoGuard guard;
#ifdef _MSC_VER
sprintf_s(buffer, "%.3f", duration);
#else
sprintf(buffer, "%.3f", duration);
#endif
return std::string(buffer);
}
}
struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
StreamingReporterBase( ReporterConfig const& _config )
@@ -111,7 +137,8 @@ namespace Catch {
BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
bool operator() ( Ptr<SectionNode> const& node ) const {
return node->stats.sectionInfo.lineInfo == m_other.lineInfo;
return ((node->stats.sectionInfo.name == m_other.name) &&
(node->stats.sectionInfo.lineInfo == m_other.lineInfo));
}
private:
void operator=( BySectionInfo const& );

View File

@@ -37,8 +37,7 @@ namespace Catch {
stream << "No test cases matched '" << spec << '\'' << std::endl;
}
virtual void assertionStarting( AssertionInfo const& ) {
}
virtual void assertionStarting( AssertionInfo const& ) {}
virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
AssertionResult const& result = _assertionStats.assertionResult;
@@ -59,6 +58,12 @@ namespace Catch {
return true;
}
virtual void sectionEnded(SectionStats const& _sectionStats) CATCH_OVERRIDE {
if (m_config->showDurations() == ShowDurations::Always) {
stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
}
}
virtual void testRunEnded( TestRunStats const& _testRunStats ) {
printTotals( _testRunStats.totals );
stream << '\n' << std::endl;
@@ -164,7 +169,7 @@ namespace Catch {
stream << result.getSourceInfo() << ':';
}
void printResultType( Colour::Code colour, std::string passOrFail ) const {
void printResultType( Colour::Code colour, std::string const& passOrFail ) const {
if( !passOrFail.empty() ) {
{
Colour colourGuard( colour );
@@ -174,7 +179,7 @@ namespace Catch {
}
}
void printIssue( std::string issue ) const {
void printIssue( std::string const& issue ) const {
stream << ' ' << issue;
}

View File

@@ -13,30 +13,12 @@
#include "../internal/catch_reporter_registrars.hpp"
#include "../internal/catch_console_colour.hpp"
#include <cassert>
#include <cfloat>
#include <cstdio>
namespace Catch {
namespace {
// Because formatting using c++ streams is stateful, drop down to C is required
// Alternatively we could use stringstream, but its performance is... not good.
std::string getFormattedDuration( double duration ) {
// Max exponent + 1 is required to represent the whole part
// + 1 for decimal point
// + 3 for the 3 decimal places
// + 1 for null terminator
const size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
char buffer[maxDoubleSize];
#ifdef _MSC_VER
sprintf_s(buffer, "%.3f", duration);
#else
sprintf(buffer, "%.3f", duration);
#endif
return std::string(buffer);
}
}
struct ConsoleReporter : StreamingReporterBase {
ConsoleReporter( ReporterConfig const& _config )
@@ -59,18 +41,15 @@ namespace Catch {
virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE {
AssertionResult const& result = _assertionStats.assertionResult;
bool printInfoMessages = true;
bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
// Drop out if result was successful and we're not printing those
if( !m_config->includeSuccessfulResults() && result.isOk() ) {
if( result.getResultType() != ResultWas::Warning )
return false;
printInfoMessages = false;
}
// Drop out if result was successful but we're not printing them.
if( !includeResults && result.getResultType() != ResultWas::Warning )
return false;
lazyPrint();
AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
AssertionPrinter printer( stream, _assertionStats, includeResults );
printer.print();
stream << std::endl;
return true;
@@ -160,7 +139,11 @@ namespace Catch {
case ResultWas::ThrewException:
colour = Colour::Error;
passOrFail = "FAILED";
messageLabel = "due to unexpected exception with message";
messageLabel = "due to unexpected exception with ";
if (_stats.infoMessages.size() == 1)
messageLabel += "message";
if (_stats.infoMessages.size() > 1)
messageLabel += "messages";
break;
case ResultWas::FatalErrorCondition:
colour = Colour::Error;
@@ -276,7 +259,7 @@ namespace Catch {
stream << '\n' << getLineOfChars<'~'>() << '\n';
Colour colour( Colour::SecondaryText );
stream << currentTestRunInfo->name
<< " is a Catch v" << libraryVersion << " host application.\n"
<< " is a Catch v" << libraryVersion() << " host application.\n"
<< "Run with -? for options\n\n";
if( m_config->rngSeed() != 0 )

View File

@@ -51,7 +51,9 @@ namespace Catch {
public:
JunitReporter( ReporterConfig const& _config )
: CumulativeReporterBase( _config ),
xml( _config.stream() )
xml( _config.stream() ),
unexpectedExceptions( 0 ),
m_okToFail( false )
{
m_reporterPrefs.shouldRedirectStdOut = true;
}
@@ -77,8 +79,11 @@ namespace Catch {
CumulativeReporterBase::testGroupStarting( groupInfo );
}
virtual void testCaseStarting( TestCaseInfo const& testCaseInfo ) CATCH_OVERRIDE {
m_okToFail = testCaseInfo.okToFail();
}
virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException )
if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
unexpectedExceptions++;
return CumulativeReporterBase::assertionEnded( assertionStats );
}
@@ -243,6 +248,7 @@ namespace Catch {
std::ostringstream stdOutForSuite;
std::ostringstream stdErrForSuite;
unsigned int unexpectedExceptions;
bool m_okToFail;
};
INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )

View File

@@ -45,18 +45,9 @@ namespace Catch {
virtual void assertionStarting( AssertionInfo const& ) {}
virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
AssertionResult const& result = _assertionStats.assertionResult;
++counter;
bool printInfoMessages = true;
// Drop out if result was successful and we're not printing those
if ( !m_config->includeSuccessfulResults() && result.isOk() ) {
if ( result.getResultType() != ResultWas::Warning )
return false;
printInfoMessages = false;
}
AssertionPrinter printer( stream, _assertionStats, printInfoMessages, ++counter );
AssertionPrinter printer( stream, _assertionStats, counter );
printer.print();
stream << " # " << currentTestCaseInfo->name ;
@@ -75,13 +66,13 @@ namespace Catch {
class AssertionPrinter {
void operator= ( AssertionPrinter const& );
public:
AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages, size_t counter = 0 )
AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, size_t counter )
: stream( _stream )
, stats( _stats )
, result( _stats.assertionResult )
, messages( _stats.infoMessages )
, itMessage( _stats.infoMessages.begin() )
, printInfoMessages( _printInfoMessages )
, printInfoMessages( true )
, counter(counter)
{}
@@ -156,28 +147,23 @@ namespace Catch {
}
private:
static Colour::Code dimColour() { return Colour::FileName; }
static const char* failedString() { return "not ok"; }
static const char* passedString() { return "ok"; }
void printSourceInfo() const {
Colour colourGuard( Colour::FileName );
Colour colourGuard( dimColour() );
stream << result.getSourceInfo() << ":";
}
void printResultType( std::string passOrFail ) const {
void printResultType( std::string const& passOrFail ) const {
if( !passOrFail.empty() ) {
{
//Colour colourGuard( colour );
stream << passOrFail << " " << counter;
}
stream << " -";
stream << passOrFail << ' ' << counter << " -";
}
}
void printIssue( std::string issue ) const {
void printIssue( std::string const& issue ) const {
stream << " " << issue;
}
@@ -218,8 +204,9 @@ namespace Catch {
}
void printRemainingMessages( Colour::Code colour = dimColour() ) {
if ( itMessage == messages.end() )
if (itMessage == messages.end()) {
return;
}
// using messages.end() directly yields compilation error:
std::vector<MessageInfo>::const_iterator itEnd = messages.end();
@@ -252,17 +239,6 @@ namespace Catch {
size_t counter;
};
// Colour, message variants:
// - white: No tests ran.
// - red: Failed [both/all] N test cases, failed [both/all] M assertions.
// - white: Passed [both/all] N test cases (no assertions).
// - red: Failed N tests cases, failed M assertions.
// - green: Passed [both/all] N tests cases with M assertions.
std::string bothOrAll( std::size_t count ) const {
return count == 1 ? "" : count == 2 ? "both " : "all " ;
}
void printTotals( const Totals& totals ) const {
if( totals.testCases.total() == 0 ) {
stream << "1..0 # Skipped: No tests ran.";

View File

@@ -14,6 +14,7 @@
// file can be distributed as a single header that works with the main
// Catch single header.
#include <cassert>
#include <cstring>
#ifdef __clang__
@@ -49,14 +50,7 @@ namespace Catch {
return "Reports test results as TeamCity service messages";
}
virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
stream << "##teamcity[testIgnored name='"
<< escape( testInfo.name ) << "'";
if( testInfo.isHidden() )
stream << " message='hidden test'";
else
stream << " message='test skipped because it didn|'t match the test spec'";
stream << "]\n";
virtual void skipTest( TestCaseInfo const& /* testInfo */ ) CATCH_OVERRIDE {
}
virtual void noMatchingTestCases( std::string const& /* spec */ ) CATCH_OVERRIDE {}
@@ -134,11 +128,21 @@ namespace Catch {
" " << result.getExpandedExpression() << "\n";
}
stream << "##teamcity[testFailed"
<< " name='" << escape( currentTestCaseInfo->name )<< "'"
<< " message='" << escape( msg.str() ) << "'"
<< "]\n";
if( currentTestCaseInfo->okToFail() ) {
msg << "- failure ignore as test marked as 'ok to fail'\n";
stream << "##teamcity[testIgnored"
<< " name='" << escape( currentTestCaseInfo->name )<< "'"
<< " message='" << escape( msg.str() ) << "'"
<< "]\n";
}
else {
stream << "##teamcity[testFailed"
<< " name='" << escape( currentTestCaseInfo->name )<< "'"
<< " message='" << escape( msg.str() ) << "'"
<< "]\n";
}
}
stream.flush();
return true;
}
@@ -148,9 +152,11 @@ namespace Catch {
}
virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
m_testTimer.start();
StreamingReporterBase::testCaseStarting( testInfo );
stream << "##teamcity[testStarted name='"
<< escape( testInfo.name ) << "']\n";
stream.flush();
}
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
@@ -164,7 +170,9 @@ namespace Catch {
<< escape( testCaseStats.testInfo.name )
<< "' out='" << escape( testCaseStats.stdErr ) << "']\n";
stream << "##teamcity[testFinished name='"
<< escape( testCaseStats.testInfo.name ) << "']\n";
<< escape( testCaseStats.testInfo.name ) << "' duration='"
<< m_testTimer.getElapsedMilliseconds() << "']\n";
stream.flush();
}
private:
@@ -203,7 +211,7 @@ namespace Catch {
}
private:
bool m_headerPrintedForThisSection;
Timer m_testTimer;
};
#ifdef CATCH_IMPL

View File

@@ -92,73 +92,77 @@ namespace Catch {
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { }
virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
const AssertionResult& assertionResult = assertionStats.assertionResult;
// Print any info messages in <Info> tags.
if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
AssertionResult const& result = assertionStats.assertionResult;
bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
if( includeResults || result.getResultType() == ResultWas::Warning ) {
// Print any info messages in <Info> tags.
for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
it != itEnd;
++it ) {
if( it->type == ResultWas::Info ) {
it != itEnd;
++it ) {
if( it->type == ResultWas::Info && includeResults ) {
m_xml.scopedElement( "Info" )
.writeText( it->message );
.writeText( it->message );
} else if ( it->type == ResultWas::Warning ) {
m_xml.scopedElement( "Warning" )
.writeText( it->message );
.writeText( it->message );
}
}
}
// Drop out if result was successful but we're not printing them.
if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) )
if( !includeResults && result.getResultType() != ResultWas::Warning )
return true;
// Print the expression if there is one.
if( assertionResult.hasExpression() ) {
m_xml.startElement( "Expression" )
.writeAttribute( "success", assertionResult.succeeded() )
.writeAttribute( "type", assertionResult.getTestMacroName() );
writeSourceInfo( assertionResult.getSourceInfo() );
// Print the expression if there is one.
if( result.hasExpression() ) {
m_xml.startElement( "Expression" )
.writeAttribute( "success", result.succeeded() )
.writeAttribute( "type", result.getTestMacroName() );
writeSourceInfo( result.getSourceInfo() );
m_xml.scopedElement( "Original" )
.writeText( assertionResult.getExpression() );
.writeText( result.getExpression() );
m_xml.scopedElement( "Expanded" )
.writeText( assertionResult.getExpandedExpression() );
.writeText( result.getExpandedExpression() );
}
// And... Print a result applicable to each result type.
switch( assertionResult.getResultType() ) {
switch( result.getResultType() ) {
case ResultWas::ThrewException:
m_xml.startElement( "Exception" );
writeSourceInfo( assertionResult.getSourceInfo() );
m_xml.writeText( assertionResult.getMessage() );
writeSourceInfo( result.getSourceInfo() );
m_xml.writeText( result.getMessage() );
m_xml.endElement();
break;
case ResultWas::FatalErrorCondition:
m_xml.startElement( "FatalErrorCondition" );
writeSourceInfo( assertionResult.getSourceInfo() );
m_xml.writeText( assertionResult.getMessage() );
writeSourceInfo( result.getSourceInfo() );
m_xml.writeText( result.getMessage() );
m_xml.endElement();
break;
case ResultWas::Info:
m_xml.scopedElement( "Info" )
.writeText( assertionResult.getMessage() );
.writeText( result.getMessage() );
break;
case ResultWas::Warning:
// Warning will already have been written
break;
case ResultWas::ExplicitFailure:
m_xml.startElement( "Failure" );
writeSourceInfo( assertionResult.getSourceInfo() );
m_xml.writeText( assertionResult.getMessage() );
writeSourceInfo( result.getSourceInfo() );
m_xml.writeText( result.getMessage() );
m_xml.endElement();
break;
default:
break;
}
if( assertionResult.hasExpression() )
if( result.hasExpression() )
m_xml.endElement();
return true;

View File

@@ -24,6 +24,8 @@ TEST_CASE
REQUIRE( Approx( d ) == 1.23 );
REQUIRE( Approx( d ) != 1.22 );
REQUIRE( Approx( d ) != 1.24 );
REQUIRE( 0 == Approx(0) );
}
///////////////////////////////////////////////////////////////////////////////
@@ -146,11 +148,22 @@ TEST_CASE( "Approximate PI", "[Approx][PI]" )
TEST_CASE( "Absolute margin", "[Approx]" ) {
REQUIRE( 104.0 != Approx(100.0) );
REQUIRE( 104.0 == Approx(100.0).margin(5) );
REQUIRE( 104.0 == Approx(100.0).margin(4) );
REQUIRE( 104.0 != Approx(100.0).margin(3) );
REQUIRE( 100.3 != Approx(100.0) );
REQUIRE( 100.3 == Approx(100.0).margin(0.5) );
}
TEST_CASE("Approx with exactly-representable margin", "[Approx]") {
CHECK( 0.25f == Approx(0.0f).margin(0.25f) );
CHECK( 0.0f == Approx(0.25f).margin(0.25f) );
CHECK( 0.5f == Approx(0.25f).margin(0.25f) );
CHECK( 245.0f == Approx(245.25f).margin(0.25f) );
CHECK( 245.5f == Approx(245.25f).margin(0.25f) );
}
////////////////////////////////////////////////////////////////////////////////
#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)

View File

@@ -3,6 +3,42 @@
<exe-name> is a <version> host application.
Run with -? for options
-------------------------------------------------------------------------------
#748 - captures with unexpected exceptions
outside assertions
-------------------------------------------------------------------------------
ExceptionTests.cpp:<line number>
...............................................................................
ExceptionTests.cpp:<line number>: FAILED:
due to unexpected exception with messages:
answer := 42
expected exception
-------------------------------------------------------------------------------
#748 - captures with unexpected exceptions
inside REQUIRE_NOTHROW
-------------------------------------------------------------------------------
ExceptionTests.cpp:<line number>
...............................................................................
ExceptionTests.cpp:<line number>: FAILED:
REQUIRE_NOTHROW( thisThrows() )
due to unexpected exception with messages:
answer := 42
expected exception
-------------------------------------------------------------------------------
#835 -- errno should not be touched by Catch
-------------------------------------------------------------------------------
MiscTests.cpp:<line number>
...............................................................................
MiscTests.cpp:<line number>: FAILED:
CHECK( f() == 0 )
with expansion:
1 == 0
-------------------------------------------------------------------------------
'Not' checks that should fail
-------------------------------------------------------------------------------
@@ -22,6 +58,8 @@ with expansion:
ConditionTests.cpp:<line number>: FAILED:
CHECK_FALSE( true )
with expansion:
!true
ConditionTests.cpp:<line number>: FAILED:
CHECK( !trueValue )
@@ -40,8 +78,6 @@ with expansion:
ConditionTests.cpp:<line number>: FAILED:
CHECK_FALSE( 1 == 1 )
with expansion:
!(1 == 1)
-------------------------------------------------------------------------------
A METHOD_AS_TEST_CASE based test run that fails
@@ -276,6 +312,20 @@ MessageTests.cpp:<line number>
MessageTests.cpp:<line number>: FAILED:
-------------------------------------------------------------------------------
FAIL_CHECK does not abort the test
-------------------------------------------------------------------------------
MessageTests.cpp:<line number>
...............................................................................
MessageTests.cpp:<line number>: FAILED:
explicitly with message:
This is a failure
MessageTests.cpp:<line number>:
warning:
This message appears in the output
-------------------------------------------------------------------------------
INFO and WARN do not abort tests
-------------------------------------------------------------------------------
@@ -318,7 +368,9 @@ MessageTests.cpp:<line number>: FAILED:
CHECK( a == 0 )
with expansion:
2 == 0
with message:
with messages:
this message may be logged later
this message should be logged
and this, but later
-------------------------------------------------------------------------------
@@ -543,6 +595,17 @@ MessageTests.cpp:<line number>:
warning:
toString(p): 0x<hex digits>
-------------------------------------------------------------------------------
Reconstruction should be based on stringification: #914
-------------------------------------------------------------------------------
DecompositionTests.cpp:<line number>
...............................................................................
DecompositionTests.cpp:<line number>: FAILED:
CHECK( truthy(false) )
with expansion:
Hey, its truthy!
-------------------------------------------------------------------------------
SCOPED_INFO is reset for each loop
-------------------------------------------------------------------------------
@@ -559,6 +622,9 @@ with messages:
A string sent directly to stdout
A string sent directly to stderr
Write to std::cerr
Write to std::clog
Interleaved writes to error streams
Message from section one
Message from section two
-------------------------------------------------------------------------------
@@ -890,6 +956,6 @@ with expansion:
"first" == "second"
===============================================================================
test cases: 163 | 118 passed | 43 failed | 2 failed as expected
assertions: 953 | 849 passed | 86 failed | 18 failed as expected
test cases: 171 | 122 passed | 45 failed | 4 failed as expected
assertions: 980 | 871 passed | 88 failed | 21 failed as expected

View File

@@ -15,26 +15,42 @@ with message:
yay
-------------------------------------------------------------------------------
#542
#748 - captures with unexpected exceptions
outside assertions
-------------------------------------------------------------------------------
CompilationTests.cpp:<line number>
ExceptionTests.cpp:<line number>
...............................................................................
CompilationTests.cpp:<line number>:
PASSED:
CHECK_THROWS_AS( throws_int(true), int )
ExceptionTests.cpp:<line number>: FAILED:
due to unexpected exception with messages:
answer := 42
expected exception
CompilationTests.cpp:<line number>:
PASSED:
CHECK_THROWS_AS( throws_int(true), int& )
-------------------------------------------------------------------------------
#748 - captures with unexpected exceptions
inside REQUIRE_NOTHROW
-------------------------------------------------------------------------------
ExceptionTests.cpp:<line number>
...............................................................................
CompilationTests.cpp:<line number>:
PASSED:
CHECK_THROWS_AS( throws_int(true), const int )
ExceptionTests.cpp:<line number>: FAILED:
REQUIRE_NOTHROW( thisThrows() )
due to unexpected exception with messages:
answer := 42
expected exception
CompilationTests.cpp:<line number>:
-------------------------------------------------------------------------------
#748 - captures with unexpected exceptions
inside REQUIRE_THROWS
-------------------------------------------------------------------------------
ExceptionTests.cpp:<line number>
...............................................................................
ExceptionTests.cpp:<line number>:
PASSED:
CHECK_THROWS_AS( throws_int(true), const int& )
REQUIRE_THROWS( thisThrows() )
with message:
answer := 42
-------------------------------------------------------------------------------
#809
@@ -48,6 +64,125 @@ PASSED:
with expansion:
42 == {?}
-------------------------------------------------------------------------------
#833
-------------------------------------------------------------------------------
CompilationTests.cpp:<line number>
...............................................................................
CompilationTests.cpp:<line number>:
PASSED:
REQUIRE( a == t )
with expansion:
3 == 3
CompilationTests.cpp:<line number>:
PASSED:
CHECK( a == t )
with expansion:
3 == 3
CompilationTests.cpp:<line number>:
PASSED:
REQUIRE_THROWS( throws_int(true) )
CompilationTests.cpp:<line number>:
PASSED:
CHECK_THROWS_AS( throws_int(true), const int& )
CompilationTests.cpp:<line number>:
PASSED:
REQUIRE_NOTHROW( throws_int(false) )
CompilationTests.cpp:<line number>:
PASSED:
REQUIRE_THAT( "aaa", Catch::EndsWith("aaa") )
with expansion:
"aaa" ends with: "aaa"
CompilationTests.cpp:<line number>:
PASSED:
REQUIRE( templated_tests<int>(3) )
with expansion:
true
-------------------------------------------------------------------------------
#835 -- errno should not be touched by Catch
-------------------------------------------------------------------------------
MiscTests.cpp:<line number>
...............................................................................
MiscTests.cpp:<line number>: FAILED:
CHECK( f() == 0 )
with expansion:
1 == 0
MiscTests.cpp:<line number>:
PASSED:
REQUIRE( errno == 1 )
with expansion:
1 == 1
-------------------------------------------------------------------------------
#961 -- Dynamically created sections should all be reported
Looped section 0
-------------------------------------------------------------------------------
MiscTests.cpp:<line number>
...............................................................................
MiscTests.cpp:<line number>:
PASSED:
with message:
Everything is OK
-------------------------------------------------------------------------------
#961 -- Dynamically created sections should all be reported
Looped section 1
-------------------------------------------------------------------------------
MiscTests.cpp:<line number>
...............................................................................
MiscTests.cpp:<line number>:
PASSED:
with message:
Everything is OK
-------------------------------------------------------------------------------
#961 -- Dynamically created sections should all be reported
Looped section 2
-------------------------------------------------------------------------------
MiscTests.cpp:<line number>
...............................................................................
MiscTests.cpp:<line number>:
PASSED:
with message:
Everything is OK
-------------------------------------------------------------------------------
#961 -- Dynamically created sections should all be reported
Looped section 3
-------------------------------------------------------------------------------
MiscTests.cpp:<line number>
...............................................................................
MiscTests.cpp:<line number>:
PASSED:
with message:
Everything is OK
-------------------------------------------------------------------------------
#961 -- Dynamically created sections should all be reported
Looped section 4
-------------------------------------------------------------------------------
MiscTests.cpp:<line number>
...............................................................................
MiscTests.cpp:<line number>:
PASSED:
with message:
Everything is OK
-------------------------------------------------------------------------------
'Not' checks that should fail
-------------------------------------------------------------------------------
@@ -67,6 +202,8 @@ with expansion:
ConditionTests.cpp:<line number>: FAILED:
CHECK_FALSE( true )
with expansion:
!true
ConditionTests.cpp:<line number>: FAILED:
CHECK( !trueValue )
@@ -85,8 +222,6 @@ with expansion:
ConditionTests.cpp:<line number>: FAILED:
CHECK_FALSE( 1 == 1 )
with expansion:
!(1 == 1)
-------------------------------------------------------------------------------
'Not' checks that should succeed
@@ -111,6 +246,8 @@ with expansion:
ConditionTests.cpp:<line number>:
PASSED:
REQUIRE_FALSE( false )
with expansion:
!false
ConditionTests.cpp:<line number>:
PASSED:
@@ -133,8 +270,6 @@ with expansion:
ConditionTests.cpp:<line number>:
PASSED:
REQUIRE_FALSE( 1 == 2 )
with expansion:
!(1 == 2)
-------------------------------------------------------------------------------
(unimplemented) static bools can be evaluated
@@ -322,6 +457,12 @@ PASSED:
with expansion:
104.0 == Approx( 100.0 )
ApproxTests.cpp:<line number>:
PASSED:
REQUIRE( 104.0 == Approx(100.0).margin(4) )
with expansion:
104.0 == Approx( 100.0 )
ApproxTests.cpp:<line number>:
PASSED:
REQUIRE( 104.0 != Approx(100.0).margin(3) )
@@ -417,6 +558,42 @@ with expansion:
"this string contains 'abc' as a substring" ( contains: "not there" or
contains: "string" )
-------------------------------------------------------------------------------
Approx with exactly-representable margin
-------------------------------------------------------------------------------
ApproxTests.cpp:<line number>
...............................................................................
ApproxTests.cpp:<line number>:
PASSED:
CHECK( 0.25f == Approx(0.0f).margin(0.25f) )
with expansion:
0.25f == Approx( 0.0 )
ApproxTests.cpp:<line number>:
PASSED:
CHECK( 0.0f == Approx(0.25f).margin(0.25f) )
with expansion:
0.0f == Approx( 0.25 )
ApproxTests.cpp:<line number>:
PASSED:
CHECK( 0.5f == Approx(0.25f).margin(0.25f) )
with expansion:
0.5f == Approx( 0.25 )
ApproxTests.cpp:<line number>:
PASSED:
CHECK( 245.0f == Approx(245.25f).margin(0.25f) )
with expansion:
245.0f == Approx( 245.25 )
ApproxTests.cpp:<line number>:
PASSED:
CHECK( 245.5f == Approx(245.25f).margin(0.25f) )
with expansion:
245.5f == Approx( 245.25 )
-------------------------------------------------------------------------------
Approximate PI
-------------------------------------------------------------------------------
@@ -603,6 +780,32 @@ PASSED:
with expansion:
true
-------------------------------------------------------------------------------
Capture and info messages
Capture should stringify like assertions
-------------------------------------------------------------------------------
ToStringGeneralTests.cpp:<line number>
...............................................................................
ToStringGeneralTests.cpp:<line number>:
PASSED:
REQUIRE( true )
with message:
i := 2
-------------------------------------------------------------------------------
Capture and info messages
Info should NOT stringify the way assertions do
-------------------------------------------------------------------------------
ToStringGeneralTests.cpp:<line number>
...............................................................................
ToStringGeneralTests.cpp:<line number>:
PASSED:
REQUIRE( true )
with message:
3
-------------------------------------------------------------------------------
Character pretty printing
Specifically escaped
@@ -718,7 +921,7 @@ TrickyTests.cpp:<line number>:
PASSED:
REQUIRE( a )
with expansion:
true
0x<hex digits>
TrickyTests.cpp:<line number>:
PASSED:
@@ -1173,6 +1376,20 @@ MessageTests.cpp:<line number>
MessageTests.cpp:<line number>: FAILED:
-------------------------------------------------------------------------------
FAIL_CHECK does not abort the test
-------------------------------------------------------------------------------
MessageTests.cpp:<line number>
...............................................................................
MessageTests.cpp:<line number>: FAILED:
explicitly with message:
This is a failure
MessageTests.cpp:<line number>:
warning:
This message appears in the output
-------------------------------------------------------------------------------
Factorials are computed
-------------------------------------------------------------------------------
@@ -2602,14 +2819,17 @@ MessageTests.cpp:<line number>: FAILED:
CHECK( a == 1 )
with expansion:
2 == 1
with message:
with messages:
this message may be logged later
this message should be logged
MessageTests.cpp:<line number>: FAILED:
CHECK( a == 0 )
with expansion:
2 == 0
with message:
with messages:
this message may be logged later
this message should be logged
and this, but later
MessageTests.cpp:<line number>:
@@ -2617,7 +2837,10 @@ PASSED:
CHECK( a == 2 )
with expansion:
2 == 2
with message:
with messages:
this message may be logged later
this message should be logged
and this, but later
but not this
-------------------------------------------------------------------------------
@@ -3292,7 +3515,7 @@ with expansion:
re>"
-------------------------------------------------------------------------------
Long text is truncted
Long text is truncated
-------------------------------------------------------------------------------
TestMain.cpp:<line number>
...............................................................................
@@ -4450,7 +4673,7 @@ TrickyTests.cpp:<line number>:
PASSED:
CHECK( True )
with expansion:
true
1
TrickyTests.cpp:<line number>:
PASSED:
@@ -4462,7 +4685,7 @@ TrickyTests.cpp:<line number>:
PASSED:
CHECK_FALSE( False )
with expansion:
!false
!0
-------------------------------------------------------------------------------
Operators at different namespace levels not hijacked by Koenig lookup
@@ -5814,6 +6037,23 @@ MessageTests.cpp:<line number>:
warning:
toString(p): 0x<hex digits>
-------------------------------------------------------------------------------
Process can be configured on command line
empty args don't cause a crash
-------------------------------------------------------------------------------
TestMain.cpp:<line number>
...............................................................................
TestMain.cpp:<line number>:
PASSED:
CHECK_NOTHROW( parser.parseInto( std::vector<std::string>(), config ) )
TestMain.cpp:<line number>:
PASSED:
CHECK( config.processName == "" )
with expansion:
"" == ""
-------------------------------------------------------------------------------
Process can be configured on command line
default - no arguments
@@ -5825,6 +6065,12 @@ TestMain.cpp:<line number>:
PASSED:
CHECK_NOTHROW( parseIntoConfig( argv, config ) )
TestMain.cpp:<line number>:
PASSED:
CHECK( config.processName == "test" )
with expansion:
"test" == "test"
TestMain.cpp:<line number>:
PASSED:
CHECK( config.shouldDebugBreak == false )
@@ -6293,6 +6539,17 @@ TestMain.cpp:<line number>:
PASSED:
REQUIRE_THROWS_WITH( parseIntoConfig( argv, config ), Contains( "colour mode must be one of" ) )
-------------------------------------------------------------------------------
Reconstruction should be based on stringification: #914
-------------------------------------------------------------------------------
DecompositionTests.cpp:<line number>
...............................................................................
DecompositionTests.cpp:<line number>: FAILED:
CHECK( truthy(false) )
with expansion:
Hey, its truthy!
-------------------------------------------------------------------------------
SCOPED_INFO is reset for each loop
-------------------------------------------------------------------------------
@@ -6631,6 +6888,45 @@ PASSED:
with expansion:
Approx( 1.23 ) != 1.24
ApproxTests.cpp:<line number>:
PASSED:
REQUIRE( 0 == Approx(0) )
with expansion:
0 == Approx( 0.0 )
Write to std::cerr
-------------------------------------------------------------------------------
Standard error is reported and redirected
std::cerr
-------------------------------------------------------------------------------
MessageTests.cpp:<line number>
...............................................................................
No assertions in section 'std::cerr'
Write to std::clog
-------------------------------------------------------------------------------
Standard error is reported and redirected
std::clog
-------------------------------------------------------------------------------
MessageTests.cpp:<line number>
...............................................................................
No assertions in section 'std::clog'
Interleaved writes to error streams
-------------------------------------------------------------------------------
Standard error is reported and redirected
Interleaved writes to cerr and clog
-------------------------------------------------------------------------------
MessageTests.cpp:<line number>
...............................................................................
No assertions in section 'Interleaved writes to cerr and clog'
Message from section one
-------------------------------------------------------------------------------
Standard output from all sections is reported
@@ -6727,7 +7023,8 @@ PASSED:
with expansion:
"error: tag alias, "[@zzz]" already registered.
First seen at file:2
Redefined at file:10" contains: "[@zzz]"
Redefined at file:10
" contains: "[@zzz]"
TagAliasTests.cpp:<line number>:
PASSED:
@@ -6735,7 +7032,8 @@ PASSED:
with expansion:
"error: tag alias, "[@zzz]" already registered.
First seen at file:2
Redefined at file:10" contains: "file"
Redefined at file:10
" contains: "file"
TagAliasTests.cpp:<line number>:
PASSED:
@@ -6743,7 +7041,8 @@ PASSED:
with expansion:
"error: tag alias, "[@zzz]" already registered.
First seen at file:2
Redefined at file:10" contains: "2"
Redefined at file:10
" contains: "2"
TagAliasTests.cpp:<line number>:
PASSED:
@@ -6751,7 +7050,8 @@ PASSED:
with expansion:
"error: tag alias, "[@zzz]" already registered.
First seen at file:2
Redefined at file:10" contains: "10"
Redefined at file:10
" contains: "10"
-------------------------------------------------------------------------------
Tag alias can be registered against tag patterns
@@ -9324,6 +9624,6 @@ MiscTests.cpp:<line number>:
PASSED:
===============================================================================
test cases: 163 | 117 passed | 44 failed | 2 failed as expected
assertions: 955 | 849 passed | 88 failed | 18 failed as expected
test cases: 171 | 120 passed | 47 failed | 4 failed as expected
assertions: 985 | 871 passed | 93 failed | 21 failed as expected

View File

@@ -15,26 +15,42 @@ with message:
yay
-------------------------------------------------------------------------------
#542
#748 - captures with unexpected exceptions
outside assertions
-------------------------------------------------------------------------------
CompilationTests.cpp:<line number>
ExceptionTests.cpp:<line number>
...............................................................................
CompilationTests.cpp:<line number>:
PASSED:
CHECK_THROWS_AS( throws_int(true), int )
ExceptionTests.cpp:<line number>: FAILED:
due to unexpected exception with messages:
answer := 42
expected exception
CompilationTests.cpp:<line number>:
PASSED:
CHECK_THROWS_AS( throws_int(true), int& )
-------------------------------------------------------------------------------
#748 - captures with unexpected exceptions
inside REQUIRE_NOTHROW
-------------------------------------------------------------------------------
ExceptionTests.cpp:<line number>
...............................................................................
CompilationTests.cpp:<line number>:
PASSED:
CHECK_THROWS_AS( throws_int(true), const int )
ExceptionTests.cpp:<line number>: FAILED:
REQUIRE_NOTHROW( thisThrows() )
due to unexpected exception with messages:
answer := 42
expected exception
CompilationTests.cpp:<line number>:
-------------------------------------------------------------------------------
#748 - captures with unexpected exceptions
inside REQUIRE_THROWS
-------------------------------------------------------------------------------
ExceptionTests.cpp:<line number>
...............................................................................
ExceptionTests.cpp:<line number>:
PASSED:
CHECK_THROWS_AS( throws_int(true), const int& )
REQUIRE_THROWS( thisThrows() )
with message:
answer := 42
-------------------------------------------------------------------------------
#809
@@ -48,6 +64,125 @@ PASSED:
with expansion:
42 == {?}
-------------------------------------------------------------------------------
#833
-------------------------------------------------------------------------------
CompilationTests.cpp:<line number>
...............................................................................
CompilationTests.cpp:<line number>:
PASSED:
REQUIRE( a == t )
with expansion:
3 == 3
CompilationTests.cpp:<line number>:
PASSED:
CHECK( a == t )
with expansion:
3 == 3
CompilationTests.cpp:<line number>:
PASSED:
REQUIRE_THROWS( throws_int(true) )
CompilationTests.cpp:<line number>:
PASSED:
CHECK_THROWS_AS( throws_int(true), const int& )
CompilationTests.cpp:<line number>:
PASSED:
REQUIRE_NOTHROW( throws_int(false) )
CompilationTests.cpp:<line number>:
PASSED:
REQUIRE_THAT( "aaa", Catch::EndsWith("aaa") )
with expansion:
"aaa" ends with: "aaa"
CompilationTests.cpp:<line number>:
PASSED:
REQUIRE( templated_tests<int>(3) )
with expansion:
true
-------------------------------------------------------------------------------
#835 -- errno should not be touched by Catch
-------------------------------------------------------------------------------
MiscTests.cpp:<line number>
...............................................................................
MiscTests.cpp:<line number>: FAILED:
CHECK( f() == 0 )
with expansion:
1 == 0
MiscTests.cpp:<line number>:
PASSED:
REQUIRE( errno == 1 )
with expansion:
1 == 1
-------------------------------------------------------------------------------
#961 -- Dynamically created sections should all be reported
Looped section 0
-------------------------------------------------------------------------------
MiscTests.cpp:<line number>
...............................................................................
MiscTests.cpp:<line number>:
PASSED:
with message:
Everything is OK
-------------------------------------------------------------------------------
#961 -- Dynamically created sections should all be reported
Looped section 1
-------------------------------------------------------------------------------
MiscTests.cpp:<line number>
...............................................................................
MiscTests.cpp:<line number>:
PASSED:
with message:
Everything is OK
-------------------------------------------------------------------------------
#961 -- Dynamically created sections should all be reported
Looped section 2
-------------------------------------------------------------------------------
MiscTests.cpp:<line number>
...............................................................................
MiscTests.cpp:<line number>:
PASSED:
with message:
Everything is OK
-------------------------------------------------------------------------------
#961 -- Dynamically created sections should all be reported
Looped section 3
-------------------------------------------------------------------------------
MiscTests.cpp:<line number>
...............................................................................
MiscTests.cpp:<line number>:
PASSED:
with message:
Everything is OK
-------------------------------------------------------------------------------
#961 -- Dynamically created sections should all be reported
Looped section 4
-------------------------------------------------------------------------------
MiscTests.cpp:<line number>
...............................................................................
MiscTests.cpp:<line number>:
PASSED:
with message:
Everything is OK
-------------------------------------------------------------------------------
'Not' checks that should fail
-------------------------------------------------------------------------------
@@ -67,8 +202,10 @@ with expansion:
ConditionTests.cpp:<line number>: FAILED:
CHECK_FALSE( true )
with expansion:
!true
===============================================================================
test cases: 4 | 3 passed | 1 failed
assertions: 10 | 6 passed | 4 failed
test cases: 7 | 4 passed | 1 failed | 2 failed as expected
assertions: 23 | 16 passed | 4 failed | 3 failed as expected

View File

@@ -1,9 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuitesspanner>
<testsuite name="<exe-name>" errors="13" failures="76" tests="956" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testsuite name="<exe-name>" errors="13" failures="81" tests="986" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testcase classname="global" name="# A test name that starts with a #" time="{duration}"/>
<testcase classname="global" name="#542" time="{duration}"/>
<testcase classname="#748 - captures with unexpected exceptions" name="outside assertions" time="{duration}">
<error type="TEST_CASE">
expected exception
answer := 42
ExceptionTests.cpp:<line number>
</error>
</testcase>
<testcase classname="#748 - captures with unexpected exceptions" name="inside REQUIRE_NOTHROW" time="{duration}">
<error message="thisThrows()" type="REQUIRE_NOTHROW">
expected exception
answer := 42
ExceptionTests.cpp:<line number>
</error>
</testcase>
<testcase classname="#748 - captures with unexpected exceptions" name="inside REQUIRE_THROWS" time="{duration}"/>
<testcase classname="global" name="#809" time="{duration}"/>
<testcase classname="global" name="#833" time="{duration}"/>
<testcase classname="global" name="#835 -- errno should not be touched by Catch" time="{duration}">
<failure message="1 == 0" type="CHECK">
MiscTests.cpp:<line number>
</failure>
</testcase>
<testcase classname="#961 -- Dynamically created sections should all be reported" name="Looped section 0" time="{duration}"/>
<testcase classname="#961 -- Dynamically created sections should all be reported" name="Looped section 1" time="{duration}"/>
<testcase classname="#961 -- Dynamically created sections should all be reported" name="Looped section 2" time="{duration}"/>
<testcase classname="#961 -- Dynamically created sections should all be reported" name="Looped section 3" time="{duration}"/>
<testcase classname="#961 -- Dynamically created sections should all be reported" name="Looped section 4" time="{duration}"/>
<testcase classname="global" name="'Not' checks that should fail" time="{duration}">
<failure message="false != false" type="CHECK">
ConditionTests.cpp:<line number>
@@ -74,6 +99,7 @@ ExceptionTests.cpp:<line number>
</testcase>
<testcase classname="global" name="Anonymous test case 1" time="{duration}"/>
<testcase classname="global" name="AnyOf matcher" time="{duration}"/>
<testcase classname="global" name="Approx with exactly-representable margin" time="{duration}"/>
<testcase classname="global" name="Approximate PI" time="{duration}"/>
<testcase classname="global" name="Approximate comparisons with different epsilons" time="{duration}"/>
<testcase classname="global" name="Approximate comparisons with floats" time="{duration}"/>
@@ -83,6 +109,8 @@ ExceptionTests.cpp:<line number>
<testcase classname="Assertions then sections" name="A section" time="{duration}"/>
<testcase classname="Assertions then sections" name="A section/Another section" time="{duration}"/>
<testcase classname="Assertions then sections" name="A section/Another other section" time="{duration}"/>
<testcase classname="Capture and info messages" name="Capture should stringify like assertions" time="{duration}"/>
<testcase classname="Capture and info messages" name="Info should NOT stringify the way assertions do" time="{duration}"/>
<testcase classname="Character pretty printing" name="Specifically escaped" time="{duration}"/>
<testcase classname="Character pretty printing" name="General chars" time="{duration}"/>
<testcase classname="Character pretty printing" name="Low ASCII" time="{duration}"/>
@@ -192,6 +220,12 @@ MessageTests.cpp:<line number>
</testcase>
<testcase classname="global" name="FAIL does not require an argument" time="{duration}">
<failure type="FAIL">
MessageTests.cpp:<line number>
</failure>
</testcase>
<testcase classname="global" name="FAIL_CHECK does not abort the test" time="{duration}">
<failure type="FAIL_CHECK">
This is a failure
MessageTests.cpp:<line number>
</failure>
</testcase>
@@ -209,10 +243,13 @@ MessageTests.cpp:<line number>
</testcase>
<testcase classname="global" name="INFO gets logged on failure, even if captured before successful assertions" time="{duration}">
<failure message="2 == 1" type="CHECK">
this message may be logged later
this message should be logged
MessageTests.cpp:<line number>
</failure>
<failure message="2 == 0" type="CHECK">
this message may be logged later
this message should be logged
and this, but later
MessageTests.cpp:<line number>
</failure>
@@ -250,7 +287,7 @@ ConditionTests.cpp:<line number>
<testcase classname="Long strings can be wrapped" name="With wrap-before/ after characters/No wrapping" time="{duration}"/>
<testcase classname="Long strings can be wrapped" name="With wrap-before/ after characters/Wrap before" time="{duration}"/>
<testcase classname="Long strings can be wrapped" name="With wrap-before/ after characters/Wrap after" time="{duration}"/>
<testcase classname="global" name="Long text is truncted" time="{duration}"/>
<testcase classname="global" name="Long text is truncated" time="{duration}"/>
<testcase classname="global" name="ManuallyRegistered" time="{duration}"/>
<testcase classname="global" name="Matchers can be (AllOf) composed with the &amp;&amp; operator" time="{duration}"/>
<testcase classname="global" name="Matchers can be (AnyOf) composed with the || operator" time="{duration}"/>
@@ -387,6 +424,7 @@ MessageTests.cpp:<line number>
<testcase classname="global" name="Parsing a std::pair" time="{duration}"/>
<testcase classname="global" name="Pointers can be compared to null" time="{duration}"/>
<testcase classname="global" name="Pointers can be converted to strings" time="{duration}"/>
<testcase classname="Process can be configured on command line" name="empty args don't cause a crash" time="{duration}"/>
<testcase classname="Process can be configured on command line" name="default - no arguments" time="{duration}"/>
<testcase classname="Process can be configured on command line" name="test lists/1 test" time="{duration}"/>
<testcase classname="Process can be configured on command line" name="test lists/Specify one test case exclusion using exclude:" time="{duration}"/>
@@ -411,6 +449,11 @@ MessageTests.cpp:<line number>
<testcase classname="Process can be configured on command line" name="use-colour/yes" time="{duration}"/>
<testcase classname="Process can be configured on command line" name="use-colour/no" time="{duration}"/>
<testcase classname="Process can be configured on command line" name="use-colour/error" time="{duration}"/>
<testcase classname="global" name="Reconstruction should be based on stringification: #914" time="{duration}">
<failure message="Hey, its truthy!" type="CHECK">
DecompositionTests.cpp:<line number>
</failure>
</testcase>
<testcase classname="global" name="SCOPED_INFO is reset for each loop" time="{duration}">
<failure message="10 &lt; 10" type="REQUIRE">
current counter 10
@@ -438,6 +481,13 @@ A string sent directly to stderr
</system-err>
</testcase>
<testcase classname="global" name="Some simple comparisons between doubles" time="{duration}"/>
<testcase classname="Standard error is reported and redirected" name="Interleaved writes to cerr and clog" time="{duration}">
<system-err>
Write to std::cerr
Write to std::clog
Interleaved writes to error streams
</system-err>
</testcase>
<testcase classname="Standard output from all sections is reported" name="two" time="{duration}">
<system-out>
Message from section one
@@ -713,6 +763,9 @@ hello
</system-out>
<system-err>
A string sent directly to stderr
Write to std::cerr
Write to std::clog
Interleaved writes to error streams
</system-err>
</testsuite>
</testsuites>

Some files were not shown because too many files have changed in this diff Show More