mirror of
https://github.com/catchorg/Catch2.git
synced 2025-09-18 02:45:40 +02:00
Compare commits
68 Commits
v1.2.1-dev
...
v1.3.4
Author | SHA1 | Date | |
---|---|---|---|
![]() |
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 |
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', '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: xcode6.4
|
||||||
|
compiler: clang
|
||||||
|
env: COMPILER='ccache clang++' BUILD_TYPE='Debug'
|
||||||
|
|
||||||
|
- os: osx
|
||||||
|
osx_image: xcode6.4
|
||||||
|
compiler: clang
|
||||||
|
env: COMPILER='ccache clang++' BUILD_TYPE='Release'
|
||||||
|
|
||||||
|
|
||||||
|
- 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'
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
|
brew install cmake 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.3.4*
|
||||||
|
|
||||||
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)
|
||||||
|
@@ -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)
|
||||||
|
@@ -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 )
|
||||||
|
@@ -43,7 +43,7 @@ namespace Catch {
|
|||||||
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;
|
||||||
@@ -52,27 +52,15 @@ namespace Catch {
|
|||||||
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 );
|
|
||||||
reporter = addListeners( config.get(), reporter );
|
|
||||||
|
|
||||||
RunContext context( config.get(), reporter );
|
Ptr<IStreamingReporter> reporter = makeReporter( config );
|
||||||
|
reporter = addListeners( iconfig, reporter );
|
||||||
|
|
||||||
|
RunContext context( iconfig, reporter );
|
||||||
|
|
||||||
Totals totals;
|
Totals totals;
|
||||||
|
|
||||||
@@ -82,17 +70,17 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +131,7 @@ 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* 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( argc, argv, m_configData );
|
||||||
@@ -170,13 +158,16 @@ namespace Catch {
|
|||||||
m_config.reset();
|
m_config.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
int run( int argc, char* const argv[] ) {
|
int run( int argc, char const* argv[] ) {
|
||||||
|
|
||||||
int returnCode = applyCommandLine( argc, argv );
|
int returnCode = applyCommandLine( argc, argv );
|
||||||
if( returnCode == 0 )
|
if( returnCode == 0 )
|
||||||
returnCode = run();
|
returnCode = run();
|
||||||
return returnCode;
|
return returnCode;
|
||||||
}
|
}
|
||||||
|
int run( int argc, char* argv[] ) {
|
||||||
|
return run( argc, const_cast<char const**>( argv ) );
|
||||||
|
}
|
||||||
|
|
||||||
int run() {
|
int run() {
|
||||||
if( m_configData.showHelp )
|
if( m_configData.showHelp )
|
||||||
|
@@ -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
|
||||||
|
201
include/external/clara.h
vendored
201
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.1.1
|
||||||
|
|
||||||
// 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,13 +175,171 @@ 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>
|
||||||
|
|
||||||
@@ -205,6 +366,9 @@ namespace Clara {
|
|||||||
const unsigned int consoleWidth = 80;
|
const unsigned int consoleWidth = 80;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Use this to try and stop compiler from warning about unreachable code
|
||||||
|
inline bool isTrue( bool value ) { return value; }
|
||||||
|
|
||||||
using namespace Tbc;
|
using namespace Tbc;
|
||||||
|
|
||||||
inline bool startsWith( std::string const& str, std::string const& prefix ) {
|
inline bool startsWith( std::string const& str, std::string const& prefix ) {
|
||||||
@@ -245,16 +409,17 @@ namespace Clara {
|
|||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline void convertInto( bool, T& ) {
|
inline void convertInto( bool, T& ) {
|
||||||
throw std::runtime_error( "Invalid conversion" );
|
if( isTrue( true ) )
|
||||||
|
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 void setFlag( ConfigT& config ) const = 0;
|
||||||
virtual bool takesArg() const = 0;
|
virtual bool takesArg() const = 0;
|
||||||
@@ -264,11 +429,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;
|
||||||
@@ -284,7 +449,7 @@ namespace Clara {
|
|||||||
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;
|
||||||
@@ -393,7 +558,7 @@ namespace Clara {
|
|||||||
std::string data;
|
std::string data;
|
||||||
};
|
};
|
||||||
|
|
||||||
void parseIntoTokens( int argc, char const * const * argv, std::vector<Parser::Token>& tokens ) const {
|
void parseIntoTokens( int argc, char const* const argv[], std::vector<Parser::Token>& tokens ) const {
|
||||||
const std::string doubleDash = "--";
|
const std::string doubleDash = "--";
|
||||||
for( int i = 1; i < argc && argv[i] != doubleDash; ++i )
|
for( int i = 1; i < argc && argv[i] != doubleDash; ++i )
|
||||||
parseIntoTokens( argv[i] , tokens);
|
parseIntoTokens( argv[i] , tokens);
|
||||||
@@ -503,7 +668,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 +745,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 +830,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,13 +894,13 @@ namespace Clara {
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigT parse( int argc, char const * const * argv ) const {
|
ConfigT parse( int argc, char const* const argv[] ) const {
|
||||||
ConfigT config;
|
ConfigT config;
|
||||||
parseInto( argc, argv, config );
|
parseInto( argc, argv, config );
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Parser::Token> parseInto( int argc, char const * const * argv, ConfigT& config ) const {
|
std::vector<Parser::Token> parseInto( int argc, char const* argv[], ConfigT& config ) const {
|
||||||
std::string processName = argv[0];
|
std::string processName = argv[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 )
|
||||||
|
@@ -39,7 +39,7 @@
|
|||||||
__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 && static_cast<bool>(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 +129,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 ); \
|
||||||
|
@@ -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,7 +126,7 @@ 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; }
|
||||||
@@ -154,14 +136,25 @@ namespace Catch {
|
|||||||
virtual bool forceColour() const { return m_data.forceColour; }
|
virtual bool forceColour() const { return m_data.forceColour; }
|
||||||
|
|
||||||
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;
|
std::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,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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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__
|
||||||
|
@@ -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 );
|
||||||
|
@@ -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 {
|
||||||
@@ -261,7 +261,7 @@ 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;
|
||||||
};
|
};
|
||||||
|
@@ -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; }
|
||||||
@@ -188,7 +234,7 @@ namespace Matchers {
|
|||||||
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();
|
||||||
|
@@ -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;
|
||||||
|
@@ -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,14 +94,18 @@ 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 );
|
||||||
@@ -120,7 +117,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 +153,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,9 +167,11 @@ 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++;
|
||||||
@@ -181,13 +182,22 @@ namespace Catch {
|
|||||||
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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,7 +266,6 @@ 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 );
|
||||||
|
|
||||||
@@ -278,6 +287,7 @@ namespace Catch {
|
|||||||
catch(...) {
|
catch(...) {
|
||||||
makeUnexpectedResultBuilder().useActiveException();
|
makeUnexpectedResultBuilder().useActiveException();
|
||||||
}
|
}
|
||||||
|
m_testCaseTracker->close();
|
||||||
handleUnfinishedSections();
|
handleUnfinishedSections();
|
||||||
m_messages.clear();
|
m_messages.clear();
|
||||||
|
|
||||||
@@ -323,18 +333,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() {
|
||||||
|
@@ -9,28 +9,55 @@
|
|||||||
#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>
|
||||||
|
|
||||||
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 {
|
||||||
|
std::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"
|
||||||
|
@@ -87,7 +87,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 +155,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,307 @@
|
|||||||
#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();
|
||||||
|
|
||||||
typedef std::map<std::string, TrackedSection> TrackedSections;
|
// 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TrackerContext {
|
||||||
|
|
||||||
public:
|
|
||||||
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 );
|
ITracker& startRun();
|
||||||
TrackedSection* acquireChild( std::string const& childName );
|
|
||||||
|
|
||||||
void enter() {
|
void endRun() {
|
||||||
if( m_runState == NotStarted )
|
m_rootTracker.reset();
|
||||||
m_runState = Executing;
|
m_currentTracker = CATCH_NULL;
|
||||||
|
m_runState = NotStarted;
|
||||||
}
|
}
|
||||||
void leave();
|
|
||||||
|
|
||||||
TrackedSection* getParent() {
|
void startCycle() {
|
||||||
return m_parent;
|
m_currentTracker = m_rootTracker.get();
|
||||||
|
m_runState = Executing;
|
||||||
}
|
}
|
||||||
bool hasChildren() const {
|
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;
|
|
||||||
RunState m_runState;
|
|
||||||
TrackedSections m_children;
|
|
||||||
TrackedSection* m_parent;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline TrackedSection* TrackedSection::findChild( std::string const& childName ) {
|
virtual void addChild( Ptr<ITracker> const& child ) CATCH_OVERRIDE {
|
||||||
TrackedSections::iterator it = m_children.find( childName );
|
m_children.push_back( child );
|
||||||
return it != m_children.end()
|
}
|
||||||
? &it->second
|
|
||||||
: CATCH_NULL;
|
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::acquireChild( std::string const& childName ) {
|
return( it != m_children.end() )
|
||||||
if( TrackedSection* child = findChild( childName ) )
|
? it->get()
|
||||||
return child;
|
: CATCH_NULL;
|
||||||
m_children.insert( std::make_pair( childName, TrackedSection( childName, this ) ) );
|
}
|
||||||
return findChild( childName );
|
virtual ITracker& parent() CATCH_OVERRIDE {
|
||||||
}
|
assert( m_parent ); // Should always be non-null except for root
|
||||||
inline void TrackedSection::leave() {
|
return *m_parent;
|
||||||
for( TrackedSections::const_iterator it = m_children.begin(), itEnd = m_children.end();
|
}
|
||||||
it != itEnd;
|
|
||||||
++it )
|
virtual void openChild() CATCH_OVERRIDE {
|
||||||
if( it->second.runState() != Completed ) {
|
if( m_runState != ExecutingChildren ) {
|
||||||
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() {
|
void open() {
|
||||||
m_currentSection->leave();
|
m_runState = Executing;
|
||||||
m_currentSection = m_currentSection->getParent();
|
moveToThis();
|
||||||
assert( m_currentSection != CATCH_NULL );
|
if( m_parent )
|
||||||
m_completedASectionThisRun = true;
|
m_parent->openChild();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool currentSectionHasChildren() const {
|
virtual void close() CATCH_OVERRIDE {
|
||||||
return m_currentSection->hasChildren();
|
|
||||||
}
|
|
||||||
bool isCompleted() const {
|
|
||||||
return m_testCase.runState() == TrackedSection::Completed;
|
|
||||||
}
|
|
||||||
|
|
||||||
class Guard {
|
// Close any still open children (e.g. generators)
|
||||||
public:
|
while( &m_ctx.currentTracker() != this )
|
||||||
Guard( TestCaseTracker& tracker ) : m_tracker( tracker ) {
|
m_ctx.currentTracker().close();
|
||||||
m_tracker.enterTestCase();
|
|
||||||
|
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;
|
static SectionTracker& acquire( TrackerContext& ctx, std::string const& name ) {
|
||||||
|
SectionTracker* section = CATCH_NULL;
|
||||||
|
|
||||||
|
ITracker& currentTracker = ctx.currentTracker();
|
||||||
|
if( ITracker* childTracker = currentTracker.findChild( name ) ) {
|
||||||
|
section = dynamic_cast<SectionTracker*>( childTracker );
|
||||||
|
assert( section );
|
||||||
|
}
|
||||||
|
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();
|
||||||
|
|
||||||
|
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 ) ) {
|
||||||
|
tracker = dynamic_cast<IndexTracker*>( childTracker );
|
||||||
|
assert( tracker );
|
||||||
|
}
|
||||||
|
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,6 +76,11 @@ 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
|
||||||
@@ -94,6 +104,10 @@ private:
|
|||||||
} \
|
} \
|
||||||
void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
|
void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
|
||||||
|
Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) );
|
||||||
|
|
||||||
#else
|
#else
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
|
#define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
|
||||||
@@ -115,6 +129,9 @@ private:
|
|||||||
} \
|
} \
|
||||||
void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
|
void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
#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
|
||||||
|
@@ -37,7 +37,7 @@ namespace Catch {
|
|||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
Version libraryVersion( 1, 2, 1, "develop", 14 );
|
Version libraryVersion( 1, 3, 4, "", 0 );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
@@ -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;
|
||||||
@@ -237,7 +237,7 @@ namespace Catch {
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -22,7 +22,7 @@ set(SOURCES
|
|||||||
${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
|
||||||
|
@@ -356,7 +356,7 @@ due to unexpected exception with message:
|
|||||||
expected exception
|
expected exception
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Unexpected custom exceptions can be translated
|
Non-std exceptions can be translated
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
ExceptionTests.cpp:<line number>
|
ExceptionTests.cpp:<line number>
|
||||||
...............................................................................
|
...............................................................................
|
||||||
@@ -365,6 +365,16 @@ ExceptionTests.cpp:<line number>: FAILED:
|
|||||||
due to unexpected exception with message:
|
due to unexpected exception with message:
|
||||||
custom exception
|
custom exception
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Custom exceptions can be translated when testing for nothrow
|
Custom exceptions can be translated when testing for nothrow
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -670,7 +680,7 @@ MiscTests.cpp:<line number>
|
|||||||
...............................................................................
|
...............................................................................
|
||||||
|
|
||||||
MiscTests.cpp:<line number>: FAILED:
|
MiscTests.cpp:<line number>: FAILED:
|
||||||
CHECK_THAT( testStringForMatching() Contains( "not there" ) )
|
CHECK_THAT( testStringForMatching(), Contains( "not there" ) )
|
||||||
with expansion:
|
with expansion:
|
||||||
"this string contains 'abc' as a substring" contains: "not there"
|
"this string contains 'abc' as a substring" contains: "not there"
|
||||||
|
|
||||||
@@ -681,7 +691,7 @@ MiscTests.cpp:<line number>
|
|||||||
...............................................................................
|
...............................................................................
|
||||||
|
|
||||||
MiscTests.cpp:<line number>: FAILED:
|
MiscTests.cpp:<line number>: FAILED:
|
||||||
CHECK_THAT( testStringForMatching() StartsWith( "string" ) )
|
CHECK_THAT( testStringForMatching(), StartsWith( "string" ) )
|
||||||
with expansion:
|
with expansion:
|
||||||
"this string contains 'abc' as a substring" starts with: "string"
|
"this string contains 'abc' as a substring" starts with: "string"
|
||||||
|
|
||||||
@@ -692,7 +702,7 @@ MiscTests.cpp:<line number>
|
|||||||
...............................................................................
|
...............................................................................
|
||||||
|
|
||||||
MiscTests.cpp:<line number>: FAILED:
|
MiscTests.cpp:<line number>: FAILED:
|
||||||
CHECK_THAT( testStringForMatching() EndsWith( "this" ) )
|
CHECK_THAT( testStringForMatching(), EndsWith( "this" ) )
|
||||||
with expansion:
|
with expansion:
|
||||||
"this string contains 'abc' as a substring" ends with: "this"
|
"this string contains 'abc' as a substring" ends with: "this"
|
||||||
|
|
||||||
@@ -703,10 +713,33 @@ MiscTests.cpp:<line number>
|
|||||||
...............................................................................
|
...............................................................................
|
||||||
|
|
||||||
MiscTests.cpp:<line number>: FAILED:
|
MiscTests.cpp:<line number>: FAILED:
|
||||||
CHECK_THAT( testStringForMatching() Equals( "something else" ) )
|
CHECK_THAT( testStringForMatching(), Equals( "something else" ) )
|
||||||
with expansion:
|
with expansion:
|
||||||
"this string contains 'abc' as a substring" equals: "something else"
|
"this string contains 'abc' as a substring" equals: "something else"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Nice descriptive name
|
Nice descriptive name
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -797,6 +830,6 @@ with expansion:
|
|||||||
"first" == "second"
|
"first" == "second"
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
test cases: 159 | 119 passed | 39 failed | 1 failed as expected
|
test cases: 167 | 124 passed | 42 failed | 1 failed as expected
|
||||||
assertions: 788 | 695 passed | 80 failed | 13 failed as expected
|
assertions: 914 | 818 passed | 83 failed | 13 failed as expected
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
<testsuites>
|
<testsuites>
|
||||||
<testsuite name="CatchSelfTest" errors="12" failures="88" tests="808" hostname="tbd" time="{duration}" timestamp="tbd">
|
<testsuite name="CatchSelfTest" errors="13" failures="72" tests="916" hostname="tbd" time="{duration}" timestamp="tbd">
|
||||||
<testcase classname="global" name="toString(enum)" time="{duration}"/>
|
<testcase classname="global" name="toString(enum)" time="{duration}"/>
|
||||||
<testcase classname="global" name="toString(enum w/operator<<)" time="{duration}"/>
|
<testcase classname="global" name="toString(enum w/operator<<)" time="{duration}"/>
|
||||||
<testcase classname="global" name="toString(enum class)" time="{duration}"/>
|
<testcase classname="global" name="toString(enum class)" time="{duration}"/>
|
||||||
@@ -226,9 +226,15 @@ expected exception
|
|||||||
ExceptionTests.cpp:<line number>
|
ExceptionTests.cpp:<line number>
|
||||||
</error>
|
</error>
|
||||||
</testcase>
|
</testcase>
|
||||||
<testcase classname="global" name="Unexpected custom exceptions can be translated" time="{duration}">
|
<testcase classname="global" name="Non-std exceptions can be translated" time="{duration}">
|
||||||
<error type="TEST_CASE">
|
<error type="TEST_CASE">
|
||||||
custom exception
|
custom exception
|
||||||
|
ExceptionTests.cpp:<line number>
|
||||||
|
</error>
|
||||||
|
</testcase>
|
||||||
|
<testcase classname="global" name="Custom std-exceptions can be custom translated" time="{duration}">
|
||||||
|
<error type="TEST_CASE">
|
||||||
|
custom std exception
|
||||||
ExceptionTests.cpp:<line number>
|
ExceptionTests.cpp:<line number>
|
||||||
</error>
|
</error>
|
||||||
</testcase>
|
</testcase>
|
||||||
@@ -341,6 +347,11 @@ MessageTests.cpp:<line number>
|
|||||||
MiscTests.cpp:<line number>
|
MiscTests.cpp:<line number>
|
||||||
</failure>
|
</failure>
|
||||||
</testcase>
|
</testcase>
|
||||||
|
<testcase classname="more nested SECTION tests" name="s1/s3" time="{duration}"/>
|
||||||
|
<testcase classname="more nested SECTION tests" name="s1/s4" time="{duration}"/>
|
||||||
|
<testcase classname="even more nested SECTION tests" name="c/d (leaf)" time="{duration}"/>
|
||||||
|
<testcase classname="even more nested SECTION tests" name="c/e (leaf)" time="{duration}"/>
|
||||||
|
<testcase classname="even more nested SECTION tests" name="f (leaf)" time="{duration}"/>
|
||||||
<testcase classname="looped SECTION tests" name="s1" time="{duration}">
|
<testcase classname="looped SECTION tests" name="s1" time="{duration}">
|
||||||
<failure message="0 > 1" type="CHECK">
|
<failure message="0 > 1" type="CHECK">
|
||||||
MiscTests.cpp:<line number>
|
MiscTests.cpp:<line number>
|
||||||
@@ -399,6 +410,8 @@ MiscTests.cpp:<line number>
|
|||||||
MiscTests.cpp:<line number>
|
MiscTests.cpp:<line number>
|
||||||
</failure>
|
</failure>
|
||||||
</testcase>
|
</testcase>
|
||||||
|
<testcase classname="xmlentitycheck" name="embedded xml" time="{duration}"/>
|
||||||
|
<testcase classname="xmlentitycheck" name="encoded chars" time="{duration}"/>
|
||||||
<testcase classname="global" name="send a single char to INFO" time="{duration}">
|
<testcase classname="global" name="send a single char to INFO" time="{duration}">
|
||||||
<failure message="false" type="REQUIRE">
|
<failure message="false" type="REQUIRE">
|
||||||
3
|
3
|
||||||
@@ -431,6 +444,20 @@ MiscTests.cpp:<line number>
|
|||||||
<testcase classname="global" name="AllOf matcher" time="{duration}"/>
|
<testcase classname="global" name="AllOf matcher" time="{duration}"/>
|
||||||
<testcase classname="global" name="AnyOf matcher" time="{duration}"/>
|
<testcase classname="global" name="AnyOf matcher" time="{duration}"/>
|
||||||
<testcase classname="global" name="Equals" time="{duration}"/>
|
<testcase classname="global" name="Equals" time="{duration}"/>
|
||||||
|
<testcase classname="global" name="Matchers can be (AllOf) composed with the && operator" time="{duration}"/>
|
||||||
|
<testcase classname="global" name="Matchers can be (AnyOf) composed with the || operator" time="{duration}"/>
|
||||||
|
<testcase classname="global" name="Matchers can be composed with both && and ||" time="{duration}"/>
|
||||||
|
<testcase classname="global" name="Matchers can be composed with both && and || - failing" time="{duration}">
|
||||||
|
<failure message=""this string contains 'abc' as a substring" ( ( contains: "string" or contains: "different" ) and contains: "random" )" type="CHECK_THAT">
|
||||||
|
MiscTests.cpp:<line number>
|
||||||
|
</failure>
|
||||||
|
</testcase>
|
||||||
|
<testcase classname="global" name="Matchers can be negated (Not) with the ! operator" time="{duration}"/>
|
||||||
|
<testcase classname="global" name="Matchers can be negated (Not) with the ! operator - failing" time="{duration}">
|
||||||
|
<failure message=""this string contains 'abc' as a substring" not contains: "substring"" type="CHECK_THAT">
|
||||||
|
MiscTests.cpp:<line number>
|
||||||
|
</failure>
|
||||||
|
</testcase>
|
||||||
<testcase classname="global" name="Factorials are computed" time="{duration}"/>
|
<testcase classname="global" name="Factorials are computed" time="{duration}"/>
|
||||||
<testcase classname="global" name="Nice descriptive name" time="{duration}"/>
|
<testcase classname="global" name="Nice descriptive name" time="{duration}"/>
|
||||||
<testcase classname="vectors can be sized and resized" name="root" time="{duration}"/>
|
<testcase classname="vectors can be sized and resized" name="root" time="{duration}"/>
|
||||||
@@ -520,6 +547,7 @@ hello
|
|||||||
</testcase>
|
</testcase>
|
||||||
<testcase classname="global" name="Text can be formatted using the Text class" time="{duration}"/>
|
<testcase classname="global" name="Text can be formatted using the Text class" time="{duration}"/>
|
||||||
<testcase classname="global" name="Long text is truncted" time="{duration}"/>
|
<testcase classname="global" name="Long text is truncted" time="{duration}"/>
|
||||||
|
<testcase classname="global" name="ManuallyRegistered" time="{duration}"/>
|
||||||
<testcase classname="global" name="Parsing a std::pair" time="{duration}"/>
|
<testcase classname="global" name="Parsing a std::pair" time="{duration}"/>
|
||||||
<testcase classname="global" name="Where there is more to the expression after the RHS" time="{duration}"/>
|
<testcase classname="global" name="Where there is more to the expression after the RHS" time="{duration}"/>
|
||||||
<testcase classname="global" name="Where the LHS is not a simple value" time="{duration}"/>
|
<testcase classname="global" name="Where the LHS is not a simple value" time="{duration}"/>
|
||||||
@@ -566,6 +594,23 @@ TrickyTests.cpp:<line number>
|
|||||||
<testcase classname="global" name="toString( vectors<has_toString )" time="{duration}"/>
|
<testcase classname="global" name="toString( vectors<has_toString )" time="{duration}"/>
|
||||||
<testcase classname="global" name="toString( vectors<has_maker )" time="{duration}"/>
|
<testcase classname="global" name="toString( vectors<has_maker )" time="{duration}"/>
|
||||||
<testcase classname="global" name="toString( vectors<has_maker_and_toString )" time="{duration}"/>
|
<testcase classname="global" name="toString( vectors<has_maker_and_toString )" time="{duration}"/>
|
||||||
|
<testcase classname="Tracker" name="root" time="{duration}"/>
|
||||||
|
<testcase classname="Tracker" name="successfully close one section" time="{duration}"/>
|
||||||
|
<testcase classname="Tracker" name="fail one section" time="{duration}"/>
|
||||||
|
<testcase classname="Tracker" name="fail one section/re-enter after failed section" time="{duration}"/>
|
||||||
|
<testcase classname="Tracker" name="fail one section/re-enter after failed section and find next section" time="{duration}"/>
|
||||||
|
<testcase classname="Tracker" name="successfully close one section, then find another" time="{duration}"/>
|
||||||
|
<testcase classname="Tracker" name="successfully close one section, then find another/Re-enter - skips S1 and enters S2" time="{duration}"/>
|
||||||
|
<testcase classname="Tracker" name="successfully close one section, then find another/Re-enter - skips S1 and enters S2/Successfully close S2" time="{duration}"/>
|
||||||
|
<testcase classname="Tracker" name="successfully close one section, then find another/Re-enter - skips S1 and enters S2/fail S2" time="{duration}"/>
|
||||||
|
<testcase classname="Tracker" name="open a nested section" time="{duration}"/>
|
||||||
|
<testcase classname="Tracker" name="start a generator" time="{duration}"/>
|
||||||
|
<testcase classname="Tracker" name="start a generator/close outer section" time="{duration}"/>
|
||||||
|
<testcase classname="Tracker" name="start a generator/close outer section/Re-enter for second generation" time="{duration}"/>
|
||||||
|
<testcase classname="Tracker" name="start a generator/Start a new inner section" time="{duration}"/>
|
||||||
|
<testcase classname="Tracker" name="start a generator/Start a new inner section/Re-enter for second generation" time="{duration}"/>
|
||||||
|
<testcase classname="Tracker" name="start a generator/Fail an inner section" time="{duration}"/>
|
||||||
|
<testcase classname="Tracker" name="start a generator/Fail an inner section/Re-enter for second generation" time="{duration}"/>
|
||||||
<testcase classname="global" name="std::pair<int,std::string> -> toString" time="{duration}"/>
|
<testcase classname="global" name="std::pair<int,std::string> -> toString" time="{duration}"/>
|
||||||
<testcase classname="global" name="std::pair<int,const std::string> -> toString" time="{duration}"/>
|
<testcase classname="global" name="std::pair<int,const std::string> -> toString" time="{duration}"/>
|
||||||
<testcase classname="global" name="std::vector<std::pair<std::string,int> > -> toString" time="{duration}"/>
|
<testcase classname="global" name="std::vector<std::pair<std::string,int> > -> toString" time="{duration}"/>
|
||||||
@@ -625,11 +670,6 @@ TrickyTests.cpp:<line number>
|
|||||||
<testcase classname="Scenario: This is a really long scenario name to see how the list command deals with wrapping" name="Given: A section name that is so long that it cannot fit in a single console width/When: The test headers are printed as part of the normal running of the scenario/Then: The, deliberately very long and overly verbose (you see what I did there?) section names must wrap, along with an indent" time="{duration}"/>
|
<testcase classname="Scenario: This is a really long scenario name to see how the list command deals with wrapping" name="Given: A section name that is so long that it cannot fit in a single console width/When: The test headers are printed as part of the normal running of the scenario/Then: The, deliberately very long and overly verbose (you see what I did there?) section names must wrap, along with an indent" time="{duration}"/>
|
||||||
<testcase classname="Fixture" name="Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or methods/Given: No operations precede me" time="{duration}"/>
|
<testcase classname="Fixture" name="Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or methods/Given: No operations precede me" time="{duration}"/>
|
||||||
<testcase classname="Fixture" name="Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or methods/Given: No operations precede me/When: We get the count/Then: Subsequently values are higher" time="{duration}"/>
|
<testcase classname="Fixture" name="Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or methods/Given: No operations precede me/When: We get the count/Then: Subsequently values are higher" time="{duration}"/>
|
||||||
<testcase classname="section tracking" name="root" time="{duration}"/>
|
|
||||||
<testcase classname="section tracking" name="test case with no sections" time="{duration}"/>
|
|
||||||
<testcase classname="section tracking" name="test case with one section" time="{duration}"/>
|
|
||||||
<testcase classname="section tracking" name="test case with two consecutive sections" time="{duration}"/>
|
|
||||||
<testcase classname="section tracking" name="test case with one section within another" time="{duration}"/>
|
|
||||||
<system-out>
|
<system-out>
|
||||||
Message from section one
|
Message from section one
|
||||||
Message from section two
|
Message from section two
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -106,22 +106,51 @@ 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" );
|
||||||
|
@@ -80,15 +80,18 @@ 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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,11 +180,11 @@ 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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,6 +208,12 @@ 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]" )
|
||||||
{
|
{
|
||||||
@@ -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;
|
||||||
|
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,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_suppress_warnings.h"
|
||||||
#include "catch_stream.h"
|
#include "catch_stream.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 ) );
|
||||||
|
@@ -44,6 +44,8 @@ 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", "" ) {
|
||||||
@@ -447,3 +449,13 @@ TEST_CASE( "Long text is truncted", "[Text][Truncated]" ) {
|
|||||||
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;
|
||||||
|
@@ -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;
|
||||||
|
46
scripts/fixTrailingWhitespace.py
Normal file
46
scripts/fixTrailingWhitespace.py
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
from __future__ import print_function
|
||||||
|
import os
|
||||||
|
from scriptCommon import catchPath
|
||||||
|
|
||||||
|
changedFiles = 0
|
||||||
|
|
||||||
|
def isSourceFile( path ):
|
||||||
|
return path.endswith( ".cpp" ) or path.endswith( ".h" ) or path.endswith( ".hpp" )
|
||||||
|
|
||||||
|
def fixAllFilesInDir( dir ):
|
||||||
|
for f in os.listdir( dir ):
|
||||||
|
path = os.path.join( dir,f )
|
||||||
|
if os.path.isfile( path ):
|
||||||
|
if isSourceFile( path ):
|
||||||
|
fixFile( path )
|
||||||
|
else:
|
||||||
|
fixAllFilesInDir( path )
|
||||||
|
|
||||||
|
def fixFile( path ):
|
||||||
|
f = open( path, 'r' )
|
||||||
|
lines = []
|
||||||
|
changed = 0
|
||||||
|
for line in f:
|
||||||
|
trimmed = line.rstrip() + "\n"
|
||||||
|
if trimmed != line:
|
||||||
|
changed = changed +1
|
||||||
|
lines.append( trimmed )
|
||||||
|
f.close()
|
||||||
|
if changed > 0:
|
||||||
|
global changedFiles
|
||||||
|
changedFiles = changedFiles + 1
|
||||||
|
print( path + ":" )
|
||||||
|
print( " - fixed " + str(changed) + " line(s)" )
|
||||||
|
altPath = path + ".backup"
|
||||||
|
os.rename( path, altPath )
|
||||||
|
f2 = open( path, 'w' )
|
||||||
|
for line in lines:
|
||||||
|
f2.write( line )
|
||||||
|
f2.close()
|
||||||
|
os.remove( altPath )
|
||||||
|
|
||||||
|
fixAllFilesInDir(catchPath)
|
||||||
|
if changedFiles > 0:
|
||||||
|
print( "Fixed " + str(changedFiles) + " file(s)" )
|
||||||
|
else:
|
||||||
|
print( "No trailing whitespace found" )
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user