mirror of
https://github.com/catchorg/Catch2.git
synced 2025-09-15 01:45:39 +02:00
Compare commits
53 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d08cee288f | ||
![]() |
873ef276b6 | ||
![]() |
bc68b9f454 | ||
![]() |
67d513aa73 | ||
![]() |
9a3486a705 | ||
![]() |
d890791800 | ||
![]() |
26f6012bb9 | ||
![]() |
50dee9ae57 | ||
![]() |
b2a6fe971b | ||
![]() |
9012f95964 | ||
![]() |
324260f253 | ||
![]() |
d0620c3495 | ||
![]() |
fd7dde10d3 | ||
![]() |
9a3788d98c | ||
![]() |
005787f1c5 | ||
![]() |
d2e814ff23 | ||
![]() |
f75a511b5c | ||
![]() |
ab44fb6811 | ||
![]() |
d6b8ac5a4e | ||
![]() |
c72ba93f92 | ||
![]() |
73159ace3d | ||
![]() |
9952dda524 | ||
![]() |
e543cc0646 | ||
![]() |
c1a5391034 | ||
![]() |
a38ccec33a | ||
![]() |
1ff56301a1 | ||
![]() |
aee3675968 | ||
![]() |
0579f07092 | ||
![]() |
e9ad954435 | ||
![]() |
1e87cae8af | ||
![]() |
4d0cd602e3 | ||
![]() |
ab199d9cf9 | ||
![]() |
97d8003a71 | ||
![]() |
1f271c9944 | ||
![]() |
7db4d8d90c | ||
![]() |
a5ce57b346 | ||
![]() |
7b8a27eadb | ||
![]() |
2b74613c54 | ||
![]() |
23600609c0 | ||
![]() |
4feb2dbb50 | ||
![]() |
84af6bc955 | ||
![]() |
197bf075c4 | ||
![]() |
1f5ec9884c | ||
![]() |
88b760276d | ||
![]() |
23eb4cc580 | ||
![]() |
a189387f49 | ||
![]() |
f65776890c | ||
![]() |
39753558eb | ||
![]() |
f126d7943a | ||
![]() |
cd489d9647 | ||
![]() |
e991c006b7 | ||
![]() |
7e7c813486 | ||
![]() |
712323ab7c |
137
.travis.yml
137
.travis.yml
@@ -1,35 +1,35 @@
|
||||
language: cpp
|
||||
sudo: false
|
||||
|
||||
cache:
|
||||
ccache: true
|
||||
directories:
|
||||
- $HOME/.ccache
|
||||
|
||||
env:
|
||||
global:
|
||||
- USE_CCACHE=1
|
||||
- CCACHE_COMPRESS=1
|
||||
- CCACHE_MAXSIZE=200M
|
||||
- CCACHE_CPP2=1
|
||||
|
||||
|
||||
matrix:
|
||||
include:
|
||||
|
||||
# 1/ Linux Clang Builds
|
||||
- os: linux
|
||||
compiler: clang
|
||||
addons: &clang34
|
||||
apt:
|
||||
sources: ['llvm-toolchain-precise', 'ubuntu-toolchain-r-test']
|
||||
packages: ['clang']
|
||||
env: COMPILER='clang++' BUILD_TYPE='Release' CPP11=0
|
||||
|
||||
- os: linux
|
||||
compiler: clang
|
||||
addons: *clang34
|
||||
env: COMPILER='clang++' BUILD_TYPE='Debug' CPP11=0
|
||||
|
||||
- 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'
|
||||
env: COMPILER='clang++-3.5' BUILD_TYPE='Release' CPP11=0
|
||||
|
||||
- os: linux
|
||||
compiler: clang
|
||||
addons: *clang35
|
||||
env: COMPILER='ccache clang++-3.5' BUILD_TYPE='Debug'
|
||||
env: COMPILER='clang++-3.5' BUILD_TYPE='Debug' CPP11=0
|
||||
|
||||
|
||||
- os: linux
|
||||
@@ -38,12 +38,12 @@ matrix:
|
||||
apt:
|
||||
sources: ['llvm-toolchain-precise-3.6', 'ubuntu-toolchain-r-test']
|
||||
packages: ['clang-3.6']
|
||||
env: COMPILER='ccache clang++-3.6' BUILD_TYPE='Release'
|
||||
env: COMPILER='clang++-3.6' BUILD_TYPE='Release' CPP11=0
|
||||
|
||||
- os: linux
|
||||
compiler: clang
|
||||
addons: *clang36
|
||||
env: COMPILER='ccache clang++-3.6' BUILD_TYPE='Debug'
|
||||
env: COMPILER='clang++-3.6' BUILD_TYPE='Debug' CPP11=0
|
||||
|
||||
|
||||
- os: linux
|
||||
@@ -52,12 +52,12 @@ matrix:
|
||||
apt:
|
||||
sources: ['llvm-toolchain-precise-3.7', 'ubuntu-toolchain-r-test']
|
||||
packages: ['clang-3.7']
|
||||
env: COMPILER='ccache clang++-3.7' BUILD_TYPE='Release'
|
||||
env: COMPILER='clang++-3.7' BUILD_TYPE='Release' CPP11=0
|
||||
|
||||
- os: linux
|
||||
compiler: clang
|
||||
addons: *clang37
|
||||
env: COMPILER='ccache clang++-3.7' BUILD_TYPE='Debug'
|
||||
env: COMPILER='clang++-3.7' BUILD_TYPE='Debug' CPP11=0
|
||||
|
||||
|
||||
- os: linux
|
||||
@@ -66,27 +66,55 @@ matrix:
|
||||
apt:
|
||||
sources: ['llvm-toolchain-precise-3.8', 'ubuntu-toolchain-r-test']
|
||||
packages: ['clang-3.8']
|
||||
env: COMPILER='ccache clang++-3.8' BUILD_TYPE='Release'
|
||||
env: COMPILER='clang++-3.8' BUILD_TYPE='Release' CPP11=0
|
||||
|
||||
- os: linux
|
||||
compiler: clang
|
||||
addons: *clang38
|
||||
env: COMPILER='ccache clang++-3.8' BUILD_TYPE='Debug'
|
||||
env: COMPILER='clang++-3.8' BUILD_TYPE='Debug' CPP11=0
|
||||
|
||||
|
||||
# 2/ Linux GCC Builds
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: &gcc44
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.4']
|
||||
env: COMPILER='g++-4.4' BUILD_TYPE='Release' CPP11=0
|
||||
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: *gcc44
|
||||
env: COMPILER='g++-4.4' BUILD_TYPE='Debug' CPP11=0
|
||||
|
||||
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: &gcc47
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.7']
|
||||
env: COMPILER='g++-4.7' BUILD_TYPE='Release' CPP11=0
|
||||
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: *gcc47
|
||||
env: COMPILER='g++-4.7' BUILD_TYPE='Debug' CPP11=0
|
||||
|
||||
|
||||
- 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'
|
||||
env: COMPILER='g++-4.8' BUILD_TYPE='Release' CPP11=0
|
||||
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: *gcc48
|
||||
env: COMPILER='ccache g++-4.8' BUILD_TYPE='Debug'
|
||||
env: COMPILER='g++-4.8' BUILD_TYPE='Debug' CPP11=0
|
||||
|
||||
|
||||
- os: linux
|
||||
@@ -95,12 +123,12 @@ matrix:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.9']
|
||||
env: COMPILER='ccache g++-4.9' BUILD_TYPE='Release'
|
||||
env: COMPILER='g++-4.9' BUILD_TYPE='Release' CPP11=0
|
||||
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: *gcc49
|
||||
env: COMPILER='ccache g++-4.9' BUILD_TYPE='Debug'
|
||||
env: COMPILER='g++-4.9' BUILD_TYPE='Debug' CPP11=0
|
||||
|
||||
|
||||
- os: linux
|
||||
@@ -109,34 +137,76 @@ matrix:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-5']
|
||||
env: COMPILER='ccache g++-5' BUILD_TYPE='Release'
|
||||
env: COMPILER='g++-5' BUILD_TYPE='Release' CPP11=0
|
||||
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: *gcc5
|
||||
env: COMPILER='ccache g++-5' BUILD_TYPE='Debug'
|
||||
env: COMPILER='g++-5' BUILD_TYPE='Debug' CPP11=0
|
||||
|
||||
|
||||
# 3/ OSX Clang Builds
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: &gcc6
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-6']
|
||||
env: COMPILER='g++-6' BUILD_TYPE='Release' CPP11=0
|
||||
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: *gcc6
|
||||
env: COMPILER='g++-6' BUILD_TYPE='Debug' CPP11=0
|
||||
|
||||
# 3a/ Linux C++11 GCC builds
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: &gcc48
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.8']
|
||||
env: COMPILER='g++-4.8' BUILD_TYPE='Release' CPP11=1
|
||||
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: *gcc48
|
||||
env: COMPILER='g++-4.8' BUILD_TYPE='Debug' CPP11=1
|
||||
|
||||
# 3b/ Linux C++11 Clang builds
|
||||
- os: linux
|
||||
compiler: clang
|
||||
addons: &clang38
|
||||
apt:
|
||||
sources: ['llvm-toolchain-precise-3.8', 'ubuntu-toolchain-r-test']
|
||||
packages: ['clang-3.8']
|
||||
env: COMPILER='clang++-3.8' BUILD_TYPE='Release' CPP11=1
|
||||
|
||||
- os: linux
|
||||
compiler: clang
|
||||
addons: *clang38
|
||||
env: COMPILER='clang++-3.8' BUILD_TYPE='Debug' CPP11=1
|
||||
|
||||
|
||||
# 4/ OSX Clang Builds
|
||||
- os: osx
|
||||
osx_image: xcode7.3
|
||||
compiler: clang
|
||||
env: COMPILER='ccache clang++' BUILD_TYPE='Debug'
|
||||
env: COMPILER='clang++' BUILD_TYPE='Debug' CPP11=0
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode7.3
|
||||
compiler: clang
|
||||
env: COMPILER='ccache clang++' BUILD_TYPE='Release'
|
||||
env: COMPILER='clang++' BUILD_TYPE='Release' CPP11=0
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode8
|
||||
compiler: clang
|
||||
env: COMPILER='ccache clang++' BUILD_TYPE='Debug'
|
||||
env: COMPILER='clang++' BUILD_TYPE='Debug' CPP11=0
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode8
|
||||
compiler: clang
|
||||
env: COMPILER='ccache clang++' BUILD_TYPE='Release'
|
||||
env: COMPILER='clang++' BUILD_TYPE='Release' CPP11=0
|
||||
|
||||
|
||||
install:
|
||||
@@ -149,13 +219,12 @@ install:
|
||||
export PATH=${DEPS_DIR}/cmake/bin:${PATH}
|
||||
elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
|
||||
which cmake || brew install cmake
|
||||
which ccache || brew install ccache
|
||||
fi
|
||||
|
||||
before_script:
|
||||
- export CXX=${COMPILER}
|
||||
- cd ${TRAVIS_BUILD_DIR}
|
||||
- cmake -H. -BBuild -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -Wdev
|
||||
- cmake -H. -BBuild -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -Wdev -DUSE_CPP11=${CPP11}
|
||||
- cd Build
|
||||
|
||||
script:
|
||||
|
@@ -53,6 +53,7 @@ set(TEST_SOURCES
|
||||
${SELF_TEST_DIR}/BDDTests.cpp
|
||||
${SELF_TEST_DIR}/ClassTests.cpp
|
||||
${SELF_TEST_DIR}/CmdLineTests.cpp
|
||||
${SELF_TEST_DIR}/CompilationTests.cpp
|
||||
${SELF_TEST_DIR}/ConditionTests.cpp
|
||||
${SELF_TEST_DIR}/EnumToString.cpp
|
||||
${SELF_TEST_DIR}/ExceptionTests.cpp
|
||||
@@ -62,6 +63,7 @@ set(TEST_SOURCES
|
||||
${SELF_TEST_DIR}/PartTrackerTests.cpp
|
||||
${SELF_TEST_DIR}/TagAliasTests.cpp
|
||||
${SELF_TEST_DIR}/TestMain.cpp
|
||||
${SELF_TEST_DIR}/ToStringGeneralTests.cpp
|
||||
${SELF_TEST_DIR}/ToStringPair.cpp
|
||||
${SELF_TEST_DIR}/ToStringTuple.cpp
|
||||
${SELF_TEST_DIR}/ToStringVector.cpp
|
||||
@@ -193,6 +195,7 @@ set(INTERNAL_HEADERS
|
||||
${HEADER_DIR}/internal/catch_tostring.h
|
||||
${HEADER_DIR}/internal/catch_tostring.hpp
|
||||
${HEADER_DIR}/internal/catch_totals.hpp
|
||||
${HEADER_DIR}/internal/catch_type_traits.hpp
|
||||
${HEADER_DIR}/internal/catch_version.h
|
||||
${HEADER_DIR}/internal/catch_version.hpp
|
||||
${HEADER_DIR}/internal/catch_wildcard_pattern.hpp
|
||||
|
@@ -1,10 +1,10 @@
|
||||

|
||||
|
||||
*v1.7.0*
|
||||
*v1.7.2*
|
||||
|
||||
Build status (on Travis CI) [](https://travis-ci.org/philsquared/Catch)
|
||||
|
||||
<a href="https://github.com/philsquared/Catch/releases/download/v1.7.0/catch.hpp">The latest, single header, version can be downloaded directly using this link</a>
|
||||
<a href="https://github.com/philsquared/Catch/releases/download/v1.7.2/catch.hpp">The latest, single header, version can be downloaded directly using this link</a>
|
||||
|
||||
## What's the Catch?
|
||||
|
||||
@@ -20,3 +20,4 @@ This documentation comprises these three parts:
|
||||
## More
|
||||
* Issues and bugs can be raised on the [Issue tracker on GitHub](https://github.com/philsquared/Catch/issues)
|
||||
* For discussion or questions please use [the dedicated Google Groups forum](https://groups.google.com/forum/?fromgroups#!forum/catch-forum)
|
||||
* See [who else is using Catch](docs/opensource-users.md)
|
||||
|
@@ -12,9 +12,11 @@ Before looking at this material be sure to read the [tutorial](tutorial.md)
|
||||
* [Configuration](configuration.md)
|
||||
* [String Conversions](tostring.md)
|
||||
* [Why are my tests slow to compile?](slow-compiles.md)
|
||||
* [Known limitations](limitations.md)
|
||||
|
||||
Other
|
||||
|
||||
* [Why Catch?](why-catch.md)
|
||||
* [Open Source Projects using Catch](opensource-users.md)
|
||||
* [Contributing](contributing.md)
|
||||
* [Release Notes](release-notes.md)
|
||||
* [Release Notes](release-notes.md)
|
||||
|
@@ -63,6 +63,11 @@ When dealing with very large or very small numbers it can be useful to specify a
|
||||
|
||||
## Exceptions
|
||||
|
||||
* **REQUIRE_NOTHROW(** _expression_ **)** and
|
||||
* **CHECK_NOTHROW(** _expression_ **)**
|
||||
|
||||
Expects that no exception is thrown during evaluation of the expression.
|
||||
|
||||
* **REQUIRE_THROWS(** _expression_ **)** and
|
||||
* **CHECK_THROWS(** _expression_ **)**
|
||||
|
||||
@@ -73,18 +78,41 @@ Expects that an exception (of any type) is be thrown during evaluation of the ex
|
||||
|
||||
Expects that an exception of the _specified type_ is thrown during evaluation of the expression.
|
||||
|
||||
* **REQUIRE_NOTHROW(** _expression_ **)** and
|
||||
* **CHECK_NOTHROW(** _expression_ **)**
|
||||
* **REQUIRE_THROWS_WITH(** _expression_, _string or string matcher_ **)** and
|
||||
* **CHECK_THROWS_WITH(** _expression_, _string or string matcher_ **)**
|
||||
|
||||
Expects that no exception is thrown during evaluation of the expression.
|
||||
Expects that an exception is thrown that, when converted to a string, matches the _string_ or _string matcher_ provided (see next section for Matchers).
|
||||
|
||||
e.g.
|
||||
```cpp
|
||||
REQUIRE_THROWS_WITH( openThePodBayDoors(), Contains( "afraid" ) && Contains( "can't do that" ) );
|
||||
REQUIRE_THROWS_WITH( dismantleHal(), "My mind is going" );
|
||||
```
|
||||
|
||||
|
||||
Please note that the `THROW` family of assertions expects to be passed a single expression, not a statement or series of statements. If you want to check a more complicated sequence of operations, you can use a C++11 lambda function.
|
||||
|
||||
```cpp
|
||||
REQUIRE_NOTHROW([&](){
|
||||
int i = 1;
|
||||
int j = 2;
|
||||
auto k = i + j;
|
||||
if (k == 3) {
|
||||
throw 1;
|
||||
}
|
||||
}());
|
||||
```
|
||||
|
||||
## Matcher expressions
|
||||
|
||||
To support Matchers a slightly different form is used. Matchers will be more fully documented elsewhere. *Note that Matchers are still at early stage development and are subject to change.*
|
||||
|
||||
* **REQUIRE_THAT(** _lhs_, _matcher call_ **)** and
|
||||
* **CHECK_THAT(** _lhs_, _matcher call_ **)**
|
||||
* **REQUIRE_THAT(** _lhs_, _matcher expression_ **)** and
|
||||
* **CHECK_THAT(** _lhs_, _matcher expression_ **)**
|
||||
|
||||
Currently only string matchers are implemented and consist of: `Contains`, `Equals`, `StartsWith` and `EndsWith`.
|
||||
|
||||
Matchers can be composed using `&&`, `||` and `!` operators.
|
||||
|
||||
---
|
||||
|
||||
|
@@ -93,7 +93,6 @@ The JUnit reporter is an xml format that follows the structure of the JUnit XML
|
||||
<pre>-b, --break</pre>
|
||||
|
||||
In some IDEs (currently XCode and Visual Studio) it is possible for Catch to break into the debugger on a test failure. This can be very helpful during debug sessions - especially when there is more than one path through a particular test.
|
||||
In addition to the command line option, ensure you have built your code with the DEBUG preprocessor symbol
|
||||
|
||||
<a id="showing-results-for-successful-tests"></a>
|
||||
## Showing results for successful tests
|
||||
|
12
docs/commercial-users.md
Normal file
12
docs/commercial-users.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Commercial users of Catch
|
||||
|
||||
As well as [Open Source](opensource-users.md) users Catch is widely used within proprietary code bases too. Many companies like to keep this
|
||||
information internal, and that's fine, but if you're more open it would be great if we could list the names of as
|
||||
many organisations as possible that use Catch somewhere in their codebase. Enterprise environments often tend to be
|
||||
far more conservative in their tool adoption - and being aware that other companies are using Catch can ease the
|
||||
path in.
|
||||
|
||||
So if you are aware of Catch usage in your organisation, and are fairly confident there is no issue with sharing this
|
||||
fact then please let us know - either directly, via a PR or [issue](https://github.com/philsquared/Catch/issues), or on the [forums](https://groups.google.com/forum/?fromgroups#!forum/catch-forum).
|
||||
|
||||
- Bloomberg
|
@@ -1,6 +1,6 @@
|
||||
Catch is designed to "just work" as much as possible. For most people the only configuration needed is telling Catch which source file should host all the implementation code (```CATCH_CONFIG_MAIN```).
|
||||
|
||||
Nonetheless there are still some occasions where finer control is needed. For these occasions Catch exposes a small set of macros for configuring how it is built.
|
||||
Nonetheless there are still some occasions where finer control is needed. For these occasions Catch exposes a set of macros for configuring how it is built.
|
||||
|
||||
# main()/ implementation
|
||||
|
||||
@@ -70,6 +70,15 @@ You may also suppress any of these features by using the `_NO_` form, e.g. `CATC
|
||||
|
||||
All C++11 support can be disabled with `CATCH_CONFIG_NO_CPP11`
|
||||
|
||||
# Other toggles
|
||||
|
||||
CATCH_CONFIG_COUNTER // Use __COUNTER__ to generate unique names for test cases
|
||||
CATCH_CONFIG_WINDOWS_SEH // Enable SEH handling on Windows
|
||||
|
||||
Currently Catch enables `CATCH_CONFIG_WINDOWS_SEH` only when compiled with MSVC, because some versions of MinGW do not have the necessary Win32 API supports.
|
||||
|
||||
Just as with the C++11 conformance toggles, these toggles can be disabled by using `_NO_` form of the toggle, e.g. `CATCH_CONFIG_NO_WINDOWS_SEH`.
|
||||
|
||||
# Windows header clutter
|
||||
|
||||
On Windows Catch includes `windows.h`. To minimize global namespace clutter in the implementation file, it defines `NOMINMAX` and `WIN32_LEAN_AND_MEAN` before including it. You can control this behaviour via two macros:
|
||||
|
99
docs/limitations.md
Normal file
99
docs/limitations.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# Known limitations
|
||||
|
||||
Catch has some known limitations, that we are not planning to change. Some of these are caused by our desire to support C++98 compilers, some of these are caused by our desire to keep Catch crossplatform, some exist because their priority is seen as low compared to the development effort they would need and some other yet are compiler/runtime bugs.
|
||||
|
||||
## Features
|
||||
This section outlines some missing features, what is their status and their possible workarounds.
|
||||
|
||||
### Thread safe assertions
|
||||
Because threading support in standard C++98 is limited (well, non-existent), assertion macros in Catch are not thread safe. This does not mean that you cannot use threads inside Catch's test, but that only single thread can interact with Catch's assertions and other macros.
|
||||
|
||||
This means that this is ok
|
||||
```cpp
|
||||
std::vector<std::thread> threads;
|
||||
std::atomic<int> cnt{ 0 };
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
threads.emplace_back([&]() {
|
||||
++cnt; ++cnt; ++cnt; ++cnt;
|
||||
});
|
||||
}
|
||||
for (auto& t : threads) { t.join(); }
|
||||
REQUIRE(cnt == 16);
|
||||
```
|
||||
because only one thread passes the `REQUIRE` macro and this is not
|
||||
```cpp
|
||||
std::vector<std::thread> threads;
|
||||
std::atomic<int> cnt{ 0 };
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
threads.emplace_back([&]() {
|
||||
++cnt; ++cnt; ++cnt; ++cnt;
|
||||
CHECK(cnt == 16);
|
||||
});
|
||||
}
|
||||
for (auto& t : threads) { t.join(); }
|
||||
REQUIRE(cnt == 16);
|
||||
```
|
||||
|
||||
|
||||
_This limitation is highly unlikely to be lifted before Catch 2 is released._
|
||||
|
||||
### Process isolation in a test
|
||||
Catch does not support running tests in isolated (forked) processes. While this might in the future, the fact that Windows does not support forking and only allows full-on process creation and the desire to keep code as similar as possible across platforms, mean that this is likely to take significant development time, that is not currently available.
|
||||
|
||||
### Running multiple tests in parallel
|
||||
Catch's test execution is strictly serial. If you find yourself with a test suite that takes too long to run and you want to make it parallel, there are 2 feasible solutions
|
||||
* You can split your tests into multiple binaries and then run these binaries in parallel.
|
||||
* You can have Catch list contained test cases and then run the same test binary multiple times in parallel, passing each instance list of test cases it should run.
|
||||
|
||||
Both of these solutions have their problems, but should let you wring parallelism out of your test suite.
|
||||
|
||||
## 3rd party bugs
|
||||
This section outlines known bugs in 3rd party components (this means compilers, standard libraries, standard runtimes).
|
||||
|
||||
### Visual Studio 2013 -- do-while loop withing range based for fails to compile (C2059)
|
||||
There is a known bug in Visual Studio 2013 (VC 12), that causes compilation error if range based for is followed by an assertion macro, without enclosing the block in braces. This snippet is sufficient to trigger the error
|
||||
```cpp
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
||||
|
||||
TEST_CASE("Syntax error with VC12") {
|
||||
for ( auto x : { 1 , 2, 3 } )
|
||||
REQUIRE( x < 3.14 );
|
||||
}
|
||||
```
|
||||
An easy workaround is possible, use braces:
|
||||
```cpp
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
||||
|
||||
TEST_CASE("No longer a syntax error with VC12") {
|
||||
for ( auto x : { 1 , 2, 3 } ) {
|
||||
REQUIRE( x < 3.14 );
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Visual Studio 2003 -- Syntax error caused by improperly expanded `__LINE__` macro
|
||||
Older version of Visual Studio can have trouble compiling Catch, not expanding the `__LINE__` macro properly when recompiling the test binary. This is caused by Edit and Continue being on.
|
||||
|
||||
A workaround is to turn off Edit and Continue when compiling the test binary.
|
||||
|
||||
### Clang/G++ -- skipping leaf sections after an exception
|
||||
Some versions of `libc++` and `libstdc++` (or their runtimes) have a bug with `std::uncaught_exception()` getting stuck returning `true` after rethrow, even if there are no active exceptions. One such case is this snippet, which skipped the sections "a" and "b", when compiled against `libcxxrt` from master
|
||||
```cpp
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("a") {
|
||||
CHECK_THROWS(throw 3);
|
||||
}
|
||||
|
||||
TEST_CASE("b") {
|
||||
int i = 0;
|
||||
SECTION("a") { i = 1; }
|
||||
SECTION("b") { i = 2; }
|
||||
CHECK(i > 0);
|
||||
}
|
||||
```
|
||||
|
||||
If you are seeing a problem like this, i.e. a weird test paths that trigger only under Clang with `libc++`, or only under very specific version of `libstdc++`, it is very likely you are seeing this. The only known workaround is to use a fixed version of your standard library.
|
56
docs/opensource-users.md
Normal file
56
docs/opensource-users.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Open Source projects using Catch
|
||||
|
||||
Catch is great for open source. With it's [liberal license](../LICENSE_1_0.txt) and single-header, dependency-free, distribution
|
||||
it's easy to just drop the header into your project and start writing tests - what's not to like?
|
||||
|
||||
As a result Catch is now being used in many Open Source projects, including some quite well known ones.
|
||||
This page is an attempt to track those projects. Obviously it can never be complete.
|
||||
This effort largely relies on the maintainers of the projects themselves updating this page and submitting a PR
|
||||
(or, if you prefer contact one of the maintainers of Catch directly, use the
|
||||
[forums](https://groups.google.com/forum/?fromgroups#!forum/catch-forum)), or raise an [issue](https://github.com/philsquared/Catch/issues) to let us know).
|
||||
Of course users of those projects might want to update this page too. That's fine - as long you're confident the project maintainers won't mind.
|
||||
If you're an Open Source project maintainer and see your project listed here but would rather it wasn't -
|
||||
just let us know via any of the previously mentioned means - although I'm sure there won't be many who feel that way.
|
||||
|
||||
Listing a project here does not imply endorsement and the plan is to keep these ordered alphabetically to avoid an implication of relative importance.
|
||||
|
||||
## Libraries & Frameworks
|
||||
|
||||
### [Azmq](https://github.com/zeromq/azmq)
|
||||
Boost Asio style bindings for ZeroMQ
|
||||
|
||||
### [ChakraCore](https://github.com/Microsoft/ChakraCore)
|
||||
The core part of the Chakra Javascript engine that powers Microsoft Edge
|
||||
|
||||
### [ChaiScript](https://github.com/ChaiScript/ChaiScript)
|
||||
A, header-only, embedded scripting language designed from the ground up to directly target C++ and take advantage of modern C++ development techniques
|
||||
|
||||
### [Couchbase-lite-core](https://github.com/couchbase/couchbase-lite-core)
|
||||
The next-generation core storage and query engine for Couchbase Lite/
|
||||
|
||||
### [JSON for Modern C++](https://github.com/nlohmann/json)
|
||||
A, single-header, JSON parsing library that takes advantage of what C++ has to offer.
|
||||
|
||||
### [MNMLSTC Core](https://github.com/mnmlstc/core)
|
||||
a small and easy to use C++11 library that adds a functionality set that will be available in C++14 and later, as well as some useful additions
|
||||
|
||||
### [Ppconsul](https://github.com/oliora/ppconsul)
|
||||
A C++ client library for Consul. Consul is a distributed tool for discovering and configuring services in your infrastructure
|
||||
|
||||
### [Reactive-Extensions/ RxCpp](https://github.com/Reactive-Extensions/RxCpp)
|
||||
A library of algorithms for values-distributed-in-time
|
||||
|
||||
### [Trompeloeil](https://github.com/rollbear/trompeloeil)
|
||||
A thread safe header only mocking framework for C++14
|
||||
|
||||
## Applications & Tools
|
||||
|
||||
### [MAME](https://github.com/mamedev/mame)
|
||||
MAME originally stood for Multiple Arcade Machine Emulator
|
||||
|
||||
### [Standardese](https://github.com/foonathan/standardese)
|
||||
Standardese aims to be a nextgen Doxygen
|
||||
|
||||
---
|
||||
|
||||
[Home](Readme.md)
|
@@ -1,4 +1,40 @@
|
||||
# 1.7.0
|
||||
# 1.7.2
|
||||
|
||||
### Fixes and minor improvements
|
||||
Xml:
|
||||
|
||||
(technically the first two are breaking changes but are also fixes and arguably break few if any people)
|
||||
* C-escape control characters instead of XML encoding them (which requires XML 1.1)
|
||||
* Revert XML output to XML 1.0
|
||||
* Can provide stylesheet references by extending the XML reporter
|
||||
* Added description and tags attribites to XML Reporter
|
||||
* Tags are closed and the stream flushed more eagerly to avoid stdout interpolation
|
||||
|
||||
|
||||
Other:
|
||||
* `REQUIRE_THROWS_AS` now catches exception by `const&` and reports expected type
|
||||
* In `SECTION`s the file/ line is now of the `SECTION`. not the `TEST_CASE`
|
||||
* Added std:: qualification to some functions from C stdlib
|
||||
* Removed use of RTTI (`dynamic_cast`) that had crept back in
|
||||
* Silenced a few more warnings in different circumstances
|
||||
* Travis improvements
|
||||
|
||||
# 1.7.1
|
||||
|
||||
### Fixes:
|
||||
* Fixed inconsistency in defining `NOMINMAX` and `WIN32_LEAN_AND_MEAN` inside `catch.hpp`.
|
||||
* Fixed SEH-related compilation error under older MinGW compilers, by making Windows SEH handling opt-in for compilers other than MSVC.
|
||||
* For specifics, look into the [documentation](docs/configuration.md).
|
||||
* Fixed compilation error under MinGW caused by improper compiler detection.
|
||||
* Fixed XML reporter sometimes leaving an empty output file when a test ends with signal/structured exception.
|
||||
* Fixed XML reporter not reporting captured stdout/stderr.
|
||||
* Fixed possible infinite recursion in Windows SEH.
|
||||
* Fixed possible compilation error caused by Catch's operator overloads being ambiguous in regards to user-defined templated operators.
|
||||
|
||||
# Older versions
|
||||
Release notes were not maintained prior to v1.6.0, but you should be able to work them out from the Git history
|
||||
|
||||
## 1.7.0
|
||||
|
||||
### Features/ Changes:
|
||||
* Catch now runs significantly faster for passing tests
|
||||
@@ -25,12 +61,6 @@
|
||||
* Catch's CMakeLists now generates projects with warnings enabled.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Older versions
|
||||
Release notes were not maintained prior to v1.6.0, but you should be able to work them out from the Git history
|
||||
|
||||
## 1.6.1
|
||||
|
||||
### Features/ Changes:
|
||||
|
@@ -17,6 +17,46 @@ Because Catch is implemented *entirely* in headers you might think that the whol
|
||||
|
||||
As a result the main source file *does* compile the whole of Catch every time! So it makes sense to dedicate this file to *only* ```#define```-ing the identifier and ```#include```-ing Catch (and implementing the runner code, if you're doing that). Keep all your test cases in other files. This way you won't pay the recompilation cost for the whole of Catch
|
||||
|
||||
## Practical example
|
||||
Assume you have the `Factorial` function from the [tutorial](tutorial.md) in `factorial.cpp` (with forward declaration in `factorial.h`) and want to test it and keep the compile times down when adding new tests. Then you should have 2 files, `tests-main.cpp` and `tests-factorial.cpp`:
|
||||
|
||||
```cpp
|
||||
// tests-main.cpp
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
||||
```
|
||||
|
||||
```cpp
|
||||
// tests-factorial.cpp
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "factorial.h"
|
||||
|
||||
TEST_CASE( "Factorials are computed", "[factorial]" ) {
|
||||
REQUIRE( Factorial(1) == 1 );
|
||||
REQUIRE( Factorial(2) == 2 );
|
||||
REQUIRE( Factorial(3) == 6 );
|
||||
REQUIRE( Factorial(10) == 3628800 );
|
||||
}
|
||||
```
|
||||
|
||||
After compiling `tests-main.cpp` once, it is enough to link it with separately compiled `tests-factorial.cpp`. This means that adding more tests to `tests-factorial.cpp`, will not result in recompiling Catch's main and the resulting compilation times will decrease substantially.
|
||||
|
||||
```
|
||||
$ g++ tests-main.cpp -c
|
||||
$ g++ tests-main.o tests-factorial.cpp -o tests && ./tests -r compact
|
||||
Passed 1 test case with 4 assertions.
|
||||
```
|
||||
|
||||
Now, the next time we change the file `tests-factorial.cpp` (say we add `REQUIRE( Factorial(0) == 1)`), it is enough to recompile the tests instead of recompiling main as well:
|
||||
|
||||
```
|
||||
$ g++ tests-main.o tests-factorial.cpp -o tests && ./tests -r compact
|
||||
tests-factorial.cpp:11: failed: Factorial(0) == 1 for: 0 == 1
|
||||
Failed 1 test case, failed 1 assertion.
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
[Home](Readme.md)
|
@@ -35,6 +35,10 @@ So what does Catch bring to the party that differentiates it from these? Apart f
|
||||
* Implement test fixtures using Obj-C classes too (like OCUnit)
|
||||
* Additional built in matchers that work with Obj-C types (e.g. string matchers)
|
||||
|
||||
## Who else is using Catch?
|
||||
|
||||
See the list of [open source projects using Catch](opensource-users.md).
|
||||
|
||||
See the [tutorial](tutorial.md) to get more of a taste of using CATCH in practice
|
||||
|
||||
---
|
||||
|
@@ -50,7 +50,7 @@ namespace Detail {
|
||||
friend bool operator == ( const T& lhs, Approx const& rhs ) {
|
||||
// Thanks to Richard Harris for his help refining this formula
|
||||
auto lhs_v = double(lhs);
|
||||
return fabs( lhs_v - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs_v), fabs(rhs.m_value) ) );
|
||||
return std::fabs( lhs_v - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( std::fabs(lhs_v), std::fabs(rhs.m_value) ) );
|
||||
}
|
||||
|
||||
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||
@@ -94,7 +94,7 @@ namespace Detail {
|
||||
#else
|
||||
friend bool operator == ( double lhs, Approx const& rhs ) {
|
||||
// Thanks to Richard Harris for his help refining this formula
|
||||
return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
|
||||
return std::fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( std::fabs(lhs), std::fabs(rhs.m_value) ) );
|
||||
}
|
||||
|
||||
friend bool operator == ( Approx const& lhs, double rhs ) {
|
||||
|
@@ -16,6 +16,7 @@
|
||||
#include "catch_tostring.h"
|
||||
#include "catch_interfaces_runner.h"
|
||||
#include "catch_compiler_capabilities.h"
|
||||
#include "catch_type_traits.hpp"
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -87,13 +88,13 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
|
||||
do { \
|
||||
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
|
||||
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr ", " #exceptionType, resultDisposition ); \
|
||||
if( __catchResult.allowThrows() ) \
|
||||
try { \
|
||||
static_cast<void>(expr); \
|
||||
__catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
|
||||
} \
|
||||
catch( exceptionType ) { \
|
||||
catch( Catch::add_const<Catch::add_lvalue_reference<exceptionType>::type>::type ) { \
|
||||
__catchResult.captureResult( Catch::ResultWas::Ok ); \
|
||||
} \
|
||||
catch( ... ) { \
|
||||
|
@@ -13,6 +13,7 @@
|
||||
#include "catch_clara.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <ctime>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@@ -51,7 +52,7 @@ namespace Catch {
|
||||
ss << seed;
|
||||
ss >> config.rngSeed;
|
||||
if( ss.fail() )
|
||||
throw std::runtime_error( "Argment to --rng-seed should be the word 'time' or a number" );
|
||||
throw std::runtime_error( "Argument to --rng-seed should be the word 'time' or a number" );
|
||||
}
|
||||
}
|
||||
inline void setVerbosity( ConfigData& config, int level ) {
|
||||
|
@@ -22,7 +22,6 @@
|
||||
#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
|
||||
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
|
||||
#include "catch_compiler_capabilities.h"
|
||||
@@ -83,7 +82,6 @@ namespace Catch {
|
||||
bool endsWith( std::string const& s, std::string const& suffix );
|
||||
bool endsWith( std::string const& s, char suffix );
|
||||
bool contains( std::string const& s, std::string const& infix );
|
||||
bool contains( std::string const& s, std::string const& infix );
|
||||
void toLowerInPlace( std::string& s );
|
||||
std::string toLower( std::string const& s );
|
||||
std::string trim( std::string const& str );
|
||||
|
@@ -11,6 +11,7 @@
|
||||
#include "catch_common.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <cctype>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@@ -29,11 +30,8 @@ namespace Catch {
|
||||
bool contains( std::string const& s, std::string const& infix ) {
|
||||
return s.find( infix ) != std::string::npos;
|
||||
}
|
||||
bool contains( std::string const& s, char infix ) {
|
||||
return s.find(infix) != std::string::npos;
|
||||
}
|
||||
char toLowerCh(char c) {
|
||||
return static_cast<char>( ::tolower( c ) );
|
||||
return static_cast<char>( std::tolower( c ) );
|
||||
}
|
||||
void toLowerInPlace( std::string& s ) {
|
||||
std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
|
||||
|
@@ -26,6 +26,7 @@
|
||||
|
||||
// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
|
||||
// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
|
||||
// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
|
||||
// ****************
|
||||
// Note to maintainers: if new toggles are added please document them
|
||||
// in configuration.md, too
|
||||
@@ -109,6 +110,8 @@
|
||||
// Visual C++
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
|
||||
|
||||
#if (_MSC_VER >= 1600)
|
||||
# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
|
||||
# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
|
||||
@@ -233,6 +236,9 @@
|
||||
# if defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_NO_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_NO_CPP11)
|
||||
# define CATCH_CONFIG_CPP11_TYPE_TRAITS
|
||||
# endif
|
||||
#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH)
|
||||
# define CATCH_CONFIG_WINDOWS_SEH
|
||||
#endif
|
||||
|
||||
#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
|
||||
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
|
||||
|
@@ -16,8 +16,7 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
#include <stdexcept>
|
||||
|
||||
#ifndef CATCH_CONFIG_CONSOLE_WIDTH
|
||||
#define CATCH_CONFIG_CONSOLE_WIDTH 80
|
||||
@@ -100,8 +99,7 @@ namespace Catch {
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~Config() {
|
||||
}
|
||||
virtual ~Config() {}
|
||||
|
||||
std::string const& getFilename() const {
|
||||
return m_data.outputFilename ;
|
||||
@@ -114,28 +112,26 @@ namespace Catch {
|
||||
|
||||
std::string getProcessName() const { return m_data.processName; }
|
||||
|
||||
bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
|
||||
|
||||
std::vector<std::string> const& getReporterNames() const { return m_data.reporterNames; }
|
||||
std::vector<std::string> const& getSectionsToRun() const CATCH_OVERRIDE { return m_data.sectionsToRun; }
|
||||
|
||||
int abortAfter() const { return m_data.abortAfter; }
|
||||
|
||||
TestSpec const& testSpec() const { return m_testSpec; }
|
||||
virtual TestSpec const& testSpec() const CATCH_OVERRIDE { return m_testSpec; }
|
||||
|
||||
bool showHelp() const { return m_data.showHelp; }
|
||||
bool showInvisibles() const { return m_data.showInvisibles; }
|
||||
|
||||
// IConfig interface
|
||||
virtual bool allowThrows() const { return !m_data.noThrow; }
|
||||
virtual std::ostream& stream() const { return m_stream->stream(); }
|
||||
virtual std::string name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
|
||||
virtual bool includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
|
||||
virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
|
||||
virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
|
||||
virtual RunTests::InWhatOrder runOrder() const { return m_data.runOrder; }
|
||||
virtual unsigned int rngSeed() const { return m_data.rngSeed; }
|
||||
virtual UseColour::YesOrNo useColour() const { return m_data.useColour; }
|
||||
virtual bool allowThrows() const CATCH_OVERRIDE { return !m_data.noThrow; }
|
||||
virtual std::ostream& stream() const CATCH_OVERRIDE { return m_stream->stream(); }
|
||||
virtual std::string name() const CATCH_OVERRIDE { return m_data.name.empty() ? m_data.processName : m_data.name; }
|
||||
virtual bool includeSuccessfulResults() const CATCH_OVERRIDE { return m_data.showSuccessfulTests; }
|
||||
virtual bool warnAboutMissingAssertions() const CATCH_OVERRIDE { return m_data.warnings & WarnAbout::NoAssertions; }
|
||||
virtual ShowDurations::OrNot showDurations() const CATCH_OVERRIDE { return m_data.showDurations; }
|
||||
virtual RunTests::InWhatOrder runOrder() const CATCH_OVERRIDE { return m_data.runOrder; }
|
||||
virtual unsigned int rngSeed() const CATCH_OVERRIDE { return m_data.rngSeed; }
|
||||
virtual UseColour::YesOrNo useColour() const CATCH_OVERRIDE { return m_data.useColour; }
|
||||
virtual bool shouldDebugBreak() const CATCH_OVERRIDE { return m_data.shouldDebugBreak; }
|
||||
virtual int abortAfter() const CATCH_OVERRIDE { return m_data.abortAfter; }
|
||||
virtual bool showInvisibles() const CATCH_OVERRIDE { return m_data.showInvisibles; }
|
||||
|
||||
private:
|
||||
|
||||
|
@@ -11,9 +11,6 @@
|
||||
#include "catch_interfaces_generators.h"
|
||||
#include "catch_ptr.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
|
@@ -11,8 +11,6 @@
|
||||
|
||||
#include "catch_debugger.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#ifdef CATCH_PLATFORM_MAC
|
||||
|
||||
#include <assert.h>
|
||||
@@ -109,7 +107,9 @@
|
||||
#endif // Platform
|
||||
|
||||
#ifdef CATCH_PLATFORM_WINDOWS
|
||||
extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );
|
||||
|
||||
#include "catch_windows_h_proxy.h"
|
||||
|
||||
namespace Catch {
|
||||
void writeToDebugConsole( std::string const& text ) {
|
||||
::OutputDebugStringA( text.c_str() );
|
||||
|
@@ -29,45 +29,45 @@ public:
|
||||
|
||||
template<typename RhsT>
|
||||
BinaryExpression<T, Internal::IsEqualTo, RhsT const&>
|
||||
operator == ( RhsT const& rhs ) const {
|
||||
operator == ( RhsT const& rhs ) {
|
||||
return captureExpression<Internal::IsEqualTo>( rhs );
|
||||
}
|
||||
|
||||
template<typename RhsT>
|
||||
BinaryExpression<T, Internal::IsNotEqualTo, RhsT const&>
|
||||
operator != ( RhsT const& rhs ) const {
|
||||
operator != ( RhsT const& rhs ) {
|
||||
return captureExpression<Internal::IsNotEqualTo>( rhs );
|
||||
}
|
||||
|
||||
template<typename RhsT>
|
||||
BinaryExpression<T, Internal::IsLessThan, RhsT const&>
|
||||
operator < ( RhsT const& rhs ) const {
|
||||
operator < ( RhsT const& rhs ) {
|
||||
return captureExpression<Internal::IsLessThan>( rhs );
|
||||
}
|
||||
|
||||
template<typename RhsT>
|
||||
BinaryExpression<T, Internal::IsGreaterThan, RhsT const&>
|
||||
operator > ( RhsT const& rhs ) const {
|
||||
operator > ( RhsT const& rhs ) {
|
||||
return captureExpression<Internal::IsGreaterThan>( rhs );
|
||||
}
|
||||
|
||||
template<typename RhsT>
|
||||
BinaryExpression<T, Internal::IsLessThanOrEqualTo, RhsT const&>
|
||||
operator <= ( RhsT const& rhs ) const {
|
||||
operator <= ( RhsT const& rhs ) {
|
||||
return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
|
||||
}
|
||||
|
||||
template<typename RhsT>
|
||||
BinaryExpression<T, Internal::IsGreaterThanOrEqualTo, RhsT const&>
|
||||
operator >= ( RhsT const& rhs ) const {
|
||||
operator >= ( RhsT const& rhs ) {
|
||||
return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
|
||||
}
|
||||
|
||||
BinaryExpression<T, Internal::IsEqualTo, bool> operator == ( bool rhs ) const {
|
||||
BinaryExpression<T, Internal::IsEqualTo, bool> operator == ( bool rhs ) {
|
||||
return captureExpression<Internal::IsEqualTo>( rhs );
|
||||
}
|
||||
|
||||
BinaryExpression<T, Internal::IsNotEqualTo, bool> operator != ( bool rhs ) const {
|
||||
BinaryExpression<T, Internal::IsNotEqualTo, bool> operator != ( bool rhs ) {
|
||||
return captureExpression<Internal::IsNotEqualTo>( rhs );
|
||||
}
|
||||
|
||||
|
@@ -22,13 +22,17 @@ namespace Catch {
|
||||
} // namespace Catch
|
||||
|
||||
#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
|
||||
#include "catch_windows_h_proxy.h"
|
||||
|
||||
#define NOMINMAX
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#undef NOMINMAX
|
||||
# if !defined ( CATCH_CONFIG_WINDOWS_SEH )
|
||||
|
||||
namespace Catch {
|
||||
struct FatalConditionHandler {
|
||||
void reset() {}
|
||||
};
|
||||
}
|
||||
|
||||
# else // CATCH_CONFIG_WINDOWS_SEH is defined
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@@ -49,6 +53,7 @@ namespace Catch {
|
||||
static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
|
||||
for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
||||
if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
|
||||
reset();
|
||||
reportFatal(signalDefs[i].name);
|
||||
}
|
||||
}
|
||||
@@ -57,22 +62,25 @@ namespace Catch {
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
// 32k seems enough for Catch to handle stack overflow,
|
||||
// but the value was found experimentally, so there is no strong guarantee
|
||||
FatalConditionHandler():m_isSet(true), m_guaranteeSize(32 * 1024), m_exceptionHandlerHandle(CATCH_NULL) {
|
||||
FatalConditionHandler() {
|
||||
isSet = true;
|
||||
// 32k seems enough for Catch to handle stack overflow,
|
||||
// but the value was found experimentally, so there is no strong guarantee
|
||||
guaranteeSize = 32 * 1024;
|
||||
exceptionHandlerHandle = CATCH_NULL;
|
||||
// Register as first handler in current chain
|
||||
m_exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
|
||||
exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
|
||||
// Pass in guarantee size to be filled
|
||||
SetThreadStackGuarantee(&m_guaranteeSize);
|
||||
SetThreadStackGuarantee(&guaranteeSize);
|
||||
}
|
||||
|
||||
void reset() {
|
||||
if (m_isSet) {
|
||||
static void reset() {
|
||||
if (isSet) {
|
||||
// Unregister handler and restore the old guarantee
|
||||
RemoveVectoredExceptionHandler(m_exceptionHandlerHandle);
|
||||
SetThreadStackGuarantee(&m_guaranteeSize);
|
||||
m_exceptionHandlerHandle = CATCH_NULL;
|
||||
m_isSet = false;
|
||||
RemoveVectoredExceptionHandler(exceptionHandlerHandle);
|
||||
SetThreadStackGuarantee(&guaranteeSize);
|
||||
exceptionHandlerHandle = CATCH_NULL;
|
||||
isSet = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,13 +88,19 @@ namespace Catch {
|
||||
reset();
|
||||
}
|
||||
private:
|
||||
bool m_isSet;
|
||||
ULONG m_guaranteeSize;
|
||||
PVOID m_exceptionHandlerHandle;
|
||||
static bool isSet;
|
||||
static ULONG guaranteeSize;
|
||||
static PVOID exceptionHandlerHandle;
|
||||
};
|
||||
|
||||
bool FatalConditionHandler::isSet = false;
|
||||
ULONG FatalConditionHandler::guaranteeSize = 0;
|
||||
PVOID FatalConditionHandler::exceptionHandlerHandle = CATCH_NULL;
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
# endif // CATCH_CONFIG_WINDOWS_SEH
|
||||
|
||||
#else // Not Windows - assumed to be POSIX compatible //////////////////////////
|
||||
|
||||
#include <signal.h>
|
||||
|
@@ -8,7 +8,7 @@
|
||||
#ifndef TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
|
||||
|
||||
#include <iostream>
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@@ -21,7 +21,6 @@
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
#include <map>
|
||||
#include <assert.h>
|
||||
|
||||
namespace Catch
|
||||
{
|
||||
|
@@ -9,7 +9,6 @@
|
||||
#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
|
||||
|
||||
#include "catch_common.h"
|
||||
#include <ostream>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
|
@@ -9,7 +9,7 @@
|
||||
#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
|
||||
|
||||
#include "catch_notimplemented_exception.h"
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
|
@@ -98,7 +98,8 @@ namespace Catch {
|
||||
|
||||
do {
|
||||
ITracker& rootTracker = m_trackerContext.startRun();
|
||||
dynamic_cast<SectionTracker&>( rootTracker ).addInitialFilters( m_config->getSectionsToRun() );
|
||||
assert( rootTracker.isSectionTracker() );
|
||||
static_cast<SectionTracker&>( rootTracker ).addInitialFilters( m_config->getSectionsToRun() );
|
||||
do {
|
||||
m_trackerContext.startCycle();
|
||||
m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( testInfo.name, testInfo.lineInfo ) );
|
||||
|
@@ -11,7 +11,6 @@
|
||||
#include "catch_section.h"
|
||||
#include "catch_capture.hpp"
|
||||
#include "catch_compiler_capabilities.h"
|
||||
#include "catch_timer.h"
|
||||
|
||||
namespace Catch {
|
||||
|
||||
|
@@ -11,6 +11,8 @@
|
||||
#include "catch_common.h"
|
||||
#include "catch_totals.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
struct SectionInfo {
|
||||
|
@@ -8,10 +8,7 @@
|
||||
#ifndef TWOBLUECUBES_CATCH_SECTION_INFO_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_SECTION_INFO_HPP_INCLUDED
|
||||
|
||||
#include "catch_common.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "catch_section_info.h"
|
||||
|
||||
namespace Catch {
|
||||
|
||||
|
@@ -11,9 +11,6 @@
|
||||
#include "catch_tag_alias_registry.h"
|
||||
#include "catch_console_colour.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
TagAliasRegistry::~TagAliasRegistry() {}
|
||||
|
@@ -13,6 +13,8 @@
|
||||
#include "catch_interfaces_testcase.h"
|
||||
#include "catch_common.h"
|
||||
|
||||
#include <cctype>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
|
||||
@@ -32,7 +34,7 @@ namespace Catch {
|
||||
return TestCaseInfo::None;
|
||||
}
|
||||
inline bool isReservedTag( std::string const& tag ) {
|
||||
return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] );
|
||||
return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( tag[0] );
|
||||
}
|
||||
inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
|
||||
if( isReservedTag( tag ) ) {
|
||||
|
@@ -16,7 +16,6 @@
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
|
@@ -16,6 +16,7 @@
|
||||
#include <assert.h>
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace Catch {
|
||||
namespace TestCaseTracking {
|
||||
|
47
include/internal/catch_type_traits.hpp
Normal file
47
include/internal/catch_type_traits.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Created by Martin on 08/02/2017.
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED
|
||||
|
||||
#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
|
||||
namespace Catch {
|
||||
|
||||
#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
|
||||
|
||||
template <typename T>
|
||||
using add_lvalue_reference = std::add_lvalue_reference<T>;
|
||||
|
||||
template <typename T>
|
||||
using add_const = std::add_const<T>;
|
||||
|
||||
#else
|
||||
|
||||
template <typename T>
|
||||
struct add_const {
|
||||
typedef const T type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct add_lvalue_reference {
|
||||
typedef T& type;
|
||||
};
|
||||
template <typename T>
|
||||
struct add_lvalue_reference<T&> {
|
||||
typedef T& type;
|
||||
};
|
||||
// No && overload, because that is C++11, in which case we have
|
||||
// proper type_traits implementation from the standard library
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED
|
@@ -37,7 +37,7 @@ namespace Catch {
|
||||
return os;
|
||||
}
|
||||
|
||||
Version libraryVersion( 1, 7, 0, "", 0 );
|
||||
Version libraryVersion( 1, 7, 2, "", 0 );
|
||||
|
||||
}
|
||||
|
||||
|
@@ -10,6 +10,9 @@
|
||||
|
||||
#include "catch_common.h"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
namespace Catch
|
||||
{
|
||||
class WildcardPattern {
|
||||
|
@@ -57,8 +57,11 @@ namespace Catch {
|
||||
default:
|
||||
// Escape control chars - based on contribution by @espenalb in PR #465 and
|
||||
// by @mrpi PR #588
|
||||
if ( ( c >= 0 && c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' )
|
||||
os << "&#x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>( c ) << ';';
|
||||
if ( ( c >= 0 && c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' ) {
|
||||
// see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
|
||||
os << "\\x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
|
||||
<< static_cast<int>( c );
|
||||
}
|
||||
else
|
||||
os << c;
|
||||
}
|
||||
@@ -112,20 +115,17 @@ namespace Catch {
|
||||
XmlWriter()
|
||||
: m_tagIsOpen( false ),
|
||||
m_needsNewline( false ),
|
||||
m_os( &Catch::cout() )
|
||||
m_os( Catch::cout() )
|
||||
{
|
||||
// We encode control characters, which requires
|
||||
// XML 1.1
|
||||
// see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
|
||||
*m_os << "<?xml version=\"1.1\" encoding=\"UTF-8\"?>\n";
|
||||
writeDeclaration();
|
||||
}
|
||||
|
||||
XmlWriter( std::ostream& os )
|
||||
: m_tagIsOpen( false ),
|
||||
m_needsNewline( false ),
|
||||
m_os( &os )
|
||||
m_os( os )
|
||||
{
|
||||
*m_os << "<?xml version=\"1.1\" encoding=\"UTF-8\"?>\n";
|
||||
writeDeclaration();
|
||||
}
|
||||
|
||||
~XmlWriter() {
|
||||
@@ -136,7 +136,7 @@ namespace Catch {
|
||||
XmlWriter& startElement( std::string const& name ) {
|
||||
ensureTagClosed();
|
||||
newlineIfNecessary();
|
||||
stream() << m_indent << '<' << name;
|
||||
m_os << m_indent << '<' << name;
|
||||
m_tags.push_back( name );
|
||||
m_indent += " ";
|
||||
m_tagIsOpen = true;
|
||||
@@ -153,24 +153,25 @@ namespace Catch {
|
||||
newlineIfNecessary();
|
||||
m_indent = m_indent.substr( 0, m_indent.size()-2 );
|
||||
if( m_tagIsOpen ) {
|
||||
stream() << "/>\n";
|
||||
m_os << "/>";
|
||||
m_tagIsOpen = false;
|
||||
}
|
||||
else {
|
||||
stream() << m_indent << "</" << m_tags.back() << ">\n";
|
||||
m_os << m_indent << "</" << m_tags.back() << ">";
|
||||
}
|
||||
m_os << std::endl;
|
||||
m_tags.pop_back();
|
||||
return *this;
|
||||
}
|
||||
|
||||
XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
|
||||
if( !name.empty() && !attribute.empty() )
|
||||
stream() << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
|
||||
m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
|
||||
return *this;
|
||||
}
|
||||
|
||||
XmlWriter& writeAttribute( std::string const& name, bool attribute ) {
|
||||
stream() << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
|
||||
m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -186,8 +187,8 @@ namespace Catch {
|
||||
bool tagWasOpen = m_tagIsOpen;
|
||||
ensureTagClosed();
|
||||
if( tagWasOpen && indent )
|
||||
stream() << m_indent;
|
||||
stream() << XmlEncode( text );
|
||||
m_os << m_indent;
|
||||
m_os << XmlEncode( text );
|
||||
m_needsNewline = true;
|
||||
}
|
||||
return *this;
|
||||
@@ -195,39 +196,39 @@ namespace Catch {
|
||||
|
||||
XmlWriter& writeComment( std::string const& text ) {
|
||||
ensureTagClosed();
|
||||
stream() << m_indent << "<!--" << text << "-->";
|
||||
m_os << m_indent << "<!--" << text << "-->";
|
||||
m_needsNewline = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void writeStylesheetRef( std::string const& url ) {
|
||||
m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
|
||||
}
|
||||
|
||||
XmlWriter& writeBlankLine() {
|
||||
ensureTagClosed();
|
||||
stream() << '\n';
|
||||
m_os << '\n';
|
||||
return *this;
|
||||
}
|
||||
|
||||
void setStream( std::ostream& os ) {
|
||||
m_os = &os;
|
||||
void ensureTagClosed() {
|
||||
if( m_tagIsOpen ) {
|
||||
m_os << ">" << std::endl;
|
||||
m_tagIsOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
XmlWriter( XmlWriter const& );
|
||||
void operator=( XmlWriter const& );
|
||||
|
||||
std::ostream& stream() {
|
||||
return *m_os;
|
||||
}
|
||||
|
||||
void ensureTagClosed() {
|
||||
if( m_tagIsOpen ) {
|
||||
stream() << ">\n";
|
||||
m_tagIsOpen = false;
|
||||
}
|
||||
void writeDeclaration() {
|
||||
m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
|
||||
}
|
||||
|
||||
void newlineIfNecessary() {
|
||||
if( m_needsNewline ) {
|
||||
stream() << '\n';
|
||||
m_os << std::endl;
|
||||
m_needsNewline = false;
|
||||
}
|
||||
}
|
||||
@@ -236,7 +237,7 @@ namespace Catch {
|
||||
bool m_needsNewline;
|
||||
std::vector<std::string> m_tags;
|
||||
std::string m_indent;
|
||||
std::ostream* m_os;
|
||||
std::ostream& m_os;
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -237,7 +237,7 @@ namespace Catch {
|
||||
char const* getLineOfChars() {
|
||||
static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
|
||||
if( !*line ) {
|
||||
memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
|
||||
std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
|
||||
line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
|
||||
}
|
||||
return line;
|
||||
|
@@ -284,7 +284,7 @@ namespace Catch {
|
||||
printHeaderString( it->name, 2 );
|
||||
}
|
||||
|
||||
SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
|
||||
SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
|
||||
|
||||
if( !lineInfo.empty() ){
|
||||
stream << getLineOfChars<'-'>() << '\n';
|
||||
|
@@ -26,7 +26,7 @@ namespace Catch {
|
||||
std::time(&rawtime);
|
||||
const size_t timeStampSize = sizeof("2017-01-16T17:06:45Z");
|
||||
|
||||
#ifdef CATCH_PLATFORM_WINDOWS
|
||||
#ifdef _MSC_VER
|
||||
std::tm timeInfo = {};
|
||||
gmtime_s(&timeInfo, &rawtime);
|
||||
#else
|
||||
@@ -37,7 +37,7 @@ namespace Catch {
|
||||
char timeStamp[timeStampSize];
|
||||
const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
|
||||
|
||||
#ifdef CATCH_PLATFORM_WINDOWS
|
||||
#ifdef _MSC_VER
|
||||
std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
|
||||
#else
|
||||
std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
|
||||
|
@@ -32,6 +32,10 @@ namespace Catch {
|
||||
return "Reports test results as an XML document";
|
||||
}
|
||||
|
||||
virtual std::string getStylesheetRef() const {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
public: // StreamingReporterBase
|
||||
|
||||
virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE {
|
||||
@@ -40,6 +44,9 @@ namespace Catch {
|
||||
|
||||
virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE {
|
||||
StreamingReporterBase::testRunStarting( testInfo );
|
||||
std::string stylesheetRef = getStylesheetRef();
|
||||
if( !stylesheetRef.empty() )
|
||||
m_xml.writeStylesheetRef( stylesheetRef );
|
||||
m_xml.startElement( "Catch" );
|
||||
if( !m_config->name().empty() )
|
||||
m_xml.writeAttribute( "name", m_config->name() );
|
||||
@@ -53,10 +60,14 @@ namespace Catch {
|
||||
|
||||
virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
|
||||
StreamingReporterBase::testCaseStarting(testInfo);
|
||||
m_xml.startElement( "TestCase" ).writeAttribute( "name", testInfo.name );
|
||||
m_xml.startElement( "TestCase" )
|
||||
.writeAttribute( "name", trim( testInfo.name ) )
|
||||
.writeAttribute( "description", testInfo.description )
|
||||
.writeAttribute( "tags", testInfo.tagsAsString );
|
||||
|
||||
if ( m_config->showDurations() == ShowDurations::Always )
|
||||
m_testCaseTimer.start();
|
||||
m_xml.ensureTagClosed();
|
||||
}
|
||||
|
||||
virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
|
||||
@@ -65,6 +76,7 @@ namespace Catch {
|
||||
m_xml.startElement( "Section" )
|
||||
.writeAttribute( "name", trim( sectionInfo.name ) )
|
||||
.writeAttribute( "description", sectionInfo.description );
|
||||
m_xml.ensureTagClosed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,6 +176,11 @@ namespace Catch {
|
||||
if ( m_config->showDurations() == ShowDurations::Always )
|
||||
e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
|
||||
|
||||
if( !testCaseStats.stdOut.empty() )
|
||||
m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false );
|
||||
if( !testCaseStats.stdErr.empty() )
|
||||
m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false );
|
||||
|
||||
m_xml.endElement();
|
||||
}
|
||||
|
||||
|
@@ -160,7 +160,7 @@ inline std::ostream& operator<<( std::ostream& os, StrongDoubleTypedef td ) {
|
||||
TEST_CASE
|
||||
(
|
||||
"Comparison with explicitly convertible types",
|
||||
"[Approx]"
|
||||
"[Approx][c++11]"
|
||||
)
|
||||
{
|
||||
StrongDoubleTypedef td(10.0);
|
||||
|
@@ -131,7 +131,7 @@ ExceptionTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ExceptionTests.cpp:<line number>: FAILED:
|
||||
REQUIRE_THROWS_AS( throwCustom() )
|
||||
REQUIRE_THROWS_AS( throwCustom(), std::exception )
|
||||
due to unexpected exception with message:
|
||||
custom exception - not std
|
||||
|
||||
@@ -245,12 +245,12 @@ ExceptionTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ExceptionTests.cpp:<line number>: FAILED:
|
||||
CHECK_THROWS_AS( thisThrows() )
|
||||
CHECK_THROWS_AS( thisThrows(), std::string )
|
||||
due to unexpected exception with message:
|
||||
expected exception
|
||||
|
||||
ExceptionTests.cpp:<line number>: FAILED:
|
||||
CHECK_THROWS_AS( thisDoesntThrow() )
|
||||
CHECK_THROWS_AS( thisDoesntThrow(), std::domain_error )
|
||||
because no exception was thrown where one was expected:
|
||||
|
||||
ExceptionTests.cpp:<line number>: FAILED:
|
||||
@@ -711,7 +711,7 @@ MiscTests.cpp:<line number>: FAILED:
|
||||
with expansion:
|
||||
false
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
spanner-------------------------------------------------------------------------------
|
||||
just failure
|
||||
-------------------------------------------------------------------------------
|
||||
MessageTests.cpp:<line number>
|
||||
@@ -829,6 +829,6 @@ with expansion:
|
||||
"first" == "second"
|
||||
|
||||
===============================================================================
|
||||
test cases: 157 | 113 passed | 42 failed | 2 failed as expected
|
||||
assertions: 913 | 817 passed | 78 failed | 18 failed as expected
|
||||
test cases: 161 | 117 passed | 42 failed | 2 failed as expected
|
||||
assertions: 932 | 836 passed | 78 failed | 18 failed as expected
|
||||
|
||||
|
@@ -14,6 +14,40 @@ PASSED:
|
||||
with message:
|
||||
yay
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#542
|
||||
-------------------------------------------------------------------------------
|
||||
CompilationTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THROWS_AS( throws_int(true), int )
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THROWS_AS( throws_int(true), int& )
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THROWS_AS( throws_int(true), const int )
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THROWS_AS( throws_int(true), const int& )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#809
|
||||
-------------------------------------------------------------------------------
|
||||
CompilationTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( 42 == f )
|
||||
with expansion:
|
||||
42 == {?}
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
'Not' checks that should fail
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -533,6 +567,111 @@ PASSED:
|
||||
with expansion:
|
||||
true
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Character pretty printing
|
||||
Specifically escaped
|
||||
-------------------------------------------------------------------------------
|
||||
ToStringGeneralTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ToStringGeneralTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK( tab == '\t' )
|
||||
with expansion:
|
||||
'\t' == '\t'
|
||||
|
||||
ToStringGeneralTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK( newline == '\n' )
|
||||
with expansion:
|
||||
'\n' == '\n'
|
||||
|
||||
ToStringGeneralTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK( carr_return == '\r' )
|
||||
with expansion:
|
||||
'\r' == '\r'
|
||||
|
||||
ToStringGeneralTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK( form_feed == '\f' )
|
||||
with expansion:
|
||||
'\f' == '\f'
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Character pretty printing
|
||||
General chars
|
||||
-------------------------------------------------------------------------------
|
||||
ToStringGeneralTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ToStringGeneralTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK( space == ' ' )
|
||||
with expansion:
|
||||
' ' == ' '
|
||||
|
||||
ToStringGeneralTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( c == chars[i] )
|
||||
with expansion:
|
||||
'a' == 'a'
|
||||
|
||||
ToStringGeneralTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( c == chars[i] )
|
||||
with expansion:
|
||||
'z' == 'z'
|
||||
|
||||
ToStringGeneralTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( c == chars[i] )
|
||||
with expansion:
|
||||
'A' == 'A'
|
||||
|
||||
ToStringGeneralTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( c == chars[i] )
|
||||
with expansion:
|
||||
'Z' == 'Z'
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Character pretty printing
|
||||
Low ASCII
|
||||
-------------------------------------------------------------------------------
|
||||
ToStringGeneralTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ToStringGeneralTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK( null_terminator == '\0' )
|
||||
with expansion:
|
||||
0 == 0
|
||||
|
||||
ToStringGeneralTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( c == i )
|
||||
with expansion:
|
||||
2 == 2
|
||||
|
||||
ToStringGeneralTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( c == i )
|
||||
with expansion:
|
||||
3 == 3
|
||||
|
||||
ToStringGeneralTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( c == i )
|
||||
with expansion:
|
||||
4 == 4
|
||||
|
||||
ToStringGeneralTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( c == i )
|
||||
with expansion:
|
||||
5 == 5
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Comparing function pointers
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -735,7 +874,7 @@ ExceptionTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ExceptionTests.cpp:<line number>: FAILED:
|
||||
REQUIRE_THROWS_AS( throwCustom() )
|
||||
REQUIRE_THROWS_AS( throwCustom(), std::exception )
|
||||
due to unexpected exception with message:
|
||||
custom exception - not std
|
||||
|
||||
@@ -979,12 +1118,12 @@ ExceptionTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ExceptionTests.cpp:<line number>: FAILED:
|
||||
CHECK_THROWS_AS( thisThrows() )
|
||||
CHECK_THROWS_AS( thisThrows(), std::string )
|
||||
due to unexpected exception with message:
|
||||
expected exception
|
||||
|
||||
ExceptionTests.cpp:<line number>: FAILED:
|
||||
CHECK_THROWS_AS( thisDoesntThrow() )
|
||||
CHECK_THROWS_AS( thisDoesntThrow(), std::domain_error )
|
||||
because no exception was thrown where one was expected:
|
||||
|
||||
ExceptionTests.cpp:<line number>: FAILED:
|
||||
@@ -7761,7 +7900,7 @@ ExceptionTests.cpp:<line number>
|
||||
|
||||
ExceptionTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THROWS_AS( thisThrows() )
|
||||
REQUIRE_THROWS_AS( thisThrows(), std::domain_error )
|
||||
|
||||
ExceptionTests.cpp:<line number>:
|
||||
PASSED:
|
||||
@@ -7989,9 +8128,9 @@ MiscTests.cpp:<line number>
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( encode( "[\x01]" ) == "[]" )
|
||||
REQUIRE( encode( "[\x01]" ) == "[\\x01]" )
|
||||
with expansion:
|
||||
"[]" == "[]"
|
||||
"[\x01]" == "[\x01]"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
XmlEncode
|
||||
@@ -8002,9 +8141,9 @@ MiscTests.cpp:<line number>
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( encode( "[\x7F]" ) == "[]" )
|
||||
REQUIRE( encode( "[\x7F]" ) == "[\\x7F]" )
|
||||
with expansion:
|
||||
"[]" == "[]"
|
||||
"[\x7F]" == "[\x7F]"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
atomic if
|
||||
@@ -8190,7 +8329,7 @@ MiscTests.cpp:<line number>
|
||||
MiscTests.cpp:<line number>:
|
||||
PASSED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
spanner-------------------------------------------------------------------------------
|
||||
just failure
|
||||
-------------------------------------------------------------------------------
|
||||
MessageTests.cpp:<line number>
|
||||
@@ -9025,6 +9164,6 @@ MiscTests.cpp:<line number>:
|
||||
PASSED:
|
||||
|
||||
===============================================================================
|
||||
test cases: 157 | 112 passed | 43 failed | 2 failed as expected
|
||||
assertions: 915 | 817 passed | 80 failed | 18 failed as expected
|
||||
test cases: 161 | 116 passed | 43 failed | 2 failed as expected
|
||||
assertions: 934 | 836 passed | 80 failed | 18 failed as expected
|
||||
|
||||
|
@@ -14,6 +14,40 @@ PASSED:
|
||||
with message:
|
||||
yay
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#542
|
||||
-------------------------------------------------------------------------------
|
||||
CompilationTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THROWS_AS( throws_int(true), int )
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THROWS_AS( throws_int(true), int& )
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THROWS_AS( throws_int(true), const int )
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THROWS_AS( throws_int(true), const int& )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#809
|
||||
-------------------------------------------------------------------------------
|
||||
CompilationTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
CompilationTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( 42 == f )
|
||||
with expansion:
|
||||
42 == {?}
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
'Not' checks that should fail
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -35,6 +69,6 @@ ConditionTests.cpp:<line number>: FAILED:
|
||||
CHECK_FALSE( true )
|
||||
|
||||
===============================================================================
|
||||
test cases: 2 | 1 passed | 1 failed
|
||||
assertions: 5 | 1 passed | 4 failed
|
||||
test cases: 4 | 3 passed | 1 failed
|
||||
assertions: 10 | 6 passed | 4 failed
|
||||
|
||||
|
@@ -1,7 +1,9 @@
|
||||
<?xml version="1.1" encoding="UTF-8"?>
|
||||
<testsuites>
|
||||
<testsuite name="<exe-name>" errors="13" failures="68" tests="916" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuitesspanner>
|
||||
<testsuite name="<exe-name>" errors="13" failures="68" tests="935" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||
<testcase classname="global" name="# A test name that starts with a #" time="{duration}"/>
|
||||
<testcase classname="global" name="#542" time="{duration}"/>
|
||||
<testcase classname="global" name="#809" time="{duration}"/>
|
||||
<testcase classname="global" name="'Not' checks that should fail" time="{duration}">
|
||||
<failure message="false != false" type="CHECK">
|
||||
ConditionTests.cpp:<line number>
|
||||
@@ -80,6 +82,9 @@ ExceptionTests.cpp:<line number>
|
||||
<testcase classname="Assertions then sections" name="A section" time="{duration}"/>
|
||||
<testcase classname="Assertions then sections" name="A section/Another section" time="{duration}"/>
|
||||
<testcase classname="Assertions then sections" name="A section/Another other section" time="{duration}"/>
|
||||
<testcase classname="Character pretty printing" name="Specifically escaped" time="{duration}"/>
|
||||
<testcase classname="Character pretty printing" name="General chars" time="{duration}"/>
|
||||
<testcase classname="Character pretty printing" name="Low ASCII" time="{duration}"/>
|
||||
<testcase classname="global" name="Comparing function pointers" time="{duration}"/>
|
||||
<testcase classname="global" name="Comparing member function pointers" time="{duration}"/>
|
||||
<testcase classname="global" name="Comparisons between ints where one side is computed" time="{duration}"/>
|
||||
@@ -97,7 +102,7 @@ ExceptionTests.cpp:<line number>
|
||||
</error>
|
||||
</testcase>
|
||||
<testcase classname="global" name="Custom exceptions can be translated when testing for throwing as something else" time="{duration}">
|
||||
<error message="throwCustom()" type="REQUIRE_THROWS_AS">
|
||||
<error message="throwCustom(), std::exception" type="REQUIRE_THROWS_AS">
|
||||
custom exception - not std
|
||||
ExceptionTests.cpp:<line number>
|
||||
</error>
|
||||
@@ -167,11 +172,11 @@ MiscTests.cpp:<line number>
|
||||
<testcase classname="Exception messages can be tested for" name="different case" time="{duration}"/>
|
||||
<testcase classname="Exception messages can be tested for" name="wildcarded" time="{duration}"/>
|
||||
<testcase classname="global" name="Expected exceptions that don't throw or unexpected exceptions fail the test" time="{duration}">
|
||||
<error message="thisThrows()" type="CHECK_THROWS_AS">
|
||||
<error message="thisThrows(), std::string" type="CHECK_THROWS_AS">
|
||||
expected exception
|
||||
ExceptionTests.cpp:<line number>
|
||||
</error>
|
||||
<failure message="thisDoesntThrow()" type="CHECK_THROWS_AS">
|
||||
<failure message="thisDoesntThrow(), std::domain_error" type="CHECK_THROWS_AS">
|
||||
ExceptionTests.cpp:<line number>
|
||||
</failure>
|
||||
<error message="thisThrows()" type="CHECK_NOTHROW">
|
||||
|
File diff suppressed because it is too large
Load Diff
42
projects/SelfTest/CompilationTests.cpp
Normal file
42
projects/SelfTest/CompilationTests.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Created by Martin on 17/02/2017.
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#include "catch.hpp"
|
||||
|
||||
|
||||
// This is a minimal example for an issue we have found in 1.7.0
|
||||
struct foo {
|
||||
int i;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
bool operator==(const T& val, foo f){
|
||||
return val == f.i;
|
||||
}
|
||||
|
||||
TEST_CASE("#809") {
|
||||
foo f; f.i = 42;
|
||||
REQUIRE(42 == f);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// REQUIRE_THROWS_AS was changed to catch exceptions by const&
|
||||
// using type traits. This means that this should compile cleanly
|
||||
|
||||
// Provides indirection to prevent unreachable-code warnings
|
||||
void throws_int(bool b) {
|
||||
if (b) {
|
||||
throw 1;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("#542") {
|
||||
CHECK_THROWS_AS(throws_int(true), int);
|
||||
CHECK_THROWS_AS(throws_int(true), int&);
|
||||
CHECK_THROWS_AS(throws_int(true), const int);
|
||||
CHECK_THROWS_AS(throws_int(true), const int&);
|
||||
}
|
@@ -458,10 +458,10 @@ TEST_CASE( "XmlEncode" ) {
|
||||
REQUIRE( encode( stringWithQuotes, Catch::XmlEncode::ForAttributes ) == "don't "quote" me on that" );
|
||||
}
|
||||
SECTION( "string with control char (1)" ) {
|
||||
REQUIRE( encode( "[\x01]" ) == "[]" );
|
||||
REQUIRE( encode( "[\x01]" ) == "[\\x01]" );
|
||||
}
|
||||
SECTION( "string with control char (x7F)" ) {
|
||||
REQUIRE( encode( "[\x7F]" ) == "[]" );
|
||||
REQUIRE( encode( "[\x7F]" ) == "[\\x7F]" );
|
||||
}
|
||||
}
|
||||
|
||||
|
40
projects/SelfTest/ToStringGeneralTests.cpp
Normal file
40
projects/SelfTest/ToStringGeneralTests.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Created by Martin on 17/02/2017.
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#include "catch.hpp"
|
||||
|
||||
|
||||
TEST_CASE( "Character pretty printing" ){
|
||||
//
|
||||
SECTION("Specifically escaped"){
|
||||
char tab = '\t';
|
||||
char newline = '\n';
|
||||
char carr_return = '\r';
|
||||
char form_feed = '\f';
|
||||
CHECK(tab == '\t');
|
||||
CHECK(newline == '\n');
|
||||
CHECK(carr_return == '\r');
|
||||
CHECK(form_feed == '\f');
|
||||
}
|
||||
SECTION("General chars"){
|
||||
char space = ' ';
|
||||
CHECK(space == ' ');
|
||||
char chars[] = {'a', 'z', 'A', 'Z'};
|
||||
for (int i = 0; i < 4; ++i){
|
||||
char c = chars[i];
|
||||
REQUIRE(c == chars[i]);
|
||||
}
|
||||
}
|
||||
SECTION("Low ASCII"){
|
||||
char null_terminator = '\0';
|
||||
CHECK(null_terminator == '\0');
|
||||
for (int i = 2; i < 6; ++i){
|
||||
char c = static_cast<char>(i);
|
||||
REQUIRE(c == i);
|
||||
}
|
||||
}
|
||||
}
|
@@ -399,3 +399,9 @@ TEST_CASE( "X/level/0/a", "[Tricky]" ) { SUCCEED(""); }
|
||||
TEST_CASE( "X/level/0/b", "[Tricky][fizz]" ){ SUCCEED(""); }
|
||||
TEST_CASE( "X/level/1/a", "[Tricky]" ) { SUCCEED(""); }
|
||||
TEST_CASE( "X/level/1/b", "[Tricky]" ) { SUCCEED(""); }
|
||||
|
||||
TEST_CASE( "has printf", "" ) {
|
||||
|
||||
// This can cause problems as, currently, stdout itself is not redirect - only the cout (and cerr) buffer
|
||||
printf( "spanner" );
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Catch v1.7.0
|
||||
* Generated: 2017-02-01 21:32:13.239291
|
||||
* Catch v1.7.2
|
||||
* Generated: 2017-02-13 15:57:33.350226
|
||||
* ----------------------------------------------------------
|
||||
* This file has been merged from multiple headers. Please don't edit it directly
|
||||
* Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
|
||||
@@ -81,6 +81,7 @@
|
||||
|
||||
// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
|
||||
// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
|
||||
// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
|
||||
// ****************
|
||||
// Note to maintainers: if new toggles are added please document them
|
||||
// in configuration.md, too
|
||||
@@ -160,6 +161,8 @@
|
||||
// Visual C++
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
|
||||
|
||||
#if (_MSC_VER >= 1600)
|
||||
# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
|
||||
# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
|
||||
@@ -284,6 +287,9 @@
|
||||
# if defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_NO_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_NO_CPP11)
|
||||
# define CATCH_CONFIG_CPP11_TYPE_TRAITS
|
||||
# endif
|
||||
#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH)
|
||||
# define CATCH_CONFIG_WINDOWS_SEH
|
||||
#endif
|
||||
|
||||
#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
|
||||
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
|
||||
@@ -331,7 +337,6 @@
|
||||
#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
|
||||
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
|
||||
namespace Catch {
|
||||
@@ -390,7 +395,6 @@ namespace Catch {
|
||||
bool endsWith( std::string const& s, std::string const& suffix );
|
||||
bool endsWith( std::string const& s, char suffix );
|
||||
bool contains( std::string const& s, std::string const& infix );
|
||||
bool contains( std::string const& s, std::string const& infix );
|
||||
void toLowerInPlace( std::string& s );
|
||||
std::string toLower( std::string const& s );
|
||||
std::string trim( std::string const& str );
|
||||
@@ -453,8 +457,6 @@ namespace Catch {
|
||||
#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
|
||||
#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
class NotImplementedException : public std::exception
|
||||
@@ -587,10 +589,6 @@ namespace Catch {
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
class TestCase;
|
||||
@@ -1878,45 +1876,45 @@ public:
|
||||
|
||||
template<typename RhsT>
|
||||
BinaryExpression<T, Internal::IsEqualTo, RhsT const&>
|
||||
operator == ( RhsT const& rhs ) const {
|
||||
operator == ( RhsT const& rhs ) {
|
||||
return captureExpression<Internal::IsEqualTo>( rhs );
|
||||
}
|
||||
|
||||
template<typename RhsT>
|
||||
BinaryExpression<T, Internal::IsNotEqualTo, RhsT const&>
|
||||
operator != ( RhsT const& rhs ) const {
|
||||
operator != ( RhsT const& rhs ) {
|
||||
return captureExpression<Internal::IsNotEqualTo>( rhs );
|
||||
}
|
||||
|
||||
template<typename RhsT>
|
||||
BinaryExpression<T, Internal::IsLessThan, RhsT const&>
|
||||
operator < ( RhsT const& rhs ) const {
|
||||
operator < ( RhsT const& rhs ) {
|
||||
return captureExpression<Internal::IsLessThan>( rhs );
|
||||
}
|
||||
|
||||
template<typename RhsT>
|
||||
BinaryExpression<T, Internal::IsGreaterThan, RhsT const&>
|
||||
operator > ( RhsT const& rhs ) const {
|
||||
operator > ( RhsT const& rhs ) {
|
||||
return captureExpression<Internal::IsGreaterThan>( rhs );
|
||||
}
|
||||
|
||||
template<typename RhsT>
|
||||
BinaryExpression<T, Internal::IsLessThanOrEqualTo, RhsT const&>
|
||||
operator <= ( RhsT const& rhs ) const {
|
||||
operator <= ( RhsT const& rhs ) {
|
||||
return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
|
||||
}
|
||||
|
||||
template<typename RhsT>
|
||||
BinaryExpression<T, Internal::IsGreaterThanOrEqualTo, RhsT const&>
|
||||
operator >= ( RhsT const& rhs ) const {
|
||||
operator >= ( RhsT const& rhs ) {
|
||||
return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
|
||||
}
|
||||
|
||||
BinaryExpression<T, Internal::IsEqualTo, bool> operator == ( bool rhs ) const {
|
||||
BinaryExpression<T, Internal::IsEqualTo, bool> operator == ( bool rhs ) {
|
||||
return captureExpression<Internal::IsEqualTo>( rhs );
|
||||
}
|
||||
|
||||
BinaryExpression<T, Internal::IsNotEqualTo, bool> operator != ( bool rhs ) const {
|
||||
BinaryExpression<T, Internal::IsNotEqualTo, bool> operator != ( bool rhs ) {
|
||||
return captureExpression<Internal::IsNotEqualTo>( rhs );
|
||||
}
|
||||
|
||||
@@ -2209,6 +2207,45 @@ namespace Catch {
|
||||
};
|
||||
}
|
||||
|
||||
// #included from: catch_type_traits.hpp
|
||||
#define TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED
|
||||
|
||||
#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
namespace Catch {
|
||||
|
||||
#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
|
||||
|
||||
template <typename T>
|
||||
using add_lvalue_reference = std::add_lvalue_reference<T>;
|
||||
|
||||
template <typename T>
|
||||
using add_const = std::add_const<T>;
|
||||
|
||||
#else
|
||||
|
||||
template <typename T>
|
||||
struct add_const {
|
||||
typedef const T type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct add_lvalue_reference {
|
||||
typedef T& type;
|
||||
};
|
||||
template <typename T>
|
||||
struct add_lvalue_reference<T&> {
|
||||
typedef T& type;
|
||||
};
|
||||
// No && overload, because that is C++11, in which case we have
|
||||
// proper type_traits implementation from the standard library
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// In the event of a failure works out if the debugger needs to be invoked
|
||||
// and/or an exception thrown and takes appropriate action.
|
||||
@@ -2277,13 +2314,13 @@ namespace Catch {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
|
||||
do { \
|
||||
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
|
||||
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr ", " #exceptionType, resultDisposition ); \
|
||||
if( __catchResult.allowThrows() ) \
|
||||
try { \
|
||||
static_cast<void>(expr); \
|
||||
__catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
|
||||
} \
|
||||
catch( exceptionType ) { \
|
||||
catch( Catch::add_const<Catch::add_lvalue_reference<exceptionType>::type>::type ) { \
|
||||
__catchResult.captureResult( Catch::ResultWas::Ok ); \
|
||||
} \
|
||||
catch( ... ) { \
|
||||
@@ -2405,6 +2442,8 @@ namespace Catch {
|
||||
};
|
||||
}
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
struct SectionInfo {
|
||||
@@ -2812,7 +2851,7 @@ namespace Detail {
|
||||
friend bool operator == ( const T& lhs, Approx const& rhs ) {
|
||||
// Thanks to Richard Harris for his help refining this formula
|
||||
auto lhs_v = double(lhs);
|
||||
return fabs( lhs_v - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs_v), fabs(rhs.m_value) ) );
|
||||
return std::fabs( lhs_v - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( std::fabs(lhs_v), std::fabs(rhs.m_value) ) );
|
||||
}
|
||||
|
||||
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||
@@ -2856,7 +2895,7 @@ namespace Detail {
|
||||
#else
|
||||
friend bool operator == ( double lhs, Approx const& rhs ) {
|
||||
// Thanks to Richard Harris for his help refining this formula
|
||||
return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
|
||||
return std::fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( std::fabs(lhs), std::fabs(rhs.m_value) ) );
|
||||
}
|
||||
|
||||
friend bool operator == ( Approx const& lhs, double rhs ) {
|
||||
@@ -3342,6 +3381,8 @@ return @ desc; \
|
||||
// #included from: catch_wildcard_pattern.hpp
|
||||
#define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace Catch
|
||||
{
|
||||
class WildcardPattern {
|
||||
@@ -3595,7 +3636,7 @@ namespace Catch {
|
||||
// #included from: catch_interfaces_config.h
|
||||
#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
|
||||
|
||||
#include <iostream>
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -3717,8 +3758,7 @@ namespace Catch {
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
#include <stdexcept>
|
||||
|
||||
#ifndef CATCH_CONFIG_CONSOLE_WIDTH
|
||||
#define CATCH_CONFIG_CONSOLE_WIDTH 80
|
||||
@@ -3800,8 +3840,7 @@ namespace Catch {
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~Config() {
|
||||
}
|
||||
virtual ~Config() {}
|
||||
|
||||
std::string const& getFilename() const {
|
||||
return m_data.outputFilename ;
|
||||
@@ -3814,28 +3853,26 @@ namespace Catch {
|
||||
|
||||
std::string getProcessName() const { return m_data.processName; }
|
||||
|
||||
bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
|
||||
|
||||
std::vector<std::string> const& getReporterNames() const { return m_data.reporterNames; }
|
||||
std::vector<std::string> const& getSectionsToRun() const CATCH_OVERRIDE { return m_data.sectionsToRun; }
|
||||
|
||||
int abortAfter() const { return m_data.abortAfter; }
|
||||
|
||||
TestSpec const& testSpec() const { return m_testSpec; }
|
||||
virtual TestSpec const& testSpec() const CATCH_OVERRIDE { return m_testSpec; }
|
||||
|
||||
bool showHelp() const { return m_data.showHelp; }
|
||||
bool showInvisibles() const { return m_data.showInvisibles; }
|
||||
|
||||
// IConfig interface
|
||||
virtual bool allowThrows() const { return !m_data.noThrow; }
|
||||
virtual std::ostream& stream() const { return m_stream->stream(); }
|
||||
virtual std::string name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
|
||||
virtual bool includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
|
||||
virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
|
||||
virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
|
||||
virtual RunTests::InWhatOrder runOrder() const { return m_data.runOrder; }
|
||||
virtual unsigned int rngSeed() const { return m_data.rngSeed; }
|
||||
virtual UseColour::YesOrNo useColour() const { return m_data.useColour; }
|
||||
virtual bool allowThrows() const CATCH_OVERRIDE { return !m_data.noThrow; }
|
||||
virtual std::ostream& stream() const CATCH_OVERRIDE { return m_stream->stream(); }
|
||||
virtual std::string name() const CATCH_OVERRIDE { return m_data.name.empty() ? m_data.processName : m_data.name; }
|
||||
virtual bool includeSuccessfulResults() const CATCH_OVERRIDE { return m_data.showSuccessfulTests; }
|
||||
virtual bool warnAboutMissingAssertions() const CATCH_OVERRIDE { return m_data.warnings & WarnAbout::NoAssertions; }
|
||||
virtual ShowDurations::OrNot showDurations() const CATCH_OVERRIDE { return m_data.showDurations; }
|
||||
virtual RunTests::InWhatOrder runOrder() const CATCH_OVERRIDE { return m_data.runOrder; }
|
||||
virtual unsigned int rngSeed() const CATCH_OVERRIDE { return m_data.rngSeed; }
|
||||
virtual UseColour::YesOrNo useColour() const CATCH_OVERRIDE { return m_data.useColour; }
|
||||
virtual bool shouldDebugBreak() const CATCH_OVERRIDE { return m_data.shouldDebugBreak; }
|
||||
virtual int abortAfter() const CATCH_OVERRIDE { return m_data.abortAfter; }
|
||||
virtual bool showInvisibles() const CATCH_OVERRIDE { return m_data.showInvisibles; }
|
||||
|
||||
private:
|
||||
|
||||
@@ -4897,6 +4934,7 @@ STITCH_CLARA_CLOSE_NAMESPACE
|
||||
#endif
|
||||
|
||||
#include <fstream>
|
||||
#include <ctime>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@@ -4935,7 +4973,7 @@ namespace Catch {
|
||||
ss << seed;
|
||||
ss >> config.rngSeed;
|
||||
if( ss.fail() )
|
||||
throw std::runtime_error( "Argment to --rng-seed should be the word 'time' or a number" );
|
||||
throw std::runtime_error( "Argument to --rng-seed should be the word 'time' or a number" );
|
||||
}
|
||||
}
|
||||
inline void setVerbosity( ConfigData& config, int level ) {
|
||||
@@ -5332,7 +5370,6 @@ namespace Catch {
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
#include <map>
|
||||
#include <assert.h>
|
||||
|
||||
namespace Catch
|
||||
{
|
||||
@@ -5756,6 +5793,7 @@ namespace Catch {
|
||||
#include <assert.h>
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace Catch {
|
||||
namespace TestCaseTracking {
|
||||
@@ -6117,12 +6155,40 @@ namespace Catch {
|
||||
} // namespace Catch
|
||||
|
||||
#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
|
||||
// #included from: catch_windows_h_proxy.h
|
||||
|
||||
#define NOMINMAX
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED
|
||||
|
||||
#ifdef CATCH_DEFINES_NOMINMAX
|
||||
# define NOMINMAX
|
||||
#endif
|
||||
#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#ifdef __AFXDLL
|
||||
#include <AfxWin.h>
|
||||
#else
|
||||
#include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#undef NOMINMAX
|
||||
#endif
|
||||
|
||||
#ifdef CATCH_DEFINES_NOMINMAX
|
||||
# undef NOMINMAX
|
||||
#endif
|
||||
#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN
|
||||
# undef WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
|
||||
# if !defined ( CATCH_CONFIG_WINDOWS_SEH )
|
||||
|
||||
namespace Catch {
|
||||
struct FatalConditionHandler {
|
||||
void reset() {}
|
||||
};
|
||||
}
|
||||
|
||||
# else // CATCH_CONFIG_WINDOWS_SEH is defined
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@@ -6143,6 +6209,7 @@ namespace Catch {
|
||||
static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
|
||||
for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
||||
if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
|
||||
reset();
|
||||
reportFatal(signalDefs[i].name);
|
||||
}
|
||||
}
|
||||
@@ -6151,22 +6218,25 @@ namespace Catch {
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
// 32k seems enough for Catch to handle stack overflow,
|
||||
// but the value was found experimentally, so there is no strong guarantee
|
||||
FatalConditionHandler():m_isSet(true), m_guaranteeSize(32 * 1024), m_exceptionHandlerHandle(CATCH_NULL) {
|
||||
FatalConditionHandler() {
|
||||
isSet = true;
|
||||
// 32k seems enough for Catch to handle stack overflow,
|
||||
// but the value was found experimentally, so there is no strong guarantee
|
||||
guaranteeSize = 32 * 1024;
|
||||
exceptionHandlerHandle = CATCH_NULL;
|
||||
// Register as first handler in current chain
|
||||
m_exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
|
||||
exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
|
||||
// Pass in guarantee size to be filled
|
||||
SetThreadStackGuarantee(&m_guaranteeSize);
|
||||
SetThreadStackGuarantee(&guaranteeSize);
|
||||
}
|
||||
|
||||
void reset() {
|
||||
if (m_isSet) {
|
||||
static void reset() {
|
||||
if (isSet) {
|
||||
// Unregister handler and restore the old guarantee
|
||||
RemoveVectoredExceptionHandler(m_exceptionHandlerHandle);
|
||||
SetThreadStackGuarantee(&m_guaranteeSize);
|
||||
m_exceptionHandlerHandle = CATCH_NULL;
|
||||
m_isSet = false;
|
||||
RemoveVectoredExceptionHandler(exceptionHandlerHandle);
|
||||
SetThreadStackGuarantee(&guaranteeSize);
|
||||
exceptionHandlerHandle = CATCH_NULL;
|
||||
isSet = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6174,13 +6244,19 @@ namespace Catch {
|
||||
reset();
|
||||
}
|
||||
private:
|
||||
bool m_isSet;
|
||||
ULONG m_guaranteeSize;
|
||||
PVOID m_exceptionHandlerHandle;
|
||||
static bool isSet;
|
||||
static ULONG guaranteeSize;
|
||||
static PVOID exceptionHandlerHandle;
|
||||
};
|
||||
|
||||
bool FatalConditionHandler::isSet = false;
|
||||
ULONG FatalConditionHandler::guaranteeSize = 0;
|
||||
PVOID FatalConditionHandler::exceptionHandlerHandle = CATCH_NULL;
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
# endif // CATCH_CONFIG_WINDOWS_SEH
|
||||
|
||||
#else // Not Windows - assumed to be POSIX compatible //////////////////////////
|
||||
|
||||
#include <signal.h>
|
||||
@@ -6338,7 +6414,8 @@ namespace Catch {
|
||||
|
||||
do {
|
||||
ITracker& rootTracker = m_trackerContext.startRun();
|
||||
dynamic_cast<SectionTracker&>( rootTracker ).addInitialFilters( m_config->getSectionsToRun() );
|
||||
assert( rootTracker.isSectionTracker() );
|
||||
static_cast<SectionTracker&>( rootTracker ).addInitialFilters( m_config->getSectionsToRun() );
|
||||
do {
|
||||
m_trackerContext.startCycle();
|
||||
m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( testInfo.name, testInfo.lineInfo ) );
|
||||
@@ -6837,7 +6914,6 @@ namespace Catch {
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
namespace Catch {
|
||||
@@ -7197,7 +7273,7 @@ namespace Catch {
|
||||
// #included from: catch_notimplemented_exception.hpp
|
||||
#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
|
||||
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@@ -7440,30 +7516,6 @@ namespace Catch {
|
||||
|
||||
#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
|
||||
|
||||
// #included from: catch_windows_h_proxy.h
|
||||
|
||||
#define TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED
|
||||
|
||||
#ifdef CATCH_DEFINES_NOMINMAX
|
||||
# define NOMINMAX
|
||||
#endif
|
||||
#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#ifdef __AFXDLL
|
||||
#include <AfxWin.h>
|
||||
#else
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef CATCH_DEFINES_NOMINMAX
|
||||
# undef NOMINMAX
|
||||
#endif
|
||||
#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN
|
||||
# undef WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
namespace Catch {
|
||||
namespace {
|
||||
|
||||
@@ -7773,6 +7825,8 @@ namespace Catch {
|
||||
// #included from: catch_test_case_info.hpp
|
||||
#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
|
||||
|
||||
#include <cctype>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
|
||||
@@ -7792,7 +7846,7 @@ namespace Catch {
|
||||
return TestCaseInfo::None;
|
||||
}
|
||||
inline bool isReservedTag( std::string const& tag ) {
|
||||
return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] );
|
||||
return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( tag[0] );
|
||||
}
|
||||
inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
|
||||
if( isReservedTag( tag ) ) {
|
||||
@@ -7989,7 +8043,7 @@ namespace Catch {
|
||||
return os;
|
||||
}
|
||||
|
||||
Version libraryVersion( 1, 7, 0, "", 0 );
|
||||
Version libraryVersion( 1, 7, 2, "", 0 );
|
||||
|
||||
}
|
||||
|
||||
@@ -8209,6 +8263,7 @@ namespace Catch {
|
||||
#define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
|
||||
|
||||
#include <cstring>
|
||||
#include <cctype>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@@ -8227,11 +8282,8 @@ namespace Catch {
|
||||
bool contains( std::string const& s, std::string const& infix ) {
|
||||
return s.find( infix ) != std::string::npos;
|
||||
}
|
||||
bool contains( std::string const& s, char infix ) {
|
||||
return s.find(infix) != std::string::npos;
|
||||
}
|
||||
char toLowerCh(char c) {
|
||||
return static_cast<char>( ::tolower( c ) );
|
||||
return static_cast<char>( std::tolower( c ) );
|
||||
}
|
||||
void toLowerInPlace( std::string& s ) {
|
||||
std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
|
||||
@@ -8356,8 +8408,6 @@ namespace Catch {
|
||||
// #included from: catch_debugger.hpp
|
||||
#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#ifdef CATCH_PLATFORM_MAC
|
||||
|
||||
#include <assert.h>
|
||||
@@ -8454,7 +8504,7 @@ namespace Catch {
|
||||
#endif // Platform
|
||||
|
||||
#ifdef CATCH_PLATFORM_WINDOWS
|
||||
extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );
|
||||
|
||||
namespace Catch {
|
||||
void writeToDebugConsole( std::string const& text ) {
|
||||
::OutputDebugStringA( text.c_str() );
|
||||
@@ -8820,9 +8870,6 @@ namespace Catch {
|
||||
|
||||
} // end namespace Catch
|
||||
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
TagAliasRegistry::~TagAliasRegistry() {}
|
||||
@@ -9256,7 +9303,7 @@ namespace Catch {
|
||||
char const* getLineOfChars() {
|
||||
static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
|
||||
if( !*line ) {
|
||||
memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
|
||||
std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
|
||||
line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
|
||||
}
|
||||
return line;
|
||||
@@ -9410,8 +9457,11 @@ namespace Catch {
|
||||
default:
|
||||
// Escape control chars - based on contribution by @espenalb in PR #465 and
|
||||
// by @mrpi PR #588
|
||||
if ( ( c >= 0 && c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' )
|
||||
os << "&#x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>( c ) << ';';
|
||||
if ( ( c >= 0 && c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' ) {
|
||||
// see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
|
||||
os << "\\x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
|
||||
<< static_cast<int>( c );
|
||||
}
|
||||
else
|
||||
os << c;
|
||||
}
|
||||
@@ -9465,20 +9515,17 @@ namespace Catch {
|
||||
XmlWriter()
|
||||
: m_tagIsOpen( false ),
|
||||
m_needsNewline( false ),
|
||||
m_os( &Catch::cout() )
|
||||
m_os( Catch::cout() )
|
||||
{
|
||||
// We encode control characters, which requires
|
||||
// XML 1.1
|
||||
// see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
|
||||
*m_os << "<?xml version=\"1.1\" encoding=\"UTF-8\"?>\n";
|
||||
writeDeclaration();
|
||||
}
|
||||
|
||||
XmlWriter( std::ostream& os )
|
||||
: m_tagIsOpen( false ),
|
||||
m_needsNewline( false ),
|
||||
m_os( &os )
|
||||
m_os( os )
|
||||
{
|
||||
*m_os << "<?xml version=\"1.1\" encoding=\"UTF-8\"?>\n";
|
||||
writeDeclaration();
|
||||
}
|
||||
|
||||
~XmlWriter() {
|
||||
@@ -9489,7 +9536,7 @@ namespace Catch {
|
||||
XmlWriter& startElement( std::string const& name ) {
|
||||
ensureTagClosed();
|
||||
newlineIfNecessary();
|
||||
stream() << m_indent << '<' << name;
|
||||
m_os << m_indent << '<' << name;
|
||||
m_tags.push_back( name );
|
||||
m_indent += " ";
|
||||
m_tagIsOpen = true;
|
||||
@@ -9506,24 +9553,25 @@ namespace Catch {
|
||||
newlineIfNecessary();
|
||||
m_indent = m_indent.substr( 0, m_indent.size()-2 );
|
||||
if( m_tagIsOpen ) {
|
||||
stream() << "/>\n";
|
||||
m_os << "/>";
|
||||
m_tagIsOpen = false;
|
||||
}
|
||||
else {
|
||||
stream() << m_indent << "</" << m_tags.back() << ">\n";
|
||||
m_os << m_indent << "</" << m_tags.back() << ">";
|
||||
}
|
||||
m_os << std::endl;
|
||||
m_tags.pop_back();
|
||||
return *this;
|
||||
}
|
||||
|
||||
XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
|
||||
if( !name.empty() && !attribute.empty() )
|
||||
stream() << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
|
||||
m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
|
||||
return *this;
|
||||
}
|
||||
|
||||
XmlWriter& writeAttribute( std::string const& name, bool attribute ) {
|
||||
stream() << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
|
||||
m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -9539,8 +9587,8 @@ namespace Catch {
|
||||
bool tagWasOpen = m_tagIsOpen;
|
||||
ensureTagClosed();
|
||||
if( tagWasOpen && indent )
|
||||
stream() << m_indent;
|
||||
stream() << XmlEncode( text );
|
||||
m_os << m_indent;
|
||||
m_os << XmlEncode( text );
|
||||
m_needsNewline = true;
|
||||
}
|
||||
return *this;
|
||||
@@ -9548,39 +9596,39 @@ namespace Catch {
|
||||
|
||||
XmlWriter& writeComment( std::string const& text ) {
|
||||
ensureTagClosed();
|
||||
stream() << m_indent << "<!--" << text << "-->";
|
||||
m_os << m_indent << "<!--" << text << "-->";
|
||||
m_needsNewline = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void writeStylesheetRef( std::string const& url ) {
|
||||
m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
|
||||
}
|
||||
|
||||
XmlWriter& writeBlankLine() {
|
||||
ensureTagClosed();
|
||||
stream() << '\n';
|
||||
m_os << '\n';
|
||||
return *this;
|
||||
}
|
||||
|
||||
void setStream( std::ostream& os ) {
|
||||
m_os = &os;
|
||||
void ensureTagClosed() {
|
||||
if( m_tagIsOpen ) {
|
||||
m_os << ">" << std::endl;
|
||||
m_tagIsOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
XmlWriter( XmlWriter const& );
|
||||
void operator=( XmlWriter const& );
|
||||
|
||||
std::ostream& stream() {
|
||||
return *m_os;
|
||||
}
|
||||
|
||||
void ensureTagClosed() {
|
||||
if( m_tagIsOpen ) {
|
||||
stream() << ">\n";
|
||||
m_tagIsOpen = false;
|
||||
}
|
||||
void writeDeclaration() {
|
||||
m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
|
||||
}
|
||||
|
||||
void newlineIfNecessary() {
|
||||
if( m_needsNewline ) {
|
||||
stream() << '\n';
|
||||
m_os << std::endl;
|
||||
m_needsNewline = false;
|
||||
}
|
||||
}
|
||||
@@ -9589,7 +9637,7 @@ namespace Catch {
|
||||
bool m_needsNewline;
|
||||
std::vector<std::string> m_tags;
|
||||
std::string m_indent;
|
||||
std::ostream* m_os;
|
||||
std::ostream& m_os;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -9625,6 +9673,10 @@ namespace Catch {
|
||||
return "Reports test results as an XML document";
|
||||
}
|
||||
|
||||
virtual std::string getStylesheetRef() const {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
public: // StreamingReporterBase
|
||||
|
||||
virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE {
|
||||
@@ -9633,6 +9685,9 @@ namespace Catch {
|
||||
|
||||
virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE {
|
||||
StreamingReporterBase::testRunStarting( testInfo );
|
||||
std::string stylesheetRef = getStylesheetRef();
|
||||
if( !stylesheetRef.empty() )
|
||||
m_xml.writeStylesheetRef( stylesheetRef );
|
||||
m_xml.startElement( "Catch" );
|
||||
if( !m_config->name().empty() )
|
||||
m_xml.writeAttribute( "name", m_config->name() );
|
||||
@@ -9646,10 +9701,14 @@ namespace Catch {
|
||||
|
||||
virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
|
||||
StreamingReporterBase::testCaseStarting(testInfo);
|
||||
m_xml.startElement( "TestCase" ).writeAttribute( "name", testInfo.name );
|
||||
m_xml.startElement( "TestCase" )
|
||||
.writeAttribute( "name", trim( testInfo.name ) )
|
||||
.writeAttribute( "description", testInfo.description )
|
||||
.writeAttribute( "tags", testInfo.tagsAsString );
|
||||
|
||||
if ( m_config->showDurations() == ShowDurations::Always )
|
||||
m_testCaseTimer.start();
|
||||
m_xml.ensureTagClosed();
|
||||
}
|
||||
|
||||
virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
|
||||
@@ -9658,6 +9717,7 @@ namespace Catch {
|
||||
m_xml.startElement( "Section" )
|
||||
.writeAttribute( "name", trim( sectionInfo.name ) )
|
||||
.writeAttribute( "description", sectionInfo.description );
|
||||
m_xml.ensureTagClosed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9757,6 +9817,11 @@ namespace Catch {
|
||||
if ( m_config->showDurations() == ShowDurations::Always )
|
||||
e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
|
||||
|
||||
if( !testCaseStats.stdOut.empty() )
|
||||
m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false );
|
||||
if( !testCaseStats.stdErr.empty() )
|
||||
m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false );
|
||||
|
||||
m_xml.endElement();
|
||||
}
|
||||
|
||||
@@ -9804,7 +9869,7 @@ namespace Catch {
|
||||
std::time(&rawtime);
|
||||
const size_t timeStampSize = sizeof("2017-01-16T17:06:45Z");
|
||||
|
||||
#ifdef CATCH_PLATFORM_WINDOWS
|
||||
#ifdef _MSC_VER
|
||||
std::tm timeInfo = {};
|
||||
gmtime_s(&timeInfo, &rawtime);
|
||||
#else
|
||||
@@ -9815,7 +9880,7 @@ namespace Catch {
|
||||
char timeStamp[timeStampSize];
|
||||
const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
|
||||
|
||||
#ifdef CATCH_PLATFORM_WINDOWS
|
||||
#ifdef _MSC_VER
|
||||
std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
|
||||
#else
|
||||
std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
|
||||
@@ -10301,7 +10366,7 @@ namespace Catch {
|
||||
printHeaderString( it->name, 2 );
|
||||
}
|
||||
|
||||
SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
|
||||
SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
|
||||
|
||||
if( !lineInfo.empty() ){
|
||||
stream << getLineOfChars<'-'>() << '\n';
|
||||
|
Reference in New Issue
Block a user