Compare commits

...

1081 Commits

Author SHA1 Message Date
7cbd0b587a v2.1.2 2018-02-09 17:10:27 +01:00
2f15ccd4d3 Passthrough error code from coverage helper 2018-02-09 16:54:10 +01:00
8f3fc15b73 Update version of Clara
Fixes #1165
2018-02-09 16:50:19 +01:00
e13d9cab02 Keep .py files with LF endings so they can be executed from bash 2018-02-09 16:49:35 +01:00
414e2fa946 Make embedClara.py executable 2018-02-09 16:49:21 +01:00
b5ef68b044 Force MSVC to use utf-8 2018-02-08 15:44:33 +01:00
681f5daa13 Update approval tests 2018-02-08 15:00:56 +01:00
3b6fda3c1b Add tests for StringRef::numberOfCharacters 2018-02-08 13:10:12 +01:00
1b2fa601c6 Remove superfluous comment 2018-02-08 13:09:02 +01:00
39bfc6e82b Export Catch as a CMake package and 'linkable' target
Create a namespaced Catch2::Catch target that is 'linkable' through
`target_link_libraries()` and export it so it is findable through
`find_package()`.

`find_package()` will find versions with the same major number and with
minor number >= requested.

This makes catch a lot easier to use in CMake-based projects. Whether it
is found using `find_package` or included in the client project as a
subdirectory, the client can include the catch headers per-target with
`target_include_directories(target PRIVATE Catch2::Catch).

Example usage:

    cmake_minimum_required(VERSION 3.1)

    # include Catch2 as subdirectory or installed package
    # add_subdirectory(Catch2)
    find_package(Catch2 VERSION 2.1.0 REQUIRED)

    add_executable(tests tests/catch_main.cpp)
    target_link_libraries(tests PRIVATE Catch2::Catch)
2018-02-08 12:18:42 +01:00
ba6d33fb8c Enable -Wpedantic, fix unconditional use of C++14 extension 2018-02-05 10:04:59 +01:00
4be81d3588 Remove unnecessary semicolons 2018-02-05 10:03:51 +01:00
5201e92564 Redirect std::uncaught_exception to Catch::uncaught_exception
This means that only one place needs to work with warnings from
the deprecation of `std::uncaught_exception()` in C++17.

Closes #1162.
2018-02-02 15:36:15 +01:00
5e484862f2 Add Catch::is_range to documentation 2018-02-01 20:29:49 +01:00
5713381d06 Fixes for cygwin 2018-02-01 16:14:20 +00:00
1ab6be30a2 Add a BrightYellow colour, also use it for reconstructed exprs
Closes #979
2018-02-01 14:58:33 +00:00
126850e76b Prefer operator<< to range-based stringification
Fixes #1172
2018-02-01 14:07:23 +01:00
5e8df1c384 Update opensource-users.md 2018-01-28 21:05:24 +01:00
44dbda9f01 Add CATCH_VERSION_* defines for external use
I wonder how much use they will actually see, but their cost is
fairly minor.

Closes #1131
2018-01-26 20:56:14 +01:00
ca2455e6e6 Fixed NoAssertions warning 2018-01-26 16:52:28 +00:00
42213d4c31 Keep LICENCE.txt with LF as line endings for easy hashing 2018-01-26 16:45:32 +01:00
62dae592c3 v2.1.1 2018-01-26 16:06:07 +01:00
9a5705411a Add % to codecov coverage decrease threshold
Maybe now it will work?
2018-01-26 15:45:31 +01:00
a1aefce6e4 Guard against CLR exceptions when translating exceptions
Partially fixes #1138, need to decide what to do about structured
exceptions.
2018-01-24 12:11:29 +01:00
d5959907f5 Added Catch::clara namespace to doc for adding Opt
- Thanks to sakamoto-poteko in #1159 for point out its ommission
2018-01-23 07:44:09 +00:00
31e6499e64 Embed Clara v1.1.1 2018-01-22 15:08:28 +00:00
b0f4f16ee0 Namespace Catch CMake options 2018-01-18 23:20:26 +01:00
1e3ddbb496 Specify VERSION in modern CMake 2018-01-18 23:20:26 +01:00
15ad95c8db Make generateSingleHeader compatible with Python 2.7 2018-01-18 16:28:19 +01:00
00a10d5a5e Return fixed codecov settings 2018-01-18 13:51:32 +01:00
0d687a15d3 Change CMake project name to 'Catch2' 2018-01-18 13:13:39 +01:00
bdf431c400 Install documentation 2018-01-18 13:13:39 +01:00
a0359980f0 Use CTest to control test suite via BUILD_TESTING 2018-01-18 13:13:39 +01:00
8d4074aad9 Use GNUInstallDirs module
* `GNUInstallDirs` is a standardised way to
  change paths, which makes systems integration
  easier and allows for a more consistent user
  experience.
2018-01-18 13:13:39 +01:00
f0f40a0dbf Ensure that the single header is kept with LFs 2018-01-18 12:44:59 +01:00
fa4fd7f296 Modify codecov.yml again 2018-01-15 13:59:48 +01:00
07c84adfba Allow disabling -Werror in CMake
Related to #1152
2018-01-14 18:14:11 +01:00
8d854c689b Provide useful and unambigous stringification for static arrays 2018-01-14 18:06:43 +01:00
f0909dfe02 Add yet another expansion of INF macro
Closes #1151
2018-01-14 17:04:36 +01:00
de36b2ada6 Fix compilation for types where relops don't return bool
Closes #1147
2018-01-12 15:49:56 +01:00
9700ee4fc0 Update CTest autodiscovery documentation 2018-01-12 12:28:14 +01:00
bbda8cd77c Update reporter docs with their new location 2018-01-12 12:20:52 +01:00
4575594bbf Comment why the return code is clamped 2018-01-12 11:49:48 +01:00
c053dca26e Update path to vcpkg's portfile 2018-01-12 11:09:46 +01:00
3d7104c124 Catch `catch_discover_tests`
Copied from [Dynamic Catch test discovery in CMake](https://gist.github.com/garethsb/a01ed0dbd4977d439c16200640549935), which was inspired by [Dynamic Google Test Discovery in CMake 3.10](https://blog.kitware.com/dynamic-google-test-discovery-in-cmake-3-10/).

Original source code:

- Adapted by [Gareth Sylvester-Bradley](https://github.com/garethsb) from [GoogleTest ``gtest_discover_tests``](https://gitlab.kitware.com/cmake/cmake/merge_requests/1056).
- BSD 3-clause "New" or "Revised" License.
- Copyright 2000-2017 Kitware, Inc. and Contributors. All rights reserved.
2018-01-11 21:17:12 +01:00
6441c20a2c Modify codecov behaviour 2018-01-11 21:13:52 +01:00
5774c4f9c2 Update release process with the need to release reporters 2018-01-11 21:06:35 +01:00
2bc33dd04d Fix script responsible for updating release link in the readme 2018-01-10 14:02:15 +01:00
cd76f5730c v2.1.0 2018-01-10 13:53:04 +01:00
f5910f38ef Copy reporters to single_include during releases 2018-01-10 13:44:08 +01:00
421ab16062 Exclude string-literal arrays from automatic range serialisation
These have specialised serialisers already anyway, and were causing ambiguities in VS 2015 & 2017
2018-01-08 15:15:44 +00:00
161dd4ed24 Merge commit '2c43620d9baed1fdcaa9146af1d3eb90520cbe92' 2018-01-08 11:13:29 +00:00
13ea4225e7 Add fuxedo.io to open source users 2018-01-06 14:02:01 +01:00
2c43620d9b Exclude benchmark dir 2018-01-05 14:39:59 +00:00
8be1df243e Added test for stringifying std::arrays 2018-01-04 10:52:55 +00:00
32eb90b9bd Fix stringifying of unknown enums 2018-01-04 10:21:52 +00:00
702cfdaf6e Added special handling for vector<bool> when stringifying 2018-01-04 10:05:02 +00:00
e41e8e8384 Added tests for stringifying map and set 2018-01-04 10:03:08 +00:00
af3f2499bc Added generic container detection in StringMaker.
Removed vector specialisation as this is now covered generically - as are any containers that can be called via (freestanding) begin/ end
2018-01-04 09:30:06 +00:00
c3a1143d23 Cleanly override warning level for SelfTest in MSVC
Eliminates warning about warning level override (by removing the default /W3)
2018-01-02 10:18:35 +00:00
f580591bf8 Test different way of excluding system headers 2017-12-25 19:38:51 +01:00
fc88313d45 Added DtCraft to Open Source users 2017-12-12 17:22:40 +00:00
3979845d5f Add coverage badge 2017-12-11 13:06:27 +01:00
88d2bac624 Trivial typo fix. (#1119) 2017-12-09 21:29:39 +01:00
ed33e9787e Update MessageTests.cpp
typo corrected
2017-12-09 20:51:56 +01:00
f466d9a1ed Fix a7a9ee5 2017-12-09 20:49:06 +01:00
a7a9ee5552 Manual cherry-pick from #1111
This hsould merge still-valid piece of #1111 into master.
2017-12-09 20:17:47 +01:00
0cf05d54a6 Force Travis badge to use status of master branch 2017-12-08 21:47:42 +01:00
11887fbbab Point AppVeyor status badge at status for this repo
Previously it pointed to AppVeyor's test repo status
2017-12-08 21:36:43 +01:00
347be87126 Removed debug code accidentally left in previous commit 2017-12-08 16:30:16 +00:00
4da655c1b0 Increased int size for timers to avoid truncations 2017-12-08 15:59:00 +00:00
c4d1aa9033 Fix std::uncaught_exception deprecation warning in ~ScopedMessage
Closes #1124
2017-12-07 19:10:28 +01:00
495d2458e0 Add UnorderedEqualsMatcher for vectors
Closes #1093
2017-12-07 19:05:00 +01:00
3035120dc7 Some bits of tidy up 2017-12-07 00:02:32 +00:00
584e04d480 Add compact reporter baseline 2017-12-06 21:47:14 +01:00
673dcc16a9 Make approval tests also check compact reporter 2017-12-06 15:48:46 +01:00
0c122c135d Add constructor arg checking to WithinAbsMatcher
Also tests :-)
2017-12-06 15:42:03 +01:00
d19b7292b3 xml reporter reports WARN message when not used with -s 2017-12-06 14:30:17 +00:00
5e063616df Moved runner helpers into Catch namespace
not sure they weren't there to start with
2017-12-05 23:26:21 +00:00
aa9d635014 Refactored StreamRedirect classes 2017-12-05 23:19:28 +00:00
7c5a21fb7d Added clog test 2017-12-05 17:48:15 +00:00
533cdc6bc1 Revirtualised IResultCapture methods
Didn't really impact runtime anyway, but will need to use interface for threading support.
2017-12-05 16:23:10 +00:00
51e281a684 Simplify code coverage CMake toggle 2017-12-03 14:53:23 +01:00
24851dff99 Add release notes from the EOL of Catch Classic 2017-12-03 14:19:02 +01:00
a4fd96fbaa Remove debug prints from batch scripts 2017-12-03 14:14:58 +01:00
12c57cedda No longer rename AppVeyor builds 2017-12-03 13:06:21 +01:00
45a465713e Add codecov.io coverage collection from AppVeyor
Also had to add new project to redirect CTest output, add
separate batch scripts for AppVeyor because it doesn't handle
multi-line batch scripts in yaml properly, and other helper
scripts.
2017-12-03 13:03:52 +01:00
dfa817ae73 Just track whether last assertion passed directly, rather than deduce it from counts 2017-12-02 18:44:23 +00:00
57c346a46d Removed assertionRun() and rolled its logic into assertionPassed() and assertionEnded() 2017-12-02 18:44:23 +00:00
67f734c799 Remove system headers when preprocessing coverage report 2017-12-02 14:17:42 +01:00
b76e80ed3d Small clean-ups 2017-11-30 17:54:44 +03:00
a3632facf3 Fix teamcity reporter compilation with single header 2017-11-30 13:48:24 +01:00
7d0db6b8e9 Moved -Wparentheses suppression before the push for GCC
Because of bugs in GCC 4 & 5 that prevent _Pragma from working :-(
2017-11-29 20:19:50 +03:00
8a7493cd88 Globally suppress Wunused-variable again, for now 2017-11-29 20:01:00 +03:00
b5a5d9a6f8 Stop leaking some warning suppressions to user code 2017-11-29 19:14:33 +03:00
8c32d0b644 Add more weird chrono::duration stringification tests 2017-11-28 21:47:06 +01:00
28d1955ea8 Also test Approx template constructor 2017-11-28 21:29:34 +01:00
20211a33e6 Stop using brew if not needed -- fix build on XCode9 image 2017-11-27 22:34:44 +01:00
e3941a9ad2 De-virtualised isBinaryExpression() and getResult() on ITransientExpression 2017-11-27 22:49:26 +03:00
da86ddc620 Fixed accidental const & formating 2017-11-27 22:28:45 +03:00
4b614ee1d1 Moved all AssertionHandler logic into RunContext and de-virtualised interface
This makes the assertion handling much less "chatty". AssertionHandler is now just a thin shim over RunContext
2017-11-27 22:23:15 +03:00
5461242ffe Renamed last usge specific handle method (and made the low level ones private) 2017-11-27 22:23:15 +03:00
e344984a1b Add codecov.io coverage tracking
* Every Linux build tracks coverage when running Debug mode
* OS X not supported yet (Future WIP)
* Our own unit tests, non-default reporters and Clara are ignored
2017-11-27 20:13:47 +01:00
db44964e27 Refactored most handle() calls to more specific/ descriptive calls 2017-11-26 21:28:43 +00:00
2800adba25 Qualified handleExceptionMatchExpr in Catch::
(was picking it up by ADL before - no need to rely on that!)
2017-11-26 21:28:43 +00:00
ae1547e202 Add extra tests to ctest 2017-11-26 21:33:09 +01:00
73a1623eaf Re-enable 2 string tests 2017-11-25 18:38:18 +01:00
c411c131cb Move crtdbg.h include outside namespace 2017-11-24 10:36:54 +00:00
091595780e Clean-up re-usable string streams 2017-11-24 08:46:17 +00:00
f417995afc Cache IResultCapture in AssertionHandler to avoid repeated lookups 2017-11-23 19:21:09 +00:00
9329d97a43 Always debug-break non-inline 2017-11-23 19:14:26 +00:00
8141a7836f Inline shouldDebugBreak() 2017-11-23 16:58:43 +00:00
5323202652 Bake exception guard into assertion handler flow 2017-11-23 16:52:46 +00:00
f052762c11 Reduce amount of CI output on success 2017-11-22 18:29:58 +01:00
401ad7a189 Remove isTrue, alwaysTrue, alwaysFalse
isTrue and alwaysFalse were replaced by (void)0, 0 inspired by doctest
alwaysTrue was replaced by warning suppression
2017-11-22 16:03:45 +01:00
63c097a077 Remove superfluous TravisCI build entry 2017-11-21 18:56:29 +01:00
87c125ecb8 Enable Werror for dev builds 2017-11-21 18:55:28 +01:00
3b965aa501 (re)Inlined isTrue() 2017-11-21 13:12:22 +00:00
e54dcdac8b Added space in StringRef literal operator 2017-11-21 12:09:04 +00:00
e4a898eaaa Removed templated StringRef ctor and added StringRef literal 2017-11-21 11:08:39 +00:00
c39109dce3 Ignore all cmake-build-* folders 2017-11-21 11:08:39 +00:00
a8a1c379c0 Introduce a way to intentionally expose interface for use in tests
Fixes #1076
2017-11-21 11:10:07 +01:00
e08a4ed99e Added missing <cstring> include to stringref.cpp 2017-11-21 09:26:56 +00:00
fcba30569c Refactored to resetAssertionInfo() 2017-11-20 16:33:06 +00:00
4353614df7 Added StringRef constructor that captures string literal size at compile time 2017-11-20 16:33:05 +00:00
f36817ef83 Check single-header using test examples
This means that examples build for all matrix entries
2017-11-19 22:03:24 +01:00
812bf21740 Move imports close to point of usage in Python scripts
This means that you no longer need urllib2 to regenerate
single header file, etc
2017-11-19 22:02:22 +01:00
baf3d2f360 Split out ratio_string::symbol bodies 2017-11-19 14:54:52 +01:00
b083b04126 Fix compilation when using g++ with libc++
Fixes #1110
2017-11-19 14:47:18 +01:00
505d2f8977 Merge pull request #1107 from coombez/contrib
performance improvements
2017-11-17 23:32:04 +00:00
f18366150e performance improvement - getCurrentContext
inlined getCurrentContext and getMutableContext
Further work on #1086.
Brings test from 0m37.913 to 0m25.584s
Catch2 is now faster than Catch 1.x!!
2017-11-17 14:55:30 -06:00
fe725648a7 performance improvement - StringRef::operator=
inlined and reduced data copy in half.
Further work on #1086.
Brings test from 0m44.942s to 0m37.913.
2017-11-17 14:15:26 -06:00
b0c379f621 Inlined StringRef ctors/ dtor and size() and empty() 2017-11-17 18:38:54 +00:00
c443afcca0 Merge pull request #1104 from coombez/contrib
Performance improvement
2017-11-17 18:38:30 +00:00
502da4b38d Added files for multiply inclusions of test cases 2017-11-17 15:46:57 +00:00
8da845810d Rebased due to whitespace changes 2017-11-17 15:46:57 +00:00
61e838edf2 Reorganised (some) usage tests so they can be included multiple times 2017-11-17 15:46:57 +00:00
516dbc83bc Add inja to open source users (#1106)
* Add Inja to open-source users
* Capitalize first letter in user description
* Fix url
2017-11-17 11:49:39 +01:00
b9339333df Performance improvement
Begin to address #1086
Brings test from 2m51.072s to 1m15.661s
2017-11-15 14:43:43 -06:00
61e29b5630 Fix AssertionPrinter name conflict in console and compact reporters 2017-11-15 21:26:31 +01:00
54fb6f2d23 Provide WandBox link for online testing
It used to be provided for Catch Classic, it was lost during
transition of Catch2 to master.

Closes #1101
2017-11-15 20:23:05 +01:00
a077ebae4c Use svg build status icon for AppVeyor
Closes #1100
2017-11-15 18:54:04 +01:00
2bbba4f544 Refer to example code from the Tutorial 2017-11-15 15:37:39 +01:00
29cdd6c526 Add link to event listener example to documentation 2017-11-15 15:37:39 +01:00
dfb7217613 Add list of examples to documentation 2017-11-15 15:37:39 +01:00
f6ae45122b Add matrix element for examples to AppVeyor 2017-11-15 15:37:39 +01:00
d5d2bee4c5 Add matrix element for examples to Travis configuration 2017-11-15 15:37:39 +01:00
85de0727d4 Add examples subdirectory to CMake build; included if BUILD_EXAMPLES is true 2017-11-15 15:37:39 +01:00
4ecb2e112e Add examples folder with initial examples 2017-11-15 15:37:39 +01:00
97a8640cbf Update 3rd party bugs documentation
Removes bugs from no longer supported compilers
Adds a confirmed 3rd party bug in VS 2015

Closes #881
2017-11-14 22:05:30 +01:00
033e078320 Fix typo in build system docs 2017-11-14 21:42:28 +01:00
9796a77a37 Initial prototype of PCH support
Related to #1061
2017-11-14 21:41:36 +01:00
98d4c49d1c Provide ConsoleReporter declaration with EXTERNAL_INTERFACES
Related to #991
2017-11-14 20:42:58 +01:00
a096e4b3f2 Provide XmlReporter declaration with EXTERNAL_INTERFACES
Related to #991
2017-11-14 17:56:27 +01:00
4b3730de8a Provide JunitReporter declaration with EXTERNAL_INTERFACES
Related to #991
2017-11-14 17:15:13 +01:00
6acdacfde0 Provide CompactReporter declaration with EXTERNAL_INTERFACES
Related to #991
2017-11-14 16:13:35 +01:00
a3cba7a0d5 Conditionally compile problematic tests under old libstdc++ 2017-11-13 21:23:52 +01:00
9796846ad0 Workaround libstdc++-4.8 regex issue in approval tests 2017-11-13 18:19:40 +01:00
74d3dfd4cc All tests files have .tests.cpp suffix. Also moved tests out of TestMain.cpp and moved up a level 2017-11-13 16:03:27 +00:00
e34754e433 Split SelfTest test files into Usage and Introspective varieties
Usage: just exercises Catch. The tests are over arbitrary date/ types
Introspective: Tests parts of Catch itself.
2017-11-13 15:38:52 +00:00
55b71bebf1 Add tests for case insensitive string matching 2017-11-13 15:46:33 +01:00
b0857e846f Provide a regex matcher against std::string
Related to #1040
2017-11-13 15:35:31 +01:00
a06b6dc3ea Remove pointless StringRef -> std::string conversions 2017-11-13 13:08:59 +01:00
0adb04807a Change how non-nullness is enforce in StringRef constructor 2017-11-13 13:04:45 +01:00
f80f28e09a Fix pointless type mismatch between StringRef and std::string 2017-11-13 12:49:13 +01:00
484eee973c Move StringRef's impl details to anonymous namespace 2017-11-13 12:41:04 +01:00
d09fe4459d Stop recounting constant string's length on each passed assertion 2017-11-13 12:27:02 +01:00
e484236825 Don't invoke UB when nullptr is passed to StringRef constructor 2017-11-13 12:09:19 +01:00
e7c23b73da Don't call strlen in StringRef when the length was already passed 2017-11-13 12:03:45 +01:00
3537b7858f Removed vestigal ComparatorT template arg to MatcherBase 2017-11-13 10:08:48 +00:00
b74d4ca96d Add compilation test for #1027 2017-11-13 10:07:06 +01:00
8dbaac61ff Final set of fixes for floating matchers approvals 2017-11-12 11:49:36 +01:00
a0dbc62955 Fix OS X compilation error 2017-11-10 19:56:39 +01:00
cecee3459a Add another MSVC NAN macro 2017-11-10 19:52:43 +01:00
030321e3e0 Add NAN test for Approx 2017-11-10 18:48:45 +01:00
5f961af70e Remove leftover commented out lines 2017-11-10 18:37:58 +01:00
0b1f1b1003 Add ULP and margin matcher
Closes #1074
2017-11-10 18:33:00 +01:00
24e6d5fa33 Fixed release notes mention of *_THROWS_MATCHES
As reported in #1088
2017-11-09 11:09:17 +01:00
13370bddf2 Revert "Move <ctime> include out of line"
This reverts commit 36f02d76d6.
2017-11-08 08:31:48 +01:00
36f02d76d6 Move <ctime> include out of line 2017-11-07 21:59:52 +01:00
07ac9b92e4 Updated badges (again) for Catch2 2017-11-07 18:50:55 +00:00
0d3fc59f6d Added missing <memory> include 2017-11-07 18:48:57 +00:00
56e1075613 Introduced ReusableStringStream and removed all uses of std::ostringstream from the main path
ReusableStringStream holds a std::ostringstream internally, but only exposes the ostream interface.
It caches a pool of ostringstreams in a vector which is currently global, but will be made thread-local.

Altogether this should enable both runtime and compile-time benefits. although more work is needed to realise the compile time opportunities.
2017-11-07 18:01:10 +00:00
868e125d49 Moved a lot of stream related stuff out of the public headers and replaced more ostream dependencies with iosfwd 2017-11-07 15:55:09 +00:00
c9cdb9a48f Tweaked logo 2017-11-07 11:41:49 +00:00
5fd1d7174c Added link to Catch2 blog post 2017-11-07 11:27:01 +00:00
3a4c765030 Refreshed artwork for Catch2 2017-11-07 11:25:13 +00:00
a20b286999 Improve travis.yml
- Added new compilers and OS X images
- Option to run SelfTest under Valgrind
- Merge "Debug" and "Release" configurations into one run
-- This saves apt setup and cmake download step per compiler, 60-90s
- Fix C++14 compilation under Clang 3.8 and up
2017-11-07 11:24:18 +01:00
e28763ad05 Fix platform detection for iOS 2017-11-06 10:08:22 +01:00
b2dd48f0c0 Cleanup travis.yml: remove duplicate compilers, remove unused flag 2017-11-05 15:58:12 +01:00
7a562d39b2 Cleanup CMakelists.txt 2017-11-05 14:15:03 +01:00
fa9c4207f1 Replace include_directories() with target_include_directories()
to prevent inheritance of include directories that possibly lead to a clash.

A clash occurs when a folder is included, e.g. examples, that wants to use the single-include directory instead of the normal include directory as used by the SelfTest in the next higher level.
2017-11-04 22:08:56 +01:00
4f9123dc20 Remove self-include in header 2017-11-03 22:34:49 +01:00
19ab2117c5 Remove spurious test following merge 2017-11-03 18:09:55 +00:00
4acf112c19 Removed zombie files
These files were removed from the Catch2 branch, and crept back in when Catch2 merged with master
2017-11-03 16:56:11 +00:00
53f6d3fc8e Locked release notes reference to v2.0.1 release 2017-11-03 13:31:59 +00:00
cf76a795cc Added note about Catch2 to readme 2017-11-03 13:18:26 +00:00
811f4d13d7 Updated links in readme 2017-11-03 13:15:22 +00:00
7423a481eb Updated some Catch references to Catch2 2017-11-03 13:05:09 +00:00
46c7c9d3a0 Merge branch 'catch2' 2017-11-03 12:05:38 +00:00
b119ebdde1 v2.0.1 release 2017-11-03 12:01:52 +00:00
1c43fb64c1 Added docs for extending command line with Clara 2017-11-02 18:01:24 +00:00
8b40c26434 Removed handling of start-up exceptions from custom main docs 2017-11-02 18:01:24 +00:00
fe05062f9e Print any start-up exceptions in Session's constructor, so custom main's don't need to worry about them 2017-11-02 17:58:07 +00:00
31cc62e6b7 Updated release notes with Approx changes 2017-11-01 22:25:17 +01:00
a49e6fdc27 Update Approx documentation 2017-11-01 13:45:21 +01:00
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
accf9859b4 Add OSX specific INFINITE macro parsing in approval tests 2017-11-01 08:46:49 +01:00
22ac9d2184 Approx cleanup: More tests, INFINITY handling, etc 2017-11-01 07:30:11 +01:00
00af677577 Approx rework: default scale == 0, epsilon applies to Approx::value
Also adds check to Approx::epsilon that the new epsilon has a valid
(ie one between 0 and 1)

Based on
http://realtimecollisiondetection.net/blog/?p=89
https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
https://en.wikipedia.org/wiki/Approximation_error#Formal_Definition

The given epsilon should refer to the target value, otherwise
the result would be unexpected, e.g. 101.02 == Approx(100).epsilon(0.01)
is true.
The default scale should be invisible, thus,
e.g. 101.01 == Approx(100).epsilon(0.01) gets false.
Finally even 101.000001 == Approx(100).epsilon(0.01) is false
2017-10-31 15:43:42 +01:00
ae21020640 dev build 6 2017-10-31 15:17:21 +01:00
11f716f28d Make Approx::margin inclusive
Fixes #952, related to #980
2017-10-31 14:49:00 +01:00
c3ddd4a7e2 Update test-cases-and-sections.md
some clarification and typo correction
2017-10-31 14:28:30 +01:00
c43ce85416 Fix very minor typo
it's -> its
2017-10-31 14:28:20 +01:00
4220f2eef2 Update build-systems.md
typo correction
2017-10-31 14:28:10 +01:00
c1a91caf00 adds flushes to the output stream of teamcity reporter, making the test output more responsive. 2017-10-31 14:27:47 +01:00
96c5de678d 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-31 14:26:36 +01:00
e68485e196 added PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS option 2017-10-31 14:21:20 +01:00
88e912b4d1 Fix documentation crosslink in configuration.md 2017-10-31 14:19:53 +01:00
44244713f1 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-10-31 14:15:54 +01:00
eea9e1efd7 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-10-31 14:09:44 +01:00
2a3606f8e3 v1.11.0 2017-10-31 13:55:48 +01:00
a6cf19abff Make Approx::margin inclusive
Fixes #952, related to #980
2017-10-30 21:33:29 +01:00
601b2888ec Remove superfluous define from cmake project 2017-10-30 12:27:14 +01:00
3049445d78 Remove benchmark binary from main cmake list
We can give it a separate CMakeLists.txt later, but there is no
point in building it every time.
2017-10-30 12:25:57 +01:00
c672512979 Fix C4601 and enable C4602 warning for internal builds
Related to #1072
2017-10-30 12:14:20 +01:00
57b4e0b64c Fix missing pragma warning(pop) and other warnings under MSVC
Fixes #1072
2017-10-30 09:58:13 +01:00
06586b7180 Update test-cases-and-sections.md
some clarification and typo correction
2017-10-26 13:57:18 +02:00
93b3d2cb8f Fix very minor typo
it's -> its
2017-10-24 20:00:27 +02:00
a90473df28 Update build-systems.md
typo correction
2017-10-24 19:59:59 +02:00
75a77b6f8c embedded v1.0-develop.2 of Clara, which addresses / prefixed options, which should impact non-windows platforms
See #1054
2017-10-21 09:16:38 +02:00
5af918eefd Fix-up pkg-config provided include path
Related to #1032
2017-10-17 17:04:37 +02:00
c9d9699ca8 adds flushes to the output stream of teamcity reporter, making the test output more responsive. 2017-10-17 16:42:05 +02:00
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
664cbf702c added PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS option 2017-10-15 17:58:39 +02:00
fb6700df54 Fix documentation crosslink in configuration.md 2017-10-14 08:36:44 +02:00
05b1ca2884 Fixed expansion of _FALSE binary expression
- see #1051
2017-10-13 19:45:19 +01:00
da6c2a6914 Fixed expansion of _FALSE binary expression
- see #1051
2017-10-13 19:44:20 +01:00
c2b7bd15c0 Changed rhs expression capture from universal ref to const ref.
- addresses #1027
2017-10-13 14:16:14 +01:00
ba6845a865 Version of Clara with (std::max) 2017-10-13 13:46:39 +01:00
2eb93f47f7 enclosed more min/ max in parentheses to default MFC macros 2017-10-13 13:46:39 +01:00
276393e4e5 Change ToC script to use <br> instead of trailing spaces
Also updated docs that contain ToC. Fixes #1048
2017-10-13 11:17:38 +02:00
c7d9f02d5b Add pkg-config support
Closes #1032
2017-10-12 21:56:22 +02:00
355ab78f4a dev build 5 2017-10-12 13:06:41 +01:00
927f520a97 Moved windows proxy inclusion outside of CATCH_CONFIG_COLOUR_WINDOWS guard, so workaround early inclusion can be removed 2017-10-12 10:37:23 +01:00
cc0b093c20 unconditional windows proxy 2017-10-11 14:58:20 +01:00
17cdf20968 Mark part of std::chrono stringification tests nonportable 2017-10-09 14:56:23 +02:00
4899d891d3 Fix MSVC compilation when stringifying std::chrono::time_point 2017-10-09 13:13:30 +02:00
760a25e813 Fix baseline for file where std::pair stringification is not enabled 2017-10-09 13:12:50 +02:00
79b405fd3f Add stringification for std::chrono::{duration,time_point}
Also hides std::chrono, std::pair and std::chrono::* behind
new configuration macros, CATCH_CONFIG_ENABLE_*_STRINGMAKER
to avoid dragging in <utility>, <tuple> and <chrono> in common
path, unless requested.
2017-10-09 13:03:29 +02:00
f972732737 Workaround for stitching issue in #1020
Closes #1020
2017-10-03 18:41:49 +02:00
61280e6d0a Rename to updateDocumentToC.py and adapt for use with Catch
adding missing GPL 3.0 license (thanks for noting @horenmar).
2017-10-03 15:43:18 +02:00
7e9b53e40c Add original markdown_toclify.py by Sebastian Raschk (@rasbt)
- https://github.com/rasbt/markdown-toclify
2017-10-03 15:43:18 +02:00
b80c5134f0 Updated release notes 2017-10-01 17:03:06 +02:00
70e0d48978 Replace throw; with std::rethrow_exception(std::current_exception());
This works around a bug in libcxxrt handling of active exception count
that caused std::uncaught_exception() to return true even if there was
none.

Closes #1028
2017-09-28 12:53:09 +02:00
11918b76d0 Direct link to the single header file updated to latest release (dev.4). 2017-09-27 18:20:34 +02:00
5fe19f73e7 Scoped parseInfos population so i can be reused 2017-09-26 16:06:48 -07:00
c1416d55cb Backed out dynamic stack array (use fixed size for now) 2017-09-26 15:55:34 -07:00
2a1f8ae684 New version of Clara 2017-09-26 14:13:08 -07:00
9541e89e6a Changed embed script to just do direct regex substitution 2017-09-26 14:13:08 -07:00
80bbce8424 Reorganize release notes 2017-09-26 13:38:09 +02:00
3d49d83128 Added benchmark support to MultiReporters
- otherwise benchmarks are not reported if multiple reporters (usually reporter + listener(s)) are used
2017-09-21 09:32:46 +01:00
bd46f66754 dev build 4 2017-09-19 17:42:20 +01:00
e9f0773f37 Updated release notes 2017-09-19 17:36:20 +01:00
54f1ce2af2 Don't use console colour if running in XCode 2017-09-19 15:25:33 +01:00
0a146e3af7 OCTest project now #includes all cpp files, so they all get __OBJC__ defined 2017-09-19 14:59:12 +01:00
b9ff7ec301 Fixed issues for ObjC use (see #1011) 2017-09-19 14:38:18 +01:00
a63b4a75bd Updated OCTest project 2017-09-19 14:37:35 +01:00
8da0d0473b qualified a load of size_ts with std:: namespace (all those not from Clara) 2017-09-18 17:13:17 +01:00
40209d1ae0 Use StringRef on fatal error path
So far the fatal error path only uses string literals, so this removes
an allocation from that context
2017-09-14 20:05:25 +02:00
4e85267203 Add fatalErrorEncountered method to Reporter/Listener interface
An empty default implementation is provided to keep backward compatibility.
Called when signal or Structured Exception is encountered.

Related to #1005
2017-09-14 19:57:59 +02:00
eaf850cd0c Do not use SEH and console api under UWP
Fixes #1020
2017-09-11 21:09:35 +02:00
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
9aa96712ae Sweep out some extra warnings
Swept:
`-Wpadded` in some places (where it caused extra size, instead of just
saying "hey, we padded struct at the end to align, just as standard says")
`-Wweak-vtables` everywhere (Clang)
`-Wexit-time-destructors` everywhere (Clang)
`-Wmissing-noreturn` everywhere (Clang)

The last three are enabled for Clang compilation going forward.

Also enabled `-Wunreachable-code` for Clang and GCC
2017-09-07 17:25:15 +02:00
6105282c4f Removed function pointer comparison test from approvals as it has different serilaisation behaviour in MSVC 2017-09-07 15:04:30 +01:00
ca7021ae19 Reflected file extension changes in CMakeLists.txt file 2017-09-07 12:58:44 +01:00
03d41ce5b9 Suppressed meaningless function type qualifier warning in MSVC again
(this time in catch_tostring.h)
2017-09-07 11:25:10 +01:00
c5608f0202 Changed all .hpp extensions to .h where there is now a corresponding .cpp 2017-09-07 11:24:33 +01:00
8c39f9a725 Suppress MSVC warning about meaningless function type qualifier in generic code 2017-09-07 11:15:07 +01:00
4e5a67bc44 Added back OCTest project 2017-09-06 15:44:42 +01:00
2d37649377 Fixed Objective-C mode 2017-09-06 15:44:42 +01:00
8d03cb4915 Use StringRef to pass comparison operator name to BinaryExpr
Some nominally C++11 platforms do not have SSO (I am looking at
you libstdc++), where this avoids meaningless allocations.
2017-09-06 15:15:48 +02:00
b000411434 Stop accepting non-const comparison operators
A) non-const comparison operators should not exist and should not be
encouraged

B) The logic breaks comparing function pointers certain way

C) It was inconsistent anyway, as it only applied to `==` and `!=`

Closes #925
2017-09-06 15:01:03 +02:00
aef2e4d9e7 Update baselines 2017-09-02 20:29:05 +02:00
ab5d176195 Fix/disable failing approval tests 2017-09-02 10:51:19 +02:00
b3a923133d Actually fix AppVeyor ctest
Note, this doesn't mean it will start passing, just that it will
run the approval tests properly

Some changes are needed before it passes, as the Windows output
somewhat differs.
2017-09-01 19:12:15 +02:00
35bad89684 Fix ctest failure on windows 2017-09-01 17:55:16 +02:00
792d3d0a26 Fixed alignment of getSupportedVerbosities in MultipleReporters 2017-09-01 09:41:28 +01:00
be067bce37 Explicit ctor used to fix compilation failures caused by copy
initialization.
2017-09-01 09:40:11 +01:00
115db71bab Incorporated Clara with TextFlow fix for assertion with consecutive newlines
fixes #1012
2017-08-31 16:14:27 +01:00
3a5b951256 Make approval tests part of ctest 2017-08-31 12:00:35 +02:00
4e4a13dfb4 Update approvals after removing deprecated matcher helpers 2017-08-31 11:50:34 +02:00
e8ec6bd73c General cleanup for C++11
Also less allocations and less stack usage on the fatal condition path
2017-08-31 11:46:37 +02:00
e871742534 Move session to internal, split apart implementation 2017-08-31 10:31:52 +02:00
6388fc946f Remove last usage of NotImplementedException
TeamCity reporter now uses CATCH_ERROR instead
2017-08-30 20:03:54 +02:00
a4df0b2c37 Remove obsoleted utility functions on matchers
Natural operators, &&, || and ! are preferred and do not have
limited arity.
2017-08-30 19:45:09 +02:00
97edf7ce65 Fix-up compilation benchmark script 2017-08-30 18:11:52 +02:00
49a1408ff2 Fix compilation of main file with CATCH_CONFIG_FAST_COMPILE 2017-08-30 18:07:29 +02:00
9796c516bb Always compile matchers implementation 2017-08-30 18:06:48 +02:00
255f7d7369 Minor cleanup 2017-08-30 15:53:39 +02:00
46e28791ff Stitch .cpp files into single header in deterministic order 2017-08-30 15:43:44 +02:00
0673b9be35 Split RNG related things into its own file
This further removes 2 function declarations from the common path
2017-08-30 15:32:44 +02:00
48db47c737 Remove unused internal macro from the common path 2017-08-30 15:30:10 +02:00
cde57d9365 Remove tag alias registry interface from the common path 2017-08-30 15:28:33 +02:00
13213faa4e Update release notes in regards to CATCH_CONFIG_DISABLE 2017-08-30 12:43:23 +02:00
fc495ba0cb Dev build 3 2017-08-30 12:20:21 +02:00
4dcdcc0ac3 Change developBuild to work same as *Release 2017-08-30 12:16:10 +02:00
61d2c375dd Add evaluation specialization for T* and long
Fixes #1005
2017-08-30 12:11:41 +02:00
07211cea9c Add table of contents 2017-08-29 17:25:24 +02:00
c5553019cc Fix heading levels
- page title (chapter): 1
- sections: 2
2017-08-29 17:25:24 +02:00
66124d9e38 Make Current, Older releases sections, add subsections for each minor release 2017-08-29 17:25:24 +02:00
dd8e79c529 Streamline includes in external interfaces 2017-08-29 16:44:02 +02:00
4453fefb00 Remove check for compiler version before using __COUNTER__
All still supported compiler versions support __COUNTER__.
User can also still turn off use of __COUNTER__ by defining
CATCH_CONFIG_NO_COUNTER.
2017-08-29 15:45:58 +02:00
6e46f29830 Remove empty compiler detection
If they are needed in the future, they can be reinstated, but there
is no point in keeping them around currently.
2017-08-29 15:40:19 +02:00
92444d8b72 Remove catch_context.h from the common include path 2017-08-29 15:36:09 +02:00
bcb430b837 Clean up various minor things 2017-08-29 14:02:14 +02:00
5932576f53 Split writeToDebugConsole out of main path 2017-08-29 13:51:55 +02:00
faead53151 Update approval test baselines after removing [hide] tag 2017-08-29 13:48:20 +02:00
3b8b25c59d Make REGISTER_TEST_CASE auto registering
This also means it can be used in global scope
2017-08-29 09:52:58 +02:00
75f143835e Prevent exception translator registration with CATCH_CONFIG_DISABLE 2017-08-29 09:52:25 +02:00
05b6f03f3e Disable reporter/listener registration with CATCH_CONFIG_DISABLE 2017-08-29 09:48:52 +02:00
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
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
053c29a2b8 Add partial implementation of CATCH_CONFIG_DISABLE
* Assertions are defined into (void)(0) no-op
* SECTIONs are defined away (leaving {} as scope)
* TEST_CASEs and TEST_CASE_METHODs are not registered.
* REGISTER_TEST_CASE is defined into (void)(0) no-op
* METHOD_AS_TEST_CASE is defined away
2017-08-27 22:05:25 +02:00
2a13593885 Update CATCH_CONFIG_FAST_COMPILE documentation
Now it mentions that CHECK family of macros is affected as well
2017-08-27 16:48:15 +02:00
a0988dabf6 Add the experimental benchmark feature in documentation 2017-08-27 16:47:25 +02:00
8f6d6a4a2d Remove legacy [hide] tag
Also removed even legacier "./" prefix for test case name...
2017-08-27 16:45:53 +02:00
e8d3be3621 Workaround raw string literal bug in VS2017 2017-08-27 12:38:59 +02:00
67dc654c70 Fix updateVcpkgPackage 2017-08-27 11:48:25 +02:00
784f6dfb34 Fix updateVcpkgPackage 2017-08-27 11:43:55 +02:00
7818e2666d v1.10.0 2017-08-26 15:34:18 +02:00
cd30dd1a70 Workaround raw string literal bug in VS2017 2017-08-26 15:14:27 +02:00
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
b1d0085796 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:33:40 +01:00
b6e7c9bd7a Specialise removeConst for nullptr 2017-08-24 23:07:44 +02:00
180d9242f5 Suppress more signed/ unsigned mismatches during Evaluator calls on MSVC 2017-08-24 23:07:03 +02:00
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
071f49b12b Add page titles 2017-08-24 22:56:27 +02:00
dee61df274 Refactor release scripts, automatically update Wandbox on release 2017-08-24 22:50:25 +02:00
b07a2bdf87 Refactor release scripts, automatically update Wandbox on release 2017-08-24 21:59:06 +02:00
6c09b45a20 Let toplevel links to .md files link to .md#top 2017-08-24 19:40:36 +02:00
e8225052f1 Add html anchor 'top' 2017-08-24 19:40:36 +02:00
c03e8fce92 Explicitly ignore return value of getchar
This silences MSVC warning about ignored return value
2017-08-22 22:06:37 +02:00
a7a9be59ff Ignore return value of getchar when waiting for keypress
Previously this was causing warnings under MSVC for ignored return
value.
2017-08-22 22:00:52 +02:00
cb2fceb119 Force include catch_platform.h before any if-defs
Closes #994
2017-08-21 14:58:50 +02:00
49f5919c41 Add partial release notes for 2.0.0 2017-08-18 20:15:00 +02:00
489b639587 Change include guards in catch_external_interfaces.h
Previously they weren't recognized by the generateSingleHeader.py
script and weren't removed during stitching
2017-08-18 19:33:00 +02:00
c7da5b5128 Remove obsolete note from reporter documentation 2017-08-18 19:33:00 +02:00
3dc4de8173 Document implementation of listeners in non-main files
Closes #991
2017-08-18 19:33:00 +02:00
626b1d3936 Add problems with SECTIONs in loops to documentations 2017-08-18 19:33:00 +02:00
5d6c1f4dd0 Dev build 2 2017-08-18 15:58:00 +01:00
3bc03cd617 Went back to Catch 1.x behaviour for -d
-d takes "yes" or "no", rather than being a standalone flag option. The default is "defaultForReporter" so the previous change actually dropped some control.
2017-08-18 15:53:10 +01:00
28f11a7149 Added dummy listener registration 2017-08-17 19:40:48 +01:00
24af32f378 Add define that pulls in reporter and listeners interfaces
This allows users to define reporters and listeners in files different
from the main file.

Related to #991, #986
2017-08-17 20:23:30 +02:00
0545de0a31 Hold translated exception in local string while matching 2017-08-17 19:21:00 +01:00
ee75b324e7 Rebased with missing [failing] tag 2017-08-17 19:21:00 +01:00
597fca3c89 Remove <algorithm> header from the common path
It was only used for std::max<double> within Approx, so we now have
::Catch::Detail::max(double, double) that is used instead.
2017-08-17 20:04:53 +02:00
f99f511155 Removed *_REGISTER_REPORTER from main path
Also simplified them to single macro: CATCH_REGISTER_REPORTER
2017-08-17 20:03:16 +02:00
9a18ba042f Remove deprecated listener registration macro 2017-08-17 20:03:16 +02:00
8e6641c19b Replace stdint.h include with cstdint include
Just small unification of includes
2017-08-17 20:03:16 +02:00
185573e701 Do not include c++ stitch marking in final single header 2017-08-17 20:03:15 +02:00
632e023ff4 Added non-copyable test to [failing] set 2017-08-17 16:55:35 +01:00
b8f482b9aa Added test comparing non-copyable values 2017-08-17 16:48:46 +01:00
aaedae60b4 Fixed issue with comparing non-copyable values 2017-08-17 16:46:05 +01:00
27640a5a96 Added Clara and TextFlowCpp to open source users 2017-08-17 10:49:56 +01:00
ff9aaf3afe Added Clara and TextFlowCpp to open source users 2017-08-17 10:48:53 +01:00
e6ffbb732a Updated conan files to use version number 2017-08-17 08:40:58 +01:00
581aaae57e Generated single include for develop build 2017-08-17 08:29:57 +01:00
0b52dbe8bb Small doc updates 2017-08-17 08:28:45 +01:00
8c0a6a4358 Create CODE_OF_CONDUCT.md 2017-08-17 07:45:50 +01:00
dd3867bbcd Create CODE_OF_CONDUCT.md 2017-08-17 07:45:12 +01:00
8582780f11 Don't include string/ vector matchers if CATCH_CONFIG_MATCHERS defined 2017-08-16 14:38:04 +01:00
a36395e2ff Changed use of strncpy to memcpy 2017-08-15 23:47:52 +01:00
699e571400 Documented benchmark-resolution-multiple command line option
- and increased default to 100
2017-08-15 19:51:22 +01:00
07ded81541 Added --libidentify and --wait-for-keypress to docs 2017-08-15 19:43:30 +01:00
387f8d254d Removed unnecessary single quotes 2017-08-15 19:41:46 +01:00
c65eccd68e Added --libidentify and --wait-for-keypress to docs 2017-08-15 19:39:38 +01:00
61c5675c11 Removed inadvertent use of auto merged from dev-modernise 2017-08-15 19:34:10 +01:00
a988af219c No longer show full usage in event of error
(it obscures the error message)
- instead just suggests running with -? to see usage
2017-08-15 17:08:32 +01:00
70e4af9d44 Implemented wait-for-keypress option 2017-08-15 14:12:11 +01:00
74dfd0b1e0 Add open-source user 2017-08-15 13:48:43 +01:00
917a51da6b Added libidentify support, including option for waiting for keypress on exit (and/ or start) 2017-08-15 13:48:14 +01:00
f06ed856d8 Cherry picked 4f21bb72ff (Add tests for #961) from master
- had to redo the baselines
2017-08-15 12:43:27 +01:00
0aec06f4c3 Update documentation with changes from 7e4038d 2017-08-14 12:20:27 +01:00
7be258536e Suppress strncpy copy warnings on MSVC 2017-08-14 12:12:28 +01:00
94d347b059 Removed StringData 2017-08-14 09:14:49 +01:00
3772f69f0f Removed String and StringBuilder 2017-08-14 09:04:14 +01:00
ece64c3b3a Removed redundant .c_str()s from StringRef usages 2017-08-14 08:54:57 +01:00
fa3535e95e Added << ostream overload to StringRef 2017-08-14 08:50:44 +01:00
bb8c1fb17f Rebased with string conversion tests 2017-08-14 08:43:33 +01:00
c659e0fd3d StringRef conversions to/ from std::string 2017-08-14 08:39:14 +01:00
8f41bdb92d Add open-source user 2017-08-13 17:55:50 +02:00
1aab791d67 reformatted benchmark output a bit 2017-08-11 22:24:52 +01:00
eed4ae86ad Added config to control multiple of clock resolution to run benchmark iterations for 2017-08-11 22:24:52 +01:00
7fa5d9ca94 Removed redundant processName argument from libIdentify call 2017-08-11 22:03:09 +01:00
feaf355489 Implemented libidentify support
- see https://github.com/janwilmans/LibIdentify
2017-08-11 19:55:55 +01:00
df5c31bb19 Cleaned up the output a bit
- removed [!shouldfail] test from "green" path
- changed "spanner" to more descriptive text
2017-08-11 10:38:29 +01:00
2ce6c74f8f v1.9.7 2017-08-11 00:01:20 +02:00
9688891868 Fix issue with fatal errors and non-failing assertions
Fixes #990
2017-08-10 21:44:54 +02:00
4f21bb72ff Add tests for #961 2017-08-10 21:38:07 +02:00
684cbb2631 Fixes issue with fatal errors and non-failing assertions
Fixes #990
2017-08-10 17:10:13 +01:00
6282999291 Rebased approvals with info loop change 2017-08-10 17:00:22 +01:00
97c06ca6fb Merge branch 'reevaluate' into dev-modernize 2017-08-10 16:18:05 +01:00
3382312bd8 Remove obsoleted SCOPED_MSG and SCOPED_CAPTURE
Standard `MSG` and `CAPTURE` behave the same way these used to,
and are recommended instead.
2017-08-10 17:06:32 +02:00
b435e0d7c7 Make default reporter configurable at compile time
Closes #978
2017-08-10 16:45:38 +02:00
ba0a09fd9e Update documentation with changes from 7e4038d 2017-08-10 16:43:17 +02:00
5da76bb7be Allow specifying default reporter at compile time 2017-08-10 16:24:31 +02:00
11295a2663 Make catch_stream.hpp a standard .cpp file 2017-08-10 11:45:05 +02:00
aa42dd92d1 Merge branch 'master' into dev-modernize 2017-08-10 11:34:26 +02:00
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
ee9b19efd3 Moved matcher-based capture macros into their own file
- this file excluded from the CATCH_CONFIG_DISABLE_MATCHERS path.
- matchers are always compiled in to the impl file
- _THROWS_WITH macros are still available with matchers disabled - but only the ones that take a string
- tests that use matchers have #ifdefs, so the whole SelfTest project can compile with matchers disable.
2017-08-09 12:10:14 +01:00
b59e0ed48a Collapsed alternate capture macros now originals are redundant 2017-08-09 11:36:33 +01:00
8d21b4a916 Removed some unnecessary #includes
- and don't #include "catch_debugger.h" in the header path when CATCH_CONFIG_FAST_COMPILE is defined
2017-08-09 10:51:50 +01:00
4b5ac4d3d9 Actually do what the previous commit claimed to do!
:-s
2017-08-09 10:29:05 +01:00
8382d99081 Workaround for GCC 4.8 "deleted ctor in aggregate" bug 2017-08-09 10:18:31 +01:00
dc1df297e3 Suppressed some warnings
- signed/ unsigned mismatches
- virtual destructor on ITransientExpression (even though not needed)
2017-08-09 09:29:44 +01:00
8c95a81448 Removed all (well, most) of the redundant, ResultBuilder-based, code 2017-08-09 09:08:33 +01:00
7df290dfc1 Integrated new AssertionHandler into unexpected exception handling in RunContext 2017-08-09 08:49:59 +01:00
201028d6ec Integrated INTERNAL_CATCH_THROWS with new AssertionHandler 2017-08-09 00:52:20 +01:00
27fd8f80bd Integrated INTERNAL_CATCH_THROWS_STR_MATCHES with new AssertionHandler 2017-08-09 00:44:30 +01:00
ef4fa56b71 integrated INTERNAL_CATCH_THROWS_MATCHES with new AssertionHandler 2017-08-08 23:41:55 +01:00
9668410b8e integrated INTERNAL_CHECK_THAT with new AssertionHandler 2017-08-08 23:31:43 +01:00
92d714ee12 Update updateVcpkgPackage script for the new port format 2017-08-08 23:04:39 +02:00
705a1bf527 Add wandbox to release process documentation
Also some formatting and wording changes.
2017-08-08 23:04:10 +02:00
2832e23aa9 Restored exceptionGuard functionality under CATCH_CONFIG_FAST_COMPILE 2017-08-08 21:07:30 +01:00
5f91724368 integrated AssertionHandler into INTERNAL_CATCH_MSG 2017-08-08 20:17:09 +01:00
8a97beece2 integrated AssertionHandler into INTERNAL_CATCH_THROWS_AS 2017-08-08 19:43:07 +01:00
f033f4f184 integrated AssertionHandler into INTERNAL_CATCH_NO_THROW 2017-08-08 19:36:18 +01:00
f247ce5bff First cut of new AssertionHandler/ Decomposer
- integrated into INTERNAL_CATCH_TEST. Needs more work to fully replace existing stuff
2017-08-08 17:53:01 +01:00
f8148ebae1 Made macroName and capturedExpression StringRefs 2017-08-08 01:22:21 +01:00
59f9bcf1ed Reduced AssertionInfo to a pure record type 2017-08-08 01:08:07 +01:00
5e60050299 Removed default ctors for AssertionInfo, AssertionResult and SourceLineInfo 2017-08-08 01:02:24 +01:00
e658bacb04 Refactored how FAST_COMPILE affects internal test macros (less duplication) 2017-08-07 00:09:54 +01:00
3a409e9fd4 Suppress more signed/ unsigned mismatches during Evaluator calls on MSVC 2017-08-06 00:38:03 +01:00
63392e095e Refactored Evaluator templates to only be specialised on Op, with Lhs/Rhs types templated on method instead 2017-08-06 00:29:37 +01:00
0a2ce87d32 Removed compare layer from expression evaluation 2017-08-06 00:13:00 +01:00
b3b29f4b4c Use size_t for String size types 2017-08-05 22:53:21 +01:00
cff3818e68 Correctly handle special tags that also imply being hidden (!benchmark) 2017-08-05 22:24:17 +01:00
519db85758 Report benchmark durations in natural units
(and extended StringRef to be able to report utf8 char lengths
2017-08-05 21:41:56 +01:00
4421672fb8 Removed benchmark tests from approval tests (for now) 2017-08-05 11:26:20 +01:00
f45d35c980 Added benchmark tests 2017-08-05 11:12:29 +01:00
22e9ebef0d Factored table writing code out into a TablePrinter class (removes a lot of magic numbers and ad-hoc formatting) 2017-08-04 23:54:51 +01:00
97d6b08087 Changed clock resolution estimator to return uint64_t 2017-08-04 21:31:28 +01:00
a9b6813ad9 First draft of (experimental) benchmarking support 2017-08-04 19:23:30 +01:00
a1e3f0b624 Moved Timer impl back to cpp
(I thought it wasn't included on the non-main path, but it is)
2017-08-04 13:53:47 +01:00
39d37d9f34 Timer resolution is now nanoseconds 2017-08-04 12:22:16 +01:00
c7028f7bc7 Made most of Timer class inline - and export getCurrentMicrosecondsSinceEpoch() 2017-08-04 12:16:05 +01:00
5450de2acd Added some missing overrides and removed some virtuals from overrides 2017-08-04 12:13:58 +01:00
d5613fb18a Update matchers docs to reflect namespace usage 2017-08-03 19:11:21 +02:00
3882ac1a19 Include proper exception header in enforce.h 2017-08-02 00:26:52 +02:00
e8b785b177 Fixup bad merge in 2212cdfe 2017-08-02 00:04:26 +02:00
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
887fe1d5d2 Adding more flexibility into the cmake catch parsing script (#971)
* Adding more flexibility into the cmake catch parsing script
2017-08-01 22:50:21 +02:00
eab56d6656 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-08-01 22:49:27 +02:00
2212cdfe26 Eliminate some work when results won't be reported. 2017-08-01 22:49:27 +02:00
28741467d5 Update tutorial.md 2017-08-01 22:29:13 +02:00
7a76ff161b added 'args' argument parser library 2017-08-01 22:27:51 +02:00
4f72202c04 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-08-01 22:25:16 +02:00
cde987a92e Note start of .cpp files in single header 2017-08-01 22:20:14 +02:00
249bf116e8 Route all T* comparisons through const void* comparisons
This should stop the evaluate machinery from instantiating all the
templates for every ptr type that is compared, instead generating it
for single one.
2017-08-01 22:09:32 +02:00
6d4673505d Add missing <algorithm> include in catch_approx.hpp 2017-08-01 22:02:00 +02:00
85e14c5fb5 Move some compile-time dispatch to runtime
The runtime performance is likely to be negligible,
but compile times need every improvement they can get.
2017-08-01 21:58:09 +02:00
feca97dfde Split out internal error macros from the common path 2017-08-01 18:46:33 +02:00
c815ad1d53 Fix fwd declaration of IConfig in catch_test_case_registry_impl.hpp 2017-08-01 17:52:02 +02:00
d4e796c138 Move Section(End)Info bodies to proper .cpp file 2017-08-01 17:51:32 +02:00
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
7575749e56 Fix compilation error on older compilers 2017-08-01 17:21:06 +02:00
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
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
0a3f899d6a Move windows.h reduction logic into windows.h proxy header
Fixes #965 (at least the primary problem, the separate warnings can
be taken care of later)
2017-07-31 08:36:39 +02:00
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
d118ce191d Disable build broken by travis changes
It should be reenabled at some point, but I don't have the time ATM
2017-07-29 08:44:40 +02:00
d08e31d89e Fix inverted CATCH_CONFIG_DISABLE_MATCHERS toggle 2017-07-29 08:43:32 +02:00
0ca4cfb743 Introduce compile time toggle to remove Matchers from TU
The toggle is `CATCH_CONFIG_DISABLE_MATCHERS` and the only use is
to speed up compilation of small TUs. For large ones it is likely
insignificant, because the speed up is constant relative to
number of tests/assertions in TU.
2017-07-28 21:34:34 +02:00
35c1301bd5 Fix missing CATCH_ prefixed macros 2017-07-28 21:04:18 +02:00
d01fe03ba6 Removed <algorithm> include from the main path 2017-07-28 15:11:05 +02:00
287cc92b2c Remove <set> include from the common test path 2017-07-27 22:31:27 +02:00
446bad752f Move std::exception_ptr out of interfaces 2017-07-27 12:24:52 +02:00
307eeefa8f Change typedefs to using 2017-07-27 12:24:21 +02:00
33fd54a673 Split Option<T> and TagAlias definitions away from the main include path 2017-07-27 11:55:30 +02:00
918eca5ee9 Improve single header generator 2017-07-27 11:32:05 +02:00
5ebbec7dab Move all stringref function bodies out of line 2017-07-27 11:32:04 +02:00
a40add3153 Clean up Approx to take arguments by const& 2017-07-27 11:32:04 +02:00
ab0f1dcde9 Remove superfluous include 2017-07-27 11:32:03 +02:00
a75eaa3c5a Split out more headers into separate .cpp files 2017-07-27 11:32:02 +02:00
9de729b515 General cleanup 2017-07-27 11:32:01 +02:00
1a96175bb2 Split out helper functions on std::string from catch_common.h 2017-07-25 21:57:35 +02:00
1e59ccee41 Addressed Resharper-C++ warnings
See #958
2017-07-25 17:16:28 +02:00
b6f62af7d1 Address more of PVS studio warnings 2017-07-25 15:45:50 +02:00
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
46bf7605f4 Hold exception translators by unique_ptr
- and removed range deleters
2017-07-20 23:50:07 +01:00
cb6963216f Removed catch_section_info.cpp (not used) 2017-07-20 23:49:03 +01:00
b35225ff3a Removed tbc_text_format from CMakeLists.txt 2017-07-20 23:37:25 +01:00
c91639e1d7 Use Columns to format reporter list 2017-07-20 23:32:35 +01:00
3a37f45a97 Removed tbc_text_format (superceded by TextFlow) 2017-07-20 23:20:42 +01:00
6ec7709e07 removed final use of tbc_text_format (console reporter) 2017-07-20 23:13:08 +01:00
58d8bc6985 Removed Text tests (TextFlow has it's own test suite) 2017-07-20 23:09:50 +01:00
93556a1fb3 Removed "unapproved" baselines that got checked in at some point 2017-07-20 23:06:21 +01:00
d3c7d424fe Removed "long text" test (not a limitation of TextFlow) 2017-07-20 23:04:34 +01:00
224250e2d4 listTests now only uses TextFlow (not tbd_text_format) again 2017-07-20 20:10:13 +01:00
5c3355ad1b Embed Clara with TextFlow fix for whitespace after newline 2017-07-20 20:07:28 +01:00
b2a4dfcda4 Embedded version of Clara with TextFlow fix for embedded newlines 2017-07-20 19:42:06 +01:00
f0890dcdf8 removed redundant virtuals on override functions (and added a couple of overrides) 2017-07-20 16:23:52 +01:00
74ab1cd94b Update Baselines 2017-07-20 00:29:19 +02:00
87a66b8479 Address results of PVS-Studio static analysis
Couple are left un-addressed, see #958 for details.
2017-07-20 00:27:28 +02:00
2a586437e8 Fix merge mishap (duplicated catch_reporter_multi header) 2017-07-19 23:20:30 +02:00
cf2678dce6 Merge branch 'dev-better-verbosity' of https://github.com/BMBurstein/Catch 2017-07-19 23:17:19 +02:00
d7f754dc49 Fix SelfTest compilation after _THROWS_ assertion change
That is, changes made in efd79aa0bd
2017-07-19 22:21:47 +02:00
a14bd08b27 Update documentation to reflect the last change 2017-07-19 21:34:06 +02:00
efd79aa0bd Extend exception type in _THROWS_ with const& unconditionally
Potentially breaking change, but most people apparently were using it
wrong and thus it won't be breaking for them.

Closes #955
2017-07-19 21:30:00 +02:00
4a1e898eae More method bodies moved out of line 2017-07-19 15:32:58 +02:00
d7ff62430a Removed superfluous inline specifications 2017-07-19 13:40:00 +02:00
edbe122761 Split out non-templated Approx methods into cpp file 2017-07-19 13:40:00 +02:00
7a22bad763 Addressed some static analysis warnings
Based on findings in #957
2017-07-19 09:50:08 +02:00
0a614ee5ba re/moved some headers in catch_tostring 2017-07-19 08:31:10 +01:00
4833932ab2 Removed redundant member 2017-07-19 08:17:41 +01:00
cd6f6c021a Minor clean-ups in string conversion code 2017-07-19 08:16:55 +01:00
b0e3f45a22 Replaced some uses of tbc_text_format with TextFlow (from Clara) 2017-07-18 20:27:42 +01:00
d43024ff6b Removed intermediate IConfig ptr 2017-07-18 18:03:57 +01:00
c7931f6f18 Reuse ostringstream in XML reporter 2017-07-18 08:35:41 +01:00
01a21f67f7 Converted a load of spelt out iterators to auto 2017-07-18 08:08:17 +01:00
7ccf11da29 Split out catch_run_context into cpp and hpp file 2017-07-15 16:48:21 +02:00
cf6f9e3253 Initialise unexpectedExceptions in JUnitReporter 2017-07-13 10:10:39 +01:00
f193698fb3 Removed all (that I could find) redundant second macro args to TEST_CASE and SECTION
- now we can rely on variadic macros
2017-07-13 09:20:37 +01:00
c89bdf842e Removed failing enum test from test run 2017-07-13 09:18:40 +01:00
c874a99c6c Enabled c++11 tests in approvals 2017-07-13 08:52:51 +01:00
e4456aa243 Some clean-ups 2017-07-13 08:29:12 +01:00
d2d5910479 Suppress clang-tidy warnings about inline asm 2017-07-13 08:26:08 +01:00
e01ed48a70 Made everything used in test case registration noexcept
- this prevents warnings about startup-time exceptions
2017-07-13 08:25:47 +01:00
989222eceb Fixed up OcMethod base 2017-07-12 23:26:13 +01:00
720fdf1d02 Simplified test case registration and started using StringRefs 2017-07-12 23:11:41 +01:00
79627cdcdb Changed some names in test case registry
- in preparation for a bigger refactoring
2017-07-12 23:11:41 +01:00
10c36aa74c added override keyword to overrides in compact reporter 2017-07-12 23:11:41 +01:00
bc73189c52 Rebase baselines to take into account the removed test 2017-07-12 16:27:09 +02:00
e3e6453229 Removed spurious "inline" (was causing linker errors) and fixed broken macOS detection 2017-07-12 15:24:35 +01:00
878bd140e6 Removed superfluous inline keywords 2017-07-12 16:16:55 +02:00
d8df83ee2f Don't rely on transitive <string> include 2017-07-12 16:07:52 +02:00
8d8f481597 Moved couple function's bodies out of common-include path 2017-07-12 16:07:27 +02:00
3f6c078173 Use = delete instead of private, unimplemented copy operations 2017-07-12 15:11:23 +02:00
0bb9f52a99 Removed declared-but-undefined function 2017-07-12 15:10:55 +02:00
91c1556078 Moved Catch NotImplementedException out of the common include path
We could probably toss it away completely, currently it is used
only by TeamCity reporter.
2017-07-12 15:05:01 +02:00
4332b84c9b Moved leak detector to its own file 2017-07-12 15:03:52 +02:00
9c318af987 Remove obsolete GENERATE macro 2017-07-12 14:46:49 +02:00
8ebe94ca2e Added NOLINT annotations to selectively suppress clang_tidy warnings 2017-07-10 18:43:07 +01:00
1d3bfa0353 More include and impl refactoring 2017-07-10 14:25:38 +02:00
5f3f19de08 Default included reporters are now also in .cpp files
The non-default ones remain as header files.
2017-07-10 11:33:18 +02:00
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
93f84b5b0d Modified generateSingleHeader script to work with .cpp files better
Also fixed the scripts to take into account renamed version file
2017-07-09 21:02:36 +02:00
af05ccfe5d Merge remote-tracking branch 'upstream/dev-modernize' into dev-better-verbosity 2017-07-09 12:48:29 +03:00
058b21e604 Previous implementation didn't work
It relied on calling a virtual method from a base constructer
2017-07-09 12:46:53 +03:00
a53ea30723 Eliminate some work when results won't be reported. 2017-07-07 01:34:12 +02:00
fc32165d48 Started work on splitting out .cpp files from header files 2017-07-06 22:28:42 +02:00
f749347523 Check that reporter supports requested verbosity 2017-07-06 01:25:49 +03:00
8d380a7399 added 'args' argument parser library 2017-07-05 15:55:28 +02:00
3083de9ea6 Fix typo in README 2017-07-05 15:54:38 +02:00
bb9f2bb3ad Use new formatting capabilities 2017-07-04 18:16:42 +03:00
431e8d06e7 Added survey monkey link 2017-07-04 09:10:36 +01:00
694fe61ae3 Add ability to format any streamable class
This should probably be done at the source of this external file, but I couldn't find where that is. Perhaps it should be mentioned in the file header comment?
2017-07-02 11:52:29 +03:00
0016362f69 explicit conversion from size_t to size_type 2017-06-29 16:31:05 +01:00
63a8017ba7 Minor session tweaks 2017-06-29 14:27:53 +01:00
03afbdfec9 Made more of StringRef noexcept 2017-06-29 11:47:09 +01:00
f9ce8fd03b Added some missing cstring includes 2017-06-29 11:43:20 +01:00
60f25c7ffd Added string tests to approvals 2017-06-29 11:19:08 +01:00
78e7994435 Added string classes 2017-06-29 11:18:14 +01:00
6f32db35af Update tutorial.md 2017-06-28 20:54:31 +02:00
7013e388f7 #926 Update Conan test version by release
Signed-off-by: Uilian Ries <uilianries@gmail.com>
2017-06-28 16:45:42 +01:00
0270afb21b Updated license 2017-06-28 16:44:46 +01:00
df7c5622b9 Merge branch 'feature/conan' of https://github.com/uilianries/Catch 2017-06-27 11:48:55 +01:00
cb0a5194af Updated overview docs a bit 2017-06-27 11:45:47 +01:00
4c1880b35f Clamp exit code internally, so it doesn’t have to be done in every main() implies 2017-06-27 11:37:50 +01:00
ee67ac6b7c v1.9.6 2017-06-27 12:21:48 +02:00
fae0fa4ec1 Merge branch 'dev-second-string-argument-removal' into dev-modernize
It is no longer true that an assertion macro has either 1 or 2 args,
so...
2017-06-26 20:48:41 +02:00
c5bac73cad Merge branch 'master' into dev-modernize
This includes the performance commits done recently
2017-06-26 19:08:42 +02:00
1e7000ed55 Merged implemention of #934, but using 'verbose' option on command line instead.
(see 616f7235ef on master for original merge)
2017-06-26 17:15:28 +01:00
9382534d59 Added "How to test changes in PR" section to documentation
Also linked it from PR template.

Closes #936
2017-06-26 16:54:14 +01:00
7bcfdf8e94 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-26 16:50:23 +01:00
8d5f6c8e2e Fix how GCC version is detected when checking for __COUNTER__
Fixes #928
2017-06-26 16:49:34 +01:00
e62a9aa444 Removed const refs from NSString/ NSObject overloads (effectively reapplies PR #855 originally applied to "1.x" master) 2017-06-26 16:48:38 +01:00
059a33d555 Fixed indentation 2017-06-26 16:47:40 +01:00
8a14af701e If --list-extra-info is specified with --list-test-names-only, only output one list 2017-06-25 17:12:29 +02:00
07c6bfc3b9 --extra-info -> --list-extra-info, behaves like other --list-* flags 2017-06-25 17:12:29 +02:00
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
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
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
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
af66106500 Updated Clara with handling for / on Windows 2017-06-23 09:08:44 +01:00
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
0eb101e165 Remove "second argument" from result builder and assertion result
This is not quite complete removal (it doesn't pass approval tests),
but it should be representative of full perf improvements from doing so
2017-06-22 18:13:05 +02:00
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
2462dff088 Updated Clara with VS ICE workaround 2017-06-22 16:07:05 +01:00
0470b300a8 Reverted previous two commits as they didn’t fix anything 2017-06-22 15:53:24 +01:00
3bb16e8418 Reorganised CLI again in another attempt to get past VS ICEs 2017-06-21 11:42:53 +01:00
e0c6c4aee7 Another attempt to fix VS ICEs - split cli parser up. 2017-06-21 09:40:52 +01:00
c43d5f673f Moved command line lambdas out-of-line in an attempt to fix VS ICEs 2017-06-21 08:54:53 +01:00
d81c1eb006 added version of Clara that has virtual destructors
(just to silence warnings - they are not actually needed)
2017-06-20 22:35:35 +01:00
da5964af78 Updated version of Clara (should fix Windows compile issues)
- embedded using new embed script
2017-06-20 18:03:47 +01:00
017a63da62 v1.9.5 2017-06-15 13:08:26 +02:00
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
ee0defb939 Silence unused argument warning in Catch 2017-06-15 11:34:29 +02:00
efba988ccc Fix how GCC version is detected when checking for __COUNTER__
Fixes #928
2017-06-13 18:20:59 +02:00
e62b3beef4 Fixed issue with different result types in Clara 2017-06-13 08:29:56 +01:00
c41a45e79c Rebased following Clara changes 2017-06-12 23:13:27 +01:00
1c223b63ba Integrated (all) new version of Clara 2017-06-12 23:07:10 +01:00
6d9171aadb Updated approvals following Junit changes 2017-06-12 22:30:33 +01:00
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
ebb3371cbf Merge remote-tracking branch 'tsondergaard/improve-junit-xml-for-jenkins' into dev-modernize 2017-06-06 16:52:02 +02:00
e0aaba6cf8 Actually link #923 from the documentation 2017-06-06 16:46:46 +02:00
a09bef23ed Refer to #923 in reporter documentation 2017-06-06 16:43:14 +02:00
b6d9976fbb Make generateSingleHeader.py Python 2.7 compatible 2017-06-06 16:32:45 +02:00
6583284731 Fix erroneous result disposition for {REQUIRE,CHECK}_THAT
This fixes result disposition being ContinueOnFailure |
ContinueOnFailure for CHECK_THAT (obviously an error) and Normal |
ContinueOnFailure for REQUIRE_THAT (less obviously an error, but worse,
as that signals to the pipeline that assertion failure should both abort
and continue the test with ???? happening).
2017-06-06 15:12:03 +02:00
07ef028483 Update baselines 2017-06-06 15:07:57 +02:00
47eb9b3d68 Fix #914 being removed during last merge 2017-06-06 15:07:34 +02:00
8fde7abf31 Add tests for *_THROWS_MATCHES
Closes #641, closes #818
2017-06-05 19:15:17 +02:00
c465fbd0ea Slight documentation improvements 2017-06-05 18:42:04 +02:00
950cae9040 Added new assertion macros: *_THROWS_WITH
It combines `*_THROWS_AS` and `*_THROWS_WITH` macros, so that the
exception type matches expectetations and its contents match a specific
matcher.
2017-06-05 18:40:50 +02:00
7f6773bb4d Merge branch 'master' into dev-modernize
Hopefully nothing went too wrong.
2017-06-05 17:19:42 +02:00
b459bb4c43 Silence GCC's Wunused-function firing in compilation tests
The whole GCC kinda sucks around warnings, this is yet another place
where pragmas manipulating warnings don't work properly and thus a
warning has to be disabled globally... luckily, this time it is
happening in selftest file and thus it isn't too problematic to just
turn that warning of for the entire file.
2017-06-05 16:59:31 +02:00
1e16be0b9e Purge deprecated generators 2017-06-05 16:49:10 +02:00
69ff7fcf42 Include suite name in junit classname attrib for grouping in jenkins
Jenkins groups junit test results by loosely interpreting the
classname attribute of the <testcase> element as a package-qualified
java class name such as java.util.String. It ignores the <testsuite>
elements in the xml. To organize test results we therefore need to
embed the suite name in the classname attribute as if it was a java
package name.

Fixes #922.
2017-06-05 12:51:56 +02:00
a6b03031ba Use [#filename] tag for junit testcase classname attribute
If [#filename] is present in tags, use it for the classname attribute,
rather than "global". If the test fixture is present that still takes
precedence.
2017-06-05 12:51:56 +02:00
47c8994a61 Inherit from NonCopyable to disable RegisterHub copies 2017-06-04 22:56:57 +02:00
860de28b8d Catch and register startup exceptions in autoregistrars
Previously they were registered where they would be thrown otherwise
2017-06-04 22:37:59 +02:00
da0edcbe25 Collect startup exceptions instead of throwing them
Previously, some errors in Catch configuration would cause exceptions to
be thrown before main was even entered. This leads to call to
`std::terminate`, which is not a particularly nice way of ending the
binary.

Now these exceptions are registered with a global collector and used
once Catch enters main. They can also be optionally ignored, if user
supplies his own main and opts not to check them (or ignored them
intentionally).

Closes #921
2017-06-04 21:39:27 +02:00
0020747420 Generate single header even if output dir does not exist 2017-06-04 21:28:08 +02:00
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
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
a64a0c6f06 Consistent junit reporting regardless of internal SECTIONS
Change it so the classname attribute on the <testcase> element is the
test fixture name or "global" regardless of whether the TEST_CASE
contains SECTIONs. This way the output is not changed substantially,
just because a SECTION is added to a TEST_CASE.
2017-05-30 17:10:14 +02:00
377c9a746d Cosmetic fixes (whitespace and spelling) 2017-05-27 14:42:54 +02:00
ea48ae0f75 Add test for #914 (stringify truthy exprs in standard way) 2017-05-27 14:42:05 +02:00
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
1c59034be4 Merge pull request #911 from dvirtz/master
CTest integration script enhancements
2017-05-27 13:52:55 +02:00
52a84788e0 Add Inscopix to commercial users
Closes #918
2017-05-27 12:23:35 +02:00
169e260e8b Enable colourized output while in debugger 2017-05-22 00:41:31 +02:00
67914d8b86 Move back to static StringMaker<T>::convert
This avoids some breakage from the modernization
2017-05-21 23:40:05 +02:00
3e328f55fc Merge pull request #913 from Carrotstrip/master
fixed spelling error in tutorial.md
2017-05-21 11:17:25 +02:00
b18e67522f fixed spelling error 2017-05-20 15:10:42 -04:00
4b086bd5b5 added target name to test name and labels 2017-05-18 16:00:18 +03:00
aac594aae3 add option to print debug messages 2017-05-18 15:53:35 +03:00
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
d271683c14 Added release process notes/checklist/explanation 2017-05-16 21:33:58 +02:00
0bb8e1247e Merge branch 'master' of https://github.com/awglyde/Catch 2017-05-16 16:09:51 +02:00
32d97caf42 Fixed missing ` in tag documentation 2017-05-16 15:45:44 +02:00
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
df5cf2d323 Minor fixup in updateVcpkgPackage.py 2017-05-16 14:34:55 +02:00
b62c0256b2 Merge branch 'master' of https://github.com/philsquared/Catch 2017-05-16 14:34:27 +02:00
1ea84cb734 Expanded logging documentation
Closes #884
2017-05-16 14:34:20 +02:00
2a5d3736e8 Merge pull request #908 from pJunger/patch-1
Typo: Added namespace in method testCaseEnded
2017-05-16 14:05:31 +02:00
3dcc923351 v1.9.4 2017-05-16 13:59:29 +02:00
589c40077b Typo fix
Somehow I made that in 5ffc8a84cd without noticing
2017-05-16 13:51:17 +02:00
31f5e2ed81 Updated documentation about stringifying UDTs 2017-05-16 13:38:52 +02:00
d4e0b1d093 Added namespace in method testCaseEnded
Did not compile as is
2017-05-14 14:11:47 +02:00
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
85aa770701 Disable unreachable code warning for TrickyTests.cpp
Somehow this only triggers for VS 2015, Win32 | Release configuration...
2017-05-08 01:26:06 +02:00
f82e312552 Attempt at fixing compilation on OSX
Since I don't have actual access to OSX, this might be a tad optimistic.
2017-05-08 01:08:07 +02:00
bffef1bffa Fix alignment for Catch::Option
This is so much easier in C++11...
2017-05-08 00:59:44 +02:00
7e14232924 Fix C4702 (unreachable code) in generators
Generators might get removed anyway, but at least compilation wont
trigger Wx on MSVC in the meantime.
2017-05-08 00:58:44 +02:00
d7eb041ab5 Fix compilation on non-OSX platforms 2017-05-08 00:54:53 +02:00
8c757cc542 Removed need for Error class to capture stream inserted strings into exceptions 2017-05-05 18:39:49 +01:00
bada67bb72 Rebased approvals 2017-05-05 18:28:04 +01:00
4c5af2089a Added CATCH_ENFORCE (and updated CATCH_INTERNAL_ERROR to be stream based)
replaced all ad-hoc exceptions (where appropriate) with CATCH_ENFORCE or CATCH_INTERNAL_ERROR - no explicit ostringstreams.
2017-05-05 15:43:31 +01:00
687437fcd1 converted IStreamingReporter to unique_ptr 2017-05-05 15:43:31 +01:00
ef8b72c949 Changed dynamic_pointer_casts to static_pointer_casts 2017-05-05 15:43:31 +01:00
5604ec7266 Updated toString documentation
It will need another update when Catch 2 goes live.

Closes #741
2017-05-03 21:09:27 +02:00
a9128d0fac More macros are now variadic
Also added tests for them
2017-05-03 19:10:27 +02:00
c5c3d368a2 Added std:: qualification to nullptr_t
Apparently Clang doesn't like it unqualfied 😄
2017-05-03 00:29:36 +02:00
33ed1773f4 Reworked stringification layer, removed Catch::toString
Now the order of stringification checks is

1) StringMaker specialization
2) operator<<

toString overloads and specializations have been removed.
2017-05-02 23:51:03 +02:00
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
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
e641485132 Updated approval tests 2017-04-29 17:54:10 +02:00
a3ceb8f007 Approval tests now can deal with different expansions of errno 2017-04-29 17:52:12 +02:00
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
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
40130e59b4 Fix order of arguments in CATCH_FAIL macro 2017-04-28 18:33:52 +02:00
5ffc8a84cd Fix order of arguments in CATCH_FAIL and nonvariadic INTERNAL_CATCH_MSG
Fixes #896
2017-04-28 18:30:04 +02:00
6e0fa4be68 Update opensource-users.md
Fixed broken link to LICENSE
2017-04-27 10:29:58 +02:00
316cb28ea8 Added missing <memory> includes 2017-04-26 17:04:00 +01:00
51c143b2c6 Added test for assertion with comma 2017-04-26 16:12:48 +01:00
d17d94e45d Made INTERNAL_CATCH_TEST variadic so commas in assertions work 2017-04-26 16:10:18 +01:00
8ccbf63f28 Removed Ptr, Shared and SharedImpl 2017-04-25 21:56:14 +01:00
e6094a9503 migrated (Reporter) Nodes to std::shared_ptr 2017-04-25 21:56:14 +01:00
851e40a4bb migrated Pattern to std::shared_ptr 2017-04-25 21:56:14 +01:00
0807a6910f migrated ITracker to std::shared_ptr 2017-04-25 21:56:14 +01:00
44cccde8b9 Migrated ITestCase to std::shared_ptr 2017-04-25 21:56:14 +01:00
0844d6e867 Migrated IStreamingReporter from Ptr to std::shared_ptr 2017-04-25 21:56:14 +01:00
a96f25c716 Some listener and factory clean-ups 2017-04-25 21:56:14 +01:00
dd78824697 Migrated IReporterFactory to std::shared_ptr 2017-04-25 21:56:14 +01:00
338ba6b9ba Migrated Config and IConfig to shared_ptr (from Ptr) 2017-04-25 21:56:14 +01:00
41afd0c3d4 Removed copy ctor, assignment operator and swap from TestCaseInfo 2017-04-25 21:56:14 +01:00
602b62f037 Removed legacy reporter support 2017-04-25 21:56:14 +01:00
de348b9bdd Removed VS 2013 from AppVeyor
Does not support C++11 properly enough
2017-04-25 21:28:12 +02:00
c1835ec203 Removed gcc 4.7 from travis
It wasn't able to deal with C++11 properly
2017-04-25 21:27:29 +02:00
e749724a11 A load more C++11 tweaks - mostly moving initialisations from constructors to inline 2017-04-25 19:30:53 +01:00
cc8206f4c3 Removed SafeBool 2017-04-25 19:30:53 +01:00
e1bca7017d Most of Assertion macros are now variadic
This means that `REQUIRE(std::vector<int>{1, 2} == std::vector<int>{1,
2});` works as expected.

Note that assertion macros taking more than 1 argument are currently not
variadic, because variadic args have to come last, which would make the
interface of these ugly: `REQUIRE_THROWS_AS(std::exception const&, ....
)`
2017-04-25 20:20:46 +02:00
53864dee7b Fix MSVC compilation error
MSVC's `std::vector` requires its allocator to have copy constructor
from the same allocator kind, but templated over different type.
2017-04-25 19:54:22 +02:00
b245eaa7d1 Fix double-to-float conversion warning in tests 2017-04-25 17:48:28 +02:00
be0fc60c07 Updated version number for v2 development and removed single include (for now). 2017-04-25 14:43:13 +00:00
a0ada2e935 v1.9.3 2017-04-25 14:23:06 +00:00
e4694f58da Removed errant uses of uint64_t
fixes #894
2017-04-25 14:15:59 +00:00
61ac34045c Enabled SFINAE stream test 2017-04-25 14:57:58 +01:00
569d355b36 Removed C++11 config macro docs 2017-04-25 14:57:47 +01:00
79650e44f4 Removed more C++98/03 compatibility 2017-04-25 12:40:52 +01:00
5c8ea03cc8 Removed debug break support for PowerPC Macs 2017-04-25 12:27:26 +01:00
242022460d Use std::chrono for Timer to eliminate platform dependency 2017-04-25 12:24:34 +01:00
67005d290c Removed more redundant compatibility stuff from timer 2017-04-25 12:13:16 +01:00
f57f96f190 Removed pre-C++11 versions of Clang (3.4) and GCC (4.4) 2017-04-25 12:10:04 +01:00
71df66365e Gutted catch_compiler_capabilities
All C++11 toggles are now removed. What is left is either platform
specific (POSIX_SIGNALS, WINDOWS_SEH), or possibly still needed
(USE_COUNTER).

If current CLion is compatible with `__COUNTER__`, then we should also
force `__COUNTER__` usage.

Changed
* CATCH_AUTO_PTR    -> std::unique_ptr
* CATCH_OVERRIDE    -> override
* CATCH_NULL        -> nullptr
* CATCH_NOEXCEPT    -> noexcept
* CATCH_NOEXCEPT_IS -> noexcept

Removed
* CATCH_CONFIG_CPP11_UNIQUE_PTR
* CATCH_CONFIG_CPP11_SHUFFLE
* CATCH_CONFIG_CPP11_TYPE_TRAITS
* CATCH_CONFIG_CPP11_OVERRIDE
* CATCH_CONFIG_CPP11_LONG_LONG
* CATCH_CONFIG_CPP11_TUPLE
* CATCH_CONFIG_CPP11_IS_ENUM
* CATCH_CONFIG_CPP11_GENERATED_METHODS
* CATCH_CONFIG_CPP11_NOEXCEPT
* CATCH_CONFIG_CPP11_NULLPTR
* CATCH_CONFIG_VARIADIC_MACROS
2017-04-25 12:43:19 +02:00
97707afae1 Removed catch_type_traits from CMakeLists.txt 2017-04-25 11:09:06 +01:00
1f3ba8a0b6 Converted (almost) all for-loops with iterators or indices to range-based 2017-04-25 11:07:02 +01:00
073377a4e4 CMake defaults to C++11 2017-04-25 11:07:02 +01:00
6a09425de1 Remove C++98 backcompat from evaluate 2017-04-25 11:28:40 +02:00
c6e5738d54 Remove c++98 backcompat from timer 2017-04-25 11:25:49 +02:00
c6980ec2d8 Remove C++98 backcompat from toString 2017-04-25 11:21:22 +02:00
7c900660ef Removed superfluous reimplementation of type traits 2017-04-25 11:19:01 +02:00
2fdd81a33f Removed C++98 backcompat from Approx
Now it always uses type traits to work with all types convertible to
double
2017-04-25 11:11:26 +02:00
fc7f0a02b8 v1.9.2 2017-04-25 11:08:02 +02:00
211b330346 Don’t unconditionally #include <stdint.h> (as earlier MSVC don’t have it) 2017-04-25 08:43:14 +01:00
d36fe214a6 Further tweaked alignment hack for Option 2017-04-25 08:38:25 +01:00
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
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
8014bf1124 cmake script to generate ctest definitions from catch tests: fix for test case body bracket 2017-04-24 13:33:04 +02:00
49d87cf182 Add Newsbeuter to OSS users list (#891) 2017-04-22 16:02:55 +02:00
eedcc82d31 Tweaked storage alignment "workaround" a bit more in Option. 2017-04-21 07:19:39 +01:00
8e8259091c Fix .travis.yml syntax 2017-04-20 22:54:17 +02:00
7869e5b007 Enable C++11 and C++14 on OSX on Travis 2017-04-20 22:52:41 +02:00
a49af4648c Minor .travis.yml cleanup
Still could use someone more experienced to clean it up properly...
2017-04-20 22:50:07 +02:00
417b2bcf5c Enable C++14 on Linux on Travis 2017-04-20 22:47:05 +02:00
8f0feaa6d2 Enable /std:c++latest (C++17) for AppVeyor VS 2017 2017-04-20 21:32:50 +02:00
b95163bd3a Don't enable POSIX signals under QNX
Fixes #889
2017-04-20 21:02:25 +02:00
2809be87cc “fixed” alignment in Option 2017-04-20 14:39:07 +01:00
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
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
e5c5a636a9 junit reporter does not count exceptions as failures if ok-to-fail 2017-04-11 15:47:42 +01:00
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
b591cb9a03 Added note about thread safety in assertions
- closes #875
2017-04-11 14:25:19 +01:00
714d01c07c approved tests that were correct the first time (previous approvals were erroneous) 2017-04-09 20:40:11 +01:00
c6990cdf91 v1.9.1 release 2017-04-09 21:25:20 +02:00
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
5577322062 Added Nonius to open-sources users 2017-04-08 22:47:13 +01:00
1b03c5ab6a v1.9.0 release 2017-04-07 22:56:36 +02:00
7dd3c19027 Added NASA to commercial users list 2017-04-07 19:12:13 +01:00
29d26d3179 Commented out unused argument 2017-04-07 11:36:54 +01:00
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
250f0ee7fb Added approvals for “failed as expected” tests 2017-04-07 09:33:19 +01:00
09e4830199 Added VS2017 to AppVeyor matrix 2017-04-06 11:01:49 +02:00
8f85d08e9f Give up on _Pragma for gcc, force disable Wparentheses in all TUs 2017-04-05 21:37:27 +02:00
3ae076ce8d Updated REQUIRE* documentation under FAST_COMPILE 2017-04-05 10:26:19 +02:00
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
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
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
9a07dde16d print messages when unexpected exceptions are thrown 2017-04-04 11:27:19 +02:00
6e091d3991 Reset the UnexpectedException report state 2017-04-03 11:48:50 +02:00
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
3a3f152979 Updated documentation of CATCH_CONFIG_FAST_COMPILE 2017-03-29 21:13:51 +02:00
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
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
4838039b65 Merge pull request #869 from mloskot/patch-1
Add nanodbc library to Catch users
2017-03-27 07:43:27 +01:00
2a221b8fcd Add nanodbc library to Catch users 2017-03-26 21:26:08 +02:00
79ce6930a2 remove redundant "/"
This "/" is not needed as CMake adds this automatically
2017-03-23 21:18:07 +01:00
d762a7ca6c Expanded documentation about THROWS_AS assertions 2017-03-23 21:16:52 +01:00
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
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
f64d914bff Throw instead of calling exit in enforceNotReservedTag
Closes #865
2017-03-22 17:53:22 +01:00
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
e04dc5105b use inline 'libraryVersion()' function (closes #858) 2017-03-22 15:51:02 +01:00
cffb031ce1 Added polymorphic_value to OSS users 2017-03-22 10:33:52 +00:00
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
55ed17f97b Removed stray define 2017-03-20 10:53:32 +01:00
6a502cc2f5 Renamed licence file, license should now be detected by github 2017-03-20 08:59:25 +01:00
6a009fabcb Documented REQUIRE under CATCH_CONFIG_FAST_COMPILE 2017-03-17 17:02:39 +01:00
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
4dc06bdb70 Use bulk vector::insert rather than back_inserter 2017-03-15 15:19:38 +00:00
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
46d166406d Set execute permission on runnable python scripts 2017-03-15 12:24:18 +01:00
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
e7984e3711 Reorganised the readme/ ref docs TOC and added link to reporters docs 2017-03-15 09:08:20 +00:00
90d89377ea Added docs on reporters 2017-03-15 09:07:23 +00:00
0692317bc5 Added Obj-C bindings fix to release notes 2017-03-15 09:04:09 +00:00
e8b31108d6 Fix Catch::toString() linker error when main() is compiled as C++
Fixes #278
2017-03-14 11:54:14 -07:00
95fc8d62a2 Fixed up old documentation links in release notes 2017-03-13 21:31:26 +01:00
0c015aa887 v1.8.2 release 2017-03-13 21:29:30 +01:00
f69f821853 Updatecd [!shouldFail] docs with extra explanatory note, 2017-03-13 19:35:17 +00:00
485dbdc0e7 Added link to event listeners docs 2017-03-13 19:27:18 +00:00
0afd52b98d Fix Objective-C Matchers
Fixes #854
2017-03-13 15:40:21 +00:00
38b05f1400 Don’t assume first CL arg (exe name) is present
Fixes #729
2017-03-13 11:00:58 +00:00
db9866677e Don’t ref past end of string
fixes #830
2017-03-13 10:22:02 +00:00
4101ff314a #include <ctype> for std::to lower 2017-03-10 19:25:00 +00:00
68da5a6d19 Docs for Listeners 2017-03-10 19:17:25 +00:00
e4a25ad5ff Added CATCH_REGISTER_LISTENER without the INTERNAL_ prefix 2017-03-10 19:15:03 +00:00
5d6c744d38 Qualified std::tolower in Clara.
Fixes #543
2017-03-10 18:38:52 +00:00
5dd0639520 Added FAIL_CHECK
Works like FAIL, but does not abort test.
As proposed in #765
2017-03-08 15:42:11 +00:00
a2515755c3 Merge pull request #846 from m0ppers/patch-1
Add ArangoDB
2017-03-07 11:34:07 +00:00
807941eb31 Add ArangoDB 2017-03-07 12:29:13 +01:00
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
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
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
d8f45cd5f1 changing tabs to spaces 2017-03-06 10:55:00 -05:00
3afd077b55 teamcity reporter should time durations explicitly 2017-03-06 10:35:03 -05:00
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
932a405e18 /Wx -> /WX (stupid typo) 2017-03-06 11:29:57 +01:00
9a037204fa Enable /Wx (Warnings as error) for SelfTest builds 2017-03-06 11:21:35 +01:00
374c050a42 benchmarkCompile.py fixup 2017-03-06 10:59:17 +01:00
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
af1ed708e4 Copied release note fixes to documentation 2017-03-06 10:46:21 +01:00
041498b221 Fixed unintentional tabs 2017-03-06 09:23:31 +00:00
d5a5883a10 Fixed mssing virtual destructor warnings
In Visual Studio with warning 4265 enabled
Closes #844
2017-03-06 08:59:52 +00:00
6fea473414 Fixed CMake generation of MSVC warning levels 2017-03-06 08:35:14 +00:00
68e7fdce20 Added 4265 to specific warnings in VS 2017-03-06 08:21:52 +00:00
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
e952fa8946 Added release badge 2017-03-03 15:25:58 +00:00
84a178f0b0 Add AppVeyor status 2017-03-03 14:38:20 +00:00
f9db24a824 Refactored console reporter include logic to match Xml Reporter’s 2017-03-03 14:19:41 +00:00
9bee606dd6 Tweaked Xml Reporter to follow same success/ info behaviour as Console reporter 2017-03-03 14:12:47 +00:00
be4f6ab8e1 Change reporting of CAPTURE'd variables
Info is not changed, intentionally.

Closes #639
2017-03-03 14:34:50 +01:00
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
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
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
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
0b28d3daf2 Merge branch 'tap-count-success' of https://github.com/gahr/Catch 2017-03-02 15:23:46 +01:00
8435dcbb61 Resized main logo again 2017-03-01 17:00:33 +00:00
99347df70e Updated artwork 2017-03-01 16:47:04 +00:00
658b5f63ef Updated release notes 2017-03-01 16:06:48 +00:00
c6535a080e v1.8.1 release 2017-03-01 16:04:44 +00:00
673ec550f5 Moved definition of _BSD_SOURCE earlier 2017-03-01 15:59:10 +00:00
ff78e7c45a Fixed typo in test name 2017-03-01 15:59:10 +00:00
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
470561cbbd Update release-notes.md
Removed speed up time placeholder
2017-03-01 08:24:16 +00:00
417202b743 Update release-notes.md
Fixed docs/ paths
2017-03-01 08:22:38 +00:00
0952b76e16 v1.8.0 release 2017-02-28 14:19:09 +00:00
bbeb192ec9 Updated baselines 2017-02-27 16:27:43 +01:00
e4f4335b07 Improved Approx documentation 2017-02-27 14:22:17 +01:00
8c07899715 Added tests for using margin with Approx. 2017-02-27 14:15:03 +01:00
d5c623b3b6 Merge branch 'develop' of https://github.com/CNugteren/Catch
This adds an optional absolute margin to the Approx checks.
2017-02-27 13:12:13 +01:00
061a183036 Console reporter now uses fixed decimal formatting
3 decimal places, output in seconds.
2017-02-27 11:34:15 +01:00
70ac6dbb9f Minor output improvements in approvalTests.py 2017-02-24 15:56:26 +01:00
593161ddd8 Documented the new vector matchers 2017-02-24 15:42:11 +01:00
71e500f4b5 Updated reporter documentation 2017-02-24 14:01:38 +01:00
ad942885ce Removed unused exception object from release notes script 2017-02-23 08:11:15 +00:00
e058a37614 Removed stray code 2017-02-23 08:11:15 +00:00
72b72ca937 Fix C++11 dependency in TAP reporter 2017-02-22 17:04:36 +01:00
a8a6b3159d Disabled C4312 in the evaluate layer
We reinterpret cast int to T* (because someone might compare 0 to a
ptr), which causes 4312 to fire when x64 platform is set.

Fixes #148
2017-02-22 14:14:59 +01:00
9e2616aeac Add missing assert.h include to reporter bases.
It being missing caused an error when compiling under MSVC.
2017-02-22 13:31:51 +01:00
c5ffd2e3f0 Fixed up Automake reporter 2017-02-22 13:29:17 +01:00
0f24a8c06f Added Automake and TAP reporters to SelfTest's main 2017-02-22 13:28:36 +01:00
b0260c615d Fixed-up TAP reporter a bit. 2017-02-22 13:28:13 +01:00
a63ce953a0 Add TAP reporter
This is a hackish attempt to add a TAP reporter (see
philsquared/Catch#309 ) by following the TAP 12 specification
<http://testanything.org/tap-specification.html>. I'm unsure how well I
did in following the spec or with following good C++ guidelines.
Comments are appreciated.

Signed-off-by: Colton Wolkins (Ogre) <frostyfrog2@gmail.com>
2017-02-22 11:35:20 +01:00
b753f05d74 Add reporter for Automake (#826)
This allows for integration with Automake's default log compiler.

See #826 for more details.
2017-02-22 11:17:25 +01:00
9bab7c8229 Changed console reporter test duration reporting format
Was
"<section-name> completed in XXX s."
Now is
"XXX s: <section-name>"

Closes #322

(cherry picked from commit 0805539)
2017-02-22 08:35:53 +00:00
d8c4512b25 Removed tabs 2017-02-22 08:26:52 +00:00
2e08bfe9cc Single include generator now handles spaces between # and include 2017-02-22 08:05:31 +00:00
d2a59ad37b Fixed test spec parser issue
- multiple specs in a single string, with escapes in each were erroring out
2017-02-22 07:49:38 +00:00
10dfca34ac Added first vector matchers (Contains and Equals) 2017-02-21 16:05:04 +00:00
45d4096756 Generalised Matchers so objects and comparators can be different types 2017-02-21 15:52:03 +00:00
4e6938d78e Moved matchers tests into their own file 2017-02-21 14:19:09 +00:00
1ca8cefa9a Added #define needed for gettimeofday() to be declared on some versions of Cygwin 2017-02-21 11:32:32 +00:00
ca66dd243c Added a couple more unimplemented assignment operators to silence VS2013 warnings 2017-02-21 09:10:44 +00:00
44632c3d71 Merge branch 'warning-c4512' of https://github.com/gchudnov/Catch into gchudnov-warning-c4512 2017-02-21 08:56:14 +00:00
aa28196e8b Ignore .vs folder 2017-02-21 08:52:08 +00:00
5d8055319e Updated docs to reflect the change to leak checking 2017-02-18 17:24:31 +01:00
b1835e1de9 Moved WIndows leak detector code out of main() 2017-02-17 23:43:31 +00:00
8cd413572a Merge branch 'dev-windows-leakdetection' 2017-02-17 14:25:08 +01:00
30e4dbef1c Report leaks to debugger in addition to stderr
This branch should also close #120.
2017-02-17 14:22:57 +01:00
90b3946e9c Add file/line to TestCase, Section and Failure elements in Xml Reporter 2017-02-17 10:26:17 +00:00
9202a77498 Documentation improvement 2017-02-16 11:11:52 +01:00
d8230a8d4d Add opt-in leak detection under MSVC + Windows.
Closes #439
2017-02-16 11:09:09 +01:00
c6178601c5 Cygwin compatibility fixes 2017-02-15 17:57:22 +01:00
2e0ae01b05 Improve -Wparentheses supression for gcc
If the gcc version supports `_Pragma` properly, we use that to disable
it locally inside assertions.

Otherwise we disable it for the entire TU.

Fixes #674
2017-02-15 17:11:44 +01:00
1f71d1f760 Some minor clean-up to Python script 2017-02-15 11:54:47 +00:00
fe690a68ef push/pop warnings when disabling parentheses warnings within assertion (gcc/ clang) 2017-02-15 10:03:28 +00:00
c9a37c59c4 Added CATCH_CONFIG_FAST_COMPILE to documentation. 2017-02-15 10:42:11 +01:00
3cfef738e7 Merge branch 'dev-performance-round3' 2017-02-15 10:35:01 +01:00
5cb9e47034 Added SOCI to open-source users 2017-02-15 08:39:21 +00:00
044b616127 Added link to matchers docs from readme 2017-02-15 08:30:47 +00:00
f88049169e Fix wrong short option for section 2017-02-15 08:17:43 +01:00
7b13a8f85a Move debug break out of tests, speeds up compilation time
This is hidden behind CATCH_CONFIG_FAST_COMPILE
2017-02-14 15:35:12 +01:00
6da5e0862a Benchmark script: allow passing flags to compiler 2017-02-14 15:34:17 +01:00
2049113935 Benchmark script: use median AND mean of compile time 2017-02-14 15:34:00 +01:00
d4ae1b18c0 Matcher documentation 2017-02-14 09:16:54 +00:00
2081caa452 Import MatcherBase to Catch namespace 2017-02-14 09:16:54 +00:00
a5a013811c Renamed toStringUncached -> describe 2017-02-14 09:16:54 +00:00
1400127d6f Extracted string matchers impl into cpp that is only compiled into main TU 2017-02-14 09:16:54 +00:00
7fed25ad1f New Matchers implementation
- simpler
- less templates and machinery
- no cloning, copying or unnecessary heap allocations
- better factored
2017-02-14 09:16:54 +00:00
5530303be7 Removed test for invoking String Matcher with NULL (this will no longer be supported) 2017-02-14 09:16:54 +00:00
29fa1edcc7 Added appveyor.yml for CI with VS {2013, 2015} for {Win32, x64} 2017-02-14 09:37:37 +01:00
1cb8bafb1f Added missing #include in test file 2017-02-13 17:43:43 +00:00
d08cee288f v1.7.2 build 2017-02-13 16:15:42 +00:00
873ef276b6 XML Reporter closes tag and flushes stream at end of TestCase and Section tags.
This fixes an issue where XML reports on stdout are broken by printf statements
2017-02-13 15:56:25 +00:00
bc68b9f454 More include simplifications 2017-02-13 14:12:22 +01:00
67d513aa73 Removed single char contains()
- had incorrect prototype anyway
2017-02-13 08:20:45 +00:00
9a3486a705 Replaced use of dynamic_cast with static_cast.
It wasn't necessary anyway.
This addresses #821
2017-02-12 22:00:17 +00:00
d890791800 Fixed editing mishap in documentation. 2017-02-12 15:48:32 +01:00
26f6012bb9 Expanded the practical example in slow-compiles documentation 2017-02-12 14:47:25 +01:00
50dee9ae57 Fixed typo in CLI error reporting 2017-02-12 13:50:15 +01:00
b2a6fe971b Couple more includes cleaned out 2017-02-12 12:48:25 +01:00
0837132ce3 Make the benchmarking script Python 2 compatible
Ended up using `time.time()`, even if it supposedly has worse accuracy,
because Python running under WSL supports `time.clock()` very badly.
2017-02-12 12:25:43 +01:00
9012f95964 Moved some std includes out from catch_common.h 2017-02-12 12:17:07 +01:00
324260f253 Removed reference to DEBUG in command line docs 2017-02-11 23:39:38 +00:00
d0620c3495 Added std:: qualification to some functions from C stdlib
This should solve #543, once Clara changes are in as well.
2017-02-11 23:20:09 +01:00
fd7dde10d3 Added example of how to separately compile Catch's main
Closes #632
2017-02-11 19:11:57 +01:00
9a3788d98c Added links to open source users page from general pages 2017-02-10 22:50:40 +00:00
005787f1c5 Marked IConfig implementations in Config CATCH_OVERRIDE
(silences warnings)
2017-02-10 22:39:27 +00:00
d2e814ff23 Tagged a C++11 specific test with [c++11] to exclude from approval tests (for now) 2017-02-10 19:13:45 +00:00
f75a511b5c Fix MSVC /analyze warning about inconsistent annotations 2017-02-10 17:12:41 +01:00
ab44fb6811 The file/ line in sections is now of the section. not the test case 2017-02-10 11:56:46 +00:00
d6b8ac5a4e Added compilation tests to approvals 2017-02-10 11:53:29 +00:00
c72ba93f92 Added file for listing commercial users 2017-02-09 17:54:13 +00:00
73159ace3d REQUIRE_THROWS_AS now catches exception by const&
Prevents some warnings caused by catching complex types by value.

Closes #542
2017-02-09 12:57:01 +01:00
9952dda524 REQUIRE_THROWS_AS is now reported with expected type as well
Also updated tests to reflect this change.
2017-02-09 12:51:43 +01:00
e543cc0646 Removed an obsolete file that somehow got into the previous master. 2017-02-09 11:12:25 +01:00
c1a5391034 Added some more open source projects 2017-02-08 21:47:07 +00:00
a38ccec33a Added 3rd party bug to documentation 2017-02-08 20:53:39 +01:00
1ff56301a1 Corrected formatting 2017-02-08 18:35:30 +00:00
aee3675968 Added ChakraCore, Couchbase-lite and MAME rot OS projects 2017-02-08 18:34:19 +00:00
0579f07092 Added RxCpp to OS page 2017-02-08 18:02:11 +00:00
e9ad954435 Seeded new doc page for tracking open source projects that use Catch 2017-02-08 17:15:37 +00:00
1e87cae8af Documented the _THROWS_WITH macros, as well as slightly expanding the matchers docs. 2017-02-08 16:18:53 +00:00
26df0781a5 Added a script for running synthetic compile time benchmark 2017-02-08 14:15:01 +01:00
4d0cd602e3 Rebased approvals with tags and description attributes in XML report 2017-02-07 23:14:49 +00:00
ab199d9cf9 XmlReporter: Trim test case name; added description and tags attributes to the test case element in the xml report. 2017-02-07 23:12:58 +00:00
97d8003a71 XmlWriter can specify a stylesheet
Provide an extension point on XmlReporter to be able to supply a stylesheet url in a derived implementation
2017-02-07 23:09:43 +00:00
1f271c9944 XmlWriter reverts to XML 1.0.
Character encodings that are not valid in XML 1.0 are instead written using C-style escapes
2017-02-07 22:48:06 +00:00
7db4d8d90c Added tests (single char pretty printing + op overload)
Tests for issue #809 -- Potentional operator overload ambiguity -- and
PR #646 -- Pretty print characters.
2017-02-07 13:32:48 +01:00
a5ce57b346 Improved .travis.yml
* Removed ccache (it was slowing down the compilation for some reason)
* Enabled some C++11 builds (gcc 4.8, gcc 6, clang 3.8 for now)
* Added gcc 4.4, 4.7 and clang 3.4
2017-02-07 11:56:34 +01:00
7b8a27eadb v1.7.1 build 2017-02-07 10:06:52 +01:00
2b74613c54 Revert "First cut of Evaluate refactoring to remove int specialisations, among other things"
This reverts commit 39753558eb.
2017-02-06 22:37:23 +00:00
23600609c0 Deregister SEH handler before reporting SE. 2017-02-06 20:40:46 +01:00
4feb2dbb50 Removed const qualification to disambiguate between operator overloads 2017-02-06 20:39:32 +01:00
84af6bc955 XmllWriter flushes the stream after every endElement now 2017-02-06 16:25:36 +00:00
197bf075c4 Rebased again - against the right executable this time :-s 2017-02-06 16:25:09 +00:00
1f5ec9884c Rebased approvals following previous reversal (d’oh!) 2017-02-06 16:23:34 +00:00
88b760276d Revert "XmlWriter reverts to XML 1.0."
This reverts commit a189387f49.
2017-02-06 16:21:01 +00:00
23eb4cc580 Added stdout and stderr to XML Reporter 2017-02-06 16:14:06 +00:00
a189387f49 XmlWriter reverts to XML 1.0.
Character encodings that are not valid in XML 1.0 are instead written using C-style escapes
2017-02-06 16:00:05 +00:00
f65776890c Merge branch 'master' of https://github.com/philsquared/Catch 2017-02-06 15:17:00 +00:00
39753558eb First cut of Evaluate refactoring to remove int specialisations, among other things 2017-02-06 15:15:43 +00:00
f126d7943a Add explanation of THROW assertion limits + using lambda 2017-02-06 16:08:13 +01:00
cd489d9647 More documentation of known issues.
Closes #315
2017-02-06 15:55:01 +01:00
e991c006b7 Fixes for MinGW compatibility
Some versions of MinGW do not support enough of Win32 API to let us work
with SEH, so SEH is now MSVC only (+ configurable toggle).

Also made use of gmtime_s MSVC only (as oposed to Windows only).

Fixes #805
2017-02-06 01:43:53 +01:00
7e7c813486 New documentation section: "known limitations"
It contains known limitation such as the fact that Catch is not thread
safe, it does not support running tests in forked process or running
multiple tests in parallel

closes #399
closes #681
closes #246
closes #483
2017-02-06 00:53:39 +01:00
712323ab7c Include windows.h proxy header, instead of windows.h itself
Because the signal changes were in a different branch from the windows.h
related changes, the SEH handling code included the header directly.

Fixes #803
2017-02-03 14:09:17 +01:00
ce37f48ffa v1.7.0 build 2017-02-01 21:47:43 +01:00
090fc74cca Scripts intended to be run should now have x bit set. 2017-02-01 21:34:45 +01:00
f58ff0c540 Remove \l, add \f in character pretty printing
I have never head of \l and MSVC warns about unknown escape sequence, so
I changed it into \f that definitely exists and potentially might be
useful.
2017-02-01 21:31:14 +01:00
a600bfeb75 Fix travis build + build warnings
The cmake download was failing, so we were relying on the old cmake,
which I broke recently (in 7ae96c710b).
Now the download should work again.

Also fixed warning that the requested OSX image no longer exists and
that it is automatically substituted for xcode 7.3 image.
2017-02-01 21:01:14 +01:00
8cad76a749 typo 2017-02-01 14:39:06 +00:00
1a3f6d829b Updated command line docs with info on -c for running sections, as well as -# for filenames as tags 2017-02-01 14:37:02 +00:00
b524fa7cd8 Fixed bugs in escape char handling in test names
1. If escape char is first char, sets start of range
2. Multiple escape chars are handled (offsets chars to remove)
2017-02-01 14:13:20 +00:00
5121b5b058 Put quote marks around printed characters; also nicely print some escapes 2017-01-31 21:53:36 +01:00
1e5176bd69 Cap main exit code to 255 (#797)
Changed default main to clamp exit code to 8 bits because of POSIX limitations.

Updated documentation about declaring non-default main.
2017-01-31 20:48:14 +01:00
7dd4f2977a Added INSTALL commands (#788)
Added INSTALL commands - this is especially useful when adding dependencies (such as CATCH) by using the ExternalProject_Add command
2017-01-31 20:22:45 +01:00
50c95a0143 Bumped min cmake version to 3.0
Now we can use target_compile_option to privately add warnings to our
build, without polluting outside CXX_FLAGS.
2017-01-31 20:21:03 +01:00
0dabd951ba expr is now cast to void in THROWS family of assertions.
This prevents Clang from complaining about unused value in expressions
containing explicit casts used in the THROW assertion macro family.

Example:
`REQUIRE_THROWS_AS(static_cast<bool>(object), std::bad_cast);` would
trigger `-Wunused-value` warning. Now it does not.

Credits to Arto Bendiken, who submitted a PR almost 3 years ago, but his
branch has since died and I was unable to merge it.
2017-01-31 18:02:11 +01:00
7ae96c710b Returned basic warnings to CMake generated builds 2017-01-31 17:37:27 +01:00
70d3c937c3 Enable breaking into debugger on Mac
The integrated assembler segment was missing an underscore:
"_asm__". Also we remove the "DEBUG" macro check, so we are consistent
with the linux and windows variant.
Now breaking into gdb on failure should work via:
	gdb --args test_executable --break
2017-01-31 16:00:42 +00:00
38af8d7035 Fixed SEH deregistration on Windows
Should fix #796
2017-01-30 19:54:16 +01:00
c97ada1910 Improved assertion documentation
Mentioned that decomposing `&&` and `||` is not supported, gave examples
+ possible workarounds.

Closes #621, #787, #341 and maybe others I haven't found.
2017-01-30 19:42:27 +01:00
615aa071a8 Merge branch 'dev-performance-round2' 2017-01-30 13:02:48 +01:00
af0b03abd2 Merge branch 'templates' 2017-01-30 12:03:01 +01:00
15816c5760 Revert "use sizeof(expr) for unevaluated syntax check"
Using sizeof(expr) can trigger a compile-time error,
"lambda expressions are not allowed in an unevaluated context", when passing
expression containing lambda, like a std algorithm. This error is considered
a standard defect, as it is meant to prevent lambdas in decltype
or templates, but not in sizeof.

This reverts commit 227598af47.
2017-01-30 11:56:29 +01:00
f11a45aa67 Added benchmark for the char literals change 2017-01-29 23:23:33 +01:00
bcaa2f9646 Use char literal instead of string literal with 1 char
In reality, this is a relatively small performance improvement,
especially with the previous improvements removing lots of superfluous
string handling, but still was measurable.
2017-01-29 23:07:15 +01:00
efab3ca8b2 Added benchmark result for the SourceLineInfo change 2017-01-29 22:10:37 +01:00
60f8ebec49 Use const char* for filename in SourceLineInfo
This is sane, because those `const char*`s are given to us by compiler,
from the text area and thus we do not have to manage their lifetimes. We
also never want to change them.

Also moved copy constructor to compiler-generated methods, not sure why
it wasn't -- even before it was the same as a compiler would generate.
2017-01-29 22:03:27 +01:00
e1dbb7cf64 First draft of issue and PR templates.
Apparently we can also get contributing.md to be linked from
issues and PRs, but it would also have to be in .github folder
or in root of the project.
2017-01-28 11:42:11 +01:00
02a69b449f Compilation warnings fix (#791)
* Compilation warnings fix

* Removed unused argument from reportFatal function
2017-01-27 09:32:58 +01:00
c390c4cb9f Fixed inconsistent and trailing whitespace
This means that all tabs used in indentation are now 4 spaces and that
there should be no more trailing whitespace.

Ill also look into creating a pre-commit hook that will prevent this
from happening in the future.

Fixes #105
2017-01-26 23:13:12 +01:00
60a9ac7e65 Enabled previous commit under MSVC, introduced new feature toggle 2017-01-26 18:47:29 +01:00
c06afe438e Add support for comparison of Approx with strong typedefs
closes #652
2017-01-26 18:44:03 +01:00
73872207db Direct download link now links to latest release version
Also edited releaseCommon script to update the link in readme as well.
2017-01-26 13:12:19 +01:00
51860f1568 Change include -> single_include in CMake example 2017-01-26 10:24:48 +01:00
dab1d9d222 Added CheckFileList in CMake over the benchmark sources 2017-01-25 23:02:25 +01:00
4ce11d63a6 Merge branch 'dev-performance' 2017-01-25 22:56:36 +01:00
99c2ea594c Renamed measurement script for benchmarking 2017-01-25 22:55:11 +01:00
51107d7cbd Added copyright headers to benchmark files. 2017-01-25 22:42:41 +01:00
83f4b39680 Added benchmark for previous commit, added iterations to failure bench. 2017-01-25 22:39:43 +01:00
b1171bd1f2 Merge branch 'dev-signals' 2017-01-25 22:09:52 +01:00
6c23a6582b Mark CHECKed-throw test as [failing] 2017-01-24 09:53:04 +00:00
7bcb42496d Changed exception tests to allow for now throw-from-CHECK behaviour 2017-01-23 17:56:41 +00:00
184865358c CHECK no longer stops running SECTION on exception.
This seems to be much closer to desired behaviour than the current one, where
CHECK(false) lets the execution continue, but CHECK(<throws>) does not.
2017-01-23 17:52:17 +00:00
225e90d8ba Don’t include tests that rely on varying two-phase-lookup behaviour in approval tests 2017-01-23 17:47:58 +00:00
31c23b9489 Added [!nonportable] tag 2017-01-23 17:44:55 +00:00
f347611403 Restated text format loop to avoid out-of-bounds condition 2017-01-23 16:58:49 +00:00
1efd8d3067 Added missing <iterator> #include 2017-01-23 15:19:42 +00:00
876af874f3 Added surrogate cpp for catch_test_case_tracker 2017-01-23 15:18:23 +00:00
e7bcbb35c0 First cut of -c/—section option for running specific sections 2017-01-23 12:36:03 +00:00
4a04682e49 Text formatting rework
Rewrote main wrapping loop. Now uses iterators instead of indices and intermediate strings.
Differentiates between chars to wrap before, after or instead of.
Doesn’t preserve trailing newlines.
Wraps or more characters.
Dropped support for using tab character as an indent setting control char.
Hopefully avoids all the undefined behaviour and other bugs of the previous implementation.
2017-01-23 12:28:40 +00:00
9a56609569 v1.6.1 build 2017-01-20 12:49:59 +01:00
81159838a5 Python scripts can now be run directly from bash 2017-01-20 12:28:40 +01:00
78a2866dc7 Approval tests are now mostly Windows compatible
There are some differences in output between Catch on Windows and
Catch on Linux, that indicate a minor bug, but those have to be fixed separately.
2017-01-19 23:56:31 +01:00
9acc6b9673 Approval tests now use Python std lib instead of call to diff
This needed to change to let it run on Windows as well as on the Unices
2017-01-19 22:52:47 +01:00
c4b5057094 Approval tests now uses path relative to cwd, not the catch folder.
This means that bash's autocompletion is actually helpful.
2017-01-19 22:08:51 +01:00
d38b9266e7 simplify output filtering in approvalTests.py 2017-01-19 22:04:29 +01:00
227598af47 use sizeof(expr) for unevaluated syntax check 2017-01-19 21:25:27 +01:00
cfaf906417 Changed documentation to use standard main function signature 2017-01-19 17:05:01 +01:00
ee0ca512ea Force short-circuited evaluation for types that have overloaded &&.
This fixes #574.
2017-01-17 23:31:03 +01:00
b71a06cf98 JUnit reporter outputs timestamps now
Also extended approval tests script to support the change
2017-01-16 20:21:43 +01:00
531d26739f Added the new proxy header to CMakeLists.txt 2017-01-16 19:56:57 +01:00
2e87f8e328 Merge branch 'windows-header-defines' of https://github.com/horenmar/Catch 2017-01-16 17:00:43 +01:00
afe46ff270 Extracted NOMINMAX and WIN32_LEAN_AND_MEAN guards into a proxy header 2017-01-16 16:52:44 +01:00
c65aeaf25f Clean up generator state 2017-01-16 10:34:16 +00:00
750b52b814 suppress use of __COUNTER__ when being parsed by CLion (or AppCode). 2017-01-16 10:34:16 +00:00
e12fc4aca0 Fix missing CATCH_ for CHECK_THAT in prefixed macro version 2017-01-15 22:11:43 +01:00
99cdc62fef Enabled CMake dev warnings in travis. 2017-01-15 22:08:12 +01:00
e6ef60a2c4 CMake will now warn if a file is in folder, but not in variable 2017-01-15 22:07:36 +01:00
e1c4a4bd9b Use inline assembly with gcc under Linux for CATCH_TRAP
This is more convenient than using the generic portable raise(SIGTRAP) as it
avoids having another stack frame in the debugger when the break happens.
2017-01-15 19:29:34 +01:00
25d017763b Refactor CATCH_BREAK_INTO_DEBUGGER() to avoid repetition
Don't duplicate Catch::isDebuggerActive() check many times, do it just once
in CATCH_BREAK_INTO_DEBUGGER() definition and use a separate CATCH_TRAP()
macro for the really platform-dependent part.
2017-01-15 19:29:34 +01:00
b634e592da Add support for breaking into debugger for Linux
Use Linux-specific /proc/$PID/status file to check whether we're being
debugged and a generic raise(SIGTRAP) to actually break into the debugger.
2017-01-15 19:29:34 +01:00
3b98a0166f Various small string usage performance improvements.
* Empty strings are now direct constructed as `std::string()`, not as empty string literals.
* `startsWith` and `endsWith` no longer construct new a string. This should be an improvement
for libstdc++ when using older standards, as it doesn't use SSO but COW and thus even short
strings are expensive to first create.
* Various places now use char literal instead of string literals containing single char.
** `startsWith` and `endsWith` now also have overload that takes single char.

Generally the performance improvements under VS2015 are small, as going from short string
to char is mostly meaningless because of SSO (Catch doesn't push string handling that hard)
and previous commit removed most string handling if tests pass, which is the expect case.
2017-01-15 10:05:01 +01:00
877fd523bc Added benchmark with Mickey Rose's improvements. 2017-01-14 22:51:44 +01:00
a1e9b841ff lazily stringify expressions 2017-01-14 21:56:16 +01:00
3b7511e564 First commit of benchmarks for Catch runtime perf.
So far its very much a WIP with some problems that are known already and
not very representative tests.
2017-01-14 21:55:37 +01:00
ffc4a9dc14 If we receive a signal, we re-register ALL previous signal handlers.
This fixes the case when we pass signal to previously registered
handler, and it needs to transform the signal into different one.

Still problematic: What if the signal handler we replaced does not
terminate the application? We can end up in a weird state and loop
forever.

Possible solution: Deregister our signal handlers, CALL the previous
signal handler explicitly and if control returns, abort. This would
however complicate our code quite a bit, as we would have to parse the
sigaction we delegate to, decide whether to use signal handler or signal
action, etc...
2017-01-14 15:21:44 +01:00
7c8b93eac3 Removed superfluous comments (bad merge after cherry pick). 2017-01-14 15:08:00 +01:00
e3659cdddd Added single char version of logo 2017-01-13 18:49:49 +00:00
40dbdf6cb2 Reset signals immediately after use and re-raise orginal signal instead of just exiting 2017-01-12 17:31:56 +01:00
70f43d719b Added signal handling under Windows.
Only some "signals" are handled under Windows, because Windows does not
use signals per-se and the mechanics are different. For now, we handle
sigsegv, stack overflow, div-by-zero and sigill. We can also
meaningfully
add various floating point errors, but not sigterm and family, because
sigterm is not a structured exception under Windows.

There is also no catch-all, because that would also catch various
debugger-related exceptions, like EXCEPTION_BREAKPOINT.
2017-01-12 16:40:14 +01:00
a281173099 Fix for sigsegv stack overflow behavior
Also stops Catch from assuming its the only signal user in the binary,
and makes it restore the signal handlers it has replaced. Same goes for
the signal stack.

The signal stack itself probably shouldn't be always reallocated for
fragmentation reasons, but that can be fixed later on.
2017-01-12 16:23:55 +01:00
b3907a78e1 Added NOMINMAX and WIN32_LEAN_AND_MEAN defines before including windows.h
This stops the `windows.h` header from defining `min` and `max` macros
and including lot of Windows APIs that are not needed by Catch.
2017-01-12 16:00:02 +01:00
d5360e8e29 Sorted file lists in CMakeLists.txt for easier maintainence 2017-01-12 11:54:53 +00:00
9062ebe390 Removed make file (now generated from CMake) 2017-01-12 11:22:30 +00:00
e6aa1f4e4e Added note on escaping names on command line to docs 2017-01-11 17:14:28 +00:00
1ff0acfe22 Tweaked release notes page with better formatting 2017-01-11 16:50:35 +00:00
713ec400e8 Fixed type in “Release Notes” link 2017-01-11 16:46:09 +00:00
3b2f206191 v1.6.0 build - including release notes 2017-01-11 16:44:36 +00:00
4e4d733f90 Added \ as escape character in test names on the command line - so you can run tests by name when they contain , or [ 2017-01-11 16:27:16 +00:00
b68e8f9a24 Added missing #include so CATCH_CONFIG_COUNTER properly takes into account the current compiler.
May address #677 and #435 and others.
2017-01-11 16:27:16 +00:00
a7cda91d4d Merge pull request #775 from philsquared/standardizing-feature-toggles
Standardize C++11 feature toggles to follow documentation
2017-01-11 16:27:05 +00:00
a1bed572be Standardize C++11 feature toggles to follow documentation
Closes #774
2017-01-10 22:54:57 +01:00
737f4ea77c Added missing C++11 feature toggle to docs 2017-01-10 22:43:58 +01:00
b0de6c938a Updated docs for contributing 2017-01-10 07:36:06 +00:00
6991549457 Fixed compile error under VS2015 /c++:latest, caused by using random_shuffle
Now if we detect C++11 compiler, or MSVC in version corresponding to VS2015,
we switch from using `std::random_shuffle` to `std::shuffle`.

`std::random_shuffle` was officially deprecated in C++14, and removed in C++17.

Also removed guarded inclusion of `<random>` header, as there was nothing
in the header that used it.
2017-01-09 23:29:13 +01:00
b50572bbfd Renamed missing project explainer filename 2017-01-09 21:59:53 +00:00
5b00fd40ba Merge pull request #767 from hmich/xml-encoder-extended-ascii
Do not encode extended ASCII characters in XML reporter
2017-01-09 18:37:52 +00:00
7bb3e859aa Removed all manually maintained project files in favour of instructions on how to use CMake to generate them 2017-01-09 17:38:42 +00:00
0bcae64d3d Set project name in CMakeLists.txt to CatchSelfTest 2017-01-09 17:38:42 +00:00
8abe17a393 CMake project groups test files separately from surrogate impl files for nicer rendering as XCode/ VS projects 2017-01-09 17:38:42 +00:00
10c44847f4 Make backticks symmetric in markdown 2017-01-09 18:03:40 +01:00
0cde0e90a6 Added approvals for “Greater-than inequalities with different epsilons” test 2017-01-09 14:40:09 +00:00
0f0dcd31eb Excluded two more C++11 tests from Approval tests 2017-01-09 14:37:28 +00:00
62cbde369e Exclude test name from approval tests 2017-01-09 14:37:28 +00:00
1ae84897d4 Marked tests that use C++11 features with [c++11] tag and exclude them from approval tests 2017-01-09 14:37:28 +00:00
976a655496 Approval tests can use Catch path fixed in env. var, and convert nullptr and __null to 0 for comparison 2017-01-09 14:37:28 +00:00
37e1e24309 add support for inequalities 2017-01-08 22:28:53 +01:00
5a4dde4b5d Changed build status to be always taken from master
Before it was taken from whatever last build happened, which led it show
a build error because I took PR against wrong branch.

This should be fixed now.
2017-01-08 21:49:14 +01:00
8d326424f3 Minor typo fix 2017-01-07 22:05:18 +01:00
ccc34b63b6 URL fixed 2017-01-07 14:51:13 +01:00
7255be28cc remove concatenation of m_exprComponents.op in if-branch where op has tested empty in previous line 2017-01-07 13:37:08 +01:00
7d2668fa15 add missing argument to CATCH_CHECK_THROWS (closes #602) 2017-01-07 12:16:06 +01:00
2a4dba177f Merge branch 'philipp-classen-master'
Removed changes to the single-include header.
2017-01-07 10:31:36 +01:00
8d1e240700 Fixed shell color code of "Blue" 2017-01-07 10:30:43 +01:00
e273a3dc88 Fix grammar error in tutorial.md
It's = it is
In the sentence "In fact it is usually a good idea to put the block with the ```#define``` [in it's own source file](slow-compiles.md).", the correct usage is "its", not "it's".
2017-01-07 09:56:21 +01:00
7bff9cb451 own-main.md: fix typo 2017-01-07 09:55:27 +01:00
fd1da4a1d1 Fixing a couple of typos
I tried to make sure I wasn't changing any British spellings so I apologize
if I've mixed any up.
2017-01-07 09:45:38 +01:00
e1fbbe1590 Added headers to CMake project (for CLion) 2017-01-06 16:59:18 +00:00
c8fefc4670 Fixed Travis and CMake after moving CMakeLists.txt 2017-01-06 16:19:20 +00:00
64193078bc Moved CMake into root folder (where it’s much happier - especially for CLion) 2017-01-06 16:00:00 +00:00
8d16d95a99 Do not encode extended ASCII characters in XML reporter 2016-12-26 11:39:19 +00:00
2be372710e Build 1.5.9 2016-11-29 12:15:50 +00:00
0c093bee38 Removed now redundant xml stream initialisation 2016-11-29 12:13:55 +00:00
dedc7c56ce Merge branch 'horenmar-xml-reporter-fix' 2016-11-29 12:11:05 +00:00
a9561ecb31 Merge branch 'xml-reporter-fix' of https://github.com/horenmar/Catch into horenmar-xml-reporter-fix 2016-11-29 12:10:46 +00:00
e4df006568 Merge branch 'horenmar-missing-include-fix' 2016-11-29 12:05:35 +00:00
fb99cc556d Merge branch 'missing-include-fix' of https://github.com/horenmar/Catch into horenmar-missing-include-fix 2016-11-29 12:05:11 +00:00
862d13138c Explicitly convert int to char during transform on string (equivalent of PR #756) 2016-11-29 12:04:09 +00:00
79acc0504b Sort test ordering during Approval testing 2016-11-29 11:32:16 +00:00
f9afa2a68d Ignore CMake and CLion generated files 2016-11-29 11:27:22 +00:00
0c8c6b347a Fixes build error caused by missing include. 2016-11-28 15:47:20 +01:00
40b6ad73df Fix XmlReporter always writing first line to stdout 2016-11-26 12:11:23 +01:00
30cebd6177 Added some missing source files (including all SurrogateCpps) to CMake project.
Fixed up relative include paths to make this work.
2016-11-09 22:55:32 +00:00
e27c4ee042 Build 1.5.8 2016-10-26 12:08:26 +01:00
072114293b Merge branch 'BillyONeal-master' 2016-10-26 12:06:35 +01:00
f90ee9fb37 Merge branch 'master' of https://github.com/BillyONeal/Catch into BillyONeal-master 2016-10-26 12:04:38 +01:00
c17ba0870a Fix transform without a lambda
Catch apparently supports targeting C++03, so use an inline function
instead.
2016-10-14 14:28:15 -07:00
79f01100e3 Fix transform narrowing warnings
Catch passes ::tolower into std::transform with string iterators.
::tolower has the signature int(int), which triggers a stealth narrowing
warning inside std::transform, because transform calls
*_Dest = _Fn(*_First), which implicitly narrows an int to a char.

For this particular application the narrowing is fine, so explicitly
narrow in a lambda.
2016-10-14 14:16:21 -07:00
ccf7f2842a Fix random_shuffle narrowing warnings
Catch passes an RNG which accepts int to random_shuffle. Inside
random_shuffle, the STL tries to call that RNG with the difference_type
of the user provided iterators. For std::vector, this is ptrdiff_t,
which on amd64 builds is wider than int. This triggers a narrowing
warning because the 64 bit difference is being truncated to 32 bits.

Note that this RNG implementation still does not produce a correctly
uniformly shuffled result -- it's currently asserting that std::rand
can produce 1000000 which is false -- but I don't know enough about
how much repeatable shuffles are necessary here, so I'm leaving that
alone for now.
2016-10-14 14:06:45 -07:00
e0302db4a6 Rename element for Fatal Error Condition so it doesn't have spaces
Fixes: #685
2016-10-14 18:45:08 +01:00
88732e85b2 Merge pull request #716 from jbcoe/master
Quick fix for failing travis builds on OS X
2016-10-04 15:57:10 +01:00
1c9a6cab88 Removed XCode6 builds (which were erroring anyway) and added XCode8 builds 2016-09-27 11:20:33 +01:00
fd7d35464b quick fix for failing travis builds on os x 2016-09-24 19:38:43 +01:00
3523c39f44 Changed 'auto' into 'bool' for C++98 compatibility 2015-11-12 15:31:42 +01:00
2585d280d1 Added an optional absolute margin to the approximation checks 2015-11-12 15:11:36 +01:00
385 changed files with 51700 additions and 40281 deletions

13
.gitattributes vendored
View File

@ -8,4 +8,15 @@
*.hpp text
# Windows specific files should retain windows line-endings
*.sln text eol=crlf
*.sln text eol=crlf
# Keep executable scripts with LFs so they can be run after being
# checked out on Windows
*.py text eol=lf
# Keep the single include header with LFs to make sure it is uploaded,
# hashed etc with LF
single_include/*.hpp eol=lf
# Also keep the LICENCE file with LFs for the same reason
LICENCE.txt eol=lf

29
.github/issue_template.md vendored Normal file
View File

@ -0,0 +1,29 @@
## Description
<!--
If your issue is a bugreport, this means describing what you did,
what did you want to happen and what actually did happen.
If your issue is a feature request, describe the feature and why do you
want it.
-->
### Steps to reproduce
<!--
This is only relevant for bug reports, but if you do have one,
please provide a minimal set of steps to reproduce the problem.
Usually this means providing a small and self-contained code using Catch
and specifying compiler flags/tools used if relevant.
-->
### Extra information
<!--
Fill in any extra information that might be important for your issue.
If your issue is a bugreport, definitely fill out at least the following.
-->
* Catch version: **v42.42.42**
* Operating System: **Joe's discount operating system**
* Compiler+version: **Hidden Dragon v1.2.3**

28
.github/pull_request_template.md vendored Normal file
View File

@ -0,0 +1,28 @@
<!--
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.
-->
## Description
<!--
Describe the what and the why of your pull request. Remember that these two
are usually a bit different. As an example, if you have made various changes
to decrease the number of new strings allocated, thats what. The why probably
was that you have a large set of tests and found that this speeds them up.
-->
## GitHub Issues
<!--
If this PR was motivated by some existing issues, reference them here.
If it is a simple bug-fix, please also add a line like 'Closes #123'
to your commit message, so that it is automatically closed.
If it is not, don't, as it might take several iterations for a feature
to be done properly. If in doubt, leave it open and reference it in the
PR itself, so that maintainers can decide.
-->

9
.gitignore vendored
View File

@ -14,9 +14,16 @@ Breakpoints.xcbkptlist
projects/VS2010/TestCatch/_UpgradeReport_Files/
projects/VS2010/TestCatch/TestCatch/TestCatch.vcxproj.filters
projects/VisualStudio/TestCatch/UpgradeLog.XML
projects/CMake/.idea
projects/CMake/cmake-build-debug
UpgradeLog.XML
Resources/DWARF
projects/XCode/iOSTest/Build
projects/Generated
*.pyc
DerivedData
*.xccheckout
Build
.idea
.vs
cmake-build-*
benchmark-dir

View File

@ -1,18 +1,12 @@
language: cpp
sudo: false
cache:
ccache: true
directories:
- $HOME/.ccache
env:
global:
- USE_CCACHE=1
- CCACHE_COMPRESS=1
- CCACHE_MAXSIZE=200M
- CCACHE_CPP2=1
common_sources: &all_sources
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty
- llvm-toolchain-trusty-3.9
- llvm-toolchain-trusty-4.0
- llvm-toolchain-trusty-5.0
matrix:
include:
@ -20,124 +14,174 @@ matrix:
# 1/ Linux Clang Builds
- os: linux
compiler: clang
addons: &clang35
addons:
apt:
sources: ['llvm-toolchain-precise-3.5', 'ubuntu-toolchain-r-test']
packages: ['clang-3.5']
env: COMPILER='ccache clang++-3.5' BUILD_TYPE='Release'
sources: *all_sources
packages: ['valgrind', 'lcov', 'clang-3.5']
env: COMPILER='clang++-3.5' VALGRIND=1
- os: linux
compiler: clang
addons: *clang35
env: COMPILER='ccache clang++-3.5' BUILD_TYPE='Debug'
- os: linux
compiler: clang
addons: &clang36
addons:
apt:
sources: ['llvm-toolchain-precise-3.6', 'ubuntu-toolchain-r-test']
packages: ['clang-3.6']
env: COMPILER='ccache clang++-3.6' BUILD_TYPE='Release'
sources: *all_sources
packages: ['valgrind', 'lcov', 'clang-3.6']
env: COMPILER='clang++-3.6' VALGRIND=1
# Travis's containers do not seem to have Clang 3.7 in apt, no matter what sources I add.
# - os: linux
# compiler: clang
# addons:
# apt:
# sources: *all_sources
# packages: ['valgrind', 'clang-3.7']
# env: COMPILER='clang++-3.7' VALGRIND=1
- os: linux
compiler: clang
addons: *clang36
env: COMPILER='ccache clang++-3.6' BUILD_TYPE='Debug'
- os: linux
compiler: clang
addons: &clang37
addons:
apt:
sources: ['llvm-toolchain-precise-3.7', 'ubuntu-toolchain-r-test']
packages: ['clang-3.7']
env: COMPILER='ccache clang++-3.7' BUILD_TYPE='Release'
sources: *all_sources
packages: ['valgrind', 'lcov', 'clang-3.8']
env: COMPILER='clang++-3.8' VALGRIND=1
- os: linux
compiler: clang
addons: *clang37
env: COMPILER='ccache clang++-3.7' BUILD_TYPE='Debug'
addons:
apt:
sources: *all_sources
packages: ['clang-3.9', 'valgrind', 'lcov']
env: COMPILER='clang++-3.9' VALGRIND=1
- os: linux
compiler: clang
addons: &clang38
apt:
sources: ['llvm-toolchain-precise-3.8', 'ubuntu-toolchain-r-test']
packages: ['clang-3.8']
env: COMPILER='ccache clang++-3.8' BUILD_TYPE='Release'
addons:
apt:
sources: *all_sources
packages: ['clang-4.0', 'valgrind', 'lcov']
env: COMPILER='clang++-4.0' VALGRIND=1
- os: linux
compiler: clang
addons: *clang38
env: COMPILER='ccache clang++-3.8' BUILD_TYPE='Debug'
addons:
apt:
sources: *all_sources
packages: ['clang-5.0', 'valgrind', 'lcov']
env: COMPILER='clang++-5.0' VALGRIND=1
# 2/ Linux GCC Builds
- os: linux
compiler: gcc
addons: &gcc48
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.8']
env: COMPILER='ccache g++-4.8' BUILD_TYPE='Release'
packages: ['valgrind', 'lcov', 'g++-4.8']
env: COMPILER='g++-4.8' VALGRIND=1
- os: linux
compiler: gcc
addons: *gcc48
env: COMPILER='ccache g++-4.8' BUILD_TYPE='Debug'
- os: linux
compiler: gcc
addons: &gcc49
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.9']
env: COMPILER='ccache g++-4.9' BUILD_TYPE='Release'
sources: *all_sources
packages: ['valgrind', 'lcov', 'g++-4.9']
env: COMPILER='g++-4.9' VALGRIND=1
- os: linux
compiler: gcc
addons: *gcc49
env: COMPILER='ccache g++-4.9' BUILD_TYPE='Debug'
- os: linux
compiler: gcc
addons: &gcc5
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-5']
env: COMPILER='ccache g++-5' BUILD_TYPE='Release'
sources: *all_sources
packages: ['valgrind', 'lcov', 'g++-5']
env: COMPILER='g++-5' VALGRIND=1
- os: linux
compiler: gcc
addons: *gcc5
env: COMPILER='ccache g++-5' BUILD_TYPE='Debug'
addons: &gcc6
apt:
sources: *all_sources
packages: ['valgrind', 'lcov', 'g++-6']
env: COMPILER='g++-6' VALGRIND=1
- os: linux
compiler: gcc
addons: &gcc7
apt:
sources: *all_sources
packages: ['valgrind', 'lcov', 'g++-7']
env: COMPILER='g++-7' VALGRIND=1
# 3/ OSX Clang Builds
- os: osx
osx_image: xcode6.4
# 3b/ Linux C++14 Clang builds
- os: linux
compiler: clang
env: COMPILER='ccache clang++' BUILD_TYPE='Debug'
addons:
apt:
packages: ['clang-3.8', 'valgrind', 'lcov', 'libstdc++-6-dev']
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty
env: COMPILER='clang++-3.8' CPP14=1 VALGRIND=1
- os: linux
compiler: clang
addons:
apt:
sources: *all_sources
packages: ['clang-3.9', 'valgrind', 'lcov', 'libstdc++-6-dev']
env: COMPILER='clang++-3.9' CPP14=1 VALGRIND=1
- os: linux
compiler: clang
addons:
apt:
sources: *all_sources
packages: ['clang-4.0', 'valgrind', 'lcov', 'libstdc++-6-dev']
env: COMPILER='clang++-4.0' CPP14=1 VALGRIND=1
- os: linux
compiler: clang
addons:
apt:
sources: *all_sources
packages: ['clang-5.0', 'valgrind', 'lcov', 'libstdc++-6-dev']
env: COMPILER='clang++-5.0' CPP14=1 VALGRIND=1
# 4a/ Linux C++14 GCC builds
- os: linux
compiler: gcc
addons: *gcc6
env: COMPILER='g++-6' CPP14=1 VALGRIND=1
- os: linux
compiler: gcc
addons: *gcc7
env: COMPILER='g++-7' CPP14=1 VALGRIND=1
# 5/ OSX Clang Builds
- os: osx
osx_image: xcode7.3
compiler: clang
env: COMPILER='clang++'
- os: osx
osx_image: xcode6.4
osx_image: xcode8
compiler: clang
env: COMPILER='ccache clang++' BUILD_TYPE='Release'
env: COMPILER='clang++'
- os: osx
osx_image: xcode7
osx_image: xcode9
compiler: clang
env: COMPILER='ccache clang++' BUILD_TYPE='Debug'
env: COMPILER='clang++'
- os: osx
osx_image: xcode7
osx_image: xcode9.1
compiler: clang
env: COMPILER='ccache clang++' BUILD_TYPE='Release'
env: COMPILER='clang++'
- os: osx
osx_image: xcode9.1
compiler: clang
env: COMPILER='clang++' USE_CPP14=1
install:
@ -146,18 +190,37 @@ install:
- |
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
CMAKE_URL="http://www.cmake.org/files/v3.3/cmake-3.3.2-Linux-x86_64.tar.gz"
mkdir cmake && travis_retry wget --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake
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
brew install cmake ccache
which cmake || brew install cmake;
fi
before_script:
- export CXX=${COMPILER}
- cd ${TRAVIS_BUILD_DIR}
- cmake -Hprojects/CMake -BBuild -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
- cd Build
# Regenerate single header file, so it is tested in the examples...
- python scripts/generateSingleHeader.py
- |
# Use Debug builds for running Valgrind and building examples
cmake -H. -BBuild-Debug -DCMAKE_BUILD_TYPE=Debug -Wdev -DUSE_CPP14=${CPP14} -DCATCH_USE_VALGRIND=${VALGRIND} -DCATCH_BUILD_EXAMPLES=ON -DCATCH_ENABLE_COVERAGE=ON
# Don't bother with release build for coverage build
cmake -H. -BBuild-Release -DCMAKE_BUILD_TYPE=Release -Wdev -DUSE_CPP14=${CPP14}
script:
- make -j 2
- ctest -V -j 2
- |
cd Build-Debug
make -j 2
CTEST_OUTPUT_ON_FAILURE=1 ctest -j 2
# Coverage collection does not work for OS X atm
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
make gcov
make lcov
bash <(curl -s https://codecov.io/bash) -X gcov || echo "Codecov did not collect coverage reports"
fi
# Go to release build
cd ../Build-Release
make -j 2
CTEST_OUTPUT_ON_FAILURE=1 ctest -j 2

157
CMake/FindGcov.cmake Normal file
View File

@ -0,0 +1,157 @@
# This file is part of CMake-codecov.
#
# Copyright (c)
# 2015-2017 RWTH Aachen University, Federal Republic of Germany
#
# See the LICENSE file in the package base directory for details
#
# Written by Alexander Haase, alexander.haase@rwth-aachen.de
#
# include required Modules
include(FindPackageHandleStandardArgs)
# Search for gcov binary.
set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET})
set(CMAKE_REQUIRED_QUIET ${codecov_FIND_QUIETLY})
get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
foreach (LANG ${ENABLED_LANGUAGES})
# Gcov evaluation is dependend on the used compiler. Check gcov support for
# each compiler that is used. If gcov binary was already found for this
# compiler, do not try to find it again.
if (NOT GCOV_${CMAKE_${LANG}_COMPILER_ID}_BIN)
get_filename_component(COMPILER_PATH "${CMAKE_${LANG}_COMPILER}" PATH)
if ("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "GNU")
# Some distributions like OSX (homebrew) ship gcov with the compiler
# version appended as gcov-x. To find this binary we'll build the
# suggested binary name with the compiler version.
string(REGEX MATCH "^[0-9]+" GCC_VERSION
"${CMAKE_${LANG}_COMPILER_VERSION}")
find_program(GCOV_BIN NAMES gcov-${GCC_VERSION} gcov
HINTS ${COMPILER_PATH})
elseif ("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "Clang")
# Some distributions like Debian ship llvm-cov with the compiler
# version appended as llvm-cov-x.y. To find this binary we'll build
# the suggested binary name with the compiler version.
string(REGEX MATCH "^[0-9]+.[0-9]+" LLVM_VERSION
"${CMAKE_${LANG}_COMPILER_VERSION}")
# llvm-cov prior version 3.5 seems to be not working with coverage
# evaluation tools, but these versions are compatible with the gcc
# gcov tool.
if(LLVM_VERSION VERSION_GREATER 3.4)
find_program(LLVM_COV_BIN NAMES "llvm-cov-${LLVM_VERSION}"
"llvm-cov" HINTS ${COMPILER_PATH})
mark_as_advanced(LLVM_COV_BIN)
if (LLVM_COV_BIN)
find_program(LLVM_COV_WRAPPER "llvm-cov-wrapper" PATHS
${CMAKE_MODULE_PATH})
if (LLVM_COV_WRAPPER)
set(GCOV_BIN "${LLVM_COV_WRAPPER}" CACHE FILEPATH "")
# set additional parameters
set(GCOV_${CMAKE_${LANG}_COMPILER_ID}_ENV
"LLVM_COV_BIN=${LLVM_COV_BIN}" CACHE STRING
"Environment variables for llvm-cov-wrapper.")
mark_as_advanced(GCOV_${CMAKE_${LANG}_COMPILER_ID}_ENV)
endif ()
endif ()
endif ()
if (NOT GCOV_BIN)
# Fall back to gcov binary if llvm-cov was not found or is
# incompatible. This is the default on OSX, but may crash on
# recent Linux versions.
find_program(GCOV_BIN gcov HINTS ${COMPILER_PATH})
endif ()
endif ()
if (GCOV_BIN)
set(GCOV_${CMAKE_${LANG}_COMPILER_ID}_BIN "${GCOV_BIN}" CACHE STRING
"${LANG} gcov binary.")
if (NOT CMAKE_REQUIRED_QUIET)
message("-- Found gcov evaluation for "
"${CMAKE_${LANG}_COMPILER_ID}: ${GCOV_BIN}")
endif()
unset(GCOV_BIN CACHE)
endif ()
endif ()
endforeach ()
# Add a new global target for all gcov targets. This target could be used to
# generate the gcov files for the whole project instead of calling <TARGET>-gcov
# for each target.
if (NOT TARGET gcov)
add_custom_target(gcov)
endif (NOT TARGET gcov)
# This function will add gcov evaluation for target <TNAME>. Only sources of
# this target will be evaluated and no dependencies will be added. It will call
# Gcov on any source file of <TNAME> once and store the gcov file in the same
# directory.
function (add_gcov_target TNAME)
set(TDIR ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TNAME}.dir)
# We don't have to check, if the target has support for coverage, thus this
# will be checked by add_coverage_target in Findcoverage.cmake. Instead we
# have to determine which gcov binary to use.
get_target_property(TSOURCES ${TNAME} SOURCES)
set(SOURCES "")
set(TCOMPILER "")
foreach (FILE ${TSOURCES})
codecov_path_of_source(${FILE} FILE)
if (NOT "${FILE}" STREQUAL "")
codecov_lang_of_source(${FILE} LANG)
if (NOT "${LANG}" STREQUAL "")
list(APPEND SOURCES "${FILE}")
set(TCOMPILER ${CMAKE_${LANG}_COMPILER_ID})
endif ()
endif ()
endforeach ()
# If no gcov binary was found, coverage data can't be evaluated.
if (NOT GCOV_${TCOMPILER}_BIN)
message(WARNING "No coverage evaluation binary found for ${TCOMPILER}.")
return()
endif ()
set(GCOV_BIN "${GCOV_${TCOMPILER}_BIN}")
set(GCOV_ENV "${GCOV_${TCOMPILER}_ENV}")
set(BUFFER "")
foreach(FILE ${SOURCES})
get_filename_component(FILE_PATH "${TDIR}/${FILE}" PATH)
# call gcov
add_custom_command(OUTPUT ${TDIR}/${FILE}.gcov
COMMAND ${GCOV_ENV} ${GCOV_BIN} ${TDIR}/${FILE}.gcno > /dev/null
DEPENDS ${TNAME} ${TDIR}/${FILE}.gcno
WORKING_DIRECTORY ${FILE_PATH}
)
list(APPEND BUFFER ${TDIR}/${FILE}.gcov)
endforeach()
# add target for gcov evaluation of <TNAME>
add_custom_target(${TNAME}-gcov DEPENDS ${BUFFER})
# add evaluation target to the global gcov target.
add_dependencies(gcov ${TNAME}-gcov)
endfunction (add_gcov_target)

354
CMake/FindLcov.cmake Normal file
View File

@ -0,0 +1,354 @@
# This file is part of CMake-codecov.
#
# Copyright (c)
# 2015-2017 RWTH Aachen University, Federal Republic of Germany
#
# See the LICENSE file in the package base directory for details
#
# Written by Alexander Haase, alexander.haase@rwth-aachen.de
#
# configuration
set(LCOV_DATA_PATH "${CMAKE_BINARY_DIR}/lcov/data")
set(LCOV_DATA_PATH_INIT "${LCOV_DATA_PATH}/init")
set(LCOV_DATA_PATH_CAPTURE "${LCOV_DATA_PATH}/capture")
set(LCOV_HTML_PATH "${CMAKE_BINARY_DIR}/lcov/html")
# Search for Gcov which is used by Lcov.
find_package(Gcov)
# This function will add lcov evaluation for target <TNAME>. Only sources of
# this target will be evaluated and no dependencies will be added. It will call
# geninfo on any source file of <TNAME> once and store the info file in the same
# directory.
#
# Note: This function is only a wrapper to define this function always, even if
# coverage is not supported by the compiler or disabled. This function must
# be defined here, because the module will be exited, if there is no coverage
# support by the compiler or it is disabled by the user.
function (add_lcov_target TNAME)
if (LCOV_FOUND)
# capture initial coverage data
lcov_capture_initial_tgt(${TNAME})
# capture coverage data after execution
lcov_capture_tgt(${TNAME})
endif ()
endfunction (add_lcov_target)
# include required Modules
include(FindPackageHandleStandardArgs)
# Search for required lcov binaries.
find_program(LCOV_BIN lcov)
find_program(GENINFO_BIN geninfo)
find_program(GENHTML_BIN genhtml)
find_package_handle_standard_args(lcov
REQUIRED_VARS LCOV_BIN GENINFO_BIN GENHTML_BIN
)
# enable genhtml C++ demangeling, if c++filt is found.
set(GENHTML_CPPFILT_FLAG "")
find_program(CPPFILT_BIN c++filt)
if (NOT CPPFILT_BIN STREQUAL "")
set(GENHTML_CPPFILT_FLAG "--demangle-cpp")
endif (NOT CPPFILT_BIN STREQUAL "")
# enable no-external flag for lcov, if available.
if (GENINFO_BIN AND NOT DEFINED GENINFO_EXTERN_FLAG)
set(FLAG "")
execute_process(COMMAND ${GENINFO_BIN} --help OUTPUT_VARIABLE GENINFO_HELP)
string(REGEX MATCH "external" GENINFO_RES "${GENINFO_HELP}")
if (GENINFO_RES)
set(FLAG "--no-external")
endif ()
set(GENINFO_EXTERN_FLAG "${FLAG}"
CACHE STRING "Geninfo flag to exclude system sources.")
endif ()
# If Lcov was not found, exit module now.
if (NOT LCOV_FOUND)
return()
endif (NOT LCOV_FOUND)
# Create directories to be used.
file(MAKE_DIRECTORY ${LCOV_DATA_PATH_INIT})
file(MAKE_DIRECTORY ${LCOV_DATA_PATH_CAPTURE})
set(LCOV_REMOVE_PATTERNS "")
# This function will merge lcov files to a single target file. Additional lcov
# flags may be set with setting LCOV_EXTRA_FLAGS before calling this function.
function (lcov_merge_files OUTFILE ...)
# Remove ${OUTFILE} from ${ARGV} and generate lcov parameters with files.
list(REMOVE_AT ARGV 0)
# Generate merged file.
string(REPLACE "${CMAKE_BINARY_DIR}/" "" FILE_REL "${OUTFILE}")
add_custom_command(OUTPUT "${OUTFILE}.raw"
COMMAND cat ${ARGV} > ${OUTFILE}.raw
DEPENDS ${ARGV}
COMMENT "Generating ${FILE_REL}"
)
add_custom_command(OUTPUT "${OUTFILE}"
COMMAND ${LCOV_BIN} --quiet -a ${OUTFILE}.raw --output-file ${OUTFILE}
--base-directory ${PROJECT_SOURCE_DIR} ${LCOV_EXTRA_FLAGS}
COMMAND ${LCOV_BIN} --quiet -r ${OUTFILE} ${LCOV_REMOVE_PATTERNS}
--output-file ${OUTFILE} ${LCOV_EXTRA_FLAGS}
DEPENDS ${OUTFILE}.raw
COMMENT "Post-processing ${FILE_REL}"
)
endfunction ()
# Add a new global target to generate initial coverage reports for all targets.
# This target will be used to generate the global initial info file, which is
# used to gather even empty report data.
if (NOT TARGET lcov-capture-init)
add_custom_target(lcov-capture-init)
set(LCOV_CAPTURE_INIT_FILES "" CACHE INTERNAL "")
endif (NOT TARGET lcov-capture-init)
# This function will add initial capture of coverage data for target <TNAME>,
# which is needed to get also data for objects, which were not loaded at
# execution time. It will call geninfo for every source file of <TNAME> once and
# store the info file in the same directory.
function (lcov_capture_initial_tgt TNAME)
# We don't have to check, if the target has support for coverage, thus this
# will be checked by add_coverage_target in Findcoverage.cmake. Instead we
# have to determine which gcov binary to use.
get_target_property(TSOURCES ${TNAME} SOURCES)
set(SOURCES "")
set(TCOMPILER "")
foreach (FILE ${TSOURCES})
codecov_path_of_source(${FILE} FILE)
if (NOT "${FILE}" STREQUAL "")
codecov_lang_of_source(${FILE} LANG)
if (NOT "${LANG}" STREQUAL "")
list(APPEND SOURCES "${FILE}")
set(TCOMPILER ${CMAKE_${LANG}_COMPILER_ID})
endif ()
endif ()
endforeach ()
# If no gcov binary was found, coverage data can't be evaluated.
if (NOT GCOV_${TCOMPILER}_BIN)
message(WARNING "No coverage evaluation binary found for ${TCOMPILER}.")
return()
endif ()
set(GCOV_BIN "${GCOV_${TCOMPILER}_BIN}")
set(GCOV_ENV "${GCOV_${TCOMPILER}_ENV}")
set(TDIR ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TNAME}.dir)
set(GENINFO_FILES "")
foreach(FILE ${SOURCES})
# generate empty coverage files
set(OUTFILE "${TDIR}/${FILE}.info.init")
list(APPEND GENINFO_FILES ${OUTFILE})
add_custom_command(OUTPUT ${OUTFILE} COMMAND ${GCOV_ENV} ${GENINFO_BIN}
--quiet --base-directory ${PROJECT_SOURCE_DIR} --initial
--gcov-tool ${GCOV_BIN} --output-filename ${OUTFILE}
${GENINFO_EXTERN_FLAG} ${TDIR}/${FILE}.gcno
DEPENDS ${TNAME}
COMMENT "Capturing initial coverage data for ${FILE}"
)
endforeach()
# Concatenate all files generated by geninfo to a single file per target.
set(OUTFILE "${LCOV_DATA_PATH_INIT}/${TNAME}.info")
set(LCOV_EXTRA_FLAGS "--initial")
lcov_merge_files("${OUTFILE}" ${GENINFO_FILES})
add_custom_target(${TNAME}-capture-init ALL DEPENDS ${OUTFILE})
# add geninfo file generation to global lcov-geninfo target
add_dependencies(lcov-capture-init ${TNAME}-capture-init)
set(LCOV_CAPTURE_INIT_FILES "${LCOV_CAPTURE_INIT_FILES}"
"${OUTFILE}" CACHE INTERNAL ""
)
endfunction (lcov_capture_initial_tgt)
# This function will generate the global info file for all targets. It has to be
# called after all other CMake functions in the root CMakeLists.txt file, to get
# a full list of all targets that generate coverage data.
function (lcov_capture_initial)
# Skip this function (and do not create the following targets), if there are
# no input files.
if ("${LCOV_CAPTURE_INIT_FILES}" STREQUAL "")
return()
endif ()
# Add a new target to merge the files of all targets.
set(OUTFILE "${LCOV_DATA_PATH_INIT}/all_targets.info")
lcov_merge_files("${OUTFILE}" ${LCOV_CAPTURE_INIT_FILES})
add_custom_target(lcov-geninfo-init ALL DEPENDS ${OUTFILE}
lcov-capture-init
)
endfunction (lcov_capture_initial)
# Add a new global target to generate coverage reports for all targets. This
# target will be used to generate the global info file.
if (NOT TARGET lcov-capture)
add_custom_target(lcov-capture)
set(LCOV_CAPTURE_FILES "" CACHE INTERNAL "")
endif (NOT TARGET lcov-capture)
# This function will add capture of coverage data for target <TNAME>, which is
# needed to get also data for objects, which were not loaded at execution time.
# It will call geninfo for every source file of <TNAME> once and store the info
# file in the same directory.
function (lcov_capture_tgt TNAME)
# We don't have to check, if the target has support for coverage, thus this
# will be checked by add_coverage_target in Findcoverage.cmake. Instead we
# have to determine which gcov binary to use.
get_target_property(TSOURCES ${TNAME} SOURCES)
set(SOURCES "")
set(TCOMPILER "")
foreach (FILE ${TSOURCES})
codecov_path_of_source(${FILE} FILE)
if (NOT "${FILE}" STREQUAL "")
codecov_lang_of_source(${FILE} LANG)
if (NOT "${LANG}" STREQUAL "")
list(APPEND SOURCES "${FILE}")
set(TCOMPILER ${CMAKE_${LANG}_COMPILER_ID})
endif ()
endif ()
endforeach ()
# If no gcov binary was found, coverage data can't be evaluated.
if (NOT GCOV_${TCOMPILER}_BIN)
message(WARNING "No coverage evaluation binary found for ${TCOMPILER}.")
return()
endif ()
set(GCOV_BIN "${GCOV_${TCOMPILER}_BIN}")
set(GCOV_ENV "${GCOV_${TCOMPILER}_ENV}")
set(TDIR ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TNAME}.dir)
set(GENINFO_FILES "")
foreach(FILE ${SOURCES})
# Generate coverage files. If no .gcda file was generated during
# execution, the empty coverage file will be used instead.
set(OUTFILE "${TDIR}/${FILE}.info")
list(APPEND GENINFO_FILES ${OUTFILE})
add_custom_command(OUTPUT ${OUTFILE}
COMMAND test -f "${TDIR}/${FILE}.gcda"
&& ${GCOV_ENV} ${GENINFO_BIN} --quiet --base-directory
${PROJECT_SOURCE_DIR} --gcov-tool ${GCOV_BIN}
--output-filename ${OUTFILE} ${GENINFO_EXTERN_FLAG}
${TDIR}/${FILE}.gcda
|| cp ${OUTFILE}.init ${OUTFILE}
DEPENDS ${TNAME} ${TNAME}-capture-init
COMMENT "Capturing coverage data for ${FILE}"
)
endforeach()
# Concatenate all files generated by geninfo to a single file per target.
set(OUTFILE "${LCOV_DATA_PATH_CAPTURE}/${TNAME}.info")
lcov_merge_files("${OUTFILE}" ${GENINFO_FILES})
add_custom_target(${TNAME}-geninfo DEPENDS ${OUTFILE})
# add geninfo file generation to global lcov-capture target
add_dependencies(lcov-capture ${TNAME}-geninfo)
set(LCOV_CAPTURE_FILES "${LCOV_CAPTURE_FILES}" "${OUTFILE}" CACHE INTERNAL
""
)
# Add target for generating html output for this target only.
file(MAKE_DIRECTORY ${LCOV_HTML_PATH}/${TNAME})
add_custom_target(${TNAME}-genhtml
COMMAND ${GENHTML_BIN} --quiet --sort --prefix ${PROJECT_SOURCE_DIR}
--baseline-file ${LCOV_DATA_PATH_INIT}/${TNAME}.info
--output-directory ${LCOV_HTML_PATH}/${TNAME}
--title "${CMAKE_PROJECT_NAME} - target ${TNAME}"
${GENHTML_CPPFILT_FLAG} ${OUTFILE}
DEPENDS ${TNAME}-geninfo ${TNAME}-capture-init
)
endfunction (lcov_capture_tgt)
# This function will generate the global info file for all targets. It has to be
# called after all other CMake functions in the root CMakeLists.txt file, to get
# a full list of all targets that generate coverage data.
function (lcov_capture)
# Skip this function (and do not create the following targets), if there are
# no input files.
if ("${LCOV_CAPTURE_FILES}" STREQUAL "")
return()
endif ()
# Add a new target to merge the files of all targets.
set(OUTFILE "${LCOV_DATA_PATH_CAPTURE}/all_targets.info")
lcov_merge_files("${OUTFILE}" ${LCOV_CAPTURE_FILES})
add_custom_target(lcov-geninfo DEPENDS ${OUTFILE} lcov-capture)
# Add a new global target for all lcov targets. This target could be used to
# generate the lcov html output for the whole project instead of calling
# <TARGET>-geninfo and <TARGET>-genhtml for each target. It will also be
# used to generate a html site for all project data together instead of one
# for each target.
if (NOT TARGET lcov)
file(MAKE_DIRECTORY ${LCOV_HTML_PATH}/all_targets)
add_custom_target(lcov
COMMAND ${GENHTML_BIN} --quiet --sort
--baseline-file ${LCOV_DATA_PATH_INIT}/all_targets.info
--output-directory ${LCOV_HTML_PATH}/all_targets
--title "${CMAKE_PROJECT_NAME}" --prefix "${PROJECT_SOURCE_DIR}"
${GENHTML_CPPFILT_FLAG} ${OUTFILE}
DEPENDS lcov-geninfo-init lcov-geninfo
)
endif ()
endfunction (lcov_capture)
# Add a new global target to generate the lcov html report for the whole project
# instead of calling <TARGET>-genhtml for each target (to create an own report
# for each target). Instead of the lcov target it does not require geninfo for
# all targets, so you have to call <TARGET>-geninfo to generate the info files
# the targets you'd like to have in your report or lcov-geninfo for generating
# info files for all targets before calling lcov-genhtml.
file(MAKE_DIRECTORY ${LCOV_HTML_PATH}/selected_targets)
if (NOT TARGET lcov-genhtml)
add_custom_target(lcov-genhtml
COMMAND ${GENHTML_BIN}
--quiet
--output-directory ${LCOV_HTML_PATH}/selected_targets
--title \"${CMAKE_PROJECT_NAME} - targets `find
${LCOV_DATA_PATH_CAPTURE} -name \"*.info\" ! -name
\"all_targets.info\" -exec basename {} .info \\\;`\"
--prefix ${PROJECT_SOURCE_DIR}
--sort
${GENHTML_CPPFILT_FLAG}
`find ${LCOV_DATA_PATH_CAPTURE} -name \"*.info\" ! -name
\"all_targets.info\"`
)
endif (NOT TARGET lcov-genhtml)

258
CMake/Findcodecov.cmake Normal file
View File

@ -0,0 +1,258 @@
# This file is part of CMake-codecov.
#
# Copyright (c)
# 2015-2017 RWTH Aachen University, Federal Republic of Germany
#
# See the LICENSE file in the package base directory for details
#
# Written by Alexander Haase, alexander.haase@rwth-aachen.de
#
# Add an option to choose, if coverage should be enabled or not. If enabled
# marked targets will be build with coverage support and appropriate targets
# will be added. If disabled coverage will be ignored for *ALL* targets.
option(ENABLE_COVERAGE "Enable coverage build." OFF)
set(COVERAGE_FLAG_CANDIDATES
# gcc and clang
"-O0 -g -fprofile-arcs -ftest-coverage"
# gcc and clang fallback
"-O0 -g --coverage"
)
# Add coverage support for target ${TNAME} and register target for coverage
# evaluation. If coverage is disabled or not supported, this function will
# simply do nothing.
#
# Note: This function is only a wrapper to define this function always, even if
# coverage is not supported by the compiler or disabled. This function must
# be defined here, because the module will be exited, if there is no coverage
# support by the compiler or it is disabled by the user.
function (add_coverage TNAME)
# only add coverage for target, if coverage is support and enabled.
if (ENABLE_COVERAGE)
foreach (TNAME ${ARGV})
add_coverage_target(${TNAME})
endforeach ()
endif ()
endfunction (add_coverage)
# Add global target to gather coverage information after all targets have been
# added. Other evaluation functions could be added here, after checks for the
# specific module have been passed.
#
# Note: This function is only a wrapper to define this function always, even if
# coverage is not supported by the compiler or disabled. This function must
# be defined here, because the module will be exited, if there is no coverage
# support by the compiler or it is disabled by the user.
function (coverage_evaluate)
# add lcov evaluation
if (LCOV_FOUND)
lcov_capture_initial()
lcov_capture()
endif (LCOV_FOUND)
endfunction ()
# Exit this module, if coverage is disabled. add_coverage is defined before this
# return, so this module can be exited now safely without breaking any build-
# scripts.
if (NOT ENABLE_COVERAGE)
return()
endif ()
# Find the reuired flags foreach language.
set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET})
set(CMAKE_REQUIRED_QUIET ${codecov_FIND_QUIETLY})
get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
foreach (LANG ${ENABLED_LANGUAGES})
# Coverage flags are not dependend on language, but the used compiler. So
# instead of searching flags foreach language, search flags foreach compiler
# used.
set(COMPILER ${CMAKE_${LANG}_COMPILER_ID})
if (NOT COVERAGE_${COMPILER}_FLAGS)
foreach (FLAG ${COVERAGE_FLAG_CANDIDATES})
if(NOT CMAKE_REQUIRED_QUIET)
message(STATUS "Try ${COMPILER} code coverage flag = [${FLAG}]")
endif()
set(CMAKE_REQUIRED_FLAGS "${FLAG}")
unset(COVERAGE_FLAG_DETECTED CACHE)
if (${LANG} STREQUAL "C")
include(CheckCCompilerFlag)
check_c_compiler_flag("${FLAG}" COVERAGE_FLAG_DETECTED)
elseif (${LANG} STREQUAL "CXX")
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag("${FLAG}" COVERAGE_FLAG_DETECTED)
elseif (${LANG} STREQUAL "Fortran")
# CheckFortranCompilerFlag was introduced in CMake 3.x. To be
# compatible with older Cmake versions, we will check if this
# module is present before we use it. Otherwise we will define
# Fortran coverage support as not available.
include(CheckFortranCompilerFlag OPTIONAL
RESULT_VARIABLE INCLUDED)
if (INCLUDED)
check_fortran_compiler_flag("${FLAG}"
COVERAGE_FLAG_DETECTED)
elseif (NOT CMAKE_REQUIRED_QUIET)
message("-- Performing Test COVERAGE_FLAG_DETECTED")
message("-- Performing Test COVERAGE_FLAG_DETECTED - Failed"
" (Check not supported)")
endif ()
endif()
if (COVERAGE_FLAG_DETECTED)
set(COVERAGE_${COMPILER}_FLAGS "${FLAG}"
CACHE STRING "${COMPILER} flags for code coverage.")
mark_as_advanced(COVERAGE_${COMPILER}_FLAGS)
break()
else ()
message(WARNING "Code coverage is not available for ${COMPILER}"
" compiler. Targets using this compiler will be "
"compiled without it.")
endif ()
endforeach ()
endif ()
endforeach ()
set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE})
# Helper function to get the language of a source file.
function (codecov_lang_of_source FILE RETURN_VAR)
get_filename_component(FILE_EXT "${FILE}" EXT)
string(TOLOWER "${FILE_EXT}" FILE_EXT)
string(SUBSTRING "${FILE_EXT}" 1 -1 FILE_EXT)
get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
foreach (LANG ${ENABLED_LANGUAGES})
list(FIND CMAKE_${LANG}_SOURCE_FILE_EXTENSIONS "${FILE_EXT}" TEMP)
if (NOT ${TEMP} EQUAL -1)
set(${RETURN_VAR} "${LANG}" PARENT_SCOPE)
return()
endif ()
endforeach()
set(${RETURN_VAR} "" PARENT_SCOPE)
endfunction ()
# Helper function to get the relative path of the source file destination path.
# This path is needed by FindGcov and FindLcov cmake files to locate the
# captured data.
function (codecov_path_of_source FILE RETURN_VAR)
string(REGEX MATCH "TARGET_OBJECTS:([^ >]+)" _source ${FILE})
# If expression was found, SOURCEFILE is a generator-expression for an
# object library. Currently we found no way to call this function automatic
# for the referenced target, so it must be called in the directoryso of the
# object library definition.
if (NOT "${_source}" STREQUAL "")
set(${RETURN_VAR} "" PARENT_SCOPE)
return()
endif ()
string(REPLACE "${CMAKE_CURRENT_BINARY_DIR}/" "" FILE "${FILE}")
if(IS_ABSOLUTE ${FILE})
file(RELATIVE_PATH FILE ${CMAKE_CURRENT_SOURCE_DIR} ${FILE})
endif()
# get the right path for file
string(REPLACE ".." "__" PATH "${FILE}")
set(${RETURN_VAR} "${PATH}" PARENT_SCOPE)
endfunction()
# Add coverage support for target ${TNAME} and register target for coverage
# evaluation.
function(add_coverage_target TNAME)
# Check if all sources for target use the same compiler. If a target uses
# e.g. C and Fortran mixed and uses different compilers (e.g. clang and
# gfortran) this can trigger huge problems, because different compilers may
# use different implementations for code coverage.
get_target_property(TSOURCES ${TNAME} SOURCES)
set(TARGET_COMPILER "")
set(ADDITIONAL_FILES "")
foreach (FILE ${TSOURCES})
# If expression was found, FILE is a generator-expression for an object
# library. Object libraries will be ignored.
string(REGEX MATCH "TARGET_OBJECTS:([^ >]+)" _file ${FILE})
if ("${_file}" STREQUAL "")
codecov_lang_of_source(${FILE} LANG)
if (LANG)
list(APPEND TARGET_COMPILER ${CMAKE_${LANG}_COMPILER_ID})
list(APPEND ADDITIONAL_FILES "${FILE}.gcno")
list(APPEND ADDITIONAL_FILES "${FILE}.gcda")
endif ()
endif ()
endforeach ()
list(REMOVE_DUPLICATES TARGET_COMPILER)
list(LENGTH TARGET_COMPILER NUM_COMPILERS)
if (NUM_COMPILERS GREATER 1)
message(WARNING "Can't use code coverage for target ${TNAME}, because "
"it will be compiled by incompatible compilers. Target will be "
"compiled without code coverage.")
return()
elseif (NUM_COMPILERS EQUAL 0)
message(WARNING "Can't use code coverage for target ${TNAME}, because "
"it uses an unknown compiler. Target will be compiled without "
"code coverage.")
return()
elseif (NOT DEFINED "COVERAGE_${TARGET_COMPILER}_FLAGS")
# A warning has been printed before, so just return if flags for this
# compiler aren't available.
return()
endif()
# enable coverage for target
set_property(TARGET ${TNAME} APPEND_STRING
PROPERTY COMPILE_FLAGS " ${COVERAGE_${TARGET_COMPILER}_FLAGS}")
set_property(TARGET ${TNAME} APPEND_STRING
PROPERTY LINK_FLAGS " ${COVERAGE_${TARGET_COMPILER}_FLAGS}")
# Add gcov files generated by compiler to clean target.
set(CLEAN_FILES "")
foreach (FILE ${ADDITIONAL_FILES})
codecov_path_of_source(${FILE} FILE)
list(APPEND CLEAN_FILES "CMakeFiles/${TNAME}.dir/${FILE}")
endforeach()
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES
"${CLEAN_FILES}")
add_gcov_target(${TNAME})
add_lcov_target(${TNAME})
endfunction(add_coverage_target)
# Include modules for parsing the collected data and output it in a readable
# format (like gcov and lcov).
find_package(Gcov)
find_package(Lcov)

56
CMake/llvm-cov-wrapper Executable file
View File

@ -0,0 +1,56 @@
#!/bin/sh
# This file is part of CMake-codecov.
#
# Copyright (c)
# 2015-2017 RWTH Aachen University, Federal Republic of Germany
#
# See the LICENSE file in the package base directory for details
#
# Written by Alexander Haase, alexander.haase@rwth-aachen.de
#
if [ -z "$LLVM_COV_BIN" ]
then
echo "LLVM_COV_BIN not set!" >& 2
exit 1
fi
# Get LLVM version to find out.
LLVM_VERSION=$($LLVM_COV_BIN -version | grep -i "LLVM version" \
| sed "s/^\([A-Za-z ]*\)\([0-9]\).\([0-9]\).*$/\2.\3/g")
if [ "$1" = "-v" ]
then
echo "llvm-cov-wrapper $LLVM_VERSION"
exit 0
fi
if [ -n "$LLVM_VERSION" ]
then
MAJOR=$(echo $LLVM_VERSION | cut -d'.' -f1)
MINOR=$(echo $LLVM_VERSION | cut -d'.' -f2)
if [ $MAJOR -eq 3 ] && [ $MINOR -le 4 ]
then
if [ -f "$1" ]
then
filename=$(basename "$1")
extension="${filename##*.}"
case "$extension" in
"gcno") exec $LLVM_COV_BIN --gcno="$1" ;;
"gcda") exec $LLVM_COV_BIN --gcda="$1" ;;
esac
fi
fi
if [ $MAJOR -eq 3 ] && [ $MINOR -le 5 ]
then
exec $LLVM_COV_BIN $@
fi
fi
exec $LLVM_COV_BIN gcov $@

442
CMakeLists.txt Normal file
View File

@ -0,0 +1,442 @@
cmake_minimum_required(VERSION 3.1)
# detect if Catch is being bundled,
# disable testsuite in that case
if(NOT DEFINED PROJECT_NAME)
set(NOT_SUBPROJECT ON)
endif()
project(Catch2 LANGUAGES CXX VERSION 2.1.2)
include(GNUInstallDirs)
option(CATCH_USE_VALGRIND "Perform SelfTests with Valgrind" OFF)
option(CATCH_BUILD_EXAMPLES "Build documentation examples" OFF)
option(CATCH_ENABLE_COVERAGE "Generate coverage for codecov.io" OFF)
option(CATCH_ENABLE_WERROR "Enable all warnings as errors" ON)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# define some folders
set(CATCH_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(SELF_TEST_DIR ${CATCH_DIR}/projects/SelfTest)
set(BENCHMARK_DIR ${CATCH_DIR}/projects/Benchmark)
set(HEADER_DIR ${CATCH_DIR}/include)
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}")
set(MESSAGE "${MESSAGE} in ${CMAKE_CURRENT_LIST_FILE}\n")
file(GLOB GLOBBED_LIST "${FOLDER}/*.cpp"
"${FOLDER}/*.hpp"
"${FOLDER}/*.h")
list(REMOVE_ITEM GLOBBED_LIST ${${LIST_VAR}})
foreach(EXTRA_ITEM ${GLOBBED_LIST})
string(REPLACE "${CATCH_DIR}/" "" RELATIVE_FILE_NAME "${EXTRA_ITEM}")
message(AUTHOR_WARNING "The file \"${RELATIVE_FILE_NAME}\"${MESSAGE}")
endforeach()
endfunction()
function(CheckFileListRec LIST_VAR FOLDER)
set(MESSAGE " should be added to the variable ${LIST_VAR}")
set(MESSAGE "${MESSAGE} in ${CMAKE_CURRENT_LIST_FILE}\n")
file(GLOB_RECURSE GLOBBED_LIST "${FOLDER}/*.cpp"
"${FOLDER}/*.hpp"
"${FOLDER}/*.h")
list(REMOVE_ITEM GLOBBED_LIST ${${LIST_VAR}})
foreach(EXTRA_ITEM ${GLOBBED_LIST})
string(REPLACE "${CATCH_DIR}/" "" RELATIVE_FILE_NAME "${EXTRA_ITEM}")
message(AUTHOR_WARNING "The file \"${RELATIVE_FILE_NAME}\"${MESSAGE}")
endforeach()
endfunction()
# define the sources of the self test
# Please keep these ordered alphabetically
set(TEST_SOURCES
${SELF_TEST_DIR}/TestMain.cpp
${SELF_TEST_DIR}/IntrospectiveTests/CmdLine.tests.cpp
${SELF_TEST_DIR}/IntrospectiveTests/PartTracker.tests.cpp
${SELF_TEST_DIR}/IntrospectiveTests/TagAlias.tests.cpp
${SELF_TEST_DIR}/IntrospectiveTests/String.tests.cpp
${SELF_TEST_DIR}/IntrospectiveTests/Xml.tests.cpp
${SELF_TEST_DIR}/UsageTests/Approx.tests.cpp
${SELF_TEST_DIR}/UsageTests/BDD.tests.cpp
${SELF_TEST_DIR}/UsageTests/Benchmark.tests.cpp
${SELF_TEST_DIR}/UsageTests/Class.tests.cpp
${SELF_TEST_DIR}/UsageTests/Compilation.tests.cpp
${SELF_TEST_DIR}/UsageTests/Condition.tests.cpp
${SELF_TEST_DIR}/UsageTests/Decomposition.tests.cpp
${SELF_TEST_DIR}/UsageTests/EnumToString.tests.cpp
${SELF_TEST_DIR}/UsageTests/Exception.tests.cpp
${SELF_TEST_DIR}/UsageTests/Message.tests.cpp
${SELF_TEST_DIR}/UsageTests/Misc.tests.cpp
${SELF_TEST_DIR}/UsageTests/ToStringChrono.tests.cpp
${SELF_TEST_DIR}/UsageTests/ToStringGeneral.tests.cpp
${SELF_TEST_DIR}/UsageTests/ToStringPair.tests.cpp
${SELF_TEST_DIR}/UsageTests/ToStringTuple.tests.cpp
${SELF_TEST_DIR}/UsageTests/ToStringVector.tests.cpp
${SELF_TEST_DIR}/UsageTests/ToStringWhich.tests.cpp
${SELF_TEST_DIR}/UsageTests/Tricky.tests.cpp
${SELF_TEST_DIR}/UsageTests/VariadicMacros.tests.cpp
${SELF_TEST_DIR}/UsageTests/Matchers.tests.cpp
)
CheckFileList(TEST_SOURCES ${SELF_TEST_DIR})
# A set of impl files that just #include a single header
# Please keep these ordered alphabetically
set(SURROGATE_SOURCES
${SELF_TEST_DIR}/SurrogateCpps/catch_console_colour.cpp
${SELF_TEST_DIR}/SurrogateCpps/catch_debugger.cpp
${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_reporter.cpp
${SELF_TEST_DIR}/SurrogateCpps/catch_option.cpp
${SELF_TEST_DIR}/SurrogateCpps/catch_stream.cpp
${SELF_TEST_DIR}/SurrogateCpps/catch_test_case_tracker.cpp
${SELF_TEST_DIR}/SurrogateCpps/catch_test_spec.cpp
${SELF_TEST_DIR}/SurrogateCpps/catch_xmlwriter.cpp
)
CheckFileList(SURROGATE_SOURCES ${SELF_TEST_DIR}/SurrogateCpps)
# Please keep these ordered alphabetically
set(TOP_LEVEL_HEADERS
${HEADER_DIR}/catch.hpp
${HEADER_DIR}/catch_with_main.hpp
)
CheckFileList(TOP_LEVEL_HEADERS ${HEADER_DIR})
# Please keep these ordered alphabetically
set(EXTERNAL_HEADERS
${HEADER_DIR}/external/clara.hpp
)
CheckFileList(EXTERNAL_HEADERS ${HEADER_DIR}/external)
# Please keep these ordered alphabetically
set(INTERNAL_HEADERS
${HEADER_DIR}/internal/catch_approx.h
${HEADER_DIR}/internal/catch_assertionhandler.h
${HEADER_DIR}/internal/catch_assertioninfo.h
${HEADER_DIR}/internal/catch_assertionresult.h
${HEADER_DIR}/internal/catch_capture.hpp
${HEADER_DIR}/internal/catch_capture_matchers.h
${HEADER_DIR}/internal/catch_clara.h
${HEADER_DIR}/internal/catch_commandline.h
${HEADER_DIR}/internal/catch_common.h
${HEADER_DIR}/internal/catch_compiler_capabilities.h
${HEADER_DIR}/internal/catch_config.hpp
${HEADER_DIR}/internal/catch_console_colour.h
${HEADER_DIR}/internal/catch_context.h
${HEADER_DIR}/internal/catch_debug_console.h
${HEADER_DIR}/internal/catch_debugger.h
${HEADER_DIR}/internal/catch_decomposer.h
${HEADER_DIR}/internal/catch_default_main.hpp
${HEADER_DIR}/internal/catch_enforce.h
${HEADER_DIR}/internal/catch_errno_guard.h
${HEADER_DIR}/internal/catch_exception_translator_registry.h
${HEADER_DIR}/internal/catch_external_interfaces.h
${HEADER_DIR}/internal/catch_fatal_condition.h
${HEADER_DIR}/internal/catch_impl.hpp
${HEADER_DIR}/internal/catch_interfaces_capture.h
${HEADER_DIR}/internal/catch_interfaces_config.h
${HEADER_DIR}/internal/catch_interfaces_exception.h
${HEADER_DIR}/internal/catch_interfaces_registry_hub.h
${HEADER_DIR}/internal/catch_interfaces_reporter.h
${HEADER_DIR}/internal/catch_interfaces_runner.h
${HEADER_DIR}/internal/catch_interfaces_tag_alias_registry.h
${HEADER_DIR}/internal/catch_interfaces_testcase.h
${HEADER_DIR}/internal/catch_leak_detector.h
${HEADER_DIR}/internal/catch_list.h
${HEADER_DIR}/internal/catch_matchers.h
${HEADER_DIR}/internal/catch_matchers_floating.h
${HEADER_DIR}/internal/catch_matchers_string.h
${HEADER_DIR}/internal/catch_matchers_vector.h
${HEADER_DIR}/internal/catch_message.h
${HEADER_DIR}/internal/catch_objc.hpp
${HEADER_DIR}/internal/catch_objc_arc.hpp
${HEADER_DIR}/internal/catch_option.hpp
${HEADER_DIR}/internal/catch_platform.h
${HEADER_DIR}/internal/catch_random_number_generator.h
${HEADER_DIR}/internal/catch_reenable_warnings.h
${HEADER_DIR}/internal/catch_reporter_registrars.hpp
${HEADER_DIR}/internal/catch_reporter_registry.h
${HEADER_DIR}/internal/catch_result_type.h
${HEADER_DIR}/internal/catch_run_context.h
${HEADER_DIR}/internal/catch_benchmark.h
${HEADER_DIR}/internal/catch_section.h
${HEADER_DIR}/internal/catch_section_info.h
${HEADER_DIR}/internal/catch_session.h
${HEADER_DIR}/internal/catch_startup_exception_registry.h
${HEADER_DIR}/internal/catch_stream.h
${HEADER_DIR}/internal/catch_stringref.h
${HEADER_DIR}/internal/catch_string_manip.h
${HEADER_DIR}/internal/catch_suppress_warnings.h
${HEADER_DIR}/internal/catch_tag_alias.h
${HEADER_DIR}/internal/catch_tag_alias_autoregistrar.h
${HEADER_DIR}/internal/catch_tag_alias_registry.h
${HEADER_DIR}/internal/catch_test_case_info.h
${HEADER_DIR}/internal/catch_test_case_registry_impl.h
${HEADER_DIR}/internal/catch_test_case_tracker.h
${HEADER_DIR}/internal/catch_test_registry.h
${HEADER_DIR}/internal/catch_test_spec.h
${HEADER_DIR}/internal/catch_test_spec_parser.h
${HEADER_DIR}/internal/catch_text.h
${HEADER_DIR}/internal/catch_timer.h
${HEADER_DIR}/internal/catch_tostring.h
${HEADER_DIR}/internal/catch_totals.h
${HEADER_DIR}/internal/catch_uncaught_exceptions.h
${HEADER_DIR}/internal/catch_user_interfaces.h
${HEADER_DIR}/internal/catch_version.h
${HEADER_DIR}/internal/catch_wildcard_pattern.h
${HEADER_DIR}/internal/catch_windows_h_proxy.h
${HEADER_DIR}/internal/catch_xmlwriter.h
)
set(IMPL_SOURCES
${HEADER_DIR}/internal/catch_approx.cpp
${HEADER_DIR}/internal/catch_assertionhandler.cpp
${HEADER_DIR}/internal/catch_assertionresult.cpp
${HEADER_DIR}/internal/catch_benchmark.cpp
${HEADER_DIR}/internal/catch_capture_matchers.cpp
${HEADER_DIR}/internal/catch_commandline.cpp
${HEADER_DIR}/internal/catch_common.cpp
${HEADER_DIR}/internal/catch_config.cpp
${HEADER_DIR}/internal/catch_console_colour.cpp
${HEADER_DIR}/internal/catch_context.cpp
${HEADER_DIR}/internal/catch_debug_console.cpp
${HEADER_DIR}/internal/catch_debugger.cpp
${HEADER_DIR}/internal/catch_decomposer.cpp
${HEADER_DIR}/internal/catch_errno_guard.cpp
${HEADER_DIR}/internal/catch_exception_translator_registry.cpp
${HEADER_DIR}/internal/catch_fatal_condition.cpp
${HEADER_DIR}/internal/catch_interfaces_capture.cpp
${HEADER_DIR}/internal/catch_interfaces_config.cpp
${HEADER_DIR}/internal/catch_interfaces_exception.cpp
${HEADER_DIR}/internal/catch_interfaces_registry_hub.cpp
${HEADER_DIR}/internal/catch_interfaces_runner.cpp
${HEADER_DIR}/internal/catch_interfaces_testcase.cpp
${HEADER_DIR}/internal/catch_list.cpp
${HEADER_DIR}/internal/catch_leak_detector.cpp
${HEADER_DIR}/internal/catch_matchers.cpp
${HEADER_DIR}/internal/catch_matchers_floating.cpp
${HEADER_DIR}/internal/catch_matchers_string.cpp
${HEADER_DIR}/internal/catch_message.cpp
${HEADER_DIR}/internal/catch_registry_hub.cpp
${HEADER_DIR}/internal/catch_interfaces_reporter.cpp
${HEADER_DIR}/internal/catch_random_number_generator.cpp
${HEADER_DIR}/internal/catch_reporter_registry.cpp
${HEADER_DIR}/internal/catch_result_type.cpp
${HEADER_DIR}/internal/catch_run_context.cpp
${HEADER_DIR}/internal/catch_section.cpp
${HEADER_DIR}/internal/catch_section_info.cpp
${HEADER_DIR}/internal/catch_session.cpp
${HEADER_DIR}/internal/catch_startup_exception_registry.cpp
${HEADER_DIR}/internal/catch_stream.cpp
${HEADER_DIR}/internal/catch_stringref.cpp
${HEADER_DIR}/internal/catch_string_manip.cpp
${HEADER_DIR}/internal/catch_tag_alias.cpp
${HEADER_DIR}/internal/catch_tag_alias_autoregistrar.cpp
${HEADER_DIR}/internal/catch_tag_alias_registry.cpp
${HEADER_DIR}/internal/catch_test_case_info.cpp
${HEADER_DIR}/internal/catch_test_case_registry_impl.cpp
${HEADER_DIR}/internal/catch_test_case_tracker.cpp
${HEADER_DIR}/internal/catch_test_registry.cpp
${HEADER_DIR}/internal/catch_test_spec.cpp
${HEADER_DIR}/internal/catch_test_spec_parser.cpp
${HEADER_DIR}/internal/catch_timer.cpp
${HEADER_DIR}/internal/catch_tostring.cpp
${HEADER_DIR}/internal/catch_totals.cpp
${HEADER_DIR}/internal/catch_uncaught_exceptions.cpp
${HEADER_DIR}/internal/catch_version.cpp
${HEADER_DIR}/internal/catch_wildcard_pattern.cpp
${HEADER_DIR}/internal/catch_xmlwriter.cpp
)
set(INTERNAL_FILES ${IMPL_SOURCES} ${INTERNAL_HEADERS})
CheckFileList(INTERNAL_FILES ${HEADER_DIR}/internal)
# Please keep these ordered alphabetically
set(REPORTER_HEADERS
${HEADER_DIR}/reporters/catch_reporter_automake.hpp
${HEADER_DIR}/reporters/catch_reporter_bases.hpp
${HEADER_DIR}/reporters/catch_reporter_compact.h
${HEADER_DIR}/reporters/catch_reporter_console.h
${HEADER_DIR}/reporters/catch_reporter_junit.h
${HEADER_DIR}/reporters/catch_reporter_multi.h
${HEADER_DIR}/reporters/catch_reporter_tap.hpp
${HEADER_DIR}/reporters/catch_reporter_teamcity.hpp
${HEADER_DIR}/reporters/catch_reporter_xml.h
)
set(REPORTER_SOURCES
${HEADER_DIR}/reporters/catch_reporter_bases.cpp
${HEADER_DIR}/reporters/catch_reporter_compact.cpp
${HEADER_DIR}/reporters/catch_reporter_console.cpp
${HEADER_DIR}/reporters/catch_reporter_junit.cpp
${HEADER_DIR}/reporters/catch_reporter_multi.cpp
${HEADER_DIR}/reporters/catch_reporter_xml.cpp
)
set(REPORTER_FILES ${REPORTER_HEADERS} ${REPORTER_SOURCES})
CheckFileList(REPORTER_FILES ${HEADER_DIR}/reporters)
# Specify the headers, too, so CLion recognises them as project files
set(HEADERS
${TOP_LEVEL_HEADERS}
${EXTERNAL_HEADERS}
${INTERNAL_HEADERS}
${REPORTER_HEADERS}
)
# Provide some groupings for IDEs
SOURCE_GROUP("Tests" FILES ${TEST_SOURCES})
SOURCE_GROUP("Surrogates" FILES ${SURROGATE_SOURCES})
# Projects consuming Catch via ExternalProject_Add might want to use install step
# without building all of our selftests.
if(DEFINED NO_SELFTEST)
message(DEPRECATION "*** CMake option NO_SELFTEST is deprecated; use BUILD_TESTING instead")
if (NO_SELFTEST)
set(BUILD_TESTING OFF CACHE BOOL "Disable Catch2 internal testsuite" FORCE)
else()
set(BUILD_TESTING ON CACHE BOOL "Disable Catch2 internal testsuite" FORCE)
endif()
endif()
include(CTest)
if (BUILD_TESTING AND NOT_SUBPROJECT)
add_executable(SelfTest ${TEST_SOURCES} ${IMPL_SOURCES} ${REPORTER_SOURCES} ${SURROGATE_SOURCES} ${HEADERS})
target_include_directories(SelfTest PRIVATE ${HEADER_DIR})
if(USE_CPP14)
message(STATUS "Enabling C++14")
set_property(TARGET SelfTest PROPERTY CXX_STANDARD 14)
else()
message(STATUS "Enabling C++11")
set_property(TARGET SelfTest PROPERTY CXX_STANDARD 11)
endif()
set_property(TARGET SelfTest PROPERTY CXX_STANDARD_REQUIRED ON)
set_property(TARGET SelfTest PROPERTY CXX_EXTENSIONS OFF)
if (CATCH_ENABLE_COVERAGE)
set(ENABLE_COVERAGE ON CACHE BOOL "Enable coverage build." FORCE)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
find_package(codecov)
add_coverage(SelfTest)
list(APPEND LCOV_REMOVE_PATTERNS "'/usr/*'")
coverage_evaluate()
endif()
# Add per compiler options
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
target_compile_options( SelfTest PRIVATE -Wall -Wextra -Wunreachable-code -Wpedantic)
if (CATCH_ENABLE_WERROR)
target_compile_options( SelfTest PRIVATE -Werror)
endif()
endif()
# Clang specific options go here
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
target_compile_options( SelfTest PRIVATE -Wweak-vtables -Wexit-time-destructors -Wglobal-constructors -Wmissing-noreturn )
endif()
if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
STRING(REGEX REPLACE "/W[0-9]" "/W4" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) # override default warning level
target_compile_options( SelfTest PRIVATE /w44265 /w44061 /w44062 )
if (CATCH_ENABLE_WERROR)
target_compile_options( SelfTest PRIVATE /WX)
endif()
# Force MSVC to consider everything as encoded in utf-8
target_compile_options( SelfTest PRIVATE /utf-8 )
endif()
# configure unit tests via CTest
include(CTest)
add_test(NAME RunTests COMMAND $<TARGET_FILE:SelfTest>)
add_test(NAME ListTests COMMAND $<TARGET_FILE:SelfTest> --list-tests --verbosity high)
set_tests_properties(ListTests PROPERTIES PASS_REGULAR_EXPRESSION "[0-9]+ test cases")
add_test(NAME ListTags COMMAND $<TARGET_FILE:SelfTest> --list-tags)
set_tests_properties(ListTags PROPERTIES PASS_REGULAR_EXPRESSION "[0-9]+ tags")
add_test(NAME ListReporters COMMAND $<TARGET_FILE:SelfTest> --list-reporters)
set_tests_properties(ListReporters PROPERTIES PASS_REGULAR_EXPRESSION "Available reporters:")
add_test(NAME ListTestNamesOnly COMMAND $<TARGET_FILE:SelfTest> --list-test-names-only)
set_tests_properties(ListTestNamesOnly PROPERTIES PASS_REGULAR_EXPRESSION "Regex string matcher")
# AppVeyor has a Python 2.7 in path, but doesn't have .py files as autorunnable
add_test(NAME ApprovalTests COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/scripts/approvalTests.py $<TARGET_FILE:SelfTest>)
set_tests_properties(ApprovalTests PROPERTIES FAIL_REGULAR_EXPRESSION "Results differed")
if (CATCH_USE_VALGRIND)
add_test(NAME ValgrindRunTests COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest>)
add_test(NAME ValgrindListTests COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest> --list-tests --verbosity high)
set_tests_properties(ValgrindListTests PROPERTIES PASS_REGULAR_EXPRESSION "definitely lost: 0 bytes in 0 blocks")
add_test(NAME ValgrindListTags COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest> --list-tags)
set_tests_properties(ValgrindListTags PROPERTIES PASS_REGULAR_EXPRESSION "definitely lost: 0 bytes in 0 blocks")
endif()
endif() # !NO_SELFTEST
if(CATCH_BUILD_EXAMPLES)
add_subdirectory(examples)
endif()
install(DIRECTORY "single_include/" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/catch")
install(DIRECTORY docs/ DESTINATION "${CMAKE_INSTALL_DOCDIR}")
## Provide some pkg-config integration
# Don't bother on Windows
if(NOT WIN32 OR NOT CMAKE_HOST_SYSTEM_NAME MATCHES Windows)
set(PKGCONFIG_INSTALL_DIR
"${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig"
CACHE PATH "Path where catch.pc is installed"
)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/catch.pc.in ${CMAKE_CURRENT_BINARY_DIR}/catch.pc @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/catch.pc DESTINATION ${PKGCONFIG_INSTALL_DIR})
endif()
# add catch as a 'linkable' target
add_library(Catch INTERFACE)
# depend on some obvious c++11 features so the dependency is transitively added dependants
target_compile_features(Catch INTERFACE cxx_auto_type cxx_constexpr cxx_noexcept)
target_include_directories(Catch
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/single_include>
$<INSTALL_INTERFACE:include/catch>
$<INSTALL_INTERFACE:include>)
# provide a namespaced alias for clients to 'link' against if catch is included as a sub-project
add_library(Catch2::Catch ALIAS Catch)
set(CATCH_CMAKE_CONFIG_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Catch2")
# create and install an export set for catch target as Catch2::Catch
install(TARGETS Catch EXPORT Catch2Config DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(EXPORT Catch2Config
NAMESPACE Catch2::
DESTINATION ${CATCH_CMAKE_CONFIG_DESTINATION})
# install Catch2ConfigVersion.cmake file to handle versions in find_package
include(CMakePackageConfigHelpers)
write_basic_package_version_file(Catch2ConfigVersion.cmake
COMPATIBILITY SameMajorVersion)
install(FILES
"${CMAKE_BINARY_DIR}/Catch2ConfigVersion.cmake"
DESTINATION ${CATCH_CMAKE_CONFIG_DESTINATION})

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,22 +1,36 @@
![catch logo](catch-logo-small.png)
<a id="top"></a>
![catch logo](artwork/catch2-logo-small.png)
*v1.5.7*
[![Github Releases](https://img.shields.io/github/release/catchorg/catch2.svg)](https://github.com/catchorg/catch2/releases)
[![Build Status](https://travis-ci.org/catchorg/Catch2.svg?branch=master)](https://travis-ci.org/catchorg/Catch2)
[![Build status](https://ci.appveyor.com/api/projects/status/github/catchorg/Catch2?svg=true)](https://ci.appveyor.com/project/catchorg/catch2)
[![codecov](https://codecov.io/gh/catchorg/Catch2/branch/master/graph/badge.svg)](https://codecov.io/gh/catchorg/Catch2)
[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/6O2wo5BOvVeUeKQe)
Build status (on Travis CI) [![Build Status](https://travis-ci.org/philsquared/Catch.png)](https://travis-ci.org/philsquared/Catch)
<a href="https://github.com/catchorg/Catch2/releases/download/v2.1.2/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
<a href="https://raw.githubusercontent.com/philsquared/Catch/master/single_include/catch.hpp">The latest, single header, version can be downloaded directly using this link</a>
## Catch2 is released!
If you've been using an earlier version of Catch, please see the
Breaking Changes section of [the release notes](https://github.com/catchorg/Catch2/releases/tag/v2.0.1)
before moving to Catch2. You might also like to read [this blog post](http://www.levelofindirection.com/journal/2017/11/3/catch2-released.html) for more details.
## What's the Catch?
Catch stands for C++ Automated Test Cases in Headers and is a multi-paradigm automated test framework for C++ and Objective-C (and, maybe, C). It is implemented entirely in a set of header files, but is packaged up as a single header for extra convenience.
Catch2 stands for C++ Automated Test Cases in a Header and is a
multi-paradigm test framework for C++. which also supports Objective-C
(and maybe C).
It is primarily distributed as a single header file, although certain
extensions may require additional headers.
## How to use it
This documentation comprises these three parts:
* [Why do we need yet another C++ Test Framework?](docs/why-catch.md)
* [Tutorial](docs/tutorial.md) - getting started
* [Reference section](docs/Readme.md) - all the details
* [Why do we need yet another C++ Test Framework?](docs/why-catch.md#top)
* [Tutorial](docs/tutorial.md#top) - getting started
* [Reference section](docs/Readme.md#top) - all the details
## More
* Issues and bugs can be raised on the [Issue tracker on GitHub](https://github.com/philsquared/Catch/issues)
* Issues and bugs can be raised on the [Issue tracker on GitHub](https://github.com/catchorg/Catch2/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 Catch2](docs/opensource-users.md#top)

63
appveyor.yml Normal file
View File

@ -0,0 +1,63 @@
# version string format -- This will be overwritten later anyway
version: "{build}"
branches:
except:
- /dev-travis.+/
os:
- Visual Studio 2017
- Visual Studio 2015
environment:
matrix:
- additional_flags: "/permissive- /std:c++latest"
wmain: 0
- additional_flags: ""
wmain: 0
- additional_flags: "/D_UNICODE /DUNICODE"
wmain: 1
matrix:
exclude:
- os: Visual Studio 2015
additional_flags: "/permissive- /std:c++latest"
init:
- git config --global core.autocrlf input
install:
- ps: if (($env:CONFIGURATION) -eq "Debug" ) { python -m pip install codecov }
- ps: if (($env:CONFIGURATION) -eq "Debug" ) { .\misc\installOpenCppCoverage.ps1 }
# Win32 and x64 are CMake-compatible solution platform names.
# This allows us to pass %PLATFORM% to CMake -A.
platform:
- Win32
- x64
# build Configurations, i.e. Debug, Release, etc.
configuration:
- Debug
- Release
#Cmake will autodetect the compiler, but we set the arch
before_build:
- set CXXFLAGS=%additional_flags%
# Indirection because appveyor doesn't handle multiline batch scripts properly
# https://stackoverflow.com/questions/37627248/how-to-split-a-command-over-multiple-lines-in-appveyor-yml/37647169#37647169
# https://help.appveyor.com/discussions/questions/3888-multi-line-cmd-or-powershell-warning-ignore
- cmd: .\misc\appveyorBuildConfigurationScript.bat
# build with MSBuild
build:
project: Build\Catch2.sln # path to Visual Studio solution or project
parallel: true # enable MSBuild parallel builds
verbosity: normal # MSBuild verbosity level {quiet|minimal|normal|detailed}
test_script:
- set CTEST_OUTPUT_ON_FAILURE=1
- cmd: .\misc\appveyorTestRunScript.bat

BIN
artwork/catch2-c-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

6
catch.pc.in Normal file
View File

@ -0,0 +1,6 @@
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
Name: Catch
Description: Testing library for C++
Version: @Catch2_VERSION@
Cflags: -I${includedir}

22
codecov.yml Normal file
View File

@ -0,0 +1,22 @@
coverage:
precision: 2
round: nearest
range: "60...90"
status:
project:
default:
threshold: 2%
codecov:
branch: master
comment:
layout: "diff"
coverage:
ignore:
- "projects/SelfTest"
- "**/catch_reporter_tap.hpp"
- "**/catch_reporter_automake.hpp"
- "**/catch_reporter_teamcity.hpp"
- "**/external/clara.hpp"

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 = "2.1.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()

175
contrib/Catch.cmake Normal file
View File

@ -0,0 +1,175 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
Catch
-----
This module defines a function to help use the Catch test framework.
The :command:`catch_discover_tests` discovers tests by asking the compiled test
executable to enumerate its tests. This does not require CMake to be re-run
when tests change. However, it may not work in a cross-compiling environment,
and setting test properties is less convenient.
This command is intended to replace use of :command:`add_test` to register
tests, and will create a separate CTest test for each Catch test case. Note
that this is in some cases less efficient, as common set-up and tear-down logic
cannot be shared by multiple test cases executing in the same instance.
However, it provides more fine-grained pass/fail information to CTest, which is
usually considered as more beneficial. By default, the CTest test name is the
same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``.
.. command:: catch_discover_tests
Automatically add tests with CTest by querying the compiled test executable
for available tests::
catch_discover_tests(target
[TEST_SPEC arg1...]
[EXTRA_ARGS arg1...]
[WORKING_DIRECTORY dir]
[TEST_PREFIX prefix]
[TEST_SUFFIX suffix]
[PROPERTIES name1 value1...]
[TEST_LIST var]
)
``catch_discover_tests`` sets up a post-build command on the test executable
that generates the list of tests by parsing the output from running the test
with the ``--list-test-names-only`` argument. This ensures that the full
list of tests is obtained. Since test discovery occurs at build time, it is
not necessary to re-run CMake when the list of tests changes.
However, it requires that :prop_tgt:`CROSSCOMPILING_EMULATOR` is properly set
in order to function in a cross-compiling environment.
Additionally, setting properties on tests is somewhat less convenient, since
the tests are not available at CMake time. Additional test properties may be
assigned to the set of tests as a whole using the ``PROPERTIES`` option. If
more fine-grained test control is needed, custom content may be provided
through an external CTest script using the :prop_dir:`TEST_INCLUDE_FILES`
directory property. The set of discovered tests is made accessible to such a
script via the ``<target>_TESTS`` variable.
The options are:
``target``
Specifies the Catch executable, which must be a known CMake executable
target. CMake will substitute the location of the built executable when
running the test.
``TEST_SPEC arg1...``
Specifies test cases, wildcarded test cases, tags and tag expressions to
pass to the Catch executable with the ``--list-test-names-only`` argument.
``EXTRA_ARGS arg1...``
Any extra arguments to pass on the command line to each test case.
``WORKING_DIRECTORY dir``
Specifies the directory in which to run the discovered test cases. If this
option is not provided, the current binary directory is used.
``TEST_PREFIX prefix``
Specifies a ``prefix`` to be prepended to the name of each discovered test
case. This can be useful when the same test executable is being used in
multiple calls to ``catch_discover_tests()`` but with different
``TEST_SPEC`` or ``EXTRA_ARGS``.
``TEST_SUFFIX suffix``
Similar to ``TEST_PREFIX`` except the ``suffix`` is appended to the name of
every discovered test case. Both ``TEST_PREFIX`` and ``TEST_SUFFIX`` may
be specified.
``PROPERTIES name1 value1...``
Specifies additional properties to be set on all tests discovered by this
invocation of ``catch_discover_tests``.
``TEST_LIST var``
Make the list of tests available in the variable ``var``, rather than the
default ``<target>_TESTS``. This can be useful when the same test
executable is being used in multiple calls to ``catch_discover_tests()``.
Note that this variable is only available in CTest.
#]=======================================================================]
#------------------------------------------------------------------------------
function(catch_discover_tests TARGET)
cmake_parse_arguments(
""
""
"TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST"
"TEST_SPEC;EXTRA_ARGS;PROPERTIES"
${ARGN}
)
if(NOT _WORKING_DIRECTORY)
set(_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
endif()
if(NOT _TEST_LIST)
set(_TEST_LIST ${TARGET}_TESTS)
endif()
## Generate a unique name based on the extra arguments
string(SHA1 args_hash "${_TEST_SPEC} ${_EXTRA_ARGS}")
string(SUBSTRING ${args_hash} 0 7 args_hash)
# Define rule to generate test list for aforementioned test executable
set(ctest_include_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_include-${args_hash}.cmake")
set(ctest_tests_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_tests-${args_hash}.cmake")
get_property(crosscompiling_emulator
TARGET ${TARGET}
PROPERTY CROSSCOMPILING_EMULATOR
)
add_custom_command(
TARGET ${TARGET} POST_BUILD
BYPRODUCTS "${ctest_tests_file}"
COMMAND "${CMAKE_COMMAND}"
-D "TEST_TARGET=${TARGET}"
-D "TEST_EXECUTABLE=$<TARGET_FILE:${TARGET}>"
-D "TEST_EXECUTOR=${crosscompiling_emulator}"
-D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}"
-D "TEST_SPEC=${_TEST_SPEC}"
-D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}"
-D "TEST_PROPERTIES=${_PROPERTIES}"
-D "TEST_PREFIX=${_TEST_PREFIX}"
-D "TEST_SUFFIX=${_TEST_SUFFIX}"
-D "TEST_LIST=${_TEST_LIST}"
-D "CTEST_FILE=${ctest_tests_file}"
-P "${_CATCH_DISCOVER_TESTS_SCRIPT}"
VERBATIM
)
file(WRITE "${ctest_include_file}"
"if(EXISTS \"${ctest_tests_file}\")\n"
" include(\"${ctest_tests_file}\")\n"
"else()\n"
" add_test(${TARGET}_NOT_BUILT-${args_hash} ${TARGET}_NOT_BUILT-${args_hash})\n"
"endif()\n"
)
if(NOT ${CMAKE_VERSION} VERSION_LESS "3.10.0")
# Add discovered tests to directory TEST_INCLUDE_FILES
set_property(DIRECTORY
APPEND PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}"
)
else()
# Add discovered tests as directory TEST_INCLUDE_FILE if possible
get_property(test_include_file_set DIRECTORY PROPERTY TEST_INCLUDE_FILE SET)
if (NOT ${test_include_file_set})
set_property(DIRECTORY
PROPERTY TEST_INCLUDE_FILE "${ctest_include_file}"
)
else()
message(FATAL_ERROR
"Cannot set more than one TEST_INCLUDE_FILE"
)
endif()
endif()
endfunction()
###############################################################################
set(_CATCH_DISCOVER_TESTS_SCRIPT
${CMAKE_CURRENT_LIST_DIR}/CatchAddTests.cmake
)

View File

@ -0,0 +1,77 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
set(prefix "${TEST_PREFIX}")
set(suffix "${TEST_SUFFIX}")
set(spec ${TEST_SPEC})
set(extra_args ${TEST_EXTRA_ARGS})
set(properties ${TEST_PROPERTIES})
set(script)
set(suite)
set(tests)
function(add_command NAME)
set(_args "")
foreach(_arg ${ARGN})
if(_arg MATCHES "[^-./:a-zA-Z0-9_]")
set(_args "${_args} [==[${_arg}]==]") # form a bracket_argument
else()
set(_args "${_args} ${_arg}")
endif()
endforeach()
set(script "${script}${NAME}(${_args})\n" PARENT_SCOPE)
endfunction()
# Run test executable to get list of available tests
if(NOT EXISTS "${TEST_EXECUTABLE}")
message(FATAL_ERROR
"Specified test executable '${TEST_EXECUTABLE}' does not exist"
)
endif()
execute_process(
COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-test-names-only
OUTPUT_VARIABLE output
RESULT_VARIABLE result
)
# Catch --list-test-names-only reports the number of tests, so 0 is... surprising
if(${result} EQUAL 0)
message(WARNING
"Test executable '${TEST_EXECUTABLE}' contains no tests!\n"
)
elseif(${result} LESS 0)
message(FATAL_ERROR
"Error running test executable '${TEST_EXECUTABLE}':\n"
" Result: ${result}\n"
" Output: ${output}\n"
)
endif()
string(REPLACE "\n" ";" output "${output}")
# Parse output
foreach(line ${output})
# Test name; strip spaces to get just the name...
string(REGEX REPLACE " +" "" test "${line}")
# ...and add to script
add_command(add_test
"${prefix}${test}${suffix}"
${TEST_EXECUTOR}
"${TEST_EXECUTABLE}"
"${test}"
${extra_args}
)
add_command(set_tests_properties
"${prefix}${test}${suffix}"
PROPERTIES
WORKING_DIRECTORY "${TEST_WORKING_DIR}"
${properties}
)
list(APPEND tests "${prefix}${test}${suffix}")
endforeach()
# Create a list of all discovered tests, which users may use to e.g. set
# properties on the tests
add_command(set ${TEST_LIST} ${tests})
# Write CTest script
file(WRITE "${CTEST_FILE}" "${script}")

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

View File

@ -1,5 +1,12 @@
<a id="top"></a>
# Assertion Macros
**Contents**<br>
[Natural Expressions](#natural-expressions)<br>
[Exceptions](#exceptions)<br>
[Matcher expressions](#matcher-expressions)<br>
[Thread Safety](#thread-safety)<br>
Most test frameworks have a large collection of assertion macros to capture all possible conditional forms (```_EQUALS```, ```_NOTEQUALS```, ```_GREATER_THAN``` etc).
Catch is different. Because it decomposes natural C-style conditional expressions most of these forms are reduced to one or two that you will use all the time. That said there are a rich set of auxilliary macros as well. We'll describe all of these here.
@ -14,7 +21,7 @@ The ```CHECK``` family are equivalent but execution continues in the same test c
* **REQUIRE(** _expression_ **)** and
* **CHECK(** _expression_ **)**
Evaluates the expression and records the result. If an exception is thrown it is caught, reported, and counted as a failure. These are the macros you will use most of the time
Evaluates the expression and records the result. If an exception is thrown, it is caught, reported, and counted as a failure. These are the macros you will use most of the time.
Examples:
```
@ -34,6 +41,15 @@ Example:
REQUIRE_FALSE( thisReturnsFalse() );
```
Do note that "overly complex" expressions cannot be decomposed and thus will not compile. This is done partly for practical reasons (to keep the underlying expression template machinery to minimum) and partly for philosophical reasons (assertions should be simple and deterministic).
Examples:
* `CHECK(a == 1 && b == 2);`
This expression is too complex because of the `&&` operator. If you want to check that 2 or more properties hold, you can either put the expression into parenthesis, which stops decomposition from working, or you need to decompose the expression into two assertions: `CHECK( a == 1 ); CHECK( b == 2);`
* `CHECK( a == 2 || b == 1 );`
This expression is too complex because of the `||` operator. If you want to check that one of several properties hold, you can put the expression into parenthesis (unlike with `&&`, expression decomposition into several `CHECK`s is not possible).
### Floating point comparisons
When comparing floating point numbers - especially if at least one of them has been computed - great care must be taken to allow for rounding errors and inexact representations.
@ -44,16 +60,45 @@ Catch provides a way to perform tolerant comparisons of floating point values th
REQUIRE( performComputation() == Approx( 2.1 ) );
```
By default a small epsilon value is used that covers many simple cases of rounding errors. When this is insufficent the epsilon value (the amount within which a difference either way is ignored) can be specified by calling the ```epsilon()``` method on the ```Approx``` instance. e.g.:
This way `Approx` is constructed with reasonable defaults, covering most simple cases of rounding errors. If these are insufficient, each `Approx` instance has 3 tuning knobs, that can be used to customize it for your computation.
```
REQUIRE( 22/7 == Approx( 3.141 ).epsilon( 0.01 ) );
* __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 epsilon's multiplicator. By default set to `0.0`.
#### epsilon example
```cpp
Approx target = Approx(100).epsilon(0.01);
100.0 == target; // Obviously true
200.0 == target; // Obviously still false
100.5 == target; // True, because we set target to allow up to 1% error
```
When dealing with very large or very small numbers it can be useful to specify a scale, which can be achieved by calling the ```scale()``` method on the ```Approx``` instance.
#### margin example
_Margin check is used only if the relative (epsilon and scale based) check fails._
```cpp
Approx target = Approx(100).margin(5);
100.0 == target; // Obviously true
200.0 == target; // Obviously still false
104.0 == target; // True, because we set target to allow absolute error up to 5
```
#### scale
Scale can be useful if the computation leading to the result worked
on different scale than is used by the results. Since allowed difference
between Approx's value and compared value is based primarily on Approx's value
(the allowed difference is computed as
`(Approx::scale + Approx::value) * epsilon`), the resulting comparison could
need rescaling to be correct.
## Exceptions
* **REQUIRE_NOTHROW(** _expression_ **)** and
* **CHECK_NOTHROW(** _expression_ **)**
Expects that no exception is thrown during evaluation of the expression.
* **REQUIRE_THROWS(** _expression_ **)** and
* **CHECK_THROWS(** _expression_ **)**
@ -62,21 +107,54 @@ 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 extended with `const&` and you should not include it yourself.
* **REQUIRE_THROWS_WITH(** _expression_, _string or string matcher_ **)** and
* **CHECK_THROWS_WITH(** _expression_, _string or string matcher_ **)**
Expects that an exception is thrown that, when converted to a string, matches the _string_ or _string matcher_ provided (see next section for Matchers).
e.g.
```cpp
REQUIRE_THROWS_WITH( openThePodBayDoors(), Contains( "afraid" ) && Contains( "can't do that" ) );
REQUIRE_THROWS_WITH( dismantleHal(), "My mind is going" );
```
* **REQUIRE_THROWS_MATCHES(** _expression_, _exception type_, _matcher for given exception type_ **)** and
* **CHECK_THROWS_MATCHES(** _expression_, _exception type_, _matcher for given exception type_ **)**
Expects that exception of _exception type_ is thrown and it matches provided matcher (see next section for Matchers).
_Please note that the `THROW` family of assertions expects to be passed a single expression, not a statement or series of statements. If you want to check a more complicated sequence of operations, you can use a C++11 lambda function._
```cpp
REQUIRE_NOTHROW([&](){
int i = 1;
int j = 2;
auto k = i + j;
if (k == 3) {
throw 1;
}
}());
```
* **REQUIRE_NOTHROW(** _expression_ **)** and
* **CHECK_NOTHROW(** _expression_ **)**
Expects that no exception is thrown during evaluation of the expression.
## Matcher expressions
To support Matchers a slightly different form is used. Matchers will be more fully documented elsewhere. *Note that Matchers are still at early stage development and are subject to change.*
To support Matchers a slightly different form is used. Matchers have [their own documentation](matchers.md#top).
* **REQUIRE_THAT(** _lhs_, _matcher call_ **)** and
* **CHECK_THAT(** _lhs_, _matcher call_ **)**
* **REQUIRE_THAT(** _lhs_, _matcher expression_ **)** and
* **CHECK_THAT(** _lhs_, _matcher expression_ **)**
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#top)

View File

@ -1,23 +1,24 @@
# Integration with build systems
<a id="top"></a>
# 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.
# Continuous Integration systems
## Continuous Integration systems
Probably the most important aspect to using Catch with a build server is the use of different reporters. Catch comes bundled with three reporters that should cover the majority of build servers out there - although adding more for better integration with some is always a possibility (as has been done with TeamCity).
Probably the most important aspect to using Catch with a build server is the use of different reporters. Catch comes bundled with three reporters that should cover the majority of build servers out there - although adding more for better integration with some is always a possibility (currently we also offer TeamCity, TAP and Automake reporters).
Two of these reporters are built in (XML and JUnit) and the third (TeamCity) is included as a separate header. It's possible that the other two may be split out in the future too - as that would make the core of Catch smaller for those that don't need them.
## XML Reporter
### XML Reporter
```-r xml```
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
### JUnit Reporter
```-r junit```
The JUnit Reporter writes in an XML format that mimics the JUnit ANT schema.
@ -26,29 +27,72 @@ The advantage of this format is that the JUnit Ant schema is widely understood b
The disadvantage is that this schema was designed to correspond to how JUnit works - and there is a significant mismatch with how Catch works. Additionally the format is not streamable (because opening elements hold counts of failed and passing tests as attributes) - so the whole test run must complete before it can be written.
## TeamCity Reporter
```-r teamcity```
## Other reporters
Other reporters are not part of the single-header distribution and need
to be downloaded and included separately. All reporters are stored in
`single_include` directory in the git repository, and are named
`catch_reporter_*.hpp`. For example, to use the TeamCity reporter you
need to download `single_include/catch_reporter_teamcity.hpp` and include
it after Catch itself.
The TeamCity Reporter writes TeamCity service messages to stdout. In order to be able to use this reporter an additional header must also be included.
```catch_reporter_teamcity.hpp``` can be found in the ```include\reporters``` directory. It should be included in the same file that ```#define```s ```CATCH_CONFIG_MAIN``` or ```CATCH_CONFIG_RUNNER```. The ```#include``` should be placed after ```#include```ing Catch itself.
e.g.:
```
```cpp
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
#include "catch_reporter_teamcity.hpp"
```
### TeamCity Reporter
```-r teamcity```
The TeamCity Reporter writes TeamCity service messages to stdout. In order to be able to use this reporter an additional header must also be included.
Being specific to TeamCity this is the best reporter to use with it - but it is completely unsuitable for any other purpose. It is a streaming format (it writes as it goes) - although test results don't appear in the TeamCity interface until the completion of a suite (usually the whole test run).
# Low-level tools
### Automake Reporter
```-r automake```
## CMake
The Automake Reporter writes out the [meta tags](https://www.gnu.org/software/automake/manual/html_node/Log-files-generation-and-test-results-recording.html#Log-files-generation-and-test-results-recording) expected by automake via `make check`.
You can use the following CMake script to automatically fetch Catch from github and configure it as an external project:
### TAP (Test Anything Protocol) Reporter
```-r tap```
Because of the incremental nature of Catch's test suites and ability to run specific tests, our implementation of TAP reporter writes out the number of tests in a suite last.
## Low-level tools
### Precompiled headers (PCHs)
Catch offers prototypal support for being included in precompiled headers, but because of its single-header nature it does need some actions by the user:
* The precompiled header needs to define `CATCH_CONFIG_ALL_PARTS`
* The implementation file needs to
* undefine `TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED`
* define `CATCH_CONFIG_IMPL_ONLY`
* define `CATCH_CONFIG_MAIN` or `CATCH_CONFIG_RUNNER`
* include "catch.hpp" again
### CMake
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)
@ -69,7 +113,7 @@ ExternalProject_Add(
# Expose required variable (CATCH_INCLUDE_DIR) to parent scope
ExternalProject_Get_Property(catch source_dir)
set(CATCH_INCLUDE_DIR ${source_dir}/include CACHE INTERNAL "Path to include folder for Catch")
set(CATCH_INCLUDE_DIR ${source_dir}/single_include CACHE INTERNAL "Path to include folder for Catch")
```
If you put it in, e.g., `${PROJECT_SRC_DIR}/${EXT_PROJECTS_DIR}/catch/`, you can use it in your project by adding the following to your root CMake file:
@ -81,6 +125,51 @@ 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
We provide 2 CMake scripts that can automatically register Catch-based
tests with CTest,
* `contrib/ParseAndAddCatchTests.cmake`
* `contrib/CatchAddTests.cmake`
The first is based on parsing the test implementation files, and attempts
to register all `TEST_CASE`s using their 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 4 CTest labels would be created, `a`, `b`, `c` and `unit`.
The second is based on parsing the output of a Catch binary given
`--list-test-names-only`. This means that it deals with inactive
(e.g. commented-out) tests better, but requires CMake 3.10 for full
functionality.
### 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#top)

View File

@ -1,3 +1,30 @@
<a id="top"></a>
# Command line
**Contents**<br>
[Specifying which tests to run](#specifying-which-tests-to-run)<br>
[Choosing a reporter to use](#choosing-a-reporter-to-use)<br>
[Breaking into the debugger](#breaking-into-the-debugger)<br>
[Showing results for successful tests](#showing-results-for-successful-tests)<br>
[Aborting after a certain number of failures](#aborting-after-a-certain-number-of-failures)<br>
[Listing available tests, tags or reporters](#listing-available-tests-tags-or-reporters)<br>
[Sending output to a file](#sending-output-to-a-file)<br>
[Naming a test run](#naming-a-test-run)<br>
[Eliding assertions expected to throw](#eliding-assertions-expected-to-throw)<br>
[Make whitespace visible](#make-whitespace-visible)<br>
[Warnings](#warnings)<br>
[Reporting timings](#reporting-timings)<br>
[Load test names to run from a file](#load-test-names-to-run-from-a-file)<br>
[Just test names](#just-test-names)<br>
[Specify the order test cases are run](#specify-the-order-test-cases-are-run)<br>
[Specify a seed for the Random Number Generator](#specify-a-seed-for-the-random-number-generator)<br>
[Identify framework and version according to the libIdentify standard](#identify-framework-and-version-according-to-the-libidentify-standard)<br>
[Wait for key before continuing](#wait-for-key-before-continuing)<br>
[Specify multiples of clock resolution to run benchmarks for](#specify-multiples-of-clock-resolution-to-run-benchmarks-for)<br>
[Usage](#usage)<br>
[Specify the section to run](#specify-the-section-to-run)<br>
[Filenames as tags](#filenames-as-tags)<br>
Catch works quite nicely without any command line options at all - but for those times when you want greater control the following options are available.
Click one of the followings links to take you straight to that option - or scroll on to browse the available options.
@ -17,6 +44,9 @@ Click one of the followings links to take you straight to that option - or scrol
<a href="#warnings"> ` -w, --warn`</a><br />
<a href="#reporting-timings"> ` -d, --durations`</a><br />
<a href="#input-file"> ` -f, --input-file`</a><br />
<a href="#run-section"> ` -c, --section`</a><br />
<a href="#filenames-as-tags"> ` -#, --filenames-as-tags`</a><br />
</br>
@ -24,6 +54,9 @@ 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 />
<a href="#benchmark-resolution-multiple"> ` --benchmark-resolution-multiple`</a><br />
</br>
@ -66,6 +99,8 @@ A series of tags form an AND expression wheras a comma-separated sequence forms
<pre>[one][two],[three]</pre>
This matches all tests tagged `[one]` and `[two]`, as well as all tests tagged `[three]`
Test names containing special characters, such as `,` or `[` can specify them on the command line using `\`.
`\` also escapes itself.
<a id="choosing-a-reporter-to-use"></a>
## Choosing a reporter to use
@ -88,7 +123,6 @@ The JUnit reporter is an xml format that follows the structure of the JUnit XML
<pre>-b, --break</pre>
In some IDEs (currently XCode and Visual Studio) it is possible for Catch to break into the debugger on a test failure. This can be very helpful during debug sessions - especially when there is more than one path through a particular test.
In addition to the command line option, ensure you have built your code with the DEBUG preprocessor symbol
<a id="showing-results-for-successful-tests"></a>
## Showing results for successful tests
@ -115,7 +149,7 @@ Sometimes this results in a flood of failure messages and you'd rather just see
--list-reporters
</pre>
```-l``` or ```--list-tests`` will list all registered tests, along with any tags.
```-l``` or ```--list-tests``` will list all registered tests, along with any tags.
If one or more test-specs have been supplied too then only the matching tests will be listed.
```-t``` or ```--list-tags``` lists all available tags, along with the number of test cases they match. Again, supplying test specs limits the tags that match.
@ -209,12 +243,86 @@ 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="benchmark-resolution-multiple"></a>
## Specify multiples of clock resolution to run benchmarks for
<pre>--benchmark-resolution-multiple &lt;multiplier&gt;</pre>
When running benchmarks the clock resolution is estimated. Benchmarks are then run for exponentially increasing
numbers of iterations until some multiple of the estimated resolution is exceed. By default that multiple is 100, but
it can be overriden here.
<a id="usage"></a>
## Usage
<pre>-h, -?, --help</pre>
Prints the command line arguments to stdout
<a id="run-section"></a>
## Specify the section to run
<pre>-c, --section &lt;section name&gt;</pre>
To limit execution to a specific section within a test case, use this option one or more times.
To narrow to sub-sections use multiple instances, where each subsequent instance specifies a deeper nesting level.
E.g. if you have:
<pre>
TEST_CASE( "Test" ) {
SECTION( "sa" ) {
SECTION( "sb" ) {
/*...*/
}
SECTION( "sc" ) {
/*...*/
}
}
SECTION( "sd" ) {
/*...*/
}
}
</pre>
Then you can run `sb` with:
<pre>./MyExe Test -c sa -c sb</pre>
Or run just `sd` with:
<pre>./MyExe Test -c sd</pre>
To run all of `sa`, including `sb` and `sc` use:
<pre>./MyExe Test -c sa</pre>
There are some limitations of this feature to be aware of:
- Code outside of sections being skipped will still be executed - e.g. any set-up code in the TEST_CASE before the
start of the first section.</br>
- At time of writing, wildcards are not supported in section names.
- If you specify a section without narrowing to a test case first then all test cases will be executed
(but only matching sections within them).
<a id="filenames-as-tags"></a>
## Filenames as tags
<pre>-#, --filenames-as-tags</pre>
When this option is used then every test is given an additional tag which is formed of the unqualified
filename it is found in, with any extension stripped, prefixed with the `#` character.
So, for example, tests within the file `~\Dev\MyProject\Ferrets.cpp` would be tagged `[#Ferrets]`.
---
[Home](Readme.md)
[Home](Readme.md#top)

17
docs/commercial-users.md Normal file
View File

@ -0,0 +1,17 @@
<a id="top"></a>
# Commercial users of Catch
As well as [Open Source](opensource-users.md#top) 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).
- Bloomberg
- NASA
- [Inscopix Inc.](https://www.inscopix.com/)

View File

@ -1,22 +1,43 @@
<a id="top"></a>
# Compile-time configuration
**Contents**<br>
[main()/ implementation](#main-implementation)<br>
[Prefixing Catch macros](#prefixing-catch-macros)<br>
[Terminal colour](#terminal-colour)<br>
[Console width](#console-width)<br>
[stdout](#stdout)<br>
[Other toggles](#other-toggles)<br>
[Windows header clutter](#windows-header-clutter)<br>
[Enabling stringification](#enabling-stringification)<br>
Catch is designed to "just work" as much as possible. For most people the only configuration needed is telling Catch which source file should host all the implementation code (```CATCH_CONFIG_MAIN```).
Nonetheless there are still some occasions where finer control is needed. For these occasions Catch exposes a small set of macros for configuring how it is built.
Nonetheless there are still some occasions where finer control is needed. For these occasions Catch exposes a set of macros for configuring how it is built.
# main()/ implementation
## main()/ implementation
CATCH_CONFIG_MAIN // Designates this as implementation file and defines main()
CATCH_CONFIG_RUNNER // Designates this as implementation file
Although Catch is header only it still, internally, maintains a distinction between interface headers and headers that contain implementation. Only one source file in your test project should compile the implementation headers and this is controlled through the use of one of these macros - one of these identifiers should be defined before including Catch in *exactly one implementation file in your project*.
# Prefixing Catch macros
# Reporter / Listener interfaces
CATCH_CONFIG_EXTERNAL_INTERFACES // Brings in neccessary headers for Reporter/Listener implementation
Brings in various parts of Catch that are required for user defined Reporters and Listeners. This means that new Reporters and Listeners can be defined in this file as well as in the main file.
Implied by both `CATCH_CONFIG_MAIN` and `CATCH_CONFIG_RUNNER`.
## Prefixing Catch macros
CATCH_CONFIG_PREFIX_ALL
To keep test code clean and uncluttered Catch uses short macro names (e.g. ```TEST_CASE``` and ```REQUIRE```). Occasionally these may conflict with identifiers from platform headers or the system under test. In this case the above identifier can be defined. This will cause all the Catch user macros to be prefixed with ```CATCH_``` (e.g. ```CATCH_TEST_CASE``` and ```CATCH_REQUIRE```).
# Terminal colour
## Terminal colour
CATCH_CONFIG_COLOUR_NONE // completely disables all text colouring
CATCH_CONFIG_COLOUR_WINDOWS // forces the Win32 console API to be used
@ -32,42 +53,86 @@ Note that when ANSI colour codes are used "unistd.h" must be includable - along
Typically you should place the ```#define``` before #including "catch.hpp" in your main source file - but if you prefer you can define it for your whole project by whatever your IDE or build system provides for you to do so.
# Console width
## Console width
CATCH_CONFIG_CONSOLE_WIDTH = x // where x is a number
Catch formats output intended for the console to fit within a fixed number of characters. This is especially important as indentation is used extensively and uncontrolled line wraps break this.
By default a console width of 80 is assumed but this can be controlled by defining the above identifier to be a different value.
# stdout
## stdout
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.
# 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 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.
You may also suppress any of these features by using the `_NO_` form, e.g. `CATCH_CONFIG_CPP11_NO_NULLPTR`.
## 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 (rather minor) features for compilation speed
CATCH_CONFIG_DISABLE_MATCHERS // Do not compile Matchers in this compilation unit
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
CATCH_CONFIG_DISABLE // Disables assertions and test case registration
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.
`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.
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*.
* Non-exception family of macros ({`REQUIRE`,`CHECK`}{`_`,`_FALSE`, `_FALSE`}, no longer use local try-cache 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_MATCHERS`
When `CATCH_CONFIG_DISABLE_MATCHERS` is defined, all mentions of Catch's Matchers are ifdef-ed away from the translation unit. Doing so will speed up compilation of that TU.
_Note: If you define `CATCH_CONFIG_DISABLE_MATCHERS` in the same file as Catch's main is implemented, your test executable will fail to link if you use Matchers anywhere._
### `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).
### `CATCH_CONFIG_DISABLE`
This toggle removes most of Catch from given file. This means that `TEST_CASE`s are not registered and assertions are turned into no-ops. Useful for keeping tests within implementation files (ie for functions with internal linkage), instead of in external files.
This feature is considered experimental and might change at any point.
_Inspired by Doctest's `DOCTEST_CONFIG_DISABLE`_
## 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:
CATCH_CONFIG_NO_NOMINMAX // Stops Catch from using NOMINMAX macro
CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN // Stops Catch from using WIN32_LEAN_AND_MEAN macro
## Enabling stringification
By default, Catch does not stringify some types from the standard library. This is done to avoid dragging in various standard library headers by default. However, Catch does contain these and can be configured to provide them, using these macros:
CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER // Provide StringMaker specialization for std::pair
CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER // Provide StringMaker specialization for std::tuple
CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER // Provide StringMaker specialization for std::chrono::duration, std::chrono::timepoint
CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS // Defines all of the above
All C++11 support can be disabled with `CATCH_CONFIG_NO_CPP11`
---
[Home](Readme.md)
[Home](Readme.md#top)

View File

@ -1,23 +1,61 @@
<a id="top"></a>
# Contributing to Catch
So you want to contribute something to Catch? That's great! Whether it's a bug fix, a new feature, support for additional compilers - or just a fix to the documentation - all contributions are very welcome and very much appreciated. Of course so are bug reports and other comments and questions.
So you want to contribute something to Catch? That's great! Whether it's a bug fix, a new feature, support for
additional compilers - or just a fix to the documentation - all contributions are very welcome and very much appreciated.
Of course so are bug reports and other comments and questions.
If you are contributing to the code base there are a few simple guidelines to keep in mind. This also includes notes to help you find your way around. As this is liable to drift out of date please raise an issue or, better still, a pull request for this file, if you notice that.
If you are contributing to the code base there are a few simple guidelines to keep in mind. This also includes notes to
help you find your way around. As this is liable to drift out of date please raise an issue or, better still, a pull
request for this file, if you notice that.
## Branches
Ongoing development is on the "develop" branch (if there is one, currently), or on feature branches that are branched off of develop. Please target any pull requests at develop, or, for larger chunks of work, a branch off of develop.
Ongoing development is currently on _master_. At some point an integration branch will be set-up and PRs should target
that - but for now it's all against master. You may see feature branches come and go from time to time, too.
## Directory structure
Users of Catch primarily use the single header version. Maintainers should work with the full source (which is still, primarily, in headers). This can be found in the ```include``` folder, but you may prefer to use one of the IDE project files (for MSVC or XCode). These can be found under ```projects/```*IDE Name*```/```*project name*. A number of contributors have proposed make files, and submitted their own versions. At some point these should be made available too.
_Users_ of Catch primarily use the single header version. _Maintainers_ should work with the full source (which is still,
primarily, in headers). This can be found in the `include` folder. There are a set of test files, currently under
`projects/SelfTest`. The test app can be built via CMake from the `CMakeLists.txt` file in the root, or you can generate
project files for Visual Studio, XCode, and others (instructions in the `projects` folder). If you have access to CLion,
it can work with the CMake file directly.
In addition to the include files and IDE projects there are a number of tests in cpp files. These can all be found in ```projects/SelfTest```. You'll also see a ```SurrogateCpps``` directory in there. This contains a set of cpp files that each ```#include``` a single header. While these files are not essential to compilation they help to keep the implementation headers self-contained. At time of writing this set is not complete but has reasonable coverage. If you add additional headers please try to remember to add a surrogate cpp for it.
As well as the runtime test files you'll also see a `SurrogateCpps` directory under `projects/SelfTest`.
This contains a set of .cpp files that each `#include` a single header.
While these files are not essential to compilation they help to keep the implementation headers self-contained.
At time of writing this set is not complete but has reasonable coverage.
If you add additional headers please try to remember to add a surrogate cpp for it.
The other directories are ```scripts``` which contains a set of python scripts to help in testing Catch as well as generating the single include, and docs, which contains the documentation as a set of markdown files.
The other directories are `scripts` which contains a set of python scripts to help in testing Catch as well as
generating the single include, and `docs`, which contains the documentation as a set of markdown files.
*this document is in-progress...*
__When submitting a pull request please do not include changes to the single include, or to the version number file
as these are managed by the scripts!__
## Testing your changes
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...*
---
[Home](Readme.md)
[Home](Readme.md#top)

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

@ -0,0 +1,75 @@
<a id="top"></a>
# 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
Simply derive a class from `Catch::TestEventListenerBase` and implement the methods you are interested in, either in
the main source file (i.e. the one that defines `CATCH_CONFIG_MAIN` or `CATCH_CONFIG_RUNNER`), or in a
file that defines `CATCH_CONFIG_EXTERNAL_INTERFACES`.
Then register it using `CATCH_REGISTER_LISTENER`.
For example ([complete source code](../examples/210-Evt-EventListeners.cpp)):
```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#top)

129
docs/limitations.md Normal file
View File

@ -0,0 +1,129 @@
<a id="top"></a>
# Known limitations
Catch has some known limitations, that we are not planning to change. Some of these are caused by our desire to support C++98 compilers, some of these are caused by our desire to keep Catch crossplatform, some exist because their priority is seen as low compared to the development effort they would need and some other yet are compiler/runtime bugs.
## Implementation limits
### Sections nested in loops
If you are using `SECTION`s inside loops, you have to create them with different name per loop's iteration. The recommended way to do so is to incorporate the loop's counter into section's name, like so
```cpp
TEST_CASE( "Looped section" ) {
for (char i = '0'; i < '5'; ++i) {
SECTION(std::string("Looped section ") + i) {
SUCCEED( "Everything is OK" );
}
}
}
```
## Features
This section outlines some missing features, what is their status and their possible workarounds.
### Thread safe assertions
Because threading support in standard C++98 is limited (well, non-existent), assertion macros in Catch are not thread safe. This does not mean that you cannot use threads inside Catch's test, but that only single thread can interact with Catch's assertions and other macros.
This means that this is ok
```cpp
std::vector<std::thread> threads;
std::atomic<int> cnt{ 0 };
for (int i = 0; i < 4; ++i) {
threads.emplace_back([&]() {
++cnt; ++cnt; ++cnt; ++cnt;
});
}
for (auto& t : threads) { t.join(); }
REQUIRE(cnt == 16);
```
because only one thread passes the `REQUIRE` macro and this is not
```cpp
std::vector<std::thread> threads;
std::atomic<int> cnt{ 0 };
for (int i = 0; i < 4; ++i) {
threads.emplace_back([&]() {
++cnt; ++cnt; ++cnt; ++cnt;
CHECK(cnt == 16);
});
}
for (auto& t : threads) { t.join(); }
REQUIRE(cnt == 16);
```
_This limitation is highly unlikely to be lifted before Catch 2 is released._
### Process isolation in a test
Catch does not support running tests in isolated (forked) processes. While this might in the future, the fact that Windows does not support forking and only allows full-on process creation and the desire to keep code as similar as possible across platforms, mean that this is likely to take significant development time, that is not currently available.
### Running multiple tests in parallel
Catch's test execution is strictly serial. If you find yourself with a test suite that takes too long to run and you want to make it parallel, there are 2 feasible solutions
* You can split your tests into multiple binaries and then run these binaries in parallel.
* You can have Catch list contained test cases and then run the same test binary multiple times in parallel, passing each instance list of test cases it should run.
Both of these solutions have their problems, but should let you wring parallelism out of your test suite.
## 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 2015 -- Wrong line number reported in debug mode
VS 2015 has a known bug where `__LINE__` macro can be improperly expanded under certain circumstances, while compiling multi-file project in Debug mode.
A workaround is to compile the binary in Release mode.
### Clang/G++ -- skipping leaf sections after an exception
Some versions of `libc++` and `libstdc++` (or their runtimes) have a bug with `std::uncaught_exception()` getting stuck returning `true` after rethrow, even if there are no active exceptions. One such case is this snippet, which skipped the sections "a" and "b", when compiled against `libcxxrt` from master
```cpp
#define CATCH_CONFIG_MAIN
#include <catch.hpp>
TEST_CASE("a") {
CHECK_THROWS(throw 3);
}
TEST_CASE("b") {
int i = 0;
SECTION("a") { i = 1; }
SECTION("b") { i = 2; }
CHECK(i > 0);
}
```
If you are seeing a problem like this, i.e. a weird test paths that trigger only under Clang with `libc++`, or only under very specific version of `libstdc++`, it is very likely you are seeing this. The only known workaround is to use a fixed version of your standard library.
### Clang/G++ -- `Matches` string matcher always returns false
This is a bug in `libstdc++-4.8`, where all matching methods from `<regex>` return false. Since `Matches` uses `<regex>` internally, if the underlying implementation does not work, it doesn't work either.
Workaround: Use newer version of `libstdc++`.

31
docs/list-of-examples.md Normal file
View File

@ -0,0 +1,31 @@
<a id="top"></a>
# List of examples
- Test Case: [Single-file](../examples/010-TestCase.cpp)
- Test Case: [Multiple-file 1](../examples/020-TestCase-1.cpp), [2](../examples/020-TestCase-1.cpp)
- Assertion: [REQUIRE, CHECK](../examples/030-Asn-Require-Check.cpp)
- Assertion: [REQUIRE_THAT and Matchers](../examples/040-Asn-RequireThat.cpp)
- Assertion: [REQUIRE_NO_THROW](../examples/050-Asn-RequireNoThrow.cpp)
- Assertion: [REQUIRE_THROWS](../examples/050-Asn-RequireThrows.cpp)
- Assertion: [REQUIRE_THROWS_AS](../examples/070-Asn-RequireThrowsAs.cpp)
- Assertion: [REQUIRE_THROWS_WITH](../examples/080-Asn-RequireThrowsWith.cpp)
- Assertion: [REQUIRE_THROWS_MATCHES](../examples/090-Asn-RequireThrowsMatches.cpp)
- Fixture: [Sections](../examples/100-Fix-Section.cpp)
- Fixture: [Class-based fixtures](../examples/110-Fix-ClassFixture.cpp)
- BDD: [SCENARIO, GIVEN, WHEN, THEN](../examples/120-Bdd-ScenarioGivenWhenThen.cpp)
- Floating point: [Approx - Comparisons](../examples/130-Fpt-Approx.cpp)
- Logging: [CAPTURE - Capture expression](../examples/140-Log-Capture.cpp)
- Logging: [INFO - Provide information with failure](../examples/150-Log-Info.cpp)
- Logging: [WARN - Issue warning](../examples/160-Log-Warn.cpp)
- Logging: [FAIL, FAIL_CHECK - Issue message and force failure/continue](../examples/170-Log-Fail.cpp)
- Logging: [SUCCEED - Issue message and continue](../examples/180-Log-Succeed.cpp)
- Report: [User-defined type](../examples/190-Rpt-ReportUserDefinedType.cpp)
- Report: [Reporter](../examples/200-Rpt-UserDefinedReporter.cpp)
- Listener: [Listeners](../examples/210-Evt-EventListeners.cpp)
- Configuration: [Provide your own main()](../examples/220-Cfg-OwnMain.cpp)
- Configuration: [Compile-time configuration](../examples/230-Cfg-CompileTimeConfiguration.cpp)
- Configuration: [Run-time configuration](../examples/240-Cfg-RunTimeConfiguration.cpp)
---
[Home](Readme.md#top)

View File

@ -1,6 +1,33 @@
<a id="top"></a>
# 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 +53,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_ **)**
@ -49,4 +80,4 @@ These macros are now deprecated and are just aliases for INFO and CAPTURE (which
---
[Home](Readme.md)
[Home](Readme.md#top)

117
docs/matchers.md Normal file
View File

@ -0,0 +1,117 @@
<a id="top"></a>
# Matchers
Matchers are an alternative way to do assertions which are easily extensible and composable.
This makes them well suited to use with more complex types (such as collections) or your own custom types.
Matchers were first popularised by the [Hamcrest](https://en.wikipedia.org/wiki/Hamcrest) family of frameworks.
## In use
Matchers are introduced with the `REQUIRE_THAT` or `CHECK_THAT` macros, which take two arguments.
The first argument is the thing (object or value) under test. The second part is a match _expression_,
which consists of either a single matcher or one or more matchers combined using `&&`, `||` or `!` operators.
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" ) );
```
The matcher objects can take multiple arguments, allowing more fine tuning.
The built-in string matchers, for example, take a second argument specifying whether the comparison is
case sensitive or not:
```c++
REQUIRE_THAT( str, EndsWith( "as a service", Catch::CaseSensitive::No ) );
```
And matchers can be combined:
```c++
REQUIRE_THAT( str,
EndsWith( "as a service" ) ||
(StartsWith( "Big data" ) && !Contains( "web scale" ) ) );
```
## Built in matchers
Catch currently provides some matchers, they are in the `Catch::Matchers` and `Catch` namespaces.
### String matchers
The string matchers are `StartsWith`, `EndsWith`, `Contains`, `Equals` and `Matches`. The first four match a literal (sub)string against a result, while `Matches` takes and matches an ECMAScript regex. Do note that `Matches` matches the string as a whole, meaning that "abc" will not match against "abcd", but "abc.*" will.
Each of the provided `std::string` matchers also takes an optional second argument, that decides case sensitivity (by-default, they are case sensitive).
### Vector matchers
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.
### Floating point matchers
The floating point matchers are `WithinULP` and `WithinAbs`. `WithinAbs` accepts floating point numbers that are within a certain margin of target. `WithinULP` performs an [ULP](https://en.wikipedia.org/wiki/Unit_in_the_last_place)-based comparison of two floating point numbers and accepts them if they are less than certain number of ULPs apart.
Do note that ULP-based checks only make sense when both compared numbers are of the same type and `WithinULP` will use type of its argument as the target type. This means that `WithinULP(1.f, 1)` will expect to compare `float`s, but `WithinULP(1., 1)` will expect to compare `double`s.
## Custom matchers
It's easy to provide your own matchers to extend Catch or just to work with your own types.
You need to provide two things:
1. A matcher class, derived from `Catch::MatcherBase<T>` - where `T` is the type being tested.
The constructor takes and stores any arguments needed (e.g. something to compare against) and you must
override two methods: `match()` and `describe()`.
2. A simple builder function. This is what is actually called from the test code and allows overloading.
Here's an example for asserting that an integer falls within a given range
(note that it is all inline for the sake of keeping the example short):
```c++
// The matcher class
class IntRange : public Catch::MatcherBase<int> {
int m_begin, m_end;
public:
IntRange( int begin, int end ) : m_begin( begin ), m_end( end ) {}
// Performs the test for this matcher
virtual bool match( int const& i ) const override {
return i >= m_begin && i <= m_end;
}
// Produces a string describing what this matcher does. It should
// include any provided data (the begin/ end in this case) and
// be written as if it were stating a fact (in the output it will be
// preceded by the value under test).
virtual std::string describe() const {
std::ostringstream ss;
ss << "is between " << m_begin << " and " << m_end;
return ss.str();
}
};
// The builder function
inline IntRange IsBetween( int begin, int end ) {
return IntRange( begin, end );
}
// ...
// Usage
TEST_CASE("Integers are within a range")
{
CHECK_THAT( 3, IsBetween( 1, 10 ) );
CHECK_THAT( 100, IsBetween( 1, 10 ) );
}
```
Running this test gives the following in the console:
```
/**/TestFile.cpp:123: FAILED:
CHECK_THAT( 100, IsBetween( 1, 10 ) )
with expansion:
100 is between 1 and 10
```
---
[Home](Readme.md#top)

99
docs/opensource-users.md Normal file
View File

@ -0,0 +1,99 @@
<a id="top"></a>
# Open Source projects using Catch
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.
This page is an attempt to track those projects. Obviously it can never be complete.
This effort largely relies on the maintainers of the projects themselves updating this page and submitting a PR
(or, if you prefer contact one of the maintainers of Catch directly, use the
[forums](https://groups.google.com/forum/?fromgroups#!forum/catch-forum)), or raise an [issue](https://github.com/philsquared/Catch/issues) to let us know).
Of course users of those projects might want to update this page too. That's fine - as long you're confident the project maintainers won't mind.
If you're an Open Source project maintainer and see your project listed here but would rather it wasn't -
just let us know via any of the previously mentioned means - although I'm sure there won't be many who feel that way.
Listing a project here does not imply endorsement and the plan is to keep these ordered alphabetically to avoid an implication of relative importance.
## Libraries & Frameworks
### [Azmq](https://github.com/zeromq/azmq)
Boost Asio style bindings for ZeroMQ
### [ChakraCore](https://github.com/Microsoft/ChakraCore)
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
### [DtCraft](https://github.com/twhuang-uiuc/DtCraft)
A High-performance Cluster Computing Engine
### [forest](https://github.com/xorz57/forest)
Forest is an open-source, template library of tree data structures written in C++11.
### [Fuxedo](https://github.com/fuxedo/fuxedo)
Open source Oracle Tuxedo-like XATMI middleware for C and C++.
### [Inja](https://github.com/pantor/inja)
A header-only template engine for modern C++.
### [JSON for Modern C++](https://github.com/nlohmann/json)
A, single-header, JSON parsing library that takes advantage of what C++ has to offer.
### [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
---
[Home](Readme.md#top)

View File

@ -1,3 +1,4 @@
<a id="top"></a>
# Supplying main() yourself
The easiest way to use Catch is to let it supply ```main()``` for you and handle configuring itself from the command line.
@ -16,8 +17,7 @@ If you just need to have code that executes before and/ or after Catch this is t
#define CATCH_CONFIG_RUNNER
#include "catch.hpp"
int main( int argc, char* const argv[] )
{
int main( int argc, char* argv[] ) {
// global setup...
int result = Catch::Session().run( argc, argv );
@ -36,22 +36,27 @@ If you still want Catch to process the command line, but you want to programatic
#define CATCH_CONFIG_RUNNER
#include "catch.hpp"
int main( int argc, char* const argv[] )
int main( int argc, char* argv[] )
{
Catch::Session session; // There must be exactly once instance
Catch::Session session; // There must be exactly one instance
// writing to session.configData() here sets defaults
// this is the preferred way to set them
int returnCode = session.applyCommandLine( argc, argv );
if( returnCode != 0 ) // Indicates a command line error
return returnCode;
return returnCode;
// writing to session.configData() or session.Config() here
// overrides command line args
// only do this if you know you need to
return session.run();
int numFailed = session.run();
// numFailed is clamped to 255 as some unices only use the lower 8 bits.
// This clamping has already been applied, so just return it here
// You can also do any post run clean-up here
return numFailed;
}
```
@ -61,8 +66,60 @@ To take full control of the config simply omit the call to ```applyCommandLine()
## Adding your own command line options
Catch embeds a powerful command line parser which you can also use to parse your own options out. This capability is still in active development but will be documented here when it is ready.
Catch embeds a powerful command line parser called [Clara](https://github.com/philsquared/Clara).
As of Catch2 (and Clara 1.0) Clara allows you to write _composable_ option and argument parsers,
so extending Catch's own command line options is now easy.
```c++
#define CATCH_CONFIG_RUNNER
#include "catch.hpp"
int main( int argc, char* argv[] )
{
Catch::Session session; // There must be exactly one instance
int height = 0; // Some user variable you want to be able to set
// Build a new parser on top of Catch's
using namespace Catch::clara;
auto cli
= session.cli() // Get Catch's composite command line parser
| Opt( height, "height" ) // bind variable to a new option, with a hint string
["-g"]["--height"] // the option names it will respond to
("how high?"); // description string for the help output
// Now pass the new composite back to Catch so it uses that
session.cli( cli );
// Let Catch (using Clara) parse the command line
int returnCode = session.applyCommandLine( argc, argv );
if( returnCode != 0 ) // Indicates a command line error
return returnCode;
// if set on the command line then 'height' is now set at this point
if( height > 0 )
std::cout << "height: " << height << std::endl;
return session.run();
}
```
See the [Clara documentation](https://github.com/philsquared/Clara/blob/master/README.md) for more details.
## Version detection
Catch provides a triplet of macros providing the header's version,
* `CATCH_VERSION_MAJOR`
* `CATCH_VERSION_MINOR`
* `CATCH_VERSION_PATCH`
these macros expand into a single number, that corresponds to the appropriate
part of the version. As an example, given single header version v2.3.4,
the macros would expand into `2`, `3`, and `4` respectively.
---
[Home](Readme.md)
[Home](Readme.md#top)

501
docs/release-notes.md Normal file
View File

@ -0,0 +1,501 @@
<a id="top"></a>
# 2.1.2
## Fixes
* Fixed compilation error with `-fno-rtti` (#1165)
* Fixed NoAssertion warnings
* `operator<<` is used before range-based stringification (#1172)
* Fixed `-Wpedantic` warnings (extra semicolons and binary literals) (#1173)
## Improvements
* Added `CATCH_VERSION_{MAJOR,MINOR,PATCH}` macros (#1131)
* Added `BrightYellow` colour for use in reporters (#979)
* It is also used by ConsoleReporter for reconstructed expressions
## Other changes
* Catch is now exported as a CMake package and linkable target (#1170)
# 2.1.1
## Improvements
* Static arrays are now properly stringified like ranges across MSVC/GCC/Clang
* Embedded newer version of Clara -- v1.1.1
* This should fix some warnings dragged in from Clara
* MSVC's CLR exceptions are supported
## Fixes
* Fixed compilation when comparison operators do not return bool (#1147)
* Fixed CLR exceptions blowing up the executable during translation (#1138)
## Other changes
* Many CMake changes
* `NO_SELFTEST` option is deprecated, use `BUILD_TESTING` instead.
* Catch specific CMake options were prefixed with `CATCH_` for namespacing purposes
* Other changes to simplify Catch2's packaging
# 2.1.0
## Improvements
* Various performance improvements
* On top of the performance regression fixes
* Experimental support for PCH was added (#1061)
* `CATCH_CONFIG_EXTERNAL_INTERFACES` now brings in declarations of Console, Compact, XML and JUnit reporters
* `MatcherBase` no longer has a pointless second template argument
* Reduced the number of warning suppressions that leak into user's code
* Bugs in g++ 4.x and 5.x mean that some of them have to be left in
## Fixes
* Fixed performance regression from Catch classic
* One of the performance improvement patches for Catch classic was not applied to Catch2
* Fixed platform detection for iOS (#1084)
* Fixed compilation when `g++` is used together with `libc++` (#1110)
* Fixed TeamCity reporter compilation with the single header version
* To fix the underlying issue we will be versioning reporters in single_include folder per release
* The XML reporter will now report `WARN` messages even when not used with `-s`
* Fixed compilation when `VectorContains` matcher was combined using `&&` (#1092)
* Fixed test duration overflowing after 10 seconds (#1125, #1129)
* Fixed `std::uncaught_exception` deprecation warning (#1124)
## New features
* New Matchers
* Regex matcher for strings, `Matches`.
* Set-equal matcher for vectors, `UnorderedEquals`
* Floating point matchers, `WithinAbs` and `WithinULP`.
* Stringification now attempts to decompose all containers (#606)
* Containers are objects that respond to ADL `begin(T)` and `end(T)`.
## Other changes
* Reporters will now be versioned in the `single_include` folder to ensure their compatibility with the last released version
# 2.0.1
## Breaking changes
* Removed C++98 support
* Removed legacy reporter support
* Removed legacy generator support
* Generator support will come back later, reworked
* Removed `Catch::toString` support
* The new stringification machinery uses `Catch::StringMaker` specializations first and `operator<<` overloads second.
* Removed legacy `SCOPED_MSG` and `SCOPED_INFO` macros
* Removed `INTERNAL_CATCH_REGISTER_REPORTER`
* `CATCH_REGISTER_REPORTER` should be used to register reporters
* Removed legacy `[hide]` tag
* `[.]`, `[.foo]` and `[!hide]` are still supported
* Output into debugger is now colourized
* `*_THROWS_AS(expr, exception_type)` now unconditionally appends `const&` to the exception type.
* `CATCH_CONFIG_FAST_COMPILE` now affects the `CHECK_` family of assertions as well as `REQUIRE_` family of assertions
* This is most noticeable in `CHECK(throws())`, which would previously report failure, properly stringify the exception and continue. Now it will report failure and stop executing current section.
* Removed deprecated matcher utility functions `Not`, `AllOf` and `AnyOf`.
* They are superseded by operators `!`, `&&` and `||`, which are natural and do not have limited arity
* Removed support for non-const comparison operators
* Non-const comparison operators are an abomination that should not exist
* They were breaking support for comparing function to function pointer
* `std::pair` and `std::tuple` are no longer stringified by default
* This is done to avoid dragging in `<tuple>` and `<utility>` headers in common path
* Their stringification can be enabled per-file via new configuration macros
* `Approx` is subtly different and hopefully behaves more as users would expect
* `Approx::scale` defaults to `0.0`
* `Approx::epsilon` no longer applies to the larger of the two compared values, but only to the `Approx`'s value
* `INFINITY == Approx(INFINITY)` returns true
## Improvements
* Reporters and Listeners can be defined in files different from the main file
* The file has to define `CATCH_CONFIG_EXTERNAL_INTERFACES` before including catch.hpp.
* Errors that happen during set up before main are now caught and properly reported once main is entered
* If you are providing your own main, you can access and use these as well.
* New assertion macros, *_THROWS_MATCHES(expr, exception_type, matcher) are provided
* As the arguments suggest, these allow you to assert that an expression throws desired type of exception and pass the exception to a matcher.
* JUnit reporter no longer has significantly different output for test cases with and without sections
* Most assertions now support expressions containing commas (ie `REQUIRE(foo() == std::vector<int>{1, 2, 3});`)
* Catch now contains experimental micro benchmarking support
* See `projects/SelfTest/Benchmark.tests.cpp` for examples
* The support being experiment means that it can be changed without prior notice
* Catch uses new CLI parsing library (Clara)
* Users can now easily add new command line options to the final executable
* This also leads to some changes in `Catch::Session` interface
* All parts of matchers can be removed from a TU by defining `CATCH_CONFIG_DISABLE_MATCHERS`
* This can be used to somewhat speed up compilation times
* An experimental implementation of `CATCH_CONFIG_DISABLE` has been added
* Inspired by Doctest's `DOCTEST_CONFIG_DISABLE`
* Useful for implementing tests in source files
* ie for functions in anonymous namespaces
* Removes all assertions
* Prevents `TEST_CASE` registrations
* Exception translators are not registered
* Reporters are not registered
* Listeners are not registered
* Reporters/Listeners are now notified of fatal errors
* This means specific signals or structured exceptions
* The Reporter/Listener interface provides default, empty, implementation to preserve backward compatibility
* Stringification of `std::chrono::duration` and `std::chrono::time_point` is now supported
* Needs to be enabled by a per-file compile time configuration option
* Add `pkg-config` support to CMake install command
## Fixes
* Don't use console colour if running in XCode
* Explicit constructor in reporter base class
* Swept out `-Wweak-vtables`, `-Wexit-time-destructors`, `-Wglobal-constructors` warnings
* Compilation for Universal Windows Platform (UWP) is supported
* SEH handling and colorized output are disabled when compiling for UWP
* Implemented a workaround for `std::uncaught_exception` issues in libcxxrt
* These issues caused incorrect section traversals
* The workaround is only partial, user's test can still trigger the issue by using `throw;` to rethrow an exception
* Suppressed C4061 warning under MSVC
## Internal changes
* The development version now uses .cpp files instead of header files containing implementation.
* This makes partial rebuilds much faster during development
* The expression decomposition layer has been rewritten
* The evaluation layer has been rewritten
* New library (TextFlow) is used for formatting text to output
# Older versions
## 1.11.x
### 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.x
### 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.x
### 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.x
### 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#top).
* 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](matchers.md#top).
* 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 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](build-systems.md#top).
* 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](assertions.md#top).
#### Fixes
* Silenced C4312 ("conversion from int to 'ClassName *") warnings in the evaluate layer.
* Fixed C4512 ("assignment operator could not be generated") warnings under VS2013.
* Cygwin compatibility fixes
* Signal handling is no longer compiled by default.
* Usage of `gettimeofday` inside Catch should no longer cause compilation errors.
* Improved `-Wparentheses` supression for gcc (#674)
* When compiled with gcc 4.8 or newer, the supression is localized to assertions only
* Otherwise it is supressed for the whole TU
* Fixed test spec parser issue (with escapes in multiple names)
#### Other
* Various documentation fixes and improvements
## 1.7.x
### 1.7.2
#### Fixes and minor improvements
Xml:
(technically the first two are breaking changes but are also fixes and arguably break few if any people)
* C-escape control characters instead of XML encoding them (which requires XML 1.1)
* Revert XML output to XML 1.0
* Can provide stylesheet references by extending the XML reporter
* Added description and tags attribites to XML Reporter
* Tags are closed and the stream flushed more eagerly to avoid stdout interpolation
Other:
* `REQUIRE_THROWS_AS` now catches exception by `const&` and reports expected type
* In `SECTION`s the file/ line is now of the `SECTION`. not the `TEST_CASE`
* Added std:: qualification to some functions from C stdlib
* Removed use of RTTI (`dynamic_cast`) that had crept back in
* Silenced a few more warnings in different circumstances
* Travis improvements
### 1.7.1
#### 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](configuration.md#top).
* 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.
* Fixed possible infinite recursion in Windows SEH.
* Fixed possible compilation error caused by Catch's operator overloads being ambiguous in regards to user-defined templated operators.
### 1.7.0
#### Features/ Changes:
* Catch now runs significantly faster for passing tests
* 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](command-line.md#top).
* 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).
* Strong typedefs mean types that are explicitly convertible to double.
* CHECK macro no longer stops executing section if an exception happens.
* Certain characters (space, tab, etc) are now pretty printed.
* This means that a `char c = ' '; REQUIRE(c == '\t');` would be printed as `' ' == '\t'`, instead of ` == 9`.
#### Fixes:
* Text formatting no longer attempts to access out-of-bounds characters under certain conditions.
* THROW family of assertions no longer trigger `-Wunused-value` on expressions containing explicit cast.
* Breaking into debugger under OS X works again and no longer required `DEBUG` to be defined.
* Compilation no longer breaks under certain compiler if a lambda is used inside assertion macro.
#### Other:
* Catch's CMakeLists now defines install command.
* Catch's CMakeLists now generates projects with warnings enabled.
## 1.6.x
### 1.6.1
#### Features/ Changes:
* Catch now supports breaking into debugger on Linux
#### Fixes:
* Generators no longer leak memory (generators are still unsupported in general)
* JUnit reporter now reports UTC timestamps, instead of "tbd"
* `CHECK_THAT` macro is now properly defined as `CATCH_CHECK_THAT` when using `CATCH_` prefixed macros
#### Other:
* Types with overloaded `&&` operator are no longer evaluated twice when used in an assertion macro.
* The use of `__COUNTER__` is supressed when Catch is parsed by CLion
* This change is not active when compiling a binary
* 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](configuration.md#top) for details.
### 1.6.0
#### Cmake/ projects:
* Moved CMakeLists.txt to root, made it friendlier for CLion and generating XCode and VS projects, and removed the manually maintained XCode and VS projects.
#### Features/ Changes:
* Approx now supports `>=` and `<=`
* Can now use `\` to escape chars in test names on command line
* Standardize C++11 feature toggles
#### Fixes:
* Blue shell colour
* Missing argument to `CATCH_CHECK_THROWS`
* Don't encode extended ASCII in XML
* use `std::shuffle` on more compilers (fixes deprecation warning/error)
* Use `__COUNTER__` more consistently (where available)
#### Other:
* Tweaks and changes to scripts - particularly for Approval test - to make them more portable
# Even Older versions
Release notes were not maintained prior to v1.6.0, but you should be able to work them out from the Git history
---
[Home](Readme.md#top)

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

@ -0,0 +1,65 @@
<a id="top"></a>
# 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.
This will take care of generating the single include header, updating
version numbers everywhere and pushing the new version to Wandbox.
### 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. All non-bundled reporters (Automake,
TAP, TeamCity) should also be attached as binaries, as they are dependent
on a specific version of the single-include header.
## Optional steps
The following steps are optional, and do not have to be performed when releasing new version of Catch. However, they *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
```

46
docs/reporters.md Normal file
View File

@ -0,0 +1,46 @@
<a id="top"></a>
# 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.
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 - 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#top)

View File

@ -1,5 +1,12 @@
<a id="top"></a>
# Why do my tests take so long to compile?
**Contents**<br>
[Short answer](#short-answer)<br>
[Long answer](#long-answer)<br>
[Practical example](#practical-example)<br>
[Other possible solutions](#other-possible-solutions)<br>
Several people have reported that test code written with Catch takes much longer to compile than they would expect. Why is that?
Catch is implemented entirely in headers. There is a little overhead due to this - but not as much as you might think - and you can minimise it simply by organising your test code as follows:
@ -17,6 +24,48 @@ Because Catch is implemented *entirely* in headers you might think that the whol
As a result the main source file *does* compile the whole of Catch every time! So it makes sense to dedicate this file to *only* ```#define```-ing the identifier and ```#include```-ing Catch (and implementing the runner code, if you're doing that). Keep all your test cases in other files. This way you won't pay the recompilation cost for the whole of Catch
## Practical example
Assume you have the `Factorial` function from the [tutorial](tutorial.md#top) in `factorial.cpp` (with forward declaration in `factorial.h`) and want to test it and keep the compile times down when adding new tests. Then you should have 2 files, `tests-main.cpp` and `tests-factorial.cpp`:
```cpp
// tests-main.cpp
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
```
```cpp
// tests-factorial.cpp
#include "catch.hpp"
#include "factorial.h"
TEST_CASE( "Factorials are computed", "[factorial]" ) {
REQUIRE( Factorial(1) == 1 );
REQUIRE( Factorial(2) == 2 );
REQUIRE( Factorial(3) == 6 );
REQUIRE( Factorial(10) == 3628800 );
}
```
After compiling `tests-main.cpp` once, it is enough to link it with separately compiled `tests-factorial.cpp`. This means that adding more tests to `tests-factorial.cpp`, will not result in recompiling Catch's main and the resulting compilation times will decrease substantially.
```
$ g++ tests-main.cpp -c
$ g++ tests-main.o tests-factorial.cpp -o tests && ./tests -r compact
Passed 1 test case with 4 assertions.
```
Now, the next time we change the file `tests-factorial.cpp` (say we add `REQUIRE( Factorial(0) == 1)`), it is enough to recompile the tests instead of recompiling main as well:
```
$ g++ tests-main.o tests-factorial.cpp -o tests && ./tests -r compact
tests-factorial.cpp:11: failed: Factorial(0) == 1 for: 0 == 1
Failed 1 test case, failed 1 assertion.
```
## Other possible solutions
You can also opt to sacrifice some features in order to speed-up Catch's compilation times. For details see the [documentation on Catch's compile-time configuration](configuration.md#other-toggles).
---
[Home](Readme.md)
[Home](Readme.md#top)

View File

@ -1,8 +1,9 @@
<a id="top"></a>
# Test cases and sections
While Catch fully supports the traditional, xUnit, style of class-based fixtures containing test case methods this is not the preferred style.
Instead Catch provides a powerful mechanism for nesting test case sections within a test case. For a more detailed discussion see the [tutorial](tutorial.md#testCasesAndSections).
Instead Catch provides a powerful mechanism for nesting test case sections within a test case. For a more detailed discussion see the [tutorial](tutorial.md#test-cases-and-sections).
Test cases and sections are very easy to use in practice:
@ -11,7 +12,7 @@ Test cases and sections are very easy to use in practice:
_test name_ and _section name_ are free form, quoted, strings. The optional _tags_ argument is a quoted string containing one or more tags enclosed in square brackets. Tags are discussed below. Test names must be unique within the Catch executable.
For examples see the [Tutorial](tutorial.md)
For examples see the [Tutorial](tutorial.md#top)
## Tags
@ -28,31 +29,35 @@ 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
All tag names beginning with non-alphanumeric characters are reserved by Catch. Catch defines a number of "special" tags, which have meaning to the test runner itself. These special tags all begin with a symbol character. Following is a list of currently defined special tags and their meanings.
* `[!hide]` or `[.]` (or, for legacy reasons, `[hide]`) - causes test cases to be skipped from the default list (ie when no test cases have been explicitly selected through tag expressions or name wildcards). The hide tag is often combined with another, user, tag (for example `[.][integration]` - so all integration tests are excluded from the default run but can be run by passing `[integration]` on the command line). As a short-cut you can combine these by simply prefixing your user tag with a `.` - e.g. `[.integration]`. Because the hide tag has evolved to have several forms, all forms are added as tags if you use one of them.
* `[!hide]` or `[.]` - causes test cases to be skipped from the default list (i.e. when no test cases have been explicitly selected through tag expressions or name wildcards). The hide tag is often combined with another, user, tag (for example `[.][integration]` - so all integration tests are excluded from the default run but can be run by passing `[integration]` on the command line). As a short-cut you can combine these by simply prefixing your user tag with a `.` - e.g. `[.integration]`. Because the hide tag has evolved to have several forms, all forms are added as tags if you use one of them.
* `[!throws]` - lets Catch know that this test is likely to throw an exception even if successful. This causes the test to be exluded when running with `-e` or `--nothrow`.
* `[!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.
* `[#<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]`.
* `[!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 to all contained tests, e.g. tests in testfile.cpp would all be tagged `[#testfile]`.
* `[@<alias>]` - tag aliases all begin with `@` (see below).
* `[!benchmark]` - this test case is actually a benchmark. This is an experimental feature, and currently has no documentation. If you want to try it out, look at `projects/SelfTest/Benchmark.tests.cpp` for details.
## 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> )
Aliases must begining with the `@` character. An example of a tag alias is:
Aliases must begin with the `@` character. An example of a tag alias is:
CATCH_REGISTER_TAG_ALIAS( "[@nhf]", "[failing]~[.]" )
@ -83,4 +88,4 @@ Other than the additional prefixes and the formatting in the console reporter th
---
[Home](Readme.md)
[Home](Readme.md#top)

View File

@ -1,4 +1,7 @@
Although Catch allows you to group tests together as sections within a test case, it can still convenient, sometimes, to group them using a more traditional test fixture. Catch fully supports this too. You define the test fixture as a simple structure:
<a id="top"></a>
# Test fixtures
Although Catch allows you to group tests together as sections within a test case, it can still be convenient, sometimes, to group them using a more traditional test fixture. Catch fully supports this too. You define the test fixture as a simple structure:
```c++
class UniqueTestsFixture {
@ -29,4 +32,4 @@ The two test cases here will create uniquely-named derived classes of UniqueTest
---
[Home](Readme.md)
[Home](Readme.md#top)

View File

@ -1,7 +1,8 @@
<a id="top"></a>
# String conversions
Catch needs to be able to convert types you use in assertions and logging expressions into strings (for logging and reporting purposes).
Most built-in or std types are supported out of the box but there are three ways that you can tell Catch how to convert your own types (or other, third-party types) into strings.
Most built-in or std types are supported out of the box but there are two ways that you can tell Catch how to convert your own types (or other, third-party types) into strings.
## operator << overload for std::ostream
@ -16,45 +17,39 @@ 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;
}
```
## Catch::toString overload
If you don't want to provide an ```operator <<``` overload, or you want to convert your type differently for testing purposes, you can provide an overload for ```Catch::toString()``` for your type.
```
namespace Catch {
std::string toString( T const& value ) {
return convertMyTypeToString( value );
}
}
```
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.
You should put this function in the same namespace as your type and have it declared before including Catch's header.
## 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:
If you don't want to provide an ```operator <<``` overload, or you want to convert your type differently for testing purposes, you can provide a specialization for `Catch::StringMaker<T>`:
```
namespace Catch {
template<> struct StringMaker<T> {
template<>
struct StringMaker<T> {
static std::string convert( T const& value ) {
return convertMyTypeToString( value );
}
};
return convertMyTypeToString( value );
}
};
}
```
## Catch::is_range<T> specialisation
As a fallback, Catch attempts to detect if the type can be iterated
(`begin(T)` and `end(T)` are valid) and if it can be, it is stringified
as a range. For certain types this can lead to infinite recursion, so
it can be disabled by specializing `Catch::is_range` like so:
```cpp
namespace Catch {
template<>
struct is_range<T> {
static const bool value = false;
};
}
```
## Exceptions
By default all exceptions deriving from `std::exception` will be translated to strings by calling the `what()` method. For exception types that do not derive from `std::exception` - or if `what()` does not return a suitable string - use `CATCH_TRANSLATE_EXCEPTION`. This defines a function that takes your exception type, by reference, and returns a string. It can appear anywhere in the code - it doesn't have to be in the same translation unit. For example:
@ -67,4 +62,4 @@ CATCH_TRANSLATE_EXCEPTION( MyType& ex ) {
---
[Home](Readme.md)
[Home](Readme.md#top)

View File

@ -1,19 +1,31 @@
# Getting Catch
<a id="top"></a>
# Tutorial
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.
**Contents**<br>
[Getting Catch2](#getting-catch2)<br>
[Where to put it?](#where-to-put-it)<br>
[Writing tests](#writing-tests)<br>
[Test cases and sections](#test-cases-and-sections)<br>
[BDD-Style](#bdd-style)<br>
[Scaling up](#scaling-up)<br>
[Next steps](#next-steps)<br>
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.
## Getting Catch2
The simplest way to get Catch2 is to download the latest [single header version](https://raw.githubusercontent.com/CatchOrg/Catch2/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 full source for Catch2, including test projects, documentation, and other things, is hosted on GitHub. [http://catch-lib.net](http://catch-lib.net) will redirect you there.
## Where to put it?
Catch is header only. All you need to do is drop the file(s) somewhere reachable from your project - either in some central location you can set your header search path to find, or directly into your project tree itself! This is a particularly good option for other Open-Source projects that want to use Catch for their test suite. See [this blog entry for more on that](http://www.levelofindirection.com/journal/2011/5/27/unit-testing-in-c-and-objective-c-just-got-ridiculously-easi.html).
Catch2 is header only. All you need to do is drop the file somewhere reachable from your project - either in some central location you can set your header search path to find, or directly into your project tree itself! This is a particularly good option for other Open-Source projects that want to use Catch for their test suite. See [this blog entry for more on that](http://www.levelofindirection.com/journal/2011/5/27/unit-testing-in-c-and-objective-c-just-got-ridiculously-easi.html).
The rest of this tutorial will assume that the Catch single-include header (or the include folder) is available unqualified - but you may need to prefix it with a folder name if necessary.
The rest of this tutorial will assume that the Catch2 single-include header (or the include folder) is available unqualified - but you may need to prefix it with a folder name if necessary.
# Writing tests
## Writing tests
Let's start with a really simple example. Say you have written a function to calculate factorials and now you want to test it (let's leave aside TDD for now).
Let's start with a really simple example ([code](../examples/010-TestCase.cpp)). Say you have written a function to calculate factorials and now you want to test it (let's leave aside TDD for now).
```c++
unsigned int Factorial( unsigned int number ) {
@ -21,7 +33,7 @@ unsigned int Factorial( unsigned int number ) {
}
```
To keep things simple we'll put everything in a single file (<a href="#scaling-up">see later for more on how to structure your test files</a>)
To keep things simple we'll put everything in a single file (<a href="#scaling-up">see later for more on how to structure your test files</a>).
```c++
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
@ -39,7 +51,7 @@ TEST_CASE( "Factorials are computed", "[factorial]" ) {
}
```
This will compile to a complete executable which responds to [command line arguments](command-line.md). If you just run it with no arguments it will execute all test cases (in this case there is just one), report any failures, report a summary of how many tests passed and failed and return the number of failed tests (useful for if you just want a yes/ no answer to: "did it work").
This will compile to a complete executable which responds to [command line arguments](command-line.md#top). If you just run it with no arguments it will execute all test cases (in this case there is just one), report any failures, report a summary of how many tests passed and failed and return the number of failed tests (useful for if you just want a yes/ no answer to: "did it work").
If you run this as written it will pass. Everything is good. Right?
Well, there is still a bug here. In fact the first version of this tutorial I posted here genuinely had the bug in! So it's not completely contrived (thanks to Daryle Walker (```@CTMacUser```) for pointing this out).
@ -68,7 +80,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,14 +92,14 @@ 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?
### What did we do here?
Although this was a simple test it's been enough to demonstrate a few things about how Catch is used. Let's take moment to consider those before we move on.
1. All we did was ```#define``` one identifier and ```#include``` one header and we got everything - even an implementation of ```main()``` that will [respond to command line arguments](command-line.md). You can only use that ```#define``` in one implementation file, for (hopefully) obvious reasons. Once you have more than one file with unit tests in you'll just ```#include "catch.hpp"``` and go. Usually it's a good idea to have a dedicated implementation file that just has ```#define CATCH_CONFIG_MAIN``` and ```#include "catch.hpp"```. You can also provide your own implementation of main and drive Catch yourself (see [Supplying-your-own-main()](own-main.md)).
2. We introduce test cases with the ```TEST_CASE``` macro. This macro takes one or two arguments - a free form test name and, optionally, one or more tags (for more see <a href="#test-cases-and-sections">Test cases and Sections</a>, ). The test name must be unique. You can run sets of tests by specifying a wildcarded test name or a tag expression. See the [command line docs](command-line.md) for more information on running tests.
1. All we did was ```#define``` one identifier and ```#include``` one header and we got everything - even an implementation of ```main()``` that will [respond to command line arguments](command-line.md#top). You can only use that ```#define``` in one implementation file, for (hopefully) obvious reasons. Once you have more than one file with unit tests in you'll just ```#include "catch.hpp"``` and go. Usually it's a good idea to have a dedicated implementation file that just has ```#define CATCH_CONFIG_MAIN``` and ```#include "catch.hpp"```. You can also provide your own implementation of main and drive Catch yourself (see [Supplying-your-own-main()](own-main.md#top)).
2. We introduce test cases with the ```TEST_CASE``` macro. This macro takes one or two arguments - a free form test name and, optionally, one or more tags (for more see <a href="#test-cases-and-sections">Test cases and Sections</a>, ). The test name must be unique. You can run sets of tests by specifying a wildcarded test name or a tag expression. See the [command line docs](command-line.md#top) for more information on running tests.
3. The name and tags arguments are just strings. We haven't had to declare a function or method - or explicitly register the test case anywhere. Behind the scenes a function with a generated name is defined for you, and automatically registered using static registry classes. By abstracting the function name away we can name our tests without the constraints of identifier names.
4. We write our individual test assertions using the ```REQUIRE``` macro. Rather than a separate macro for each type of condition we express the condition naturally using C/C++ syntax. Behind the scenes a simple set of expression templates captures the left-hand-side and right-hand-side of the expression so we can display the values in our test report. As we'll see later there _are_ other assertion macros - but because of this technique the number of them is drastically reduced.
@ -98,7 +110,7 @@ Most test frameworks have a class-based fixture mechanism. That is, test cases m
While Catch fully supports this way of working there are a few problems with the approach. In particular the way your code must be split up, and the blunt granularity of it, may cause problems. You can only have one setup/ teardown pair across a set of methods, but sometimes you want slightly different setup in each method, or you may even want several levels of setup (a concept which we will clarify later on in this tutorial). It was <a href="http://jamesnewkirk.typepad.com/posts/2007/09/why-you-should-.html">problems like these</a> that led James Newkirk, who led the team that built NUnit, to start again from scratch and <a href="http://jamesnewkirk.typepad.com/posts/2007/09/announcing-xuni.html">build xUnit</a>).
Catch takes a different approach (to both NUnit and xUnit) that is a more natural fit for C++ and the C family of languages. This is best explained through an example:
Catch takes a different approach (to both NUnit and xUnit) that is a more natural fit for C++ and the C family of languages. This is best explained through an example ([code](../examples/100-Fix-Section.cpp)):
```c++
TEST_CASE( "vectors can be sized and resized", "[vector]" ) {
@ -161,9 +173,9 @@ Sections can be nested to an arbitrary depth (limited only by your stack size).
## BDD-Style
If you name your test cases and sections appropriately you can achieve a BDD-style specification structure. This became such a useful way of working that first class support has been added to Catch. Scenarios can be specified using ```SCENARIO```, ```GIVEN```, ```WHEN``` and ```THEN``` macros, which map on to ```TEST_CASE```s and ```SECTION```s, respectively. For more details see [Test cases and sections](test-cases-and-sections.md).
If you name your test cases and sections appropriately you can achieve a BDD-style specification structure. This became such a useful way of working that first class support has been added to Catch. Scenarios can be specified using ```SCENARIO```, ```GIVEN```, ```WHEN``` and ```THEN``` macros, which map on to ```TEST_CASE```s and ```SECTION```s, respectively. For more details see [Test cases and sections](test-cases-and-sections.md#top).
The vector example can be adjusted to use these macros like so:
The vector example can be adjusted to use these macros like so ([example code](../examples/120-Bdd-ScenarioGivenWhenThen.cpp)):
```c++
SCENARIO( "vectors can be sized and resized", "[vector]" ) {
@ -224,7 +236,7 @@ Scenario: vectors can be sized and resized
To keep the tutorial simple we put all our code in a single file. This is fine to get started - and makes jumping into Catch even quicker and easier. As you write more real-world tests, though, this is not really the best approach.
The requirement is that the following block of code ([or equivalent](own-main.md)):
The requirement is that the following block of code ([or equivalent](own-main.md#top)):
```c++
#define CATCH_CONFIG_MAIN
@ -233,7 +245,7 @@ The requirement is that the following block of code ([or equivalent](own-main.md
appears in _exactly one_ source file. Use as many additional cpp files (or whatever you call your implementation files) as you need for your tests, partitioned however makes most sense for your way of working. Each additional file need only ```#include "catch.hpp"``` - do not repeat the ```#define```!
In fact it is usually a good idea to put the block with the ```#define``` [in it's own source file](slow-compiles.md).
In fact it is usually a good idea to put the block with the ```#define``` [in its own source file](slow-compiles.md#top) (code example [main](../examples/020-TestCase-1.cpp), [tests](../examples/020-TestCase-2.cpp)).
Do not write your tests in header files!
@ -242,8 +254,8 @@ Do not write your tests in header files!
This has been a brief introduction to get you up and running with Catch, and to point out some of the key differences between Catch and other frameworks you may already be familiar with. This will get you going quite far already and you are now in a position to dive in and write some tests.
Of course there is more to learn - most of which you should be able to page-fault in as you go. Please see the ever-growing [Reference section](Readme.md) for what's available.
Of course there is more to learn - most of which you should be able to page-fault in as you go. Please see the ever-growing [Reference section](Readme.md#top) for what's available.
---
[Home](Readme.md)
[Home](Readme.md#top)

View File

@ -1,42 +1,46 @@
<a id="top"></a>
# Why do we need yet another C++ test framework?
Good question. For C++ there are quite a number of established frameworks, including (but not limited to), [CppUnit](http://sourceforge.net/apps/mediawiki/cppunit/index.php?title=Main_Page), [Google Test](http://code.google.com/p/googletest/), [Boost.Test](http://www.boost.org/doc/libs/1_49_0/libs/test/doc/html/index.html), [Aeryn](https://launchpad.net/aeryn), [Cute](http://r2.ifs.hsr.ch/cute), [Fructose](http://fructose.sourceforge.net/) and [many, many more](http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#C.2B.2B). Even for Objective-C there are a few, including OCUnit - which now comes bundled with XCode.
Good question. For C++ there are quite a number of established frameworks,
including (but not limited to),
[Google Test](http://code.google.com/p/googletest/),
[Boost.Test](http://www.boost.org/doc/libs/1_49_0/libs/test/doc/html/index.html),
[CppUnit](http://sourceforge.net/apps/mediawiki/cppunit/index.php?title=Main_Page),
[Cute](http://r2.ifs.hsr.ch/cute),
[many, many more](http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#C.2B.2B).
So what does Catch bring to the party that differentiates it from these? Apart from a Catchy name, of course.
## Key Features
* Really easy to get started. Just download catch.hpp, #include it and you're away.
* No external dependencies. As long as you can compile C++98 and have a C++ standard library available.
* Write test cases as, self-registering, functions or methods.
* Divide test cases into sections, each of which is run in isolation (eliminates the need for fixtures!)
* Quick and Really easy to get started. Just download catch.hpp, `#include` it and you're away.
* No external dependencies. As long as you can compile C++11 and have a C++ standard library available.
* Write test cases as, self-registering, functions (or methods, if you prefer).
* Divide test cases into sections, each of which is run in isolation (eliminates the need for fixtures).
* Use BDD-style Given-When-Then sections as well as traditional unit test cases.
* Only one core assertion macro for comparisons. Standard C/C++ operators are used for the comparison - yet the full expression is decomposed and lhs and rhs values are logged.
* Tests are named using free-form strings - no more couching names in legal identifiers.
## Other core features
* Tests are named using free-form strings - no more couching names in legal identifiers.
* Tests can be tagged for easily running ad-hoc groups of tests.
* Failures can (optionally) break into the debugger on Windows and Mac.
* Output is through modular reporter objects. Basic textual and XML reporters are included. Custom reporters can easily be added.
* JUnit xml output is supported for integration with third-party tools, such as CI servers.
* A default main() function is provided (in a header), but you can supply your own for complete control (e.g. integration into your own test runner GUI).
* A default main() function is provided, but you can supply your own for complete control (e.g. integration into your own test runner GUI).
* A command line parser is provided and can still be used if you choose to provided your own main() function.
* Catch can test itself.
* Alternative assertion macro(s) report failures but don't abort the test case
* Floating point tolerance comparisons are built in using an expressive Approx() syntax.
* Internal and friendly macros are isolated so name clashes can be managed
* Support for Matchers (early stages)
* Matchers
## Objective-C-specific features
## Who else is using Catch?
* Automatically detects if you are using it from an Objective-C project
* Works with and without ARC with no additional configuration
* Implement test fixtures using Obj-C classes too (like OCUnit)
* Additional built in matchers that work with Obj-C types (e.g. string matchers)
See the list of [open source projects using Catch](opensource-users.md#top).
See the [tutorial](tutorial.md) to get more of a taste of using CATCH in practice
See the [tutorial](tutorial.md#top) to get more of a taste of using Catch in practice
---
[Home](Readme.md)
[Home](Readme.md#top)

View File

@ -0,0 +1,15 @@
// 000-CatchMain.cpp
// In a Catch project with multiple files, dedicate one file to compile the
// source code of Catch itself and reuse the resulting object file for linking.
// Let Catch provide main():
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
// That's it
// Compile implementation of Catch for use with files that do contain tests:
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -c 000-CatchMain.cpp
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% -c 000-CatchMain.cpp

36
examples/010-TestCase.cpp Normal file
View File

@ -0,0 +1,36 @@
// 010-TestCase.cpp
// Let Catch provide main():
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
int Factorial( int number ) {
return number <= 1 ? number : Factorial( number - 1 ) * number; // fail
// return number <= 1 ? 1 : Factorial( number - 1 ) * number; // pass
}
TEST_CASE( "Factorial of 0 is 1 (fail)", "[single-file]" ) {
REQUIRE( Factorial(0) == 1 );
}
TEST_CASE( "Factorials of 1 and higher are computed (pass)", "[single-file]" ) {
REQUIRE( Factorial(1) == 1 );
REQUIRE( Factorial(2) == 2 );
REQUIRE( Factorial(3) == 6 );
REQUIRE( Factorial(10) == 3628800 );
}
// Compile & run:
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 010-TestCase 010-TestCase.cpp && 010-TestCase --success
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 010-TestCase.cpp && 010-TestCase --success
// Expected compact output (all assertions):
//
// prompt> 010-TestCase --reporter compact --success
// 010-TestCase.cpp:14: failed: Factorial(0) == 1 for: 0 == 1
// 010-TestCase.cpp:18: passed: Factorial(1) == 1 for: 1 == 1
// 010-TestCase.cpp:19: passed: Factorial(2) == 2 for: 2 == 2
// 010-TestCase.cpp:20: passed: Factorial(3) == 6 for: 6 == 6
// 010-TestCase.cpp:21: passed: Factorial(10) == 3628800 for: 3628800 (0x375f00) == 3628800 (0x375f00)
// Failed 1 test case, failed 1 assertion.

View File

@ -0,0 +1,35 @@
// 020-TestCase-1.cpp
// In a Catch project with multiple files, dedicate one file to compile the
// source code of Catch itself and reuse the resulting object file for linking.
// Let Catch provide main():
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
TEST_CASE( "1: All test cases reside in other .cpp files (empty)", "[multi-file:1]" ) {
}
// ^^^
// Normally no TEST_CASEs in this file.
// Here just to show there are two source files via option --list-tests.
// Compile & run:
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -c 020-TestCase-1.cpp
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 020-TestCase TestCase-1.o 020-TestCase-2.cpp && 020-TestCase --success
//
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% -c 020-TestCase-1.cpp
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% -Fe020-TestCase.exe 020-TestCase-1.obj 020-TestCase-2.cpp && 020-TestCase --success
// Expected test case listing:
//
// prompt> 020-TestCase --list-tests *
// Matching test cases:
// 1: All test cases reside in other .cpp files (empty)
// [multi-file:1]
// 2: Factorial of 0 is computed (fail)
// [multi-file:2]
// 2: Factorials of 1 and higher are computed (pass)
// [multi-file:2]
// 3 matching test cases

View File

@ -0,0 +1,33 @@
// 020-TestCase-2.cpp
// main() provided by Catch in file 020-TestCase-1.cpp.
#include "catch.hpp"
int Factorial( int number ) {
return number <= 1 ? number : Factorial( number - 1 ) * number; // fail
// return number <= 1 ? 1 : Factorial( number - 1 ) * number; // pass
}
TEST_CASE( "2: Factorial of 0 is 1 (fail)", "[multi-file:2]" ) {
REQUIRE( Factorial(0) == 1 );
}
TEST_CASE( "2: Factorials of 1 and higher are computed (pass)", "[multi-file:2]" ) {
REQUIRE( Factorial(1) == 1 );
REQUIRE( Factorial(2) == 2 );
REQUIRE( Factorial(3) == 6 );
REQUIRE( Factorial(10) == 3628800 );
}
// Compile: see 020-TestCase-1.cpp
// Expected compact output (all assertions):
//
// prompt> 020-TestCase --reporter compact --success
// 020-TestCase-2.cpp:13: failed: Factorial(0) == 1 for: 0 == 1
// 020-TestCase-2.cpp:17: passed: Factorial(1) == 1 for: 1 == 1
// 020-TestCase-2.cpp:18: passed: Factorial(2) == 2 for: 2 == 2
// 020-TestCase-2.cpp:19: passed: Factorial(3) == 6 for: 6 == 6
// 020-TestCase-2.cpp:20: passed: Factorial(10) == 3628800 for: 3628800 (0x375f00) == 3628800 (0x375f00)
// Failed 1 test case, failed 1 assertion.

View File

@ -0,0 +1,74 @@
// 030-Asn-Require-Check.cpp
// Catch has two natural expression assertion macro's:
// - REQUIRE() stops at first failure.
// - CHECK() continues after failure.
// There are two variants to support decomposing negated expressions:
// - REQUIRE_FALSE() stops at first failure.
// - CHECK_FALSE() continues after failure.
// main() provided in 000-CatchMain.cpp
#include "catch.hpp"
std::string one() {
return "1";
}
TEST_CASE( "Assert that something is true (pass)", "[require]" ) {
REQUIRE( one() == "1" );
}
TEST_CASE( "Assert that something is true (fail)", "[require]" ) {
REQUIRE( one() == "x" );
}
TEST_CASE( "Assert that something is true (stop at first failure)", "[require]" ) {
WARN( "REQUIRE stops at first failure:" );
REQUIRE( one() == "x" );
REQUIRE( one() == "1" );
}
TEST_CASE( "Assert that something is true (continue after failure)", "[check]" ) {
WARN( "CHECK continues after failure:" );
CHECK( one() == "x" );
REQUIRE( one() == "1" );
}
TEST_CASE( "Assert that something is false (stops at first failure)", "[require-false]" ) {
WARN( "REQUIRE_FALSE stops at first failure:" );
REQUIRE_FALSE( one() == "1" );
REQUIRE_FALSE( one() != "1" );
}
TEST_CASE( "Assert that something is false (continue after failure)", "[check-false]" ) {
WARN( "CHECK_FALSE continues after failure:" );
CHECK_FALSE( one() == "1" );
REQUIRE_FALSE( one() != "1" );
}
// Compile & run:
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 030-Asn-Require-Check 030-Asn-Require-Check.cpp 000-CatchMain.o && 030-Asn-Require-Check --success
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 030-Asn-Require-Check.cpp 000-CatchMain.obj && 030-Asn-Require-Check --success
// Expected compact output (all assertions):
//
// prompt> 030-Asn-Require-Check.exe --reporter compact --success
// 030-Asn-Require-Check.cpp:20: passed: one() == "1" for: "1" == "1"
// 030-Asn-Require-Check.cpp:24: failed: one() == "x" for: "1" == "x"
// 030-Asn-Require-Check.cpp:28: warning: 'REQUIRE stops at first failure:'
// 030-Asn-Require-Check.cpp:30: failed: one() == "x" for: "1" == "x"
// 030-Asn-Require-Check.cpp:35: warning: 'CHECK continues after failure:'
// 030-Asn-Require-Check.cpp:37: failed: one() == "x" for: "1" == "x"
// 030-Asn-Require-Check.cpp:38: passed: one() == "1" for: "1" == "1"
// 030-Asn-Require-Check.cpp:42: warning: 'REQUIRE_FALSE stops at first failure:'
// 030-Asn-Require-Check.cpp:44: failed: !(one() == "1") for: !("1" == "1")
// 030-Asn-Require-Check.cpp:49: warning: 'CHECK_FALSE continues after failure:'
// 030-Asn-Require-Check.cpp:51: failed: !(one() == "1") for: !("1" == "1")
// 030-Asn-Require-Check.cpp:52: passed: !(one() != "1") for: !("1" != "1")
// Failed 5 test cases, failed 5 assertions.

View File

@ -0,0 +1,69 @@
// 100-Fix-Section.cpp
// Catch has two ways to express fixtures:
// - Sections (this file)
// - Traditional class-based fixtures
// main() provided in 000-CatchMain.cpp
#include "catch.hpp"
TEST_CASE( "vectors can be sized and resized", "[vector]" ) {
// For each section, vector v is anew:
std::vector<int> v( 5 );
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 5 );
SECTION( "resizing bigger changes size and capacity" ) {
v.resize( 10 );
REQUIRE( v.size() == 10 );
REQUIRE( v.capacity() >= 10 );
}
SECTION( "resizing smaller changes size but not capacity" ) {
v.resize( 0 );
REQUIRE( v.size() == 0 );
REQUIRE( v.capacity() >= 5 );
}
SECTION( "reserving bigger changes capacity but not size" ) {
v.reserve( 10 );
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 10 );
}
SECTION( "reserving smaller does not change size or capacity" ) {
v.reserve( 0 );
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 5 );
}
}
// Compile & run:
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 100-Fix-Section 100-Fix-Section.cpp 000-CatchMain.o && 100-Fix-Section --success
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 100-Fix-Section.cpp 000-CatchMain.obj && 100-Fix-Section --success
// Expected compact output (all assertions):
//
// prompt> 100-Fix-Section.exe --reporter compact --success
// 100-Fix-Section.cpp:17: passed: v.size() == 5 for: 5 == 5
// 100-Fix-Section.cpp:18: passed: v.capacity() >= 5 for: 5 >= 5
// 100-Fix-Section.cpp:23: passed: v.size() == 10 for: 10 == 10
// 100-Fix-Section.cpp:24: passed: v.capacity() >= 10 for: 10 >= 10
// 100-Fix-Section.cpp:17: passed: v.size() == 5 for: 5 == 5
// 100-Fix-Section.cpp:18: passed: v.capacity() >= 5 for: 5 >= 5
// 100-Fix-Section.cpp:29: passed: v.size() == 0 for: 0 == 0
// 100-Fix-Section.cpp:30: passed: v.capacity() >= 5 for: 5 >= 5
// 100-Fix-Section.cpp:17: passed: v.size() == 5 for: 5 == 5
// 100-Fix-Section.cpp:18: passed: v.capacity() >= 5 for: 5 >= 5
// 100-Fix-Section.cpp:35: passed: v.size() == 5 for: 5 == 5
// 100-Fix-Section.cpp:36: passed: v.capacity() >= 10 for: 10 >= 10
// 100-Fix-Section.cpp:17: passed: v.size() == 5 for: 5 == 5
// 100-Fix-Section.cpp:18: passed: v.capacity() >= 5 for: 5 >= 5
// 100-Fix-Section.cpp:41: passed: v.size() == 5 for: 5 == 5
// 100-Fix-Section.cpp:42: passed: v.capacity() >= 5 for: 5 >= 5
// Passed 1 test case with 16 assertions.

View File

@ -0,0 +1,63 @@
// 110-Fix-ClassFixture.cpp
// Catch has two ways to express fixtures:
// - Sections
// - Traditional class-based fixtures (this file)
// main() provided in 000-CatchMain.cpp
#include "catch.hpp"
class DBConnection
{
public:
static DBConnection createConnection( std::string const & /*dbName*/ ) {
return DBConnection();
}
bool executeSQL( std::string const & /*query*/, int const /*id*/, std::string const & arg ) {
if ( arg.length() == 0 ) {
throw std::logic_error("empty SQL query argument");
}
return true; // ok
}
};
class UniqueTestsFixture
{
protected:
UniqueTestsFixture()
: conn( DBConnection::createConnection( "myDB" ) )
{}
int getID() {
return ++uniqueID;
}
protected:
DBConnection conn;
private:
static int uniqueID;
};
int UniqueTestsFixture::uniqueID = 0;
TEST_CASE_METHOD( UniqueTestsFixture, "Create Employee/No Name", "[create]" ) {
REQUIRE_THROWS( conn.executeSQL( "INSERT INTO employee (id, name) VALUES (?, ?)", getID(), "") );
}
TEST_CASE_METHOD( UniqueTestsFixture, "Create Employee/Normal", "[create]" ) {
REQUIRE( conn.executeSQL( "INSERT INTO employee (id, name) VALUES (?, ?)", getID(), "Joe Bloggs" ) );
}
// Compile & run:
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 110-Fix-ClassFixture 110-Fix-ClassFixture.cpp 000-CatchMain.o && 110-Fix-ClassFixture --success
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 110-Fix-ClassFixture.cpp 000-CatchMain.obj && 110-Fix-ClassFixture --success
// Expected compact output (all assertions):
//
// prompt> 110-Fix-ClassFixture.exe --reporter compact --success
// 110-Fix-ClassFixture.cpp:47: passed: conn.executeSQL( "INSERT INTO employee (id, name) VALUES (?, ?)", getID(), "")
// 110-Fix-ClassFixture.cpp:51: passed: conn.executeSQL( "INSERT INTO employee (id, name) VALUES (?, ?)", getID(), "Joe Bloggs" ) for: true
// Passed both 2 test cases with 2 assertions.

View File

@ -0,0 +1,73 @@
// 120-Bdd-ScenarioGivenWhenThen.cpp
// main() provided in 000-CatchMain.cpp
#include "catch.hpp"
SCENARIO( "vectors can be sized and resized", "[vector]" ) {
GIVEN( "A vector with some items" ) {
std::vector<int> v( 5 );
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 5 );
WHEN( "the size is increased" ) {
v.resize( 10 );
THEN( "the size and capacity change" ) {
REQUIRE( v.size() == 10 );
REQUIRE( v.capacity() >= 10 );
}
}
WHEN( "the size is reduced" ) {
v.resize( 0 );
THEN( "the size changes but not capacity" ) {
REQUIRE( v.size() == 0 );
REQUIRE( v.capacity() >= 5 );
}
}
WHEN( "more capacity is reserved" ) {
v.reserve( 10 );
THEN( "the capacity changes but not the size" ) {
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 10 );
}
}
WHEN( "less capacity is reserved" ) {
v.reserve( 0 );
THEN( "neither size nor capacity are changed" ) {
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 5 );
}
}
}
}
// Compile & run:
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 120-Bdd-ScenarioGivenWhenThen 120-Bdd-ScenarioGivenWhenThen.cpp 000-CatchMain.o && 120-Bdd-ScenarioGivenWhenThen --success
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 120-Bdd-ScenarioGivenWhenThen.cpp 000-CatchMain.obj && 120-Bdd-ScenarioGivenWhenThen --success
// Expected compact output (all assertions):
//
// prompt> 120-Bdd-ScenarioGivenWhenThen.exe --reporter compact --success
// 120-Bdd-ScenarioGivenWhenThen.cpp:12: passed: v.size() == 5 for: 5 == 5
// 120-Bdd-ScenarioGivenWhenThen.cpp:13: passed: v.capacity() >= 5 for: 5 >= 5
// 120-Bdd-ScenarioGivenWhenThen.cpp:19: passed: v.size() == 10 for: 10 == 10
// 120-Bdd-ScenarioGivenWhenThen.cpp:20: passed: v.capacity() >= 10 for: 10 >= 10
// 120-Bdd-ScenarioGivenWhenThen.cpp:12: passed: v.size() == 5 for: 5 == 5
// 120-Bdd-ScenarioGivenWhenThen.cpp:13: passed: v.capacity() >= 5 for: 5 >= 5
// 120-Bdd-ScenarioGivenWhenThen.cpp:27: passed: v.size() == 0 for: 0 == 0
// 120-Bdd-ScenarioGivenWhenThen.cpp:28: passed: v.capacity() >= 5 for: 5 >= 5
// 120-Bdd-ScenarioGivenWhenThen.cpp:12: passed: v.size() == 5 for: 5 == 5
// 120-Bdd-ScenarioGivenWhenThen.cpp:13: passed: v.capacity() >= 5 for: 5 >= 5
// 120-Bdd-ScenarioGivenWhenThen.cpp:35: passed: v.size() == 5 for: 5 == 5
// 120-Bdd-ScenarioGivenWhenThen.cpp:36: passed: v.capacity() >= 10 for: 10 >= 10
// 120-Bdd-ScenarioGivenWhenThen.cpp:12: passed: v.size() == 5 for: 5 == 5
// 120-Bdd-ScenarioGivenWhenThen.cpp:13: passed: v.capacity() >= 5 for: 5 >= 5
// 120-Bdd-ScenarioGivenWhenThen.cpp:43: passed: v.size() == 5 for: 5 == 5
// 120-Bdd-ScenarioGivenWhenThen.cpp:44: passed: v.capacity() >= 5 for: 5 >= 5
// Passed 1 test case with 16 assertions.

View File

@ -0,0 +1,423 @@
// 210-Evt-EventListeners.cpp
// Contents:
// 1. Printing of listener data
// 2. My listener and registration
// 3. Test cases
// main() provided in 000-CatchMain.cpp
// Let Catch provide the required interfaces:
#define CATCH_CONFIG_EXTERNAL_INTERFACES
#include "catch.hpp"
#include <iostream>
// -----------------------------------------------------------------------
// 1. Printing of listener data:
//
std::string ws(int const level) {
return std::string( 2 * level, ' ' );
}
template< typename T >
std::ostream& operator<<( std::ostream& os, std::vector<T> const& v ) {
os << "{ ";
for ( auto x : v )
os << x << ", ";
return os << "}";
}
// struct SourceLineInfo {
// char const* file;
// std::size_t line;
// };
void print( std::ostream& os, int const level, std::string const& title, Catch::SourceLineInfo const& info ) {
os << ws(level ) << title << ":\n"
<< ws(level+1) << "- file: " << info.file << "\n"
<< ws(level+1) << "- line: " << info.line << "\n";
}
//struct MessageInfo {
// std::string macroName;
// std::string message;
// SourceLineInfo lineInfo;
// ResultWas::OfType type;
// unsigned int sequence;
//};
void print( std::ostream& os, int const level, Catch::MessageInfo const& info ) {
os << ws(level+1) << "- macroName: '" << info.macroName << "'\n"
<< ws(level+1) << "- message '" << info.message << "'\n";
print( os,level+1 , "- lineInfo", info.lineInfo );
os << ws(level+1) << "- sequence " << info.sequence << "\n";
}
void print( std::ostream& os, int const level, std::string const& title, std::vector<Catch::MessageInfo> const& v ) {
os << ws(level ) << title << ":\n";
for ( auto x : v )
{
os << ws(level+1) << "{\n";
print( os, level+2, x );
os << ws(level+1) << "}\n";
}
// os << ws(level+1) << "\n";
}
// struct TestRunInfo {
// std::string name;
// };
void print( std::ostream& os, int const level, std::string const& title, Catch::TestRunInfo const& info ) {
os << ws(level ) << title << ":\n"
<< ws(level+1) << "- name: " << info.name << "\n";
}
// struct Counts {
// std::size_t total() const;
// bool allPassed() const;
// bool allOk() const;
//
// std::size_t passed = 0;
// std::size_t failed = 0;
// std::size_t failedButOk = 0;
// };
void print( std::ostream& os, int const level, std::string const& title, Catch::Counts const& info ) {
os << ws(level ) << title << ":\n"
<< ws(level+1) << "- total(): " << info.total() << "\n"
<< ws(level+1) << "- allPassed(): " << info.allPassed() << "\n"
<< ws(level+1) << "- allOk(): " << info.allOk() << "\n"
<< ws(level+1) << "- passed: " << info.passed << "\n"
<< ws(level+1) << "- failed: " << info.failed << "\n"
<< ws(level+1) << "- failedButOk: " << info.failedButOk << "\n";
}
// struct Totals {
// Counts assertions;
// Counts testCases;
// };
void print( std::ostream& os, int const level, std::string const& title, Catch::Totals const& info ) {
os << ws(level) << title << ":\n";
print( os, level+1, "- assertions", info.assertions );
print( os, level+1, "- testCases" , info.testCases );
}
// struct TestRunStats {
// TestRunInfo runInfo;
// Totals totals;
// bool aborting;
// };
void print( std::ostream& os, int const level, std::string const& title, Catch::TestRunStats const& info ) {
os << ws(level) << title << ":\n";
print( os, level+1 , "- runInfo", info.runInfo );
print( os, level+1 , "- totals" , info.totals );
os << ws(level+1) << "- aborting: " << info.aborting << "\n";
}
// struct TestCaseInfo {
// enum SpecialProperties{
// None = 0,
// IsHidden = 1 << 1,
// ShouldFail = 1 << 2,
// MayFail = 1 << 3,
// Throws = 1 << 4,
// NonPortable = 1 << 5,
// Benchmark = 1 << 6
// };
//
// bool isHidden() const;
// bool throws() const;
// bool okToFail() const;
// bool expectedToFail() const;
//
// std::string tagsAsString() const;
//
// std::string name;
// std::string className;
// std::string description;
// std::vector<std::string> tags;
// std::vector<std::string> lcaseTags;
// SourceLineInfo lineInfo;
// SpecialProperties properties;
// };
void print( std::ostream& os, int const level, std::string const& title, Catch::TestCaseInfo const& info ) {
os << ws(level ) << title << ":\n"
<< ws(level+1) << "- isHidden(): " << info.isHidden() << "\n"
<< ws(level+1) << "- throws(): " << info.throws() << "\n"
<< ws(level+1) << "- okToFail(): " << info.okToFail() << "\n"
<< ws(level+1) << "- expectedToFail(): " << info.expectedToFail() << "\n"
<< ws(level+1) << "- tagsAsString(): '" << info.tagsAsString() << "'\n"
<< ws(level+1) << "- name: '" << info.name << "'\n"
<< ws(level+1) << "- className: '" << info.className << "'\n"
<< ws(level+1) << "- description: '" << info.description << "'\n"
<< ws(level+1) << "- tags: " << info.tags << "\n"
<< ws(level+1) << "- lcaseTags: " << info.lcaseTags << "\n";
print( os, level+1 , "- lineInfo", info.lineInfo );
os << ws(level+1) << "- properties (flags): 0x" << std::hex << info.properties << std::dec << "\n";
}
// struct TestCaseStats {
// TestCaseInfo testInfo;
// Totals totals;
// std::string stdOut;
// std::string stdErr;
// bool aborting;
// };
void print( std::ostream& os, int const level, std::string const& title, Catch::TestCaseStats const& info ) {
os << ws(level ) << title << ":\n";
print( os, level+1 , "- testInfo", info.testInfo );
print( os, level+1 , "- totals" , info.totals );
os << ws(level+1) << "- stdOut: " << info.stdOut << "\n"
<< ws(level+1) << "- stdErr: " << info.stdErr << "\n"
<< ws(level+1) << "- aborting: " << info.aborting << "\n";
}
// struct SectionInfo {
// std::string name;
// std::string description;
// SourceLineInfo lineInfo;
// };
void print( std::ostream& os, int const level, std::string const& title, Catch::SectionInfo const& info ) {
os << ws(level ) << title << ":\n"
<< ws(level+1) << "- name: " << info.name << "\n"
<< ws(level+1) << "- description: '" << info.description << "'\n";
print( os, level+1 , "- lineInfo", info.lineInfo );
}
// struct SectionStats {
// SectionInfo sectionInfo;
// Counts assertions;
// double durationInSeconds;
// bool missingAssertions;
// };
void print( std::ostream& os, int const level, std::string const& title, Catch::SectionStats const& info ) {
os << ws(level ) << title << ":\n";
print( os, level+1 , "- sectionInfo", info.sectionInfo );
print( os, level+1 , "- assertions" , info.assertions );
os << ws(level+1) << "- durationInSeconds: " << info.durationInSeconds << "\n"
<< ws(level+1) << "- missingAssertions: " << info.missingAssertions << "\n";
}
// struct AssertionInfo
// {
// StringRef macroName;
// SourceLineInfo lineInfo;
// StringRef capturedExpression;
// ResultDisposition::Flags resultDisposition;
// };
void print( std::ostream& os, int const level, std::string const& title, Catch::AssertionInfo const& info ) {
os << ws(level ) << title << ":\n"
<< ws(level+1) << "- macroName: '" << info.macroName << "'\n";
print( os, level+1 , "- lineInfo" , info.lineInfo );
os << ws(level+1) << "- capturedExpression: '" << info.capturedExpression << "'\n"
<< ws(level+1) << "- resultDisposition (flags): 0x" << std::hex << info.resultDisposition << std::dec << "\n";
}
//struct AssertionResultData
//{
// std::string reconstructExpression() const;
//
// std::string message;
// mutable std::string reconstructedExpression;
// LazyExpression lazyExpression;
// ResultWas::OfType resultType;
//};
void print( std::ostream& os, int const level, std::string const& title, Catch::AssertionResultData const& info ) {
os << ws(level ) << title << ":\n"
<< ws(level+1) << "- reconstructExpression(): '" << info.reconstructExpression() << "'\n"
<< ws(level+1) << "- message: '" << info.message << "'\n"
<< ws(level+1) << "- lazyExpression: '" << "(info.lazyExpression)" << "'\n"
<< ws(level+1) << "- resultType: '" << info.resultType << "'\n";
}
//class AssertionResult {
// bool isOk() const;
// bool succeeded() const;
// ResultWas::OfType getResultType() const;
// bool hasExpression() const;
// bool hasMessage() const;
// std::string getExpression() const;
// std::string getExpressionInMacro() const;
// bool hasExpandedExpression() const;
// std::string getExpandedExpression() const;
// std::string getMessage() const;
// SourceLineInfo getSourceInfo() const;
// std::string getTestMacroName() const;
//
// AssertionInfo m_info;
// AssertionResultData m_resultData;
//};
void print( std::ostream& os, int const level, std::string const& title, Catch::AssertionResult const& info ) {
os << ws(level ) << title << ":\n"
<< ws(level+1) << "- isOk(): " << info.isOk() << "\n"
<< ws(level+1) << "- succeeded(): " << info.succeeded() << "\n"
<< ws(level+1) << "- getResultType(): " << info.getResultType() << "\n"
<< ws(level+1) << "- hasExpression(): " << info.hasExpression() << "\n"
<< ws(level+1) << "- hasMessage(): " << info.hasMessage() << "\n"
<< ws(level+1) << "- getExpression(): '" << info.getExpression() << "'\n"
<< ws(level+1) << "- getExpressionInMacro(): '" << info.getExpressionInMacro() << "'\n"
<< ws(level+1) << "- hasExpandedExpression(): " << info.hasExpandedExpression() << "\n"
<< ws(level+1) << "- getExpandedExpression(): " << info.getExpandedExpression() << "'\n"
<< ws(level+1) << "- getMessage(): '" << info.getMessage() << "'\n";
print( os, level+1 , "- getSourceInfo(): ", info.getSourceInfo() );
os << ws(level+1) << "- getTestMacroName(): '" << info.getTestMacroName() << "'\n";
// print( os, level+1 , "- *** m_info (AssertionInfo)", info.m_info );
// print( os, level+1 , "- *** m_resultData (AssertionResultData)", info.m_resultData );
}
// struct AssertionStats {
// AssertionResult assertionResult;
// std::vector<MessageInfo> infoMessages;
// Totals totals;
// };
void print( std::ostream& os, int const level, std::string const& title, Catch::AssertionStats const& info ) {
os << ws(level ) << title << ":\n";
print( os, level+1 , "- assertionResult", info.assertionResult );
print( os, level+1 , "- infoMessages", info.infoMessages );
print( os, level+1 , "- totals", info.totals );
}
// -----------------------------------------------------------------------
// 2. My listener and registration:
//
char const * dashed_line =
"--------------------------------------------------------------------------";
struct MyListener : Catch::TestEventListenerBase {
using TestEventListenerBase::TestEventListenerBase; // inherit constructor
// Get rid of Wweak-tables
~MyListener();
// The whole test run starting
virtual void testRunStarting( Catch::TestRunInfo const& testRunInfo ) override {
std::cout
<< std::boolalpha
<< "\nEvent: testRunStarting:\n";
print( std::cout, 1, "- testRunInfo", testRunInfo );
}
// The whole test run ending
virtual void testRunEnded( Catch::TestRunStats const& testRunStats ) override {
std::cout
<< dashed_line
<< "\nEvent: testRunEnded:\n";
print( std::cout, 1, "- testRunStats", testRunStats );
}
// A test is being skipped (because it is "hidden")
virtual void skipTest( Catch::TestCaseInfo const& testInfo ) override {
std::cout
<< dashed_line
<< "\nEvent: skipTest:\n";
print( std::cout, 1, "- testInfo", testInfo );
}
// Test cases starting
virtual void testCaseStarting( Catch::TestCaseInfo const& testInfo ) override {
std::cout
<< dashed_line
<< "\nEvent: testCaseStarting:\n";
print( std::cout, 1, "- testInfo", testInfo );
}
// Test cases ending
virtual void testCaseEnded( Catch::TestCaseStats const& testCaseStats ) override {
std::cout << "\nEvent: testCaseEnded:\n";
print( std::cout, 1, "testCaseStats", testCaseStats );
}
// Sections starting
virtual void sectionStarting( Catch::SectionInfo const& sectionInfo ) override {
std::cout << "\nEvent: sectionStarting:\n";
print( std::cout, 1, "- sectionInfo", sectionInfo );
}
// Sections ending
virtual void sectionEnded( Catch::SectionStats const& sectionStats ) override {
std::cout << "\nEvent: sectionEnded:\n";
print( std::cout, 1, "- sectionStats", sectionStats );
}
// Assertions before/ after
virtual void assertionStarting( Catch::AssertionInfo const& assertionInfo ) override {
std::cout << "\nEvent: assertionStarting:\n";
print( std::cout, 1, "- assertionInfo", assertionInfo );
}
virtual bool assertionEnded( Catch::AssertionStats const& assertionStats ) override {
std::cout << "\nEvent: assertionEnded:\n";
print( std::cout, 1, "- assertionStats", assertionStats );
return true;
}
};
CATCH_REGISTER_LISTENER( MyListener )
// Get rid of Wweak-tables
MyListener::~MyListener() {}
// -----------------------------------------------------------------------
// 3. Test cases:
//
TEST_CASE( "1: Hidden testcase", "[.hidden]" ) {
}
TEST_CASE( "2: Testcase with sections", "[tag-A][tag-B]" ) {
int i = 42;
REQUIRE( i == 42 );
SECTION("Section 1") {
INFO("Section 1")
i = 7;
SECTION("Section 1.1") {
INFO("Section 1.1")
REQUIRE( i == 42 );
}
}
SECTION("Section 2") {
INFO("Section 2")
REQUIRE( i == 42 );
}
WARN("At end of test case");
}
struct Fixture {
int fortytwo() const {
return 42;
}
};
TEST_CASE_METHOD( Fixture, "3: Testcase with class-based fixture", "[tag-C][tag-D]" ) {
REQUIRE( fortytwo() == 42 );
}
// Compile & run:
// - g++ -std=c++11 -Wall -I$(CATCH_SINGLE_INCLUDE) -o 210-Evt-EventListeners 210-Evt-EventListeners.cpp 000-CatchMain.o && 210-Evt-EventListeners --success
// - cl -EHsc -I%CATCH_SINGLE_INCLUDE% 210-Evt-EventListeners.cpp 000-CatchMain.obj && 210-Evt-EventListeners --success
// Expected compact output (all assertions):
//
// prompt> 210-Evt-EventListeners --reporter compact --success
// result omitted for brevity.

100
examples/CMakeLists.txt Normal file
View File

@ -0,0 +1,100 @@
#
# Build examples.
#
# Requires CATCH_BUILD_EXAMPLES to be defined 'true', see ../CMakeLists.txt.
#
cmake_minimum_required( VERSION 3.0 )
project( CatchExamples CXX )
# define folders used:
set( EXAMPLES_DIR ${CATCH_DIR}/examples )
set( HEADER_DIR ${CATCH_DIR}/single_include )
# single-file sources:
set( SOURCES_SINGLE_FILE
010-TestCase.cpp
)
# multiple-file modules:
set( SOURCES_020
020-TestCase-1.cpp
020-TestCase-2.cpp
)
# main for idiomatic test sources:
set( SOURCES_IDIOMATIC_MAIN
000-CatchMain.cpp
)
# sources to combine with 000-CatchMain.cpp:
set( SOURCES_IDIOMATIC_TESTS
030-Asn-Require-Check.cpp
100-Fix-Section.cpp
110-Fix-ClassFixture.cpp
120-Bdd-ScenarioGivenWhenThen.cpp
210-Evt-EventListeners.cpp
)
# check if all sources are listed, warn if not:
set( SOURCES_ALL
${SOURCES_020}
${SOURCES_SINGLE_FILE}
${SOURCES_IDIOMATIC_MAIN}
${SOURCES_IDIOMATIC_TESTS}
)
foreach( name ${SOURCES_ALL} )
list( APPEND SOURCES_ALL_PATH ${EXAMPLES_DIR}/${name} )
endforeach()
CheckFileList( SOURCES_ALL_PATH ${EXAMPLES_DIR} )
# create target names:
string( REPLACE ".cpp" "" BASENAMES_SINGLE_FILE "${SOURCES_SINGLE_FILE}" )
string( REPLACE ".cpp" "" BASENAMES_IDIOMATIC_TESTS "${SOURCES_IDIOMATIC_TESTS}" )
set( TARGETS_SINGLE_FILE ${BASENAMES_SINGLE_FILE} )
set( TARGETS_IDIOMATIC_TESTS ${BASENAMES_IDIOMATIC_TESTS} )
set( TARGETS_ALL ${TARGETS_SINGLE_FILE} ${TARGETS_IDIOMATIC_TESTS} 020-TestCase CatchMain )
# define program targets:
add_library( CatchMain OBJECT ${EXAMPLES_DIR}/${SOURCES_IDIOMATIC_MAIN} ${HEADER_DIR}/catch.hpp )
add_executable( 020-TestCase ${EXAMPLES_DIR}/020-TestCase-1.cpp ${EXAMPLES_DIR}/020-TestCase-2.cpp ${HEADER_DIR}/catch.hpp )
foreach( name ${TARGETS_SINGLE_FILE} )
add_executable( ${name} ${EXAMPLES_DIR}/${name}.cpp ${HEADER_DIR}/catch.hpp )
endforeach()
foreach( name ${TARGETS_IDIOMATIC_TESTS} )
add_executable( ${name} ${EXAMPLES_DIR}/${name}.cpp $<TARGET_OBJECTS:CatchMain> ${HEADER_DIR}/catch.hpp )
endforeach()
foreach( name ${TARGETS_ALL} )
target_include_directories( ${name} PRIVATE ${HEADER_DIR} )
set_property(TARGET ${name} PROPERTY CXX_STANDARD 11)
# Add desired warnings
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
target_compile_options( ${name} PRIVATE -Wall -Wextra -Wunreachable-code )
endif()
# Clang specific warning go here
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
# Actually keep these
target_compile_options( ${name} PRIVATE -Wweak-vtables -Wexit-time-destructors -Wglobal-constructors -Wmissing-noreturn )
endif()
if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
target_compile_options( ${name} PRIVATE /W4 /w44265 /WX )
endif()
endforeach()

View File

@ -9,6 +9,10 @@
#ifndef TWOBLUECUBES_CATCH_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_HPP_INCLUDED
#define CATCH_VERSION_MAJOR 2
#define CATCH_VERSION_MINOR 1
#define CATCH_VERSION_PATCH 2
#ifdef __clang__
# pragma clang system_header
#elif defined __GNUC__
@ -19,8 +23,22 @@
#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
# define CATCH_IMPL
# define CATCH_CONFIG_ALL_PARTS
#endif
// In the impl file, we want to have access to all parts of the headers
// Can also be used to sanely support PCHs
#if defined(CATCH_CONFIG_ALL_PARTS)
# define CATCH_CONFIG_EXTERNAL_INTERFACES
# if defined(CATCH_CONFIG_DISABLE_MATCHERS)
# undef CATCH_CONFIG_DISABLE_MATCHERS
# endif
# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
#endif
#if !defined(CATCH_CONFIG_IMPL_ONLY)
#include "internal/catch_platform.h"
#ifdef CATCH_IMPL
# ifndef CLARA_CONFIG_MAIN
# define CLARA_CONFIG_MAIN_NOT_DEFINED
@ -28,17 +46,20 @@
# endif
#endif
#include "internal/catch_notimplemented_exception.h"
#include "internal/catch_context.h"
#include "internal/catch_test_registry.hpp"
#include "internal/catch_user_interfaces.h"
#include "internal/catch_tag_alias_autoregistrar.h"
#include "internal/catch_test_registry.h"
#include "internal/catch_capture.hpp"
#include "internal/catch_section.h"
#include "internal/catch_generators.hpp"
#include "internal/catch_benchmark.h"
#include "internal/catch_interfaces_exception.h"
#include "internal/catch_approx.hpp"
#include "internal/catch_matchers.hpp"
#include "internal/catch_approx.h"
#include "internal/catch_compiler_capabilities.h"
#include "internal/catch_interfaces_tag_alias_registry.h"
#include "internal/catch_string_manip.h"
#ifndef CATCH_CONFIG_DISABLE_MATCHERS
#include "internal/catch_capture_matchers.h"
#endif
// These files are included here so the single_include script doesn't put them
// in the conditionally compiled sections
@ -49,6 +70,12 @@
#include "internal/catch_objc.hpp"
#endif
#ifdef CATCH_CONFIG_EXTERNAL_INTERFACES
#include "internal/catch_external_interfaces.h"
#endif
#endif // ! CATCH_CONFIG_IMPL_ONLY
#ifdef CATCH_IMPL
#include "internal/catch_impl.hpp"
#endif
@ -57,157 +84,267 @@
#include "internal/catch_default_main.hpp"
#endif
#if !defined(CATCH_CONFIG_IMPL_ONLY)
#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
# undef CLARA_CONFIG_MAIN
#endif
#if !defined(CATCH_CONFIG_DISABLE)
//////
// 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" )
#define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
#define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
#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( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", __VA_ARGS__ )
#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_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
#endif// CATCH_CONFIG_DISABLE_MATCHERS
#define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
#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( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
#define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
#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( ... ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", __VA_ARGS__ )
#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_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
#endif // CATCH_CONFIG_DISABLE_MATCHERS
#define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define 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" )
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#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" )
#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
#endif // CATCH_CONFIG_DISABLE_MATCHERS
#ifdef CATCH_CONFIG_VARIADIC_MACROS
#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
#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__ )
#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 )
#endif
#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
#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_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) )
#define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
#define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
#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_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__ )
#define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
// "BDD-style" convenience wrappers
#ifdef CATCH_CONFIG_VARIADIC_MACROS
#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
#else
#define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags )
#define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
#endif
#define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc, "" )
#define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc, "" )
#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" )
#define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc, "" )
#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" )
#define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc )
#define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc )
#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc )
#define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc )
#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc )
// 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" )
#define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
#define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
#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" )
#define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
#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_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
#endif // CATCH_CONFIG_DISABLE_MATCHERS
#define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
#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 CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
#define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
#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_THROWS( ... ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#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_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
#endif // CATCH_CONFIG_DISABLE_MATCHERS
#define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#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 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" )
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
#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__ )
#else
#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 )
#endif
#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
#endif // CATCH_CONFIG_DISABLE_MATCHERS
#define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
#define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
#define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
#define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
#define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) )
#define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
#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__ )
#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
#endif
#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
// "BDD-style" convenience wrappers
#ifdef CATCH_CONFIG_VARIADIC_MACROS
#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
#else
#define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags )
#define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
#endif
#define GIVEN( desc ) SECTION( std::string(" Given: ") + desc, "" )
#define WHEN( desc ) SECTION( std::string(" When: ") + desc, "" )
#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" )
#define THEN( desc ) SECTION( std::string(" Then: ") + desc, "" )
#define AND_THEN( desc ) SECTION( std::string(" And: ") + desc, "" )
#define GIVEN( desc ) SECTION( std::string(" Given: ") + desc )
#define WHEN( desc ) SECTION( std::string(" When: ") + desc )
#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc )
#define THEN( desc ) SECTION( std::string(" Then: ") + desc )
#define AND_THEN( desc ) SECTION( std::string(" And: ") + desc )
using Catch::Detail::Approx;
#else
//////
// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
#ifdef CATCH_CONFIG_PREFIX_ALL
#define CATCH_REQUIRE( ... ) (void)(0)
#define CATCH_REQUIRE_FALSE( ... ) (void)(0)
#define CATCH_REQUIRE_THROWS( ... ) (void)(0)
#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
#endif// CATCH_CONFIG_DISABLE_MATCHERS
#define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)
#define CATCH_CHECK( ... ) (void)(0)
#define CATCH_CHECK_FALSE( ... ) (void)(0)
#define CATCH_CHECKED_IF( ... ) if (__VA_ARGS__)
#define CATCH_CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
#define CATCH_CHECK_NOFAIL( ... ) (void)(0)
#define CATCH_CHECK_THROWS( ... ) (void)(0)
#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
#define CATCH_CHECK_THROWS_WITH( expr, matcher ) (void)(0)
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
#endif // CATCH_CONFIG_DISABLE_MATCHERS
#define CATCH_CHECK_NOTHROW( ... ) (void)(0)
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#define CATCH_CHECK_THAT( arg, matcher ) (void)(0)
#define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
#endif // CATCH_CONFIG_DISABLE_MATCHERS
#define CATCH_INFO( msg ) (void)(0)
#define CATCH_WARN( msg ) (void)(0)
#define CATCH_CAPTURE( msg ) (void)(0)
#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
#define CATCH_METHOD_AS_TEST_CASE( method, ... )
#define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
#define CATCH_SECTION( ... )
#define CATCH_FAIL( ... ) (void)(0)
#define CATCH_FAIL_CHECK( ... ) (void)(0)
#define CATCH_SUCCEED( ... ) (void)(0)
#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
// "BDD-style" convenience wrappers
#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
#define CATCH_GIVEN( desc )
#define CATCH_WHEN( desc )
#define CATCH_AND_WHEN( desc )
#define CATCH_THEN( desc )
#define CATCH_AND_THEN( desc )
// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
#else
#define REQUIRE( ... ) (void)(0)
#define REQUIRE_FALSE( ... ) (void)(0)
#define REQUIRE_THROWS( ... ) (void)(0)
#define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
#define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
#endif // CATCH_CONFIG_DISABLE_MATCHERS
#define REQUIRE_NOTHROW( ... ) (void)(0)
#define CHECK( ... ) (void)(0)
#define CHECK_FALSE( ... ) (void)(0)
#define CHECKED_IF( ... ) if (__VA_ARGS__)
#define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
#define CHECK_NOFAIL( ... ) (void)(0)
#define CHECK_THROWS( ... ) (void)(0)
#define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
#define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
#endif // CATCH_CONFIG_DISABLE_MATCHERS
#define CHECK_NOTHROW( ... ) (void)(0)
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#define CHECK_THAT( arg, matcher ) (void)(0)
#define REQUIRE_THAT( arg, matcher ) (void)(0)
#endif // CATCH_CONFIG_DISABLE_MATCHERS
#define INFO( msg ) (void)(0)
#define WARN( msg ) (void)(0)
#define CAPTURE( msg ) (void)(0)
#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
#define METHOD_AS_TEST_CASE( method, ... )
#define REGISTER_TEST_CASE( Function, ... ) (void)(0)
#define SECTION( ... )
#define FAIL( ... ) (void)(0)
#define FAIL_CHECK( ... ) (void)(0)
#define SUCCEED( ... ) (void)(0)
#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
#endif
#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
// "BDD-style" convenience wrappers
#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) )
#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
#define GIVEN( desc )
#define WHEN( desc )
#define AND_WHEN( desc )
#define THEN( desc )
#define AND_THEN( desc )
using Catch::Detail::Approx;
#endif
#endif // ! CATCH_CONFIG_IMPL_ONLY
#include "internal/catch_reenable_warnings.h"
#endif // TWOBLUECUBES_CATCH_HPP_INCLUDED

View File

@ -1,219 +0,0 @@
/*
* Created by Phil on 31/10/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
#include "internal/catch_commandline.hpp"
#include "internal/catch_list.hpp"
#include "internal/catch_run_context.hpp"
#include "internal/catch_test_spec.hpp"
#include "internal/catch_version.h"
#include "internal/catch_text.h"
#include <fstream>
#include <stdlib.h>
#include <limits>
namespace Catch {
Ptr<IStreamingReporter> createReporter( std::string const& reporterName, Ptr<Config> const& config ) {
Ptr<IStreamingReporter> reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() );
if( !reporter ) {
std::ostringstream oss;
oss << "No reporter registered with name: '" << reporterName << "'";
throw std::domain_error( oss.str() );
}
return reporter;
}
Ptr<IStreamingReporter> makeReporter( Ptr<Config> const& config ) {
std::vector<std::string> reporters = config->getReporterNames();
if( reporters.empty() )
reporters.push_back( "console" );
Ptr<IStreamingReporter> reporter;
for( std::vector<std::string>::const_iterator it = reporters.begin(), itEnd = reporters.end();
it != itEnd;
++it )
reporter = addReporter( reporter, createReporter( *it, config ) );
return reporter;
}
Ptr<IStreamingReporter> addListeners( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> reporters ) {
IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners();
for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end();
it != itEnd;
++it )
reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) );
return reporters;
}
Totals runTests( Ptr<Config> const& config ) {
Ptr<IConfig const> iconfig = config.get();
Ptr<IStreamingReporter> reporter = makeReporter( config );
reporter = addListeners( iconfig, reporter );
RunContext context( iconfig, reporter );
Totals totals;
context.testGroupStarting( config->name(), 1, 1 );
TestSpec testSpec = config->testSpec();
if( !testSpec.hasFilters() )
testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests
std::vector<TestCase> const& allTestCases = getAllTestCasesSorted( *iconfig );
for( std::vector<TestCase>::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end();
it != itEnd;
++it ) {
if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) )
totals += context.runTest( *it );
else
reporter->skipTest( *it );
}
context.testGroupEnded( iconfig->name(), totals, 1, 1 );
return totals;
}
void applyFilenamesAsTags( IConfig const& config ) {
std::vector<TestCase> const& tests = getAllTestCasesSorted( config );
for(std::size_t i = 0; i < tests.size(); ++i ) {
TestCase& test = const_cast<TestCase&>( tests[i] );
std::set<std::string> tags = test.tags;
std::string filename = test.lineInfo.file;
std::string::size_type lastSlash = filename.find_last_of( "\\/" );
if( lastSlash != std::string::npos )
filename = filename.substr( lastSlash+1 );
std::string::size_type lastDot = filename.find_last_of( "." );
if( lastDot != std::string::npos )
filename = filename.substr( 0, lastDot );
tags.insert( "#" + filename );
setTags( test, tags );
}
}
class Session : NonCopyable {
static bool alreadyInstantiated;
public:
struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; };
Session()
: m_cli( makeCommandLineParser() ) {
if( alreadyInstantiated ) {
std::string msg = "Only one instance of Catch::Session can ever be used";
Catch::cerr() << msg << std::endl;
throw std::logic_error( msg );
}
alreadyInstantiated = true;
}
~Session() {
Catch::cleanUp();
}
void showHelp( std::string const& processName ) {
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;
}
int applyCommandLine( int argc, char const* const* const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
try {
m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData );
if( m_configData.showHelp )
showHelp( m_configData.processName );
m_config.reset();
}
catch( std::exception& ex ) {
{
Colour colourGuard( Colour::Red );
Catch::cerr()
<< "\nError(s) in input:\n"
<< Text( ex.what(), TextAttributes().setIndent(2) )
<< "\n\n";
}
m_cli.usage( Catch::cout(), m_configData.processName );
return (std::numeric_limits<int>::max)();
}
return 0;
}
void useConfigData( ConfigData const& _configData ) {
m_configData = _configData;
m_config.reset();
}
int run( int argc, char const* const* const argv ) {
int returnCode = applyCommandLine( argc, argv );
if( returnCode == 0 )
returnCode = run();
return returnCode;
}
int run() {
if( m_configData.showHelp )
return 0;
try
{
config(); // Force config to be constructed
seedRng( *m_config );
if( m_configData.filenamesAsTags )
applyFilenamesAsTags( *m_config );
// Handle list request
if( Option<std::size_t> listed = list( config() ) )
return static_cast<int>( *listed );
return static_cast<int>( runTests( m_config ).assertions.failed );
}
catch( std::exception& ex ) {
Catch::cerr() << ex.what() << std::endl;
return (std::numeric_limits<int>::max)();
}
}
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;
Ptr<Config> m_config;
};
bool Session::alreadyInstantiated = false;
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED

1048
include/external/clara.h vendored

File diff suppressed because it is too large Load Diff

1240
include/external/clara.hpp vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,153 +0,0 @@
/*
* Created by Phil on 18/4/2013.
* Copyright 2013 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
// Only use header guard if we are not using an outer namespace
#ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
# ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
# ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
# define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
# endif
# else
# define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
# endif
#endif
#ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
#include <string>
#include <vector>
#include <sstream>
// Use optional outer namespace
#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
#endif
namespace Tbc {
#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
#else
const unsigned int consoleWidth = 80;
#endif
struct TextAttributes {
TextAttributes()
: initialIndent( std::string::npos ),
indent( 0 ),
width( consoleWidth-1 ),
tabChar( '\t' )
{}
TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
std::size_t initialIndent; // indent of first line, or npos
std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
std::size_t width; // maximum width of text, including indent. Longer text will wrap
char tabChar; // If this char is seen the indent is changed to current pos
};
class Text {
public:
Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
: attr( _attr )
{
std::string wrappableChars = " [({.,/|\\-";
std::size_t indent = _attr.initialIndent != std::string::npos
? _attr.initialIndent
: _attr.indent;
std::string remainder = _str;
while( !remainder.empty() ) {
if( lines.size() >= 1000 ) {
lines.push_back( "... message truncated due to excessive size" );
return;
}
std::size_t tabPos = std::string::npos;
std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
std::size_t pos = remainder.find_first_of( '\n' );
if( pos <= width ) {
width = pos;
}
pos = remainder.find_last_of( _attr.tabChar, width );
if( pos != std::string::npos ) {
tabPos = pos;
if( remainder[width] == '\n' )
width--;
remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
}
if( width == remainder.size() ) {
spliceLine( indent, remainder, width );
}
else if( remainder[width] == '\n' ) {
spliceLine( indent, remainder, width );
if( width <= 1 || remainder.size() != 1 )
remainder = remainder.substr( 1 );
indent = _attr.indent;
}
else {
pos = remainder.find_last_of( wrappableChars, width );
if( pos != std::string::npos && pos > 0 ) {
spliceLine( indent, remainder, pos );
if( remainder[0] == ' ' )
remainder = remainder.substr( 1 );
}
else {
spliceLine( indent, remainder, width-1 );
lines.back() += "-";
}
if( lines.size() == 1 )
indent = _attr.indent;
if( tabPos != std::string::npos )
indent += tabPos;
}
}
}
void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
_remainder = _remainder.substr( _pos );
}
typedef std::vector<std::string>::const_iterator const_iterator;
const_iterator begin() const { return lines.begin(); }
const_iterator end() const { return lines.end(); }
std::string const& last() const { return lines.back(); }
std::size_t size() const { return lines.size(); }
std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
std::string toString() const {
std::ostringstream oss;
oss << *this;
return oss.str();
}
inline 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() )
_stream << "\n";
_stream << *it;
}
return _stream;
}
private:
std::string str;
TextAttributes attr;
std::vector<std::string> lines;
};
} // end namespace Tbc
#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
} // end outer namespace
#endif
#endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED

View File

@ -0,0 +1,56 @@
/*
* Created by Martin on 19/07/2017.
* Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include "catch_approx.h"
#include <cmath>
#include <limits>
namespace {
// Performs equivalent check of std::fabs(lhs - rhs) <= margin
// But without the subtraction to allow for INFINITY in comparison
bool marginComparison(double lhs, double rhs, double margin) {
return (lhs + margin >= rhs) && (rhs + margin >= lhs);
}
}
namespace Catch {
namespace Detail {
Approx::Approx ( double value )
: m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
m_margin( 0.0 ),
m_scale( 0.0 ),
m_value( value )
{}
Approx Approx::custom() {
return Approx( 0 );
}
std::string Approx::toString() const {
ReusableStringStream rss;
rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
return rss.str();
}
bool Approx::equalityComparisonImpl(const double other) const {
// First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
// Thanks to Richard Harris for his help refining the scaled margin value
return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
}
} // end namespace Detail
std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
return value.toString();
}
} // end namespace Catch

View File

@ -0,0 +1,133 @@
/*
* Created by Phil on 28/04/2011.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
#include "catch_tostring.h"
#include <type_traits>
#include <stdexcept>
namespace Catch {
namespace Detail {
class Approx {
private:
bool equalityComparisonImpl(double other) const;
public:
explicit Approx ( double value );
static Approx custom();
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
Approx operator()( T const& value ) {
Approx approx( static_cast<double>(value) );
approx.epsilon( m_epsilon );
approx.margin( m_margin );
approx.scale( m_scale );
return approx;
}
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
explicit Approx( T const& 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 ) {
auto lhs_v = static_cast<double>(lhs);
return rhs.equalityComparisonImpl(lhs_v);
}
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
friend bool operator == ( Approx const& lhs, const T& rhs ) {
return operator==( rhs, lhs );
}
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
friend bool operator != ( T const& lhs, Approx const& rhs ) {
return !operator==( lhs, rhs );
}
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
friend bool operator != ( Approx const& lhs, T const& rhs ) {
return !operator==( rhs, lhs );
}
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
friend bool operator <= ( T const& lhs, Approx const& rhs ) {
return static_cast<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 const& rhs ) {
return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
}
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
friend bool operator >= ( T const& lhs, Approx const& rhs ) {
return static_cast<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 const& rhs ) {
return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
}
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
Approx& epsilon( T const& newEpsilon ) {
double epsilonAsDouble = static_cast<double>(newEpsilon);
if( epsilonAsDouble < 0 || epsilonAsDouble > 1.0 ) {
throw std::domain_error
( "Invalid Approx::epsilon: " +
Catch::Detail::stringify( epsilonAsDouble ) +
", Approx::epsilon has to be between 0 and 1" );
}
m_epsilon = epsilonAsDouble;
return *this;
}
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
Approx& margin( T const& newMargin ) {
double marginAsDouble = static_cast<double>(newMargin);
if( marginAsDouble < 0 ) {
throw std::domain_error
( "Invalid Approx::margin: " +
Catch::Detail::stringify( marginAsDouble ) +
", Approx::Margin has to be non-negative." );
}
m_margin = marginAsDouble;
return *this;
}
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
Approx& scale( T const& newScale ) {
m_scale = static_cast<double>(newScale);
return *this;
}
std::string toString() const;
private:
double m_epsilon;
double m_margin;
double m_scale;
double m_value;
};
}
template<>
struct StringMaker<Catch::Detail::Approx> {
static std::string convert(Catch::Detail::Approx const& value);
};
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED

View File

@ -1,91 +0,0 @@
/*
* Created by Phil on 28/04/2011.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
#include "catch_tostring.h"
#include <cmath>
#include <limits>
namespace Catch {
namespace Detail {
class Approx {
public:
explicit Approx ( double value )
: m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
m_scale( 1.0 ),
m_value( value )
{}
Approx( Approx const& other )
: m_epsilon( other.m_epsilon ),
m_scale( other.m_scale ),
m_value( other.m_value )
{}
static Approx custom() {
return Approx( 0 );
}
Approx operator()( double value ) {
Approx approx( value );
approx.epsilon( m_epsilon );
approx.scale( m_scale );
return approx;
}
friend bool operator == ( double lhs, Approx const& rhs ) {
// Thanks to Richard Harris for his help refining this formula
return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
}
friend bool operator == ( Approx const& lhs, double rhs ) {
return operator==( rhs, lhs );
}
friend bool operator != ( double lhs, Approx const& rhs ) {
return !operator==( lhs, rhs );
}
friend bool operator != ( Approx const& lhs, double rhs ) {
return !operator==( rhs, lhs );
}
Approx& epsilon( double newEpsilon ) {
m_epsilon = newEpsilon;
return *this;
}
Approx& scale( double newScale ) {
m_scale = newScale;
return *this;
}
std::string toString() const {
std::ostringstream oss;
oss << "Approx( " << Catch::toString( m_value ) << " )";
return oss.str();
}
private:
double m_epsilon;
double m_scale;
double m_value;
};
}
template<>
inline std::string toString<Detail::Approx>( Detail::Approx const& value ) {
return value.toString();
}
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED

View File

@ -0,0 +1,114 @@
/*
* Created by Phil on 8/8/2017.
* Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include "catch_assertionhandler.h"
#include "catch_assertionresult.h"
#include "catch_interfaces_runner.h"
#include "catch_interfaces_config.h"
#include "catch_context.h"
#include "catch_debugger.h"
#include "catch_interfaces_registry_hub.h"
#include "catch_capture_matchers.h"
#include "catch_run_context.h"
namespace Catch {
auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
expr.streamReconstructedExpression( os );
return os;
}
LazyExpression::LazyExpression( bool isNegated )
: m_isNegated( isNegated )
{}
LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {}
LazyExpression::operator bool() const {
return m_transientExpression != nullptr;
}
auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& {
if( lazyExpr.m_isNegated )
os << "!";
if( lazyExpr ) {
if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )
os << "(" << *lazyExpr.m_transientExpression << ")";
else
os << *lazyExpr.m_transientExpression;
}
else {
os << "{** error - unchecked empty expression requested **}";
}
return os;
}
AssertionHandler::AssertionHandler
( StringRef macroName,
SourceLineInfo const& lineInfo,
StringRef capturedExpression,
ResultDisposition::Flags resultDisposition )
: m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
m_resultCapture( getResultCapture() )
{}
void AssertionHandler::handleExpr( ITransientExpression const& expr ) {
m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );
}
void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) {
m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction );
}
auto AssertionHandler::allowThrows() const -> bool {
return getCurrentContext().getConfig()->allowThrows();
}
void AssertionHandler::complete() {
setCompleted();
if( m_reaction.shouldDebugBreak ) {
// If you find your debugger stopping you here then go one level up on the
// call-stack for the code that caused it (typically a failed assertion)
// (To go back to the test and change execution, jump over the throw, next)
CATCH_BREAK_INTO_DEBUGGER();
}
if( m_reaction.shouldThrow )
throw Catch::TestFailureException();
}
void AssertionHandler::setCompleted() {
m_completed = true;
}
void AssertionHandler::handleUnexpectedInflightException() {
m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );
}
void AssertionHandler::handleExceptionThrownAsExpected() {
m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
}
void AssertionHandler::handleExceptionNotThrownAsExpected() {
m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
}
void AssertionHandler::handleUnexpectedExceptionNotThrown() {
m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction );
}
void AssertionHandler::handleThrowingCallSkipped() {
m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
}
// This is the overload that takes a string and infers the Equals matcher from it
// The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef matcherString ) {
handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
}
} // namespace Catch

View File

@ -0,0 +1,88 @@
/*
* Created by Phil on 8/8/2017.
* Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_ASSERTIONHANDLER_H_INCLUDED
#define TWOBLUECUBES_CATCH_ASSERTIONHANDLER_H_INCLUDED
#include "catch_assertioninfo.h"
#include "catch_decomposer.h"
#include "catch_interfaces_capture.h"
namespace Catch {
struct TestFailureException{};
struct AssertionResultData;
struct IResultCapture;
class RunContext;
class LazyExpression {
friend class AssertionHandler;
friend struct AssertionStats;
friend class RunContext;
ITransientExpression const* m_transientExpression = nullptr;
bool m_isNegated;
public:
LazyExpression( bool isNegated );
LazyExpression( LazyExpression const& other );
LazyExpression& operator = ( LazyExpression const& ) = delete;
explicit operator bool() const;
friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;
};
struct AssertionReaction {
bool shouldDebugBreak = false;
bool shouldThrow = false;
};
class AssertionHandler {
AssertionInfo m_assertionInfo;
AssertionReaction m_reaction;
bool m_completed = false;
IResultCapture& m_resultCapture;
public:
AssertionHandler
( StringRef macroName,
SourceLineInfo const& lineInfo,
StringRef capturedExpression,
ResultDisposition::Flags resultDisposition );
~AssertionHandler() {
if ( !m_completed ) {
m_resultCapture.handleIncomplete( m_assertionInfo );
}
}
template<typename T>
void handleExpr( ExprLhs<T> const& expr ) {
handleExpr( expr.makeUnaryExpr() );
}
void handleExpr( ITransientExpression const& expr );
void handleMessage(ResultWas::OfType resultType, StringRef const& message);
void handleExceptionThrownAsExpected();
void handleUnexpectedExceptionNotThrown();
void handleExceptionNotThrownAsExpected();
void handleThrowingCallSkipped();
void handleUnexpectedInflightException();
void complete();
void setCompleted();
// query
auto allowThrows() const -> bool;
};
void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef matcherString );
} // namespace Catch
#endif // TWOBLUECUBES_CATCH_ASSERTIONHANDLER_H_INCLUDED

View File

@ -0,0 +1,31 @@
/*
* Created by Phil on 8/8/2017.
* Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_ASSERTIONINFO_H_INCLUDED
#define TWOBLUECUBES_CATCH_ASSERTIONINFO_H_INCLUDED
#include "catch_result_type.h"
#include "catch_common.h"
#include "catch_stringref.h"
namespace Catch {
struct AssertionInfo
{
StringRef macroName;
SourceLineInfo lineInfo;
StringRef capturedExpression;
ResultDisposition::Flags resultDisposition;
// We want to delete this constructor but a compiler bug in 4.8 means
// the struct is then treated as non-aggregate
//AssertionInfo() = delete;
};
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_ASSERTIONINFO_H_INCLUDED

View File

@ -5,33 +5,31 @@
* 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_ASSERTIONRESULT_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED
#include "catch_assertionresult.h"
namespace Catch {
AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression):
lazyExpression(_lazyExpression),
resultType(_resultType) {}
std::string AssertionResultData::reconstructExpression() const {
AssertionInfo::AssertionInfo( std::string const& _macroName,
SourceLineInfo const& _lineInfo,
std::string const& _capturedExpression,
ResultDisposition::Flags _resultDisposition )
: macroName( _macroName ),
lineInfo( _lineInfo ),
capturedExpression( _capturedExpression ),
resultDisposition( _resultDisposition )
{}
AssertionResult::AssertionResult() {}
if( reconstructedExpression.empty() ) {
if( lazyExpression ) {
ReusableStringStream rss;
rss << lazyExpression;
reconstructedExpression = rss.str();
}
}
return reconstructedExpression;
}
AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
: m_info( info ),
m_resultData( data )
{}
AssertionResult::~AssertionResult() {}
// Result was a success
bool AssertionResult::succeeded() const {
return Catch::isOk( m_resultData.resultType );
@ -47,7 +45,7 @@ namespace Catch {
}
bool AssertionResult::hasExpression() const {
return !m_info.capturedExpression.empty();
return m_info.capturedExpression[0] != 0;
}
bool AssertionResult::hasMessage() const {
@ -56,15 +54,23 @@ namespace Catch {
std::string AssertionResult::getExpression() const {
if( isFalseTest( m_info.resultDisposition ) )
return "!" + m_info.capturedExpression;
return "!(" + m_info.capturedExpression + ")";
else
return m_info.capturedExpression;
}
std::string AssertionResult::getExpressionInMacro() const {
if( m_info.macroName.empty() )
return m_info.capturedExpression;
else
return m_info.macroName + "( " + m_info.capturedExpression + " )";
std::string expr;
if( m_info.macroName[0] == 0 )
expr = m_info.capturedExpression;
else {
expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
expr += m_info.macroName.c_str();
expr += "( ";
expr += m_info.capturedExpression.c_str();
expr += " )";
}
return expr;
}
bool AssertionResult::hasExpandedExpression() const {
@ -72,7 +78,10 @@ namespace Catch {
}
std::string AssertionResult::getExpandedExpression() const {
return m_resultData.reconstructedExpression;
std::string expr = m_resultData.reconstructExpression();
return expr.empty()
? getExpression()
: expr;
}
std::string AssertionResult::getMessage() const {
@ -82,10 +91,8 @@ namespace Catch {
return m_info.lineInfo;
}
std::string AssertionResult::getTestMacroName() const {
StringRef AssertionResult::getTestMacroName() const {
return m_info.macroName;
}
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED

View File

@ -9,44 +9,32 @@
#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
#include <string>
#include "catch_assertioninfo.h"
#include "catch_result_type.h"
#include "catch_common.h"
#include "catch_stringref.h"
#include "catch_assertionhandler.h"
namespace Catch {
struct AssertionInfo
{
AssertionInfo() {}
AssertionInfo( std::string const& _macroName,
SourceLineInfo const& _lineInfo,
std::string const& _capturedExpression,
ResultDisposition::Flags _resultDisposition );
std::string macroName;
SourceLineInfo lineInfo;
std::string capturedExpression;
ResultDisposition::Flags resultDisposition;
};
struct AssertionResultData
{
AssertionResultData() : resultType( ResultWas::Unknown ) {}
AssertionResultData() = delete;
AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression );
std::string reconstructedExpression;
std::string message;
mutable std::string reconstructedExpression;
LazyExpression lazyExpression;
ResultWas::OfType resultType;
std::string reconstructExpression() const;
};
class AssertionResult {
public:
AssertionResult();
AssertionResult() = delete;
AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
~AssertionResult();
# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
AssertionResult( AssertionResult const& ) = default;
AssertionResult( AssertionResult && ) = default;
AssertionResult& operator = ( AssertionResult const& ) = default;
AssertionResult& operator = ( AssertionResult && ) = default;
# endif
bool isOk() const;
bool succeeded() const;
@ -59,9 +47,9 @@ namespace Catch {
std::string getExpandedExpression() const;
std::string getMessage() const;
SourceLineInfo getSourceInfo() const;
std::string getTestMacroName() const;
StringRef getTestMacroName() const;
protected:
//protected:
AssertionInfo m_info;
AssertionResultData m_resultData;
};

View File

@ -0,0 +1,36 @@
/*
* Created by Phil on 04/07/2017.
* Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include "catch_benchmark.h"
#include "catch_capture.hpp"
#include "catch_interfaces_reporter.h"
#include "catch_context.h"
namespace Catch {
auto BenchmarkLooper::getResolution() -> uint64_t {
return getEstimatedClockResolution() * getCurrentContext().getConfig()->benchmarkResolutionMultiple();
}
void BenchmarkLooper::reportStart() {
getResultCapture().benchmarkStarting( { m_name } );
}
auto BenchmarkLooper::needsMoreIterations() -> bool {
auto elapsed = m_timer.getElapsedNanoseconds();
// Exponentially increasing iterations until we're confident in our timer resolution
if( elapsed < m_resolution ) {
m_iterationsToRun *= 10;
return true;
}
getResultCapture().benchmarkEnded( { { m_name }, m_count, elapsed } );
return false;
}
} // end namespace Catch

View File

@ -0,0 +1,57 @@
/*
* Created by Phil on 04/07/2017.
* Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_BENCHMARK_H_INCLUDED
#define TWOBLUECUBES_CATCH_BENCHMARK_H_INCLUDED
#include "catch_stringref.h"
#include "catch_timer.h"
#include <cstdint>
#include <string>
namespace Catch {
class BenchmarkLooper {
std::string m_name;
std::size_t m_count = 0;
std::size_t m_iterationsToRun = 1;
uint64_t m_resolution;
Timer m_timer;
static auto getResolution() -> uint64_t;
public:
// Keep most of this inline as it's on the code path that is being timed
BenchmarkLooper( StringRef name )
: m_name( name ),
m_resolution( getResolution() )
{
reportStart();
m_timer.start();
}
explicit operator bool() {
if( m_count < m_iterationsToRun )
return true;
return needsMoreIterations();
}
void increment() {
++m_count;
}
void reportStart();
auto needsMoreIterations() -> bool;
};
} // end namespace Catch
#define BENCHMARK( name ) \
for( Catch::BenchmarkLooper looper( name ); looper; looper.increment() )
#endif // TWOBLUECUBES_CATCH_BENCHMARK_H_INCLUDED

View File

@ -8,141 +8,140 @@
#ifndef TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
#include "catch_result_builder.h"
#include "catch_assertionhandler.h"
#include "catch_message.h"
#include "catch_interfaces_capture.h"
#include "catch_debugger.h"
#include "catch_common.h"
#include "catch_tostring.h"
#include "catch_interfaces_runner.h"
#include "catch_compiler_capabilities.h"
#if !defined(CATCH_CONFIG_DISABLE)
///////////////////////////////////////////////////////////////////////////////
// In the event of a failure works out if the debugger needs to be invoked
// and/or an exception thrown and takes appropriate action.
// This needs to be done as a macro so the debugger will stop in the user
// source code rather than in Catch library code
#define INTERNAL_CATCH_REACT( resultBuilder ) \
if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
resultBuilder.react();
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
try { \
CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
( __catchResult <= expr ).endExpression(); \
} \
catch( ... ) { \
__catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
} \
INTERNAL_CATCH_REACT( __catchResult ) \
} while( Catch::isTrue( false && !!(expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
if( Catch::getResultCapture().getLastResult()->succeeded() )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \
INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
if( !Catch::getResultCapture().getLastResult()->succeeded() )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
try { \
expr; \
__catchResult.captureResult( Catch::ResultWas::Ok ); \
} \
catch( ... ) { \
__catchResult.useActiveException( resultDisposition ); \
} \
INTERNAL_CATCH_REACT( __catchResult ) \
} while( Catch::alwaysFalse() )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_THROWS( expr, resultDisposition, matcher, macroName ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \
if( __catchResult.allowThrows() ) \
try { \
expr; \
__catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
} \
catch( ... ) { \
__catchResult.captureExpectedException( matcher ); \
} \
else \
__catchResult.captureResult( Catch::ResultWas::Ok ); \
INTERNAL_CATCH_REACT( __catchResult ) \
} while( Catch::alwaysFalse() )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
if( __catchResult.allowThrows() ) \
try { \
expr; \
__catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
} \
catch( exceptionType ) { \
__catchResult.captureResult( Catch::ResultWas::Ok ); \
} \
catch( ... ) { \
__catchResult.useActiveException( resultDisposition ); \
} \
else \
__catchResult.captureResult( Catch::ResultWas::Ok ); \
INTERNAL_CATCH_REACT( __catchResult ) \
} while( Catch::alwaysFalse() )
///////////////////////////////////////////////////////////////////////////////
#ifdef CATCH_CONFIG_VARIADIC_MACROS
#define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
__catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
__catchResult.captureResult( messageType ); \
INTERNAL_CATCH_REACT( __catchResult ) \
} while( Catch::alwaysFalse() )
#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
#define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
#else
#define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
__catchResult << log + ::Catch::StreamEndStop(); \
__catchResult.captureResult( messageType ); \
INTERNAL_CATCH_REACT( __catchResult ) \
} while( Catch::alwaysFalse() )
#define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
#endif
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_INFO( log, macroName ) \
Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
#if defined(CATCH_CONFIG_FAST_COMPILE)
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
// Another way to speed-up compilation is to omit local try-catch for REQUIRE*
// macros.
#define INTERNAL_CATCH_TRY
#define INTERNAL_CATCH_CATCH( capturer )
#else // CATCH_CONFIG_FAST_COMPILE
#define INTERNAL_CATCH_TRY try
#define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }
#endif
#define INTERNAL_CATCH_REACT( handler ) handler.complete();
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \
Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
INTERNAL_CATCH_TRY { \
CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
} INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
INTERNAL_CATCH_REACT( catchAssertionHandler ) \
} while( (void)0, false && static_cast<bool>( !!(__VA_ARGS__) ) ) // the expression 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_CATCH_IF( macroName, resultDisposition, ... ) \
INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
if( Catch::getResultCapture().lastAssertionPassed() )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
if( !Catch::getResultCapture().lastAssertionPassed() )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
do { \
Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
try { \
std::string matcherAsString = (matcher).toString(); \
__catchResult \
.setLhs( Catch::toString( arg ) ) \
.setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
.setOp( "matches" ) \
.setResultType( (matcher).match( arg ) ); \
__catchResult.captureExpression(); \
} catch( ... ) { \
__catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
static_cast<void>(__VA_ARGS__); \
catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
} \
INTERNAL_CATCH_REACT( __catchResult ) \
} while( Catch::alwaysFalse() )
catch( ... ) { \
catchAssertionHandler.handleUnexpectedInflightException(); \
} \
INTERNAL_CATCH_REACT( catchAssertionHandler ) \
} while( false )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
do { \
Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
if( catchAssertionHandler.allowThrows() ) \
try { \
static_cast<void>(__VA_ARGS__); \
catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
} \
catch( ... ) { \
catchAssertionHandler.handleExceptionThrownAsExpected(); \
} \
else \
catchAssertionHandler.handleThrowingCallSkipped(); \
INTERNAL_CATCH_REACT( catchAssertionHandler ) \
} while( false )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
do { \
Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
if( catchAssertionHandler.allowThrows() ) \
try { \
static_cast<void>(expr); \
catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
} \
catch( exceptionType const& ) { \
catchAssertionHandler.handleExceptionThrownAsExpected(); \
} \
catch( ... ) { \
catchAssertionHandler.handleUnexpectedInflightException(); \
} \
else \
catchAssertionHandler.handleThrowingCallSkipped(); \
INTERNAL_CATCH_REACT( catchAssertionHandler ) \
} while( false )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
do { \
Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
INTERNAL_CATCH_REACT( catchAssertionHandler ) \
} while( false )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_INFO( macroName, log ) \
Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
///////////////////////////////////////////////////////////////////////////////
// Although this is matcher-based, it can be used with just a string
#define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
do { \
Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
if( catchAssertionHandler.allowThrows() ) \
try { \
static_cast<void>(__VA_ARGS__); \
catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
} \
catch( ... ) { \
Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher ); \
} \
else \
catchAssertionHandler.handleThrowingCallSkipped(); \
INTERNAL_CATCH_REACT( catchAssertionHandler ) \
} while( false )
#endif // CATCH_CONFIG_DISABLE
#endif // TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED

View File

@ -0,0 +1,24 @@
/*
* Created by Phil on 9/8/2017.
* Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include "catch_capture_matchers.h"
#include "catch_interfaces_registry_hub.h"
namespace Catch {
using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
// This is the general overload that takes a any string matcher
// There is another overload, in catch_assertinhandler.h/.cpp, that only takes a string and infers
// the Equals matcher (so the header does not mention matchers)
void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString ) {
std::string exceptionMessage = Catch::translateActiveException();
MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );
handler.handleExpr( expr );
}
} // namespace Catch

View File

@ -0,0 +1,85 @@
/*
* Created by Phil on 9/8/2017
* Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_CAPTURE_MATCHERS_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_CAPTURE_MATCHERS_HPP_INCLUDED
#include "catch_capture.hpp"
#include "catch_matchers.h"
#include "catch_matchers_floating.h"
#include "catch_matchers_string.h"
#include "catch_matchers_vector.h"
namespace Catch {
template<typename ArgT, typename MatcherT>
class MatchExpr : public ITransientExpression {
ArgT const& m_arg;
MatcherT m_matcher;
StringRef m_matcherString;
public:
MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef matcherString )
: ITransientExpression{ true, matcher.match( arg ) },
m_arg( arg ),
m_matcher( matcher ),
m_matcherString( matcherString )
{}
void streamReconstructedExpression( std::ostream &os ) const override {
auto matcherAsString = m_matcher.toString();
os << Catch::Detail::stringify( m_arg ) << ' ';
if( matcherAsString == Detail::unprintableString )
os << m_matcherString;
else
os << matcherAsString;
}
};
using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString );
template<typename ArgT, typename MatcherT>
auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef matcherString ) -> MatchExpr<ArgT, MatcherT> {
return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
}
} // namespace Catch
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
do { \
Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
INTERNAL_CATCH_TRY { \
catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher ) ); \
} INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
INTERNAL_CATCH_REACT( catchAssertionHandler ) \
} while( false )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
do { \
Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
if( catchAssertionHandler.allowThrows() ) \
try { \
static_cast<void>(__VA_ARGS__ ); \
catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
} \
catch( exceptionType const& ex ) { \
catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher ) ); \
} \
catch( ... ) { \
catchAssertionHandler.handleUnexpectedInflightException(); \
} \
else \
catchAssertionHandler.handleThrowingCallSkipped(); \
INTERNAL_CATCH_REACT( catchAssertionHandler ) \
} while( false )
#endif // TWOBLUECUBES_CATCH_CAPTURE_MATCHERS_HPP_INCLUDED

View File

@ -11,21 +11,27 @@
// Use Catch's value for console width (store Clara's off to the side, if present)
#ifdef CLARA_CONFIG_CONSOLE_WIDTH
#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
#undef CLARA_CONFIG_CONSOLE_WIDTH
#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
#undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
#endif
#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wweak-vtables"
#pragma clang diagnostic ignored "-Wexit-time-destructors"
#pragma clang diagnostic ignored "-Wshadow"
#endif
// Declare Clara inside the Catch namespace
#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
#include "../external/clara.h"
#undef STITCH_CLARA_OPEN_NAMESPACE
#include "../external/clara.hpp"
#ifdef __clang__
#pragma clang diagnostic pop
#endif
// Restore Clara's value for console width, if present
#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
#endif

View File

@ -0,0 +1,184 @@
/*
* Created by Phil on 02/11/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include "catch_commandline.h"
#include "catch_string_manip.h"
#include <fstream>
#include <ctime>
namespace Catch {
clara::Parser makeCommandLineParser( ConfigData& config ) {
using namespace clara;
auto const setWarning = [&]( std::string const& warning ) {
if( warning != "NoAssertions" )
return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" );
config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
return ParserResult::ok( ParseResultType::Matched );
};
auto const loadTestNamesFromFile = [&]( std::string const& filename ) {
std::ifstream f( filename.c_str() );
if( !f.is_open() )
return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" );
std::string line;
while( std::getline( f, line ) ) {
line = trim(line);
if( !line.empty() && !startsWith( line, '#' ) ) {
if( !startsWith( line, '"' ) )
line = '"' + line + '"';
config.testsOrTags.push_back( line + ',' );
}
}
return ParserResult::ok( ParseResultType::Matched );
};
auto const setTestOrder = [&]( std::string const& order ) {
if( startsWith( "declared", order ) )
config.runOrder = RunTests::InDeclarationOrder;
else if( startsWith( "lexical", order ) )
config.runOrder = RunTests::InLexicographicalOrder;
else if( startsWith( "random", order ) )
config.runOrder = RunTests::InRandomOrder;
else
return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" );
return ParserResult::ok( ParseResultType::Matched );
};
auto const setRngSeed = [&]( std::string const& seed ) {
if( seed != "time" )
return clara::detail::convertInto( seed, config.rngSeed );
config.rngSeed = static_cast<unsigned int>( std::time(nullptr) );
return ParserResult::ok( ParseResultType::Matched );
};
auto const setColourUsage = [&]( std::string const& useColour ) {
auto mode = toLower( useColour );
if( mode == "yes" )
config.useColour = UseColour::Yes;
else if( mode == "no" )
config.useColour = UseColour::No;
else if( mode == "auto" )
config.useColour = UseColour::Auto;
else
return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" );
return ParserResult::ok( ParseResultType::Matched );
};
auto const setWaitForKeypress = [&]( std::string const& keypress ) {
auto 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
return ParserResult::runtimeError( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" );
return ParserResult::ok( ParseResultType::Matched );
};
auto const setVerbosity = [&]( std::string const& verbosity ) {
auto lcVerbosity = toLower( verbosity );
if( lcVerbosity == "quiet" )
config.verbosity = Verbosity::Quiet;
else if( lcVerbosity == "normal" )
config.verbosity = Verbosity::Normal;
else if( lcVerbosity == "high" )
config.verbosity = Verbosity::High;
else
return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" );
return ParserResult::ok( ParseResultType::Matched );
};
auto cli
= ExeName( config.processName )
| Help( config.showHelp )
| Opt( config.listTests )
["-l"]["--list-tests"]
( "list all/matching test cases" )
| Opt( config.listTags )
["-t"]["--list-tags"]
( "list all/matching tags" )
| Opt( config.showSuccessfulTests )
["-s"]["--success"]
( "include successful tests in output" )
| Opt( config.shouldDebugBreak )
["-b"]["--break"]
( "break into debugger on failure" )
| Opt( config.noThrow )
["-e"]["--nothrow"]
( "skip exception tests" )
| Opt( config.showInvisibles )
["-i"]["--invisibles"]
( "show invisibles (tabs, newlines)" )
| Opt( config.outputFilename, "filename" )
["-o"]["--out"]
( "output filename" )
| Opt( config.reporterNames, "name" )
["-r"]["--reporter"]
( "reporter to use (defaults to console)" )
| Opt( config.name, "name" )
["-n"]["--name"]
( "suite name" )
| Opt( [&]( bool ){ config.abortAfter = 1; } )
["-a"]["--abort"]
( "abort at first failure" )
| Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" )
["-x"]["--abortx"]
( "abort after x failures" )
| Opt( setWarning, "warning name" )
["-w"]["--warn"]
( "enable warnings" )
| Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" )
["-d"]["--durations"]
( "show test durations" )
| Opt( loadTestNamesFromFile, "filename" )
["-f"]["--input-file"]
( "load test names to run from a file" )
| Opt( config.filenamesAsTags )
["-#"]["--filenames-as-tags"]
( "adds a tag for the filename" )
| Opt( config.sectionsToRun, "section name" )
["-c"]["--section"]
( "specify section to run" )
| Opt( setVerbosity, "quiet|normal|high" )
["-v"]["--verbosity"]
( "set output verbosity" )
| Opt( config.listTestNamesOnly )
["--list-test-names-only"]
( "list all/matching test cases names only" )
| Opt( config.listReporters )
["--list-reporters"]
( "list all reporters" )
| Opt( setTestOrder, "decl|lex|rand" )
["--order"]
( "test case order (defaults to decl)" )
| Opt( setRngSeed, "'time'|number" )
["--rng-seed"]
( "set a specific seed for random numbers" )
| Opt( setColourUsage, "yes|no" )
["--use-colour"]
( "should output be colourised" )
| Opt( config.libIdentify )
["--libidentify"]
( "report name and version according to libidentify standard" )
| Opt( setWaitForKeypress, "start|exit|both" )
["--wait-for-keypress"]
( "waits for a keypress before exiting" )
| Opt( config.benchmarkResolutionMultiple, "multiplier" )
["--benchmark-resolution-multiple"]
( "multiple of clock resolution to run benchmarks" )
| Arg( config.testsOrTags, "test name|pattern|tags" )
( "which test or tests to use" );
return cli;
}
} // end namespace Catch

View File

@ -0,0 +1,20 @@
/*
* Created by Phil on 02/11/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
#include "catch_config.hpp"
#include "catch_clara.h"
namespace Catch {
clara::Parser makeCommandLineParser( ConfigData& config );
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED

View File

@ -1,209 +0,0 @@
/*
* Created by Phil on 02/11/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
#include "catch_config.hpp"
#include "catch_common.h"
#include "catch_clara.h"
#include <fstream>
namespace Catch {
inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
inline void abortAfterX( ConfigData& config, int x ) {
if( x < 1 )
throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" );
config.abortAfter = x;
}
inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); }
inline void addWarning( ConfigData& config, std::string const& _warning ) {
if( _warning == "NoAssertions" )
config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
else
throw std::runtime_error( "Unrecognised warning: '" + _warning + "'" );
}
inline void setOrder( ConfigData& config, std::string const& order ) {
if( startsWith( "declared", order ) )
config.runOrder = RunTests::InDeclarationOrder;
else if( startsWith( "lexical", order ) )
config.runOrder = RunTests::InLexicographicalOrder;
else if( startsWith( "random", order ) )
config.runOrder = RunTests::InRandomOrder;
else
throw std::runtime_error( "Unrecognised ordering: '" + order + "'" );
}
inline void setRngSeed( ConfigData& config, std::string const& seed ) {
if( seed == "time" ) {
config.rngSeed = static_cast<unsigned int>( std::time(0) );
}
else {
std::stringstream ss;
ss << seed;
ss >> config.rngSeed;
if( ss.fail() )
throw std::runtime_error( "Argment to --rng-seed should be the word 'time' or a number" );
}
}
inline void setVerbosity( ConfigData& config, int level ) {
// !TBD: accept strings?
config.verbosity = static_cast<Verbosity::Level>( level );
}
inline void setShowDurations( ConfigData& config, bool _showDurations ) {
config.showDurations = _showDurations
? ShowDurations::Always
: ShowDurations::Never;
}
inline void setUseColour( ConfigData& config, std::string const& value ) {
std::string mode = toLower( value );
if( mode == "yes" )
config.useColour = UseColour::Yes;
else if( mode == "no" )
config.useColour = UseColour::No;
else if( mode == "auto" )
config.useColour = UseColour::Auto;
else
throw std::runtime_error( "colour mode must be one of: auto, yes or no" );
}
inline void forceColour( ConfigData& config ) {
config.useColour = UseColour::Yes;
}
inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
std::ifstream f( _filename.c_str() );
if( !f.is_open() )
throw std::domain_error( "Unable to load input file: " + _filename );
std::string line;
while( std::getline( f, line ) ) {
line = trim(line);
if( !line.empty() && !startsWith( line, "#" ) ) {
if( !startsWith( line, "\"" ) )
line = "\"" + line + "\"";
addTestOrTags( config, line + "," );
}
}
}
inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
using namespace Clara;
CommandLine<ConfigData> cli;
cli.bindProcessName( &ConfigData::processName );
cli["-?"]["-h"]["--help"]
.describe( "display usage information" )
.bind( &ConfigData::showHelp );
cli["-l"]["--list-tests"]
.describe( "list all/matching test cases" )
.bind( &ConfigData::listTests );
cli["-t"]["--list-tags"]
.describe( "list all/matching tags" )
.bind( &ConfigData::listTags );
cli["-s"]["--success"]
.describe( "include successful tests in output" )
.bind( &ConfigData::showSuccessfulTests );
cli["-b"]["--break"]
.describe( "break into debugger on failure" )
.bind( &ConfigData::shouldDebugBreak );
cli["-e"]["--nothrow"]
.describe( "skip exception tests" )
.bind( &ConfigData::noThrow );
cli["-i"]["--invisibles"]
.describe( "show invisibles (tabs, newlines)" )
.bind( &ConfigData::showInvisibles );
cli["-o"]["--out"]
.describe( "output filename" )
.bind( &ConfigData::outputFilename, "filename" );
cli["-r"]["--reporter"]
// .placeholder( "name[:filename]" )
.describe( "reporter to use (defaults to console)" )
.bind( &addReporterName, "name" );
cli["-n"]["--name"]
.describe( "suite name" )
.bind( &ConfigData::name, "name" );
cli["-a"]["--abort"]
.describe( "abort at first failure" )
.bind( &abortAfterFirst );
cli["-x"]["--abortx"]
.describe( "abort after x failures" )
.bind( &abortAfterX, "no. failures" );
cli["-w"]["--warn"]
.describe( "enable warnings" )
.bind( &addWarning, "warning name" );
// - needs updating if reinstated
// cli.into( &setVerbosity )
// .describe( "level of verbosity (0=no output)" )
// .shortOpt( "v")
// .longOpt( "verbosity" )
// .placeholder( "level" );
cli[_]
.describe( "which test or tests to use" )
.bind( &addTestOrTags, "test name, pattern or tags" );
cli["-d"]["--durations"]
.describe( "show test durations" )
.bind( &setShowDurations, "yes|no" );
cli["-f"]["--input-file"]
.describe( "load test names to run from a file" )
.bind( &loadTestNamesFromFile, "filename" );
cli["-#"]["--filenames-as-tags"]
.describe( "adds a tag for the filename" )
.bind( &ConfigData::filenamesAsTags );
// Less common commands which don't have a short form
cli["--list-test-names-only"]
.describe( "list all/matching test cases names only" )
.bind( &ConfigData::listTestNamesOnly );
cli["--list-reporters"]
.describe( "list all reporters" )
.bind( &ConfigData::listReporters );
cli["--order"]
.describe( "test case order (defaults to decl)" )
.bind( &setOrder, "decl|lex|rand" );
cli["--rng-seed"]
.describe( "set a specific seed for random numbers" )
.bind( &setRngSeed, "'time'|number" );
cli["--force-colour"]
.describe( "force colourised output (deprecated)" )
.bind( &forceColour );
cli["--use-colour"]
.describe( "should output be colourised" )
.bind( &setUseColour, "yes|no" );
return cli;
}
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED

View File

@ -0,0 +1,44 @@
/*
* Created by Phil on 27/11/2013.
* Copyright 2013 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include "catch_common.h"
#include "catch_context.h"
#include "catch_interfaces_config.h"
#include <cstring>
#include <ostream>
namespace Catch {
bool SourceLineInfo::empty() const noexcept {
return file[0] == '\0';
}
bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {
return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
}
bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {
return line < other.line || ( line == other.line && (std::strcmp(file, other.file) < 0));
}
std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
#ifndef __GNUG__
os << info.file << '(' << info.line << ')';
#else
os << info.file << ':' << info.line;
#endif
return os;
}
std::string StreamEndStop::operator+() const {
return std::string();
}
NonCopyable::NonCopyable() = default;
NonCopyable::~NonCopyable() = default;
}

View File

@ -8,6 +8,8 @@
#ifndef TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
#include "catch_compiler_capabilities.h"
#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
#ifdef CATCH_CONFIG_COUNTER
@ -16,121 +18,57 @@
# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
#endif
#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
#include <sstream>
#include <stdexcept>
#include <algorithm>
#include "catch_compiler_capabilities.h"
#include <iosfwd>
#include <string>
#include <cstdint>
namespace Catch {
struct IConfig;
struct CaseSensitive { enum Choice {
Yes,
No
}; };
class NonCopyable {
#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
NonCopyable( NonCopyable const& ) = delete;
NonCopyable( NonCopyable && ) = delete;
NonCopyable& operator = ( NonCopyable const& ) = delete;
NonCopyable& operator = ( NonCopyable && ) = delete;
#else
NonCopyable( NonCopyable const& info );
NonCopyable& operator = ( NonCopyable const& );
#endif
protected:
NonCopyable() {}
NonCopyable();
virtual ~NonCopyable();
};
class SafeBool {
public:
typedef void (SafeBool::*type)() const;
static type makeSafe( bool value ) {
return value ? &SafeBool::trueValue : 0;
}
private:
void trueValue() const {}
};
template<typename ContainerT>
inline 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 ) {
typename AssociativeContainerT::const_iterator it = container.begin();
typename AssociativeContainerT::const_iterator itEnd = container.end();
for(; it != itEnd; ++it )
delete it->second;
}
bool startsWith( std::string const& s, std::string const& prefix );
bool endsWith( std::string const& s, std::string const& suffix );
bool contains( std::string const& s, std::string const& infix );
void toLowerInPlace( std::string& s );
std::string toLower( std::string const& s );
std::string trim( std::string const& str );
bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
struct pluralise {
pluralise( std::size_t count, std::string const& label );
friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
std::size_t m_count;
std::string m_label;
};
struct SourceLineInfo {
SourceLineInfo();
SourceLineInfo( char const* _file, std::size_t _line );
SourceLineInfo( SourceLineInfo const& other );
# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
SourceLineInfo() = delete;
SourceLineInfo( char const* _file, std::size_t _line ) noexcept
: file( _file ),
line( _line )
{}
SourceLineInfo( SourceLineInfo const& other ) = default;
SourceLineInfo( SourceLineInfo && ) = default;
SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
SourceLineInfo& operator = ( SourceLineInfo && ) = default;
# endif
bool empty() const;
bool operator == ( SourceLineInfo const& other ) const;
bool operator < ( SourceLineInfo const& other ) const;
std::string file;
bool empty() const noexcept;
bool operator == ( SourceLineInfo const& other ) const noexcept;
bool operator < ( SourceLineInfo const& other ) const noexcept;
char const* file;
std::size_t line;
};
std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
// This is just here to avoid compiler warnings with macro constants and boolean literals
inline bool isTrue( bool value ){ return value; }
inline bool alwaysTrue() { return true; }
inline bool alwaysFalse() { return false; }
void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
void seedRng( IConfig const& config );
unsigned int rngSeed();
// Use this in variadic streaming macros to allow
// >> +StreamEndStop
// as well as
// >> stuff +StreamEndStop
struct StreamEndStop {
std::string operator+() {
return std::string();
}
std::string operator+() const;
};
template<typename T>
T const& operator + ( T const& value, StreamEndStop ) {
@ -138,8 +76,8 @@ namespace Catch {
}
}
#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
#define CATCH_INTERNAL_LINEINFO \
::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
#endif // TWOBLUECUBES_CATCH_COMMON_H_INCLUDED

View File

@ -1,111 +0,0 @@
/*
* Created by Phil on 27/11/2013.
* Copyright 2013 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
#include "catch_common.h"
namespace Catch {
bool startsWith( std::string const& s, std::string const& prefix ) {
return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
}
bool endsWith( std::string const& s, std::string const& suffix ) {
return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
}
bool contains( std::string const& s, std::string const& infix ) {
return s.find( infix ) != std::string::npos;
}
void toLowerInPlace( std::string& s ) {
std::transform( s.begin(), s.end(), s.begin(), ::tolower );
}
std::string toLower( std::string const& s ) {
std::string lc = s;
toLowerInPlace( lc );
return lc;
}
std::string trim( std::string const& str ) {
static char const* whitespaceChars = "\n\r\t ";
std::string::size_type start = str.find_first_not_of( whitespaceChars );
std::string::size_type end = str.find_last_not_of( whitespaceChars );
return start != std::string::npos ? str.substr( start, 1+end-start ) : "";
}
bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
bool replaced = false;
std::size_t i = str.find( replaceThis );
while( i != std::string::npos ) {
replaced = true;
str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
if( i < str.size()-withThis.size() )
i = str.find( replaceThis, i+withThis.size() );
else
i = std::string::npos;
}
return replaced;
}
pluralise::pluralise( std::size_t count, std::string const& label )
: m_count( count ),
m_label( label )
{}
std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
os << pluraliser.m_count << " " << pluraliser.m_label;
if( pluraliser.m_count != 1 )
os << "s";
return os;
}
SourceLineInfo::SourceLineInfo() : line( 0 ){}
SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
: file( _file ),
line( _line )
{}
SourceLineInfo::SourceLineInfo( SourceLineInfo const& other )
: file( other.file ),
line( other.line )
{}
bool SourceLineInfo::empty() const {
return file.empty();
}
bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
return line == other.line && file == other.file;
}
bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {
return line < other.line || ( line == other.line && file < other.file );
}
void seedRng( IConfig const& config ) {
if( config.rngSeed() != 0 )
std::srand( config.rngSeed() );
}
unsigned int rngSeed() {
return getCurrentContext().getConfig()->rngSeed();
}
std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
#ifndef __GNUG__
os << info.file << "(" << info.line << ")";
#else
os << info.file << ":" << info.line;
#endif
return os;
}
void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
std::ostringstream oss;
oss << locationInfo << ": Internal Catch error: '" << message << "'";
if( alwaysTrue() )
throw std::logic_error( oss.str() );
}
}
#endif // TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED

View File

@ -8,247 +8,137 @@
#ifndef TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
// Detect a number of compiler features - mostly C++11/14 conformance - by compiler
// Detect a number of compiler features - by compiler
// The following features are defined:
//
// CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported?
// CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
// CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
// CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported?
// CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported
// CATCH_CONFIG_CPP11_LONG_LONG : is long long supported?
// CATCH_CONFIG_CPP11_OVERRIDE : is override supported?
// CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
// ****************
// Note to maintainers: if new toggles are added please document them
// in configuration.md, too
// ****************
// In general each macro has a _NO_<feature name> form
// (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
// Many features, at point of detection, define an _INTERNAL_ macro, so they
// can be combined, en-mass, with the _NO_ forms later.
// All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11
#ifdef __cplusplus
# if __cplusplus >= 201103L
# define CATCH_CPP11_OR_GREATER
# endif
# if __cplusplus >= 201402L
# define CATCH_CPP14_OR_GREATER
# endif
# if __cplusplus >= 201703L
# define CATCH_CPP17_OR_GREATER
# endif
#endif
#if defined(CATCH_CPP17_OR_GREATER)
# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
#endif
#ifdef __clang__
# if __has_feature(cxx_nullptr)
# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
# endif
# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
_Pragma( "clang diagnostic push" ) \
_Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
_Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
_Pragma( "clang diagnostic pop" )
# if __has_feature(cxx_noexcept)
# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
# endif
# if defined(CATCH_CPP11_OR_GREATER)
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
# endif
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
_Pragma( "clang diagnostic push" ) \
_Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
_Pragma( "clang diagnostic pop" )
#endif // __clang__
////////////////////////////////////////////////////////////////////////////////
// Borland
#ifdef __BORLANDC__
#endif // __BORLANDC__
////////////////////////////////////////////////////////////////////////////////
// EDG
#ifdef __EDG_VERSION__
// We know some environments not to support full POSIX signals
#if defined(__CYGWIN__) || defined(__QNX__)
#endif // __EDG_VERSION__
////////////////////////////////////////////////////////////////////////////////
// Digital Mars
#ifdef __DMC__
#endif // __DMC__
////////////////////////////////////////////////////////////////////////////////
// GCC
#ifdef __GNUC__
# if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
# if !defined(CATCH_CONFIG_POSIX_SIGNALS)
# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
# endif
# if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) && defined(CATCH_CPP11_OR_GREATER)
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "GCC diagnostic ignored \"-Wparentheses\"" )
# endif
#endif
// - otherwise more recent versions define __cplusplus >= 201103L
// and will get picked up below
#ifdef __OS400__
# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
# define CATCH_CONFIG_COLOUR_NONE
#endif
////////////////////////////////////////////////////////////////////////////////
// Cygwin
#ifdef __CYGWIN__
#endif // __GNUC__
// 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__
////////////////////////////////////////////////////////////////////////////////
// Visual C++
#ifdef _MSC_VER
#if (_MSC_VER >= 1600)
# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
#endif
#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
#endif
# if _MSC_VER >= 1900 // Visual Studio 2015 or newer
# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
# endif
// Universal Windows platform does not support SEH
// Or console colours (or console at all...)
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
# define CATCH_CONFIG_COLOUR_NONE
# else
# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
# endif
#endif // _MSC_VER
////////////////////////////////////////////////////////////////////////////////
// Use variadic macros if the compiler supports them
#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 )
#define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
// Use of __COUNTER__ is suppressed during code analysis in
// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
// handled by it.
// Otherwise all supported compilers support COUNTER macro,
// but user still might want to turn it off
#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
#define CATCH_INTERNAL_CONFIG_COUNTER
#endif
// Use __COUNTER__ if the compiler supports it
#if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \
( defined __GNUC__ && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 ) || \
( defined __clang__ && __clang_major__ >= 3 )
#define CATCH_INTERNAL_CONFIG_COUNTER
#endif
////////////////////////////////////////////////////////////////////////////////
// C++ language feature support
// catch all support for C++11
#if defined(CATCH_CPP11_OR_GREATER)
# if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)
# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
# endif
# ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
# endif
# ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
# define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
# endif
# ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
# define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
# endif
# ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE
# define CATCH_INTERNAL_CONFIG_CPP11_TUPLE
# endif
# ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
# define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
# endif
# if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG)
# define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG
# endif
# if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE)
# define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE
# endif
# if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
# endif
#endif // __cplusplus >= 201103L
// Now set the actual defines based on the above + anything the user has configured
#if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11)
# define CATCH_CONFIG_CPP11_NULLPTR
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11)
# define CATCH_CONFIG_CPP11_NOEXCEPT
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11)
# define CATCH_CONFIG_CPP11_GENERATED_METHODS
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11)
# define CATCH_CONFIG_CPP11_IS_ENUM
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11)
# define CATCH_CONFIG_CPP11_TUPLE
#endif
#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)
# define CATCH_CONFIG_VARIADIC_MACROS
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11)
# define CATCH_CONFIG_CPP11_LONG_LONG
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11)
# define CATCH_CONFIG_CPP11_OVERRIDE
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)
# define CATCH_CONFIG_CPP11_UNIQUE_PTR
#endif
#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_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH)
# 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)
# define CATCH_CONFIG_POSIX_SIGNALS
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_INTERNAL_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
#endif
#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
#endif
#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
#endif
// noexcept support:
#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
# define CATCH_NOEXCEPT noexcept
# define CATCH_NOEXCEPT_IS(x) noexcept(x)
#else
# define CATCH_NOEXCEPT throw()
# define CATCH_NOEXCEPT_IS(x)
#endif
// nullptr support
#ifdef CATCH_CONFIG_CPP11_NULLPTR
# define CATCH_NULL nullptr
#else
# define CATCH_NULL NULL
#endif
// override support
#ifdef CATCH_CONFIG_CPP11_OVERRIDE
# define CATCH_OVERRIDE override
#else
# define CATCH_OVERRIDE
#endif
// unique_ptr support
#ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR
# define CATCH_AUTO_PTR( T ) std::unique_ptr<T>
#else
# define CATCH_AUTO_PTR( T ) std::auto_ptr<T>
#endif
#endif // TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED

View File

@ -0,0 +1,64 @@
/*
* Created by Martin on 19/07/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)
*/
#include "catch_config.hpp"
#include "catch_enforce.h"
#include "catch_stringref.h"
namespace Catch {
Config::Config( ConfigData const& data )
: m_data( data ),
m_stream( openStream() )
{
if( !data.testsOrTags.empty() ) {
TestSpecParser parser( ITagAliasRegistry::get() );
for( auto const& testOrTags : data.testsOrTags )
parser.parse( testOrTags );
m_testSpec = parser.testSpec();
}
}
std::string const& Config::getFilename() const {
return m_data.outputFilename ;
}
bool Config::listTests() const { return m_data.listTests; }
bool Config::listTestNamesOnly() const { return m_data.listTestNamesOnly; }
bool Config::listTags() const { return m_data.listTags; }
bool Config::listReporters() const { return m_data.listReporters; }
std::string Config::getProcessName() const { return m_data.processName; }
std::vector<std::string> const& Config::getReporterNames() const { return m_data.reporterNames; }
std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
TestSpec const& Config::testSpec() const { return m_testSpec; }
bool Config::showHelp() const { return m_data.showHelp; }
// IConfig interface
bool Config::allowThrows() const { return !m_data.noThrow; }
std::ostream& Config::stream() const { return m_stream->stream(); }
std::string Config::name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
bool Config::includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
bool Config::warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; }
unsigned int Config::rngSeed() const { return m_data.rngSeed; }
int Config::benchmarkResolutionMultiple() const { return m_data.benchmarkResolutionMultiple; }
UseColour::YesOrNo Config::useColour() const { return m_data.useColour; }
bool Config::shouldDebugBreak() const { return m_data.shouldDebugBreak; }
int Config::abortAfter() const { return m_data.abortAfter; }
bool Config::showInvisibles() const { return m_data.showInvisibles; }
Verbosity Config::verbosity() const { return m_data.verbosity; }
IStream const* Config::openStream() {
return Catch::makeStream(m_data.outputFilename);
}
} // end namespace Catch

View File

@ -8,16 +8,15 @@
#ifndef TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
#include "catch_test_spec_parser.hpp"
#include "catch_context.h"
#include "catch_test_spec_parser.h"
#include "catch_interfaces_config.h"
// Libstdc++ doesn't like incomplete classes for unique_ptr
#include "catch_stream.h"
#include <memory>
#include <vector>
#include <string>
#include <iostream>
#include <ctime>
#ifndef CATCH_CONFIG_CONSOLE_WIDTH
#define CATCH_CONFIG_CONSOLE_WIDTH 80
@ -25,48 +24,32 @@
namespace Catch {
struct IStream;
struct ConfigData {
bool listTests = false;
bool listTags = false;
bool listReporters = false;
bool listTestNamesOnly = false;
ConfigData()
: listTests( false ),
listTags( false ),
listReporters( false ),
listTestNamesOnly( false ),
showSuccessfulTests( false ),
shouldDebugBreak( false ),
noThrow( false ),
showHelp( false ),
showInvisibles( false ),
filenamesAsTags( false ),
abortAfter( -1 ),
rngSeed( 0 ),
verbosity( Verbosity::Normal ),
warnings( WarnAbout::Nothing ),
showDurations( ShowDurations::DefaultForReporter ),
runOrder( RunTests::InDeclarationOrder ),
useColour( UseColour::Auto )
{}
bool showSuccessfulTests = false;
bool shouldDebugBreak = false;
bool noThrow = false;
bool showHelp = false;
bool showInvisibles = false;
bool filenamesAsTags = false;
bool libIdentify = false;
bool listTests;
bool listTags;
bool listReporters;
bool listTestNamesOnly;
int abortAfter = -1;
unsigned int rngSeed = 0;
int benchmarkResolutionMultiple = 100;
bool showSuccessfulTests;
bool shouldDebugBreak;
bool noThrow;
bool showHelp;
bool showInvisibles;
bool filenamesAsTags;
int abortAfter;
unsigned int rngSeed;
Verbosity::Level verbosity;
WarnAbout::What warnings;
ShowDurations::OrNot showDurations;
RunTests::InWhatOrder runOrder;
UseColour::YesOrNo useColour;
Verbosity verbosity = Verbosity::Normal;
WarnAbout::What warnings = WarnAbout::Nothing;
ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
UseColour::YesOrNo useColour = UseColour::Auto;
WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
std::string outputFilename;
std::string name;
@ -74,84 +57,55 @@ namespace Catch {
std::vector<std::string> reporterNames;
std::vector<std::string> testsOrTags;
std::vector<std::string> sectionsToRun;
};
class Config : public SharedImpl<IConfig> {
private:
Config( Config const& other );
Config& operator = ( Config const& other );
virtual void dummy();
class Config : public IConfig {
public:
Config()
{}
Config() = default;
Config( ConfigData const& data );
virtual ~Config() = default;
Config( ConfigData const& data )
: m_data( data ),
m_stream( openStream() )
{
if( !data.testsOrTags.empty() ) {
TestSpecParser parser( ITagAliasRegistry::get() );
for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
parser.parse( data.testsOrTags[i] );
m_testSpec = parser.testSpec();
}
}
std::string const& getFilename() const;
virtual ~Config() {
}
bool listTests() const;
bool listTestNamesOnly() const;
bool listTags() const;
bool listReporters() const;
std::string const& getFilename() const {
return m_data.outputFilename ;
}
std::string getProcessName() const;
bool listTests() const { return m_data.listTests; }
bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
bool listTags() const { return m_data.listTags; }
bool listReporters() const { return m_data.listReporters; }
std::vector<std::string> const& getReporterNames() const;
std::vector<std::string> const& getSectionsToRun() const override;
std::string getProcessName() const { return m_data.processName; }
virtual TestSpec const& testSpec() const override;
bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
std::vector<std::string> getReporterNames() const { return m_data.reporterNames; }
int abortAfter() const { return m_data.abortAfter; }
TestSpec const& testSpec() const { return m_testSpec; }
bool showHelp() const { return m_data.showHelp; }
bool showInvisibles() const { return m_data.showInvisibles; }
bool showHelp() const;
// IConfig interface
virtual bool allowThrows() const { return !m_data.noThrow; }
virtual std::ostream& stream() const { return m_stream->stream(); }
virtual std::string name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
virtual bool includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
virtual RunTests::InWhatOrder runOrder() const { return m_data.runOrder; }
virtual unsigned int rngSeed() const { return m_data.rngSeed; }
virtual UseColour::YesOrNo useColour() const { return m_data.useColour; }
bool allowThrows() const override;
std::ostream& stream() const override;
std::string name() const override;
bool includeSuccessfulResults() const override;
bool warnAboutMissingAssertions() const override;
ShowDurations::OrNot showDurations() const override;
RunTests::InWhatOrder runOrder() const override;
unsigned int rngSeed() const override;
int benchmarkResolutionMultiple() const override;
UseColour::YesOrNo useColour() const override;
bool shouldDebugBreak() const override;
int abortAfter() const override;
bool showInvisibles() const override;
Verbosity verbosity() const override;
private:
IStream const* openStream() {
if( m_data.outputFilename.empty() )
return new CoutStream();
else if( m_data.outputFilename[0] == '%' ) {
if( m_data.outputFilename == "%debug" )
return new DebugOutStream();
else
throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename );
}
else
return new FileStream( m_data.outputFilename );
}
IStream const* openStream();
ConfigData m_data;
CATCH_AUTO_PTR( IStream const ) m_stream;
std::unique_ptr<IStream const> m_stream;
TestSpec m_testSpec;
};

View File

@ -5,16 +5,31 @@
* 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_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
#include "catch_console_colour.hpp"
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wexit-time-destructors"
#endif
#include "catch_console_colour.h"
#include "catch_enforce.h"
#include "catch_errno_guard.h"
#include "catch_interfaces_config.h"
#include "catch_stream.h"
#include "catch_context.h"
#include "catch_platform.h"
#include "catch_debugger.h"
#include "catch_windows_h_proxy.h"
#include <sstream>
namespace Catch {
namespace {
struct IColourImpl {
virtual ~IColourImpl() {}
virtual ~IColourImpl() = default;
virtual void use( Colour::Code _colourCode ) = 0;
};
@ -41,16 +56,6 @@ namespace Catch {
#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
#ifndef NOMINMAX
#define NOMINMAX
#endif
#ifdef __AFXDLL
#include <AfxWin.h>
#else
#include <windows.h>
#endif
namespace Catch {
namespace {
@ -64,7 +69,7 @@ namespace {
originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
}
virtual void use( Colour::Code _colourCode ) {
virtual void use( Colour::Code _colourCode ) override {
switch( _colourCode ) {
case Colour::None: return setTextAttribute( originalForegroundAttributes );
case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
@ -79,8 +84,12 @@ namespace {
case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
case Colour::BrightYellow: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );
case Colour::Bright: throw std::logic_error( "not a colour" );
case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
default:
CATCH_ERROR( "Unknown colour requested" );
}
}
@ -96,14 +105,12 @@ namespace {
IColourImpl* platformColourInstance() {
static Win32ColourImpl s_instance;
Ptr<IConfig const> config = getCurrentContext().getConfig();
IConfigPtr config = getCurrentContext().getConfig();
UseColour::YesOrNo colourMode = config
? config->useColour()
: UseColour::Auto;
if( colourMode == UseColour::Auto )
colourMode = !isDebuggerActive()
? UseColour::Yes
: UseColour::No;
colourMode = UseColour::Yes;
return colourMode == UseColour::Yes
? &s_instance
: NoColourImpl::instance();
@ -125,13 +132,13 @@ namespace {
// https://github.com/philsquared/Catch/pull/131
class PosixColourImpl : public IColourImpl {
public:
virtual void use( Colour::Code _colourCode ) {
virtual void use( Colour::Code _colourCode ) override {
switch( _colourCode ) {
case Colour::None:
case Colour::White: return setColour( "[0m" );
case Colour::Red: return setColour( "[0;31m" );
case Colour::Green: return setColour( "[0;32m" );
case Colour::Blue: return setColour( "[0:34m" );
case Colour::Blue: return setColour( "[0;34m" );
case Colour::Cyan: return setColour( "[0;36m" );
case Colour::Yellow: return setColour( "[0;33m" );
case Colour::Grey: return setColour( "[1;30m" );
@ -140,8 +147,10 @@ namespace {
case Colour::BrightRed: return setColour( "[1;31m" );
case Colour::BrightGreen: return setColour( "[1;32m" );
case Colour::BrightWhite: return setColour( "[1;37m" );
case Colour::BrightYellow: return setColour( "[1;33m" );
case Colour::Bright: throw std::logic_error( "not a colour" );
case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
default: CATCH_INTERNAL_ERROR( "Unknown colour requested" );
}
}
static IColourImpl* instance() {
@ -155,13 +164,21 @@ namespace {
}
};
bool useColourOnPlatform() {
return
#ifdef CATCH_PLATFORM_MAC
!isDebuggerActive() &&
#endif
isatty(STDOUT_FILENO);
}
IColourImpl* platformColourInstance() {
Ptr<IConfig const> config = getCurrentContext().getConfig();
ErrnoGuard guard;
IConfigPtr config = getCurrentContext().getConfig();
UseColour::YesOrNo colourMode = config
? config->useColour()
: UseColour::Auto;
if( colourMode == UseColour::Auto )
colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) )
colourMode = useColourOnPlatform()
? UseColour::Yes
: UseColour::No;
return colourMode == UseColour::Yes
@ -184,8 +201,17 @@ namespace Catch {
namespace Catch {
Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); }
Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; }
Colour::Colour( Code _colourCode ) { use( _colourCode ); }
Colour::Colour( Colour&& rhs ) noexcept {
m_moved = rhs.m_moved;
rhs.m_moved = true;
}
Colour& Colour::operator=( Colour&& rhs ) noexcept {
m_moved = rhs.m_moved;
rhs.m_moved = true;
return *this;
}
Colour::~Colour(){ if( !m_moved ) use( None ); }
void Colour::use( Code _colourCode ) {
@ -193,6 +219,13 @@ namespace Catch {
impl->use( _colourCode );
}
std::ostream& operator << ( std::ostream& os, Colour const& ) {
return os;
}
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
#if defined(__clang__)
# pragma clang diagnostic pop
#endif

View File

@ -30,10 +30,11 @@ namespace Catch {
BrightGreen = Bright | Green,
LightGrey = Bright | Grey,
BrightWhite = Bright | White,
BrightYellow = Bright | Yellow,
// By intention
FileName = LightGrey,
Warning = Yellow,
Warning = BrightYellow,
ResultError = BrightRed,
ResultSuccess = BrightGreen,
ResultExpectedFailure = Warning,
@ -42,7 +43,7 @@ namespace Catch {
Success = Green,
OriginalExpression = Cyan,
ReconstructedExpression = Yellow,
ReconstructedExpression = BrightYellow,
SecondaryText = LightGrey,
Headers = White
@ -50,17 +51,18 @@ namespace Catch {
// Use constructed object for RAII guard
Colour( Code _colourCode );
Colour( Colour const& other );
Colour( Colour&& other ) noexcept;
Colour& operator=( Colour&& other ) noexcept;
~Colour();
// Use static method for one-shot changes
static void use( Code _colourCode );
private:
bool m_moved;
bool m_moved = false;
};
inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; }
std::ostream& operator << ( std::ostream& os, Colour const& );
} // end namespace Catch

View File

@ -0,0 +1,62 @@
/*
* Created by Phil on 31/12/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include "catch_context.h"
#include "catch_common.h"
namespace Catch {
class Context : public IMutableContext, NonCopyable {
public: // IContext
virtual IResultCapture* getResultCapture() override {
return m_resultCapture;
}
virtual IRunner* getRunner() override {
return m_runner;
}
virtual IConfigPtr const& getConfig() const override {
return m_config;
}
virtual ~Context() override;
public: // IMutableContext
virtual void setResultCapture( IResultCapture* resultCapture ) override {
m_resultCapture = resultCapture;
}
virtual void setRunner( IRunner* runner ) override {
m_runner = runner;
}
virtual void setConfig( IConfigPtr const& config ) override {
m_config = config;
}
friend IMutableContext& getCurrentMutableContext();
private:
IConfigPtr m_config;
IRunner* m_runner = nullptr;
IResultCapture* m_resultCapture = nullptr;
};
IMutableContext *IMutableContext::currentContext = nullptr;
void IMutableContext::createContext()
{
currentContext = new Context();
}
void cleanUpContext() {
delete IMutableContext::currentContext;
IMutableContext::currentContext = nullptr;
}
IContext::~IContext() = default;
IMutableContext::~IMutableContext() = default;
Context::~Context() = default;
}

View File

@ -8,21 +8,16 @@
#ifndef TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
#include "catch_interfaces_generators.h"
#include "catch_ptr.hpp"
#include <memory>
#include <vector>
#include <stdlib.h>
namespace Catch {
class TestCase;
class Stream;
struct IResultCapture;
struct IRunner;
struct IGeneratorsForTest;
struct IConfig;
struct IMutableContext;
using IConfigPtr = std::shared_ptr<IConfig const>;
struct IContext
{
@ -30,9 +25,7 @@ namespace Catch {
virtual IResultCapture* getResultCapture() = 0;
virtual IRunner* getRunner() = 0;
virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
virtual bool advanceGeneratorsForCurrentTest() = 0;
virtual Ptr<IConfig const> getConfig() const = 0;
virtual IConfigPtr const& getConfig() const = 0;
};
struct IMutableContext : IContext
@ -40,14 +33,28 @@ namespace Catch {
virtual ~IMutableContext();
virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
virtual void setRunner( IRunner* runner ) = 0;
virtual void setConfig( Ptr<IConfig const> const& config ) = 0;
virtual void setConfig( IConfigPtr const& config ) = 0;
private:
static IMutableContext *currentContext;
friend IMutableContext& getCurrentMutableContext();
friend void cleanUpContext();
static void createContext();
};
IContext& getCurrentContext();
IMutableContext& getCurrentMutableContext();
void cleanUpContext();
Stream createStream( std::string const& streamName );
inline IMutableContext& getCurrentMutableContext()
{
if( !IMutableContext::currentContext )
IMutableContext::createContext();
return *IMutableContext::currentContext;
}
inline IContext& getCurrentContext()
{
return getCurrentMutableContext();
}
void cleanUpContext();
}
#endif // TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED

View File

@ -1,104 +0,0 @@
/*
* Created by Phil on 31/12/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
#include "catch_run_context.hpp"
#include "catch_context.h"
#include "catch_stream.hpp"
namespace Catch {
class Context : public IMutableContext {
Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {}
Context( Context const& );
void operator=( Context const& );
public: // IContext
virtual IResultCapture* getResultCapture() {
return m_resultCapture;
}
virtual IRunner* getRunner() {
return m_runner;
}
virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {
return getGeneratorsForCurrentTest()
.getGeneratorInfo( fileInfo, totalSize )
.getCurrentIndex();
}
virtual bool advanceGeneratorsForCurrentTest() {
IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
return generators && generators->moveNext();
}
virtual Ptr<IConfig const> getConfig() const {
return m_config;
}
public: // IMutableContext
virtual void setResultCapture( IResultCapture* resultCapture ) {
m_resultCapture = resultCapture;
}
virtual void setRunner( IRunner* runner ) {
m_runner = runner;
}
virtual void setConfig( Ptr<IConfig const> const& config ) {
m_config = config;
}
friend IMutableContext& getCurrentMutableContext();
private:
IGeneratorsForTest* findGeneratorsForCurrentTest() {
std::string testName = getResultCapture()->getCurrentTestName();
std::map<std::string, IGeneratorsForTest*>::const_iterator it =
m_generatorsByTestName.find( testName );
return it != m_generatorsByTestName.end()
? it->second
: CATCH_NULL;
}
IGeneratorsForTest& getGeneratorsForCurrentTest() {
IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
if( !generators ) {
std::string testName = getResultCapture()->getCurrentTestName();
generators = createGeneratorsForTest();
m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
}
return *generators;
}
private:
Ptr<IConfig const> m_config;
IRunner* m_runner;
IResultCapture* m_resultCapture;
std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
};
namespace {
Context* currentContext = CATCH_NULL;
}
IMutableContext& getCurrentMutableContext() {
if( !currentContext )
currentContext = new Context();
return *currentContext;
}
IContext& getCurrentContext() {
return getCurrentMutableContext();
}
void cleanUpContext() {
delete currentContext;
currentContext = CATCH_NULL;
}
}
#endif // TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED

View File

@ -0,0 +1,29 @@
/*
* Created by Martin on 29/08/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)
*
*/
#include "catch_debug_console.h"
#include "catch_stream.h"
#include "catch_platform.h"
#ifdef CATCH_PLATFORM_WINDOWS
#include "catch_windows_h_proxy.h"
namespace Catch {
void writeToDebugConsole( std::string const& text ) {
::OutputDebugStringA( text.c_str() );
}
}
#else
namespace Catch {
void writeToDebugConsole( std::string const& text ) {
// !TBD: Need a version for Mac/ XCode and other IDEs
Catch::cout() << text;
}
}
#endif // Platform

View File

@ -0,0 +1,17 @@
/*
* Created by Martin on 29/08/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_DEBUG_CONSOLE_H_INCLUDED
#define TWOBLUECUBES_CATCH_DEBUG_CONSOLE_H_INCLUDED
#include <string>
namespace Catch {
void writeToDebugConsole( std::string const& text );
}
#endif // TWOBLUECUBES_CATCH_DEBUG_CONSOLE_H_INCLUDED

View File

@ -6,22 +6,23 @@
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#ifndef TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
#include "catch_debugger.h"
#include <iostream>
#include "catch_errno_guard.h"
#include "catch_stream.h"
#include "catch_platform.h"
#ifdef CATCH_PLATFORM_MAC
#include <assert.h>
#include <stdbool.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/sysctl.h>
# include <assert.h>
# include <stdbool.h>
# include <sys/types.h>
# include <unistd.h>
# include <sys/sysctl.h>
# include <cstddef>
# include <ostream>
namespace Catch{
namespace Catch {
// The following function is taken directly from the following technical note:
// http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
@ -32,7 +33,7 @@
int mib[4];
struct kinfo_proc info;
size_t size;
std::size_t size;
// Initialize the flags so that, if sysctl fails for some bizarre
// reason, we get a predictable result.
@ -50,7 +51,7 @@
// Call sysctl.
size = sizeof(info);
if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) {
if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) {
Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
return false;
}
@ -61,6 +62,36 @@
}
} // namespace Catch
#elif defined(CATCH_PLATFORM_LINUX)
#include <fstream>
#include <string>
namespace Catch{
// The standard POSIX way of detecting a debugger is to attempt to
// ptrace() the process, but this needs to be done from a child and not
// this process itself to still allow attaching to this process later
// if wanted, so is rather heavy. Under Linux we have the PID of the
// "debugger" (which doesn't need to be gdb, of course, it could also
// 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;
if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
// We're traced if the PID is not 0 and no other PID starts
// with 0 digit, so it's enough to check for just a single
// character.
return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
}
}
return false;
}
} // namespace Catch
#elif defined(_MSC_VER)
extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
namespace Catch {
@ -77,24 +108,6 @@
}
#else
namespace Catch {
inline bool isDebuggerActive() { return false; }
bool isDebuggerActive() { return false; }
}
#endif // Platform
#ifdef CATCH_PLATFORM_WINDOWS
extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );
namespace Catch {
void writeToDebugConsole( std::string const& text ) {
::OutputDebugStringA( text.c_str() );
}
}
#else
namespace Catch {
void writeToDebugConsole( std::string const& text ) {
// !TBD: Need a version for Mac/ XCode and other IDEs
Catch::cout() << text;
}
}
#endif // Platform
#endif // TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED

View File

@ -11,39 +11,39 @@
#include "catch_platform.h"
#include <string>
namespace Catch{
namespace Catch {
bool isDebuggerActive();
void writeToDebugConsole( std::string const& text );
}
#ifdef CATCH_PLATFORM_MAC
// The following code snippet based on:
// http://cocoawithlove.com/2008/03/break-into-debugger.html
#ifdef DEBUG
#if defined(__ppc64__) || defined(__ppc__)
#define CATCH_BREAK_INTO_DEBUGGER() \
if( Catch::isDebuggerActive() ) { \
__asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
: : : "memory","r0","r3","r4" ); \
}
#else
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
#endif
#endif
#define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
#elif defined(CATCH_PLATFORM_LINUX)
// If we can use inline assembler, do it because this allows us to break
// 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") /* NOLINT */
#else // Fall back to the generic way.
#include <signal.h>
#define CATCH_TRAP() raise(SIGTRAP)
#endif
#elif defined(_MSC_VER)
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); }
#define CATCH_TRAP() __debugbreak()
#elif defined(__MINGW32__)
extern "C" __declspec(dllimport) void __stdcall DebugBreak();
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); }
#define CATCH_TRAP() DebugBreak()
#endif
#ifndef CATCH_BREAK_INTO_DEBUGGER
#define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
#ifdef CATCH_TRAP
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); }
#else
namespace Catch {
inline void doNothing() {}
}
#define CATCH_BREAK_INTO_DEBUGGER() Catch::doNothing()
#endif
#endif // TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED

View File

@ -0,0 +1,24 @@
/*
* Created by Phil Nash on 8/8/2017.
* Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include "catch_decomposer.h"
#include "catch_config.hpp"
namespace Catch {
ITransientExpression::~ITransientExpression() = default;
void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {
if( lhs.size() + rhs.size() < 40 &&
lhs.find('\n') == std::string::npos &&
rhs.find('\n') == std::string::npos )
os << lhs << " " << op << " " << rhs;
else
os << lhs << "\n" << op << "\n" << rhs;
}
}

View File

@ -0,0 +1,175 @@
/*
* Created by Phil Nash on 8/8/2017.
* Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_DECOMPOSER_H_INCLUDED
#define TWOBLUECUBES_CATCH_DECOMPOSER_H_INCLUDED
#include "catch_tostring.h"
#include "catch_stringref.h"
#include <iosfwd>
#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)
#pragma warning(disable:4180) // qualifier applied to function type has no meaning
#endif
namespace Catch {
struct ITransientExpression {
auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
auto getResult() const -> bool { return m_result; }
virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
ITransientExpression( bool isBinaryExpression, bool result )
: m_isBinaryExpression( isBinaryExpression ),
m_result( result )
{}
// We don't actually need a virtual destructor, but many static analysers
// complain if it's not here :-(
virtual ~ITransientExpression();
bool m_isBinaryExpression;
bool m_result;
};
void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
template<typename LhsT, typename RhsT>
class BinaryExpr : public ITransientExpression {
LhsT m_lhs;
StringRef m_op;
RhsT m_rhs;
void streamReconstructedExpression( std::ostream &os ) const override {
formatReconstructedExpression
( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
}
public:
BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
: ITransientExpression{ true, comparisonResult },
m_lhs( lhs ),
m_op( op ),
m_rhs( rhs )
{}
};
template<typename LhsT>
class UnaryExpr : public ITransientExpression {
LhsT m_lhs;
void streamReconstructedExpression( std::ostream &os ) const override {
os << Catch::Detail::stringify( m_lhs );
}
public:
explicit UnaryExpr( LhsT lhs )
: ITransientExpression{ false, lhs ? true : false },
m_lhs( lhs )
{}
};
// Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
template<typename LhsT, typename RhsT>
auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
template<typename T>
auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
template<typename T>
auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
template<typename T>
auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
template<typename T>
auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
template<typename LhsT, typename RhsT>
auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
template<typename T>
auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
template<typename T>
auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
template<typename T>
auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
template<typename T>
auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
template<typename LhsT>
class ExprLhs {
LhsT m_lhs;
public:
explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
template<typename RhsT>
auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs };
}
auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
return { m_lhs == rhs, m_lhs, "==", rhs };
}
template<typename RhsT>
auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs };
}
auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
return { m_lhs != rhs, m_lhs, "!=", rhs };
}
template<typename RhsT>
auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs };
}
template<typename RhsT>
auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs };
}
template<typename RhsT>
auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs };
}
template<typename RhsT>
auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
}
auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
return UnaryExpr<LhsT>{ m_lhs };
}
};
void handleExpression( ITransientExpression const& expr );
template<typename T>
void handleExpression( ExprLhs<T> const& expr ) {
handleExpression( expr.makeUnaryExpr() );
}
struct Decomposer {
template<typename T>
auto operator <= ( T const& lhs ) -> ExprLhs<T const&> {
return ExprLhs<T const&>{ lhs };
}
auto operator <=( bool value ) -> ExprLhs<bool> {
return ExprLhs<bool>{ value };
}
};
} // end namespace Catch
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#endif // TWOBLUECUBES_CATCH_DECOMPOSER_H_INCLUDED

View File

@ -8,10 +8,18 @@
#ifndef TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
#include "catch_session.h"
#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[]) {
#endif
return Catch::Session().run( argc, argv );
}
@ -24,7 +32,7 @@ int main (int argc, char * const argv[]) {
#endif
Catch::registerTestMethods();
int result = Catch::Session().run( argc, (char* const*)argv );
int result = Catch::Session().run( argc, (char**)argv );
#if !CATCH_ARC_ENABLED
[pool drain];

View File

@ -0,0 +1,25 @@
/*
* Created by Martin on 01/08/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_ENFORCE_H_INCLUDED
#define TWOBLUECUBES_CATCH_ENFORCE_H_INCLUDED
#include "catch_common.h"
#include "catch_stream.h"
#include <stdexcept>
#include <iosfwd>
#define CATCH_PREPARE_EXCEPTION( type, msg ) \
type( static_cast<std::ostringstream&&>( Catch::ReusableStringStream().get() << msg ).str() )
#define CATCH_INTERNAL_ERROR( msg ) \
throw CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg);
#define CATCH_ERROR( msg ) \
throw CATCH_PREPARE_EXCEPTION( std::domain_error, msg )
#define CATCH_ENFORCE( condition, msg ) \
do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false)
#endif // TWOBLUECUBES_CATCH_ENFORCE_H_INCLUDED

View File

@ -0,0 +1,15 @@
/*
* 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)
*/
#include "catch_errno_guard.h"
#include <cerrno>
namespace Catch {
ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}
ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }
}

View File

@ -0,0 +1,22 @@
/*
* 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_H_INCLUDED
#define TWOBLUECUBES_CATCH_ERRNO_GUARD_H_INCLUDED
namespace Catch {
class ErrnoGuard {
public:
ErrnoGuard();
~ErrnoGuard();
private:
int m_oldErrno;
};
}
#endif // TWOBLUECUBES_CATCH_ERRNO_GUARD_H_INCLUDED

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