mirror of
https://github.com/catchorg/Catch2.git
synced 2025-09-15 09:55:39 +02:00
Compare commits
141 Commits
v1.2.1-dev
...
v1.5.9
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2be372710e | ||
![]() |
0c093bee38 | ||
![]() |
dedc7c56ce | ||
![]() |
a9561ecb31 | ||
![]() |
e4df006568 | ||
![]() |
fb99cc556d | ||
![]() |
862d13138c | ||
![]() |
79acc0504b | ||
![]() |
f9afa2a68d | ||
![]() |
0c8c6b347a | ||
![]() |
40b6ad73df | ||
![]() |
30cebd6177 | ||
![]() |
e27c4ee042 | ||
![]() |
072114293b | ||
![]() |
f90ee9fb37 | ||
![]() |
c17ba0870a | ||
![]() |
79f01100e3 | ||
![]() |
ccf7f2842a | ||
![]() |
e0302db4a6 | ||
![]() |
88732e85b2 | ||
![]() |
1c9a6cab88 | ||
![]() |
40f6068d52 | ||
![]() |
21cbfc107e | ||
![]() |
31861bbd46 | ||
![]() |
b1eeec7c69 | ||
![]() |
c23b374f3d | ||
![]() |
916317bd81 | ||
![]() |
8c459dd207 | ||
![]() |
fd7d35464b | ||
![]() |
c47c1797d2 | ||
![]() |
f5d2b2dce8 | ||
![]() |
02c7e41c7c | ||
![]() |
5095619955 | ||
![]() |
35f510545d | ||
![]() |
742457cbcf | ||
![]() |
1aa6c91e64 | ||
![]() |
ac220289a6 | ||
![]() |
be3570ef22 | ||
![]() |
a74d760d74 | ||
![]() |
f666f5f0ae | ||
![]() |
7940d58a2f | ||
![]() |
ebf9f3bb9d | ||
![]() |
1ebebd4ab8 | ||
![]() |
b57e734eb4 | ||
![]() |
5aa2b82b17 | ||
![]() |
5c198d85e6 | ||
![]() |
5a6b291878 | ||
![]() |
1706dd4f11 | ||
![]() |
92b141ee53 | ||
![]() |
4f1263d6b4 | ||
![]() |
3b19458fed | ||
![]() |
e5537842d0 | ||
![]() |
0fe303b6b7 | ||
![]() |
1c47fe023a | ||
![]() |
6f3bc629be | ||
![]() |
6de7142d1f | ||
![]() |
7544644bb4 | ||
![]() |
86c0ea2999 | ||
![]() |
7075b7defb | ||
![]() |
c984fc3ecd | ||
![]() |
447f53e9e3 | ||
![]() |
13a887ad24 | ||
![]() |
02af70ed0b | ||
![]() |
c362894565 | ||
![]() |
97e335437e | ||
![]() |
ae5ee2cf63 | ||
![]() |
f895e0d95f | ||
![]() |
458f37ed57 | ||
![]() |
91bfe68a75 | ||
![]() |
8ccb18daa9 | ||
![]() |
dce2154474 | ||
![]() |
e52ad48fb7 | ||
![]() |
776247af81 | ||
![]() |
3b4edd7a48 | ||
![]() |
880a2046d9 | ||
![]() |
ffad3a0a39 | ||
![]() |
3bd20bf2cd | ||
![]() |
c7243562b0 | ||
![]() |
b84e08ad6f | ||
![]() |
aca16a0f99 | ||
![]() |
f294c98472 | ||
![]() |
7424b23bfb | ||
![]() |
dbd3a84d92 | ||
![]() |
5262e61e9d | ||
![]() |
a5fba672e1 | ||
![]() |
2106d82881 | ||
![]() |
981347b6e4 | ||
![]() |
9e341231ba | ||
![]() |
2b688e1cef | ||
![]() |
84d1c080d6 | ||
![]() |
722315a1f5 | ||
![]() |
fdc42d0af4 | ||
![]() |
d274fc571c | ||
![]() |
7e15d9b20b | ||
![]() |
0e64973f55 | ||
![]() |
e4fa62a14e | ||
![]() |
a49f088032 | ||
![]() |
ed6e9128a4 | ||
![]() |
92356769f1 | ||
![]() |
d10b73f9f1 | ||
![]() |
71fd2c2fdf | ||
![]() |
08844e7e57 | ||
![]() |
054e3c5b43 | ||
![]() |
f3e7722cc6 | ||
![]() |
315c83ad87 | ||
![]() |
9576ad9108 | ||
![]() |
e91738103c | ||
![]() |
8c32b49d5f | ||
![]() |
ece529ae7c | ||
![]() |
9e42153fe5 | ||
![]() |
c81778ecd0 | ||
![]() |
f5642be7b4 | ||
![]() |
7e34619f03 | ||
![]() |
4636be9744 | ||
![]() |
015e07100e | ||
![]() |
bc8840cbb8 | ||
![]() |
471bd2556a | ||
![]() |
aa49823bc0 | ||
![]() |
52a417df7b | ||
![]() |
0b523db6b9 | ||
![]() |
b8515929b8 | ||
![]() |
3deb3e010f | ||
![]() |
73a140fb9e | ||
![]() |
ef62b578e2 | ||
![]() |
f4389b4fdb | ||
![]() |
4b99be6a9a | ||
![]() |
293e54dcbe | ||
![]() |
d758428fe2 | ||
![]() |
9a6a0865f2 | ||
![]() |
2c6411e70a | ||
![]() |
1cb993970a | ||
![]() |
bc00d59a4e | ||
![]() |
b3b2352045 | ||
![]() |
c9a188df45 | ||
![]() |
e904aa7f6e | ||
![]() |
d43a47efca | ||
![]() |
a0de07d45b | ||
![]() |
15317632f3 | ||
![]() |
a28d40e941 | ||
![]() |
7da777a4b7 | ||
![]() |
1dd0d4c61a |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -14,6 +14,8 @@ Breakpoints.xcbkptlist
|
|||||||
projects/VS2010/TestCatch/_UpgradeReport_Files/
|
projects/VS2010/TestCatch/_UpgradeReport_Files/
|
||||||
projects/VS2010/TestCatch/TestCatch/TestCatch.vcxproj.filters
|
projects/VS2010/TestCatch/TestCatch/TestCatch.vcxproj.filters
|
||||||
projects/VisualStudio/TestCatch/UpgradeLog.XML
|
projects/VisualStudio/TestCatch/UpgradeLog.XML
|
||||||
|
projects/CMake/.idea
|
||||||
|
projects/CMake/cmake-build-debug
|
||||||
UpgradeLog.XML
|
UpgradeLog.XML
|
||||||
Resources/DWARF
|
Resources/DWARF
|
||||||
projects/XCode/iOSTest/Build
|
projects/XCode/iOSTest/Build
|
||||||
|
164
.travis.yml
164
.travis.yml
@@ -1,19 +1,163 @@
|
|||||||
language: cpp
|
language: cpp
|
||||||
|
sudo: false
|
||||||
|
|
||||||
compiler:
|
cache:
|
||||||
- clang
|
ccache: true
|
||||||
- gcc
|
directories:
|
||||||
|
- $HOME/.ccache
|
||||||
|
|
||||||
env:
|
env:
|
||||||
- BUILD_TYPE=Debug
|
global:
|
||||||
- BUILD_TYPE=Release
|
- USE_CCACHE=1
|
||||||
|
- CCACHE_COMPRESS=1
|
||||||
|
- CCACHE_MAXSIZE=200M
|
||||||
|
- CCACHE_CPP2=1
|
||||||
|
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
|
||||||
|
# 1/ Linux Clang Builds
|
||||||
|
- os: linux
|
||||||
|
compiler: clang
|
||||||
|
addons: &clang35
|
||||||
|
apt:
|
||||||
|
sources: ['llvm-toolchain-precise-3.5', 'ubuntu-toolchain-r-test']
|
||||||
|
packages: ['clang-3.5']
|
||||||
|
env: COMPILER='ccache clang++-3.5' BUILD_TYPE='Release'
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
compiler: clang
|
||||||
|
addons: *clang35
|
||||||
|
env: COMPILER='ccache clang++-3.5' BUILD_TYPE='Debug'
|
||||||
|
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
compiler: clang
|
||||||
|
addons: &clang36
|
||||||
|
apt:
|
||||||
|
sources: ['llvm-toolchain-precise-3.6', 'ubuntu-toolchain-r-test']
|
||||||
|
packages: ['clang-3.6']
|
||||||
|
env: COMPILER='ccache clang++-3.6' BUILD_TYPE='Release'
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
compiler: clang
|
||||||
|
addons: *clang36
|
||||||
|
env: COMPILER='ccache clang++-3.6' BUILD_TYPE='Debug'
|
||||||
|
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
compiler: clang
|
||||||
|
addons: &clang37
|
||||||
|
apt:
|
||||||
|
sources: ['llvm-toolchain-precise-3.7', 'ubuntu-toolchain-r-test']
|
||||||
|
packages: ['clang-3.7']
|
||||||
|
env: COMPILER='ccache clang++-3.7' BUILD_TYPE='Release'
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
compiler: clang
|
||||||
|
addons: *clang37
|
||||||
|
env: COMPILER='ccache clang++-3.7' BUILD_TYPE='Debug'
|
||||||
|
|
||||||
|
|
||||||
|
- 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'
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
compiler: clang
|
||||||
|
addons: *clang38
|
||||||
|
env: COMPILER='ccache clang++-3.8' BUILD_TYPE='Debug'
|
||||||
|
|
||||||
|
|
||||||
|
# 2/ Linux GCC Builds
|
||||||
|
- os: linux
|
||||||
|
compiler: gcc
|
||||||
|
addons: &gcc48
|
||||||
|
apt:
|
||||||
|
sources: ['ubuntu-toolchain-r-test']
|
||||||
|
packages: ['g++-4.8']
|
||||||
|
env: COMPILER='ccache g++-4.8' BUILD_TYPE='Release'
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
compiler: gcc
|
||||||
|
addons: *gcc48
|
||||||
|
env: COMPILER='ccache g++-4.8' BUILD_TYPE='Debug'
|
||||||
|
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
compiler: gcc
|
||||||
|
addons: &gcc49
|
||||||
|
apt:
|
||||||
|
sources: ['ubuntu-toolchain-r-test']
|
||||||
|
packages: ['g++-4.9']
|
||||||
|
env: COMPILER='ccache g++-4.9' BUILD_TYPE='Release'
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
compiler: gcc
|
||||||
|
addons: *gcc49
|
||||||
|
env: COMPILER='ccache g++-4.9' BUILD_TYPE='Debug'
|
||||||
|
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
compiler: gcc
|
||||||
|
addons: &gcc5
|
||||||
|
apt:
|
||||||
|
sources: ['ubuntu-toolchain-r-test']
|
||||||
|
packages: ['g++-5']
|
||||||
|
env: COMPILER='ccache g++-5' BUILD_TYPE='Release'
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
compiler: gcc
|
||||||
|
addons: *gcc5
|
||||||
|
env: COMPILER='ccache g++-5' BUILD_TYPE='Debug'
|
||||||
|
|
||||||
|
|
||||||
|
# 3/ OSX Clang Builds
|
||||||
|
- os: osx
|
||||||
|
osx_image: xcode7
|
||||||
|
compiler: clang
|
||||||
|
env: COMPILER='ccache clang++' BUILD_TYPE='Debug'
|
||||||
|
|
||||||
|
- os: osx
|
||||||
|
osx_image: xcode7
|
||||||
|
compiler: clang
|
||||||
|
env: COMPILER='ccache clang++' BUILD_TYPE='Release'
|
||||||
|
|
||||||
|
- os: osx
|
||||||
|
osx_image: xcode8
|
||||||
|
compiler: clang
|
||||||
|
env: COMPILER='ccache clang++' BUILD_TYPE='Debug'
|
||||||
|
|
||||||
|
- os: osx
|
||||||
|
osx_image: xcode8
|
||||||
|
compiler: clang
|
||||||
|
env: COMPILER='ccache clang++' BUILD_TYPE='Release'
|
||||||
|
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- cmake -Hprojects/CMake -BBuild -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
- DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
|
||||||
|
- mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR}
|
||||||
|
- |
|
||||||
|
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
|
||||||
|
export PATH=${DEPS_DIR}/cmake/bin:${PATH}
|
||||||
|
elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
|
||||||
|
which cmake || brew install cmake
|
||||||
|
which ccache || brew install ccache
|
||||||
|
fi
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- export CXX=${COMPILER}
|
||||||
|
- cd ${TRAVIS_BUILD_DIR}
|
||||||
|
- cmake -Hprojects/CMake -BBuild -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
|
||||||
- cd Build
|
- cd Build
|
||||||
- make
|
|
||||||
- cd ..
|
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- cd Build
|
- make -j 2
|
||||||
- ctest -V
|
- ctest -V -j 2
|
||||||
|
@@ -1,12 +1,10 @@
|
|||||||

|

|
||||||
|
|
||||||
*v1.2.1-develop.14*
|
*v1.5.9*
|
||||||
|
|
||||||
Build status (on Travis CI) [](https://travis-ci.org/philsquared/Catch)
|
Build status (on Travis CI) [](https://travis-ci.org/philsquared/Catch)
|
||||||
|
|
||||||
[Please see this page if you are updating from a version before 1.0](docs/whats-changed.md)
|
<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>
|
||||||
|
|
||||||
<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>
|
|
||||||
|
|
||||||
## What's the Catch?
|
## What's the Catch?
|
||||||
|
|
||||||
@@ -19,8 +17,6 @@ This documentation comprises these three parts:
|
|||||||
* [Tutorial](docs/tutorial.md) - getting started
|
* [Tutorial](docs/tutorial.md) - getting started
|
||||||
* [Reference section](docs/Readme.md) - all the details
|
* [Reference section](docs/Readme.md) - all the details
|
||||||
|
|
||||||
The documentation will continue until morale improves
|
|
||||||
|
|
||||||
## More
|
## 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/philsquared/Catch/issues)
|
||||||
* For discussion or questions please use [the dedicated Google Groups forum](https://groups.google.com/forum/?fromgroups#!forum/catch-forum)
|
* For discussion or questions please use [the dedicated Google Groups forum](https://groups.google.com/forum/?fromgroups#!forum/catch-forum)
|
||||||
|
@@ -16,5 +16,4 @@ Before looking at this material be sure to read the [tutorial](tutorial.md)
|
|||||||
Other
|
Other
|
||||||
|
|
||||||
* [Why Catch?](why-catch.md)
|
* [Why Catch?](why-catch.md)
|
||||||
* [What's changed](whats-changed.md)
|
|
||||||
* [Contributing](contributing.md)
|
* [Contributing](contributing.md)
|
||||||
|
@@ -55,6 +55,16 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 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:
|
||||||
|
|
||||||
|
```
|
||||||
|
CATCH_TRANSLATE_EXCEPTION( MyType& ex ) {
|
||||||
|
return ex.message();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
[Home](Readme.md)
|
[Home](Readme.md)
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# Getting Catch
|
# Getting Catch
|
||||||
|
|
||||||
The simplest way to get Catch is to download the single header version from [http://builds.catch-lib.net](http://builds.catch-lib.net). Don't be put off by the word "builds" there. The single header is generated by merging a set of individual headers but it is still just normal source code in a header file.
|
The simplest way to get Catch is to download the latest [single header version](https://raw.githubusercontent.com/philsquared/Catch/master/single_include/catch.hpp). The single header is generated by merging a set of individual headers but it is still just normal source code in a header file.
|
||||||
|
|
||||||
The 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.
|
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.
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ Although this was a simple test it's been enough to demonstrate a few things abo
|
|||||||
|
|
||||||
Most test frameworks have a class-based fixture mechanism. That is, test cases map to methods on a class and common setup and teardown can be performed in ```setup()``` and ```teardown()``` methods (or constructor/ destructor in languages, like C++, that support deterministic destruction).
|
Most test frameworks have a class-based fixture mechanism. That is, test cases map to methods on a class and common setup and teardown can be performed in ```setup()``` and ```teardown()``` methods (or constructor/ destructor in languages, like C++, that support deterministic destruction).
|
||||||
|
|
||||||
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 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>).
|
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:
|
||||||
|
|
||||||
|
@@ -1,24 +0,0 @@
|
|||||||
## What's new in Catch for 1.0
|
|
||||||
|
|
||||||
After a long "developer preview" state Catch turned 1.0 in mid-2013. Just prior to this a large number of changes, some of them breaking, where merged from the integration branch and now form part of the 1.0 code-base. If this might affect you please read this summary through so you know what to expect.
|
|
||||||
|
|
||||||
* Calling Catch from your own ```main()``` has changed - please review [the updated docs](own-main.md)
|
|
||||||
* The command line has changed. The biggest change is that test case names and tags should now only be supplied as primary arguments - in fact the ```-t``` option has been repurposed to mean "list tags". There are [updated docs for this too](command-line.md)
|
|
||||||
* There is a new reporter interface. If you have written a custom reporter you can use the ```LegacyReporterAdapter``` to minimise any differences. Ideally you should update to the new interface - especially as it has been designed to be more robust in the face of future changes (which should be minimal).
|
|
||||||
* The docs have moved from the wiki to the repository itself. They consist of a set of markdown files in the docs folder and are referenced directly from the README in the root. You can still read them online from GitHub.
|
|
||||||
* Lots of new goodness - more documentation for which is coming. The existing docs have been updated to account for some of the changes already (e.g. variadic macros). A quick rundown:
|
|
||||||
* Variadic macros are used, where possible, so that, e.g. you can write a ```TEST_CASE``` with just a name - or even no name at all (making it an anonymous test case).
|
|
||||||
* The hierarchical naming convention is deprecated in favour of using tags (see next)
|
|
||||||
* ```TEST_CASE```s (but not ```SECTION```s) can now be tagged by placing keywords in square brackets in the second argument - e.g.: ```TEST_CASE( "A nice name", "[tag1][tag2]")```. The old style is still supported but please consider using this new style.
|
|
||||||
* Tests can still be "hidden" using the ```./``` prefix as before, but the preferred way now is to give it the ```[hide]``` tag (hidden tests are skipped if you run the test process without specifying any test specs).
|
|
||||||
* As well as ```TEST_CASE```s and ```SECTION```s you can now also use BDD-style ```SCENARIO``` (in place of ```TEST_CASE```) and ```GIVEN```, ```WHEN``` and ```THEN``` macros (in place of ```SECTION```s).
|
|
||||||
* New command line parser. Under the hood it is a complete rewrite - now powered by a command line library that will soon be spun out as a separate project: Clara. The options themselves are largely the same but there are some notable differences (as already discussed).
|
|
||||||
* Completely overhauled output from the textual reporter (now the Console reporter). This now features a much clearer, cleaner format, including good use of indentation.
|
|
||||||
|
|
||||||
More information can be found in [this blog post](http://www.levelofindirection.com/journal/2013/6/28/catch-10.html).
|
|
||||||
|
|
||||||
If you find any issues please raise issue tickets on the [issue tracker on GitHub](https://github.com/philsquared/Catch/issues) as before. For general questions, comments and suggestions, though, please use the [new forums on Google Groups](https://groups.google.com/forum/?fromgroups#!forum/catch-forum).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
[Home](Readme.md)
|
|
@@ -99,6 +99,7 @@
|
|||||||
#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
|
#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_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_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_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
|
||||||
#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ )
|
#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ )
|
||||||
#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ )
|
#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ )
|
||||||
@@ -106,6 +107,7 @@
|
|||||||
#define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
|
#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_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_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_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_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg )
|
||||||
#define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg )
|
#define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg )
|
||||||
@@ -166,6 +168,7 @@
|
|||||||
#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
|
#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
|
||||||
#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __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 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 SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
|
||||||
#define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ )
|
#define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ )
|
||||||
#define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ )
|
#define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ )
|
||||||
@@ -173,6 +176,7 @@
|
|||||||
#define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
|
#define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
|
||||||
#define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
|
#define 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 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 SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
|
||||||
#define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg )
|
#define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg )
|
||||||
#define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg )
|
#define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg )
|
||||||
|
@@ -30,7 +30,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
return reporter;
|
return reporter;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ptr<IStreamingReporter> makeReporter( Ptr<Config> const& config ) {
|
Ptr<IStreamingReporter> makeReporter( Ptr<Config> const& config ) {
|
||||||
std::vector<std::string> reporters = config->getReporterNames();
|
std::vector<std::string> reporters = config->getReporterNames();
|
||||||
if( reporters.empty() )
|
if( reporters.empty() )
|
||||||
@@ -40,10 +40,10 @@ namespace Catch {
|
|||||||
for( std::vector<std::string>::const_iterator it = reporters.begin(), itEnd = reporters.end();
|
for( std::vector<std::string>::const_iterator it = reporters.begin(), itEnd = reporters.end();
|
||||||
it != itEnd;
|
it != itEnd;
|
||||||
++it )
|
++it )
|
||||||
reporter = addReporter( reporter, createReporter( *it, config ) );
|
reporter = addReporter( reporter, createReporter( *it, config ) );
|
||||||
return reporter;
|
return reporter;
|
||||||
}
|
}
|
||||||
Ptr<IStreamingReporter> addListeners( Ptr<IConfig> const& config, Ptr<IStreamingReporter> reporters ) {
|
Ptr<IStreamingReporter> addListeners( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> reporters ) {
|
||||||
IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners();
|
IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners();
|
||||||
for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end();
|
for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end();
|
||||||
it != itEnd;
|
it != itEnd;
|
||||||
@@ -51,28 +51,16 @@ namespace Catch {
|
|||||||
reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) );
|
reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) );
|
||||||
return reporters;
|
return reporters;
|
||||||
}
|
}
|
||||||
|
|
||||||
void openStreamInto( Ptr<Config> const& config, std::ofstream& ofs ) {
|
|
||||||
// Open output file, if specified
|
|
||||||
if( !config->getFilename().empty() ) {
|
|
||||||
ofs.open( config->getFilename().c_str() );
|
|
||||||
if( ofs.fail() ) {
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << "Unable to open file: '" << config->getFilename() << "'";
|
|
||||||
throw std::domain_error( oss.str() );
|
|
||||||
}
|
|
||||||
config->setStreamBuf( ofs.rdbuf() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Totals runTests( Ptr<Config> const& config ) {
|
Totals runTests( Ptr<Config> const& config ) {
|
||||||
|
|
||||||
std::ofstream ofs;
|
Ptr<IConfig const> iconfig = config.get();
|
||||||
openStreamInto( config, ofs );
|
|
||||||
Ptr<IStreamingReporter> reporter = makeReporter( config );
|
Ptr<IStreamingReporter> reporter = makeReporter( config );
|
||||||
reporter = addListeners( config.get(), reporter );
|
reporter = addListeners( iconfig, reporter );
|
||||||
|
|
||||||
RunContext context( config.get(), reporter );
|
RunContext context( iconfig, reporter );
|
||||||
|
|
||||||
Totals totals;
|
Totals totals;
|
||||||
|
|
||||||
@@ -82,26 +70,26 @@ namespace Catch {
|
|||||||
if( !testSpec.hasFilters() )
|
if( !testSpec.hasFilters() )
|
||||||
testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests
|
testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests
|
||||||
|
|
||||||
std::vector<TestCase> const& allTestCases = getAllTestCasesSorted( *config );
|
std::vector<TestCase> const& allTestCases = getAllTestCasesSorted( *iconfig );
|
||||||
for( std::vector<TestCase>::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end();
|
for( std::vector<TestCase>::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end();
|
||||||
it != itEnd;
|
it != itEnd;
|
||||||
++it ) {
|
++it ) {
|
||||||
if( !context.aborting() && matchTest( *it, testSpec, *config ) )
|
if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) )
|
||||||
totals += context.runTest( *it );
|
totals += context.runTest( *it );
|
||||||
else
|
else
|
||||||
reporter->skipTest( *it );
|
reporter->skipTest( *it );
|
||||||
}
|
}
|
||||||
|
|
||||||
context.testGroupEnded( config->name(), totals, 1, 1 );
|
context.testGroupEnded( iconfig->name(), totals, 1, 1 );
|
||||||
return totals;
|
return totals;
|
||||||
}
|
}
|
||||||
|
|
||||||
void applyFilenamesAsTags( IConfig const& config ) {
|
void applyFilenamesAsTags( IConfig const& config ) {
|
||||||
std::vector<TestCase> const& tests = getAllTestCasesSorted( config );
|
std::vector<TestCase> const& tests = getAllTestCasesSorted( config );
|
||||||
for(std::size_t i = 0; i < tests.size(); ++i ) {
|
for(std::size_t i = 0; i < tests.size(); ++i ) {
|
||||||
TestCase& test = const_cast<TestCase&>( tests[i] );
|
TestCase& test = const_cast<TestCase&>( tests[i] );
|
||||||
std::set<std::string> tags = test.tags;
|
std::set<std::string> tags = test.tags;
|
||||||
|
|
||||||
std::string filename = test.lineInfo.file;
|
std::string filename = test.lineInfo.file;
|
||||||
std::string::size_type lastSlash = filename.find_last_of( "\\/" );
|
std::string::size_type lastSlash = filename.find_last_of( "\\/" );
|
||||||
if( lastSlash != std::string::npos )
|
if( lastSlash != std::string::npos )
|
||||||
@@ -110,7 +98,7 @@ namespace Catch {
|
|||||||
std::string::size_type lastDot = filename.find_last_of( "." );
|
std::string::size_type lastDot = filename.find_last_of( "." );
|
||||||
if( lastDot != std::string::npos )
|
if( lastDot != std::string::npos )
|
||||||
filename = filename.substr( 0, lastDot );
|
filename = filename.substr( 0, lastDot );
|
||||||
|
|
||||||
tags.insert( "#" + filename );
|
tags.insert( "#" + filename );
|
||||||
setTags( test, tags );
|
setTags( test, tags );
|
||||||
}
|
}
|
||||||
@@ -143,10 +131,10 @@ namespace Catch {
|
|||||||
Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
|
Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
int applyCommandLine( int argc, char* const argv[], OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
|
int applyCommandLine( int argc, char const* const* const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
|
||||||
try {
|
try {
|
||||||
m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
|
m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
|
||||||
m_unusedTokens = m_cli.parseInto( argc, argv, m_configData );
|
m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData );
|
||||||
if( m_configData.showHelp )
|
if( m_configData.showHelp )
|
||||||
showHelp( m_configData.processName );
|
showHelp( m_configData.processName );
|
||||||
m_config.reset();
|
m_config.reset();
|
||||||
@@ -170,7 +158,7 @@ namespace Catch {
|
|||||||
m_config.reset();
|
m_config.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
int run( int argc, char* const argv[] ) {
|
int run( int argc, char const* const* const argv ) {
|
||||||
|
|
||||||
int returnCode = applyCommandLine( argc, argv );
|
int returnCode = applyCommandLine( argc, argv );
|
||||||
if( returnCode == 0 )
|
if( returnCode == 0 )
|
||||||
@@ -185,12 +173,12 @@ namespace Catch {
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
config(); // Force config to be constructed
|
config(); // Force config to be constructed
|
||||||
|
|
||||||
seedRng( *m_config );
|
seedRng( *m_config );
|
||||||
|
|
||||||
if( m_configData.filenamesAsTags )
|
if( m_configData.filenamesAsTags )
|
||||||
applyFilenamesAsTags( *m_config );
|
applyFilenamesAsTags( *m_config );
|
||||||
|
|
||||||
// Handle list request
|
// Handle list request
|
||||||
if( Option<std::size_t> listed = list( config() ) )
|
if( Option<std::size_t> listed = list( config() ) )
|
||||||
return static_cast<int>( *listed );
|
return static_cast<int>( *listed );
|
||||||
|
@@ -8,8 +8,7 @@
|
|||||||
#ifndef TWOBLUECUBES_CATCH_WITH_MAIN_HPP_INCLUDED
|
#ifndef TWOBLUECUBES_CATCH_WITH_MAIN_HPP_INCLUDED
|
||||||
#define TWOBLUECUBES_CATCH_WITH_MAIN_HPP_INCLUDED
|
#define TWOBLUECUBES_CATCH_WITH_MAIN_HPP_INCLUDED
|
||||||
|
|
||||||
#include "catch_runner.hpp"
|
#define CATCH_CONFIG_MAIN
|
||||||
#include "catch.hpp"
|
#include "catch.hpp"
|
||||||
#include "internal/catch_default_main.hpp"
|
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_WITH_MAIN_HPP_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_WITH_MAIN_HPP_INCLUDED
|
||||||
|
352
include/external/clara.h
vendored
352
include/external/clara.h
vendored
@@ -6,6 +6,8 @@
|
|||||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Version 0.0.2.4
|
||||||
|
|
||||||
// Only use header guard if we are not using an outer namespace
|
// Only use header guard if we are not using an outer namespace
|
||||||
#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
|
#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
|
||||||
|
|
||||||
@@ -38,6 +40,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
// Use optional outer namespace
|
// Use optional outer namespace
|
||||||
#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
|
#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
|
||||||
@@ -172,16 +175,179 @@ namespace Tbc {
|
|||||||
#endif // TBC_TEXT_FORMAT_H_INCLUDED
|
#endif // TBC_TEXT_FORMAT_H_INCLUDED
|
||||||
|
|
||||||
// ----------- end of #include from tbc_text_format.h -----------
|
// ----------- end of #include from tbc_text_format.h -----------
|
||||||
// ........... back in /Users/philnash/Dev/OSS/Clara/srcs/clara.h
|
// ........... back in clara.h
|
||||||
|
|
||||||
#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
|
#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
// ----------- #included from clara_compilers.h -----------
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Created by Phil on 10/02/2016.
|
||||||
|
* Copyright 2016 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_CLARA_COMPILERS_H_INCLUDED
|
||||||
|
#define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
|
||||||
|
|
||||||
|
// Detect a number of compiler features - mostly C++11/14 conformance - by compiler
|
||||||
|
// The following features are defined:
|
||||||
|
//
|
||||||
|
// CLARA_CONFIG_CPP11_NULLPTR : is nullptr supported?
|
||||||
|
// CLARA_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
|
||||||
|
// CLARA_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
|
||||||
|
// CLARA_CONFIG_CPP11_OVERRIDE : is override supported?
|
||||||
|
// CLARA_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
|
||||||
|
|
||||||
|
// CLARA_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
|
||||||
|
|
||||||
|
// CLARA_CONFIG_VARIADIC_MACROS : are variadic macros supported?
|
||||||
|
|
||||||
|
// In general each macro has a _NO_<feature name> form
|
||||||
|
// (e.g. CLARA_CONFIG_CPP11_NO_NULLPTR) 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 CLARA_CONFIG_NO_CPP11
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
|
||||||
|
#if __has_feature(cxx_nullptr)
|
||||||
|
#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_feature(cxx_noexcept)
|
||||||
|
#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __clang__
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// GCC
|
||||||
|
#ifdef __GNUC__
|
||||||
|
|
||||||
|
#if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||||
|
#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// - otherwise more recent versions define __cplusplus >= 201103L
|
||||||
|
// and will get picked up below
|
||||||
|
|
||||||
|
#endif // __GNUC__
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Visual C++
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
#if (_MSC_VER >= 1600)
|
||||||
|
#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
|
||||||
|
#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
|
||||||
|
#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
|
||||||
|
#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // _MSC_VER
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// C++ language feature support
|
||||||
|
|
||||||
|
// catch all support for C++11
|
||||||
|
#if defined(__cplusplus) && __cplusplus >= 201103L
|
||||||
|
|
||||||
|
#define CLARA_CPP11_OR_GREATER
|
||||||
|
|
||||||
|
#if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR)
|
||||||
|
#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
|
||||||
|
#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
|
||||||
|
#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE)
|
||||||
|
#define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE
|
||||||
|
#endif
|
||||||
|
#if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
|
||||||
|
#define CLARA_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(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11)
|
||||||
|
#define CLARA_CONFIG_CPP11_NULLPTR
|
||||||
|
#endif
|
||||||
|
#if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11)
|
||||||
|
#define CLARA_CONFIG_CPP11_NOEXCEPT
|
||||||
|
#endif
|
||||||
|
#if defined(CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_NO_CPP11)
|
||||||
|
#define CLARA_CONFIG_CPP11_GENERATED_METHODS
|
||||||
|
#endif
|
||||||
|
#if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11)
|
||||||
|
#define CLARA_CONFIG_CPP11_OVERRIDE
|
||||||
|
#endif
|
||||||
|
#if defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_UNIQUE_PTR) && !defined(CLARA_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_CPP11)
|
||||||
|
#define CLARA_CONFIG_CPP11_UNIQUE_PTR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// noexcept support:
|
||||||
|
#if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT)
|
||||||
|
#define CLARA_NOEXCEPT noexcept
|
||||||
|
# define CLARA_NOEXCEPT_IS(x) noexcept(x)
|
||||||
|
#else
|
||||||
|
#define CLARA_NOEXCEPT throw()
|
||||||
|
# define CLARA_NOEXCEPT_IS(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// nullptr support
|
||||||
|
#ifdef CLARA_CONFIG_CPP11_NULLPTR
|
||||||
|
#define CLARA_NULL nullptr
|
||||||
|
#else
|
||||||
|
#define CLARA_NULL NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// override support
|
||||||
|
#ifdef CLARA_CONFIG_CPP11_OVERRIDE
|
||||||
|
#define CLARA_OVERRIDE override
|
||||||
|
#else
|
||||||
|
#define CLARA_OVERRIDE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// unique_ptr support
|
||||||
|
#ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR
|
||||||
|
# define CLARA_AUTO_PTR( T ) std::unique_ptr<T>
|
||||||
|
#else
|
||||||
|
# define CLARA_AUTO_PTR( T ) std::auto_ptr<T>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
// ----------- end of #include from clara_compilers.h -----------
|
||||||
|
// ........... back in clara.h
|
||||||
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <algorithm>
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
|
||||||
|
#define CLARA_PLATFORM_WINDOWS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Use optional outer namespace
|
// Use optional outer namespace
|
||||||
#ifdef STITCH_CLARA_OPEN_NAMESPACE
|
#ifdef STITCH_CLARA_OPEN_NAMESPACE
|
||||||
STITCH_CLARA_OPEN_NAMESPACE
|
STITCH_CLARA_OPEN_NAMESPACE
|
||||||
@@ -230,9 +396,12 @@ namespace Clara {
|
|||||||
inline void convertInto( std::string const& _source, std::string& _dest ) {
|
inline void convertInto( std::string const& _source, std::string& _dest ) {
|
||||||
_dest = _source;
|
_dest = _source;
|
||||||
}
|
}
|
||||||
|
char toLowerCh(char c) {
|
||||||
|
return static_cast<char>( ::tolower( c ) );
|
||||||
|
}
|
||||||
inline void convertInto( std::string const& _source, bool& _dest ) {
|
inline void convertInto( std::string const& _source, bool& _dest ) {
|
||||||
std::string sourceLC = _source;
|
std::string sourceLC = _source;
|
||||||
std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower );
|
std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), toLowerCh );
|
||||||
if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" )
|
if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" )
|
||||||
_dest = true;
|
_dest = true;
|
||||||
else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" )
|
else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" )
|
||||||
@@ -240,23 +409,16 @@ namespace Clara {
|
|||||||
else
|
else
|
||||||
throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" );
|
throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" );
|
||||||
}
|
}
|
||||||
inline void convertInto( bool _source, bool& _dest ) {
|
|
||||||
_dest = _source;
|
|
||||||
}
|
|
||||||
template<typename T>
|
|
||||||
inline void convertInto( bool, T& ) {
|
|
||||||
throw std::runtime_error( "Invalid conversion" );
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ConfigT>
|
template<typename ConfigT>
|
||||||
struct IArgFunction {
|
struct IArgFunction {
|
||||||
virtual ~IArgFunction() {}
|
virtual ~IArgFunction() {}
|
||||||
# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
|
#ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS
|
||||||
IArgFunction() = default;
|
IArgFunction() = default;
|
||||||
IArgFunction( IArgFunction const& ) = default;
|
IArgFunction( IArgFunction const& ) = default;
|
||||||
# endif
|
#endif
|
||||||
virtual void set( ConfigT& config, std::string const& value ) const = 0;
|
virtual void set( ConfigT& config, std::string const& value ) const = 0;
|
||||||
virtual void setFlag( ConfigT& config ) const = 0;
|
|
||||||
virtual bool takesArg() const = 0;
|
virtual bool takesArg() const = 0;
|
||||||
virtual IArgFunction* clone() const = 0;
|
virtual IArgFunction* clone() const = 0;
|
||||||
};
|
};
|
||||||
@@ -264,11 +426,11 @@ namespace Clara {
|
|||||||
template<typename ConfigT>
|
template<typename ConfigT>
|
||||||
class BoundArgFunction {
|
class BoundArgFunction {
|
||||||
public:
|
public:
|
||||||
BoundArgFunction() : functionObj( CATCH_NULL ) {}
|
BoundArgFunction() : functionObj( CLARA_NULL ) {}
|
||||||
BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
|
BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
|
||||||
BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CATCH_NULL ) {}
|
BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {}
|
||||||
BoundArgFunction& operator = ( BoundArgFunction const& other ) {
|
BoundArgFunction& operator = ( BoundArgFunction const& other ) {
|
||||||
IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : CATCH_NULL;
|
IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL;
|
||||||
delete functionObj;
|
delete functionObj;
|
||||||
functionObj = newFunctionObj;
|
functionObj = newFunctionObj;
|
||||||
return *this;
|
return *this;
|
||||||
@@ -278,13 +440,10 @@ namespace Clara {
|
|||||||
void set( ConfigT& config, std::string const& value ) const {
|
void set( ConfigT& config, std::string const& value ) const {
|
||||||
functionObj->set( config, value );
|
functionObj->set( config, value );
|
||||||
}
|
}
|
||||||
void setFlag( ConfigT& config ) const {
|
|
||||||
functionObj->setFlag( config );
|
|
||||||
}
|
|
||||||
bool takesArg() const { return functionObj->takesArg(); }
|
bool takesArg() const { return functionObj->takesArg(); }
|
||||||
|
|
||||||
bool isSet() const {
|
bool isSet() const {
|
||||||
return functionObj != CATCH_NULL;
|
return functionObj != CLARA_NULL;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
IArgFunction<ConfigT>* functionObj;
|
IArgFunction<ConfigT>* functionObj;
|
||||||
@@ -294,7 +453,6 @@ namespace Clara {
|
|||||||
template<typename C>
|
template<typename C>
|
||||||
struct NullBinder : IArgFunction<C>{
|
struct NullBinder : IArgFunction<C>{
|
||||||
virtual void set( C&, std::string const& ) const {}
|
virtual void set( C&, std::string const& ) const {}
|
||||||
virtual void setFlag( C& ) const {}
|
|
||||||
virtual bool takesArg() const { return true; }
|
virtual bool takesArg() const { return true; }
|
||||||
virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
|
virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
|
||||||
};
|
};
|
||||||
@@ -305,9 +463,6 @@ namespace Clara {
|
|||||||
virtual void set( C& p, std::string const& stringValue ) const {
|
virtual void set( C& p, std::string const& stringValue ) const {
|
||||||
convertInto( stringValue, p.*member );
|
convertInto( stringValue, p.*member );
|
||||||
}
|
}
|
||||||
virtual void setFlag( C& p ) const {
|
|
||||||
convertInto( true, p.*member );
|
|
||||||
}
|
|
||||||
virtual bool takesArg() const { return !IsBool<M>::value; }
|
virtual bool takesArg() const { return !IsBool<M>::value; }
|
||||||
virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
|
virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
|
||||||
M C::* member;
|
M C::* member;
|
||||||
@@ -320,11 +475,6 @@ namespace Clara {
|
|||||||
convertInto( stringValue, value );
|
convertInto( stringValue, value );
|
||||||
(p.*member)( value );
|
(p.*member)( value );
|
||||||
}
|
}
|
||||||
virtual void setFlag( C& p ) const {
|
|
||||||
typename RemoveConstRef<M>::type value;
|
|
||||||
convertInto( true, value );
|
|
||||||
(p.*member)( value );
|
|
||||||
}
|
|
||||||
virtual bool takesArg() const { return !IsBool<M>::value; }
|
virtual bool takesArg() const { return !IsBool<M>::value; }
|
||||||
virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
|
virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
|
||||||
void (C::*member)( M );
|
void (C::*member)( M );
|
||||||
@@ -338,9 +488,6 @@ namespace Clara {
|
|||||||
if( value )
|
if( value )
|
||||||
(p.*member)();
|
(p.*member)();
|
||||||
}
|
}
|
||||||
virtual void setFlag( C& p ) const {
|
|
||||||
(p.*member)();
|
|
||||||
}
|
|
||||||
virtual bool takesArg() const { return false; }
|
virtual bool takesArg() const { return false; }
|
||||||
virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
|
virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
|
||||||
void (C::*member)();
|
void (C::*member)();
|
||||||
@@ -355,9 +502,6 @@ namespace Clara {
|
|||||||
if( value )
|
if( value )
|
||||||
function( obj );
|
function( obj );
|
||||||
}
|
}
|
||||||
virtual void setFlag( C& p ) const {
|
|
||||||
function( p );
|
|
||||||
}
|
|
||||||
virtual bool takesArg() const { return false; }
|
virtual bool takesArg() const { return false; }
|
||||||
virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
|
virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
|
||||||
void (*function)( C& );
|
void (*function)( C& );
|
||||||
@@ -371,11 +515,6 @@ namespace Clara {
|
|||||||
convertInto( stringValue, value );
|
convertInto( stringValue, value );
|
||||||
function( obj, value );
|
function( obj, value );
|
||||||
}
|
}
|
||||||
virtual void setFlag( C& obj ) const {
|
|
||||||
typename RemoveConstRef<T>::type value;
|
|
||||||
convertInto( true, value );
|
|
||||||
function( obj, value );
|
|
||||||
}
|
|
||||||
virtual bool takesArg() const { return !IsBool<T>::value; }
|
virtual bool takesArg() const { return !IsBool<T>::value; }
|
||||||
virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
|
virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
|
||||||
void (*function)( C&, T );
|
void (*function)( C&, T );
|
||||||
@@ -383,8 +522,20 @@ namespace Clara {
|
|||||||
|
|
||||||
} // namespace Detail
|
} // namespace Detail
|
||||||
|
|
||||||
struct Parser {
|
inline std::vector<std::string> argsToVector( int argc, char const* const* const argv ) {
|
||||||
Parser() : separators( " \t=:" ) {}
|
std::vector<std::string> args( static_cast<std::size_t>( argc ) );
|
||||||
|
for( std::size_t i = 0; i < static_cast<std::size_t>( argc ); ++i )
|
||||||
|
args[i] = argv[i];
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Parser {
|
||||||
|
enum Mode { None, MaybeShortOpt, SlashOpt, ShortOpt, LongOpt, Positional };
|
||||||
|
Mode mode;
|
||||||
|
std::size_t from;
|
||||||
|
bool inQuotes;
|
||||||
|
public:
|
||||||
|
|
||||||
struct Token {
|
struct Token {
|
||||||
enum Type { Positional, ShortOpt, LongOpt };
|
enum Type { Positional, ShortOpt, LongOpt };
|
||||||
@@ -393,38 +544,75 @@ namespace Clara {
|
|||||||
std::string data;
|
std::string data;
|
||||||
};
|
};
|
||||||
|
|
||||||
void parseIntoTokens( int argc, char const * const * argv, std::vector<Parser::Token>& tokens ) const {
|
Parser() : mode( None ), from( 0 ), inQuotes( false ){}
|
||||||
|
|
||||||
|
void parseIntoTokens( std::vector<std::string> const& args, std::vector<Token>& tokens ) {
|
||||||
const std::string doubleDash = "--";
|
const std::string doubleDash = "--";
|
||||||
for( int i = 1; i < argc && argv[i] != doubleDash; ++i )
|
for( std::size_t i = 1; i < args.size() && args[i] != doubleDash; ++i )
|
||||||
parseIntoTokens( argv[i] , tokens);
|
parseIntoTokens( args[i], tokens);
|
||||||
}
|
}
|
||||||
void parseIntoTokens( std::string arg, std::vector<Parser::Token>& tokens ) const {
|
|
||||||
while( !arg.empty() ) {
|
void parseIntoTokens( std::string const& arg, std::vector<Token>& tokens ) {
|
||||||
Parser::Token token( Parser::Token::Positional, arg );
|
for( std::size_t i = 0; i <= arg.size(); ++i ) {
|
||||||
arg = "";
|
char c = arg[i];
|
||||||
if( token.data[0] == '-' ) {
|
if( c == '"' )
|
||||||
if( token.data.size() > 1 && token.data[1] == '-' ) {
|
inQuotes = !inQuotes;
|
||||||
token = Parser::Token( Parser::Token::LongOpt, token.data.substr( 2 ) );
|
mode = handleMode( i, c, arg, tokens );
|
||||||
}
|
|
||||||
else {
|
|
||||||
token = Parser::Token( Parser::Token::ShortOpt, token.data.substr( 1 ) );
|
|
||||||
if( token.data.size() > 1 && separators.find( token.data[1] ) == std::string::npos ) {
|
|
||||||
arg = "-" + token.data.substr( 1 );
|
|
||||||
token.data = token.data.substr( 0, 1 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( token.type != Parser::Token::Positional ) {
|
|
||||||
std::size_t pos = token.data.find_first_of( separators );
|
|
||||||
if( pos != std::string::npos ) {
|
|
||||||
arg = token.data.substr( pos+1 );
|
|
||||||
token.data = token.data.substr( 0, pos );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tokens.push_back( token );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::string separators;
|
Mode handleMode( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
|
||||||
|
switch( mode ) {
|
||||||
|
case None: return handleNone( i, c );
|
||||||
|
case MaybeShortOpt: return handleMaybeShortOpt( i, c );
|
||||||
|
case ShortOpt:
|
||||||
|
case LongOpt:
|
||||||
|
case SlashOpt: return handleOpt( i, c, arg, tokens );
|
||||||
|
case Positional: return handlePositional( i, c, arg, tokens );
|
||||||
|
default: throw std::logic_error( "Unknown mode" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Mode handleNone( std::size_t i, char c ) {
|
||||||
|
if( inQuotes ) {
|
||||||
|
from = i;
|
||||||
|
return Positional;
|
||||||
|
}
|
||||||
|
switch( c ) {
|
||||||
|
case '-': return MaybeShortOpt;
|
||||||
|
#ifdef CLARA_PLATFORM_WINDOWS
|
||||||
|
case '/': from = i+1; return SlashOpt;
|
||||||
|
#endif
|
||||||
|
default: from = i; return Positional;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Mode handleMaybeShortOpt( std::size_t i, char c ) {
|
||||||
|
switch( c ) {
|
||||||
|
case '-': from = i+1; return LongOpt;
|
||||||
|
default: from = i; return ShortOpt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Mode handleOpt( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
|
||||||
|
if( std::string( ":=\0", 3 ).find( c ) == std::string::npos )
|
||||||
|
return mode;
|
||||||
|
|
||||||
|
std::string optName = arg.substr( from, i-from );
|
||||||
|
if( mode == ShortOpt )
|
||||||
|
for( std::size_t j = 0; j < optName.size(); ++j )
|
||||||
|
tokens.push_back( Token( Token::ShortOpt, optName.substr( j, 1 ) ) );
|
||||||
|
else if( mode == SlashOpt && optName.size() == 1 )
|
||||||
|
tokens.push_back( Token( Token::ShortOpt, optName ) );
|
||||||
|
else
|
||||||
|
tokens.push_back( Token( Token::LongOpt, optName ) );
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Mode handlePositional( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
|
||||||
|
if( inQuotes || std::string( "\0", 1 ).find( c ) == std::string::npos )
|
||||||
|
return mode;
|
||||||
|
|
||||||
|
std::string data = arg.substr( from, i-from );
|
||||||
|
tokens.push_back( Token( Token::Positional, data ) );
|
||||||
|
return None;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename ConfigT>
|
template<typename ConfigT>
|
||||||
@@ -503,7 +691,7 @@ namespace Clara {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef CATCH_AUTO_PTR( Arg ) ArgAutoPtr;
|
typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr;
|
||||||
|
|
||||||
friend void addOptName( Arg& arg, std::string const& optName )
|
friend void addOptName( Arg& arg, std::string const& optName )
|
||||||
{
|
{
|
||||||
@@ -580,8 +768,8 @@ namespace Clara {
|
|||||||
m_arg->description = description;
|
m_arg->description = description;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
ArgBuilder& detail( std::string const& _detail ) {
|
ArgBuilder& detail( std::string const& detail ) {
|
||||||
m_arg->detail = _detail;
|
m_arg->detail = detail;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -665,14 +853,14 @@ namespace Clara {
|
|||||||
maxWidth = (std::max)( maxWidth, it->commands().size() );
|
maxWidth = (std::max)( maxWidth, it->commands().size() );
|
||||||
|
|
||||||
for( it = itBegin; it != itEnd; ++it ) {
|
for( it = itBegin; it != itEnd; ++it ) {
|
||||||
Detail::Text usageText( it->commands(), Detail::TextAttributes()
|
Detail::Text usage( it->commands(), Detail::TextAttributes()
|
||||||
.setWidth( maxWidth+indent )
|
.setWidth( maxWidth+indent )
|
||||||
.setIndent( indent ) );
|
.setIndent( indent ) );
|
||||||
Detail::Text desc( it->description, Detail::TextAttributes()
|
Detail::Text desc( it->description, Detail::TextAttributes()
|
||||||
.setWidth( width - maxWidth - 3 ) );
|
.setWidth( width - maxWidth - 3 ) );
|
||||||
|
|
||||||
for( std::size_t i = 0; i < (std::max)( usageText.size(), desc.size() ); ++i ) {
|
for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {
|
||||||
std::string usageCol = i < usageText.size() ? usageText[i] : "";
|
std::string usageCol = i < usage.size() ? usage[i] : "";
|
||||||
os << usageCol;
|
os << usageCol;
|
||||||
|
|
||||||
if( i < desc.size() && !desc[i].empty() )
|
if( i < desc.size() && !desc[i].empty() )
|
||||||
@@ -729,21 +917,21 @@ namespace Clara {
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigT parse( int argc, char const * const * argv ) const {
|
ConfigT parse( std::vector<std::string> const& args ) const {
|
||||||
ConfigT config;
|
ConfigT config;
|
||||||
parseInto( argc, argv, config );
|
parseInto( args, config );
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Parser::Token> parseInto( int argc, char const * const * argv, ConfigT& config ) const {
|
std::vector<Parser::Token> parseInto( std::vector<std::string> const& args, ConfigT& config ) const {
|
||||||
std::string processName = argv[0];
|
std::string processName = args[0];
|
||||||
std::size_t lastSlash = processName.find_last_of( "/\\" );
|
std::size_t lastSlash = processName.find_last_of( "/\\" );
|
||||||
if( lastSlash != std::string::npos )
|
if( lastSlash != std::string::npos )
|
||||||
processName = processName.substr( lastSlash+1 );
|
processName = processName.substr( lastSlash+1 );
|
||||||
m_boundProcessName.set( config, processName );
|
m_boundProcessName.set( config, processName );
|
||||||
std::vector<Parser::Token> tokens;
|
std::vector<Parser::Token> tokens;
|
||||||
Parser parser;
|
Parser parser;
|
||||||
parser.parseIntoTokens( argc, argv, tokens );
|
parser.parseIntoTokens( args, tokens );
|
||||||
return populate( tokens, config );
|
return populate( tokens, config );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -774,7 +962,7 @@ namespace Clara {
|
|||||||
arg.boundField.set( config, tokens[++i].data );
|
arg.boundField.set( config, tokens[++i].data );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
arg.boundField.setFlag( config );
|
arg.boundField.set( config, "true" );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -33,13 +33,14 @@
|
|||||||
do { \
|
do { \
|
||||||
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
|
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
|
||||||
try { \
|
try { \
|
||||||
|
CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
|
||||||
( __catchResult <= expr ).endExpression(); \
|
( __catchResult <= expr ).endExpression(); \
|
||||||
} \
|
} \
|
||||||
catch( ... ) { \
|
catch( ... ) { \
|
||||||
__catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
|
__catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
|
||||||
} \
|
} \
|
||||||
INTERNAL_CATCH_REACT( __catchResult ) \
|
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
|
} 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 ) \
|
#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
|
||||||
@@ -129,14 +130,14 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
|
#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
|
||||||
do { \
|
do { \
|
||||||
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg " " #matcher, resultDisposition ); \
|
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \
|
||||||
try { \
|
try { \
|
||||||
std::string matcherAsString = ::Catch::Matchers::matcher.toString(); \
|
std::string matcherAsString = (matcher).toString(); \
|
||||||
__catchResult \
|
__catchResult \
|
||||||
.setLhs( Catch::toString( arg ) ) \
|
.setLhs( Catch::toString( arg ) ) \
|
||||||
.setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
|
.setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
|
||||||
.setOp( "matches" ) \
|
.setOp( "matches" ) \
|
||||||
.setResultType( ::Catch::Matchers::matcher.match( arg ) ); \
|
.setResultType( (matcher).match( arg ) ); \
|
||||||
__catchResult.captureExpression(); \
|
__catchResult.captureExpression(); \
|
||||||
} catch( ... ) { \
|
} catch( ... ) { \
|
||||||
__catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
|
__catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
|
||||||
|
@@ -62,6 +62,21 @@ namespace Catch {
|
|||||||
? ShowDurations::Always
|
? ShowDurations::Always
|
||||||
: ShowDurations::Never;
|
: 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 ) {
|
inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
|
||||||
std::ifstream f( _filename.c_str() );
|
std::ifstream f( _filename.c_str() );
|
||||||
if( !f.is_open() )
|
if( !f.is_open() )
|
||||||
@@ -70,8 +85,11 @@ namespace Catch {
|
|||||||
std::string line;
|
std::string line;
|
||||||
while( std::getline( f, line ) ) {
|
while( std::getline( f, line ) ) {
|
||||||
line = trim(line);
|
line = trim(line);
|
||||||
if( !line.empty() && !startsWith( line, "#" ) )
|
if( !line.empty() && !startsWith( line, "#" ) ) {
|
||||||
addTestOrTags( config, "\"" + line + "\"," );
|
if( !startsWith( line, "\"" ) )
|
||||||
|
line = "\"" + line + "\"";
|
||||||
|
addTestOrTags( config, line + "," );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +166,7 @@ namespace Catch {
|
|||||||
|
|
||||||
cli["-d"]["--durations"]
|
cli["-d"]["--durations"]
|
||||||
.describe( "show test durations" )
|
.describe( "show test durations" )
|
||||||
.bind( &setShowDurations, "yes/no" );
|
.bind( &setShowDurations, "yes|no" );
|
||||||
|
|
||||||
cli["-f"]["--input-file"]
|
cli["-f"]["--input-file"]
|
||||||
.describe( "load test names to run from a file" )
|
.describe( "load test names to run from a file" )
|
||||||
@@ -163,7 +181,7 @@ namespace Catch {
|
|||||||
.describe( "list all/matching test cases names only" )
|
.describe( "list all/matching test cases names only" )
|
||||||
.bind( &ConfigData::listTestNamesOnly );
|
.bind( &ConfigData::listTestNamesOnly );
|
||||||
|
|
||||||
cli["--list-reporters"]
|
cli["--list-reporters"]
|
||||||
.describe( "list all reporters" )
|
.describe( "list all reporters" )
|
||||||
.bind( &ConfigData::listReporters );
|
.bind( &ConfigData::listReporters );
|
||||||
|
|
||||||
@@ -176,9 +194,13 @@ namespace Catch {
|
|||||||
.bind( &setRngSeed, "'time'|number" );
|
.bind( &setRngSeed, "'time'|number" );
|
||||||
|
|
||||||
cli["--force-colour"]
|
cli["--force-colour"]
|
||||||
.describe( "force colourised output" )
|
.describe( "force colourised output (deprecated)" )
|
||||||
.bind( &ConfigData::forceColour );
|
.bind( &forceColour );
|
||||||
|
|
||||||
|
cli["--use-colour"]
|
||||||
|
.describe( "should output be colourised" )
|
||||||
|
.bind( &setUseColour, "yes|no" );
|
||||||
|
|
||||||
return cli;
|
return cli;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -10,7 +10,11 @@
|
|||||||
|
|
||||||
#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
|
#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 )
|
#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
|
||||||
#define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
|
#ifdef CATCH_CONFIG_COUNTER
|
||||||
|
# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
|
||||||
|
#else
|
||||||
|
# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
|
||||||
|
#endif
|
||||||
|
|
||||||
#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
|
#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
|
||||||
#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
|
#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
|
||||||
@@ -22,14 +26,14 @@
|
|||||||
#include "catch_compiler_capabilities.h"
|
#include "catch_compiler_capabilities.h"
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
struct IConfig;
|
struct IConfig;
|
||||||
|
|
||||||
struct CaseSensitive { enum Choice {
|
struct CaseSensitive { enum Choice {
|
||||||
Yes,
|
Yes,
|
||||||
No
|
No
|
||||||
}; };
|
}; };
|
||||||
|
|
||||||
class NonCopyable {
|
class NonCopyable {
|
||||||
#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
|
#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
|
||||||
NonCopyable( NonCopyable const& ) = delete;
|
NonCopyable( NonCopyable const& ) = delete;
|
||||||
@@ -118,7 +122,7 @@ namespace Catch {
|
|||||||
|
|
||||||
void seedRng( IConfig const& config );
|
void seedRng( IConfig const& config );
|
||||||
unsigned int rngSeed();
|
unsigned int rngSeed();
|
||||||
|
|
||||||
// Use this in variadic streaming macros to allow
|
// Use this in variadic streaming macros to allow
|
||||||
// >> +StreamEndStop
|
// >> +StreamEndStop
|
||||||
// as well as
|
// as well as
|
||||||
|
@@ -21,8 +21,11 @@ namespace Catch {
|
|||||||
bool contains( std::string const& s, std::string const& infix ) {
|
bool contains( std::string const& s, std::string const& infix ) {
|
||||||
return s.find( infix ) != std::string::npos;
|
return s.find( infix ) != std::string::npos;
|
||||||
}
|
}
|
||||||
|
char toLowerCh(char c) {
|
||||||
|
return static_cast<char>( ::tolower( c ) );
|
||||||
|
}
|
||||||
void toLowerInPlace( std::string& s ) {
|
void toLowerInPlace( std::string& s ) {
|
||||||
std::transform( s.begin(), s.end(), s.begin(), ::tolower );
|
std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
|
||||||
}
|
}
|
||||||
std::string toLower( std::string const& s ) {
|
std::string toLower( std::string const& s ) {
|
||||||
std::string lc = s;
|
std::string lc = s;
|
||||||
@@ -36,7 +39,7 @@ namespace Catch {
|
|||||||
|
|
||||||
return start != std::string::npos ? str.substr( start, 1+end-start ) : "";
|
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 replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
|
||||||
bool replaced = false;
|
bool replaced = false;
|
||||||
std::size_t i = str.find( replaceThis );
|
std::size_t i = str.find( replaceThis );
|
||||||
@@ -50,7 +53,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
return replaced;
|
return replaced;
|
||||||
}
|
}
|
||||||
|
|
||||||
pluralise::pluralise( std::size_t count, std::string const& label )
|
pluralise::pluralise( std::size_t count, std::string const& label )
|
||||||
: m_count( count ),
|
: m_count( count ),
|
||||||
m_label( label )
|
m_label( label )
|
||||||
|
@@ -23,7 +23,7 @@
|
|||||||
// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
|
// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
|
||||||
|
|
||||||
// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
|
// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
|
||||||
|
// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
|
||||||
// ****************
|
// ****************
|
||||||
// Note to maintainers: if new toggles are added please document them
|
// Note to maintainers: if new toggles are added please document them
|
||||||
// in configuration.md, too
|
// in configuration.md, too
|
||||||
@@ -36,6 +36,18 @@
|
|||||||
|
|
||||||
// All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11
|
// 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
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
|
|
||||||
# if __has_feature(cxx_nullptr)
|
# if __has_feature(cxx_nullptr)
|
||||||
@@ -46,6 +58,10 @@
|
|||||||
# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
|
# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# if defined(CATCH_CPP11_OR_GREATER)
|
||||||
|
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
|
||||||
|
# endif
|
||||||
|
|
||||||
#endif // __clang__
|
#endif // __clang__
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -73,9 +89,13 @@
|
|||||||
// GCC
|
// GCC
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
|
||||||
#if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
|
# if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||||
# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
|
# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
|
||||||
#endif
|
# 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
|
||||||
|
|
||||||
// - otherwise more recent versions define __cplusplus >= 201103L
|
// - otherwise more recent versions define __cplusplus >= 201103L
|
||||||
// and will get picked up below
|
// and will get picked up below
|
||||||
@@ -111,13 +131,20 @@
|
|||||||
|
|
||||||
#endif
|
#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
|
// C++ language feature support
|
||||||
|
|
||||||
// catch all support for C++11
|
// catch all support for C++11
|
||||||
#if defined(__cplusplus) && __cplusplus >= 201103L
|
#if defined(CATCH_CPP11_OR_GREATER)
|
||||||
|
|
||||||
# define CATCH_CPP11_OR_GREATER
|
|
||||||
|
|
||||||
# if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)
|
# if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)
|
||||||
# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
|
# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
|
||||||
@@ -185,7 +212,13 @@
|
|||||||
#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)
|
#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
|
# define CATCH_CONFIG_CPP11_UNIQUE_PTR
|
||||||
#endif
|
#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_SUPPRESS_PARENTHESES_WARNINGS)
|
||||||
|
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
|
||||||
|
#endif
|
||||||
|
|
||||||
// noexcept support:
|
// noexcept support:
|
||||||
#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
|
#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
|
||||||
|
@@ -37,14 +37,14 @@ namespace Catch {
|
|||||||
noThrow( false ),
|
noThrow( false ),
|
||||||
showHelp( false ),
|
showHelp( false ),
|
||||||
showInvisibles( false ),
|
showInvisibles( false ),
|
||||||
forceColour( false ),
|
|
||||||
filenamesAsTags( false ),
|
filenamesAsTags( false ),
|
||||||
abortAfter( -1 ),
|
abortAfter( -1 ),
|
||||||
rngSeed( 0 ),
|
rngSeed( 0 ),
|
||||||
verbosity( Verbosity::Normal ),
|
verbosity( Verbosity::Normal ),
|
||||||
warnings( WarnAbout::Nothing ),
|
warnings( WarnAbout::Nothing ),
|
||||||
showDurations( ShowDurations::DefaultForReporter ),
|
showDurations( ShowDurations::DefaultForReporter ),
|
||||||
runOrder( RunTests::InDeclarationOrder )
|
runOrder( RunTests::InDeclarationOrder ),
|
||||||
|
useColour( UseColour::Auto )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool listTests;
|
bool listTests;
|
||||||
@@ -57,7 +57,6 @@ namespace Catch {
|
|||||||
bool noThrow;
|
bool noThrow;
|
||||||
bool showHelp;
|
bool showHelp;
|
||||||
bool showInvisibles;
|
bool showInvisibles;
|
||||||
bool forceColour;
|
|
||||||
bool filenamesAsTags;
|
bool filenamesAsTags;
|
||||||
|
|
||||||
int abortAfter;
|
int abortAfter;
|
||||||
@@ -67,6 +66,7 @@ namespace Catch {
|
|||||||
WarnAbout::What warnings;
|
WarnAbout::What warnings;
|
||||||
ShowDurations::OrNot showDurations;
|
ShowDurations::OrNot showDurations;
|
||||||
RunTests::InWhatOrder runOrder;
|
RunTests::InWhatOrder runOrder;
|
||||||
|
UseColour::YesOrNo useColour;
|
||||||
|
|
||||||
std::string outputFilename;
|
std::string outputFilename;
|
||||||
std::string name;
|
std::string name;
|
||||||
@@ -85,12 +85,11 @@ namespace Catch {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
Config()
|
Config()
|
||||||
: m_os( Catch::cout().rdbuf() )
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Config( ConfigData const& data )
|
Config( ConfigData const& data )
|
||||||
: m_data( data ),
|
: m_data( data ),
|
||||||
m_os( Catch::cout().rdbuf() )
|
m_stream( openStream() )
|
||||||
{
|
{
|
||||||
if( !data.testsOrTags.empty() ) {
|
if( !data.testsOrTags.empty() ) {
|
||||||
TestSpecParser parser( ITagAliasRegistry::get() );
|
TestSpecParser parser( ITagAliasRegistry::get() );
|
||||||
@@ -101,12 +100,6 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Config() {
|
virtual ~Config() {
|
||||||
m_os.rdbuf( Catch::cout().rdbuf() );
|
|
||||||
m_stream.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setFilename( std::string const& filename ) {
|
|
||||||
m_data.outputFilename = filename;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string const& getFilename() const {
|
std::string const& getFilename() const {
|
||||||
@@ -122,17 +115,6 @@ namespace Catch {
|
|||||||
|
|
||||||
bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
|
bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
|
||||||
|
|
||||||
void setStreamBuf( std::streambuf* buf ) {
|
|
||||||
m_os.rdbuf( buf ? buf : Catch::cout().rdbuf() );
|
|
||||||
}
|
|
||||||
|
|
||||||
void useStream( std::string const& streamName ) {
|
|
||||||
Stream stream = createStream( streamName );
|
|
||||||
setStreamBuf( stream.streamBuf );
|
|
||||||
m_stream.release();
|
|
||||||
m_stream = stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> getReporterNames() const { return m_data.reporterNames; }
|
std::vector<std::string> getReporterNames() const { return m_data.reporterNames; }
|
||||||
|
|
||||||
int abortAfter() const { return m_data.abortAfter; }
|
int abortAfter() const { return m_data.abortAfter; }
|
||||||
@@ -144,24 +126,35 @@ namespace Catch {
|
|||||||
|
|
||||||
// IConfig interface
|
// IConfig interface
|
||||||
virtual bool allowThrows() const { return !m_data.noThrow; }
|
virtual bool allowThrows() const { return !m_data.noThrow; }
|
||||||
virtual std::ostream& stream() const { return m_os; }
|
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 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 includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
|
||||||
virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
|
virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
|
||||||
virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
|
virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
|
||||||
virtual RunTests::InWhatOrder runOrder() const { return m_data.runOrder; }
|
virtual RunTests::InWhatOrder runOrder() const { return m_data.runOrder; }
|
||||||
virtual unsigned int rngSeed() const { return m_data.rngSeed; }
|
virtual unsigned int rngSeed() const { return m_data.rngSeed; }
|
||||||
virtual bool forceColour() const { return m_data.forceColour; }
|
virtual UseColour::YesOrNo useColour() const { return m_data.useColour; }
|
||||||
|
|
||||||
private:
|
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 );
|
||||||
|
}
|
||||||
ConfigData m_data;
|
ConfigData m_data;
|
||||||
|
|
||||||
Stream m_stream;
|
CATCH_AUTO_PTR( IStream const ) m_stream;
|
||||||
mutable std::ostream m_os;
|
|
||||||
TestSpec m_testSpec;
|
TestSpec m_testSpec;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
|
||||||
|
@@ -95,7 +95,18 @@ namespace {
|
|||||||
|
|
||||||
IColourImpl* platformColourInstance() {
|
IColourImpl* platformColourInstance() {
|
||||||
static Win32ColourImpl s_instance;
|
static Win32ColourImpl s_instance;
|
||||||
return &s_instance;
|
|
||||||
|
Ptr<IConfig const> config = getCurrentContext().getConfig();
|
||||||
|
UseColour::YesOrNo colourMode = config
|
||||||
|
? config->useColour()
|
||||||
|
: UseColour::Auto;
|
||||||
|
if( colourMode == UseColour::Auto )
|
||||||
|
colourMode = !isDebuggerActive()
|
||||||
|
? UseColour::Yes
|
||||||
|
: UseColour::No;
|
||||||
|
return colourMode == UseColour::Yes
|
||||||
|
? &s_instance
|
||||||
|
: NoColourImpl::instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end anon namespace
|
} // end anon namespace
|
||||||
@@ -146,7 +157,14 @@ namespace {
|
|||||||
|
|
||||||
IColourImpl* platformColourInstance() {
|
IColourImpl* platformColourInstance() {
|
||||||
Ptr<IConfig const> config = getCurrentContext().getConfig();
|
Ptr<IConfig const> config = getCurrentContext().getConfig();
|
||||||
return (config && config->forceColour()) || isatty(STDOUT_FILENO)
|
UseColour::YesOrNo colourMode = config
|
||||||
|
? config->useColour()
|
||||||
|
: UseColour::Auto;
|
||||||
|
if( colourMode == UseColour::Auto )
|
||||||
|
colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) )
|
||||||
|
? UseColour::Yes
|
||||||
|
: UseColour::No;
|
||||||
|
return colourMode == UseColour::Yes
|
||||||
? PosixColourImpl::instance()
|
? PosixColourImpl::instance()
|
||||||
: NoColourImpl::instance();
|
: NoColourImpl::instance();
|
||||||
}
|
}
|
||||||
@@ -171,9 +189,7 @@ namespace Catch {
|
|||||||
Colour::~Colour(){ if( !m_moved ) use( None ); }
|
Colour::~Colour(){ if( !m_moved ) use( None ); }
|
||||||
|
|
||||||
void Colour::use( Code _colourCode ) {
|
void Colour::use( Code _colourCode ) {
|
||||||
static IColourImpl* impl = isDebuggerActive()
|
static IColourImpl* impl = platformColourInstance();
|
||||||
? NoColourImpl::instance()
|
|
||||||
: platformColourInstance();
|
|
||||||
impl->use( _colourCode );
|
impl->use( _colourCode );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -95,14 +95,6 @@ namespace Catch {
|
|||||||
return getCurrentMutableContext();
|
return getCurrentMutableContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream createStream( std::string const& streamName ) {
|
|
||||||
if( streamName == "stdout" ) return Stream( Catch::cout().rdbuf(), false );
|
|
||||||
if( streamName == "stderr" ) return Stream( Catch::cerr().rdbuf(), false );
|
|
||||||
if( streamName == "debug" ) return Stream( new StreamBufImpl<OutputDebugWriter>, true );
|
|
||||||
|
|
||||||
throw std::domain_error( "Unknown stream: " + streamName );
|
|
||||||
}
|
|
||||||
|
|
||||||
void cleanUpContext() {
|
void cleanUpContext() {
|
||||||
delete currentContext;
|
delete currentContext;
|
||||||
currentContext = CATCH_NULL;
|
currentContext = CATCH_NULL;
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
#ifndef __OBJC__
|
#ifndef __OBJC__
|
||||||
|
|
||||||
// Standard C/C++ main entry point
|
// Standard C/C++ main entry point
|
||||||
int main (int argc, char * const argv[]) {
|
int main (int argc, char * argv[]) {
|
||||||
return Catch::Session().run( argc, argv );
|
return Catch::Session().run( argc, argv );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -52,37 +52,37 @@ namespace Internal {
|
|||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct Evaluator<T1, T2, IsEqualTo> {
|
struct Evaluator<T1, T2, IsEqualTo> {
|
||||||
static bool evaluate( T1 const& lhs, T2 const& rhs) {
|
static bool evaluate( T1 const& lhs, T2 const& rhs) {
|
||||||
return opCast( lhs ) == opCast( rhs );
|
return bool( opCast( lhs ) == opCast( rhs ) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct Evaluator<T1, T2, IsNotEqualTo> {
|
struct Evaluator<T1, T2, IsNotEqualTo> {
|
||||||
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
||||||
return opCast( lhs ) != opCast( rhs );
|
return bool( opCast( lhs ) != opCast( rhs ) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct Evaluator<T1, T2, IsLessThan> {
|
struct Evaluator<T1, T2, IsLessThan> {
|
||||||
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
||||||
return opCast( lhs ) < opCast( rhs );
|
return bool( opCast( lhs ) < opCast( rhs ) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct Evaluator<T1, T2, IsGreaterThan> {
|
struct Evaluator<T1, T2, IsGreaterThan> {
|
||||||
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
||||||
return opCast( lhs ) > opCast( rhs );
|
return bool( opCast( lhs ) > opCast( rhs ) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
|
struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
|
||||||
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
||||||
return opCast( lhs ) >= opCast( rhs );
|
return bool( opCast( lhs ) >= opCast( rhs ) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
|
struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
|
||||||
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
||||||
return opCast( lhs ) <= opCast( rhs );
|
return bool( opCast( lhs ) <= opCast( rhs ) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -174,7 +174,7 @@ namespace Internal {
|
|||||||
template<Operator Op> bool compare( long long lhs, unsigned char rhs ) {
|
template<Operator Op> bool compare( long long lhs, unsigned char rhs ) {
|
||||||
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
|
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
|
||||||
}
|
}
|
||||||
|
|
||||||
// unsigned long long to X
|
// unsigned long long to X
|
||||||
template<Operator Op> bool compare( unsigned long long lhs, int rhs ) {
|
template<Operator Op> bool compare( unsigned long long lhs, int rhs ) {
|
||||||
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
|
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
|
||||||
@@ -188,7 +188,7 @@ namespace Internal {
|
|||||||
template<Operator Op> bool compare( unsigned long long lhs, char rhs ) {
|
template<Operator Op> bool compare( unsigned long long lhs, char rhs ) {
|
||||||
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
|
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
|
||||||
}
|
}
|
||||||
|
|
||||||
// pointer to long long (when comparing against NULL)
|
// pointer to long long (when comparing against NULL)
|
||||||
template<Operator Op, typename T> bool compare( long long lhs, T* rhs ) {
|
template<Operator Op, typename T> bool compare( long long lhs, T* rhs ) {
|
||||||
return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
|
return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
|
||||||
@@ -197,7 +197,7 @@ namespace Internal {
|
|||||||
return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
|
return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
|
||||||
}
|
}
|
||||||
#endif // CATCH_CONFIG_CPP11_LONG_LONG
|
#endif // CATCH_CONFIG_CPP11_LONG_LONG
|
||||||
|
|
||||||
#ifdef CATCH_CONFIG_CPP11_NULLPTR
|
#ifdef CATCH_CONFIG_CPP11_NULLPTR
|
||||||
// pointer to nullptr_t (when comparing against nullptr)
|
// pointer to nullptr_t (when comparing against nullptr)
|
||||||
template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
|
template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
|
||||||
|
@@ -32,13 +32,13 @@ namespace Catch {
|
|||||||
#ifdef __OBJC__
|
#ifdef __OBJC__
|
||||||
// In Objective-C try objective-c exceptions first
|
// In Objective-C try objective-c exceptions first
|
||||||
@try {
|
@try {
|
||||||
throw;
|
return tryTranslators();
|
||||||
}
|
}
|
||||||
@catch (NSException *exception) {
|
@catch (NSException *exception) {
|
||||||
return Catch::toString( [exception description] );
|
return Catch::toString( [exception description] );
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
throw;
|
return tryTranslators();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
catch( TestFailureException& ) {
|
catch( TestFailureException& ) {
|
||||||
@@ -54,20 +54,15 @@ namespace Catch {
|
|||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
catch(...) {
|
catch(...) {
|
||||||
return tryTranslators( m_translators.begin() );
|
return "Unknown exception";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tryTranslators( std::vector<const IExceptionTranslator*>::const_iterator it ) const {
|
std::string tryTranslators() const {
|
||||||
if( it == m_translators.end() )
|
if( m_translators.empty() )
|
||||||
return "Unknown exception";
|
throw;
|
||||||
|
else
|
||||||
try {
|
return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
|
||||||
return (*it)->translate();
|
|
||||||
}
|
|
||||||
catch(...) {
|
|
||||||
return tryTranslators( it+1 );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
#include "catch_tostring.hpp"
|
#include "catch_tostring.hpp"
|
||||||
#include "catch_result_builder.hpp"
|
#include "catch_result_builder.hpp"
|
||||||
#include "catch_tag_alias_registry.hpp"
|
#include "catch_tag_alias_registry.hpp"
|
||||||
|
#include "catch_test_case_tracker.hpp"
|
||||||
|
|
||||||
#include "../reporters/catch_reporter_multi.hpp"
|
#include "../reporters/catch_reporter_multi.hpp"
|
||||||
#include "../reporters/catch_reporter_xml.hpp"
|
#include "../reporters/catch_reporter_xml.hpp"
|
||||||
@@ -43,8 +44,14 @@
|
|||||||
#include "../reporters/catch_reporter_compact.hpp"
|
#include "../reporters/catch_reporter_compact.hpp"
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
// These are all here to avoid warnings about not having any out of line
|
||||||
|
// virtual methods
|
||||||
NonCopyable::~NonCopyable() {}
|
NonCopyable::~NonCopyable() {}
|
||||||
IShared::~IShared() {}
|
IShared::~IShared() {}
|
||||||
|
IStream::~IStream() CATCH_NOEXCEPT {}
|
||||||
|
FileStream::~FileStream() CATCH_NOEXCEPT {}
|
||||||
|
CoutStream::~CoutStream() CATCH_NOEXCEPT {}
|
||||||
|
DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {}
|
||||||
StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
|
StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
|
||||||
IContext::~IContext() {}
|
IContext::~IContext() {}
|
||||||
IResultCapture::~IResultCapture() {}
|
IResultCapture::~IResultCapture() {}
|
||||||
@@ -90,6 +97,13 @@ namespace Catch {
|
|||||||
Matchers::Impl::StdString::EndsWith::~EndsWith() {}
|
Matchers::Impl::StdString::EndsWith::~EndsWith() {}
|
||||||
|
|
||||||
void Config::dummy() {}
|
void Config::dummy() {}
|
||||||
|
|
||||||
|
namespace TestCaseTracking {
|
||||||
|
ITracker::~ITracker() {}
|
||||||
|
TrackerBase::~TrackerBase() {}
|
||||||
|
SectionTracker::~SectionTracker() {}
|
||||||
|
IndexTracker::~IndexTracker() {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
|
@@ -37,6 +37,11 @@ namespace Catch {
|
|||||||
InLexicographicalOrder,
|
InLexicographicalOrder,
|
||||||
InRandomOrder
|
InRandomOrder
|
||||||
}; };
|
}; };
|
||||||
|
struct UseColour { enum YesOrNo {
|
||||||
|
Auto,
|
||||||
|
Yes,
|
||||||
|
No
|
||||||
|
}; };
|
||||||
|
|
||||||
class TestSpec;
|
class TestSpec;
|
||||||
|
|
||||||
@@ -56,7 +61,7 @@ namespace Catch {
|
|||||||
virtual TestSpec const& testSpec() const = 0;
|
virtual TestSpec const& testSpec() const = 0;
|
||||||
virtual RunTests::InWhatOrder runOrder() const = 0;
|
virtual RunTests::InWhatOrder runOrder() const = 0;
|
||||||
virtual unsigned int rngSeed() const = 0;
|
virtual unsigned int rngSeed() const = 0;
|
||||||
virtual bool forceColour() const = 0;
|
virtual UseColour::YesOrNo useColour() const = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -9,15 +9,20 @@
|
|||||||
#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
|
#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "catch_interfaces_registry_hub.h"
|
#include "catch_interfaces_registry_hub.h"
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
typedef std::string(*exceptionTranslateFunction)();
|
typedef std::string(*exceptionTranslateFunction)();
|
||||||
|
|
||||||
|
struct IExceptionTranslator;
|
||||||
|
typedef std::vector<const IExceptionTranslator*> ExceptionTranslators;
|
||||||
|
|
||||||
struct IExceptionTranslator {
|
struct IExceptionTranslator {
|
||||||
virtual ~IExceptionTranslator();
|
virtual ~IExceptionTranslator();
|
||||||
virtual std::string translate() const = 0;
|
virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IExceptionTranslatorRegistry {
|
struct IExceptionTranslatorRegistry {
|
||||||
@@ -35,9 +40,12 @@ namespace Catch {
|
|||||||
: m_translateFunction( translateFunction )
|
: m_translateFunction( translateFunction )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual std::string translate() const {
|
virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE {
|
||||||
try {
|
try {
|
||||||
throw;
|
if( it == itEnd )
|
||||||
|
throw;
|
||||||
|
else
|
||||||
|
return (*it)->translate( it+1, itEnd );
|
||||||
}
|
}
|
||||||
catch( T& ex ) {
|
catch( T& ex ) {
|
||||||
return m_translateFunction( ex );
|
return m_translateFunction( ex );
|
||||||
@@ -58,9 +66,11 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) \
|
#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
|
||||||
static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ); \
|
static std::string translatorName( signature ); \
|
||||||
namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ) ); }\
|
namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\
|
||||||
static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature )
|
static std::string translatorName( signature )
|
||||||
|
|
||||||
|
#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
|
||||||
|
@@ -26,18 +26,18 @@
|
|||||||
namespace Catch
|
namespace Catch
|
||||||
{
|
{
|
||||||
struct ReporterConfig {
|
struct ReporterConfig {
|
||||||
explicit ReporterConfig( Ptr<IConfig> const& _fullConfig )
|
explicit ReporterConfig( Ptr<IConfig const> const& _fullConfig )
|
||||||
: m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
|
: m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
|
||||||
|
|
||||||
ReporterConfig( Ptr<IConfig> const& _fullConfig, std::ostream& _stream )
|
ReporterConfig( Ptr<IConfig const> const& _fullConfig, std::ostream& _stream )
|
||||||
: m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
|
: m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
|
||||||
|
|
||||||
std::ostream& stream() const { return *m_stream; }
|
std::ostream& stream() const { return *m_stream; }
|
||||||
Ptr<IConfig> fullConfig() const { return m_fullConfig; }
|
Ptr<IConfig const> fullConfig() const { return m_fullConfig; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::ostream* m_stream;
|
std::ostream* m_stream;
|
||||||
Ptr<IConfig> m_fullConfig;
|
Ptr<IConfig const> m_fullConfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ReporterPreferences {
|
struct ReporterPreferences {
|
||||||
@@ -219,6 +219,7 @@ namespace Catch
|
|||||||
bool aborting;
|
bool aborting;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MultipleReporters;
|
||||||
|
|
||||||
struct IStreamingReporter : IShared {
|
struct IStreamingReporter : IShared {
|
||||||
virtual ~IStreamingReporter();
|
virtual ~IStreamingReporter();
|
||||||
@@ -240,13 +241,15 @@ namespace Catch
|
|||||||
|
|
||||||
// The return value indicates if the messages buffer should be cleared:
|
// The return value indicates if the messages buffer should be cleared:
|
||||||
virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
|
virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
|
||||||
|
|
||||||
virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
|
virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
|
||||||
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
|
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
|
||||||
virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
|
virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
|
||||||
virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
|
virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
|
||||||
|
|
||||||
virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
|
virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
|
||||||
|
|
||||||
|
virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -261,13 +264,13 @@ namespace Catch
|
|||||||
typedef std::vector<Ptr<IReporterFactory> > Listeners;
|
typedef std::vector<Ptr<IReporterFactory> > Listeners;
|
||||||
|
|
||||||
virtual ~IReporterRegistry();
|
virtual ~IReporterRegistry();
|
||||||
virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const = 0;
|
virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const = 0;
|
||||||
virtual FactoryMap const& getFactories() const = 0;
|
virtual FactoryMap const& getFactories() const = 0;
|
||||||
virtual Listeners const& getListeners() const = 0;
|
virtual Listeners const& getListeners() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter );
|
Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
|
||||||
|
@@ -34,7 +34,7 @@ namespace Catch {
|
|||||||
bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
|
bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
|
||||||
std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
|
std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
|
||||||
std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
|
std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
|
||||||
|
@@ -68,7 +68,10 @@ namespace Catch {
|
|||||||
++it ) {
|
++it ) {
|
||||||
matchedTests++;
|
matchedTests++;
|
||||||
TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
|
TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
|
||||||
Catch::cout() << testCaseInfo.name << std::endl;
|
if( startsWith( testCaseInfo.name, "#" ) )
|
||||||
|
Catch::cout() << "\"" << testCaseInfo.name << "\"" << std::endl;
|
||||||
|
else
|
||||||
|
Catch::cout() << testCaseInfo.name << std::endl;
|
||||||
}
|
}
|
||||||
return matchedTests;
|
return matchedTests;
|
||||||
}
|
}
|
||||||
|
@@ -12,6 +12,12 @@ namespace Catch {
|
|||||||
namespace Matchers {
|
namespace Matchers {
|
||||||
namespace Impl {
|
namespace Impl {
|
||||||
|
|
||||||
|
namespace Generic {
|
||||||
|
template<typename ExpressionT> class AllOf;
|
||||||
|
template<typename ExpressionT> class AnyOf;
|
||||||
|
template<typename ExpressionT> class Not;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ExpressionT>
|
template<typename ExpressionT>
|
||||||
struct Matcher : SharedImpl<IShared>
|
struct Matcher : SharedImpl<IShared>
|
||||||
{
|
{
|
||||||
@@ -21,6 +27,10 @@ namespace Matchers {
|
|||||||
virtual Ptr<Matcher> clone() const = 0;
|
virtual Ptr<Matcher> clone() const = 0;
|
||||||
virtual bool match( ExpressionT const& expr ) const = 0;
|
virtual bool match( ExpressionT const& expr ) const = 0;
|
||||||
virtual std::string toString() const = 0;
|
virtual std::string toString() const = 0;
|
||||||
|
|
||||||
|
Generic::AllOf<ExpressionT> operator && ( Matcher<ExpressionT> const& other ) const;
|
||||||
|
Generic::AnyOf<ExpressionT> operator || ( Matcher<ExpressionT> const& other ) const;
|
||||||
|
Generic::Not<ExpressionT> operator ! () const;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename DerivedT, typename ExpressionT>
|
template<typename DerivedT, typename ExpressionT>
|
||||||
@@ -33,8 +43,9 @@ namespace Matchers {
|
|||||||
|
|
||||||
namespace Generic {
|
namespace Generic {
|
||||||
template<typename ExpressionT>
|
template<typename ExpressionT>
|
||||||
struct Not : public MatcherImpl<Not<ExpressionT>, ExpressionT> {
|
class Not : public MatcherImpl<Not<ExpressionT>, ExpressionT> {
|
||||||
Not( Matcher<ExpressionT> const& matcher ) : m_matcher(matcher.clone()) {}
|
public:
|
||||||
|
explicit Not( Matcher<ExpressionT> const& matcher ) : m_matcher(matcher.clone()) {}
|
||||||
Not( Not const& other ) : m_matcher( other.m_matcher ) {}
|
Not( Not const& other ) : m_matcher( other.m_matcher ) {}
|
||||||
|
|
||||||
virtual bool match( ExpressionT const& expr ) const CATCH_OVERRIDE {
|
virtual bool match( ExpressionT const& expr ) const CATCH_OVERRIDE {
|
||||||
@@ -44,7 +55,7 @@ namespace Matchers {
|
|||||||
virtual std::string toString() const CATCH_OVERRIDE {
|
virtual std::string toString() const CATCH_OVERRIDE {
|
||||||
return "not " + m_matcher->toString();
|
return "not " + m_matcher->toString();
|
||||||
}
|
}
|
||||||
|
private:
|
||||||
Ptr< Matcher<ExpressionT> > m_matcher;
|
Ptr< Matcher<ExpressionT> > m_matcher;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -78,6 +89,12 @@ namespace Matchers {
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AllOf operator && ( Matcher<ExpressionT> const& other ) const {
|
||||||
|
AllOf allOfExpr( *this );
|
||||||
|
allOfExpr.add( other );
|
||||||
|
return allOfExpr;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
|
std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
|
||||||
};
|
};
|
||||||
@@ -112,11 +129,40 @@ namespace Matchers {
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AnyOf operator || ( Matcher<ExpressionT> const& other ) const {
|
||||||
|
AnyOf anyOfExpr( *this );
|
||||||
|
anyOfExpr.add( other );
|
||||||
|
return anyOfExpr;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
|
std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace Generic
|
||||||
|
|
||||||
|
template<typename ExpressionT>
|
||||||
|
Generic::AllOf<ExpressionT> Matcher<ExpressionT>::operator && ( Matcher<ExpressionT> const& other ) const {
|
||||||
|
Generic::AllOf<ExpressionT> allOfExpr;
|
||||||
|
allOfExpr.add( *this );
|
||||||
|
allOfExpr.add( other );
|
||||||
|
return allOfExpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename ExpressionT>
|
||||||
|
Generic::AnyOf<ExpressionT> Matcher<ExpressionT>::operator || ( Matcher<ExpressionT> const& other ) const {
|
||||||
|
Generic::AnyOf<ExpressionT> anyOfExpr;
|
||||||
|
anyOfExpr.add( *this );
|
||||||
|
anyOfExpr.add( other );
|
||||||
|
return anyOfExpr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ExpressionT>
|
||||||
|
Generic::Not<ExpressionT> Matcher<ExpressionT>::operator ! () const {
|
||||||
|
return Generic::Not<ExpressionT>( *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace StdString {
|
namespace StdString {
|
||||||
|
|
||||||
inline std::string makeString( std::string const& str ) { return str; }
|
inline std::string makeString( std::string const& str ) { return str; }
|
||||||
@@ -132,7 +178,7 @@ namespace Matchers {
|
|||||||
return m_caseSensitivity == CaseSensitive::No
|
return m_caseSensitivity == CaseSensitive::No
|
||||||
? toLower( str )
|
? toLower( str )
|
||||||
: str;
|
: str;
|
||||||
|
|
||||||
}
|
}
|
||||||
std::string toStringSuffix() const
|
std::string toStringSuffix() const
|
||||||
{
|
{
|
||||||
@@ -143,7 +189,7 @@ namespace Matchers {
|
|||||||
CaseSensitive::Choice m_caseSensitivity;
|
CaseSensitive::Choice m_caseSensitivity;
|
||||||
std::string m_str;
|
std::string m_str;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Equals : MatcherImpl<Equals, std::string> {
|
struct Equals : MatcherImpl<Equals, std::string> {
|
||||||
Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
|
Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
|
||||||
: m_data( str, caseSensitivity )
|
: m_data( str, caseSensitivity )
|
||||||
@@ -182,13 +228,13 @@ namespace Matchers {
|
|||||||
struct StartsWith : MatcherImpl<StartsWith, std::string> {
|
struct StartsWith : MatcherImpl<StartsWith, std::string> {
|
||||||
StartsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
|
StartsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
|
||||||
: m_data( substr, caseSensitivity ){}
|
: m_data( substr, caseSensitivity ){}
|
||||||
|
|
||||||
StartsWith( StartsWith const& other ) : m_data( other.m_data ){}
|
StartsWith( StartsWith const& other ) : m_data( other.m_data ){}
|
||||||
|
|
||||||
virtual ~StartsWith();
|
virtual ~StartsWith();
|
||||||
|
|
||||||
virtual bool match( std::string const& expr ) const {
|
virtual bool match( std::string const& expr ) const {
|
||||||
return m_data.adjustString( expr ).find( m_data.m_str ) == 0;
|
return startsWith( m_data.adjustString( expr ), m_data.m_str );
|
||||||
}
|
}
|
||||||
virtual std::string toString() const {
|
virtual std::string toString() const {
|
||||||
return "starts with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
|
return "starts with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
|
||||||
@@ -205,7 +251,7 @@ namespace Matchers {
|
|||||||
virtual ~EndsWith();
|
virtual ~EndsWith();
|
||||||
|
|
||||||
virtual bool match( std::string const& expr ) const {
|
virtual bool match( std::string const& expr ) const {
|
||||||
return m_data.adjustString( expr ).find( m_data.m_str ) == expr.size() - m_data.m_str.size();
|
return endsWith( m_data.adjustString( expr ), m_data.m_str );
|
||||||
}
|
}
|
||||||
virtual std::string toString() const {
|
virtual std::string toString() const {
|
||||||
return "ends with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
|
return "ends with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
|
||||||
|
@@ -64,12 +64,12 @@ namespace Catch {
|
|||||||
getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
|
getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class ListenerRegistrar {
|
class ListenerRegistrar {
|
||||||
|
|
||||||
class ListenerFactory : public SharedImpl<IReporterFactory> {
|
class ListenerFactory : public SharedImpl<IReporterFactory> {
|
||||||
|
|
||||||
virtual IStreamingReporter* create( ReporterConfig const& config ) const {
|
virtual IStreamingReporter* create( ReporterConfig const& config ) const {
|
||||||
return new T( config );
|
return new T( config );
|
||||||
}
|
}
|
||||||
@@ -77,9 +77,9 @@ namespace Catch {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ListenerRegistrar() {
|
ListenerRegistrar() {
|
||||||
getMutableRegistryHub().registerListener( new ListenerFactory() );
|
getMutableRegistryHub().registerListener( new ListenerFactory() );
|
||||||
}
|
}
|
||||||
|
@@ -20,7 +20,7 @@ namespace Catch {
|
|||||||
|
|
||||||
virtual ~ReporterRegistry() CATCH_OVERRIDE {}
|
virtual ~ReporterRegistry() CATCH_OVERRIDE {}
|
||||||
|
|
||||||
virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const CATCH_OVERRIDE {
|
virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const CATCH_OVERRIDE {
|
||||||
FactoryMap::const_iterator it = m_factories.find( name );
|
FactoryMap::const_iterator it = m_factories.find( name );
|
||||||
if( it == m_factories.end() )
|
if( it == m_factories.end() )
|
||||||
return CATCH_NULL;
|
return CATCH_NULL;
|
||||||
|
@@ -85,7 +85,7 @@ namespace Catch {
|
|||||||
std::string lhs, rhs, op;
|
std::string lhs, rhs, op;
|
||||||
} m_exprComponents;
|
} m_exprComponents;
|
||||||
CopyableStream m_stream;
|
CopyableStream m_stream;
|
||||||
|
|
||||||
bool m_shouldDebugBreak;
|
bool m_shouldDebugBreak;
|
||||||
bool m_shouldThrow;
|
bool m_shouldThrow;
|
||||||
};
|
};
|
||||||
|
@@ -77,12 +77,12 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ResultBuilder::captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher ) {
|
void ResultBuilder::captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher ) {
|
||||||
|
|
||||||
assert( m_exprComponents.testFalse == false );
|
assert( m_exprComponents.testFalse == false );
|
||||||
AssertionResultData data = m_data;
|
AssertionResultData data = m_data;
|
||||||
data.resultType = ResultWas::Ok;
|
data.resultType = ResultWas::Ok;
|
||||||
data.reconstructedExpression = m_assertionInfo.capturedExpression;
|
data.reconstructedExpression = m_assertionInfo.capturedExpression;
|
||||||
|
|
||||||
std::string actualMessage = Catch::translateActiveException();
|
std::string actualMessage = Catch::translateActiveException();
|
||||||
if( !matcher.match( actualMessage ) ) {
|
if( !matcher.match( actualMessage ) ) {
|
||||||
data.resultType = ResultWas::ExpressionFailed;
|
data.resultType = ResultWas::ExpressionFailed;
|
||||||
@@ -99,7 +99,7 @@ namespace Catch {
|
|||||||
void ResultBuilder::handleResult( AssertionResult const& result )
|
void ResultBuilder::handleResult( AssertionResult const& result )
|
||||||
{
|
{
|
||||||
getResultCapture().assertionEnded( result );
|
getResultCapture().assertionEnded( result );
|
||||||
|
|
||||||
if( !result.isOk() ) {
|
if( !result.isOk() ) {
|
||||||
if( getCurrentContext().getConfig()->shouldDebugBreak() )
|
if( getCurrentContext().getConfig()->shouldDebugBreak() )
|
||||||
m_shouldDebugBreak = true;
|
m_shouldDebugBreak = true;
|
||||||
|
@@ -55,7 +55,7 @@ namespace Catch {
|
|||||||
inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
|
inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
|
||||||
inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
|
inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
|
||||||
inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
|
inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
|
||||||
|
@@ -64,10 +64,7 @@ namespace Catch {
|
|||||||
m_context( getCurrentMutableContext() ),
|
m_context( getCurrentMutableContext() ),
|
||||||
m_activeTestCase( CATCH_NULL ),
|
m_activeTestCase( CATCH_NULL ),
|
||||||
m_config( _config ),
|
m_config( _config ),
|
||||||
m_reporter( reporter ),
|
m_reporter( reporter )
|
||||||
m_prevRunner( m_context.getRunner() ),
|
|
||||||
m_prevResultCapture( m_context.getResultCapture() ),
|
|
||||||
m_prevConfig( m_context.getConfig() )
|
|
||||||
{
|
{
|
||||||
m_context.setRunner( this );
|
m_context.setRunner( this );
|
||||||
m_context.setConfig( m_config );
|
m_context.setConfig( m_config );
|
||||||
@@ -77,10 +74,6 @@ namespace Catch {
|
|||||||
|
|
||||||
virtual ~RunContext() {
|
virtual ~RunContext() {
|
||||||
m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
|
m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
|
||||||
m_context.setRunner( m_prevRunner );
|
|
||||||
m_context.setConfig( Ptr<IConfig const>() );
|
|
||||||
m_context.setResultCapture( m_prevResultCapture );
|
|
||||||
m_context.setConfig( m_prevConfig );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
|
void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
|
||||||
@@ -101,17 +94,26 @@ namespace Catch {
|
|||||||
m_reporter->testCaseStarting( testInfo );
|
m_reporter->testCaseStarting( testInfo );
|
||||||
|
|
||||||
m_activeTestCase = &testCase;
|
m_activeTestCase = &testCase;
|
||||||
m_testCaseTracker = TestCaseTracker( testInfo.name );
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
m_trackerContext.startRun();
|
||||||
do {
|
do {
|
||||||
|
m_trackerContext.startCycle();
|
||||||
|
m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, testInfo.name );
|
||||||
runCurrentTest( redirectedCout, redirectedCerr );
|
runCurrentTest( redirectedCout, redirectedCerr );
|
||||||
}
|
}
|
||||||
while( !m_testCaseTracker->isCompleted() && !aborting() );
|
while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() );
|
||||||
}
|
}
|
||||||
|
// !TBD: deprecated - this will be replaced by indexed trackers
|
||||||
while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
|
while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
|
||||||
|
|
||||||
Totals deltaTotals = m_totals.delta( prevTotals );
|
Totals deltaTotals = m_totals.delta( prevTotals );
|
||||||
|
if( testInfo.expectedToFail() && deltaTotals.testCases.passed > 0 ) {
|
||||||
|
deltaTotals.assertions.failed++;
|
||||||
|
deltaTotals.testCases.passed--;
|
||||||
|
deltaTotals.testCases.failed++;
|
||||||
|
}
|
||||||
m_totals.testCases += deltaTotals.testCases;
|
m_totals.testCases += deltaTotals.testCases;
|
||||||
m_reporter->testCaseEnded( TestCaseStats( testInfo,
|
m_reporter->testCaseEnded( TestCaseStats( testInfo,
|
||||||
deltaTotals,
|
deltaTotals,
|
||||||
@@ -120,7 +122,7 @@ namespace Catch {
|
|||||||
aborting() ) );
|
aborting() ) );
|
||||||
|
|
||||||
m_activeTestCase = CATCH_NULL;
|
m_activeTestCase = CATCH_NULL;
|
||||||
m_testCaseTracker.reset();
|
m_testCaseTracker = CATCH_NULL;
|
||||||
|
|
||||||
return deltaTotals;
|
return deltaTotals;
|
||||||
}
|
}
|
||||||
@@ -156,8 +158,10 @@ namespace Catch {
|
|||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << sectionInfo.name << "@" << sectionInfo.lineInfo;
|
oss << sectionInfo.name << "@" << sectionInfo.lineInfo;
|
||||||
|
|
||||||
if( !m_testCaseTracker->enterSection( oss.str() ) )
|
ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, oss.str() );
|
||||||
|
if( !sectionTracker.isOpen() )
|
||||||
return false;
|
return false;
|
||||||
|
m_activeSections.push_back( §ionTracker );
|
||||||
|
|
||||||
m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
|
m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
|
||||||
|
|
||||||
@@ -168,29 +172,40 @@ namespace Catch {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool testForMissingAssertions( Counts& assertions ) {
|
bool testForMissingAssertions( Counts& assertions ) {
|
||||||
if( assertions.total() != 0 ||
|
if( assertions.total() != 0 )
|
||||||
!m_config->warnAboutMissingAssertions() ||
|
return false;
|
||||||
m_testCaseTracker->currentSectionHasChildren() )
|
if( !m_config->warnAboutMissingAssertions() )
|
||||||
|
return false;
|
||||||
|
if( m_trackerContext.currentTracker().hasChildren() )
|
||||||
return false;
|
return false;
|
||||||
m_totals.assertions.failed++;
|
m_totals.assertions.failed++;
|
||||||
assertions.failed++;
|
assertions.failed++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void sectionEnded( SectionEndInfo const& endInfo ) {
|
virtual void sectionEnded( SectionEndInfo const& endInfo ) {
|
||||||
Counts assertions = m_totals.assertions - endInfo.prevAssertions;
|
Counts assertions = m_totals.assertions - endInfo.prevAssertions;
|
||||||
bool missingAssertions = testForMissingAssertions( assertions );
|
bool missingAssertions = testForMissingAssertions( assertions );
|
||||||
|
|
||||||
m_testCaseTracker->leaveSection();
|
if( !m_activeSections.empty() ) {
|
||||||
|
m_activeSections.back()->close();
|
||||||
|
m_activeSections.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) );
|
m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) );
|
||||||
m_messages.clear();
|
m_messages.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) {
|
virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) {
|
||||||
|
if( m_unfinishedSections.empty() )
|
||||||
|
m_activeSections.back()->fail();
|
||||||
|
else
|
||||||
|
m_activeSections.back()->close();
|
||||||
|
m_activeSections.pop_back();
|
||||||
|
|
||||||
m_unfinishedSections.push_back( endInfo );
|
m_unfinishedSections.push_back( endInfo );
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void pushScopedMessage( MessageInfo const& message ) {
|
virtual void pushScopedMessage( MessageInfo const& message ) {
|
||||||
m_messages.push_back( message );
|
m_messages.push_back( message );
|
||||||
}
|
}
|
||||||
@@ -256,10 +271,9 @@ namespace Catch {
|
|||||||
double duration = 0;
|
double duration = 0;
|
||||||
try {
|
try {
|
||||||
m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
|
m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
|
||||||
TestCaseTracker::Guard guard( *m_testCaseTracker );
|
|
||||||
|
|
||||||
seedRng( *m_config );
|
seedRng( *m_config );
|
||||||
|
|
||||||
Timer timer;
|
Timer timer;
|
||||||
timer.start();
|
timer.start();
|
||||||
if( m_reporter->getPreferences().shouldRedirectStdOut ) {
|
if( m_reporter->getPreferences().shouldRedirectStdOut ) {
|
||||||
@@ -278,6 +292,7 @@ namespace Catch {
|
|||||||
catch(...) {
|
catch(...) {
|
||||||
makeUnexpectedResultBuilder().useActiveException();
|
makeUnexpectedResultBuilder().useActiveException();
|
||||||
}
|
}
|
||||||
|
m_testCaseTracker->close();
|
||||||
handleUnfinishedSections();
|
handleUnfinishedSections();
|
||||||
m_messages.clear();
|
m_messages.clear();
|
||||||
|
|
||||||
@@ -308,7 +323,7 @@ namespace Catch {
|
|||||||
m_lastAssertionInfo.capturedExpression.c_str(),
|
m_lastAssertionInfo.capturedExpression.c_str(),
|
||||||
m_lastAssertionInfo.resultDisposition );
|
m_lastAssertionInfo.resultDisposition );
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleUnfinishedSections() {
|
void handleUnfinishedSections() {
|
||||||
// If sections ended prematurely due to an exception we stored their
|
// If sections ended prematurely due to an exception we stored their
|
||||||
// infos here so we can tear them down outside the unwind process.
|
// infos here so we can tear them down outside the unwind process.
|
||||||
@@ -323,18 +338,18 @@ namespace Catch {
|
|||||||
TestRunInfo m_runInfo;
|
TestRunInfo m_runInfo;
|
||||||
IMutableContext& m_context;
|
IMutableContext& m_context;
|
||||||
TestCase const* m_activeTestCase;
|
TestCase const* m_activeTestCase;
|
||||||
Option<TestCaseTracker> m_testCaseTracker;
|
ITracker* m_testCaseTracker;
|
||||||
|
ITracker* m_currentSectionTracker;
|
||||||
AssertionResult m_lastResult;
|
AssertionResult m_lastResult;
|
||||||
|
|
||||||
Ptr<IConfig const> m_config;
|
Ptr<IConfig const> m_config;
|
||||||
Totals m_totals;
|
Totals m_totals;
|
||||||
Ptr<IStreamingReporter> m_reporter;
|
Ptr<IStreamingReporter> m_reporter;
|
||||||
std::vector<MessageInfo> m_messages;
|
std::vector<MessageInfo> m_messages;
|
||||||
IRunner* m_prevRunner;
|
|
||||||
IResultCapture* m_prevResultCapture;
|
|
||||||
Ptr<IConfig const> m_prevConfig;
|
|
||||||
AssertionInfo m_lastAssertionInfo;
|
AssertionInfo m_lastAssertionInfo;
|
||||||
std::vector<SectionEndInfo> m_unfinishedSections;
|
std::vector<SectionEndInfo> m_unfinishedSections;
|
||||||
|
std::vector<ITracker*> m_activeSections;
|
||||||
|
TrackerContext m_trackerContext;
|
||||||
};
|
};
|
||||||
|
|
||||||
IResultCapture& getResultCapture() {
|
IResultCapture& getResultCapture() {
|
||||||
|
@@ -23,17 +23,17 @@ namespace Catch {
|
|||||||
std::string description;
|
std::string description;
|
||||||
SourceLineInfo lineInfo;
|
SourceLineInfo lineInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SectionEndInfo {
|
struct SectionEndInfo {
|
||||||
SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
|
SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
|
||||||
: sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
|
: sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SectionInfo sectionInfo;
|
SectionInfo sectionInfo;
|
||||||
Counts prevAssertions;
|
Counts prevAssertions;
|
||||||
double durationInSeconds;
|
double durationInSeconds;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
|
||||||
|
@@ -9,28 +9,56 @@
|
|||||||
#ifndef TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
|
#ifndef TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
|
||||||
#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
|
#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
|
||||||
|
|
||||||
#include <streambuf>
|
#include "catch_compiler_capabilities.h"
|
||||||
|
#include "catch_streambuf.h"
|
||||||
|
|
||||||
#ifdef __clang__
|
#include <streambuf>
|
||||||
#pragma clang diagnostic ignored "-Wpadded"
|
#include <ostream>
|
||||||
#endif
|
#include <fstream>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
class Stream {
|
|
||||||
public:
|
|
||||||
Stream();
|
|
||||||
Stream( std::streambuf* _streamBuf, bool _isOwned );
|
|
||||||
void release();
|
|
||||||
|
|
||||||
std::streambuf* streamBuf;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool isOwned;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::ostream& cout();
|
std::ostream& cout();
|
||||||
std::ostream& cerr();
|
std::ostream& cerr();
|
||||||
|
|
||||||
|
|
||||||
|
struct IStream {
|
||||||
|
virtual ~IStream() CATCH_NOEXCEPT;
|
||||||
|
virtual std::ostream& stream() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FileStream : public IStream {
|
||||||
|
mutable std::ofstream m_ofs;
|
||||||
|
public:
|
||||||
|
FileStream( std::string const& filename );
|
||||||
|
virtual ~FileStream() CATCH_NOEXCEPT;
|
||||||
|
public: // IStream
|
||||||
|
virtual std::ostream& stream() const CATCH_OVERRIDE;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class CoutStream : public IStream {
|
||||||
|
mutable std::ostream m_os;
|
||||||
|
public:
|
||||||
|
CoutStream();
|
||||||
|
virtual ~CoutStream() CATCH_NOEXCEPT;
|
||||||
|
|
||||||
|
public: // IStream
|
||||||
|
virtual std::ostream& stream() const CATCH_OVERRIDE;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class DebugOutStream : public IStream {
|
||||||
|
CATCH_AUTO_PTR( StreamBufBase ) m_streamBuf;
|
||||||
|
mutable std::ostream m_os;
|
||||||
|
public:
|
||||||
|
DebugOutStream();
|
||||||
|
virtual ~DebugOutStream() CATCH_NOEXCEPT;
|
||||||
|
|
||||||
|
public: // IStream
|
||||||
|
virtual std::ostream& stream() const CATCH_OVERRIDE;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
|
||||||
|
@@ -10,7 +10,6 @@
|
|||||||
#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
|
#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
|
||||||
|
|
||||||
#include "catch_stream.h"
|
#include "catch_stream.h"
|
||||||
#include "catch_streambuf.h"
|
|
||||||
#include "catch_debugger.h"
|
#include "catch_debugger.h"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
@@ -57,6 +56,20 @@ namespace Catch {
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
FileStream::FileStream( std::string const& filename ) {
|
||||||
|
m_ofs.open( filename.c_str() );
|
||||||
|
if( m_ofs.fail() ) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "Unable to open file: '" << filename << "'";
|
||||||
|
throw std::domain_error( oss.str() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& FileStream::stream() const {
|
||||||
|
return m_ofs;
|
||||||
|
}
|
||||||
|
|
||||||
struct OutputDebugWriter {
|
struct OutputDebugWriter {
|
||||||
|
|
||||||
void operator()( std::string const&str ) {
|
void operator()( std::string const&str ) {
|
||||||
@@ -64,23 +77,26 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Stream::Stream()
|
DebugOutStream::DebugOutStream()
|
||||||
: streamBuf( CATCH_NULL ), isOwned( false )
|
: m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
|
||||||
|
m_os( m_streamBuf.get() )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Stream::Stream( std::streambuf* _streamBuf, bool _isOwned )
|
std::ostream& DebugOutStream::stream() const {
|
||||||
: streamBuf( _streamBuf ), isOwned( _isOwned )
|
return m_os;
|
||||||
{}
|
|
||||||
|
|
||||||
void Stream::release() {
|
|
||||||
if( isOwned ) {
|
|
||||||
delete streamBuf;
|
|
||||||
streamBuf = CATCH_NULL;
|
|
||||||
isOwned = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement this functions
|
// Store the streambuf from cout up-front because
|
||||||
|
// cout may get redirected when running tests
|
||||||
|
CoutStream::CoutStream()
|
||||||
|
: m_os( Catch::cout().rdbuf() )
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::ostream& CoutStream::stream() const {
|
||||||
|
return m_os;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
|
||||||
std::ostream& cout() {
|
std::ostream& cout() {
|
||||||
return std::cout;
|
return std::cout;
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
# pragma clang diagnostic ignored "-Wc++98-compat"
|
# pragma clang diagnostic ignored "-Wc++98-compat"
|
||||||
# pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
|
# pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
|
||||||
# pragma clang diagnostic ignored "-Wswitch-enum"
|
# pragma clang diagnostic ignored "-Wswitch-enum"
|
||||||
|
# pragma clang diagnostic ignored "-Wcovered-switch-default"
|
||||||
# endif
|
# endif
|
||||||
#elif defined __GNUC__
|
#elif defined __GNUC__
|
||||||
# pragma GCC diagnostic ignored "-Wvariadic-macros"
|
# pragma GCC diagnostic ignored "-Wvariadic-macros"
|
||||||
|
@@ -31,7 +31,7 @@ namespace Catch {
|
|||||||
MayFail = 1 << 3,
|
MayFail = 1 << 3,
|
||||||
Throws = 1 << 4
|
Throws = 1 << 4
|
||||||
};
|
};
|
||||||
|
|
||||||
TestCaseInfo( std::string const& _name,
|
TestCaseInfo( std::string const& _name,
|
||||||
std::string const& _className,
|
std::string const& _className,
|
||||||
std::string const& _description,
|
std::string const& _description,
|
||||||
@@ -41,7 +41,7 @@ namespace Catch {
|
|||||||
TestCaseInfo( TestCaseInfo const& other );
|
TestCaseInfo( TestCaseInfo const& other );
|
||||||
|
|
||||||
friend void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags );
|
friend void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags );
|
||||||
|
|
||||||
bool isHidden() const;
|
bool isHidden() const;
|
||||||
bool throws() const;
|
bool throws() const;
|
||||||
bool okToFail() const;
|
bool okToFail() const;
|
||||||
|
@@ -88,7 +88,7 @@ namespace Catch {
|
|||||||
tags.insert( "hide" );
|
tags.insert( "hide" );
|
||||||
tags.insert( "." );
|
tags.insert( "." );
|
||||||
}
|
}
|
||||||
|
|
||||||
TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
|
TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
|
||||||
return TestCase( _testCase, info );
|
return TestCase( _testCase, info );
|
||||||
}
|
}
|
||||||
@@ -97,7 +97,7 @@ namespace Catch {
|
|||||||
{
|
{
|
||||||
testCaseInfo.tags = tags;
|
testCaseInfo.tags = tags;
|
||||||
testCaseInfo.lcaseTags.clear();
|
testCaseInfo.lcaseTags.clear();
|
||||||
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) {
|
for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) {
|
||||||
oss << "[" << *it << "]";
|
oss << "[" << *it << "]";
|
||||||
@@ -107,7 +107,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
testCaseInfo.tagsAsString = oss.str();
|
testCaseInfo.tagsAsString = oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
TestCaseInfo::TestCaseInfo( std::string const& _name,
|
TestCaseInfo::TestCaseInfo( std::string const& _name,
|
||||||
std::string const& _className,
|
std::string const& _className,
|
||||||
std::string const& _description,
|
std::string const& _description,
|
||||||
|
@@ -19,29 +19,45 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#ifdef CATCH_CPP14_OR_GREATER
|
||||||
|
#include <random>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
struct LexSort {
|
|
||||||
bool operator() (TestCase i,TestCase j) const { return (i<j);}
|
|
||||||
};
|
|
||||||
struct RandomNumberGenerator {
|
struct RandomNumberGenerator {
|
||||||
int operator()( int n ) const { return std::rand() % n; }
|
typedef std::ptrdiff_t result_type;
|
||||||
|
|
||||||
|
result_type operator()( result_type n ) const { return std::rand() % n; }
|
||||||
|
|
||||||
|
#ifdef CATCH_CPP14_OR_GREATER
|
||||||
|
static constexpr result_type min() { return 0; }
|
||||||
|
static constexpr result_type max() { return 1000000; }
|
||||||
|
result_type operator()() const { return std::rand() % max(); }
|
||||||
|
#endif
|
||||||
|
template<typename V>
|
||||||
|
static void shuffle( V& vector ) {
|
||||||
|
RandomNumberGenerator rng;
|
||||||
|
#ifdef CATCH_CPP14_OR_GREATER
|
||||||
|
std::shuffle( vector.begin(), vector.end(), rng );
|
||||||
|
#else
|
||||||
|
std::random_shuffle( vector.begin(), vector.end(), rng );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
|
inline std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
|
||||||
|
|
||||||
std::vector<TestCase> sorted = unsortedTestCases;
|
std::vector<TestCase> sorted = unsortedTestCases;
|
||||||
|
|
||||||
switch( config.runOrder() ) {
|
switch( config.runOrder() ) {
|
||||||
case RunTests::InLexicographicalOrder:
|
case RunTests::InLexicographicalOrder:
|
||||||
std::sort( sorted.begin(), sorted.end(), LexSort() );
|
std::sort( sorted.begin(), sorted.end() );
|
||||||
break;
|
break;
|
||||||
case RunTests::InRandomOrder:
|
case RunTests::InRandomOrder:
|
||||||
{
|
{
|
||||||
seedRng( config );
|
seedRng( config );
|
||||||
|
RandomNumberGenerator::shuffle( sorted );
|
||||||
RandomNumberGenerator rng;
|
|
||||||
std::random_shuffle( sorted.begin(), sorted.end(), rng );
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RunTests::InDeclarationOrder:
|
case RunTests::InDeclarationOrder:
|
||||||
@@ -60,17 +76,19 @@ namespace Catch {
|
|||||||
it != itEnd;
|
it != itEnd;
|
||||||
++it ) {
|
++it ) {
|
||||||
std::pair<std::set<TestCase>::const_iterator, bool> prev = seenFunctions.insert( *it );
|
std::pair<std::set<TestCase>::const_iterator, bool> prev = seenFunctions.insert( *it );
|
||||||
if( !prev.second ){
|
if( !prev.second ) {
|
||||||
Catch::cerr()
|
std::ostringstream ss;
|
||||||
<< Colour( Colour::Red )
|
|
||||||
<< "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n"
|
ss << Colour( Colour::Red )
|
||||||
<< "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
|
<< "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n"
|
||||||
<< "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl;
|
<< "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
|
||||||
exit(1);
|
<< "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl;
|
||||||
|
|
||||||
|
throw std::runtime_error(ss.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
|
std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
|
||||||
std::vector<TestCase> filtered;
|
std::vector<TestCase> filtered;
|
||||||
filtered.reserve( testCases.size() );
|
filtered.reserve( testCases.size() );
|
||||||
@@ -87,7 +105,10 @@ namespace Catch {
|
|||||||
|
|
||||||
class TestRegistry : public ITestCaseRegistry {
|
class TestRegistry : public ITestCaseRegistry {
|
||||||
public:
|
public:
|
||||||
TestRegistry() : m_unnamedCount( 0 ) {}
|
TestRegistry()
|
||||||
|
: m_currentSortOrder( RunTests::InDeclarationOrder ),
|
||||||
|
m_unnamedCount( 0 )
|
||||||
|
{}
|
||||||
virtual ~TestRegistry();
|
virtual ~TestRegistry();
|
||||||
|
|
||||||
virtual void registerTest( TestCase const& testCase ) {
|
virtual void registerTest( TestCase const& testCase ) {
|
||||||
@@ -152,29 +173,38 @@ namespace Catch {
|
|||||||
return className;
|
return className;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
void registerTestCase
|
||||||
|
( ITestCase* testCase,
|
||||||
|
char const* classOrQualifiedMethodName,
|
||||||
|
NameAndDesc const& nameAndDesc,
|
||||||
|
SourceLineInfo const& lineInfo ) {
|
||||||
|
|
||||||
AutoReg::AutoReg( TestFunction function,
|
getMutableRegistryHub().registerTest
|
||||||
SourceLineInfo const& lineInfo,
|
( makeTestCase
|
||||||
NameAndDesc const& nameAndDesc ) {
|
( testCase,
|
||||||
|
extractClassName( classOrQualifiedMethodName ),
|
||||||
|
nameAndDesc.name,
|
||||||
|
nameAndDesc.description,
|
||||||
|
lineInfo ) );
|
||||||
|
}
|
||||||
|
void registerTestCaseFunction
|
||||||
|
( TestFunction function,
|
||||||
|
SourceLineInfo const& lineInfo,
|
||||||
|
NameAndDesc const& nameAndDesc ) {
|
||||||
registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
|
registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoReg::~AutoReg() {}
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void AutoReg::registerTestCase( ITestCase* testCase,
|
AutoReg::AutoReg
|
||||||
char const* classOrQualifiedMethodName,
|
( TestFunction function,
|
||||||
NameAndDesc const& nameAndDesc,
|
SourceLineInfo const& lineInfo,
|
||||||
SourceLineInfo const& lineInfo ) {
|
NameAndDesc const& nameAndDesc ) {
|
||||||
|
registerTestCaseFunction( function, lineInfo, nameAndDesc );
|
||||||
getMutableRegistryHub().registerTest
|
|
||||||
( makeTestCase( testCase,
|
|
||||||
extractClassName( classOrQualifiedMethodName ),
|
|
||||||
nameAndDesc.name,
|
|
||||||
nameAndDesc.description,
|
|
||||||
lineInfo ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AutoReg::~AutoReg() {}
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
|
|
||||||
|
@@ -9,141 +9,321 @@
|
|||||||
#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
|
#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
|
||||||
|
|
||||||
#include "catch_compiler_capabilities.h"
|
#include "catch_compiler_capabilities.h"
|
||||||
|
#include "catch_ptr.hpp"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
namespace SectionTracking {
|
namespace TestCaseTracking {
|
||||||
|
|
||||||
class TrackedSection {
|
struct ITracker : SharedImpl<> {
|
||||||
|
virtual ~ITracker();
|
||||||
|
|
||||||
|
// static queries
|
||||||
|
virtual std::string name() const = 0;
|
||||||
|
|
||||||
|
// dynamic queries
|
||||||
|
virtual bool isComplete() const = 0; // Successfully completed or failed
|
||||||
|
virtual bool isSuccessfullyCompleted() const = 0;
|
||||||
|
virtual bool isOpen() const = 0; // Started but not complete
|
||||||
|
virtual bool hasChildren() const = 0;
|
||||||
|
|
||||||
|
virtual ITracker& parent() = 0;
|
||||||
|
|
||||||
|
// actions
|
||||||
|
virtual void close() = 0; // Successfully complete
|
||||||
|
virtual void fail() = 0;
|
||||||
|
virtual void markAsNeedingAnotherRun() = 0;
|
||||||
|
|
||||||
|
virtual void addChild( Ptr<ITracker> const& child ) = 0;
|
||||||
|
virtual ITracker* findChild( std::string const& name ) = 0;
|
||||||
|
virtual void openChild() = 0;
|
||||||
|
|
||||||
typedef std::map<std::string, TrackedSection> TrackedSections;
|
// Debug/ checking
|
||||||
|
virtual bool isSectionTracker() const = 0;
|
||||||
public:
|
virtual bool isIndexTracker() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TrackerContext {
|
||||||
|
|
||||||
enum RunState {
|
enum RunState {
|
||||||
NotStarted,
|
NotStarted,
|
||||||
Executing,
|
Executing,
|
||||||
ExecutingChildren,
|
CompletedCycle
|
||||||
Completed
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TrackedSection( std::string const& name, TrackedSection* parent )
|
Ptr<ITracker> m_rootTracker;
|
||||||
: m_name( name ), m_runState( NotStarted ), m_parent( parent )
|
ITracker* m_currentTracker;
|
||||||
|
RunState m_runState;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
static TrackerContext& instance() {
|
||||||
|
static TrackerContext s_instance;
|
||||||
|
return s_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
TrackerContext()
|
||||||
|
: m_currentTracker( CATCH_NULL ),
|
||||||
|
m_runState( NotStarted )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
RunState runState() const { return m_runState; }
|
|
||||||
|
|
||||||
TrackedSection* findChild( std::string const& childName );
|
|
||||||
TrackedSection* acquireChild( std::string const& childName );
|
|
||||||
|
|
||||||
void enter() {
|
|
||||||
if( m_runState == NotStarted )
|
|
||||||
m_runState = Executing;
|
|
||||||
}
|
|
||||||
void leave();
|
|
||||||
|
|
||||||
TrackedSection* getParent() {
|
ITracker& startRun();
|
||||||
return m_parent;
|
|
||||||
|
void endRun() {
|
||||||
|
m_rootTracker.reset();
|
||||||
|
m_currentTracker = CATCH_NULL;
|
||||||
|
m_runState = NotStarted;
|
||||||
}
|
}
|
||||||
bool hasChildren() const {
|
|
||||||
|
void startCycle() {
|
||||||
|
m_currentTracker = m_rootTracker.get();
|
||||||
|
m_runState = Executing;
|
||||||
|
}
|
||||||
|
void completeCycle() {
|
||||||
|
m_runState = CompletedCycle;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool completedCycle() const {
|
||||||
|
return m_runState == CompletedCycle;
|
||||||
|
}
|
||||||
|
ITracker& currentTracker() {
|
||||||
|
return *m_currentTracker;
|
||||||
|
}
|
||||||
|
void setCurrentTracker( ITracker* tracker ) {
|
||||||
|
m_currentTracker = tracker;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class TrackerBase : public ITracker {
|
||||||
|
protected:
|
||||||
|
enum CycleState {
|
||||||
|
NotStarted,
|
||||||
|
Executing,
|
||||||
|
ExecutingChildren,
|
||||||
|
NeedsAnotherRun,
|
||||||
|
CompletedSuccessfully,
|
||||||
|
Failed
|
||||||
|
};
|
||||||
|
class TrackerHasName {
|
||||||
|
std::string m_name;
|
||||||
|
public:
|
||||||
|
TrackerHasName( std::string const& name ) : m_name( name ) {}
|
||||||
|
bool operator ()( Ptr<ITracker> const& tracker ) {
|
||||||
|
return tracker->name() == m_name;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
typedef std::vector<Ptr<ITracker> > Children;
|
||||||
|
std::string m_name;
|
||||||
|
TrackerContext& m_ctx;
|
||||||
|
ITracker* m_parent;
|
||||||
|
Children m_children;
|
||||||
|
CycleState m_runState;
|
||||||
|
public:
|
||||||
|
TrackerBase( std::string const& name, TrackerContext& ctx, ITracker* parent )
|
||||||
|
: m_name( name ),
|
||||||
|
m_ctx( ctx ),
|
||||||
|
m_parent( parent ),
|
||||||
|
m_runState( NotStarted )
|
||||||
|
{}
|
||||||
|
virtual ~TrackerBase();
|
||||||
|
|
||||||
|
virtual std::string name() const CATCH_OVERRIDE {
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
virtual bool isComplete() const CATCH_OVERRIDE {
|
||||||
|
return m_runState == CompletedSuccessfully || m_runState == Failed;
|
||||||
|
}
|
||||||
|
virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE {
|
||||||
|
return m_runState == CompletedSuccessfully;
|
||||||
|
}
|
||||||
|
virtual bool isOpen() const CATCH_OVERRIDE {
|
||||||
|
return m_runState != NotStarted && !isComplete();
|
||||||
|
}
|
||||||
|
virtual bool hasChildren() const CATCH_OVERRIDE {
|
||||||
return !m_children.empty();
|
return !m_children.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
std::string m_name;
|
virtual void addChild( Ptr<ITracker> const& child ) CATCH_OVERRIDE {
|
||||||
RunState m_runState;
|
m_children.push_back( child );
|
||||||
TrackedSections m_children;
|
}
|
||||||
TrackedSection* m_parent;
|
|
||||||
};
|
virtual ITracker* findChild( std::string const& name ) CATCH_OVERRIDE {
|
||||||
|
Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( name ) );
|
||||||
inline TrackedSection* TrackedSection::findChild( std::string const& childName ) {
|
return( it != m_children.end() )
|
||||||
TrackedSections::iterator it = m_children.find( childName );
|
? it->get()
|
||||||
return it != m_children.end()
|
: CATCH_NULL;
|
||||||
? &it->second
|
}
|
||||||
: CATCH_NULL;
|
virtual ITracker& parent() CATCH_OVERRIDE {
|
||||||
}
|
assert( m_parent ); // Should always be non-null except for root
|
||||||
inline TrackedSection* TrackedSection::acquireChild( std::string const& childName ) {
|
return *m_parent;
|
||||||
if( TrackedSection* child = findChild( childName ) )
|
}
|
||||||
return child;
|
|
||||||
m_children.insert( std::make_pair( childName, TrackedSection( childName, this ) ) );
|
virtual void openChild() CATCH_OVERRIDE {
|
||||||
return findChild( childName );
|
if( m_runState != ExecutingChildren ) {
|
||||||
}
|
|
||||||
inline void TrackedSection::leave() {
|
|
||||||
for( TrackedSections::const_iterator it = m_children.begin(), itEnd = m_children.end();
|
|
||||||
it != itEnd;
|
|
||||||
++it )
|
|
||||||
if( it->second.runState() != Completed ) {
|
|
||||||
m_runState = ExecutingChildren;
|
m_runState = ExecutingChildren;
|
||||||
return;
|
if( m_parent )
|
||||||
|
m_parent->openChild();
|
||||||
}
|
}
|
||||||
m_runState = Completed;
|
|
||||||
}
|
|
||||||
|
|
||||||
class TestCaseTracker {
|
|
||||||
public:
|
|
||||||
TestCaseTracker( std::string const& testCaseName )
|
|
||||||
: m_testCase( testCaseName, CATCH_NULL ),
|
|
||||||
m_currentSection( &m_testCase ),
|
|
||||||
m_completedASectionThisRun( false )
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool enterSection( std::string const& name ) {
|
|
||||||
TrackedSection* child = m_currentSection->acquireChild( name );
|
|
||||||
if( m_completedASectionThisRun || child->runState() == TrackedSection::Completed )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
m_currentSection = child;
|
|
||||||
m_currentSection->enter();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
void leaveSection() {
|
|
||||||
m_currentSection->leave();
|
|
||||||
m_currentSection = m_currentSection->getParent();
|
|
||||||
assert( m_currentSection != CATCH_NULL );
|
|
||||||
m_completedASectionThisRun = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool currentSectionHasChildren() const {
|
virtual bool isSectionTracker() const CATCH_OVERRIDE { return false; }
|
||||||
return m_currentSection->hasChildren();
|
virtual bool isIndexTracker() const CATCH_OVERRIDE { return false; }
|
||||||
}
|
|
||||||
bool isCompleted() const {
|
void open() {
|
||||||
return m_testCase.runState() == TrackedSection::Completed;
|
m_runState = Executing;
|
||||||
|
moveToThis();
|
||||||
|
if( m_parent )
|
||||||
|
m_parent->openChild();
|
||||||
}
|
}
|
||||||
|
|
||||||
class Guard {
|
virtual void close() CATCH_OVERRIDE {
|
||||||
public:
|
|
||||||
Guard( TestCaseTracker& tracker ) : m_tracker( tracker ) {
|
// Close any still open children (e.g. generators)
|
||||||
m_tracker.enterTestCase();
|
while( &m_ctx.currentTracker() != this )
|
||||||
|
m_ctx.currentTracker().close();
|
||||||
|
|
||||||
|
switch( m_runState ) {
|
||||||
|
case NotStarted:
|
||||||
|
case CompletedSuccessfully:
|
||||||
|
case Failed:
|
||||||
|
throw std::logic_error( "Illogical state" );
|
||||||
|
|
||||||
|
case NeedsAnotherRun:
|
||||||
|
break;;
|
||||||
|
|
||||||
|
case Executing:
|
||||||
|
m_runState = CompletedSuccessfully;
|
||||||
|
break;
|
||||||
|
case ExecutingChildren:
|
||||||
|
if( m_children.empty() || m_children.back()->isComplete() )
|
||||||
|
m_runState = CompletedSuccessfully;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw std::logic_error( "Unexpected state" );
|
||||||
}
|
}
|
||||||
~Guard() {
|
moveToParent();
|
||||||
m_tracker.leaveTestCase();
|
m_ctx.completeCycle();
|
||||||
}
|
}
|
||||||
private:
|
virtual void fail() CATCH_OVERRIDE {
|
||||||
Guard( Guard const& );
|
m_runState = Failed;
|
||||||
void operator = ( Guard const& );
|
if( m_parent )
|
||||||
TestCaseTracker& m_tracker;
|
m_parent->markAsNeedingAnotherRun();
|
||||||
};
|
moveToParent();
|
||||||
|
m_ctx.completeCycle();
|
||||||
|
}
|
||||||
|
virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE {
|
||||||
|
m_runState = NeedsAnotherRun;
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
void enterTestCase() {
|
void moveToParent() {
|
||||||
m_currentSection = &m_testCase;
|
assert( m_parent );
|
||||||
m_completedASectionThisRun = false;
|
m_ctx.setCurrentTracker( m_parent );
|
||||||
m_testCase.enter();
|
|
||||||
}
|
}
|
||||||
void leaveTestCase() {
|
void moveToThis() {
|
||||||
m_testCase.leave();
|
m_ctx.setCurrentTracker( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackedSection m_testCase;
|
|
||||||
TrackedSection* m_currentSection;
|
|
||||||
bool m_completedASectionThisRun;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace SectionTracking
|
class SectionTracker : public TrackerBase {
|
||||||
|
public:
|
||||||
|
SectionTracker( std::string const& name, TrackerContext& ctx, ITracker* parent )
|
||||||
|
: TrackerBase( name, ctx, parent )
|
||||||
|
{}
|
||||||
|
virtual ~SectionTracker();
|
||||||
|
|
||||||
using SectionTracking::TestCaseTracker;
|
virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; }
|
||||||
|
|
||||||
|
static SectionTracker& acquire( TrackerContext& ctx, std::string const& name ) {
|
||||||
|
SectionTracker* section = CATCH_NULL;
|
||||||
|
|
||||||
|
ITracker& currentTracker = ctx.currentTracker();
|
||||||
|
if( ITracker* childTracker = currentTracker.findChild( name ) ) {
|
||||||
|
assert( childTracker );
|
||||||
|
assert( childTracker->isSectionTracker() );
|
||||||
|
section = static_cast<SectionTracker*>( childTracker );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
section = new SectionTracker( name, ctx, ¤tTracker );
|
||||||
|
currentTracker.addChild( section );
|
||||||
|
}
|
||||||
|
if( !ctx.completedCycle() && !section->isComplete() ) {
|
||||||
|
|
||||||
|
section->open();
|
||||||
|
}
|
||||||
|
return *section;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class IndexTracker : public TrackerBase {
|
||||||
|
int m_size;
|
||||||
|
int m_index;
|
||||||
|
public:
|
||||||
|
IndexTracker( std::string const& name, TrackerContext& ctx, ITracker* parent, int size )
|
||||||
|
: TrackerBase( name, ctx, parent ),
|
||||||
|
m_size( size ),
|
||||||
|
m_index( -1 )
|
||||||
|
{}
|
||||||
|
virtual ~IndexTracker();
|
||||||
|
|
||||||
|
virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; }
|
||||||
|
|
||||||
|
static IndexTracker& acquire( TrackerContext& ctx, std::string const& name, int size ) {
|
||||||
|
IndexTracker* tracker = CATCH_NULL;
|
||||||
|
|
||||||
|
ITracker& currentTracker = ctx.currentTracker();
|
||||||
|
if( ITracker* childTracker = currentTracker.findChild( name ) ) {
|
||||||
|
assert( childTracker );
|
||||||
|
assert( childTracker->isIndexTracker() );
|
||||||
|
tracker = static_cast<IndexTracker*>( childTracker );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tracker = new IndexTracker( name, ctx, ¤tTracker, size );
|
||||||
|
currentTracker.addChild( tracker );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !ctx.completedCycle() && !tracker->isComplete() ) {
|
||||||
|
if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
|
||||||
|
tracker->moveNext();
|
||||||
|
tracker->open();
|
||||||
|
}
|
||||||
|
|
||||||
|
return *tracker;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index() const { return m_index; }
|
||||||
|
|
||||||
|
void moveNext() {
|
||||||
|
m_index++;
|
||||||
|
m_children.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void close() CATCH_OVERRIDE {
|
||||||
|
TrackerBase::close();
|
||||||
|
if( m_runState == CompletedSuccessfully && m_index < m_size-1 )
|
||||||
|
m_runState = Executing;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline ITracker& TrackerContext::startRun() {
|
||||||
|
m_rootTracker = new SectionTracker( "{root}", *this, CATCH_NULL );
|
||||||
|
m_currentTracker = CATCH_NULL;
|
||||||
|
m_runState = Executing;
|
||||||
|
return *m_rootTracker;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace TestCaseTracking
|
||||||
|
|
||||||
|
using TestCaseTracking::ITracker;
|
||||||
|
using TestCaseTracking::TrackerContext;
|
||||||
|
using TestCaseTracking::SectionTracker;
|
||||||
|
using TestCaseTracking::IndexTracker;
|
||||||
|
|
||||||
} // namespace Catch
|
} // namespace Catch
|
||||||
|
|
||||||
|
@@ -42,27 +42,32 @@ struct NameAndDesc {
|
|||||||
const char* description;
|
const char* description;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void registerTestCase
|
||||||
|
( ITestCase* testCase,
|
||||||
|
char const* className,
|
||||||
|
NameAndDesc const& nameAndDesc,
|
||||||
|
SourceLineInfo const& lineInfo );
|
||||||
|
|
||||||
struct AutoReg {
|
struct AutoReg {
|
||||||
|
|
||||||
AutoReg( TestFunction function,
|
AutoReg
|
||||||
SourceLineInfo const& lineInfo,
|
( TestFunction function,
|
||||||
NameAndDesc const& nameAndDesc );
|
SourceLineInfo const& lineInfo,
|
||||||
|
NameAndDesc const& nameAndDesc );
|
||||||
|
|
||||||
template<typename C>
|
template<typename C>
|
||||||
AutoReg( void (C::*method)(),
|
AutoReg
|
||||||
char const* className,
|
( void (C::*method)(),
|
||||||
NameAndDesc const& nameAndDesc,
|
char const* className,
|
||||||
SourceLineInfo const& lineInfo ) {
|
NameAndDesc const& nameAndDesc,
|
||||||
registerTestCase( new MethodTestCase<C>( method ),
|
SourceLineInfo const& lineInfo ) {
|
||||||
className,
|
|
||||||
nameAndDesc,
|
|
||||||
lineInfo );
|
|
||||||
}
|
|
||||||
|
|
||||||
void registerTestCase( ITestCase* testCase,
|
registerTestCase
|
||||||
char const* className,
|
( new MethodTestCase<C>( method ),
|
||||||
NameAndDesc const& nameAndDesc,
|
className,
|
||||||
SourceLineInfo const& lineInfo );
|
nameAndDesc,
|
||||||
|
lineInfo );
|
||||||
|
}
|
||||||
|
|
||||||
~AutoReg();
|
~AutoReg();
|
||||||
|
|
||||||
@@ -71,50 +76,70 @@ private:
|
|||||||
void operator= ( AutoReg const& );
|
void operator= ( AutoReg const& );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void registerTestCaseFunction
|
||||||
|
( TestFunction function,
|
||||||
|
SourceLineInfo const& lineInfo,
|
||||||
|
NameAndDesc const& nameAndDesc );
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
#ifdef CATCH_CONFIG_VARIADIC_MACROS
|
#ifdef CATCH_CONFIG_VARIADIC_MACROS
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
|
||||||
|
static void TestName(); \
|
||||||
|
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
|
||||||
|
static void TestName()
|
||||||
#define INTERNAL_CATCH_TESTCASE( ... ) \
|
#define INTERNAL_CATCH_TESTCASE( ... ) \
|
||||||
static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
|
INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
|
||||||
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
|
|
||||||
static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
|
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
|
||||||
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
|
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... )\
|
#define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
|
||||||
namespace{ \
|
namespace{ \
|
||||||
struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
|
struct TestName : ClassName{ \
|
||||||
void test(); \
|
void test(); \
|
||||||
}; \
|
}; \
|
||||||
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
|
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
|
||||||
} \
|
} \
|
||||||
void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
|
void TestName::test()
|
||||||
|
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
|
||||||
|
INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
|
||||||
|
Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) );
|
||||||
|
|
||||||
#else
|
#else
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \
|
||||||
|
static void TestName(); \
|
||||||
|
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
|
||||||
|
static void TestName()
|
||||||
#define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
|
#define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
|
||||||
static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
|
INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc )
|
||||||
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
|
|
||||||
static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
|
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
|
||||||
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
|
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
|
#define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\
|
||||||
namespace{ \
|
namespace{ \
|
||||||
struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
|
struct TestCaseName : ClassName{ \
|
||||||
void test(); \
|
void test(); \
|
||||||
}; \
|
}; \
|
||||||
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
|
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
|
||||||
} \
|
} \
|
||||||
void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
|
void TestCaseName::test()
|
||||||
|
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
|
||||||
|
INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc )
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \
|
||||||
|
Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
class TestSpec {
|
class TestSpec {
|
||||||
struct Pattern : SharedImpl<> {
|
struct Pattern : SharedImpl<> {
|
||||||
virtual ~Pattern();
|
virtual ~Pattern();
|
||||||
@@ -38,7 +38,7 @@ namespace Catch {
|
|||||||
private:
|
private:
|
||||||
WildcardPattern m_wildcardPattern;
|
WildcardPattern m_wildcardPattern;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TagPattern : public Pattern {
|
class TagPattern : public Pattern {
|
||||||
public:
|
public:
|
||||||
TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
|
TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
|
||||||
@@ -49,7 +49,7 @@ namespace Catch {
|
|||||||
private:
|
private:
|
||||||
std::string m_tag;
|
std::string m_tag;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExcludedPattern : public Pattern {
|
class ExcludedPattern : public Pattern {
|
||||||
public:
|
public:
|
||||||
ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
|
ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
|
||||||
@@ -64,10 +64,11 @@ namespace Catch {
|
|||||||
|
|
||||||
bool matches( TestCaseInfo const& testCase ) const {
|
bool matches( TestCaseInfo const& testCase ) const {
|
||||||
// All patterns in a filter must match for the filter to be a match
|
// All patterns in a filter must match for the filter to be a match
|
||||||
for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it )
|
for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) {
|
||||||
if( !(*it)->matches( testCase ) )
|
if( !(*it)->matches( testCase ) )
|
||||||
return false;
|
return false;
|
||||||
return true;
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -67,7 +67,7 @@ std::string toString( std::nullptr_t );
|
|||||||
std::string toString( NSObject* const& nsObject );
|
std::string toString( NSObject* const& nsObject );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace Detail {
|
namespace Detail {
|
||||||
|
|
||||||
extern const std::string unprintableString;
|
extern const std::string unprintableString;
|
||||||
@@ -78,7 +78,7 @@ namespace Detail {
|
|||||||
|
|
||||||
struct TrueType { char sizer[1]; };
|
struct TrueType { char sizer[1]; };
|
||||||
struct FalseType { char sizer[2]; };
|
struct FalseType { char sizer[2]; };
|
||||||
|
|
||||||
TrueType& testStreamable( std::ostream& );
|
TrueType& testStreamable( std::ostream& );
|
||||||
FalseType testStreamable( FalseType );
|
FalseType testStreamable( FalseType );
|
||||||
|
|
||||||
|
@@ -16,7 +16,7 @@ namespace Catch {
|
|||||||
namespace Detail {
|
namespace Detail {
|
||||||
|
|
||||||
const std::string unprintableString = "{?}";
|
const std::string unprintableString = "{?}";
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const int hexThreshold = 255;
|
const int hexThreshold = 255;
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ std::string toString( unsigned long long value ) {
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CATCH_CONFIG_CPP11_NULLPTR
|
#ifdef CATCH_CONFIG_CPP11_NULLPTR
|
||||||
std::string toString( std::nullptr_t ) {
|
std::string toString( std::nullptr_t ) {
|
||||||
return "nullptr";
|
return "nullptr";
|
||||||
|
@@ -27,7 +27,7 @@ namespace Catch {
|
|||||||
unsigned int const buildNumber;
|
unsigned int const buildNumber;
|
||||||
|
|
||||||
friend std::ostream& operator << ( std::ostream& os, Version const& version );
|
friend std::ostream& operator << ( std::ostream& os, Version const& version );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void operator=( Version const& );
|
void operator=( Version const& );
|
||||||
};
|
};
|
||||||
|
@@ -37,7 +37,7 @@ namespace Catch {
|
|||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
Version libraryVersion( 1, 2, 1, "develop", 14 );
|
Version libraryVersion( 1, 5, 9, "", 0 );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -19,9 +19,9 @@ namespace Catch
|
|||||||
WildcardAtEnd = 2,
|
WildcardAtEnd = 2,
|
||||||
WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
|
WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity )
|
WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity )
|
||||||
: m_caseSensitivity( caseSensitivity ),
|
: m_caseSensitivity( caseSensitivity ),
|
||||||
m_wildcard( NoWildcard ),
|
m_wildcard( NoWildcard ),
|
||||||
@@ -48,7 +48,7 @@ namespace Catch
|
|||||||
case WildcardAtBothEnds:
|
case WildcardAtBothEnds:
|
||||||
return contains( adjustCase( str ), m_pattern );
|
return contains( adjustCase( str ), m_pattern );
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
#pragma clang diagnostic ignored "-Wunreachable-code"
|
#pragma clang diagnostic ignored "-Wunreachable-code"
|
||||||
|
@@ -22,23 +22,23 @@ namespace Catch {
|
|||||||
class XmlEncode {
|
class XmlEncode {
|
||||||
public:
|
public:
|
||||||
enum ForWhat { ForTextNodes, ForAttributes };
|
enum ForWhat { ForTextNodes, ForAttributes };
|
||||||
|
|
||||||
XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes )
|
XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes )
|
||||||
: m_str( str ),
|
: m_str( str ),
|
||||||
m_forWhat( forWhat )
|
m_forWhat( forWhat )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void encodeTo( std::ostream& os ) const {
|
void encodeTo( std::ostream& os ) const {
|
||||||
|
|
||||||
// Apostrophe escaping not necessary if we always use " to write attributes
|
// Apostrophe escaping not necessary if we always use " to write attributes
|
||||||
// (see: http://www.w3.org/TR/xml/#syntax)
|
// (see: http://www.w3.org/TR/xml/#syntax)
|
||||||
|
|
||||||
for( std::size_t i = 0; i < m_str.size(); ++ i ) {
|
for( std::size_t i = 0; i < m_str.size(); ++ i ) {
|
||||||
char c = m_str[i];
|
char c = m_str[i];
|
||||||
switch( c ) {
|
switch( c ) {
|
||||||
case '<': os << "<"; break;
|
case '<': os << "<"; break;
|
||||||
case '&': os << "&"; break;
|
case '&': os << "&"; break;
|
||||||
|
|
||||||
case '>':
|
case '>':
|
||||||
// See: http://www.w3.org/TR/xml/#syntax
|
// See: http://www.w3.org/TR/xml/#syntax
|
||||||
if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' )
|
if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' )
|
||||||
@@ -46,18 +46,19 @@ namespace Catch {
|
|||||||
else
|
else
|
||||||
os << c;
|
os << c;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '\"':
|
case '\"':
|
||||||
if( m_forWhat == ForAttributes )
|
if( m_forWhat == ForAttributes )
|
||||||
os << """;
|
os << """;
|
||||||
else
|
else
|
||||||
os << c;
|
os << c;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Escape control chars - based on contribution by @espenalb in PR #465
|
// Escape control chars - based on contribution by @espenalb in PR #465 and
|
||||||
|
// by @mrpi PR #588
|
||||||
if ( ( c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' )
|
if ( ( c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' )
|
||||||
os << "&#x" << std::uppercase << std::hex << static_cast<int>( c );
|
os << "&#x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>( c ) << ';';
|
||||||
else
|
else
|
||||||
os << c;
|
os << c;
|
||||||
}
|
}
|
||||||
@@ -68,12 +69,12 @@ namespace Catch {
|
|||||||
xmlEncode.encodeTo( os );
|
xmlEncode.encodeTo( os );
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_str;
|
std::string m_str;
|
||||||
ForWhat m_forWhat;
|
ForWhat m_forWhat;
|
||||||
};
|
};
|
||||||
|
|
||||||
class XmlWriter {
|
class XmlWriter {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -112,13 +113,20 @@ namespace Catch {
|
|||||||
: m_tagIsOpen( false ),
|
: m_tagIsOpen( false ),
|
||||||
m_needsNewline( false ),
|
m_needsNewline( false ),
|
||||||
m_os( &Catch::cout() )
|
m_os( &Catch::cout() )
|
||||||
{}
|
{
|
||||||
|
// We encode control characters, which requires
|
||||||
|
// XML 1.1
|
||||||
|
// see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
|
||||||
|
*m_os << "<?xml version=\"1.1\" encoding=\"UTF-8\"?>\n";
|
||||||
|
}
|
||||||
|
|
||||||
XmlWriter( std::ostream& os )
|
XmlWriter( std::ostream& os )
|
||||||
: m_tagIsOpen( false ),
|
: m_tagIsOpen( false ),
|
||||||
m_needsNewline( false ),
|
m_needsNewline( false ),
|
||||||
m_os( &os )
|
m_os( &os )
|
||||||
{}
|
{
|
||||||
|
*m_os << "<?xml version=\"1.1\" encoding=\"UTF-8\"?>\n";
|
||||||
|
}
|
||||||
|
|
||||||
~XmlWriter() {
|
~XmlWriter() {
|
||||||
while( !m_tags.empty() )
|
while( !m_tags.empty() )
|
||||||
|
@@ -65,7 +65,7 @@ namespace Catch {
|
|||||||
// It can optionally be overridden in the derived class.
|
// It can optionally be overridden in the derived class.
|
||||||
}
|
}
|
||||||
|
|
||||||
Ptr<IConfig> m_config;
|
Ptr<IConfig const> m_config;
|
||||||
std::ostream& stream;
|
std::ostream& stream;
|
||||||
|
|
||||||
LazyStat<TestRunInfo> currentTestRunInfo;
|
LazyStat<TestRunInfo> currentTestRunInfo;
|
||||||
@@ -166,7 +166,7 @@ namespace Catch {
|
|||||||
|
|
||||||
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
|
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
|
||||||
|
|
||||||
virtual bool assertionEnded( AssertionStats const& assertionStats ) {
|
virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
|
||||||
assert( !m_sectionStack.empty() );
|
assert( !m_sectionStack.empty() );
|
||||||
SectionNode& sectionNode = *m_sectionStack.back();
|
SectionNode& sectionNode = *m_sectionStack.back();
|
||||||
sectionNode.assertions.push_back( assertionStats );
|
sectionNode.assertions.push_back( assertionStats );
|
||||||
@@ -204,7 +204,7 @@ namespace Catch {
|
|||||||
|
|
||||||
virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {}
|
virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {}
|
||||||
|
|
||||||
Ptr<IConfig> m_config;
|
Ptr<IConfig const> m_config;
|
||||||
std::ostream& stream;
|
std::ostream& stream;
|
||||||
std::vector<AssertionStats> m_assertions;
|
std::vector<AssertionStats> m_assertions;
|
||||||
std::vector<std::vector<Ptr<SectionNode> > > m_sections;
|
std::vector<std::vector<Ptr<SectionNode> > > m_sections;
|
||||||
@@ -230,18 +230,18 @@ namespace Catch {
|
|||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct TestEventListenerBase : StreamingReporterBase {
|
struct TestEventListenerBase : StreamingReporterBase {
|
||||||
TestEventListenerBase( ReporterConfig const& _config )
|
TestEventListenerBase( ReporterConfig const& _config )
|
||||||
: StreamingReporterBase( _config )
|
: StreamingReporterBase( _config )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
|
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
|
||||||
virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE {
|
virtual bool assertionEnded( AssertionStats const& ) CATCH_OVERRIDE {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
|
||||||
|
@@ -349,7 +349,7 @@ namespace Catch {
|
|||||||
if( totals.testCases.total() == 0 ) {
|
if( totals.testCases.total() == 0 ) {
|
||||||
stream << Colour( Colour::Warning ) << "No tests ran\n";
|
stream << Colour( Colour::Warning ) << "No tests ran\n";
|
||||||
}
|
}
|
||||||
else if( totals.assertions.total() > 0 && totals.assertions.allPassed() ) {
|
else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) {
|
||||||
stream << Colour( Colour::ResultSuccess ) << "All tests passed";
|
stream << Colour( Colour::ResultSuccess ) << "All tests passed";
|
||||||
stream << " ("
|
stream << " ("
|
||||||
<< pluralise( totals.assertions.passed, "assertion" ) << " in "
|
<< pluralise( totals.assertions.passed, "assertion" ) << " in "
|
||||||
|
@@ -104,7 +104,7 @@ namespace Catch {
|
|||||||
SectionNode const& rootSection = *testCaseNode.children.front();
|
SectionNode const& rootSection = *testCaseNode.children.front();
|
||||||
|
|
||||||
std::string className = stats.testInfo.className;
|
std::string className = stats.testInfo.className;
|
||||||
|
|
||||||
if( className.empty() ) {
|
if( className.empty() ) {
|
||||||
if( rootSection.childSections.empty() )
|
if( rootSection.childSections.empty() )
|
||||||
className = "global";
|
className = "global";
|
||||||
@@ -118,7 +118,7 @@ namespace Catch {
|
|||||||
std::string name = trim( sectionNode.stats.sectionInfo.name );
|
std::string name = trim( sectionNode.stats.sectionInfo.name );
|
||||||
if( !rootName.empty() )
|
if( !rootName.empty() )
|
||||||
name = rootName + "/" + name;
|
name = rootName + "/" + name;
|
||||||
|
|
||||||
if( !sectionNode.assertions.empty() ||
|
if( !sectionNode.assertions.empty() ||
|
||||||
!sectionNode.stdOut.empty() ||
|
!sectionNode.stdOut.empty() ||
|
||||||
!sectionNode.stdErr.empty() ) {
|
!sectionNode.stdErr.empty() ) {
|
||||||
@@ -187,7 +187,7 @@ namespace Catch {
|
|||||||
elementName = "internalError";
|
elementName = "internalError";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlWriter::ScopedElement e = xml.scopedElement( elementName );
|
XmlWriter::ScopedElement e = xml.scopedElement( elementName );
|
||||||
|
|
||||||
xml.writeAttribute( "message", result.getExpandedExpression() );
|
xml.writeAttribute( "message", result.getExpandedExpression() );
|
||||||
@@ -216,7 +216,7 @@ namespace Catch {
|
|||||||
unsigned int unexpectedExceptions;
|
unsigned int unexpectedExceptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )
|
INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
|
@@ -15,18 +15,18 @@ namespace Catch {
|
|||||||
class MultipleReporters : public SharedImpl<IStreamingReporter> {
|
class MultipleReporters : public SharedImpl<IStreamingReporter> {
|
||||||
typedef std::vector<Ptr<IStreamingReporter> > Reporters;
|
typedef std::vector<Ptr<IStreamingReporter> > Reporters;
|
||||||
Reporters m_reporters;
|
Reporters m_reporters;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void add( Ptr<IStreamingReporter> const& reporter ) {
|
void add( Ptr<IStreamingReporter> const& reporter ) {
|
||||||
m_reporters.push_back( reporter );
|
m_reporters.push_back( reporter );
|
||||||
}
|
}
|
||||||
|
|
||||||
public: // IStreamingReporter
|
public: // IStreamingReporter
|
||||||
|
|
||||||
virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
|
virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
|
||||||
return m_reporters[0]->getPreferences();
|
return m_reporters[0]->getPreferences();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
|
virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
|
||||||
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
|
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
|
||||||
it != itEnd;
|
it != itEnd;
|
||||||
@@ -34,7 +34,7 @@ public: // IStreamingReporter
|
|||||||
(*it)->noMatchingTestCases( spec );
|
(*it)->noMatchingTestCases( spec );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE {
|
virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE {
|
||||||
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
|
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
|
||||||
it != itEnd;
|
it != itEnd;
|
||||||
@@ -49,7 +49,7 @@ public: // IStreamingReporter
|
|||||||
(*it)->testGroupStarting( groupInfo );
|
(*it)->testGroupStarting( groupInfo );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
|
virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
|
||||||
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
|
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
|
||||||
it != itEnd;
|
it != itEnd;
|
||||||
@@ -64,7 +64,7 @@ public: // IStreamingReporter
|
|||||||
(*it)->sectionStarting( sectionInfo );
|
(*it)->sectionStarting( sectionInfo );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE {
|
virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE {
|
||||||
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
|
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
|
||||||
it != itEnd;
|
it != itEnd;
|
||||||
@@ -72,7 +72,7 @@ public: // IStreamingReporter
|
|||||||
(*it)->assertionStarting( assertionInfo );
|
(*it)->assertionStarting( assertionInfo );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// The return value indicates if the messages buffer should be cleared:
|
// The return value indicates if the messages buffer should be cleared:
|
||||||
virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
|
virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
|
||||||
bool clearBuffer = false;
|
bool clearBuffer = false;
|
||||||
@@ -111,20 +111,25 @@ public: // IStreamingReporter
|
|||||||
(*it)->testRunEnded( testRunStats );
|
(*it)->testRunEnded( testRunStats );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
|
virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
|
||||||
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
|
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
|
||||||
it != itEnd;
|
it != itEnd;
|
||||||
++it )
|
++it )
|
||||||
(*it)->skipTest( testInfo );
|
(*it)->skipTest( testInfo );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual MultipleReporters* tryAsMulti() CATCH_OVERRIDE {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter ) {
|
Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter ) {
|
||||||
Ptr<IStreamingReporter> resultingReporter;
|
Ptr<IStreamingReporter> resultingReporter;
|
||||||
|
|
||||||
if( existingReporter ) {
|
if( existingReporter ) {
|
||||||
MultipleReporters* multi = dynamic_cast<MultipleReporters*>( existingReporter.get() );
|
MultipleReporters* multi = existingReporter->tryAsMulti();
|
||||||
if( !multi ) {
|
if( !multi ) {
|
||||||
multi = new MultipleReporters;
|
multi = new MultipleReporters;
|
||||||
resultingReporter = Ptr<IStreamingReporter>( multi );
|
resultingReporter = Ptr<IStreamingReporter>( multi );
|
||||||
@@ -137,11 +142,11 @@ Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingRepo
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
resultingReporter = additionalReporter;
|
resultingReporter = additionalReporter;
|
||||||
|
|
||||||
return resultingReporter;
|
return resultingReporter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED
|
||||||
|
@@ -24,7 +24,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
struct TeamCityReporter : StreamingReporterBase {
|
struct TeamCityReporter : StreamingReporterBase {
|
||||||
TeamCityReporter( ReporterConfig const& _config )
|
TeamCityReporter( ReporterConfig const& _config )
|
||||||
: StreamingReporterBase( _config ),
|
: StreamingReporterBase( _config ),
|
||||||
@@ -32,7 +32,7 @@ namespace Catch {
|
|||||||
{
|
{
|
||||||
m_reporterPrefs.shouldRedirectStdOut = true;
|
m_reporterPrefs.shouldRedirectStdOut = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string escape( std::string const& str ) {
|
static std::string escape( std::string const& str ) {
|
||||||
std::string escaped = str;
|
std::string escaped = str;
|
||||||
replaceInPlace( escaped, "|", "||" );
|
replaceInPlace( escaped, "|", "||" );
|
||||||
@@ -58,9 +58,9 @@ namespace Catch {
|
|||||||
stream << " message='test skipped because it didn|'t match the test spec'";
|
stream << " message='test skipped because it didn|'t match the test spec'";
|
||||||
stream << "]\n";
|
stream << "]\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void noMatchingTestCases( std::string const& /* spec */ ) CATCH_OVERRIDE {}
|
virtual void noMatchingTestCases( std::string const& /* spec */ ) CATCH_OVERRIDE {}
|
||||||
|
|
||||||
virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
|
virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
|
||||||
StreamingReporterBase::testGroupStarting( groupInfo );
|
StreamingReporterBase::testGroupStarting( groupInfo );
|
||||||
stream << "##teamcity[testSuiteStarted name='"
|
stream << "##teamcity[testSuiteStarted name='"
|
||||||
@@ -72,21 +72,21 @@ namespace Catch {
|
|||||||
<< escape( testGroupStats.groupInfo.name ) << "']\n";
|
<< escape( testGroupStats.groupInfo.name ) << "']\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {
|
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
|
virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
|
||||||
AssertionResult const& result = assertionStats.assertionResult;
|
AssertionResult const& result = assertionStats.assertionResult;
|
||||||
if( !result.isOk() ) {
|
if( !result.isOk() ) {
|
||||||
|
|
||||||
std::ostringstream msg;
|
std::ostringstream msg;
|
||||||
if( !m_headerPrintedForThisSection )
|
if( !m_headerPrintedForThisSection )
|
||||||
printSectionHeader( msg );
|
printSectionHeader( msg );
|
||||||
m_headerPrintedForThisSection = true;
|
m_headerPrintedForThisSection = true;
|
||||||
|
|
||||||
msg << result.getSourceInfo() << "\n";
|
msg << result.getSourceInfo() << "\n";
|
||||||
|
|
||||||
switch( result.getResultType() ) {
|
switch( result.getResultType() ) {
|
||||||
case ResultWas::ExpressionFailed:
|
case ResultWas::ExpressionFailed:
|
||||||
msg << "expression failed";
|
msg << "expression failed";
|
||||||
@@ -125,15 +125,15 @@ namespace Catch {
|
|||||||
it != itEnd;
|
it != itEnd;
|
||||||
++it )
|
++it )
|
||||||
msg << "\n \"" << it->message << "\"";
|
msg << "\n \"" << it->message << "\"";
|
||||||
|
|
||||||
|
|
||||||
if( result.hasExpression() ) {
|
if( result.hasExpression() ) {
|
||||||
msg <<
|
msg <<
|
||||||
"\n " << result.getExpressionInMacro() << "\n"
|
"\n " << result.getExpressionInMacro() << "\n"
|
||||||
"with expansion:\n" <<
|
"with expansion:\n" <<
|
||||||
" " << result.getExpandedExpression() << "\n";
|
" " << result.getExpandedExpression() << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
stream << "##teamcity[testFailed"
|
stream << "##teamcity[testFailed"
|
||||||
<< " name='" << escape( currentTestCaseInfo->name )<< "'"
|
<< " name='" << escape( currentTestCaseInfo->name )<< "'"
|
||||||
<< " message='" << escape( msg.str() ) << "'"
|
<< " message='" << escape( msg.str() ) << "'"
|
||||||
@@ -141,7 +141,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
|
virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
|
||||||
m_headerPrintedForThisSection = false;
|
m_headerPrintedForThisSection = false;
|
||||||
StreamingReporterBase::sectionStarting( sectionInfo );
|
StreamingReporterBase::sectionStarting( sectionInfo );
|
||||||
@@ -152,7 +152,7 @@ namespace Catch {
|
|||||||
stream << "##teamcity[testStarted name='"
|
stream << "##teamcity[testStarted name='"
|
||||||
<< escape( testInfo.name ) << "']\n";
|
<< escape( testInfo.name ) << "']\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
|
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
|
||||||
StreamingReporterBase::testCaseEnded( testCaseStats );
|
StreamingReporterBase::testCaseEnded( testCaseStats );
|
||||||
if( !testCaseStats.stdOut.empty() )
|
if( !testCaseStats.stdOut.empty() )
|
||||||
@@ -181,9 +181,9 @@ namespace Catch {
|
|||||||
printHeaderString( os, it->name );
|
printHeaderString( os, it->name );
|
||||||
os << getLineOfChars<'-'>() << "\n";
|
os << getLineOfChars<'-'>() << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
|
SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
|
||||||
|
|
||||||
if( !lineInfo.empty() )
|
if( !lineInfo.empty() )
|
||||||
os << lineInfo << "\n";
|
os << lineInfo << "\n";
|
||||||
os << getLineOfChars<'.'>() << "\n\n";
|
os << getLineOfChars<'.'>() << "\n\n";
|
||||||
@@ -203,15 +203,15 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
bool m_headerPrintedForThisSection;
|
bool m_headerPrintedForThisSection;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CATCH_IMPL
|
#ifdef CATCH_IMPL
|
||||||
TeamCityReporter::~TeamCityReporter() {}
|
TeamCityReporter::~TeamCityReporter() {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
INTERNAL_CATCH_REGISTER_REPORTER( "teamcity", TeamCityReporter )
|
INTERNAL_CATCH_REGISTER_REPORTER( "teamcity", TeamCityReporter )
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
|
@@ -20,13 +20,14 @@ namespace Catch {
|
|||||||
public:
|
public:
|
||||||
XmlReporter( ReporterConfig const& _config )
|
XmlReporter( ReporterConfig const& _config )
|
||||||
: StreamingReporterBase( _config ),
|
: StreamingReporterBase( _config ),
|
||||||
|
m_xml(_config.stream()),
|
||||||
m_sectionDepth( 0 )
|
m_sectionDepth( 0 )
|
||||||
{
|
{
|
||||||
m_reporterPrefs.shouldRedirectStdOut = true;
|
m_reporterPrefs.shouldRedirectStdOut = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~XmlReporter() CATCH_OVERRIDE;
|
virtual ~XmlReporter() CATCH_OVERRIDE;
|
||||||
|
|
||||||
static std::string getDescription() {
|
static std::string getDescription() {
|
||||||
return "Reports test results as an XML document";
|
return "Reports test results as an XML document";
|
||||||
}
|
}
|
||||||
@@ -39,7 +40,6 @@ namespace Catch {
|
|||||||
|
|
||||||
virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE {
|
virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE {
|
||||||
StreamingReporterBase::testRunStarting( testInfo );
|
StreamingReporterBase::testRunStarting( testInfo );
|
||||||
m_xml.setStream( stream );
|
|
||||||
m_xml.startElement( "Catch" );
|
m_xml.startElement( "Catch" );
|
||||||
if( !m_config->name().empty() )
|
if( !m_config->name().empty() )
|
||||||
m_xml.writeAttribute( "name", m_config->name() );
|
m_xml.writeAttribute( "name", m_config->name() );
|
||||||
@@ -53,7 +53,7 @@ namespace Catch {
|
|||||||
|
|
||||||
virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
|
virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
|
||||||
StreamingReporterBase::testCaseStarting(testInfo);
|
StreamingReporterBase::testCaseStarting(testInfo);
|
||||||
m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) );
|
m_xml.startElement( "TestCase" ).writeAttribute( "name", testInfo.name );
|
||||||
|
|
||||||
if ( m_config->showDurations() == ShowDurations::Always )
|
if ( m_config->showDurations() == ShowDurations::Always )
|
||||||
m_testCaseTimer.start();
|
m_testCaseTimer.start();
|
||||||
@@ -72,7 +72,7 @@ namespace Catch {
|
|||||||
|
|
||||||
virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
|
virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
|
||||||
const AssertionResult& assertionResult = assertionStats.assertionResult;
|
const AssertionResult& assertionResult = assertionStats.assertionResult;
|
||||||
|
|
||||||
// Print any info messages in <Info> tags.
|
// Print any info messages in <Info> tags.
|
||||||
if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
|
if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
|
||||||
for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
|
for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
|
||||||
@@ -115,7 +115,7 @@ namespace Catch {
|
|||||||
.writeText( assertionResult.getMessage() );
|
.writeText( assertionResult.getMessage() );
|
||||||
break;
|
break;
|
||||||
case ResultWas::FatalErrorCondition:
|
case ResultWas::FatalErrorCondition:
|
||||||
m_xml.scopedElement( "Fatal Error Condition" )
|
m_xml.scopedElement( "FatalErrorCondition" )
|
||||||
.writeAttribute( "filename", assertionResult.getSourceInfo().file )
|
.writeAttribute( "filename", assertionResult.getSourceInfo().file )
|
||||||
.writeAttribute( "line", assertionResult.getSourceInfo().line )
|
.writeAttribute( "line", assertionResult.getSourceInfo().line )
|
||||||
.writeText( assertionResult.getMessage() );
|
.writeText( assertionResult.getMessage() );
|
||||||
@@ -134,10 +134,10 @@ namespace Catch {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( assertionResult.hasExpression() )
|
if( assertionResult.hasExpression() )
|
||||||
m_xml.endElement();
|
m_xml.endElement();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,7 +176,7 @@ namespace Catch {
|
|||||||
.writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
|
.writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
|
||||||
m_xml.endElement();
|
m_xml.endElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
|
virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
|
||||||
StreamingReporterBase::testRunEnded( testRunStats );
|
StreamingReporterBase::testRunEnded( testRunStats );
|
||||||
m_xml.scopedElement( "OverallResults" )
|
m_xml.scopedElement( "OverallResults" )
|
||||||
|
@@ -7,31 +7,51 @@ get_filename_component(CATCH_DIR "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
|
|||||||
get_filename_component(CATCH_DIR "${CATCH_DIR}" PATH)
|
get_filename_component(CATCH_DIR "${CATCH_DIR}" PATH)
|
||||||
set(SELF_TEST_DIR ${CATCH_DIR}/projects/SelfTest)
|
set(SELF_TEST_DIR ${CATCH_DIR}/projects/SelfTest)
|
||||||
if(USE_CPP11)
|
if(USE_CPP11)
|
||||||
## We can't turn this on by default, since it breaks on travis
|
## We can't turn this on by default, since it breaks on travis
|
||||||
message(STATUS "Enabling C++11")
|
message(STATUS "Enabling C++11")
|
||||||
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
|
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# define the sources of the self test
|
# define the sources of the self test
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
${SELF_TEST_DIR}/ApproxTests.cpp
|
${SELF_TEST_DIR}/ApproxTests.cpp
|
||||||
${SELF_TEST_DIR}/BDDTests.cpp
|
${SELF_TEST_DIR}/BDDTests.cpp
|
||||||
${SELF_TEST_DIR}/ClassTests.cpp
|
${SELF_TEST_DIR}/ClassTests.cpp
|
||||||
${SELF_TEST_DIR}/ConditionTests.cpp
|
${SELF_TEST_DIR}/ConditionTests.cpp
|
||||||
${SELF_TEST_DIR}/ExceptionTests.cpp
|
${SELF_TEST_DIR}/ExceptionTests.cpp
|
||||||
${SELF_TEST_DIR}/GeneratorTests.cpp
|
${SELF_TEST_DIR}/GeneratorTests.cpp
|
||||||
${SELF_TEST_DIR}/MessageTests.cpp
|
${SELF_TEST_DIR}/MessageTests.cpp
|
||||||
${SELF_TEST_DIR}/MiscTests.cpp
|
${SELF_TEST_DIR}/MiscTests.cpp
|
||||||
${SELF_TEST_DIR}/SectionTrackerTests.cpp
|
${SELF_TEST_DIR}/PartTrackerTests.cpp
|
||||||
${SELF_TEST_DIR}/TestMain.cpp
|
${SELF_TEST_DIR}/TestMain.cpp
|
||||||
${SELF_TEST_DIR}/TrickyTests.cpp
|
${SELF_TEST_DIR}/TrickyTests.cpp
|
||||||
${SELF_TEST_DIR}/VariadicMacrosTests.cpp
|
${SELF_TEST_DIR}/VariadicMacrosTests.cpp
|
||||||
${SELF_TEST_DIR}/EnumToString.cpp
|
${SELF_TEST_DIR}/EnumToString.cpp
|
||||||
${SELF_TEST_DIR}/ToStringPair.cpp
|
${SELF_TEST_DIR}/ToStringPair.cpp
|
||||||
${SELF_TEST_DIR}/ToStringVector.cpp
|
${SELF_TEST_DIR}/ToStringVector.cpp
|
||||||
${SELF_TEST_DIR}/ToStringWhich.cpp
|
${SELF_TEST_DIR}/ToStringWhich.cpp
|
||||||
${SELF_TEST_DIR}/ToStringTuple.cpp
|
${SELF_TEST_DIR}/ToStringTuple.cpp
|
||||||
)
|
${SELF_TEST_DIR}/CmdLineTests.cpp
|
||||||
|
${SELF_TEST_DIR}/TagAliasTests.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_common.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_console_colour.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_debugger.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_capture.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_config.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_exception.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_generators.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_registry_hub.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_reporter.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_runner.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_testcase.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_message.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_option.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_ptr.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_stream.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_streambuf.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_test_spec.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_xmlwriter.cpp
|
||||||
|
)
|
||||||
|
|
||||||
# configure the executable
|
# configure the executable
|
||||||
include_directories(${CATCH_DIR}/include)
|
include_directories(${CATCH_DIR}/include)
|
||||||
|
@@ -16,7 +16,7 @@ TEST_CASE
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
double d = 1.23;
|
double d = 1.23;
|
||||||
|
|
||||||
REQUIRE( d == Approx( 1.23 ) );
|
REQUIRE( d == Approx( 1.23 ) );
|
||||||
REQUIRE( d != Approx( 1.22 ) );
|
REQUIRE( d != Approx( 1.22 ) );
|
||||||
REQUIRE( d != Approx( 1.24 ) );
|
REQUIRE( d != Approx( 1.24 ) );
|
||||||
@@ -34,7 +34,7 @@ TEST_CASE
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
double d = 1.23;
|
double d = 1.23;
|
||||||
|
|
||||||
REQUIRE( d != Approx( 1.231 ) );
|
REQUIRE( d != Approx( 1.231 ) );
|
||||||
REQUIRE( d == Approx( 1.231 ).epsilon( 0.1 ) );
|
REQUIRE( d == Approx( 1.231 ).epsilon( 0.1 ) );
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ TEST_CASE
|
|||||||
const double dZero = 0;
|
const double dZero = 0;
|
||||||
const double dSmall = 0.00001;
|
const double dSmall = 0.00001;
|
||||||
const double dMedium = 1.234;
|
const double dMedium = 1.234;
|
||||||
|
|
||||||
REQUIRE( 1.0f == Approx( 1 ) );
|
REQUIRE( 1.0f == Approx( 1 ) );
|
||||||
REQUIRE( 0 == Approx( dZero) );
|
REQUIRE( 0 == Approx( dZero) );
|
||||||
REQUIRE( 0 == Approx( dSmall ).epsilon( 0.001 ) );
|
REQUIRE( 0 == Approx( dSmall ).epsilon( 0.001 ) );
|
||||||
@@ -87,14 +87,14 @@ TEST_CASE
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
double d = 1.23;
|
double d = 1.23;
|
||||||
|
|
||||||
Approx approx = Approx::custom().epsilon( 0.005 );
|
Approx approx = Approx::custom().epsilon( 0.005 );
|
||||||
|
|
||||||
REQUIRE( d == approx( 1.23 ) );
|
REQUIRE( d == approx( 1.23 ) );
|
||||||
REQUIRE( d == approx( 1.22 ) );
|
REQUIRE( d == approx( 1.22 ) );
|
||||||
REQUIRE( d == approx( 1.24 ) );
|
REQUIRE( d == approx( 1.24 ) );
|
||||||
REQUIRE( d != approx( 1.25 ) );
|
REQUIRE( d != approx( 1.25 ) );
|
||||||
|
|
||||||
REQUIRE( approx( d ) == 1.23 );
|
REQUIRE( approx( d ) == 1.23 );
|
||||||
REQUIRE( approx( d ) == 1.22 );
|
REQUIRE( approx( d ) == 1.22 );
|
||||||
REQUIRE( approx( d ) == 1.24 );
|
REQUIRE( approx( d ) == 1.24 );
|
||||||
|
@@ -30,13 +30,13 @@ SCENARIO( "Vector resizing affects size and capacity", "[vector][bdd][size][capa
|
|||||||
GIVEN( "an empty vector" ) {
|
GIVEN( "an empty vector" ) {
|
||||||
std::vector<int> v;
|
std::vector<int> v;
|
||||||
REQUIRE( v.size() == 0 );
|
REQUIRE( v.size() == 0 );
|
||||||
|
|
||||||
WHEN( "it is made larger" ) {
|
WHEN( "it is made larger" ) {
|
||||||
v.resize( 10 );
|
v.resize( 10 );
|
||||||
THEN( "the size and capacity go up" ) {
|
THEN( "the size and capacity go up" ) {
|
||||||
REQUIRE( v.size() == 10 );
|
REQUIRE( v.size() == 10 );
|
||||||
REQUIRE( v.capacity() >= 10 );
|
REQUIRE( v.capacity() >= 10 );
|
||||||
|
|
||||||
AND_WHEN( "it is made smaller again" ) {
|
AND_WHEN( "it is made smaller again" ) {
|
||||||
v.resize( 5 );
|
v.resize( 5 );
|
||||||
THEN( "the size goes down but the capacity stays the same" ) {
|
THEN( "the size goes down but the capacity stays the same" ) {
|
||||||
@@ -46,7 +46,7 @@ SCENARIO( "Vector resizing affects size and capacity", "[vector][bdd][size][capa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WHEN( "we reserve more space" ) {
|
WHEN( "we reserve more space" ) {
|
||||||
v.reserve( 10 );
|
v.reserve( 10 );
|
||||||
THEN( "The capacity is increased but the size remains the same" ) {
|
THEN( "The capacity is increased but the size remains the same" ) {
|
||||||
@@ -76,19 +76,19 @@ struct Fixture
|
|||||||
: d_counter(0)
|
: d_counter(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int counter()
|
int counter()
|
||||||
{
|
{
|
||||||
return d_counter++;
|
return d_counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int d_counter;
|
int d_counter;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SCENARIO_METHOD(Fixture,
|
SCENARIO_METHOD(Fixture,
|
||||||
"BDD tests requiring Fixtures to provide commonly-accessed data or methods",
|
"BDD tests requiring Fixtures to provide commonly-accessed data or methods",
|
||||||
"[bdd][fixtures]") {
|
"[bdd][fixtures]") {
|
||||||
const int before(counter());
|
const int before(counter());
|
||||||
GIVEN("No operations precede me") {
|
GIVEN("No operations precede me") {
|
||||||
|
@@ -3,6 +3,46 @@
|
|||||||
CatchSelfTest is a <version> host application.
|
CatchSelfTest is a <version> host application.
|
||||||
Run with -? for options
|
Run with -? for options
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
'Not' checks that should fail
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
ConditionTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
ConditionTests.cpp:<line number>: FAILED:
|
||||||
|
CHECK( false != false )
|
||||||
|
|
||||||
|
ConditionTests.cpp:<line number>: FAILED:
|
||||||
|
CHECK( true != true )
|
||||||
|
|
||||||
|
ConditionTests.cpp:<line number>: FAILED:
|
||||||
|
CHECK( !true )
|
||||||
|
with expansion:
|
||||||
|
false
|
||||||
|
|
||||||
|
ConditionTests.cpp:<line number>: FAILED:
|
||||||
|
CHECK_FALSE( true )
|
||||||
|
|
||||||
|
ConditionTests.cpp:<line number>: FAILED:
|
||||||
|
CHECK( !trueValue )
|
||||||
|
with expansion:
|
||||||
|
false
|
||||||
|
|
||||||
|
ConditionTests.cpp:<line number>: FAILED:
|
||||||
|
CHECK_FALSE( trueValue )
|
||||||
|
with expansion:
|
||||||
|
!true
|
||||||
|
|
||||||
|
ConditionTests.cpp:<line number>: FAILED:
|
||||||
|
CHECK( !(1 == 1) )
|
||||||
|
with expansion:
|
||||||
|
false
|
||||||
|
|
||||||
|
ConditionTests.cpp:<line number>: FAILED:
|
||||||
|
CHECK_FALSE( 1 == 1 )
|
||||||
|
with expansion:
|
||||||
|
!(1 == 1)
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
A METHOD_AS_TEST_CASE based test run that fails
|
A METHOD_AS_TEST_CASE based test run that fails
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -25,6 +65,97 @@ ClassTests.cpp:<line number>: FAILED:
|
|||||||
with expansion:
|
with expansion:
|
||||||
1 == 2
|
1 == 2
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
A couple of nested sections followed by a failure
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
MiscTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
MiscTests.cpp:<line number>: FAILED:
|
||||||
|
explicitly with message:
|
||||||
|
to infinity and beyond
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
A failing expression with a non streamable type is still captured
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
TrickyTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
TrickyTests.cpp:<line number>: FAILED:
|
||||||
|
CHECK( &o1 == &o2 )
|
||||||
|
with expansion:
|
||||||
|
0x<hex digits> == 0x<hex digits>
|
||||||
|
|
||||||
|
TrickyTests.cpp:<line number>: FAILED:
|
||||||
|
CHECK( o1 == o2 )
|
||||||
|
with expansion:
|
||||||
|
{?} == {?}
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
An unchecked exception reports the line of the last assertion
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
ExceptionTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
ExceptionTests.cpp:<line number>: FAILED:
|
||||||
|
{Unknown expression after the reported line}
|
||||||
|
due to unexpected exception with message:
|
||||||
|
unexpected exception
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Contains string matcher
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
MiscTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
MiscTests.cpp:<line number>: FAILED:
|
||||||
|
CHECK_THAT( testStringForMatching(), Contains( "not there" ) )
|
||||||
|
with expansion:
|
||||||
|
"this string contains 'abc' as a substring" contains: "not there"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Custom exceptions can be translated when testing for nothrow
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
ExceptionTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
ExceptionTests.cpp:<line number>: FAILED:
|
||||||
|
REQUIRE_NOTHROW( throwCustom() )
|
||||||
|
due to unexpected exception with message:
|
||||||
|
custom exception - not std
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Custom exceptions can be translated when testing for throwing as something else
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
ExceptionTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
ExceptionTests.cpp:<line number>: FAILED:
|
||||||
|
REQUIRE_THROWS_AS( throwCustom() )
|
||||||
|
due to unexpected exception with message:
|
||||||
|
custom exception - not std
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Custom std-exceptions can be custom translated
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
ExceptionTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
ExceptionTests.cpp:<line number>: FAILED:
|
||||||
|
due to unexpected exception with message:
|
||||||
|
custom std exception
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
EndsWith string matcher
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
MiscTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
MiscTests.cpp:<line number>: FAILED:
|
||||||
|
CHECK_THAT( testStringForMatching(), EndsWith( "this" ) )
|
||||||
|
with expansion:
|
||||||
|
"this string contains 'abc' as a substring" ends with: "this"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Equality checks that should fail
|
Equality checks that should fail
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -96,6 +227,100 @@ ConditionTests.cpp:<line number>: FAILED:
|
|||||||
with expansion:
|
with expansion:
|
||||||
1.3 == Approx( 1.301 )
|
1.3 == Approx( 1.301 )
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Equals string matcher
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
MiscTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
MiscTests.cpp:<line number>: FAILED:
|
||||||
|
CHECK_THAT( testStringForMatching(), Equals( "something else" ) )
|
||||||
|
with expansion:
|
||||||
|
"this string contains 'abc' as a substring" equals: "something else"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Expected exceptions that don't throw or unexpected exceptions fail the test
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
ExceptionTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
ExceptionTests.cpp:<line number>: FAILED:
|
||||||
|
CHECK_THROWS_AS( thisThrows() )
|
||||||
|
due to unexpected exception with message:
|
||||||
|
expected exception
|
||||||
|
|
||||||
|
ExceptionTests.cpp:<line number>: FAILED:
|
||||||
|
CHECK_THROWS_AS( thisDoesntThrow() )
|
||||||
|
because no exception was thrown where one was expected:
|
||||||
|
|
||||||
|
ExceptionTests.cpp:<line number>: FAILED:
|
||||||
|
CHECK_NOTHROW( thisThrows() )
|
||||||
|
due to unexpected exception with message:
|
||||||
|
expected exception
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
FAIL aborts the test
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
MessageTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
MessageTests.cpp:<line number>: FAILED:
|
||||||
|
explicitly with message:
|
||||||
|
This is a failure
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
FAIL does not require an argument
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
MessageTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
MessageTests.cpp:<line number>: FAILED:
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
INFO and WARN do not abort tests
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
MessageTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
MessageTests.cpp:<line number>:
|
||||||
|
warning:
|
||||||
|
this is a warning
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
INFO gets logged on failure
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
MessageTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
MessageTests.cpp:<line number>: FAILED:
|
||||||
|
REQUIRE( a == 1 )
|
||||||
|
with expansion:
|
||||||
|
2 == 1
|
||||||
|
with messages:
|
||||||
|
this message should be logged
|
||||||
|
so should this
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
INFO gets logged on failure, even if captured before successful assertions
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
MessageTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
MessageTests.cpp:<line number>: FAILED:
|
||||||
|
CHECK( a == 1 )
|
||||||
|
with expansion:
|
||||||
|
2 == 1
|
||||||
|
with messages:
|
||||||
|
this message may be logged later
|
||||||
|
this message should be logged
|
||||||
|
|
||||||
|
MessageTests.cpp:<line number>: FAILED:
|
||||||
|
CHECK( a == 0 )
|
||||||
|
with expansion:
|
||||||
|
2 == 0
|
||||||
|
with message:
|
||||||
|
and this, but later
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Inequality checks that should fail
|
Inequality checks that should fail
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -127,6 +352,60 @@ ConditionTests.cpp:<line number>: FAILED:
|
|||||||
with expansion:
|
with expansion:
|
||||||
5 != 5
|
5 != 5
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Matchers can be composed with both && and || - failing
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
MiscTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
MiscTests.cpp:<line number>: FAILED:
|
||||||
|
CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "random" ) )
|
||||||
|
with expansion:
|
||||||
|
"this string contains 'abc' as a substring" ( ( contains: "string" or
|
||||||
|
contains: "different" ) and contains: "random" )
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Matchers can be negated (Not) with the ! operator - failing
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
MiscTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
MiscTests.cpp:<line number>: FAILED:
|
||||||
|
CHECK_THAT( testStringForMatching(), !Contains( "substring" ) )
|
||||||
|
with expansion:
|
||||||
|
"this string contains 'abc' as a substring" not contains: "substring"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Mismatching exception messages failing the test
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
ExceptionTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
ExceptionTests.cpp:<line number>: FAILED:
|
||||||
|
REQUIRE_THROWS_WITH( thisThrows(), "should fail" )
|
||||||
|
with expansion:
|
||||||
|
expected exception
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Nice descriptive name
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
MiscTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
MiscTests.cpp:<line number>:
|
||||||
|
warning:
|
||||||
|
This one ran
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Non-std exceptions can be translated
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
ExceptionTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
ExceptionTests.cpp:<line number>: FAILED:
|
||||||
|
due to unexpected exception with message:
|
||||||
|
custom exception
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Ordering comparison checks that should fail
|
Ordering comparison checks that should fail
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -229,64 +508,99 @@ with expansion:
|
|||||||
"hello" <= "a"
|
"hello" <= "a"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
'Not' checks that should fail
|
Output from all sections is reported
|
||||||
|
one
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
ConditionTests.cpp:<line number>
|
MessageTests.cpp:<line number>
|
||||||
...............................................................................
|
...............................................................................
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>: FAILED:
|
MessageTests.cpp:<line number>: FAILED:
|
||||||
CHECK( false != false )
|
explicitly with message:
|
||||||
|
Message from section one
|
||||||
ConditionTests.cpp:<line number>: FAILED:
|
|
||||||
CHECK( true != true )
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>: FAILED:
|
|
||||||
CHECK( !true )
|
|
||||||
with expansion:
|
|
||||||
false
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>: FAILED:
|
|
||||||
CHECK_FALSE( true )
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>: FAILED:
|
|
||||||
CHECK( !trueValue )
|
|
||||||
with expansion:
|
|
||||||
false
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>: FAILED:
|
|
||||||
CHECK_FALSE( trueValue )
|
|
||||||
with expansion:
|
|
||||||
!true
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>: FAILED:
|
|
||||||
CHECK( !(1 == 1) )
|
|
||||||
with expansion:
|
|
||||||
false
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>: FAILED:
|
|
||||||
CHECK_FALSE( 1 == 1 )
|
|
||||||
with expansion:
|
|
||||||
!(1 == 1)
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Expected exceptions that don't throw or unexpected exceptions fail the test
|
Output from all sections is reported
|
||||||
|
two
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
MessageTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
MessageTests.cpp:<line number>: FAILED:
|
||||||
|
explicitly with message:
|
||||||
|
Message from section two
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Pointers can be converted to strings
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
MessageTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
MessageTests.cpp:<line number>:
|
||||||
|
warning:
|
||||||
|
actual address of p: 0x<hex digits>
|
||||||
|
|
||||||
|
MessageTests.cpp:<line number>:
|
||||||
|
warning:
|
||||||
|
toString(p): 0x<hex digits>
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
SCOPED_INFO is reset for each loop
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
MessageTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
MessageTests.cpp:<line number>: FAILED:
|
||||||
|
REQUIRE( i < 10 )
|
||||||
|
with expansion:
|
||||||
|
10 < 10
|
||||||
|
with messages:
|
||||||
|
current counter 10
|
||||||
|
i := 10
|
||||||
|
|
||||||
|
A string sent directly to stdout
|
||||||
|
A string sent directly to stderr
|
||||||
|
Message from section one
|
||||||
|
Message from section two
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
StartsWith string matcher
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
MiscTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
MiscTests.cpp:<line number>: FAILED:
|
||||||
|
CHECK_THAT( testStringForMatching(), StartsWith( "string" ) )
|
||||||
|
with expansion:
|
||||||
|
"this string contains 'abc' as a substring" starts with: "string"
|
||||||
|
|
||||||
|
hello
|
||||||
|
hello
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Tabs and newlines show in output
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
MiscTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
MiscTests.cpp:<line number>: FAILED:
|
||||||
|
CHECK( s1 == s2 )
|
||||||
|
with expansion:
|
||||||
|
"if ($b == 10) {
|
||||||
|
$a= 20;
|
||||||
|
}"
|
||||||
|
==
|
||||||
|
"if ($b == 10) {
|
||||||
|
$a = 20;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Unexpected exceptions can be translated
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
ExceptionTests.cpp:<line number>
|
ExceptionTests.cpp:<line number>
|
||||||
...............................................................................
|
...............................................................................
|
||||||
|
|
||||||
ExceptionTests.cpp:<line number>: FAILED:
|
ExceptionTests.cpp:<line number>: FAILED:
|
||||||
CHECK_THROWS_AS( thisThrows() )
|
|
||||||
due to unexpected exception with message:
|
due to unexpected exception with message:
|
||||||
expected exception
|
3.14
|
||||||
|
|
||||||
ExceptionTests.cpp:<line number>: FAILED:
|
|
||||||
CHECK_THROWS_AS( thisDoesntThrow() )
|
|
||||||
because no exception was thrown where one was expected:
|
|
||||||
|
|
||||||
ExceptionTests.cpp:<line number>: FAILED:
|
|
||||||
CHECK_NOTHROW( thisThrows() )
|
|
||||||
due to unexpected exception with message:
|
|
||||||
expected exception
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
When unchecked exceptions are thrown directly they are always failures
|
When unchecked exceptions are thrown directly they are always failures
|
||||||
@@ -299,29 +613,8 @@ due to unexpected exception with message:
|
|||||||
unexpected exception
|
unexpected exception
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
An unchecked exception reports the line of the last assertion
|
When unchecked exceptions are thrown during a CHECK the test should abort and
|
||||||
-------------------------------------------------------------------------------
|
fail
|
||||||
ExceptionTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
ExceptionTests.cpp:<line number>: FAILED:
|
|
||||||
{Unknown expression after the reported line}
|
|
||||||
due to unexpected exception with message:
|
|
||||||
unexpected exception
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
When unchecked exceptions are thrown from sections they are always failures
|
|
||||||
section name
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
ExceptionTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
ExceptionTests.cpp:<line number>: FAILED:
|
|
||||||
due to unexpected exception with message:
|
|
||||||
unexpected exception
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
When unchecked exceptions are thrown from functions they are always failures
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
ExceptionTests.cpp:<line number>
|
ExceptionTests.cpp:<line number>
|
||||||
...............................................................................
|
...............................................................................
|
||||||
@@ -344,8 +637,7 @@ due to unexpected exception with message:
|
|||||||
expected exception
|
expected exception
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
When unchecked exceptions are thrown during a CHECK the test should abort and
|
When unchecked exceptions are thrown from functions they are always failures
|
||||||
fail
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
ExceptionTests.cpp:<line number>
|
ExceptionTests.cpp:<line number>
|
||||||
...............................................................................
|
...............................................................................
|
||||||
@@ -356,158 +648,69 @@ due to unexpected exception with message:
|
|||||||
expected exception
|
expected exception
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Unexpected custom exceptions can be translated
|
When unchecked exceptions are thrown from sections they are always failures
|
||||||
|
section name
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
ExceptionTests.cpp:<line number>
|
ExceptionTests.cpp:<line number>
|
||||||
...............................................................................
|
...............................................................................
|
||||||
|
|
||||||
ExceptionTests.cpp:<line number>: FAILED:
|
ExceptionTests.cpp:<line number>: FAILED:
|
||||||
due to unexpected exception with message:
|
due to unexpected exception with message:
|
||||||
custom exception
|
unexpected exception
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Custom exceptions can be translated when testing for nothrow
|
Where the LHS is not a simple value
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
ExceptionTests.cpp:<line number>
|
TrickyTests.cpp:<line number>
|
||||||
...............................................................................
|
...............................................................................
|
||||||
|
|
||||||
ExceptionTests.cpp:<line number>: FAILED:
|
TrickyTests.cpp:<line number>:
|
||||||
REQUIRE_NOTHROW( throwCustom() )
|
|
||||||
due to unexpected exception with message:
|
|
||||||
custom exception - not std
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Custom exceptions can be translated when testing for throwing as something else
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
ExceptionTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
ExceptionTests.cpp:<line number>: FAILED:
|
|
||||||
REQUIRE_THROWS_AS( throwCustom() )
|
|
||||||
due to unexpected exception with message:
|
|
||||||
custom exception - not std
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Unexpected exceptions can be translated
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
ExceptionTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
ExceptionTests.cpp:<line number>: FAILED:
|
|
||||||
due to unexpected exception with message:
|
|
||||||
3.14
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Mismatching exception messages failing the test
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
ExceptionTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
ExceptionTests.cpp:<line number>: FAILED:
|
|
||||||
REQUIRE_THROWS_WITH( thisThrows(), "should fail" )
|
|
||||||
with expansion:
|
|
||||||
expected exception
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
INFO and WARN do not abort tests
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
MessageTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
MessageTests.cpp:<line number>:
|
|
||||||
warning:
|
warning:
|
||||||
this is a warning
|
Uncomment the code in this test to check that it gives a sensible compiler
|
||||||
|
error
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
INFO gets logged on failure
|
Where there is more to the expression after the RHS
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
MessageTests.cpp:<line number>
|
TrickyTests.cpp:<line number>
|
||||||
...............................................................................
|
...............................................................................
|
||||||
|
|
||||||
MessageTests.cpp:<line number>: FAILED:
|
TrickyTests.cpp:<line number>:
|
||||||
REQUIRE( a == 1 )
|
warning:
|
||||||
|
Uncomment the code in this test to check that it gives a sensible compiler
|
||||||
|
error
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
checkedElse, failing
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
MiscTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
MiscTests.cpp:<line number>: FAILED:
|
||||||
|
CHECKED_ELSE( flag )
|
||||||
with expansion:
|
with expansion:
|
||||||
2 == 1
|
false
|
||||||
with messages:
|
|
||||||
this message should be logged
|
|
||||||
so should this
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
MiscTests.cpp:<line number>: FAILED:
|
||||||
INFO gets logged on failure, even if captured before successful assertions
|
REQUIRE( testCheckedElse( false ) )
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
MessageTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
MessageTests.cpp:<line number>: FAILED:
|
|
||||||
CHECK( a == 1 )
|
|
||||||
with expansion:
|
with expansion:
|
||||||
2 == 1
|
false
|
||||||
with messages:
|
|
||||||
this message may be logged later
|
|
||||||
this message should be logged
|
|
||||||
|
|
||||||
MessageTests.cpp:<line number>: FAILED:
|
-------------------------------------------------------------------------------
|
||||||
CHECK( a == 0 )
|
checkedIf, failing
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
MiscTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
MiscTests.cpp:<line number>: FAILED:
|
||||||
|
CHECKED_IF( flag )
|
||||||
with expansion:
|
with expansion:
|
||||||
2 == 0
|
false
|
||||||
with message:
|
|
||||||
and this, but later
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
MiscTests.cpp:<line number>: FAILED:
|
||||||
FAIL aborts the test
|
REQUIRE( testCheckedIf( false ) )
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
MessageTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
MessageTests.cpp:<line number>: FAILED:
|
|
||||||
explicitly with message:
|
|
||||||
This is a failure
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
FAIL does not require an argument
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
MessageTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
MessageTests.cpp:<line number>: FAILED:
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Output from all sections is reported
|
|
||||||
one
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
MessageTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
MessageTests.cpp:<line number>: FAILED:
|
|
||||||
explicitly with message:
|
|
||||||
Message from section one
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Output from all sections is reported
|
|
||||||
two
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
MessageTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
MessageTests.cpp:<line number>: FAILED:
|
|
||||||
explicitly with message:
|
|
||||||
Message from section two
|
|
||||||
|
|
||||||
Message from section one
|
|
||||||
Message from section two
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
SCOPED_INFO is reset for each loop
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
MessageTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
MessageTests.cpp:<line number>: FAILED:
|
|
||||||
REQUIRE( i < 10 )
|
|
||||||
with expansion:
|
with expansion:
|
||||||
10 < 10
|
false
|
||||||
with messages:
|
|
||||||
current counter 10
|
|
||||||
i := 10
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
just failure
|
just failure
|
||||||
@@ -519,45 +722,6 @@ MessageTests.cpp:<line number>: FAILED:
|
|||||||
explicitly with message:
|
explicitly with message:
|
||||||
Previous info should not be seen
|
Previous info should not be seen
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
sends information to INFO
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
MessageTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
MessageTests.cpp:<line number>: FAILED:
|
|
||||||
REQUIRE( false )
|
|
||||||
with messages:
|
|
||||||
hi
|
|
||||||
i := 7
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Pointers can be converted to strings
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
MessageTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
MessageTests.cpp:<line number>:
|
|
||||||
warning:
|
|
||||||
actual address of p: 0x<hex digits>
|
|
||||||
|
|
||||||
MessageTests.cpp:<line number>:
|
|
||||||
warning:
|
|
||||||
toString(p): 0x<hex digits>
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
more nested SECTION tests
|
|
||||||
s1
|
|
||||||
s2
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
MiscTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
MiscTests.cpp:<line number>: FAILED:
|
|
||||||
REQUIRE( a == b )
|
|
||||||
with expansion:
|
|
||||||
1 == 2
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
looped SECTION tests
|
looped SECTION tests
|
||||||
s1
|
s1
|
||||||
@@ -618,39 +782,18 @@ with expansion:
|
|||||||
with message:
|
with message:
|
||||||
Testing if fib[7] (21) is even
|
Testing if fib[7] (21) is even
|
||||||
|
|
||||||
A string sent directly to stdout
|
|
||||||
A string sent directly to stderr
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
checkedIf, failing
|
more nested SECTION tests
|
||||||
|
s1
|
||||||
|
s2
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
MiscTests.cpp:<line number>
|
MiscTests.cpp:<line number>
|
||||||
...............................................................................
|
...............................................................................
|
||||||
|
|
||||||
MiscTests.cpp:<line number>: FAILED:
|
MiscTests.cpp:<line number>: FAILED:
|
||||||
CHECKED_IF( flag )
|
REQUIRE( a == b )
|
||||||
with expansion:
|
with expansion:
|
||||||
false
|
1 == 2
|
||||||
|
|
||||||
MiscTests.cpp:<line number>: FAILED:
|
|
||||||
REQUIRE( testCheckedIf( false ) )
|
|
||||||
with expansion:
|
|
||||||
false
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
checkedElse, failing
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
MiscTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
MiscTests.cpp:<line number>: FAILED:
|
|
||||||
CHECKED_ELSE( flag )
|
|
||||||
with expansion:
|
|
||||||
false
|
|
||||||
|
|
||||||
MiscTests.cpp:<line number>: FAILED:
|
|
||||||
REQUIRE( testCheckedElse( false ) )
|
|
||||||
with expansion:
|
|
||||||
false
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
send a single char to INFO
|
send a single char to INFO
|
||||||
@@ -664,126 +807,16 @@ with message:
|
|||||||
3
|
3
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Contains string matcher
|
sends information to INFO
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
MiscTests.cpp:<line number>
|
MessageTests.cpp:<line number>
|
||||||
...............................................................................
|
...............................................................................
|
||||||
|
|
||||||
MiscTests.cpp:<line number>: FAILED:
|
MessageTests.cpp:<line number>: FAILED:
|
||||||
CHECK_THAT( testStringForMatching() Contains( "not there" ) )
|
REQUIRE( false )
|
||||||
with expansion:
|
with messages:
|
||||||
"this string contains 'abc' as a substring" contains: "not there"
|
hi
|
||||||
|
i := 7
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
StartsWith string matcher
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
MiscTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
MiscTests.cpp:<line number>: FAILED:
|
|
||||||
CHECK_THAT( testStringForMatching() StartsWith( "string" ) )
|
|
||||||
with expansion:
|
|
||||||
"this string contains 'abc' as a substring" starts with: "string"
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
EndsWith string matcher
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
MiscTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
MiscTests.cpp:<line number>: FAILED:
|
|
||||||
CHECK_THAT( testStringForMatching() EndsWith( "this" ) )
|
|
||||||
with expansion:
|
|
||||||
"this string contains 'abc' as a substring" ends with: "this"
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Equals string matcher
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
MiscTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
MiscTests.cpp:<line number>: FAILED:
|
|
||||||
CHECK_THAT( testStringForMatching() Equals( "something else" ) )
|
|
||||||
with expansion:
|
|
||||||
"this string contains 'abc' as a substring" equals: "something else"
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Nice descriptive name
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
MiscTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
MiscTests.cpp:<line number>:
|
|
||||||
warning:
|
|
||||||
This one ran
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
A couple of nested sections followed by a failure
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
MiscTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
MiscTests.cpp:<line number>: FAILED:
|
|
||||||
explicitly with message:
|
|
||||||
to infinity and beyond
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Tabs and newlines show in output
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
MiscTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
MiscTests.cpp:<line number>: FAILED:
|
|
||||||
CHECK( s1 == s2 )
|
|
||||||
with expansion:
|
|
||||||
"if ($b == 10) {
|
|
||||||
$a= 20;
|
|
||||||
}"
|
|
||||||
==
|
|
||||||
"if ($b == 10) {
|
|
||||||
$a = 20;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
|
|
||||||
hello
|
|
||||||
hello
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Where there is more to the expression after the RHS
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
TrickyTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
TrickyTests.cpp:<line number>:
|
|
||||||
warning:
|
|
||||||
Uncomment the code in this test to check that it gives a sensible compiler
|
|
||||||
error
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Where the LHS is not a simple value
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
TrickyTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
TrickyTests.cpp:<line number>:
|
|
||||||
warning:
|
|
||||||
Uncomment the code in this test to check that it gives a sensible compiler
|
|
||||||
error
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
A failing expression with a non streamable type is still captured
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
TrickyTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
TrickyTests.cpp:<line number>: FAILED:
|
|
||||||
CHECK( &o1 == &o2 )
|
|
||||||
with expansion:
|
|
||||||
0x<hex digits> == 0x<hex digits>
|
|
||||||
|
|
||||||
TrickyTests.cpp:<line number>: FAILED:
|
|
||||||
CHECK( o1 == o2 )
|
|
||||||
with expansion:
|
|
||||||
{?} == {?}
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
string literals of different sizes can be compared
|
string literals of different sizes can be compared
|
||||||
@@ -797,6 +830,6 @@ with expansion:
|
|||||||
"first" == "second"
|
"first" == "second"
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
test cases: 159 | 119 passed | 39 failed | 1 failed as expected
|
test cases: 169 | 125 passed | 42 failed | 2 failed as expected
|
||||||
assertions: 788 | 695 passed | 80 failed | 13 failed as expected
|
assertions: 921 | 825 passed | 78 failed | 18 failed as expected
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -4,488 +4,37 @@ CatchSelfTest is a <version> host application.
|
|||||||
Run with -? for options
|
Run with -? for options
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
toString(enum)
|
# A test name that starts with a #
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
EnumToString.cpp:<line number>
|
MiscTests.cpp:<line number>
|
||||||
...............................................................................
|
...............................................................................
|
||||||
|
|
||||||
EnumToString.cpp:<line number>:
|
MiscTests.cpp:<line number>:
|
||||||
PASSED:
|
PASSED:
|
||||||
CHECK( Catch::toString(e0) == "0" )
|
with message:
|
||||||
with expansion:
|
yay
|
||||||
"0" == "0"
|
|
||||||
|
|
||||||
EnumToString.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
CHECK( Catch::toString(e1) == "1" )
|
|
||||||
with expansion:
|
|
||||||
"1" == "1"
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
toString(enum w/operator<<)
|
'Not' checks that should fail
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
EnumToString.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
EnumToString.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
CHECK( Catch::toString(e0) == "E2{0}" )
|
|
||||||
with expansion:
|
|
||||||
"E2{0}" == "E2{0}"
|
|
||||||
|
|
||||||
EnumToString.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
CHECK( Catch::toString(e1) == "E2{1}" )
|
|
||||||
with expansion:
|
|
||||||
"E2{1}" == "E2{1}"
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
toString(enum class)
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
EnumToString.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
EnumToString.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
CHECK( Catch::toString(e0) == "0" )
|
|
||||||
with expansion:
|
|
||||||
"0" == "0"
|
|
||||||
|
|
||||||
EnumToString.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
CHECK( Catch::toString(e1) == "1" )
|
|
||||||
with expansion:
|
|
||||||
"1" == "1"
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
toString(enum class w/operator<<)
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
EnumToString.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
EnumToString.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
CHECK( Catch::toString(e0) == "E2/V0" )
|
|
||||||
with expansion:
|
|
||||||
"E2/V0" == "E2/V0"
|
|
||||||
|
|
||||||
EnumToString.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
CHECK( Catch::toString(e1) == "E2/V1" )
|
|
||||||
with expansion:
|
|
||||||
"E2/V1" == "E2/V1"
|
|
||||||
|
|
||||||
EnumToString.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
CHECK( Catch::toString(e3) == "Unknown enum value 10" )
|
|
||||||
with expansion:
|
|
||||||
"Unknown enum value 10"
|
|
||||||
==
|
|
||||||
"Unknown enum value 10"
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Some simple comparisons between doubles
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
ApproxTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( d == Approx( 1.23 ) )
|
|
||||||
with expansion:
|
|
||||||
1.23 == Approx( 1.23 )
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( d != Approx( 1.22 ) )
|
|
||||||
with expansion:
|
|
||||||
1.23 != Approx( 1.22 )
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( d != Approx( 1.24 ) )
|
|
||||||
with expansion:
|
|
||||||
1.23 != Approx( 1.24 )
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( Approx( d ) == 1.23 )
|
|
||||||
with expansion:
|
|
||||||
Approx( 1.23 ) == 1.23
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( Approx( d ) != 1.22 )
|
|
||||||
with expansion:
|
|
||||||
Approx( 1.23 ) != 1.22
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( Approx( d ) != 1.24 )
|
|
||||||
with expansion:
|
|
||||||
Approx( 1.23 ) != 1.24
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Approximate comparisons with different epsilons
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
ApproxTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( d != Approx( 1.231 ) )
|
|
||||||
with expansion:
|
|
||||||
1.23 != Approx( 1.231 )
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( d == Approx( 1.231 ).epsilon( 0.1 ) )
|
|
||||||
with expansion:
|
|
||||||
1.23 == Approx( 1.231 )
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Approximate comparisons with floats
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
ApproxTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( 1.23f == Approx( 1.23f ) )
|
|
||||||
with expansion:
|
|
||||||
1.23f == Approx( 1.2300000191 )
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( 0.0f == Approx( 0.0f ) )
|
|
||||||
with expansion:
|
|
||||||
0.0f == Approx( 0.0 )
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Approximate comparisons with ints
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
ApproxTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( 1 == Approx( 1 ) )
|
|
||||||
with expansion:
|
|
||||||
1 == Approx( 1.0 )
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( 0 == Approx( 0 ) )
|
|
||||||
with expansion:
|
|
||||||
0 == Approx( 0.0 )
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Approximate comparisons with mixed numeric types
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
ApproxTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( 1.0f == Approx( 1 ) )
|
|
||||||
with expansion:
|
|
||||||
1.0f == Approx( 1.0 )
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( 0 == Approx( dZero) )
|
|
||||||
with expansion:
|
|
||||||
0 == Approx( 0.0 )
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( 0 == Approx( dSmall ).epsilon( 0.001 ) )
|
|
||||||
with expansion:
|
|
||||||
0 == Approx( 0.00001 )
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( 1.234f == Approx( dMedium ) )
|
|
||||||
with expansion:
|
|
||||||
1.234f == Approx( 1.234 )
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( dMedium == Approx( 1.234f ) )
|
|
||||||
with expansion:
|
|
||||||
1.234 == Approx( 1.2339999676 )
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Use a custom approx
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
ApproxTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( d == approx( 1.23 ) )
|
|
||||||
with expansion:
|
|
||||||
1.23 == Approx( 1.23 )
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( d == approx( 1.22 ) )
|
|
||||||
with expansion:
|
|
||||||
1.23 == Approx( 1.22 )
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( d == approx( 1.24 ) )
|
|
||||||
with expansion:
|
|
||||||
1.23 == Approx( 1.24 )
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( d != approx( 1.25 ) )
|
|
||||||
with expansion:
|
|
||||||
1.23 != Approx( 1.25 )
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( approx( d ) == 1.23 )
|
|
||||||
with expansion:
|
|
||||||
Approx( 1.23 ) == 1.23
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( approx( d ) == 1.22 )
|
|
||||||
with expansion:
|
|
||||||
Approx( 1.23 ) == 1.22
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( approx( d ) == 1.24 )
|
|
||||||
with expansion:
|
|
||||||
Approx( 1.23 ) == 1.24
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( approx( d ) != 1.25 )
|
|
||||||
with expansion:
|
|
||||||
Approx( 1.23 ) != 1.25
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Approximate PI
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
ApproxTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 ) )
|
|
||||||
with expansion:
|
|
||||||
3.1428571429 == Approx( 3.141 )
|
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 ) )
|
|
||||||
with expansion:
|
|
||||||
3.1428571429 != Approx( 3.141 )
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
A METHOD_AS_TEST_CASE based test run that succeeds
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
ClassTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
ClassTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( s == "hello" )
|
|
||||||
with expansion:
|
|
||||||
"hello" == "hello"
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
A METHOD_AS_TEST_CASE based test run that fails
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
ClassTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
ClassTests.cpp:<line number>: FAILED:
|
|
||||||
REQUIRE( s == "world" )
|
|
||||||
with expansion:
|
|
||||||
"hello" == "world"
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
A TEST_CASE_METHOD based test run that succeeds
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
ClassTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
ClassTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( m_a == 1 )
|
|
||||||
with expansion:
|
|
||||||
1 == 1
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
A TEST_CASE_METHOD based test run that fails
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
ClassTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
ClassTests.cpp:<line number>: FAILED:
|
|
||||||
REQUIRE( m_a == 2 )
|
|
||||||
with expansion:
|
|
||||||
1 == 2
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Equality checks that should succeed
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
ConditionTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( data.int_seven == 7 )
|
|
||||||
with expansion:
|
|
||||||
7 == 7
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( data.float_nine_point_one == Approx( 9.1f ) )
|
|
||||||
with expansion:
|
|
||||||
9.1f == Approx( 9.1000003815 )
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( data.double_pi == Approx( 3.1415926535 ) )
|
|
||||||
with expansion:
|
|
||||||
3.1415926535 == Approx( 3.1415926535 )
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( data.str_hello == "hello" )
|
|
||||||
with expansion:
|
|
||||||
"hello" == "hello"
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( "hello" == data.str_hello )
|
|
||||||
with expansion:
|
|
||||||
"hello" == "hello"
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( data.str_hello.size() == 5 )
|
|
||||||
with expansion:
|
|
||||||
5 == 5
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( x == Approx( 1.3 ) )
|
|
||||||
with expansion:
|
|
||||||
1.3 == Approx( 1.3 )
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Equality checks that should fail
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
ConditionTests.cpp:<line number>
|
ConditionTests.cpp:<line number>
|
||||||
...............................................................................
|
...............................................................................
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>: FAILED:
|
ConditionTests.cpp:<line number>: FAILED:
|
||||||
CHECK( data.int_seven == 6 )
|
CHECK( false != false )
|
||||||
with expansion:
|
|
||||||
7 == 6
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>: FAILED:
|
ConditionTests.cpp:<line number>: FAILED:
|
||||||
CHECK( data.int_seven == 8 )
|
CHECK( true != true )
|
||||||
with expansion:
|
|
||||||
7 == 8
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Inequality checks that should succeed
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
ConditionTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( data.int_seven != 6 )
|
|
||||||
with expansion:
|
|
||||||
7 != 6
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( data.int_seven != 8 )
|
|
||||||
with expansion:
|
|
||||||
7 != 8
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( data.float_nine_point_one != Approx( 9.11f ) )
|
|
||||||
with expansion:
|
|
||||||
9.1f != Approx( 9.1099996567 )
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( data.float_nine_point_one != Approx( 9.0f ) )
|
|
||||||
with expansion:
|
|
||||||
9.1f != Approx( 9.0 )
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( data.float_nine_point_one != Approx( 1 ) )
|
|
||||||
with expansion:
|
|
||||||
9.1f != Approx( 1.0 )
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( data.float_nine_point_one != Approx( 0 ) )
|
|
||||||
with expansion:
|
|
||||||
9.1f != Approx( 0.0 )
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( data.double_pi != Approx( 3.1415 ) )
|
|
||||||
with expansion:
|
|
||||||
3.1415926535 != Approx( 3.1415 )
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( data.str_hello != "goodbye" )
|
|
||||||
with expansion:
|
|
||||||
"hello" != "goodbye"
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( data.str_hello != "hell" )
|
|
||||||
with expansion:
|
|
||||||
"hello" != "hell"
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( data.str_hello != "hello1" )
|
|
||||||
with expansion:
|
|
||||||
"hello" != "hello1"
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( data.str_hello.size() != 6 )
|
|
||||||
with expansion:
|
|
||||||
5 != 6
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Inequality checks that should fail
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
ConditionTests.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>: FAILED:
|
ConditionTests.cpp:<line number>: FAILED:
|
||||||
CHECK( data.int_seven != 7 )
|
CHECK( !true )
|
||||||
with expansion:
|
with expansion:
|
||||||
7 != 7
|
false
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>: FAILED:
|
ConditionTests.cpp:<line number>: FAILED:
|
||||||
CHECK( data.float_nine_point_one != Approx( 9.1f ) )
|
CHECK_FALSE( true )
|
||||||
with expansion:
|
|
||||||
9.1f != Approx( 9.1000003815 )
|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
test cases: 19 | 15 passed | 3 failed | 1 failed as expected
|
test cases: 2 | 1 passed | 1 failed
|
||||||
assertions: 62 | 56 passed | 4 failed | 2 failed as expected
|
assertions: 5 | 1 passed | 4 failed
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -13,18 +13,18 @@ namespace
|
|||||||
class TestClass
|
class TestClass
|
||||||
{
|
{
|
||||||
std::string s;
|
std::string s;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TestClass()
|
TestClass()
|
||||||
: s( "hello" )
|
: s( "hello" )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void succeedingCase()
|
void succeedingCase()
|
||||||
{
|
{
|
||||||
REQUIRE( s == "hello" );
|
REQUIRE( s == "hello" );
|
||||||
}
|
}
|
||||||
void failingCase()
|
void failingCase()
|
||||||
{
|
{
|
||||||
REQUIRE( s == "world" );
|
REQUIRE( s == "world" );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -38,20 +38,20 @@ METHOD_AS_TEST_CASE( TestClass::failingCase, "A METHOD_AS_TEST_CASE based test r
|
|||||||
struct Fixture
|
struct Fixture
|
||||||
{
|
{
|
||||||
Fixture() : m_a( 1 ) {}
|
Fixture() : m_a( 1 ) {}
|
||||||
|
|
||||||
int m_a;
|
int m_a;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_CASE_METHOD( Fixture, "A TEST_CASE_METHOD based test run that succeeds", "[class]" )
|
TEST_CASE_METHOD( Fixture, "A TEST_CASE_METHOD based test run that succeeds", "[class]" )
|
||||||
{
|
{
|
||||||
REQUIRE( m_a == 1 );
|
REQUIRE( m_a == 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// We should be able to write our tests within a different namespace
|
// We should be able to write our tests within a different namespace
|
||||||
namespace Inner
|
namespace Inner
|
||||||
{
|
{
|
||||||
TEST_CASE_METHOD( Fixture, "A TEST_CASE_METHOD based test run that fails", "[.][class][failing]" )
|
TEST_CASE_METHOD( Fixture, "A TEST_CASE_METHOD based test run that fails", "[.][class][failing]" )
|
||||||
{
|
{
|
||||||
REQUIRE( m_a == 2 );
|
REQUIRE( m_a == 2 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "catch.hpp"
|
#include "catch.hpp"
|
||||||
#include "catch_test_spec_parser.hpp"
|
#include "internal/catch_test_spec_parser.hpp"
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
# pragma clang diagnostic ignored "-Wc++98-compat"
|
# pragma clang diagnostic ignored "-Wc++98-compat"
|
||||||
|
@@ -22,7 +22,7 @@ struct TestData {
|
|||||||
float_nine_point_one( 9.1f ),
|
float_nine_point_one( 9.1f ),
|
||||||
double_pi( 3.1415926535 )
|
double_pi( 3.1415926535 )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
int int_seven;
|
int int_seven;
|
||||||
std::string str_hello;
|
std::string str_hello;
|
||||||
float float_nine_point_one;
|
float float_nine_point_one;
|
||||||
@@ -37,7 +37,7 @@ struct TestDef {
|
|||||||
TestDef& operator[]( const std::string& ) {
|
TestDef& operator[]( const std::string& ) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// The "failing" tests all use the CHECK macro, which continues if the specific test fails.
|
// The "failing" tests all use the CHECK macro, which continues if the specific test fails.
|
||||||
@@ -49,14 +49,14 @@ TEST_CASE( "Equality checks that should succeed", "" )
|
|||||||
|
|
||||||
TestDef td;
|
TestDef td;
|
||||||
td + "hello" + "hello";
|
td + "hello" + "hello";
|
||||||
|
|
||||||
TestData data;
|
TestData data;
|
||||||
|
|
||||||
REQUIRE( data.int_seven == 7 );
|
REQUIRE( data.int_seven == 7 );
|
||||||
REQUIRE( data.float_nine_point_one == Approx( 9.1f ) );
|
REQUIRE( data.float_nine_point_one == Approx( 9.1f ) );
|
||||||
REQUIRE( data.double_pi == Approx( 3.1415926535 ) );
|
REQUIRE( data.double_pi == Approx( 3.1415926535 ) );
|
||||||
REQUIRE( data.str_hello == "hello" );
|
REQUIRE( data.str_hello == "hello" );
|
||||||
REQUIRE( "hello" == data.str_hello );
|
REQUIRE( "hello" == data.str_hello );
|
||||||
REQUIRE( data.str_hello.size() == 5 );
|
REQUIRE( data.str_hello.size() == 5 );
|
||||||
|
|
||||||
double x = 1.1 + 0.1 + 0.1;
|
double x = 1.1 + 0.1 + 0.1;
|
||||||
@@ -66,7 +66,7 @@ TEST_CASE( "Equality checks that should succeed", "" )
|
|||||||
TEST_CASE( "Equality checks that should fail", "[.][failing][!mayfail]" )
|
TEST_CASE( "Equality checks that should fail", "[.][failing][!mayfail]" )
|
||||||
{
|
{
|
||||||
TestData data;
|
TestData data;
|
||||||
|
|
||||||
CHECK( data.int_seven == 6 );
|
CHECK( data.int_seven == 6 );
|
||||||
CHECK( data.int_seven == 8 );
|
CHECK( data.int_seven == 8 );
|
||||||
CHECK( data.int_seven == 0 );
|
CHECK( data.int_seven == 0 );
|
||||||
@@ -87,7 +87,7 @@ TEST_CASE( "Equality checks that should fail", "[.][failing][!mayfail]" )
|
|||||||
TEST_CASE( "Inequality checks that should succeed", "" )
|
TEST_CASE( "Inequality checks that should succeed", "" )
|
||||||
{
|
{
|
||||||
TestData data;
|
TestData data;
|
||||||
|
|
||||||
REQUIRE( data.int_seven != 6 );
|
REQUIRE( data.int_seven != 6 );
|
||||||
REQUIRE( data.int_seven != 8 );
|
REQUIRE( data.int_seven != 8 );
|
||||||
REQUIRE( data.float_nine_point_one != Approx( 9.11f ) );
|
REQUIRE( data.float_nine_point_one != Approx( 9.11f ) );
|
||||||
@@ -101,10 +101,10 @@ TEST_CASE( "Inequality checks that should succeed", "" )
|
|||||||
REQUIRE( data.str_hello.size() != 6 );
|
REQUIRE( data.str_hello.size() != 6 );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Inequality checks that should fail", "[.][failing]" )
|
TEST_CASE( "Inequality checks that should fail", "[.][failing][!shouldfail]" )
|
||||||
{
|
{
|
||||||
TestData data;
|
TestData data;
|
||||||
|
|
||||||
CHECK( data.int_seven != 7 );
|
CHECK( data.int_seven != 7 );
|
||||||
CHECK( data.float_nine_point_one != Approx( 9.1f ) );
|
CHECK( data.float_nine_point_one != Approx( 9.1f ) );
|
||||||
CHECK( data.double_pi != Approx( 3.1415926535 ) );
|
CHECK( data.double_pi != Approx( 3.1415926535 ) );
|
||||||
@@ -116,7 +116,7 @@ TEST_CASE( "Inequality checks that should fail", "[.][failing]" )
|
|||||||
TEST_CASE( "Ordering comparison checks that should succeed", "" )
|
TEST_CASE( "Ordering comparison checks that should succeed", "" )
|
||||||
{
|
{
|
||||||
TestData data;
|
TestData data;
|
||||||
|
|
||||||
REQUIRE( data.int_seven < 8 );
|
REQUIRE( data.int_seven < 8 );
|
||||||
REQUIRE( data.int_seven > 6 );
|
REQUIRE( data.int_seven > 6 );
|
||||||
REQUIRE( data.int_seven > 0 );
|
REQUIRE( data.int_seven > 0 );
|
||||||
@@ -126,14 +126,14 @@ TEST_CASE( "Ordering comparison checks that should succeed", "" )
|
|||||||
REQUIRE( data.int_seven >= 6 );
|
REQUIRE( data.int_seven >= 6 );
|
||||||
REQUIRE( data.int_seven <= 7 );
|
REQUIRE( data.int_seven <= 7 );
|
||||||
REQUIRE( data.int_seven <= 8 );
|
REQUIRE( data.int_seven <= 8 );
|
||||||
|
|
||||||
REQUIRE( data.float_nine_point_one > 9 );
|
REQUIRE( data.float_nine_point_one > 9 );
|
||||||
REQUIRE( data.float_nine_point_one < 10 );
|
REQUIRE( data.float_nine_point_one < 10 );
|
||||||
REQUIRE( data.float_nine_point_one < 9.2 );
|
REQUIRE( data.float_nine_point_one < 9.2 );
|
||||||
|
|
||||||
REQUIRE( data.str_hello <= "hello" );
|
REQUIRE( data.str_hello <= "hello" );
|
||||||
REQUIRE( data.str_hello >= "hello" );
|
REQUIRE( data.str_hello >= "hello" );
|
||||||
|
|
||||||
REQUIRE( data.str_hello < "hellp" );
|
REQUIRE( data.str_hello < "hellp" );
|
||||||
REQUIRE( data.str_hello < "zebra" );
|
REQUIRE( data.str_hello < "zebra" );
|
||||||
REQUIRE( data.str_hello > "hellm" );
|
REQUIRE( data.str_hello > "hellm" );
|
||||||
@@ -143,7 +143,7 @@ TEST_CASE( "Ordering comparison checks that should succeed", "" )
|
|||||||
TEST_CASE( "Ordering comparison checks that should fail", "[.][failing]" )
|
TEST_CASE( "Ordering comparison checks that should fail", "[.][failing]" )
|
||||||
{
|
{
|
||||||
TestData data;
|
TestData data;
|
||||||
|
|
||||||
CHECK( data.int_seven > 7 );
|
CHECK( data.int_seven > 7 );
|
||||||
CHECK( data.int_seven < 7 );
|
CHECK( data.int_seven < 7 );
|
||||||
CHECK( data.int_seven > 8 );
|
CHECK( data.int_seven > 8 );
|
||||||
@@ -153,11 +153,11 @@ TEST_CASE( "Ordering comparison checks that should fail", "[.][failing]" )
|
|||||||
|
|
||||||
CHECK( data.int_seven >= 8 );
|
CHECK( data.int_seven >= 8 );
|
||||||
CHECK( data.int_seven <= 6 );
|
CHECK( data.int_seven <= 6 );
|
||||||
|
|
||||||
CHECK( data.float_nine_point_one < 9 );
|
CHECK( data.float_nine_point_one < 9 );
|
||||||
CHECK( data.float_nine_point_one > 10 );
|
CHECK( data.float_nine_point_one > 10 );
|
||||||
CHECK( data.float_nine_point_one > 9.2 );
|
CHECK( data.float_nine_point_one > 9.2 );
|
||||||
|
|
||||||
CHECK( data.str_hello > "hello" );
|
CHECK( data.str_hello > "hello" );
|
||||||
CHECK( data.str_hello < "hello" );
|
CHECK( data.str_hello < "hello" );
|
||||||
CHECK( data.str_hello > "hellp" );
|
CHECK( data.str_hello > "hellp" );
|
||||||
@@ -178,7 +178,7 @@ TEST_CASE( "Comparisons with int literals don't warn when mixing signed/ unsigne
|
|||||||
unsigned long ul = 4;
|
unsigned long ul = 4;
|
||||||
char c = 5;
|
char c = 5;
|
||||||
unsigned char uc = 6;
|
unsigned char uc = 6;
|
||||||
|
|
||||||
REQUIRE( i == 1 );
|
REQUIRE( i == 1 );
|
||||||
REQUIRE( ui == 2 );
|
REQUIRE( ui == 2 );
|
||||||
REQUIRE( l == 3 );
|
REQUIRE( l == 3 );
|
||||||
@@ -215,7 +215,7 @@ TEST_CASE( "comparisons between int variables", "" )
|
|||||||
unsigned short unsigned_short_var = 1;
|
unsigned short unsigned_short_var = 1;
|
||||||
unsigned int unsigned_int_var = 1;
|
unsigned int unsigned_int_var = 1;
|
||||||
unsigned long unsigned_long_var = 1L;
|
unsigned long unsigned_long_var = 1L;
|
||||||
|
|
||||||
REQUIRE( long_var == unsigned_char_var );
|
REQUIRE( long_var == unsigned_char_var );
|
||||||
REQUIRE( long_var == unsigned_short_var );
|
REQUIRE( long_var == unsigned_short_var );
|
||||||
REQUIRE( long_var == unsigned_int_var );
|
REQUIRE( long_var == unsigned_int_var );
|
||||||
@@ -252,7 +252,7 @@ template<typename T>
|
|||||||
struct Ex
|
struct Ex
|
||||||
{
|
{
|
||||||
Ex( T ){}
|
Ex( T ){}
|
||||||
|
|
||||||
bool operator == ( const T& ) const { return true; }
|
bool operator == ( const T& ) const { return true; }
|
||||||
T operator * ( const T& ) const { return T(); }
|
T operator * ( const T& ) const { return T(); }
|
||||||
};
|
};
|
||||||
@@ -273,13 +273,13 @@ TEST_CASE( "Pointers can be compared to null", "" )
|
|||||||
{
|
{
|
||||||
TestData* p = CATCH_NULL;
|
TestData* p = CATCH_NULL;
|
||||||
TestData* pNULL = CATCH_NULL;
|
TestData* pNULL = CATCH_NULL;
|
||||||
|
|
||||||
REQUIRE( p == CATCH_NULL );
|
REQUIRE( p == CATCH_NULL );
|
||||||
REQUIRE( p == pNULL );
|
REQUIRE( p == pNULL );
|
||||||
|
|
||||||
TestData data;
|
TestData data;
|
||||||
p = &data;
|
p = &data;
|
||||||
|
|
||||||
REQUIRE( p != CATCH_NULL );
|
REQUIRE( p != CATCH_NULL );
|
||||||
|
|
||||||
const TestData* cp = p;
|
const TestData* cp = p;
|
||||||
@@ -290,7 +290,7 @@ TEST_CASE( "Pointers can be compared to null", "" )
|
|||||||
|
|
||||||
REQUIRE( returnsNull() == CATCH_NULL );
|
REQUIRE( returnsNull() == CATCH_NULL );
|
||||||
REQUIRE( returnsConstNull() == CATCH_NULL );
|
REQUIRE( returnsConstNull() == CATCH_NULL );
|
||||||
|
|
||||||
REQUIRE( CATCH_NULL != p );
|
REQUIRE( CATCH_NULL != p );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,7 +304,7 @@ TEST_CASE( "Pointers can be compared to null", "" )
|
|||||||
TEST_CASE( "'Not' checks that should succeed", "" )
|
TEST_CASE( "'Not' checks that should succeed", "" )
|
||||||
{
|
{
|
||||||
bool falseValue = false;
|
bool falseValue = false;
|
||||||
|
|
||||||
REQUIRE( false == false );
|
REQUIRE( false == false );
|
||||||
REQUIRE( true == true );
|
REQUIRE( true == true );
|
||||||
REQUIRE( !false );
|
REQUIRE( !false );
|
||||||
@@ -320,15 +320,15 @@ TEST_CASE( "'Not' checks that should succeed", "" )
|
|||||||
TEST_CASE( "'Not' checks that should fail", "[.][failing]" )
|
TEST_CASE( "'Not' checks that should fail", "[.][failing]" )
|
||||||
{
|
{
|
||||||
bool trueValue = true;
|
bool trueValue = true;
|
||||||
|
|
||||||
CHECK( false != false );
|
CHECK( false != false );
|
||||||
CHECK( true != true );
|
CHECK( true != true );
|
||||||
CHECK( !true );
|
CHECK( !true );
|
||||||
CHECK_FALSE( true );
|
CHECK_FALSE( true );
|
||||||
|
|
||||||
CHECK( !trueValue );
|
CHECK( !trueValue );
|
||||||
CHECK_FALSE( trueValue );
|
CHECK_FALSE( trueValue );
|
||||||
|
|
||||||
CHECK( !(1 == 1) );
|
CHECK( !(1 == 1) );
|
||||||
CHECK_FALSE( 1 == 1 );
|
CHECK_FALSE( 1 == 1 );
|
||||||
}
|
}
|
||||||
|
@@ -96,32 +96,61 @@ public:
|
|||||||
CustomException( const std::string& msg )
|
CustomException( const std::string& msg )
|
||||||
: m_msg( msg )
|
: m_msg( msg )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::string getMessage() const
|
std::string getMessage() const
|
||||||
{
|
{
|
||||||
return m_msg;
|
return m_msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_msg;
|
std::string m_msg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CustomStdException : public std::exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CustomStdException( const std::string& msg )
|
||||||
|
: m_msg( msg )
|
||||||
|
{}
|
||||||
|
~CustomStdException() CATCH_NOEXCEPT {}
|
||||||
|
|
||||||
|
std::string getMessage() const
|
||||||
|
{
|
||||||
|
return m_msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
CATCH_TRANSLATE_EXCEPTION( CustomException& ex )
|
CATCH_TRANSLATE_EXCEPTION( CustomException& ex )
|
||||||
{
|
{
|
||||||
return ex.getMessage();
|
return ex.getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CATCH_TRANSLATE_EXCEPTION( CustomStdException& ex )
|
||||||
|
{
|
||||||
|
return ex.getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
CATCH_TRANSLATE_EXCEPTION( double& ex )
|
CATCH_TRANSLATE_EXCEPTION( double& ex )
|
||||||
{
|
{
|
||||||
return Catch::toString( ex );
|
return Catch::toString( ex );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Unexpected custom exceptions can be translated", "[.][failing]" )
|
TEST_CASE("Non-std exceptions can be translated", "[.][failing]" )
|
||||||
{
|
{
|
||||||
if( Catch::alwaysTrue() )
|
if( Catch::alwaysTrue() )
|
||||||
throw CustomException( "custom exception" );
|
throw CustomException( "custom exception" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Custom std-exceptions can be custom translated", "[.][failing]" )
|
||||||
|
{
|
||||||
|
if( Catch::alwaysTrue() )
|
||||||
|
throw CustomException( "custom std exception" );
|
||||||
|
}
|
||||||
|
|
||||||
inline void throwCustom() {
|
inline void throwCustom() {
|
||||||
if( Catch::alwaysTrue() )
|
if( Catch::alwaysTrue() )
|
||||||
throw CustomException( "custom exception - not std" );
|
throw CustomException( "custom exception - not std" );
|
||||||
|
@@ -19,10 +19,10 @@ inline int multiply( int a, int b )
|
|||||||
CATCH_TEST_CASE( "Generators over two ranges", "[generators]" )
|
CATCH_TEST_CASE( "Generators over two ranges", "[generators]" )
|
||||||
{
|
{
|
||||||
using namespace Catch::Generators;
|
using namespace Catch::Generators;
|
||||||
|
|
||||||
int i = CATCH_GENERATE( between( 1, 5 ).then( values( 15, 20, 21 ).then( 36 ) ) );
|
int i = CATCH_GENERATE( between( 1, 5 ).then( values( 15, 20, 21 ).then( 36 ) ) );
|
||||||
int j = CATCH_GENERATE( between( 100, 107 ) );
|
int j = CATCH_GENERATE( between( 100, 107 ) );
|
||||||
|
|
||||||
CATCH_REQUIRE( multiply( i, 2 ) == i*2 );
|
CATCH_REQUIRE( multiply( i, 2 ) == i*2 );
|
||||||
CATCH_REQUIRE( multiply( j, 2 ) == j*2 );
|
CATCH_REQUIRE( multiply( j, 2 ) == j*2 );
|
||||||
}
|
}
|
||||||
@@ -32,11 +32,11 @@ struct IntPair { int first, second; };
|
|||||||
CATCH_TEST_CASE( "Generator over a range of pairs", "[generators]" )
|
CATCH_TEST_CASE( "Generator over a range of pairs", "[generators]" )
|
||||||
{
|
{
|
||||||
using namespace Catch::Generators;
|
using namespace Catch::Generators;
|
||||||
|
|
||||||
IntPair p[] = { { 0, 1 }, { 2, 3 } };
|
IntPair p[] = { { 0, 1 }, { 2, 3 } };
|
||||||
|
|
||||||
IntPair* i = CATCH_GENERATE( between( p, &p[1] ) );
|
IntPair* i = CATCH_GENERATE( between( p, &p[1] ) );
|
||||||
|
|
||||||
CATCH_REQUIRE( i->first == i->second-1 );
|
CATCH_REQUIRE( i->first == i->second-1 );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -38,7 +38,7 @@ TEST_CASE( "INFO gets logged on failure, even if captured before successful asse
|
|||||||
CHECK( a == 2 );
|
CHECK( a == 2 );
|
||||||
|
|
||||||
INFO( "this message should be logged" );
|
INFO( "this message should be logged" );
|
||||||
|
|
||||||
CHECK( a == 1 );
|
CHECK( a == 1 );
|
||||||
|
|
||||||
INFO( "and this, but later" );
|
INFO( "and this, but later" );
|
||||||
@@ -85,7 +85,7 @@ TEST_CASE( "Standard output from all sections is reported", "[messages][.]" )
|
|||||||
{
|
{
|
||||||
std::cout << "Message from section one" << std::endl;
|
std::cout << "Message from section one" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION( "two", "" )
|
SECTION( "two", "" )
|
||||||
{
|
{
|
||||||
std::cout << "Message from section two" << std::endl;
|
std::cout << "Message from section two" << std::endl;
|
||||||
|
@@ -21,7 +21,7 @@ TEST_CASE( "random SECTION tests", "[.][sections][failing]" )
|
|||||||
{
|
{
|
||||||
int a = 1;
|
int a = 1;
|
||||||
int b = 2;
|
int b = 2;
|
||||||
|
|
||||||
SECTION( "s1", "doesn't equal" )
|
SECTION( "s1", "doesn't equal" )
|
||||||
{
|
{
|
||||||
REQUIRE( a != b );
|
REQUIRE( a != b );
|
||||||
@@ -38,7 +38,7 @@ TEST_CASE( "nested SECTION tests", "[.][sections][failing]" )
|
|||||||
{
|
{
|
||||||
int a = 1;
|
int a = 1;
|
||||||
int b = 2;
|
int b = 2;
|
||||||
|
|
||||||
SECTION( "s1", "doesn't equal" )
|
SECTION( "s1", "doesn't equal" )
|
||||||
{
|
{
|
||||||
REQUIRE( a != b );
|
REQUIRE( a != b );
|
||||||
@@ -55,7 +55,7 @@ TEST_CASE( "more nested SECTION tests", "[sections][failing][.]" )
|
|||||||
{
|
{
|
||||||
int a = 1;
|
int a = 1;
|
||||||
int b = 2;
|
int b = 2;
|
||||||
|
|
||||||
SECTION( "s1", "doesn't equal" )
|
SECTION( "s1", "doesn't equal" )
|
||||||
{
|
{
|
||||||
SECTION( "s2", "equal" )
|
SECTION( "s2", "equal" )
|
||||||
@@ -80,29 +80,32 @@ TEST_CASE( "even more nested SECTION tests", "[sections]" )
|
|||||||
{
|
{
|
||||||
SECTION( "d (leaf)", "" )
|
SECTION( "d (leaf)", "" )
|
||||||
{
|
{
|
||||||
|
SUCCEED(""); // avoid failing due to no tests
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION( "e (leaf)", "" )
|
SECTION( "e (leaf)", "" )
|
||||||
{
|
{
|
||||||
|
SUCCEED(""); // avoid failing due to no tests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION( "f (leaf)", "" )
|
SECTION( "f (leaf)", "" )
|
||||||
{
|
{
|
||||||
|
SUCCEED(""); // avoid failing due to no tests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "looped SECTION tests", "[.][failing][sections]" )
|
TEST_CASE( "looped SECTION tests", "[.][failing][sections]" )
|
||||||
{
|
{
|
||||||
int a = 1;
|
int a = 1;
|
||||||
|
|
||||||
for( int b = 0; b < 10; ++b )
|
for( int b = 0; b < 10; ++b )
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "b is currently: " << b;
|
oss << "b is currently: " << b;
|
||||||
SECTION( "s1", oss.str() )
|
SECTION( "s1", oss.str() )
|
||||||
{
|
{
|
||||||
CHECK( b > a );
|
CHECK( b > a );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -110,18 +113,18 @@ TEST_CASE( "looped SECTION tests", "[.][failing][sections]" )
|
|||||||
TEST_CASE( "looped tests", "[.][failing]" )
|
TEST_CASE( "looped tests", "[.][failing]" )
|
||||||
{
|
{
|
||||||
static const int fib[] = { 1, 1, 2, 3, 5, 8, 13, 21 };
|
static const int fib[] = { 1, 1, 2, 3, 5, 8, 13, 21 };
|
||||||
|
|
||||||
for( size_t i=0; i < sizeof(fib)/sizeof(int); ++i )
|
for( size_t i=0; i < sizeof(fib)/sizeof(int); ++i )
|
||||||
{
|
{
|
||||||
INFO( "Testing if fib[" << i << "] (" << fib[i] << ") is even" );
|
INFO( "Testing if fib[" << i << "] (" << fib[i] << ") is even" );
|
||||||
CHECK( ( fib[i] % 2 ) == 0 );
|
CHECK( ( fib[i] % 2 ) == 0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Sends stuff to stdout and stderr", "[.]" )
|
TEST_CASE( "Sends stuff to stdout and stderr", "[.]" )
|
||||||
{
|
{
|
||||||
std::cout << "A string sent directly to stdout" << std::endl;
|
std::cout << "A string sent directly to stdout" << std::endl;
|
||||||
|
|
||||||
std::cerr << "A string sent directly to stderr" << std::endl;
|
std::cerr << "A string sent directly to stderr" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,7 +162,7 @@ inline bool testCheckedElse( bool flag )
|
|||||||
{
|
{
|
||||||
CHECKED_ELSE( flag )
|
CHECKED_ELSE( flag )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,24 +180,24 @@ TEST_CASE( "xmlentitycheck", "" )
|
|||||||
{
|
{
|
||||||
SECTION( "embedded xml", "<test>it should be possible to embed xml characters, such as <, \" or &, or even whole <xml>documents</xml> within an attribute</test>" )
|
SECTION( "embedded xml", "<test>it should be possible to embed xml characters, such as <, \" or &, or even whole <xml>documents</xml> within an attribute</test>" )
|
||||||
{
|
{
|
||||||
// No test
|
SUCCEED(""); // We need this here to stop it failing due to no tests
|
||||||
}
|
}
|
||||||
SECTION( "encoded chars", "these should all be encoded: &&&\"\"\"<<<&\"<<&\"" )
|
SECTION( "encoded chars", "these should all be encoded: &&&\"\"\"<<<&\"<<&\"" )
|
||||||
{
|
{
|
||||||
// No test
|
SUCCEED(""); // We need this here to stop it failing due to no tests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "send a single char to INFO", "[failing][.]" )
|
TEST_CASE( "send a single char to INFO", "[failing][.]" )
|
||||||
{
|
{
|
||||||
INFO(3);
|
INFO(3);
|
||||||
REQUIRE(false);
|
REQUIRE(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "atomic if", "[failing][0]")
|
TEST_CASE( "atomic if", "[failing][0]")
|
||||||
{
|
{
|
||||||
size_t x = 0;
|
size_t x = 0;
|
||||||
|
|
||||||
if( x )
|
if( x )
|
||||||
REQUIRE(x > 0);
|
REQUIRE(x > 0);
|
||||||
else
|
else
|
||||||
@@ -205,10 +208,16 @@ inline const char* testStringForMatching()
|
|||||||
{
|
{
|
||||||
return "this string contains 'abc' as a substring";
|
return "this string contains 'abc' as a substring";
|
||||||
}
|
}
|
||||||
|
inline const char* testStringForMatching2()
|
||||||
|
{
|
||||||
|
return "some completely different text that contains one common word";
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace Catch::Matchers;
|
||||||
|
|
||||||
TEST_CASE("String matchers", "[matchers]" )
|
TEST_CASE("String matchers", "[matchers]" )
|
||||||
{
|
{
|
||||||
REQUIRE_THAT( testStringForMatching(), Contains( "string" ) );
|
REQUIRE_THAT( testStringForMatching(), Contains( "string" ) );
|
||||||
CHECK_THAT( testStringForMatching(), Contains( "abc" ) );
|
CHECK_THAT( testStringForMatching(), Contains( "abc" ) );
|
||||||
|
|
||||||
CHECK_THAT( testStringForMatching(), StartsWith( "this" ) );
|
CHECK_THAT( testStringForMatching(), StartsWith( "this" ) );
|
||||||
@@ -253,6 +262,42 @@ TEST_CASE("Equals", "[matchers]")
|
|||||||
CHECK_THAT( testStringForMatching(), Equals( "this string contains 'abc' as a substring" ) );
|
CHECK_THAT( testStringForMatching(), Equals( "this string contains 'abc' as a substring" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Matchers can be (AllOf) composed with the && operator", "[matchers][operators][operator&&]")
|
||||||
|
{
|
||||||
|
CHECK_THAT( testStringForMatching(),
|
||||||
|
Contains( "string" ) &&
|
||||||
|
Contains( "abc" ) &&
|
||||||
|
Contains( "substring" ) &&
|
||||||
|
Contains( "contains" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Matchers can be (AnyOf) composed with the || operator", "[matchers][operators][operator||]")
|
||||||
|
{
|
||||||
|
CHECK_THAT( testStringForMatching(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) );
|
||||||
|
CHECK_THAT( testStringForMatching2(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Matchers can be composed with both && and ||", "[matchers][operators][operator||][operator&&]")
|
||||||
|
{
|
||||||
|
CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "substring" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Matchers can be composed with both && and || - failing", "[matchers][operators][operator||][operator&&][.failing]")
|
||||||
|
{
|
||||||
|
CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "random" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Matchers can be negated (Not) with the ! operator", "[matchers][operators][not]")
|
||||||
|
{
|
||||||
|
CHECK_THAT( testStringForMatching(), !Contains( "different" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Matchers can be negated (Not) with the ! operator - failing", "[matchers][operators][not][.failing]")
|
||||||
|
{
|
||||||
|
CHECK_THAT( testStringForMatching(), !Contains( "substring" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline unsigned int Factorial( unsigned int number )
|
inline unsigned int Factorial( unsigned int number )
|
||||||
{
|
{
|
||||||
// return number <= 1 ? number : Factorial(number-1)*number;
|
// return number <= 1 ? number : Factorial(number-1)*number;
|
||||||
@@ -294,38 +339,38 @@ TEST_CASE( "second tag", "[tag2]" )
|
|||||||
TEST_CASE( "vectors can be sized and resized", "[vector]" ) {
|
TEST_CASE( "vectors can be sized and resized", "[vector]" ) {
|
||||||
|
|
||||||
std::vector<int> v( 5 );
|
std::vector<int> v( 5 );
|
||||||
|
|
||||||
REQUIRE( v.size() == 5 );
|
REQUIRE( v.size() == 5 );
|
||||||
REQUIRE( v.capacity() >= 5 );
|
REQUIRE( v.capacity() >= 5 );
|
||||||
|
|
||||||
SECTION( "resizing bigger changes size and capacity", "" ) {
|
SECTION( "resizing bigger changes size and capacity", "" ) {
|
||||||
v.resize( 10 );
|
v.resize( 10 );
|
||||||
|
|
||||||
REQUIRE( v.size() == 10 );
|
REQUIRE( v.size() == 10 );
|
||||||
REQUIRE( v.capacity() >= 10 );
|
REQUIRE( v.capacity() >= 10 );
|
||||||
}
|
}
|
||||||
SECTION( "resizing smaller changes size but not capacity", "" ) {
|
SECTION( "resizing smaller changes size but not capacity", "" ) {
|
||||||
v.resize( 0 );
|
v.resize( 0 );
|
||||||
|
|
||||||
REQUIRE( v.size() == 0 );
|
REQUIRE( v.size() == 0 );
|
||||||
REQUIRE( v.capacity() >= 5 );
|
REQUIRE( v.capacity() >= 5 );
|
||||||
|
|
||||||
SECTION( "We can use the 'swap trick' to reset the capacity", "" ) {
|
SECTION( "We can use the 'swap trick' to reset the capacity", "" ) {
|
||||||
std::vector<int> empty;
|
std::vector<int> empty;
|
||||||
empty.swap( v );
|
empty.swap( v );
|
||||||
|
|
||||||
REQUIRE( v.capacity() == 0 );
|
REQUIRE( v.capacity() == 0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SECTION( "reserving bigger changes capacity but not size", "" ) {
|
SECTION( "reserving bigger changes capacity but not size", "" ) {
|
||||||
v.reserve( 10 );
|
v.reserve( 10 );
|
||||||
|
|
||||||
REQUIRE( v.size() == 5 );
|
REQUIRE( v.size() == 5 );
|
||||||
REQUIRE( v.capacity() >= 10 );
|
REQUIRE( v.capacity() >= 10 );
|
||||||
}
|
}
|
||||||
SECTION( "reserving smaller does not change size or capacity", "" ) {
|
SECTION( "reserving smaller does not change size or capacity", "" ) {
|
||||||
v.reserve( 0 );
|
v.reserve( 0 );
|
||||||
|
|
||||||
REQUIRE( v.size() == 5 );
|
REQUIRE( v.size() == 5 );
|
||||||
REQUIRE( v.capacity() >= 5 );
|
REQUIRE( v.capacity() >= 5 );
|
||||||
}
|
}
|
||||||
@@ -361,27 +406,27 @@ TEST_CASE( "Tabs and newlines show in output", "[.][whitespace][failing]" ) {
|
|||||||
|
|
||||||
|
|
||||||
TEST_CASE( "toString on const wchar_t const pointer returns the string contents", "[toString]" ) {
|
TEST_CASE( "toString on const wchar_t const pointer returns the string contents", "[toString]" ) {
|
||||||
const wchar_t * const s = L"wide load";
|
const wchar_t * const s = L"wide load";
|
||||||
std::string result = Catch::toString( s );
|
std::string result = Catch::toString( s );
|
||||||
CHECK( result == "\"wide load\"" );
|
CHECK( result == "\"wide load\"" );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "toString on const wchar_t pointer returns the string contents", "[toString]" ) {
|
TEST_CASE( "toString on const wchar_t pointer returns the string contents", "[toString]" ) {
|
||||||
const wchar_t * s = L"wide load";
|
const wchar_t * s = L"wide load";
|
||||||
std::string result = Catch::toString( s );
|
std::string result = Catch::toString( s );
|
||||||
CHECK( result == "\"wide load\"" );
|
CHECK( result == "\"wide load\"" );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "toString on wchar_t const pointer returns the string contents", "[toString]" ) {
|
TEST_CASE( "toString on wchar_t const pointer returns the string contents", "[toString]" ) {
|
||||||
wchar_t * const s = const_cast<wchar_t* const>( L"wide load" );
|
wchar_t * const s = const_cast<wchar_t* const>( L"wide load" );
|
||||||
std::string result = Catch::toString( s );
|
std::string result = Catch::toString( s );
|
||||||
CHECK( result == "\"wide load\"" );
|
CHECK( result == "\"wide load\"" );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "toString on wchar_t returns the string contents", "[toString]" ) {
|
TEST_CASE( "toString on wchar_t returns the string contents", "[toString]" ) {
|
||||||
wchar_t * s = const_cast<wchar_t*>( L"wide load" );
|
wchar_t * s = const_cast<wchar_t*>( L"wide load" );
|
||||||
std::string result = Catch::toString( s );
|
std::string result = Catch::toString( s );
|
||||||
CHECK( result == "\"wide load\"" );
|
CHECK( result == "\"wide load\"" );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string encode( std::string const& str, Catch::XmlEncode::ForWhat forWhat = Catch::XmlEncode::ForTextNodes ) {
|
inline std::string encode( std::string const& str, Catch::XmlEncode::ForWhat forWhat = Catch::XmlEncode::ForTextNodes ) {
|
||||||
@@ -413,17 +458,17 @@ TEST_CASE( "XmlEncode" ) {
|
|||||||
REQUIRE( encode( stringWithQuotes, Catch::XmlEncode::ForAttributes ) == "don't "quote" me on that" );
|
REQUIRE( encode( stringWithQuotes, Catch::XmlEncode::ForAttributes ) == "don't "quote" me on that" );
|
||||||
}
|
}
|
||||||
SECTION( "string with control char (1)" ) {
|
SECTION( "string with control char (1)" ) {
|
||||||
REQUIRE( encode( "[\x01]" ) == "[]" );
|
REQUIRE( encode( "[\x01]" ) == "[]" );
|
||||||
}
|
}
|
||||||
SECTION( "string with control char (x7F)" ) {
|
SECTION( "string with control char (x7F)" ) {
|
||||||
REQUIRE( encode( "[\x7F]" ) == "[]" );
|
REQUIRE( encode( "[\x7F]" ) == "[]" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CATCH_CONFIG_CPP11_LONG_LONG
|
#ifdef CATCH_CONFIG_CPP11_LONG_LONG
|
||||||
TEST_CASE( "long long" ) {
|
TEST_CASE( "long long" ) {
|
||||||
long long l = std::numeric_limits<long long>::max();
|
long long l = std::numeric_limits<long long>::max();
|
||||||
|
|
||||||
REQUIRE( l == std::numeric_limits<long long>::max() );
|
REQUIRE( l == std::numeric_limits<long long>::max() );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -433,3 +478,12 @@ TEST_CASE( "long long" ) {
|
|||||||
// int x = 10/i; // This should cause the signal to fire
|
// int x = 10/i; // This should cause the signal to fire
|
||||||
// CHECK( x == 0 );
|
// CHECK( x == 0 );
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
TEST_CASE( "This test 'should' fail but doesn't", "[.][failing][!shouldfail]" )
|
||||||
|
{
|
||||||
|
SUCCEED( "oops!" );
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE( "# A test name that starts with a #" ) {
|
||||||
|
SUCCEED( "yay" );
|
||||||
|
}
|
||||||
|
328
projects/SelfTest/PartTrackerTests.cpp
Normal file
328
projects/SelfTest/PartTrackerTests.cpp
Normal file
@@ -0,0 +1,328 @@
|
|||||||
|
/*
|
||||||
|
* Created by Phil on 1/10/2015.
|
||||||
|
* Copyright 2015 Two Blue Cubes Ltd
|
||||||
|
*
|
||||||
|
* 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 "internal/catch_suppress_warnings.h"
|
||||||
|
#include "internal/catch_test_case_tracker.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Catch
|
||||||
|
{
|
||||||
|
class LocalContext {
|
||||||
|
|
||||||
|
public:
|
||||||
|
TrackerContext& operator()() const {
|
||||||
|
return TrackerContext::instance();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Catch
|
||||||
|
|
||||||
|
inline Catch::TrackerContext& C_A_T_C_H_Context() {
|
||||||
|
return Catch::TrackerContext::instance();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
|
||||||
|
#include "catch.hpp"
|
||||||
|
|
||||||
|
using namespace Catch;
|
||||||
|
|
||||||
|
//inline void testCase( Catch::LocalContext const& C_A_T_C_H_Context ) {
|
||||||
|
//
|
||||||
|
// REQUIRE( C_A_T_C_H_Context().i() == 42 );
|
||||||
|
//}
|
||||||
|
|
||||||
|
TEST_CASE( "Tracker", "" ) {
|
||||||
|
|
||||||
|
TrackerContext ctx;
|
||||||
|
ctx.startRun();
|
||||||
|
ctx.startCycle();
|
||||||
|
|
||||||
|
ITracker& testCase = SectionTracker::acquire( ctx, "Testcase" );
|
||||||
|
REQUIRE( testCase.isOpen() );
|
||||||
|
|
||||||
|
ITracker& s1 = SectionTracker::acquire( ctx, "S1" );
|
||||||
|
REQUIRE( s1.isOpen() );
|
||||||
|
|
||||||
|
SECTION( "successfully close one section", "" ) {
|
||||||
|
s1.close();
|
||||||
|
REQUIRE( s1.isSuccessfullyCompleted() );
|
||||||
|
REQUIRE( testCase.isComplete() == false );
|
||||||
|
|
||||||
|
testCase.close();
|
||||||
|
REQUIRE( ctx.completedCycle() );
|
||||||
|
REQUIRE( testCase.isSuccessfullyCompleted() );
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION( "fail one section", "" ) {
|
||||||
|
s1.fail();
|
||||||
|
REQUIRE( s1.isComplete() );
|
||||||
|
REQUIRE( s1.isSuccessfullyCompleted() == false );
|
||||||
|
REQUIRE( testCase.isComplete() == false );
|
||||||
|
|
||||||
|
testCase.close();
|
||||||
|
REQUIRE( ctx.completedCycle() );
|
||||||
|
REQUIRE( testCase.isSuccessfullyCompleted() == false );
|
||||||
|
|
||||||
|
SECTION( "re-enter after failed section", "" ) {
|
||||||
|
ctx.startCycle();
|
||||||
|
ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
|
||||||
|
REQUIRE( testCase2.isOpen() );
|
||||||
|
|
||||||
|
ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
|
||||||
|
REQUIRE( s1b.isOpen() == false );
|
||||||
|
|
||||||
|
testCase2.close();
|
||||||
|
REQUIRE( ctx.completedCycle() );
|
||||||
|
REQUIRE( testCase.isComplete() );
|
||||||
|
REQUIRE( testCase.isSuccessfullyCompleted() );
|
||||||
|
}
|
||||||
|
SECTION( "re-enter after failed section and find next section", "" ) {
|
||||||
|
ctx.startCycle();
|
||||||
|
ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
|
||||||
|
REQUIRE( testCase2.isOpen() );
|
||||||
|
|
||||||
|
ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
|
||||||
|
REQUIRE( s1b.isOpen() == false );
|
||||||
|
|
||||||
|
ITracker& s2 = SectionTracker::acquire( ctx, "S2" );
|
||||||
|
REQUIRE( s2.isOpen() );
|
||||||
|
|
||||||
|
s2.close();
|
||||||
|
REQUIRE( ctx.completedCycle() );
|
||||||
|
|
||||||
|
testCase2.close();
|
||||||
|
REQUIRE( testCase.isComplete() );
|
||||||
|
REQUIRE( testCase.isSuccessfullyCompleted() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION( "successfully close one section, then find another", "" ) {
|
||||||
|
s1.close();
|
||||||
|
|
||||||
|
ITracker& s2 = SectionTracker::acquire( ctx, "S2" );
|
||||||
|
REQUIRE( s2.isOpen() == false );
|
||||||
|
|
||||||
|
testCase.close();
|
||||||
|
REQUIRE( testCase.isComplete() == false );
|
||||||
|
|
||||||
|
SECTION( "Re-enter - skips S1 and enters S2", "" ) {
|
||||||
|
ctx.startCycle();
|
||||||
|
ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
|
||||||
|
REQUIRE( testCase2.isOpen() );
|
||||||
|
|
||||||
|
ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
|
||||||
|
REQUIRE( s1b.isOpen() == false );
|
||||||
|
|
||||||
|
ITracker& s2b = SectionTracker::acquire( ctx, "S2" );
|
||||||
|
REQUIRE( s2b.isOpen() );
|
||||||
|
|
||||||
|
REQUIRE( ctx.completedCycle() == false );
|
||||||
|
|
||||||
|
SECTION ("Successfully close S2") {
|
||||||
|
s2b.close();
|
||||||
|
REQUIRE( ctx.completedCycle() );
|
||||||
|
|
||||||
|
REQUIRE( s2b.isSuccessfullyCompleted() );
|
||||||
|
REQUIRE( testCase2.isComplete() == false );
|
||||||
|
|
||||||
|
testCase2.close();
|
||||||
|
REQUIRE( testCase2.isSuccessfullyCompleted() );
|
||||||
|
}
|
||||||
|
SECTION ("fail S2") {
|
||||||
|
s2b.fail();
|
||||||
|
REQUIRE( ctx.completedCycle() );
|
||||||
|
|
||||||
|
REQUIRE( s2b.isComplete() );
|
||||||
|
REQUIRE( s2b.isSuccessfullyCompleted() == false );
|
||||||
|
|
||||||
|
testCase2.close();
|
||||||
|
REQUIRE( testCase2.isSuccessfullyCompleted() == false );
|
||||||
|
|
||||||
|
// Need a final cycle
|
||||||
|
ctx.startCycle();
|
||||||
|
ITracker& testCase3 = SectionTracker::acquire( ctx, "Testcase" );
|
||||||
|
REQUIRE( testCase3.isOpen() );
|
||||||
|
|
||||||
|
ITracker& s1c = SectionTracker::acquire( ctx, "S1" );
|
||||||
|
REQUIRE( s1c.isOpen() == false );
|
||||||
|
|
||||||
|
ITracker& s2c = SectionTracker::acquire( ctx, "S2" );
|
||||||
|
REQUIRE( s2c.isOpen() == false );
|
||||||
|
|
||||||
|
testCase3.close();
|
||||||
|
REQUIRE( testCase3.isSuccessfullyCompleted() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION( "open a nested section", "" ) {
|
||||||
|
ITracker& s2 = SectionTracker::acquire( ctx, "S2" );
|
||||||
|
REQUIRE( s2.isOpen() );
|
||||||
|
|
||||||
|
s2.close();
|
||||||
|
REQUIRE( s2.isComplete() );
|
||||||
|
REQUIRE( s1.isComplete() == false );
|
||||||
|
|
||||||
|
s1.close();
|
||||||
|
REQUIRE( s1.isComplete() );
|
||||||
|
REQUIRE( testCase.isComplete() == false );
|
||||||
|
|
||||||
|
testCase.close();
|
||||||
|
REQUIRE( testCase.isComplete() );
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION( "start a generator", "" ) {
|
||||||
|
IndexTracker& g1 = IndexTracker::acquire( ctx, "G1", 2 );
|
||||||
|
REQUIRE( g1.isOpen() );
|
||||||
|
REQUIRE( g1.index() == 0 );
|
||||||
|
|
||||||
|
REQUIRE( g1.isComplete() == false );
|
||||||
|
REQUIRE( s1.isComplete() == false );
|
||||||
|
|
||||||
|
SECTION( "close outer section" )
|
||||||
|
{
|
||||||
|
s1.close();
|
||||||
|
REQUIRE( s1.isComplete() == false );
|
||||||
|
testCase.close();
|
||||||
|
REQUIRE( testCase.isSuccessfullyCompleted() == false );
|
||||||
|
|
||||||
|
SECTION( "Re-enter for second generation", "" ) {
|
||||||
|
ctx.startCycle();
|
||||||
|
ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
|
||||||
|
REQUIRE( testCase2.isOpen() );
|
||||||
|
|
||||||
|
ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
|
||||||
|
REQUIRE( s1b.isOpen() );
|
||||||
|
|
||||||
|
|
||||||
|
IndexTracker& g1b = IndexTracker::acquire( ctx, "G1", 2 );
|
||||||
|
REQUIRE( g1b.isOpen() );
|
||||||
|
REQUIRE( g1b.index() == 1 );
|
||||||
|
|
||||||
|
REQUIRE( s1.isComplete() == false );
|
||||||
|
|
||||||
|
s1b.close();
|
||||||
|
REQUIRE( s1b.isComplete() );
|
||||||
|
REQUIRE( g1b.isComplete() );
|
||||||
|
testCase2.close();
|
||||||
|
REQUIRE( testCase2.isComplete() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SECTION( "Start a new inner section", "" ) {
|
||||||
|
ITracker& s2 = SectionTracker::acquire( ctx, "S2" );
|
||||||
|
REQUIRE( s2.isOpen() );
|
||||||
|
|
||||||
|
s2.close();
|
||||||
|
REQUIRE( s2.isComplete() );
|
||||||
|
|
||||||
|
s1.close();
|
||||||
|
REQUIRE( s1.isComplete() == false );
|
||||||
|
|
||||||
|
testCase.close();
|
||||||
|
REQUIRE( testCase.isComplete() == false );
|
||||||
|
|
||||||
|
SECTION( "Re-enter for second generation", "" ) {
|
||||||
|
ctx.startCycle();
|
||||||
|
ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
|
||||||
|
REQUIRE( testCase2.isOpen() );
|
||||||
|
|
||||||
|
ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
|
||||||
|
REQUIRE( s1b.isOpen() );
|
||||||
|
|
||||||
|
// generator - next value
|
||||||
|
IndexTracker& g1b = IndexTracker::acquire( ctx, "G1", 2 );
|
||||||
|
REQUIRE( g1b.isOpen() );
|
||||||
|
REQUIRE( g1b.index() == 1 );
|
||||||
|
|
||||||
|
// inner section again
|
||||||
|
ITracker& s2b = SectionTracker::acquire( ctx, "S2" );
|
||||||
|
REQUIRE( s2b.isOpen() );
|
||||||
|
|
||||||
|
s2b.close();
|
||||||
|
REQUIRE( s2b.isComplete() );
|
||||||
|
|
||||||
|
s1b.close();
|
||||||
|
REQUIRE( g1b.isComplete() );
|
||||||
|
REQUIRE( s1b.isComplete() );
|
||||||
|
|
||||||
|
testCase2.close();
|
||||||
|
REQUIRE( testCase2.isComplete() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION( "Fail an inner section", "" ) {
|
||||||
|
ITracker& s2 = SectionTracker::acquire( ctx, "S2" );
|
||||||
|
REQUIRE( s2.isOpen() );
|
||||||
|
|
||||||
|
s2.fail();
|
||||||
|
REQUIRE( s2.isComplete() );
|
||||||
|
REQUIRE( s2.isSuccessfullyCompleted() == false );
|
||||||
|
|
||||||
|
s1.close();
|
||||||
|
REQUIRE( s1.isComplete() == false );
|
||||||
|
|
||||||
|
testCase.close();
|
||||||
|
REQUIRE( testCase.isComplete() == false );
|
||||||
|
|
||||||
|
SECTION( "Re-enter for second generation", "" ) {
|
||||||
|
ctx.startCycle();
|
||||||
|
ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
|
||||||
|
REQUIRE( testCase2.isOpen() );
|
||||||
|
|
||||||
|
ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
|
||||||
|
REQUIRE( s1b.isOpen() );
|
||||||
|
|
||||||
|
// generator - still same value
|
||||||
|
IndexTracker& g1b = IndexTracker::acquire( ctx, "G1", 2 );
|
||||||
|
REQUIRE( g1b.isOpen() );
|
||||||
|
REQUIRE( g1b.index() == 0 );
|
||||||
|
|
||||||
|
// inner section again - this time won't open
|
||||||
|
ITracker& s2b = SectionTracker::acquire( ctx, "S2" );
|
||||||
|
REQUIRE( s2b.isOpen() == false );
|
||||||
|
|
||||||
|
s1b.close();
|
||||||
|
REQUIRE( g1b.isComplete() == false );
|
||||||
|
REQUIRE( s1b.isComplete() == false );
|
||||||
|
|
||||||
|
testCase2.close();
|
||||||
|
REQUIRE( testCase2.isComplete() == false );
|
||||||
|
|
||||||
|
// Another cycle - now should complete
|
||||||
|
ctx.startCycle();
|
||||||
|
ITracker& testCase3 = SectionTracker::acquire( ctx, "Testcase" );
|
||||||
|
REQUIRE( testCase3.isOpen() );
|
||||||
|
|
||||||
|
ITracker& s1c = SectionTracker::acquire( ctx, "S1" );
|
||||||
|
REQUIRE( s1c.isOpen() );
|
||||||
|
|
||||||
|
// generator - now next value
|
||||||
|
IndexTracker& g1c = IndexTracker::acquire( ctx, "G1", 2 );
|
||||||
|
REQUIRE( g1c.isOpen() );
|
||||||
|
REQUIRE( g1c.index() == 1 );
|
||||||
|
|
||||||
|
// inner section - now should open again
|
||||||
|
ITracker& s2c = SectionTracker::acquire( ctx, "S2" );
|
||||||
|
REQUIRE( s2c.isOpen() );
|
||||||
|
|
||||||
|
s2c.close();
|
||||||
|
REQUIRE( s2c.isComplete() );
|
||||||
|
|
||||||
|
s1c.close();
|
||||||
|
REQUIRE( g1c.isComplete() );
|
||||||
|
REQUIRE( s1c.isComplete() );
|
||||||
|
|
||||||
|
testCase3.close();
|
||||||
|
REQUIRE( testCase3.isComplete() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// !TBD"
|
||||||
|
// nested generator
|
||||||
|
// two sections within a generator
|
||||||
|
}
|
||||||
|
}
|
@@ -1,118 +0,0 @@
|
|||||||
/*
|
|
||||||
* Created by Phil on 20/07/2013.
|
|
||||||
* Copyright 2013 Two Blue Cubes Ltd
|
|
||||||
*
|
|
||||||
* 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)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
# pragma clang diagnostic ignored "-Wpadded"
|
|
||||||
# pragma clang diagnostic ignored "-Wc++98-compat"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "internal/catch_test_case_tracker.hpp"
|
|
||||||
|
|
||||||
#include "catch.hpp"
|
|
||||||
|
|
||||||
TEST_CASE( "section tracking", "" ) {
|
|
||||||
|
|
||||||
using namespace Catch;
|
|
||||||
TestCaseTracker testCaseTracker( "test case" );
|
|
||||||
|
|
||||||
const std::string section1Name = "section 1";
|
|
||||||
const std::string section2Name = "section 2";
|
|
||||||
|
|
||||||
CHECK_FALSE( testCaseTracker.isCompleted() );
|
|
||||||
|
|
||||||
SECTION( "test case with no sections", "" ) {
|
|
||||||
|
|
||||||
{
|
|
||||||
TestCaseTracker::Guard guard( testCaseTracker );
|
|
||||||
CHECK_FALSE( testCaseTracker.isCompleted() );
|
|
||||||
}
|
|
||||||
CHECK( testCaseTracker.isCompleted() );
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION( "test case with one section", "" ) {
|
|
||||||
|
|
||||||
{
|
|
||||||
TestCaseTracker::Guard guard( testCaseTracker );
|
|
||||||
|
|
||||||
// Enter section? - yes
|
|
||||||
CHECK( testCaseTracker.enterSection( section1Name ) );
|
|
||||||
CHECK_FALSE( testCaseTracker.isCompleted() );
|
|
||||||
testCaseTracker.leaveSection();
|
|
||||||
|
|
||||||
// Leave test case - now complete
|
|
||||||
}
|
|
||||||
CHECK( testCaseTracker.isCompleted() );
|
|
||||||
|
|
||||||
// ...
|
|
||||||
|
|
||||||
// Enter test case again
|
|
||||||
{
|
|
||||||
TestCaseTracker::Guard guard( testCaseTracker );
|
|
||||||
|
|
||||||
// Enter section? - no - now complete
|
|
||||||
CHECK_FALSE( testCaseTracker.enterSection( section1Name ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION( "test case with two consecutive sections", "" ) {
|
|
||||||
|
|
||||||
// Enter test case
|
|
||||||
{
|
|
||||||
TestCaseTracker::Guard guard( testCaseTracker );
|
|
||||||
|
|
||||||
// Enter section 1? - yes
|
|
||||||
CHECK( testCaseTracker.enterSection( section1Name ) );
|
|
||||||
testCaseTracker.leaveSection();
|
|
||||||
|
|
||||||
// Enter section 2? - no - we just exected section 1
|
|
||||||
CHECK_FALSE( testCaseTracker.enterSection( section2Name ) );
|
|
||||||
|
|
||||||
// Leave test case - incomplete (still need to visit section 2)
|
|
||||||
}
|
|
||||||
CHECK_FALSE( testCaseTracker.isCompleted() );
|
|
||||||
|
|
||||||
// ...
|
|
||||||
|
|
||||||
// Enter test case again
|
|
||||||
{
|
|
||||||
TestCaseTracker::Guard guard( testCaseTracker );
|
|
||||||
|
|
||||||
// Enter section 1? - no, already done now
|
|
||||||
CHECK_FALSE( testCaseTracker.enterSection( section1Name ) );
|
|
||||||
|
|
||||||
// Enter section 2? - yes
|
|
||||||
CHECK( testCaseTracker.enterSection( section2Name ) );
|
|
||||||
testCaseTracker.leaveSection();
|
|
||||||
|
|
||||||
// Leave test case - now complete
|
|
||||||
}
|
|
||||||
CHECK( testCaseTracker.isCompleted() );
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION( "test case with one section within another", "" ) {
|
|
||||||
|
|
||||||
// Enter test case again
|
|
||||||
{
|
|
||||||
TestCaseTracker::Guard guard( testCaseTracker );
|
|
||||||
|
|
||||||
// Enter section 1? - yes
|
|
||||||
CHECK( testCaseTracker.enterSection( section1Name ) );
|
|
||||||
|
|
||||||
// Enter section 2? - yes
|
|
||||||
CHECK( testCaseTracker.enterSection( section2Name ) );
|
|
||||||
|
|
||||||
CHECK_FALSE( testCaseTracker.isCompleted() );
|
|
||||||
|
|
||||||
testCaseTracker.leaveSection(); // section 2
|
|
||||||
testCaseTracker.leaveSection(); // section 1
|
|
||||||
|
|
||||||
// Leave test case - now complete
|
|
||||||
}
|
|
||||||
CHECK( testCaseTracker.isCompleted() );
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,3 +1,3 @@
|
|||||||
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
||||||
#include "catch_suppress_warnings.h"
|
#include "internal/catch_suppress_warnings.h"
|
||||||
#include "catch_common.h"
|
#include "internal/catch_common.h"
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
||||||
#include "catch_suppress_warnings.h"
|
#include "internal/catch_suppress_warnings.h"
|
||||||
#include "catch_console_colour.hpp"
|
#include "internal/catch_console_colour.hpp"
|
||||||
|
@@ -1,2 +1,2 @@
|
|||||||
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
||||||
#include "catch_debugger.h"
|
#include "internal/catch_debugger.h"
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
||||||
#include "catch_suppress_warnings.h"
|
#include "internal/catch_suppress_warnings.h"
|
||||||
#include "catch_interfaces_capture.h"
|
#include "internal/catch_interfaces_capture.h"
|
||||||
|
@@ -1,2 +1,2 @@
|
|||||||
#include "catch_suppress_warnings.h"
|
#include "internal/catch_suppress_warnings.h"
|
||||||
#include "catch_interfaces_config.h"
|
#include "internal/catch_interfaces_config.h"
|
||||||
|
@@ -1,2 +1,2 @@
|
|||||||
#include "catch_suppress_warnings.h"
|
#include "internal/catch_suppress_warnings.h"
|
||||||
#include "catch_interfaces_exception.h"
|
#include "internal/catch_interfaces_exception.h"
|
||||||
|
@@ -1 +1 @@
|
|||||||
#include "catch_interfaces_generators.h"
|
#include "internal/catch_interfaces_generators.h"
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
||||||
#include "catch_suppress_warnings.h"
|
#include "internal/catch_suppress_warnings.h"
|
||||||
#include "catch_interfaces_registry_hub.h"
|
#include "internal/catch_interfaces_registry_hub.h"
|
||||||
|
@@ -1,2 +1,2 @@
|
|||||||
#include "catch_suppress_warnings.h"
|
#include "internal/catch_suppress_warnings.h"
|
||||||
#include "catch_interfaces_reporter.h"
|
#include "internal/catch_interfaces_reporter.h"
|
||||||
|
@@ -1 +1 @@
|
|||||||
#include "catch_interfaces_runner.h"
|
#include "internal/catch_interfaces_runner.h"
|
||||||
|
@@ -1,2 +1,2 @@
|
|||||||
#include "catch_suppress_warnings.h"
|
#include "internal/catch_suppress_warnings.h"
|
||||||
#include "catch_interfaces_testcase.h"
|
#include "internal/catch_interfaces_testcase.h"
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
||||||
#include "catch_suppress_warnings.h"
|
#include "internal/catch_suppress_warnings.h"
|
||||||
#include "catch_message.h"
|
#include "internal/catch_message.h"
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
||||||
#include "catch_suppress_warnings.h"
|
#include "internal/catch_suppress_warnings.h"
|
||||||
#include "catch_option.hpp"
|
#include "internal/catch_option.hpp"
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
||||||
#include "catch_suppress_warnings.h"
|
#include "internal/catch_suppress_warnings.h"
|
||||||
#include "catch_ptr.hpp"
|
#include "internal/catch_ptr.hpp"
|
||||||
|
@@ -1,2 +1,3 @@
|
|||||||
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
||||||
#include "catch_stream.h"
|
#include "internal/catch_suppress_warnings.h"
|
||||||
|
#include "internal/catch_stream.h"
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
||||||
#include "catch_suppress_warnings.h"
|
#include "internal/catch_suppress_warnings.h"
|
||||||
#include "catch_streambuf.h"
|
#include "internal/catch_streambuf.h"
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
||||||
#include "catch_suppress_warnings.h"
|
#include "internal/catch_suppress_warnings.h"
|
||||||
#include "catch_test_spec.hpp"
|
#include "internal/catch_test_spec.hpp"
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
||||||
#include "catch_suppress_warnings.h"
|
#include "internal/catch_suppress_warnings.h"
|
||||||
#include "catch_xmlwriter.hpp"
|
#include "internal/catch_xmlwriter.hpp"
|
||||||
#include "catch_reenable_warnings.h"
|
#include "internal/catch_reenable_warnings.h"
|
||||||
|
@@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
TEST_CASE( "Tag alias can be registered against tag patterns", "" ) {
|
TEST_CASE( "Tag alias can be registered against tag patterns", "" ) {
|
||||||
|
|
||||||
|
using namespace Catch::Matchers;
|
||||||
|
|
||||||
Catch::TagAliasRegistry registry;
|
Catch::TagAliasRegistry registry;
|
||||||
|
|
||||||
registry.add( "[@zzz]", "[one][two]", Catch::SourceLineInfo( "file", 2 ) );
|
registry.add( "[@zzz]", "[one][two]", Catch::SourceLineInfo( "file", 2 ) );
|
||||||
|
@@ -25,7 +25,7 @@ CATCH_REGISTER_TAG_ALIAS( "[@tricky]", "[tricky]~[.]" )
|
|||||||
template<size_t size>
|
template<size_t size>
|
||||||
void parseIntoConfig( const char * (&argv)[size], Catch::ConfigData& config ) {
|
void parseIntoConfig( const char * (&argv)[size], Catch::ConfigData& config ) {
|
||||||
Catch::Clara::CommandLine<Catch::ConfigData> parser = Catch::makeCommandLineParser();
|
Catch::Clara::CommandLine<Catch::ConfigData> parser = Catch::makeCommandLineParser();
|
||||||
parser.parseInto( size, argv, config );
|
parser.parseInto( Catch::Clara::argsToVector( size, argv ), config );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size>
|
template<size_t size>
|
||||||
@@ -44,18 +44,20 @@ inline Catch::TestCase fakeTestCase( const char* name, const char* desc = "" ){
|
|||||||
|
|
||||||
TEST_CASE( "Process can be configured on command line", "[config][command-line]" ) {
|
TEST_CASE( "Process can be configured on command line", "[config][command-line]" ) {
|
||||||
|
|
||||||
|
using namespace Catch::Matchers;
|
||||||
|
|
||||||
Catch::ConfigData config;
|
Catch::ConfigData config;
|
||||||
|
|
||||||
SECTION( "default - no arguments", "" ) {
|
SECTION( "default - no arguments", "" ) {
|
||||||
const char* argv[] = { "test" };
|
const char* argv[] = { "test" };
|
||||||
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
||||||
|
|
||||||
CHECK( config.shouldDebugBreak == false );
|
CHECK( config.shouldDebugBreak == false );
|
||||||
CHECK( config.abortAfter == -1 );
|
CHECK( config.abortAfter == -1 );
|
||||||
CHECK( config.noThrow == false );
|
CHECK( config.noThrow == false );
|
||||||
CHECK( config.reporterNames.empty() );
|
CHECK( config.reporterNames.empty() );
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION( "test lists", "" ) {
|
SECTION( "test lists", "" ) {
|
||||||
SECTION( "1 test", "Specify one test case using" ) {
|
SECTION( "1 test", "Specify one test case using" ) {
|
||||||
const char* argv[] = { "test", "test1" };
|
const char* argv[] = { "test", "test1" };
|
||||||
@@ -84,24 +86,24 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]"
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION( "reporter", "" ) {
|
SECTION( "reporter", "" ) {
|
||||||
SECTION( "-r/console", "" ) {
|
SECTION( "-r/console", "" ) {
|
||||||
const char* argv[] = { "test", "-r", "console" };
|
const char* argv[] = { "test", "-r", "console" };
|
||||||
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
||||||
|
|
||||||
REQUIRE( config.reporterNames[0] == "console" );
|
REQUIRE( config.reporterNames[0] == "console" );
|
||||||
}
|
}
|
||||||
SECTION( "-r/xml", "" ) {
|
SECTION( "-r/xml", "" ) {
|
||||||
const char* argv[] = { "test", "-r", "xml" };
|
const char* argv[] = { "test", "-r", "xml" };
|
||||||
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
||||||
|
|
||||||
REQUIRE( config.reporterNames[0] == "xml" );
|
REQUIRE( config.reporterNames[0] == "xml" );
|
||||||
}
|
}
|
||||||
SECTION( "-r xml and junit", "" ) {
|
SECTION( "-r xml and junit", "" ) {
|
||||||
const char* argv[] = { "test", "-r", "xml", "-r", "junit" };
|
const char* argv[] = { "test", "-r", "xml", "-r", "junit" };
|
||||||
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
||||||
|
|
||||||
REQUIRE( config.reporterNames.size() == 2 );
|
REQUIRE( config.reporterNames.size() == 2 );
|
||||||
REQUIRE( config.reporterNames[0] == "xml" );
|
REQUIRE( config.reporterNames[0] == "xml" );
|
||||||
REQUIRE( config.reporterNames[1] == "junit" );
|
REQUIRE( config.reporterNames[1] == "junit" );
|
||||||
@@ -109,26 +111,26 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]"
|
|||||||
SECTION( "--reporter/junit", "" ) {
|
SECTION( "--reporter/junit", "" ) {
|
||||||
const char* argv[] = { "test", "--reporter", "junit" };
|
const char* argv[] = { "test", "--reporter", "junit" };
|
||||||
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
||||||
|
|
||||||
REQUIRE( config.reporterNames[0] == "junit" );
|
REQUIRE( config.reporterNames[0] == "junit" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION( "debugger", "" ) {
|
SECTION( "debugger", "" ) {
|
||||||
SECTION( "-b", "" ) {
|
SECTION( "-b", "" ) {
|
||||||
const char* argv[] = { "test", "-b" };
|
const char* argv[] = { "test", "-b" };
|
||||||
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
||||||
|
|
||||||
REQUIRE( config.shouldDebugBreak == true );
|
REQUIRE( config.shouldDebugBreak == true );
|
||||||
}
|
}
|
||||||
SECTION( "--break", "" ) {
|
SECTION( "--break", "" ) {
|
||||||
const char* argv[] = { "test", "--break" };
|
const char* argv[] = { "test", "--break" };
|
||||||
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
||||||
|
|
||||||
REQUIRE( config.shouldDebugBreak );
|
REQUIRE( config.shouldDebugBreak );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION( "abort", "" ) {
|
SECTION( "abort", "" ) {
|
||||||
SECTION( "-a aborts after first failure", "" ) {
|
SECTION( "-a aborts after first failure", "" ) {
|
||||||
const char* argv[] = { "test", "-a" };
|
const char* argv[] = { "test", "-a" };
|
||||||
@@ -151,7 +153,7 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]"
|
|||||||
REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "-x" ) );
|
REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "-x" ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION( "nothrow", "" ) {
|
SECTION( "nothrow", "" ) {
|
||||||
SECTION( "-e", "" ) {
|
SECTION( "-e", "" ) {
|
||||||
const char* argv[] = { "test", "-e" };
|
const char* argv[] = { "test", "-e" };
|
||||||
@@ -193,19 +195,41 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]"
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION( "force-colour", "") {
|
SECTION( "use-colour", "") {
|
||||||
SECTION( "--force-colour", "" ) {
|
|
||||||
const char* argv[] = { "test", "--force-colour" };
|
using Catch::UseColour;
|
||||||
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
|
||||||
|
SECTION( "without option", "" ) {
|
||||||
REQUIRE( config.forceColour );
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION( "without --force-colour", "" ) {
|
|
||||||
const char* argv[] = { "test" };
|
const char* argv[] = { "test" };
|
||||||
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
||||||
|
|
||||||
|
REQUIRE( config.useColour == UseColour::Auto );
|
||||||
|
}
|
||||||
|
|
||||||
REQUIRE( !config.forceColour );
|
SECTION( "auto", "" ) {
|
||||||
|
const char* argv[] = { "test", "--use-colour", "auto" };
|
||||||
|
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
||||||
|
|
||||||
|
REQUIRE( config.useColour == UseColour::Auto );
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION( "yes", "" ) {
|
||||||
|
const char* argv[] = { "test", "--use-colour", "yes" };
|
||||||
|
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
||||||
|
|
||||||
|
REQUIRE( config.useColour == UseColour::Yes );
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION( "no", "" ) {
|
||||||
|
const char* argv[] = { "test", "--use-colour", "no" };
|
||||||
|
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
||||||
|
|
||||||
|
REQUIRE( config.useColour == UseColour::No );
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION( "error", "" ) {
|
||||||
|
const char* argv[] = { "test", "--use-colour", "wrong" };
|
||||||
|
REQUIRE_THROWS_WITH( parseIntoConfig( argv, config ), Contains( "colour mode must be one of" ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -217,7 +241,7 @@ TEST_CASE( "Long strings can be wrapped", "[wrap]" ) {
|
|||||||
SECTION( "plain string", "" ) {
|
SECTION( "plain string", "" ) {
|
||||||
// guide: 123456789012345678
|
// guide: 123456789012345678
|
||||||
std::string testString = "one two three four";
|
std::string testString = "one two three four";
|
||||||
|
|
||||||
SECTION( "No wrapping", "" ) {
|
SECTION( "No wrapping", "" ) {
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString );
|
CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString );
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString );
|
CHECK( Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString );
|
||||||
@@ -261,14 +285,14 @@ TEST_CASE( "Long strings can be wrapped", "[wrap]" ) {
|
|||||||
.setInitialIndent( 1 ) );
|
.setInitialIndent( 1 ) );
|
||||||
CHECK( text.toString() == " one two\n three\n four" );
|
CHECK( text.toString() == " one two\n three\n four" );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION( "With newlines", "" ) {
|
SECTION( "With newlines", "" ) {
|
||||||
|
|
||||||
// guide: 1234567890123456789
|
// guide: 1234567890123456789
|
||||||
std::string testString = "one two\nthree four";
|
std::string testString = "one two\nthree four";
|
||||||
|
|
||||||
SECTION( "No wrapping" , "" ) {
|
SECTION( "No wrapping" , "" ) {
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString );
|
CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString );
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString );
|
CHECK( Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString );
|
||||||
@@ -288,17 +312,17 @@ TEST_CASE( "Long strings can be wrapped", "[wrap]" ) {
|
|||||||
CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" );
|
CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION( "With tabs", "" ) {
|
SECTION( "With tabs", "" ) {
|
||||||
|
|
||||||
// guide: 1234567890123456789
|
// guide: 1234567890123456789
|
||||||
std::string testString = "one two \tthree four five six";
|
std::string testString = "one two \tthree four five six";
|
||||||
|
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 15 ) ).toString()
|
CHECK( Text( testString, TextAttributes().setWidth( 15 ) ).toString()
|
||||||
== "one two three\n four\n five\n six" );
|
== "one two three\n four\n five\n six" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace Catch;
|
using namespace Catch;
|
||||||
@@ -324,7 +348,7 @@ public:
|
|||||||
ColourString( std::string const& _string, std::vector<ColourIndex> const& _colours )
|
ColourString( std::string const& _string, std::vector<ColourIndex> const& _colours )
|
||||||
: string( _string ), colours( _colours )
|
: string( _string ), colours( _colours )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
ColourString& addColour( Colour::Code colour, int _index ) {
|
ColourString& addColour( Colour::Code colour, int _index ) {
|
||||||
colours.push_back( ColourIndex( colour,
|
colours.push_back( ColourIndex( colour,
|
||||||
resolveRelativeIndex( _index ),
|
resolveRelativeIndex( _index ),
|
||||||
@@ -337,7 +361,7 @@ public:
|
|||||||
resolveLastRelativeIndex( _toIndex ) ) );
|
resolveLastRelativeIndex( _toIndex ) ) );
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeToStream( std::ostream& _stream ) const {
|
void writeToStream( std::ostream& _stream ) const {
|
||||||
std::size_t last = 0;
|
std::size_t last = 0;
|
||||||
for( std::size_t i = 0; i < colours.size(); ++i ) {
|
for( std::size_t i = 0; i < colours.size(); ++i ) {
|
||||||
@@ -351,7 +375,7 @@ public:
|
|||||||
last = index.toIndex;
|
last = index.toIndex;
|
||||||
}
|
}
|
||||||
if( last < string.size() )
|
if( last < string.size() )
|
||||||
_stream << string.substr( last );
|
_stream << string.substr( last );
|
||||||
}
|
}
|
||||||
friend std::ostream& operator << ( std::ostream& _stream, ColourString const& _colourString ) {
|
friend std::ostream& operator << ( std::ostream& _stream, ColourString const& _colourString ) {
|
||||||
_colourString.writeToStream( _stream );
|
_colourString.writeToStream( _stream );
|
||||||
@@ -408,7 +432,7 @@ TEST_CASE( "replaceInPlace", "" ) {
|
|||||||
|
|
||||||
// !TBD: This will be folded into Text class
|
// !TBD: This will be folded into Text class
|
||||||
TEST_CASE( "Strings can be rendered with colour", "[.colour]" ) {
|
TEST_CASE( "Strings can be rendered with colour", "[.colour]" ) {
|
||||||
|
|
||||||
{
|
{
|
||||||
ColourString cs( "hello" );
|
ColourString cs( "hello" );
|
||||||
cs .addColour( Colour::Red, 0 )
|
cs .addColour( Colour::Red, 0 )
|
||||||
@@ -420,19 +444,19 @@ TEST_CASE( "Strings can be rendered with colour", "[.colour]" ) {
|
|||||||
{
|
{
|
||||||
ColourString cs( "hello" );
|
ColourString cs( "hello" );
|
||||||
cs .addColour( Colour::Blue, 1, -2 );
|
cs .addColour( Colour::Blue, 1, -2 );
|
||||||
|
|
||||||
Catch::cout() << cs << std::endl;
|
Catch::cout() << cs << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Text can be formatted using the Text class", "" ) {
|
TEST_CASE( "Text can be formatted using the Text class", "" ) {
|
||||||
|
|
||||||
CHECK( Text( "hi there" ).toString() == "hi there" );
|
CHECK( Text( "hi there" ).toString() == "hi there" );
|
||||||
|
|
||||||
TextAttributes narrow;
|
TextAttributes narrow;
|
||||||
narrow.setWidth( 6 );
|
narrow.setWidth( 6 );
|
||||||
|
|
||||||
CHECK( Text( "hi there", narrow ).toString() == "hi\nthere" );
|
CHECK( Text( "hi there", narrow ).toString() == "hi\nthere" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,5 +469,15 @@ TEST_CASE( "Long text is truncted", "[Text][Truncated]" ) {
|
|||||||
oss << longLine << longLine << "\n";
|
oss << longLine << longLine << "\n";
|
||||||
Text t( oss.str() );
|
Text t( oss.str() );
|
||||||
CHECK_THAT( t.toString(), EndsWith( "... message truncated due to excessive size" ) );
|
CHECK_THAT( t.toString(), EndsWith( "... message truncated due to excessive size" ) );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void manuallyRegisteredTestFunction() {
|
||||||
|
SUCCEED( "was called" );
|
||||||
|
}
|
||||||
|
struct AutoTestReg {
|
||||||
|
AutoTestReg() {
|
||||||
|
REGISTER_TEST_CASE( manuallyRegisteredTestFunction, "ManuallyRegistered", "" );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
AutoTestReg autoTestReg;
|
||||||
|
@@ -25,7 +25,7 @@ namespace Catch
|
|||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "std::pair( " << value.first << ", " << value.second << " )";
|
oss << "std::pair( " << value.first << ", " << value.second << " )";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ TEST_CASE
|
|||||||
{
|
{
|
||||||
std::pair<int, int> aNicePair( 1, 2 );
|
std::pair<int, int> aNicePair( 1, 2 );
|
||||||
|
|
||||||
REQUIRE( (std::pair<int, int>( 1, 2 )) == aNicePair );
|
REQUIRE( (std::pair<int, int>( 1, 2 )) == aNicePair );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -62,7 +62,7 @@ TEST_CASE
|
|||||||
/*
|
/*
|
||||||
int a = 1;
|
int a = 1;
|
||||||
int b = 2;
|
int b = 2;
|
||||||
|
|
||||||
// This only captures part of the expression, but issues a warning about the rest
|
// This only captures part of the expression, but issues a warning about the rest
|
||||||
REQUIRE( a+1 == b-1 );
|
REQUIRE( a+1 == b-1 );
|
||||||
*/
|
*/
|
||||||
@@ -85,38 +85,38 @@ TEST_CASE
|
|||||||
"[Tricky][failing][.]"
|
"[Tricky][failing][.]"
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
||||||
Opaque o1, o2;
|
Opaque o1, o2;
|
||||||
o1.val = 7;
|
o1.val = 7;
|
||||||
o2.val = 8;
|
o2.val = 8;
|
||||||
|
|
||||||
CHECK( &o1 == &o2 );
|
CHECK( &o1 == &o2 );
|
||||||
CHECK( o1 == o2 );
|
CHECK( o1 == o2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
TEST_CASE
|
TEST_CASE
|
||||||
(
|
(
|
||||||
"string literals of different sizes can be compared",
|
"string literals of different sizes can be compared",
|
||||||
"[Tricky][failing][.]"
|
"[Tricky][failing][.]"
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
REQUIRE( std::string( "first" ) == "second" );
|
REQUIRE( std::string( "first" ) == "second" );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
TEST_CASE
|
TEST_CASE
|
||||||
(
|
(
|
||||||
"An expression with side-effects should only be evaluated once",
|
"An expression with side-effects should only be evaluated once",
|
||||||
"[Tricky]"
|
"[Tricky]"
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int i = 7;
|
int i = 7;
|
||||||
|
|
||||||
REQUIRE( i++ == 7 );
|
REQUIRE( i++ == 7 );
|
||||||
REQUIRE( i++ == 8 );
|
REQUIRE( i++ == 8 );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace A {
|
namespace A {
|
||||||
@@ -167,8 +167,8 @@ TEST_CASE
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
namespace ObjectWithConversions
|
namespace ObjectWithConversions
|
||||||
{
|
{
|
||||||
struct Object
|
struct Object
|
||||||
{
|
{
|
||||||
operator unsigned int() {return 0xc0000000;}
|
operator unsigned int() {return 0xc0000000;}
|
||||||
};
|
};
|
||||||
@@ -179,31 +179,31 @@ namespace ObjectWithConversions
|
|||||||
"Operators at different namespace levels not hijacked by Koenig lookup",
|
"Operators at different namespace levels not hijacked by Koenig lookup",
|
||||||
"[Tricky]"
|
"[Tricky]"
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Object o;
|
Object o;
|
||||||
REQUIRE(0xc0000000 == o );
|
REQUIRE(0xc0000000 == o );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ObjectWithNonConstEqualityOperator
|
namespace ObjectWithNonConstEqualityOperator
|
||||||
{
|
{
|
||||||
struct Test
|
struct Test
|
||||||
{
|
{
|
||||||
Test( unsigned int v )
|
Test( unsigned int v )
|
||||||
: m_value(v)
|
: m_value(v)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool operator==( const Test&rhs )
|
bool operator==( const Test&rhs )
|
||||||
{
|
{
|
||||||
return (m_value == rhs.m_value);
|
return (m_value == rhs.m_value);
|
||||||
}
|
}
|
||||||
bool operator==( const Test&rhs ) const
|
bool operator==( const Test&rhs ) const
|
||||||
{
|
{
|
||||||
return (m_value != rhs.m_value);
|
return (m_value != rhs.m_value);
|
||||||
}
|
}
|
||||||
unsigned int m_value;
|
unsigned int m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_CASE("Demonstrate that a non-const == is not used", "[Tricky]" )
|
TEST_CASE("Demonstrate that a non-const == is not used", "[Tricky]" )
|
||||||
{
|
{
|
||||||
Test t( 1 );
|
Test t( 1 );
|
||||||
@@ -226,7 +226,7 @@ namespace EnumBitFieldTests
|
|||||||
struct Obj
|
struct Obj
|
||||||
{
|
{
|
||||||
Obj():prop(&p){}
|
Obj():prop(&p){}
|
||||||
|
|
||||||
int p;
|
int p;
|
||||||
int* prop;
|
int* prop;
|
||||||
};
|
};
|
||||||
@@ -284,11 +284,11 @@ TEST_CASE( "(unimplemented) static bools can be evaluated", "[Tricky]" )
|
|||||||
/*
|
/*
|
||||||
TEST_CASE( "Tests with the same name are not allowed", "[Tricky]" )
|
TEST_CASE( "Tests with the same name are not allowed", "[Tricky]" )
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
TEST_CASE( "Tests with the same name are not allowed", "[Tricky]" )
|
TEST_CASE( "Tests with the same name are not allowed", "[Tricky]" )
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -317,13 +317,13 @@ TEST_CASE( "Assertions then sections", "[Tricky]" )
|
|||||||
{
|
{
|
||||||
// This was causing a failure due to the way the console reporter was handling
|
// This was causing a failure due to the way the console reporter was handling
|
||||||
// the current section
|
// the current section
|
||||||
|
|
||||||
REQUIRE( Catch::alwaysTrue() );
|
REQUIRE( Catch::alwaysTrue() );
|
||||||
|
|
||||||
SECTION( "A section", "" )
|
SECTION( "A section", "" )
|
||||||
{
|
{
|
||||||
REQUIRE( Catch::alwaysTrue() );
|
REQUIRE( Catch::alwaysTrue() );
|
||||||
|
|
||||||
SECTION( "Another section", "" )
|
SECTION( "Another section", "" )
|
||||||
{
|
{
|
||||||
REQUIRE( Catch::alwaysTrue() );
|
REQUIRE( Catch::alwaysTrue() );
|
||||||
|
@@ -93,7 +93,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\..\SelfTest\ApproxTests.cpp" />
|
<ClCompile Include="..\..\..\SelfTest\ApproxTests.cpp" />
|
||||||
<ClCompile Include="..\..\..\SelfTest\BDDTests.cpp" />
|
<ClCompile Include="..\..\..\SelfTest\BDDTests.cpp" />
|
||||||
<ClCompile Include="..\..\..\SelfTest\SectionTrackerTests.cpp" />
|
<ClCompile Include="..\..\..\SelfTest\PartTrackerTests.cpp" />
|
||||||
<ClCompile Include="..\..\..\SelfTest\TestMain.cpp" />
|
<ClCompile Include="..\..\..\SelfTest\TestMain.cpp" />
|
||||||
<ClCompile Include="..\..\..\SelfTest\ClassTests.cpp" />
|
<ClCompile Include="..\..\..\SelfTest\ClassTests.cpp" />
|
||||||
<ClCompile Include="..\..\..\SelfTest\ConditionTests.cpp" />
|
<ClCompile Include="..\..\..\SelfTest\ConditionTests.cpp" />
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
26059AF21BD4B94C003D575C /* PartTrackerTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26059AF11BD4B94C003D575C /* PartTrackerTests.cpp */; };
|
||||||
263F7A4719B6FCBF009474C2 /* EnumToString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263F7A4619B6FCBF009474C2 /* EnumToString.cpp */; };
|
263F7A4719B6FCBF009474C2 /* EnumToString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263F7A4619B6FCBF009474C2 /* EnumToString.cpp */; };
|
||||||
263F7A4B19B6FE1E009474C2 /* ToStringPair.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263F7A4819B6FE1E009474C2 /* ToStringPair.cpp */; };
|
263F7A4B19B6FE1E009474C2 /* ToStringPair.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263F7A4819B6FE1E009474C2 /* ToStringPair.cpp */; };
|
||||||
263F7A4C19B6FE1E009474C2 /* ToStringVector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263F7A4919B6FE1E009474C2 /* ToStringVector.cpp */; };
|
263F7A4C19B6FE1E009474C2 /* ToStringVector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263F7A4919B6FE1E009474C2 /* ToStringVector.cpp */; };
|
||||||
@@ -17,7 +18,6 @@
|
|||||||
26711C8F195D465C0033EDA2 /* TagAliasTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26711C8D195D465C0033EDA2 /* TagAliasTests.cpp */; };
|
26711C8F195D465C0033EDA2 /* TagAliasTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26711C8D195D465C0033EDA2 /* TagAliasTests.cpp */; };
|
||||||
26847E5F16BBADB40043B9C1 /* catch_message.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26847E5D16BBADB40043B9C1 /* catch_message.cpp */; };
|
26847E5F16BBADB40043B9C1 /* catch_message.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26847E5D16BBADB40043B9C1 /* catch_message.cpp */; };
|
||||||
2691574C1A532A280054F1ED /* ToStringTuple.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2691574B1A532A280054F1ED /* ToStringTuple.cpp */; };
|
2691574C1A532A280054F1ED /* ToStringTuple.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2691574B1A532A280054F1ED /* ToStringTuple.cpp */; };
|
||||||
26948286179A9AB900ED166E /* SectionTrackerTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26948284179A9AB900ED166E /* SectionTrackerTests.cpp */; };
|
|
||||||
2694A1FD16A0000E004816E3 /* catch_text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2694A1FB16A0000E004816E3 /* catch_text.cpp */; };
|
2694A1FD16A0000E004816E3 /* catch_text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2694A1FB16A0000E004816E3 /* catch_text.cpp */; };
|
||||||
26E1B7D319213BC900812682 /* CmdLineTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E1B7D119213BC900812682 /* CmdLineTests.cpp */; };
|
26E1B7D319213BC900812682 /* CmdLineTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E1B7D119213BC900812682 /* CmdLineTests.cpp */; };
|
||||||
4A45DA2416161EF9004F8D6B /* catch_console_colour.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A45DA2316161EF9004F8D6B /* catch_console_colour.cpp */; };
|
4A45DA2416161EF9004F8D6B /* catch_console_colour.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A45DA2316161EF9004F8D6B /* catch_console_colour.cpp */; };
|
||||||
@@ -62,6 +62,7 @@
|
|||||||
/* End PBXCopyFilesBuildPhase section */
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
26059AF11BD4B94C003D575C /* PartTrackerTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PartTrackerTests.cpp; path = ../../../SelfTest/PartTrackerTests.cpp; sourceTree = "<group>"; };
|
||||||
261488FA184C81130041FBEB /* catch_test_spec.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_test_spec.hpp; sourceTree = "<group>"; };
|
261488FA184C81130041FBEB /* catch_test_spec.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_test_spec.hpp; sourceTree = "<group>"; };
|
||||||
261488FC184D1DC10041FBEB /* catch_stream.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_stream.h; sourceTree = "<group>"; };
|
261488FC184D1DC10041FBEB /* catch_stream.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_stream.h; sourceTree = "<group>"; };
|
||||||
261488FD184D21290041FBEB /* catch_section_info.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_section_info.h; sourceTree = "<group>"; };
|
261488FD184D21290041FBEB /* catch_section_info.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_section_info.h; sourceTree = "<group>"; };
|
||||||
@@ -100,7 +101,6 @@
|
|||||||
2691574B1A532A280054F1ED /* ToStringTuple.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ToStringTuple.cpp; path = ../../../SelfTest/ToStringTuple.cpp; sourceTree = "<group>"; };
|
2691574B1A532A280054F1ED /* ToStringTuple.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ToStringTuple.cpp; path = ../../../SelfTest/ToStringTuple.cpp; sourceTree = "<group>"; };
|
||||||
26926E8318D7777D004E10F2 /* clara.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = clara.h; path = ../../../../include/external/clara.h; sourceTree = "<group>"; };
|
26926E8318D7777D004E10F2 /* clara.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = clara.h; path = ../../../../include/external/clara.h; sourceTree = "<group>"; };
|
||||||
26926E8418D77809004E10F2 /* tbc_text_format.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tbc_text_format.h; path = ../../../../include/external/tbc_text_format.h; sourceTree = "<group>"; };
|
26926E8418D77809004E10F2 /* tbc_text_format.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tbc_text_format.h; path = ../../../../include/external/tbc_text_format.h; sourceTree = "<group>"; };
|
||||||
26948284179A9AB900ED166E /* SectionTrackerTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SectionTrackerTests.cpp; path = ../../../SelfTest/SectionTrackerTests.cpp; sourceTree = "<group>"; };
|
|
||||||
26948287179EF7F900ED166E /* catch_test_case_tracker.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_test_case_tracker.hpp; sourceTree = "<group>"; };
|
26948287179EF7F900ED166E /* catch_test_case_tracker.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_test_case_tracker.hpp; sourceTree = "<group>"; };
|
||||||
2694A1FB16A0000E004816E3 /* catch_text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = catch_text.cpp; sourceTree = "<group>"; };
|
2694A1FB16A0000E004816E3 /* catch_text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = catch_text.cpp; sourceTree = "<group>"; };
|
||||||
269831E519078C1600BB0CE0 /* catch_tostring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_tostring.h; sourceTree = "<group>"; };
|
269831E519078C1600BB0CE0 /* catch_tostring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_tostring.h; sourceTree = "<group>"; };
|
||||||
@@ -212,7 +212,7 @@
|
|||||||
266E9AD317290E710061DAB2 /* Introspective Tests */ = {
|
266E9AD317290E710061DAB2 /* Introspective Tests */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
26948284179A9AB900ED166E /* SectionTrackerTests.cpp */,
|
26059AF11BD4B94C003D575C /* PartTrackerTests.cpp */,
|
||||||
26E1B7D119213BC900812682 /* CmdLineTests.cpp */,
|
26E1B7D119213BC900812682 /* CmdLineTests.cpp */,
|
||||||
26711C8D195D465C0033EDA2 /* TagAliasTests.cpp */,
|
26711C8D195D465C0033EDA2 /* TagAliasTests.cpp */,
|
||||||
);
|
);
|
||||||
@@ -513,7 +513,7 @@
|
|||||||
4A6D0C17149B3D3B00DB3EAA /* Project object */ = {
|
4A6D0C17149B3D3B00DB3EAA /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastUpgradeCheck = 0630;
|
LastUpgradeCheck = 0710;
|
||||||
};
|
};
|
||||||
buildConfigurationList = 4A6D0C1A149B3D3B00DB3EAA /* Build configuration list for PBXProject "CatchSelfTest" */;
|
buildConfigurationList = 4A6D0C1A149B3D3B00DB3EAA /* Build configuration list for PBXProject "CatchSelfTest" */;
|
||||||
compatibilityVersion = "Xcode 3.2";
|
compatibilityVersion = "Xcode 3.2";
|
||||||
@@ -548,6 +548,7 @@
|
|||||||
4A6D0C3E149B3D9E00DB3EAA /* TestMain.cpp in Sources */,
|
4A6D0C3E149B3D9E00DB3EAA /* TestMain.cpp in Sources */,
|
||||||
4A6D0C3F149B3D9E00DB3EAA /* TrickyTests.cpp in Sources */,
|
4A6D0C3F149B3D9E00DB3EAA /* TrickyTests.cpp in Sources */,
|
||||||
263F7A4D19B6FE1E009474C2 /* ToStringWhich.cpp in Sources */,
|
263F7A4D19B6FE1E009474C2 /* ToStringWhich.cpp in Sources */,
|
||||||
|
26059AF21BD4B94C003D575C /* PartTrackerTests.cpp in Sources */,
|
||||||
263F7A4B19B6FE1E009474C2 /* ToStringPair.cpp in Sources */,
|
263F7A4B19B6FE1E009474C2 /* ToStringPair.cpp in Sources */,
|
||||||
4AEE032016142F910071E950 /* catch_common.cpp in Sources */,
|
4AEE032016142F910071E950 /* catch_common.cpp in Sources */,
|
||||||
263F7A4C19B6FE1E009474C2 /* ToStringVector.cpp in Sources */,
|
263F7A4C19B6FE1E009474C2 /* ToStringVector.cpp in Sources */,
|
||||||
@@ -574,7 +575,6 @@
|
|||||||
26847E5F16BBADB40043B9C1 /* catch_message.cpp in Sources */,
|
26847E5F16BBADB40043B9C1 /* catch_message.cpp in Sources */,
|
||||||
266B06B816F3A60A004ED264 /* VariadicMacrosTests.cpp in Sources */,
|
266B06B816F3A60A004ED264 /* VariadicMacrosTests.cpp in Sources */,
|
||||||
266ECD74170F3C620030D735 /* BDDTests.cpp in Sources */,
|
266ECD74170F3C620030D735 /* BDDTests.cpp in Sources */,
|
||||||
26948286179A9AB900ED166E /* SectionTrackerTests.cpp in Sources */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -595,6 +595,7 @@
|
|||||||
CLANG_WARN__EXIT_TIME_DESTRUCTORS = NO;
|
CLANG_WARN__EXIT_TIME_DESTRUCTORS = NO;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_TESTABILITY = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
@interface iTchRunnerAppDelegate : NSObject <UIApplicationDelegate>
|
@interface iTchRunnerAppDelegate : NSObject <UIApplicationDelegate>
|
||||||
{
|
{
|
||||||
UIWindow *window;
|
UIWindow *window;
|
||||||
}
|
}
|
||||||
@@ -25,15 +25,15 @@
|
|||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||||
{
|
{
|
||||||
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||||
[window setUserInteractionEnabled:YES];
|
[window setUserInteractionEnabled:YES];
|
||||||
[window setMultipleTouchEnabled:YES];
|
[window setMultipleTouchEnabled:YES];
|
||||||
|
|
||||||
CGRect screenRect = [[UIScreen mainScreen] applicationFrame];
|
CGRect screenRect = [[UIScreen mainScreen] applicationFrame];
|
||||||
iTchRunnerMainView* view = [[iTchRunnerMainView alloc] initWithFrame:screenRect];
|
iTchRunnerMainView* view = [[iTchRunnerMainView alloc] initWithFrame:screenRect];
|
||||||
|
|
||||||
[window addSubview:view];
|
[window addSubview:view];
|
||||||
[window makeKeyAndVisible];
|
[window makeKeyAndVisible];
|
||||||
arcSafeRelease( view );
|
arcSafeRelease( view );
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
#if !CATCH_ARC_ENABLED
|
#if !CATCH_ARC_ENABLED
|
||||||
[window release];
|
[window release];
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
- (void)applicationWillResignActive:(UIApplication *)application
|
- (void)applicationWillResignActive:(UIApplication *)application
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
||||||
@@ -62,17 +62,17 @@
|
|||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
- (void)applicationDidEnterBackground:(UIApplication *)application
|
- (void)applicationDidEnterBackground:(UIApplication *)application
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
|
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
|
||||||
If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
|
If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
- (void)applicationWillEnterForeground:(UIApplication *)application
|
- (void)applicationWillEnterForeground:(UIApplication *)application
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background.
|
Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background.
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
- (void)applicationDidBecomeActive:(UIApplication *)application
|
- (void)applicationDidBecomeActive:(UIApplication *)application
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
|
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
- (void)applicationWillTerminate:(UIApplication *)application
|
- (void)applicationWillTerminate:(UIApplication *)application
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Called when the application is about to terminate.
|
Called when the application is about to terminate.
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
|
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
|
Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
|
||||||
|
@@ -33,7 +33,7 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
-(id) initWithFrame:(CGRect)frame
|
-(id) initWithFrame:(CGRect)frame
|
||||||
{
|
{
|
||||||
if ((self = [super initWithFrame:frame]))
|
if ((self = [super initWithFrame:frame]))
|
||||||
{
|
{
|
||||||
// Initialization code
|
// Initialization code
|
||||||
self.backgroundColor = [UIColor blackColor];
|
self.backgroundColor = [UIColor blackColor];
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
-(void) showAlert
|
-(void) showAlert
|
||||||
{
|
{
|
||||||
UIActionSheet* menu = [[UIActionSheet alloc] initWithTitle:@"Options"
|
UIActionSheet* menu = [[UIActionSheet alloc] initWithTitle:@"Options"
|
||||||
delegate:self
|
delegate:self
|
||||||
cancelButtonTitle:nil
|
cancelButtonTitle:nil
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
otherButtonTitles:@"Run all tests", nil];
|
otherButtonTitles:@"Run all tests", nil];
|
||||||
[menu showInView: self];
|
[menu showInView: self];
|
||||||
arcSafeRelease( menu );
|
arcSafeRelease( menu );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a copy & paste from Catch::Runner2 to get us bootstrapped (this is due to all be
|
// This is a copy & paste from Catch::Runner2 to get us bootstrapped (this is due to all be
|
||||||
@@ -144,7 +144,7 @@ inline Catch::Totals runTestsForGroup( Catch::RunContext& context, const Catch::
|
|||||||
{
|
{
|
||||||
const Catch::AssertionResult& resultInfo = *pResultInfo;
|
const Catch::AssertionResult& resultInfo = *pResultInfo;
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
|
|
||||||
if( resultInfo.hasExpression() )
|
if( resultInfo.hasExpression() )
|
||||||
{
|
{
|
||||||
oss << resultInfo.getExpression();
|
oss << resultInfo.getExpression();
|
||||||
@@ -174,7 +174,7 @@ inline Catch::Totals runTestsForGroup( Catch::RunContext& context, const Catch::
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( resultInfo.hasExpression() )
|
if( resultInfo.hasExpression() )
|
||||||
{
|
{
|
||||||
oss << " for: " << resultInfo.getExpandedExpression();
|
oss << " for: " << resultInfo.getExpandedExpression();
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
@protocol iTchRunnerDelegate
|
@protocol iTchRunnerDelegate
|
||||||
|
|
||||||
-(void) testWasRun: (const Catch::AssertionResult*) result;
|
-(void) testWasRun: (const Catch::AssertionResult*) result;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@@ -38,14 +38,14 @@ namespace Catch
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
static std::string getDescription
|
static std::string getDescription
|
||||||
()
|
()
|
||||||
{
|
{
|
||||||
return "Captures results for iOS runner";
|
return "Captures results for iOS runner";
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
size_t getSucceeded
|
size_t getSucceeded
|
||||||
()
|
()
|
||||||
@@ -53,7 +53,7 @@ namespace Catch
|
|||||||
{
|
{
|
||||||
return m_totals.assertions.passed;
|
return m_totals.assertions.passed;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
size_t getFailed
|
size_t getFailed
|
||||||
()
|
()
|
||||||
@@ -61,20 +61,20 @@ namespace Catch
|
|||||||
{
|
{
|
||||||
return m_totals.assertions.failed;
|
return m_totals.assertions.failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
m_totals = Totals();
|
m_totals = Totals();
|
||||||
}
|
}
|
||||||
|
|
||||||
private: // IReporter
|
private: // IReporter
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
virtual void StartTesting
|
virtual void StartTesting
|
||||||
()
|
()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
virtual void EndTesting
|
virtual void EndTesting
|
||||||
(
|
(
|
||||||
@@ -83,7 +83,7 @@ namespace Catch
|
|||||||
{
|
{
|
||||||
m_totals = totals;
|
m_totals = totals;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
virtual void Result
|
virtual void Result
|
||||||
(
|
(
|
||||||
@@ -92,7 +92,7 @@ namespace Catch
|
|||||||
{
|
{
|
||||||
[m_delegate testWasRun: &result];
|
[m_delegate testWasRun: &result];
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Deliberately unimplemented:
|
// Deliberately unimplemented:
|
||||||
virtual void StartGroup( const std::string& ){}
|
virtual void StartGroup( const std::string& ){}
|
||||||
@@ -107,7 +107,7 @@ namespace Catch
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Totals m_totals;
|
Totals m_totals;
|
||||||
|
|
||||||
id<iTchRunnerDelegate> m_delegate;
|
id<iTchRunnerDelegate> m_delegate;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user