mirror of
https://github.com/catchorg/Catch2.git
synced 2025-09-23 13:05:39 +02:00
Compare commits
55 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ce37f48ffa | ||
![]() |
090fc74cca | ||
![]() |
f58ff0c540 | ||
![]() |
a600bfeb75 | ||
![]() |
8cad76a749 | ||
![]() |
1a3f6d829b | ||
![]() |
b524fa7cd8 | ||
![]() |
5121b5b058 | ||
![]() |
1e5176bd69 | ||
![]() |
7dd4f2977a | ||
![]() |
50c95a0143 | ||
![]() |
0dabd951ba | ||
![]() |
7ae96c710b | ||
![]() |
70d3c937c3 | ||
![]() |
38af8d7035 | ||
![]() |
c97ada1910 | ||
![]() |
615aa071a8 | ||
![]() |
af0b03abd2 | ||
![]() |
15816c5760 | ||
![]() |
f11a45aa67 | ||
![]() |
bcaa2f9646 | ||
![]() |
efab3ca8b2 | ||
![]() |
60f8ebec49 | ||
![]() |
e1dbb7cf64 | ||
![]() |
02a69b449f | ||
![]() |
c390c4cb9f | ||
![]() |
60a9ac7e65 | ||
![]() |
c06afe438e | ||
![]() |
73872207db | ||
![]() |
51860f1568 | ||
![]() |
dab1d9d222 | ||
![]() |
4ce11d63a6 | ||
![]() |
99c2ea594c | ||
![]() |
51107d7cbd | ||
![]() |
83f4b39680 | ||
![]() |
b1171bd1f2 | ||
![]() |
6c23a6582b | ||
![]() |
7bcb42496d | ||
![]() |
184865358c | ||
![]() |
225e90d8ba | ||
![]() |
31c23b9489 | ||
![]() |
f347611403 | ||
![]() |
1efd8d3067 | ||
![]() |
876af874f3 | ||
![]() |
e7bcbb35c0 | ||
![]() |
4a04682e49 | ||
![]() |
3b98a0166f | ||
![]() |
877fd523bc | ||
![]() |
a1e9b841ff | ||
![]() |
3b7511e564 | ||
![]() |
ffc4a9dc14 | ||
![]() |
7c8b93eac3 | ||
![]() |
40dbdf6cb2 | ||
![]() |
70f43d719b | ||
![]() |
a281173099 |
29
.github/issue_template.md
vendored
Normal file
29
.github/issue_template.md
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
## Description
|
||||||
|
<!--
|
||||||
|
If your issue is a bugreport, this means describing what you did,
|
||||||
|
what did you want to happen and what actually did happen.
|
||||||
|
|
||||||
|
If your issue is a feature request, describe the feature and why do you
|
||||||
|
want it.
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
### Steps to reproduce
|
||||||
|
<!--
|
||||||
|
This is only relevant for bug reports, but if you do have one,
|
||||||
|
please provide a minimal set of steps to reproduce the problem.
|
||||||
|
|
||||||
|
Usually this means providing a small and self-contained code using Catch
|
||||||
|
and specifying compiler flags/tools used if relevant.
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
### Extra information
|
||||||
|
<!--
|
||||||
|
Fill in any extra information that might be important for your issue.
|
||||||
|
|
||||||
|
If your issue is a bugreport, definitely fill out at least the following.
|
||||||
|
-->
|
||||||
|
* Catch version: **v42.42.42**
|
||||||
|
* Operating System: **Joe's discount operating system**
|
||||||
|
* Compiler+version: **Hidden Dragon v1.2.3**
|
25
.github/pull_request_template.md
vendored
Normal file
25
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<!--
|
||||||
|
Please do not submit pull requests changing the `version.hpp`
|
||||||
|
or the single-include `catch.hpp` file, these are changed
|
||||||
|
only when a new release is made.
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
## Description
|
||||||
|
<!--
|
||||||
|
Describe the what and the why of your pull request. Remember that these two
|
||||||
|
are usually a bit different. As an example, if you have made various changes
|
||||||
|
to decrease the number of new strings allocated, thats what. The why probably
|
||||||
|
was that you have a large set of tests and found that this speeds them up.
|
||||||
|
-->
|
||||||
|
|
||||||
|
## GitHub Issues
|
||||||
|
<!--
|
||||||
|
If this PR was motivated by some existing issues, reference them here.
|
||||||
|
|
||||||
|
If it is a simple bug-fix, please also add a line like 'Closes #123'
|
||||||
|
to your commit message, so that it is automatically closed.
|
||||||
|
If it is not, don't, as it might take several iterations for a feature
|
||||||
|
to be done properly. If in doubt, leave it open and reference it in the
|
||||||
|
PR itself, so that maintainers can decide.
|
||||||
|
-->
|
@@ -119,12 +119,12 @@ matrix:
|
|||||||
|
|
||||||
# 3/ OSX Clang Builds
|
# 3/ OSX Clang Builds
|
||||||
- os: osx
|
- os: osx
|
||||||
osx_image: xcode7
|
osx_image: xcode7.3
|
||||||
compiler: clang
|
compiler: clang
|
||||||
env: COMPILER='ccache clang++' BUILD_TYPE='Debug'
|
env: COMPILER='ccache clang++' BUILD_TYPE='Debug'
|
||||||
|
|
||||||
- os: osx
|
- os: osx
|
||||||
osx_image: xcode7
|
osx_image: xcode7.3
|
||||||
compiler: clang
|
compiler: clang
|
||||||
env: COMPILER='ccache clang++' BUILD_TYPE='Release'
|
env: COMPILER='ccache clang++' BUILD_TYPE='Release'
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ install:
|
|||||||
- |
|
- |
|
||||||
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
|
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
|
||||||
CMAKE_URL="http://www.cmake.org/files/v3.3/cmake-3.3.2-Linux-x86_64.tar.gz"
|
CMAKE_URL="http://www.cmake.org/files/v3.3/cmake-3.3.2-Linux-x86_64.tar.gz"
|
||||||
mkdir cmake && travis_retry wget --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake
|
mkdir cmake && travis_retry wget --no-check-certificate --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake
|
||||||
export PATH=${DEPS_DIR}/cmake/bin:${PATH}
|
export PATH=${DEPS_DIR}/cmake/bin:${PATH}
|
||||||
elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
|
elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
|
||||||
which cmake || brew install cmake
|
which cmake || brew install cmake
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 3.0)
|
||||||
|
|
||||||
project(CatchSelfTest)
|
project(CatchSelfTest)
|
||||||
|
|
||||||
@@ -7,6 +7,7 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
|||||||
# define some folders
|
# define some folders
|
||||||
set(CATCH_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
set(CATCH_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
set(SELF_TEST_DIR ${CATCH_DIR}/projects/SelfTest)
|
set(SELF_TEST_DIR ${CATCH_DIR}/projects/SelfTest)
|
||||||
|
set(BENCHMARK_DIR ${CATCH_DIR}/projects/Benchmark)
|
||||||
set(HEADER_DIR ${CATCH_DIR}/include)
|
set(HEADER_DIR ${CATCH_DIR}/include)
|
||||||
|
|
||||||
if(USE_CPP11)
|
if(USE_CPP11)
|
||||||
@@ -91,6 +92,7 @@ set(IMPL_SOURCES
|
|||||||
${SELF_TEST_DIR}/SurrogateCpps/catch_streambuf.cpp
|
${SELF_TEST_DIR}/SurrogateCpps/catch_streambuf.cpp
|
||||||
${SELF_TEST_DIR}/SurrogateCpps/catch_test_spec.cpp
|
${SELF_TEST_DIR}/SurrogateCpps/catch_test_spec.cpp
|
||||||
${SELF_TEST_DIR}/SurrogateCpps/catch_xmlwriter.cpp
|
${SELF_TEST_DIR}/SurrogateCpps/catch_xmlwriter.cpp
|
||||||
|
${SELF_TEST_DIR}/SurrogateCpps/catch_test_case_tracker.cpp
|
||||||
)
|
)
|
||||||
CheckFileList(IMPL_SOURCES ${SELF_TEST_DIR}/SurrogateCpps)
|
CheckFileList(IMPL_SOURCES ${SELF_TEST_DIR}/SurrogateCpps)
|
||||||
|
|
||||||
@@ -102,7 +104,7 @@ set(TOP_LEVEL_HEADERS
|
|||||||
${HEADER_DIR}/catch_with_main.hpp
|
${HEADER_DIR}/catch_with_main.hpp
|
||||||
)
|
)
|
||||||
CheckFileList(TOP_LEVEL_HEADERS ${HEADER_DIR})
|
CheckFileList(TOP_LEVEL_HEADERS ${HEADER_DIR})
|
||||||
|
|
||||||
# Please keep these ordered alphabetically
|
# Please keep these ordered alphabetically
|
||||||
set(EXTERNAL_HEADERS
|
set(EXTERNAL_HEADERS
|
||||||
${HEADER_DIR}/external/clara.h
|
${HEADER_DIR}/external/clara.h
|
||||||
@@ -110,7 +112,7 @@ set(EXTERNAL_HEADERS
|
|||||||
)
|
)
|
||||||
CheckFileList(EXTERNAL_HEADERS ${HEADER_DIR}/external)
|
CheckFileList(EXTERNAL_HEADERS ${HEADER_DIR}/external)
|
||||||
|
|
||||||
|
|
||||||
# Please keep these ordered alphabetically
|
# Please keep these ordered alphabetically
|
||||||
set(INTERNAL_HEADERS
|
set(INTERNAL_HEADERS
|
||||||
${HEADER_DIR}/internal/catch_approx.hpp
|
${HEADER_DIR}/internal/catch_approx.hpp
|
||||||
@@ -220,13 +222,32 @@ set(HEADERS
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
set(BENCH_SOURCES
|
||||||
|
${BENCHMARK_DIR}/BenchMain.cpp
|
||||||
|
${BENCHMARK_DIR}/StringificationBench.cpp
|
||||||
|
)
|
||||||
|
CheckFileList(BENCH_SOURCES ${BENCHMARK_DIR})
|
||||||
|
|
||||||
# Provide some groupings for IDEs
|
# Provide some groupings for IDEs
|
||||||
SOURCE_GROUP("Tests" FILES ${TEST_SOURCES})
|
SOURCE_GROUP("Tests" FILES ${TEST_SOURCES})
|
||||||
SOURCE_GROUP("Surrogates" FILES ${IMPL_SOURCES})
|
SOURCE_GROUP("Surrogates" FILES ${IMPL_SOURCES})
|
||||||
|
SOURCE_GROUP("Benchmarks" FILES ${BENCH_SOURCES})
|
||||||
|
|
||||||
# configure the executable
|
# configure the executable
|
||||||
include_directories(${HEADER_DIR})
|
include_directories(${HEADER_DIR})
|
||||||
add_executable(SelfTest ${TEST_SOURCES} ${IMPL_SOURCES} ${HEADERS})
|
add_executable(SelfTest ${TEST_SOURCES} ${IMPL_SOURCES} ${HEADERS})
|
||||||
|
add_executable(Benchmark ${BENCH_SOURCES} ${HEADERS})
|
||||||
|
|
||||||
|
# Add desired warnings
|
||||||
|
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
|
||||||
|
target_compile_options( SelfTest PRIVATE -Wall -Wextra )
|
||||||
|
target_compile_options( Benchmark PRIVATE -Wall -Wextra )
|
||||||
|
endif()
|
||||||
|
if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
|
||||||
|
target_compile_options( SelfTest PRIVATE /W4 )
|
||||||
|
target_compile_options( Benchmark PRIVATE /W4 )
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
# configure unit tests via CTest
|
# configure unit tests via CTest
|
||||||
enable_testing()
|
enable_testing()
|
||||||
@@ -237,3 +258,5 @@ set_tests_properties(ListTests PROPERTIES PASS_REGULAR_EXPRESSION "[0-9]+ test c
|
|||||||
|
|
||||||
add_test(NAME ListTags COMMAND SelfTest --list-tags)
|
add_test(NAME ListTags COMMAND SelfTest --list-tags)
|
||||||
set_tests_properties(ListTags PROPERTIES PASS_REGULAR_EXPRESSION "[0-9]+ tags")
|
set_tests_properties(ListTags PROPERTIES PASS_REGULAR_EXPRESSION "[0-9]+ tags")
|
||||||
|
|
||||||
|
install(DIRECTORY "single_include/" DESTINATION "include/catch/")
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||

|

|
||||||
|
|
||||||
*v1.6.1*
|
*v1.7.0*
|
||||||
|
|
||||||
Build status (on Travis CI) [](https://travis-ci.org/philsquared/Catch)
|
Build status (on Travis CI) [](https://travis-ci.org/philsquared/Catch)
|
||||||
|
|
||||||
<a href="https://raw.githubusercontent.com/philsquared/Catch/master/single_include/catch.hpp">The latest, single header, version can be downloaded directly using this link</a>
|
<a href="https://github.com/philsquared/Catch/releases/download/v1.7.0/catch.hpp">The latest, single header, version can be downloaded directly using this link</a>
|
||||||
|
|
||||||
## What's the Catch?
|
## What's the Catch?
|
||||||
|
|
||||||
|
@@ -34,6 +34,15 @@ Example:
|
|||||||
REQUIRE_FALSE( thisReturnsFalse() );
|
REQUIRE_FALSE( thisReturnsFalse() );
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Do note that "overly complex" expressions cannot be decomposed and thus will not compile. This is done partly for practical reasons (to keep the underlying expression template machinery to minimum) and partly for philosophical reasons (assertions should be simple and deterministic).
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
* `CHECK(a == 1 && b == 2);`
|
||||||
|
This expression is too complex because of the `&&` operator. If you want to check that 2 or more properties hold, you can either put the expression into parenthesis, which stops decomposition from working, or you need to decompose the expression into two assertions: `CHECK( a == 1 ); CHECK( b == 2);`
|
||||||
|
* `CHECK( a == 2 || b == 1 );`
|
||||||
|
This expression is too complex because of the `||` operator. If you want to check that one of several properties hold, you can put the expression into parenthesis (unlike with `&&`, expression decomposition into several `CHECK`s is not possible).
|
||||||
|
|
||||||
|
|
||||||
### Floating point comparisons
|
### Floating point comparisons
|
||||||
|
|
||||||
When comparing floating point numbers - especially if at least one of them has been computed - great care must be taken to allow for rounding errors and inexact representations.
|
When comparing floating point numbers - especially if at least one of them has been computed - great care must be taken to allow for rounding errors and inexact representations.
|
||||||
|
@@ -69,7 +69,7 @@ ExternalProject_Add(
|
|||||||
|
|
||||||
# Expose required variable (CATCH_INCLUDE_DIR) to parent scope
|
# Expose required variable (CATCH_INCLUDE_DIR) to parent scope
|
||||||
ExternalProject_Get_Property(catch source_dir)
|
ExternalProject_Get_Property(catch source_dir)
|
||||||
set(CATCH_INCLUDE_DIR ${source_dir}/include CACHE INTERNAL "Path to include folder for Catch")
|
set(CATCH_INCLUDE_DIR ${source_dir}/single_include CACHE INTERNAL "Path to include folder for Catch")
|
||||||
```
|
```
|
||||||
|
|
||||||
If you put it in, e.g., `${PROJECT_SRC_DIR}/${EXT_PROJECTS_DIR}/catch/`, you can use it in your project by adding the following to your root CMake file:
|
If you put it in, e.g., `${PROJECT_SRC_DIR}/${EXT_PROJECTS_DIR}/catch/`, you can use it in your project by adding the following to your root CMake file:
|
||||||
|
@@ -17,6 +17,9 @@ Click one of the followings links to take you straight to that option - or scrol
|
|||||||
<a href="#warnings"> ` -w, --warn`</a><br />
|
<a href="#warnings"> ` -w, --warn`</a><br />
|
||||||
<a href="#reporting-timings"> ` -d, --durations`</a><br />
|
<a href="#reporting-timings"> ` -d, --durations`</a><br />
|
||||||
<a href="#input-file"> ` -f, --input-file`</a><br />
|
<a href="#input-file"> ` -f, --input-file`</a><br />
|
||||||
|
<a href="#run-section"> ` -c, --section`</a><br />
|
||||||
|
<a href="#filenames-as-tags"> ` -#, --filenames-as-tags`</a><br />
|
||||||
|
|
||||||
|
|
||||||
</br>
|
</br>
|
||||||
|
|
||||||
@@ -217,6 +220,59 @@ In either case the actual value for the seed is printed as part of Catch's outpu
|
|||||||
|
|
||||||
Prints the command line arguments to stdout
|
Prints the command line arguments to stdout
|
||||||
|
|
||||||
|
|
||||||
|
<a id="run-section"></a>
|
||||||
|
## Specify the section to run
|
||||||
|
<pre>-s, --section <section name></pre>
|
||||||
|
|
||||||
|
To limit execution to a specific section within a test case, use this option one or more times.
|
||||||
|
To narrow to sub-sections use multiple instances, where each subsequent instance specifies a deeper nesting level.
|
||||||
|
|
||||||
|
E.g. if you have:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
TEST_CASE( "Test" ) {
|
||||||
|
SECTION( "sa" ) {
|
||||||
|
SECTION( "sb" ) {
|
||||||
|
/*...*/
|
||||||
|
}
|
||||||
|
SECTION( "sc" ) {
|
||||||
|
/*...*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SECTION( "sd" ) {
|
||||||
|
/*...*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
Then you can run `sb` with:
|
||||||
|
<pre>./MyExe Test -c sa -c sb</pre>
|
||||||
|
|
||||||
|
Or run just `sd` with:
|
||||||
|
<pre>./MyExe Test -c sd</pre>
|
||||||
|
|
||||||
|
To run all of `sa`, including `sb` and `sc` use:
|
||||||
|
<pre>./MyExe Test -c sa</pre>
|
||||||
|
|
||||||
|
There are some limitations of this feature to be aware of:
|
||||||
|
- Code outside of sections being skipped will still be executed - e.g. any set-up code in the TEST_CASE before the
|
||||||
|
start of the first section.</br>
|
||||||
|
- At time of writing, wildcards are not supported in section names.
|
||||||
|
- If you specify a section without narrowing to a test case first then all test cases will be executed
|
||||||
|
(but only matching sections within them).
|
||||||
|
|
||||||
|
|
||||||
|
<a id="filenames-as-tags"></a>
|
||||||
|
## Filenames as tags
|
||||||
|
<pre>-#, --filenames-as-tags</pre>
|
||||||
|
|
||||||
|
When this option is used then every test is given an additional tag which is formed of the unqualified
|
||||||
|
filename it is found in, with any extension stripped, prefixed with the `#` character.
|
||||||
|
|
||||||
|
So, for example, tests within the file `~\Dev\MyProject\Ferrets.cpp` would be tagged `[#Ferrets]`.
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
[Home](Readme.md)
|
[Home](Readme.md)
|
||||||
|
@@ -62,6 +62,7 @@ This can be useful on certain platforms that do not provide ```std::cout``` and
|
|||||||
CATCH_CONFIG_CPP11_OVERRIDE // CATCH_OVERRIDE expands to override (for virtual function implementations)
|
CATCH_CONFIG_CPP11_OVERRIDE // CATCH_OVERRIDE expands to override (for virtual function implementations)
|
||||||
CATCH_CONFIG_CPP11_UNIQUE_PTR // Use std::unique_ptr instead of std::auto_ptr
|
CATCH_CONFIG_CPP11_UNIQUE_PTR // Use std::unique_ptr instead of std::auto_ptr
|
||||||
CATCH_CONFIG_CPP11_SHUFFLE // Use std::shuffle instead of std::random_shuffle
|
CATCH_CONFIG_CPP11_SHUFFLE // Use std::shuffle instead of std::random_shuffle
|
||||||
|
CATCH_CONFIG_CPP11_TYPE_TRAITS // Use std::enable_if and <type_traits>
|
||||||
|
|
||||||
Catch has some basic compiler detection that will attempt to select the appropriate mix of these macros. However being incomplete - and often without access to the respective compilers - this detection tends to be conservative.
|
Catch has some basic compiler detection that will attempt to select the appropriate mix of these macros. However being incomplete - and often without access to the respective compilers - this detection tends to be conservative.
|
||||||
So overriding control is given to the user. If a compiler supports a feature (and Catch does not already detect it) then one or more of these may be defined to enable it (or suppress it, in some cases). If you do do this please raise an issue, specifying your compiler version (ideally with an idea of how to detect it) and stating that it has such support.
|
So overriding control is given to the user. If a compiler supports a feature (and Catch does not already detect it) then one or more of these may be defined to enable it (or suppress it, in some cases). If you do do this please raise an issue, specifying your compiler version (ideally with an idea of how to detect it) and stating that it has such support.
|
||||||
|
@@ -24,7 +24,7 @@ int main( int argc, char* argv[] )
|
|||||||
|
|
||||||
// global clean-up...
|
// global clean-up...
|
||||||
|
|
||||||
return result;
|
return ( result < 0xff ? result : 0xff );
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -51,7 +51,11 @@ int main( int argc, char* argv[] )
|
|||||||
// overrides command line args
|
// overrides command line args
|
||||||
// only do this if you know you need to
|
// only do this if you know you need to
|
||||||
|
|
||||||
return session.run();
|
int numFailed = session.run();
|
||||||
|
// Note that on unices only the lower 8 bits are usually used, clamping
|
||||||
|
// the return value to 255 prevents false negative when some multiple
|
||||||
|
// of 256 tests has failed
|
||||||
|
return ( numFailed < 0xff ? numFailed : 0xff );
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@@ -1,4 +1,37 @@
|
|||||||
# 1.6.1
|
# 1.7.0
|
||||||
|
|
||||||
|
### Features/ Changes:
|
||||||
|
* Catch now runs significantly faster for passing tests
|
||||||
|
* Microbenchmark focused on Catch's overhead went from ~3.4s to ~0.7s.
|
||||||
|
* Real world test using [JSON for Modern C++](https://github.com/nlohmann/json)'s test suite went from ~6m 25s to ~4m 14s.
|
||||||
|
* Catch can now run specific sections within test cases.
|
||||||
|
* For now the support is only basic (no wildcards or tags), for details see the [documentation](docs/command-line.md).
|
||||||
|
* Catch now supports SEH on Windows as well as signals on Linux.
|
||||||
|
* After receiving a signal, Catch reports failing assertion and then passes the signal onto the previous handler.
|
||||||
|
* Approx can be used to compare values against strong typedefs (available in C++11 mode only).
|
||||||
|
* Strong typedefs mean types that are explicitly convertible to double.
|
||||||
|
* CHECK macro no longer stops executing section if an exception happens.
|
||||||
|
* Certain characters (space, tab, etc) are now pretty printed.
|
||||||
|
* This means that a `char c = ' '; REQUIRE(c == '\t');` would be printed as `' ' == '\t'`, instead of ` == 9`.
|
||||||
|
|
||||||
|
### Fixes:
|
||||||
|
* Text formatting no longer attempts to access out-of-bounds characters under certain conditions.
|
||||||
|
* THROW family of assertions no longer trigger `-Wunused-value` on expressions containing explicit cast.
|
||||||
|
* Breaking into debugger under OS X works again and no longer required `DEBUG` to be defined.
|
||||||
|
* Compilation no longer breaks under certain compiler if a lambda is used inside assertion macro.
|
||||||
|
|
||||||
|
### Other:
|
||||||
|
* Catch's CMakeLists now defines install command.
|
||||||
|
* Catch's CMakeLists now generates projects with warnings enabled.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 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:
|
### Features/ Changes:
|
||||||
* Catch now supports breaking into debugger on Linux
|
* Catch now supports breaking into debugger on Linux
|
||||||
@@ -18,10 +51,6 @@
|
|||||||
* This can be disabled if needed, see [documentation](docs/configuration.md) for details.
|
* This can be disabled if needed, see [documentation](docs/configuration.md) for details.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 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.0
|
## 1.6.0
|
||||||
|
|
||||||
### Cmake/ projects:
|
### Cmake/ projects:
|
||||||
|
@@ -42,6 +42,8 @@ All tag names beginning with non-alphanumeric characters are reserved by Catch.
|
|||||||
|
|
||||||
* `[!mayfail]` - doesn't fail the test if any given assertion fails (but still reports it). This can be useful to flag a work-in-progress, or a known issue that you don't want to immediately fix but still want to track in the your tests.
|
* `[!mayfail]` - doesn't fail the test if any given assertion fails (but still reports it). This can be useful to flag a work-in-progress, or a known issue that you don't want to immediately fix but still want to track in the your tests.
|
||||||
|
|
||||||
|
* `[!nonportable]` - Indicates that behaviour may vary between platforms or compilers.
|
||||||
|
|
||||||
* `[#<filename>]` - running with `-#` or `--filenames-as-tags` causes Catch to add the filename, prefixed with `#` (and with any extension stripped) as a tag. e.g. tests in testfile.cpp would all be tagged `[#testfile]`.
|
* `[#<filename>]` - running with `-#` or `--filenames-as-tags` causes Catch to add the filename, prefixed with `#` (and with any extension stripped) as a tag. e.g. tests in testfile.cpp would all be tagged `[#testfile]`.
|
||||||
|
|
||||||
* `[@<alias>]` - tag aliases all begin with `@` (see below).
|
* `[@<alias>]` - tag aliases all begin with `@` (see below).
|
||||||
|
111
include/external/tbc_text_format.h
vendored
111
include/external/tbc_text_format.h
vendored
@@ -37,19 +37,16 @@ namespace Tbc {
|
|||||||
TextAttributes()
|
TextAttributes()
|
||||||
: initialIndent( std::string::npos ),
|
: initialIndent( std::string::npos ),
|
||||||
indent( 0 ),
|
indent( 0 ),
|
||||||
width( consoleWidth-1 ),
|
width( consoleWidth-1 )
|
||||||
tabChar( '\t' )
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
|
TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
|
||||||
TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
|
TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
|
||||||
TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
|
TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
|
||||||
TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
|
|
||||||
|
|
||||||
std::size_t initialIndent; // indent of first line, or npos
|
std::size_t initialIndent; // indent of first line, or npos
|
||||||
std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
|
std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
|
||||||
std::size_t width; // maximum width of text, including indent. Longer text will wrap
|
std::size_t width; // maximum width of text, including indent. Longer text will wrap
|
||||||
char tabChar; // If this char is seen the indent is changed to current pos
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Text {
|
class Text {
|
||||||
@@ -57,63 +54,80 @@ namespace Tbc {
|
|||||||
Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
|
Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
|
||||||
: attr( _attr )
|
: attr( _attr )
|
||||||
{
|
{
|
||||||
std::string wrappableChars = " [({.,/|\\-";
|
const std::string wrappableBeforeChars = "[({<\t";
|
||||||
std::size_t indent = _attr.initialIndent != std::string::npos
|
const std::string wrappableAfterChars = "])}>-,./|\\";
|
||||||
? _attr.initialIndent
|
const std::string wrappableInsteadOfChars = " \n\r";
|
||||||
: _attr.indent;
|
std::string indent = _attr.initialIndent != std::string::npos
|
||||||
std::string remainder = _str;
|
? std::string( _attr.initialIndent, ' ' )
|
||||||
|
: std::string( _attr.indent, ' ' );
|
||||||
|
|
||||||
|
typedef std::string::const_iterator iterator;
|
||||||
|
iterator it = _str.begin();
|
||||||
|
const iterator strEnd = _str.end();
|
||||||
|
|
||||||
|
while( it != strEnd ) {
|
||||||
|
|
||||||
while( !remainder.empty() ) {
|
|
||||||
if( lines.size() >= 1000 ) {
|
if( lines.size() >= 1000 ) {
|
||||||
lines.push_back( "... message truncated due to excessive size" );
|
lines.push_back( "... message truncated due to excessive size" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::size_t tabPos = std::string::npos;
|
|
||||||
std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
|
|
||||||
std::size_t pos = remainder.find_first_of( '\n' );
|
|
||||||
if( pos <= width ) {
|
|
||||||
width = pos;
|
|
||||||
}
|
|
||||||
pos = remainder.find_last_of( _attr.tabChar, width );
|
|
||||||
if( pos != std::string::npos ) {
|
|
||||||
tabPos = pos;
|
|
||||||
if( remainder[width] == '\n' )
|
|
||||||
width--;
|
|
||||||
remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( width == remainder.size() ) {
|
|
||||||
spliceLine( indent, remainder, width );
|
std::string suffix;
|
||||||
}
|
std::size_t width = (std::min)( static_cast<size_t>( strEnd-it ), _attr.width-static_cast<size_t>( indent.size() ) );
|
||||||
else if( remainder[width] == '\n' ) {
|
iterator itEnd = it+width;
|
||||||
spliceLine( indent, remainder, width );
|
iterator itNext = _str.end();
|
||||||
if( width <= 1 || remainder.size() != 1 )
|
|
||||||
remainder = remainder.substr( 1 );
|
iterator itNewLine = std::find( it, itEnd, '\n' );
|
||||||
indent = _attr.indent;
|
if( itNewLine != itEnd )
|
||||||
}
|
itEnd = itNewLine;
|
||||||
else {
|
|
||||||
pos = remainder.find_last_of( wrappableChars, width );
|
if( itEnd != strEnd ) {
|
||||||
if( pos != std::string::npos && pos > 0 ) {
|
bool foundWrapPoint = false;
|
||||||
spliceLine( indent, remainder, pos );
|
iterator findIt = itEnd;
|
||||||
if( remainder[0] == ' ' )
|
do {
|
||||||
remainder = remainder.substr( 1 );
|
if( wrappableAfterChars.find( *findIt ) != std::string::npos && findIt != itEnd ) {
|
||||||
|
itEnd = findIt+1;
|
||||||
|
itNext = findIt+1;
|
||||||
|
foundWrapPoint = true;
|
||||||
|
}
|
||||||
|
else if( findIt > it && wrappableBeforeChars.find( *findIt ) != std::string::npos ) {
|
||||||
|
itEnd = findIt;
|
||||||
|
itNext = findIt;
|
||||||
|
foundWrapPoint = true;
|
||||||
|
}
|
||||||
|
else if( wrappableInsteadOfChars.find( *findIt ) != std::string::npos ) {
|
||||||
|
itNext = findIt+1;
|
||||||
|
itEnd = findIt;
|
||||||
|
foundWrapPoint = true;
|
||||||
|
}
|
||||||
|
if( findIt == it )
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
--findIt;
|
||||||
|
}
|
||||||
|
while( !foundWrapPoint );
|
||||||
|
|
||||||
|
if( !foundWrapPoint ) {
|
||||||
|
// No good wrap char, so we'll break mid word and add a hyphen
|
||||||
|
--itEnd;
|
||||||
|
itNext = itEnd;
|
||||||
|
suffix = "-";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
spliceLine( indent, remainder, width-1 );
|
while( itEnd > it && wrappableInsteadOfChars.find( *(itEnd-1) ) != std::string::npos )
|
||||||
lines.back() += "-";
|
--itEnd;
|
||||||
}
|
}
|
||||||
if( lines.size() == 1 )
|
|
||||||
indent = _attr.indent;
|
|
||||||
if( tabPos != std::string::npos )
|
|
||||||
indent += tabPos;
|
|
||||||
}
|
}
|
||||||
|
lines.push_back( indent + std::string( it, itEnd ) + suffix );
|
||||||
|
|
||||||
|
if( indent.size() != _attr.indent )
|
||||||
|
indent = std::string( _attr.indent, ' ' );
|
||||||
|
it = itNext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
|
|
||||||
lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
|
|
||||||
_remainder = _remainder.substr( _pos );
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef std::vector<std::string>::const_iterator const_iterator;
|
typedef std::vector<std::string>::const_iterator const_iterator;
|
||||||
|
|
||||||
@@ -138,6 +152,7 @@ namespace Tbc {
|
|||||||
return _stream;
|
return _stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string str;
|
std::string str;
|
||||||
TextAttributes attr;
|
TextAttributes attr;
|
||||||
|
@@ -13,6 +13,10 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
|
||||||
|
#include <type_traits>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
namespace Detail {
|
namespace Detail {
|
||||||
|
|
||||||
@@ -41,6 +45,53 @@ namespace Detail {
|
|||||||
return approx;
|
return approx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
|
||||||
|
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||||
|
friend bool operator == ( const T& lhs, Approx const& rhs ) {
|
||||||
|
// Thanks to Richard Harris for his help refining this formula
|
||||||
|
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) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||||
|
friend bool operator == ( Approx const& lhs, const T& rhs ) {
|
||||||
|
return operator==( rhs, lhs );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||||
|
friend bool operator != ( T lhs, Approx const& rhs ) {
|
||||||
|
return !operator==( lhs, rhs );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||||
|
friend bool operator != ( Approx const& lhs, T rhs ) {
|
||||||
|
return !operator==( rhs, lhs );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||||
|
friend bool operator <= ( T lhs, Approx const& rhs )
|
||||||
|
{
|
||||||
|
return double(lhs) < rhs.m_value || lhs == rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||||
|
friend bool operator <= ( Approx const& lhs, T rhs )
|
||||||
|
{
|
||||||
|
return lhs.m_value < double(rhs) || lhs == rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||||
|
friend bool operator >= ( T lhs, Approx const& rhs )
|
||||||
|
{
|
||||||
|
return double(lhs) > rhs.m_value || lhs == rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||||
|
friend bool operator >= ( Approx const& lhs, T rhs )
|
||||||
|
{
|
||||||
|
return lhs.m_value > double(rhs) || lhs == rhs;
|
||||||
|
}
|
||||||
|
#else
|
||||||
friend bool operator == ( double lhs, Approx const& rhs ) {
|
friend bool operator == ( double lhs, Approx const& rhs ) {
|
||||||
// Thanks to Richard Harris for his help refining this formula
|
// 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 fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
|
||||||
@@ -77,6 +128,7 @@ namespace Detail {
|
|||||||
{
|
{
|
||||||
return lhs.m_value > rhs || lhs == rhs;
|
return lhs.m_value > rhs || lhs == rhs;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Approx& epsilon( double newEpsilon ) {
|
Approx& epsilon( double newEpsilon ) {
|
||||||
m_epsilon = newEpsilon;
|
m_epsilon = newEpsilon;
|
||||||
|
@@ -13,6 +13,27 @@
|
|||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
|
struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
|
||||||
|
|
||||||
|
struct DecomposedExpression
|
||||||
|
{
|
||||||
|
virtual ~DecomposedExpression() {}
|
||||||
|
virtual bool isBinaryExpression() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
virtual void reconstructExpression( std::string& dest ) const = 0;
|
||||||
|
|
||||||
|
// Only simple binary comparisons can be decomposed.
|
||||||
|
// If more complex check is required then wrap sub-expressions in parentheses.
|
||||||
|
template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( T const& );
|
||||||
|
template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( T const& );
|
||||||
|
template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( T const& );
|
||||||
|
template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( T const& );
|
||||||
|
template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator % ( T const& );
|
||||||
|
template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( T const& );
|
||||||
|
template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( T const& );
|
||||||
|
};
|
||||||
|
|
||||||
struct AssertionInfo
|
struct AssertionInfo
|
||||||
{
|
{
|
||||||
AssertionInfo() {}
|
AssertionInfo() {}
|
||||||
@@ -29,11 +50,41 @@ namespace Catch {
|
|||||||
|
|
||||||
struct AssertionResultData
|
struct AssertionResultData
|
||||||
{
|
{
|
||||||
AssertionResultData() : resultType( ResultWas::Unknown ) {}
|
AssertionResultData() : decomposedExpression( CATCH_NULL )
|
||||||
|
, resultType( ResultWas::Unknown )
|
||||||
|
, negated( false )
|
||||||
|
, parenthesized( false ) {}
|
||||||
|
|
||||||
std::string reconstructedExpression;
|
void negate( bool parenthesize ) {
|
||||||
|
negated = !negated;
|
||||||
|
parenthesized = parenthesize;
|
||||||
|
if( resultType == ResultWas::Ok )
|
||||||
|
resultType = ResultWas::ExpressionFailed;
|
||||||
|
else if( resultType == ResultWas::ExpressionFailed )
|
||||||
|
resultType = ResultWas::Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string const& reconstructExpression() const {
|
||||||
|
if( decomposedExpression != CATCH_NULL ) {
|
||||||
|
decomposedExpression->reconstructExpression( reconstructedExpression );
|
||||||
|
if( parenthesized ) {
|
||||||
|
reconstructedExpression.insert( 0, 1, '(' );
|
||||||
|
reconstructedExpression.append( 1, ')' );
|
||||||
|
}
|
||||||
|
if( negated ) {
|
||||||
|
reconstructedExpression.insert( 0, 1, '!' );
|
||||||
|
}
|
||||||
|
decomposedExpression = CATCH_NULL;
|
||||||
|
}
|
||||||
|
return reconstructedExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutable DecomposedExpression const* decomposedExpression;
|
||||||
|
mutable std::string reconstructedExpression;
|
||||||
std::string message;
|
std::string message;
|
||||||
ResultWas::OfType resultType;
|
ResultWas::OfType resultType;
|
||||||
|
bool negated;
|
||||||
|
bool parenthesized;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AssertionResult {
|
class AssertionResult {
|
||||||
@@ -60,6 +111,8 @@ namespace Catch {
|
|||||||
std::string getMessage() const;
|
std::string getMessage() const;
|
||||||
SourceLineInfo getSourceInfo() const;
|
SourceLineInfo getSourceInfo() const;
|
||||||
std::string getTestMacroName() const;
|
std::string getTestMacroName() const;
|
||||||
|
void discardDecomposedExpression() const;
|
||||||
|
void expandDecomposedExpression() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AssertionInfo m_info;
|
AssertionInfo m_info;
|
||||||
|
@@ -56,7 +56,7 @@ namespace Catch {
|
|||||||
|
|
||||||
std::string AssertionResult::getExpression() const {
|
std::string AssertionResult::getExpression() const {
|
||||||
if( isFalseTest( m_info.resultDisposition ) )
|
if( isFalseTest( m_info.resultDisposition ) )
|
||||||
return "!" + m_info.capturedExpression;
|
return '!' + m_info.capturedExpression;
|
||||||
else
|
else
|
||||||
return m_info.capturedExpression;
|
return m_info.capturedExpression;
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string AssertionResult::getExpandedExpression() const {
|
std::string AssertionResult::getExpandedExpression() const {
|
||||||
return m_resultData.reconstructedExpression;
|
return m_resultData.reconstructExpression();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AssertionResult::getMessage() const {
|
std::string AssertionResult::getMessage() const {
|
||||||
@@ -86,6 +86,14 @@ namespace Catch {
|
|||||||
return m_info.macroName;
|
return m_info.macroName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssertionResult::discardDecomposedExpression() const {
|
||||||
|
m_resultData.decomposedExpression = CATCH_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssertionResult::expandDecomposedExpression() const {
|
||||||
|
m_resultData.reconstructExpression();
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED
|
||||||
|
@@ -37,10 +37,11 @@
|
|||||||
( __catchResult <= expr ).endExpression(); \
|
( __catchResult <= expr ).endExpression(); \
|
||||||
} \
|
} \
|
||||||
catch( ... ) { \
|
catch( ... ) { \
|
||||||
__catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
|
__catchResult.useActiveException( resultDisposition ); \
|
||||||
} \
|
} \
|
||||||
INTERNAL_CATCH_REACT( __catchResult ) \
|
INTERNAL_CATCH_REACT( __catchResult ) \
|
||||||
} while( Catch::alwaysFalse( sizeof(expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
|
} while( Catch::isTrue( false && static_cast<bool>( !!(expr) ) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
|
||||||
|
// The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
|
#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
|
||||||
@@ -57,7 +58,7 @@
|
|||||||
do { \
|
do { \
|
||||||
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
|
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
|
||||||
try { \
|
try { \
|
||||||
expr; \
|
static_cast<void>(expr); \
|
||||||
__catchResult.captureResult( Catch::ResultWas::Ok ); \
|
__catchResult.captureResult( Catch::ResultWas::Ok ); \
|
||||||
} \
|
} \
|
||||||
catch( ... ) { \
|
catch( ... ) { \
|
||||||
@@ -72,7 +73,7 @@
|
|||||||
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \
|
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \
|
||||||
if( __catchResult.allowThrows() ) \
|
if( __catchResult.allowThrows() ) \
|
||||||
try { \
|
try { \
|
||||||
expr; \
|
static_cast<void>(expr); \
|
||||||
__catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
|
__catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
|
||||||
} \
|
} \
|
||||||
catch( ... ) { \
|
catch( ... ) { \
|
||||||
@@ -89,7 +90,7 @@
|
|||||||
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
|
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
|
||||||
if( __catchResult.allowThrows() ) \
|
if( __catchResult.allowThrows() ) \
|
||||||
try { \
|
try { \
|
||||||
expr; \
|
static_cast<void>(expr); \
|
||||||
__catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
|
__catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
|
||||||
} \
|
} \
|
||||||
catch( exceptionType ) { \
|
catch( exceptionType ) { \
|
||||||
@@ -132,13 +133,7 @@
|
|||||||
do { \
|
do { \
|
||||||
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \
|
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \
|
||||||
try { \
|
try { \
|
||||||
std::string matcherAsString = (matcher).toString(); \
|
__catchResult.captureMatch( arg, matcher, #matcher ); \
|
||||||
__catchResult \
|
|
||||||
.setLhs( Catch::toString( arg ) ) \
|
|
||||||
.setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
|
|
||||||
.setOp( "matches" ) \
|
|
||||||
.setResultType( (matcher).match( arg ) ); \
|
|
||||||
__catchResult.captureExpression(); \
|
|
||||||
} catch( ... ) { \
|
} catch( ... ) { \
|
||||||
__catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
|
__catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
|
||||||
} \
|
} \
|
||||||
|
@@ -23,13 +23,14 @@ namespace Catch {
|
|||||||
config.abortAfter = x;
|
config.abortAfter = x;
|
||||||
}
|
}
|
||||||
inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
|
inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
|
||||||
|
inline void addSectionToRun( ConfigData& config, std::string const& sectionName ) { config.sectionsToRun.push_back( sectionName ); }
|
||||||
inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); }
|
inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); }
|
||||||
|
|
||||||
inline void addWarning( ConfigData& config, std::string const& _warning ) {
|
inline void addWarning( ConfigData& config, std::string const& _warning ) {
|
||||||
if( _warning == "NoAssertions" )
|
if( _warning == "NoAssertions" )
|
||||||
config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
|
config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
|
||||||
else
|
else
|
||||||
throw std::runtime_error( "Unrecognised warning: '" + _warning + "'" );
|
throw std::runtime_error( "Unrecognised warning: '" + _warning + '\'' );
|
||||||
}
|
}
|
||||||
inline void setOrder( ConfigData& config, std::string const& order ) {
|
inline void setOrder( ConfigData& config, std::string const& order ) {
|
||||||
if( startsWith( "declared", order ) )
|
if( startsWith( "declared", order ) )
|
||||||
@@ -39,7 +40,7 @@ namespace Catch {
|
|||||||
else if( startsWith( "random", order ) )
|
else if( startsWith( "random", order ) )
|
||||||
config.runOrder = RunTests::InRandomOrder;
|
config.runOrder = RunTests::InRandomOrder;
|
||||||
else
|
else
|
||||||
throw std::runtime_error( "Unrecognised ordering: '" + order + "'" );
|
throw std::runtime_error( "Unrecognised ordering: '" + order + '\'' );
|
||||||
}
|
}
|
||||||
inline void setRngSeed( ConfigData& config, std::string const& seed ) {
|
inline void setRngSeed( ConfigData& config, std::string const& seed ) {
|
||||||
if( seed == "time" ) {
|
if( seed == "time" ) {
|
||||||
@@ -64,7 +65,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
inline void setUseColour( ConfigData& config, std::string const& value ) {
|
inline void setUseColour( ConfigData& config, std::string const& value ) {
|
||||||
std::string mode = toLower( value );
|
std::string mode = toLower( value );
|
||||||
|
|
||||||
if( mode == "yes" )
|
if( mode == "yes" )
|
||||||
config.useColour = UseColour::Yes;
|
config.useColour = UseColour::Yes;
|
||||||
else if( mode == "no" )
|
else if( mode == "no" )
|
||||||
@@ -85,10 +86,10 @@ namespace Catch {
|
|||||||
std::string line;
|
std::string line;
|
||||||
while( std::getline( f, line ) ) {
|
while( std::getline( f, line ) ) {
|
||||||
line = trim(line);
|
line = trim(line);
|
||||||
if( !line.empty() && !startsWith( line, "#" ) ) {
|
if( !line.empty() && !startsWith( line, '#' ) ) {
|
||||||
if( !startsWith( line, "\"" ) )
|
if( !startsWith( line, '"' ) )
|
||||||
line = "\"" + line + "\"";
|
line = '"' + line + '"';
|
||||||
addTestOrTags( config, line + "," );
|
addTestOrTags( config, line + ',' );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -176,6 +177,10 @@ namespace Catch {
|
|||||||
.describe( "adds a tag for the filename" )
|
.describe( "adds a tag for the filename" )
|
||||||
.bind( &ConfigData::filenamesAsTags );
|
.bind( &ConfigData::filenamesAsTags );
|
||||||
|
|
||||||
|
cli["-c"]["--section"]
|
||||||
|
.describe( "specify section to run" )
|
||||||
|
.bind( &addSectionToRun, "section name" );
|
||||||
|
|
||||||
// Less common commands which don't have a short form
|
// Less common commands which don't have a short form
|
||||||
cli["--list-test-names-only"]
|
cli["--list-test-names-only"]
|
||||||
.describe( "list all/matching test cases names only" )
|
.describe( "list all/matching test cases names only" )
|
||||||
@@ -196,7 +201,7 @@ namespace Catch {
|
|||||||
cli["--force-colour"]
|
cli["--force-colour"]
|
||||||
.describe( "force colourised output (deprecated)" )
|
.describe( "force colourised output (deprecated)" )
|
||||||
.bind( &forceColour );
|
.bind( &forceColour );
|
||||||
|
|
||||||
cli["--use-colour"]
|
cli["--use-colour"]
|
||||||
.describe( "should output be colourised" )
|
.describe( "should output be colourised" )
|
||||||
.bind( &setUseColour, "yes|no" );
|
.bind( &setUseColour, "yes|no" );
|
||||||
|
@@ -79,7 +79,10 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool startsWith( std::string const& s, std::string const& prefix );
|
bool startsWith( std::string const& s, std::string const& prefix );
|
||||||
|
bool startsWith( std::string const& s, char prefix );
|
||||||
bool endsWith( std::string const& s, std::string const& suffix );
|
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 );
|
bool contains( std::string const& s, std::string const& infix );
|
||||||
void toLowerInPlace( std::string& s );
|
void toLowerInPlace( std::string& s );
|
||||||
std::string toLower( std::string const& s );
|
std::string toLower( std::string const& s );
|
||||||
@@ -99,8 +102,8 @@ namespace Catch {
|
|||||||
|
|
||||||
SourceLineInfo();
|
SourceLineInfo();
|
||||||
SourceLineInfo( char const* _file, std::size_t _line );
|
SourceLineInfo( char const* _file, std::size_t _line );
|
||||||
SourceLineInfo( SourceLineInfo const& other );
|
|
||||||
# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
|
# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
|
||||||
|
SourceLineInfo(SourceLineInfo const& other) = default;
|
||||||
SourceLineInfo( SourceLineInfo && ) = default;
|
SourceLineInfo( SourceLineInfo && ) = default;
|
||||||
SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
|
SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
|
||||||
SourceLineInfo& operator = ( SourceLineInfo && ) = default;
|
SourceLineInfo& operator = ( SourceLineInfo && ) = default;
|
||||||
@@ -109,15 +112,16 @@ namespace Catch {
|
|||||||
bool operator == ( SourceLineInfo const& other ) const;
|
bool operator == ( SourceLineInfo const& other ) const;
|
||||||
bool operator < ( SourceLineInfo const& other ) const;
|
bool operator < ( SourceLineInfo const& other ) const;
|
||||||
|
|
||||||
std::string file;
|
char const* file;
|
||||||
std::size_t line;
|
std::size_t line;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
|
std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
|
||||||
|
|
||||||
// This is just here to avoid compiler warnings with macro constants and boolean literals
|
// This is just here to avoid compiler warnings with macro constants and boolean literals
|
||||||
inline bool alwaysTrue( std::size_t = 0 ) { return true; }
|
inline bool isTrue( bool value ){ return value; }
|
||||||
inline bool alwaysFalse( std::size_t = 0 ) { return false; }
|
inline bool alwaysTrue() { return true; }
|
||||||
|
inline bool alwaysFalse() { return false; }
|
||||||
|
|
||||||
void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
|
void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
|
||||||
|
|
||||||
|
@@ -10,17 +10,28 @@
|
|||||||
|
|
||||||
#include "catch_common.h"
|
#include "catch_common.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
bool startsWith( std::string const& s, std::string const& prefix ) {
|
bool startsWith( std::string const& s, std::string const& prefix ) {
|
||||||
return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
|
return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
|
||||||
|
}
|
||||||
|
bool startsWith( std::string const& s, char prefix ) {
|
||||||
|
return !s.empty() && s[0] == prefix;
|
||||||
}
|
}
|
||||||
bool endsWith( std::string const& s, std::string const& suffix ) {
|
bool endsWith( std::string const& s, std::string const& suffix ) {
|
||||||
return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
|
return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
|
||||||
|
}
|
||||||
|
bool endsWith( std::string const& s, char suffix ) {
|
||||||
|
return !s.empty() && s[s.size()-1] == suffix;
|
||||||
}
|
}
|
||||||
bool contains( std::string const& s, std::string const& infix ) {
|
bool contains( std::string const& s, std::string const& infix ) {
|
||||||
return s.find( infix ) != std::string::npos;
|
return s.find( infix ) != std::string::npos;
|
||||||
}
|
}
|
||||||
|
bool contains( std::string const& s, char infix ) {
|
||||||
|
return s.find(infix) != std::string::npos;
|
||||||
|
}
|
||||||
char toLowerCh(char c) {
|
char toLowerCh(char c) {
|
||||||
return static_cast<char>( ::tolower( c ) );
|
return static_cast<char>( ::tolower( c ) );
|
||||||
}
|
}
|
||||||
@@ -37,7 +48,7 @@ namespace Catch {
|
|||||||
std::string::size_type start = str.find_first_not_of( whitespaceChars );
|
std::string::size_type start = str.find_first_not_of( whitespaceChars );
|
||||||
std::string::size_type end = str.find_last_not_of( whitespaceChars );
|
std::string::size_type end = str.find_last_not_of( whitespaceChars );
|
||||||
|
|
||||||
return start != std::string::npos ? str.substr( start, 1+end-start ) : "";
|
return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
|
bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
|
||||||
@@ -60,29 +71,25 @@ namespace Catch {
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
|
std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
|
||||||
os << pluraliser.m_count << " " << pluraliser.m_label;
|
os << pluraliser.m_count << ' ' << pluraliser.m_label;
|
||||||
if( pluraliser.m_count != 1 )
|
if( pluraliser.m_count != 1 )
|
||||||
os << "s";
|
os << 's';
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceLineInfo::SourceLineInfo() : line( 0 ){}
|
SourceLineInfo::SourceLineInfo() : file(""), line( 0 ){}
|
||||||
SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
|
SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
|
||||||
: file( _file ),
|
: file( _file ),
|
||||||
line( _line )
|
line( _line )
|
||||||
{}
|
{}
|
||||||
SourceLineInfo::SourceLineInfo( SourceLineInfo const& other )
|
|
||||||
: file( other.file ),
|
|
||||||
line( other.line )
|
|
||||||
{}
|
|
||||||
bool SourceLineInfo::empty() const {
|
bool SourceLineInfo::empty() const {
|
||||||
return file.empty();
|
return file[0] == '\0';
|
||||||
}
|
}
|
||||||
bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
|
bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
|
||||||
return line == other.line && file == other.file;
|
return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
|
||||||
}
|
}
|
||||||
bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {
|
bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {
|
||||||
return line < other.line || ( line == other.line && file < other.file );
|
return line < other.line || ( line == other.line && (std::strcmp(file, other.file) < 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void seedRng( IConfig const& config ) {
|
void seedRng( IConfig const& config ) {
|
||||||
@@ -95,16 +102,16 @@ namespace Catch {
|
|||||||
|
|
||||||
std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
|
std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
|
||||||
#ifndef __GNUG__
|
#ifndef __GNUG__
|
||||||
os << info.file << "(" << info.line << ")";
|
os << info.file << '(' << info.line << ')';
|
||||||
#else
|
#else
|
||||||
os << info.file << ":" << info.line;
|
os << info.file << ':' << info.line;
|
||||||
#endif
|
#endif
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
|
void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << locationInfo << ": Internal Catch error: '" << message << "'";
|
oss << locationInfo << ": Internal Catch error: '" << message << '\'';
|
||||||
if( alwaysTrue() )
|
if( alwaysTrue() )
|
||||||
throw std::logic_error( oss.str() );
|
throw std::logic_error( oss.str() );
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,8 @@
|
|||||||
// CATCH_CONFIG_CPP11_LONG_LONG : is long long supported?
|
// CATCH_CONFIG_CPP11_LONG_LONG : is long long supported?
|
||||||
// CATCH_CONFIG_CPP11_OVERRIDE : is override supported?
|
// CATCH_CONFIG_CPP11_OVERRIDE : is override supported?
|
||||||
// CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
|
// CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
|
||||||
|
// CATCH_CONFIG_CPP11_SHUFFLE : is std::shuffle supported?
|
||||||
|
// CATCH_CONFIG_CPP11_TYPE_TRAITS : are type_traits and enable_if supported?
|
||||||
|
|
||||||
// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
|
// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
|
||||||
|
|
||||||
@@ -116,6 +118,7 @@
|
|||||||
#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
|
#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
|
||||||
#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
|
#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
|
||||||
#define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE
|
#define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE
|
||||||
|
#define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
@@ -184,6 +187,9 @@
|
|||||||
# if !defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE)
|
# if !defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE)
|
||||||
# define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE
|
# define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE
|
||||||
# endif
|
# endif
|
||||||
|
# if !defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS)
|
||||||
|
# define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS
|
||||||
|
# endif
|
||||||
|
|
||||||
#endif // __cplusplus >= 201103L
|
#endif // __cplusplus >= 201103L
|
||||||
|
|
||||||
@@ -224,6 +230,9 @@
|
|||||||
#if defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_NO_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_NO_CPP11)
|
#if defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_NO_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_NO_CPP11)
|
||||||
# define CATCH_CONFIG_CPP11_SHUFFLE
|
# define CATCH_CONFIG_CPP11_SHUFFLE
|
||||||
#endif
|
#endif
|
||||||
|
# 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_SUPPRESS_PARENTHESES_WARNINGS)
|
#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
|
||||||
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
|
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
|
||||||
|
@@ -74,6 +74,7 @@ namespace Catch {
|
|||||||
|
|
||||||
std::vector<std::string> reporterNames;
|
std::vector<std::string> reporterNames;
|
||||||
std::vector<std::string> testsOrTags;
|
std::vector<std::string> testsOrTags;
|
||||||
|
std::vector<std::string> sectionsToRun;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -115,7 +116,8 @@ namespace Catch {
|
|||||||
|
|
||||||
bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
|
bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
|
||||||
|
|
||||||
std::vector<std::string> getReporterNames() const { return m_data.reporterNames; }
|
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; }
|
int abortAfter() const { return m_data.abortAfter; }
|
||||||
|
|
||||||
|
@@ -23,14 +23,12 @@ namespace Catch{
|
|||||||
|
|
||||||
// The following code snippet based on:
|
// The following code snippet based on:
|
||||||
// http://cocoawithlove.com/2008/03/break-into-debugger.html
|
// http://cocoawithlove.com/2008/03/break-into-debugger.html
|
||||||
#ifdef DEBUG
|
#if defined(__ppc64__) || defined(__ppc__)
|
||||||
#if defined(__ppc64__) || defined(__ppc__)
|
#define CATCH_TRAP() \
|
||||||
#define CATCH_TRAP() \
|
__asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
|
||||||
__asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
|
: : : "memory","r0","r3","r4" )
|
||||||
: : : "memory","r0","r3","r4" )
|
#else
|
||||||
#else
|
#define CATCH_TRAP() __asm__("int $3\n" : : )
|
||||||
#define CATCH_TRAP() _asm__("int $3\n" : : )
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#elif defined(CATCH_PLATFORM_LINUX)
|
#elif defined(CATCH_PLATFORM_LINUX)
|
||||||
|
@@ -12,7 +12,8 @@
|
|||||||
|
|
||||||
// Standard C/C++ main entry point
|
// Standard C/C++ main entry point
|
||||||
int main (int argc, char * argv[]) {
|
int main (int argc, char * argv[]) {
|
||||||
return Catch::Session().run( argc, argv );
|
int result = Catch::Session().run( argc, argv );
|
||||||
|
return ( result < 0xff ? result : 0xff );
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // __OBJC__
|
#else // __OBJC__
|
||||||
@@ -30,7 +31,7 @@ int main (int argc, char * const argv[]) {
|
|||||||
[pool drain];
|
[pool drain];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return result;
|
return ( result < 0xff ? result : 0xff );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __OBJC__
|
#endif // __OBJC__
|
||||||
|
@@ -14,90 +14,155 @@
|
|||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
// Wraps the LHS of an expression and captures the operator and RHS (if any) -
|
template<typename LhsT, Internal::Operator Op, typename RhsT>
|
||||||
// wrapping them all in a ResultBuilder object
|
class BinaryExpression;
|
||||||
template<typename T>
|
|
||||||
class ExpressionLhs {
|
|
||||||
ExpressionLhs& operator = ( ExpressionLhs const& );
|
|
||||||
# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
|
|
||||||
ExpressionLhs& operator = ( ExpressionLhs && ) = delete;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
|
template<typename ArgT, typename MatcherT>
|
||||||
|
class MatchExpression;
|
||||||
|
|
||||||
|
// Wraps the LHS of an expression and overloads comparison operators
|
||||||
|
// for also capturing those and RHS (if any)
|
||||||
|
template<typename T>
|
||||||
|
class ExpressionLhs : public DecomposedExpression {
|
||||||
public:
|
public:
|
||||||
ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {}
|
ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ), m_truthy(false) {}
|
||||||
# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
|
|
||||||
ExpressionLhs( ExpressionLhs const& ) = default;
|
|
||||||
ExpressionLhs( ExpressionLhs && ) = default;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
ResultBuilder& operator == ( RhsT const& rhs ) {
|
BinaryExpression<T, Internal::IsEqualTo, RhsT const&>
|
||||||
|
operator == ( RhsT const& rhs ) const {
|
||||||
return captureExpression<Internal::IsEqualTo>( rhs );
|
return captureExpression<Internal::IsEqualTo>( rhs );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
ResultBuilder& operator != ( RhsT const& rhs ) {
|
BinaryExpression<T, Internal::IsNotEqualTo, RhsT const&>
|
||||||
|
operator != ( RhsT const& rhs ) const {
|
||||||
return captureExpression<Internal::IsNotEqualTo>( rhs );
|
return captureExpression<Internal::IsNotEqualTo>( rhs );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
ResultBuilder& operator < ( RhsT const& rhs ) {
|
BinaryExpression<T, Internal::IsLessThan, RhsT const&>
|
||||||
|
operator < ( RhsT const& rhs ) const {
|
||||||
return captureExpression<Internal::IsLessThan>( rhs );
|
return captureExpression<Internal::IsLessThan>( rhs );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
ResultBuilder& operator > ( RhsT const& rhs ) {
|
BinaryExpression<T, Internal::IsGreaterThan, RhsT const&>
|
||||||
|
operator > ( RhsT const& rhs ) const {
|
||||||
return captureExpression<Internal::IsGreaterThan>( rhs );
|
return captureExpression<Internal::IsGreaterThan>( rhs );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
ResultBuilder& operator <= ( RhsT const& rhs ) {
|
BinaryExpression<T, Internal::IsLessThanOrEqualTo, RhsT const&>
|
||||||
|
operator <= ( RhsT const& rhs ) const {
|
||||||
return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
|
return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
ResultBuilder& operator >= ( RhsT const& rhs ) {
|
BinaryExpression<T, Internal::IsGreaterThanOrEqualTo, RhsT const&>
|
||||||
|
operator >= ( RhsT const& rhs ) const {
|
||||||
return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
|
return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultBuilder& operator == ( bool rhs ) {
|
BinaryExpression<T, Internal::IsEqualTo, bool> operator == ( bool rhs ) const {
|
||||||
return captureExpression<Internal::IsEqualTo>( rhs );
|
return captureExpression<Internal::IsEqualTo>( rhs );
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultBuilder& operator != ( bool rhs ) {
|
BinaryExpression<T, Internal::IsNotEqualTo, bool> operator != ( bool rhs ) const {
|
||||||
return captureExpression<Internal::IsNotEqualTo>( rhs );
|
return captureExpression<Internal::IsNotEqualTo>( rhs );
|
||||||
}
|
}
|
||||||
|
|
||||||
void endExpression() {
|
void endExpression() {
|
||||||
bool value = m_lhs ? true : false;
|
m_truthy = m_lhs ? true : false;
|
||||||
m_rb
|
m_rb
|
||||||
.setLhs( Catch::toString( value ) )
|
.setResultType( m_truthy )
|
||||||
.setResultType( value )
|
.endExpression( *this );
|
||||||
.endExpression();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only simple binary expressions are allowed on the LHS.
|
virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE {
|
||||||
// If more complex compositions are required then place the sub expression in parentheses
|
dest = Catch::toString( m_truthy );
|
||||||
template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& );
|
}
|
||||||
template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& );
|
|
||||||
template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& );
|
|
||||||
template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& );
|
|
||||||
template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
|
|
||||||
template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<Internal::Operator Op, typename RhsT>
|
template<Internal::Operator Op, typename RhsT>
|
||||||
ResultBuilder& captureExpression( RhsT const& rhs ) {
|
BinaryExpression<T, Op, RhsT&> captureExpression( RhsT& rhs ) const {
|
||||||
return m_rb
|
return BinaryExpression<T, Op, RhsT&>( m_rb, m_lhs, rhs );
|
||||||
.setResultType( Internal::compare<Op>( m_lhs, rhs ) )
|
}
|
||||||
.setLhs( Catch::toString( m_lhs ) )
|
|
||||||
.setRhs( Catch::toString( rhs ) )
|
template<Internal::Operator Op>
|
||||||
.setOp( Internal::OperatorTraits<Op>::getName() );
|
BinaryExpression<T, Op, bool> captureExpression( bool rhs ) const {
|
||||||
|
return BinaryExpression<T, Op, bool>( m_rb, m_lhs, rhs );
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ResultBuilder& m_rb;
|
ResultBuilder& m_rb;
|
||||||
T m_lhs;
|
T m_lhs;
|
||||||
|
bool m_truthy;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename LhsT, Internal::Operator Op, typename RhsT>
|
||||||
|
class BinaryExpression : public DecomposedExpression {
|
||||||
|
public:
|
||||||
|
BinaryExpression( ResultBuilder& rb, LhsT lhs, RhsT rhs )
|
||||||
|
: m_rb( rb ), m_lhs( lhs ), m_rhs( rhs ) {}
|
||||||
|
|
||||||
|
void endExpression() const {
|
||||||
|
m_rb
|
||||||
|
.setResultType( Internal::compare<Op>( m_lhs, m_rhs ) )
|
||||||
|
.endExpression( *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool isBinaryExpression() const CATCH_OVERRIDE {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE {
|
||||||
|
std::string lhs = Catch::toString( m_lhs );
|
||||||
|
std::string rhs = Catch::toString( m_rhs );
|
||||||
|
char delim = lhs.size() + rhs.size() < 40 &&
|
||||||
|
lhs.find('\n') == std::string::npos &&
|
||||||
|
rhs.find('\n') == std::string::npos ? ' ' : '\n';
|
||||||
|
dest.reserve( 7 + lhs.size() + rhs.size() );
|
||||||
|
// 2 for spaces around operator
|
||||||
|
// 2 for operator
|
||||||
|
// 2 for parentheses (conditionally added later)
|
||||||
|
// 1 for negation (conditionally added later)
|
||||||
|
dest = lhs;
|
||||||
|
dest += delim;
|
||||||
|
dest += Internal::OperatorTraits<Op>::getName();
|
||||||
|
dest += delim;
|
||||||
|
dest += rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ResultBuilder& m_rb;
|
||||||
|
LhsT m_lhs;
|
||||||
|
RhsT m_rhs;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ArgT, typename MatcherT>
|
||||||
|
class MatchExpression : public DecomposedExpression {
|
||||||
|
public:
|
||||||
|
MatchExpression( ArgT arg, MatcherT matcher, char const* matcherString )
|
||||||
|
: m_arg( arg ), m_matcher( matcher ), m_matcherString( matcherString ) {}
|
||||||
|
|
||||||
|
virtual bool isBinaryExpression() const CATCH_OVERRIDE {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE {
|
||||||
|
std::string matcherAsString = m_matcher.toString();
|
||||||
|
dest = Catch::toString( m_arg );
|
||||||
|
dest += ' ';
|
||||||
|
if( matcherAsString == Detail::unprintableString )
|
||||||
|
dest += m_matcherString;
|
||||||
|
else
|
||||||
|
dest += matcherAsString;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ArgT m_arg;
|
||||||
|
MatcherT m_matcher;
|
||||||
|
char const* m_matcherString;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
@@ -12,25 +12,78 @@
|
|||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
// Report the error condition then exit the process
|
// Report the error condition
|
||||||
inline void fatal( std::string const& message, int exitCode ) {
|
inline void reportFatal( std::string const& message ) {
|
||||||
IContext& context = Catch::getCurrentContext();
|
IContext& context = Catch::getCurrentContext();
|
||||||
IResultCapture* resultCapture = context.getResultCapture();
|
IResultCapture* resultCapture = context.getResultCapture();
|
||||||
resultCapture->handleFatalErrorCondition( message );
|
resultCapture->handleFatalErrorCondition( message );
|
||||||
|
|
||||||
if( Catch::alwaysTrue() ) // avoids "no return" warnings
|
|
||||||
exit( exitCode );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Catch
|
} // namespace Catch
|
||||||
|
|
||||||
#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
|
#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
|
||||||
|
|
||||||
|
#define NOMINMAX
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
|
#undef NOMINMAX
|
||||||
|
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
|
struct SignalDefs { DWORD id; const char* name; };
|
||||||
|
extern SignalDefs signalDefs[];
|
||||||
|
// There is no 1-1 mapping between signals and windows exceptions.
|
||||||
|
// Windows can easily distinguish between SO and SigSegV,
|
||||||
|
// but SigInt, SigTerm, etc are handled differently.
|
||||||
|
SignalDefs signalDefs[] = {
|
||||||
|
{ EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal" },
|
||||||
|
{ EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" },
|
||||||
|
{ EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" },
|
||||||
|
{ EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" },
|
||||||
|
};
|
||||||
|
|
||||||
struct FatalConditionHandler {
|
struct FatalConditionHandler {
|
||||||
void reset() {}
|
|
||||||
};
|
static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
|
||||||
|
for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
||||||
|
if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
|
||||||
|
reportFatal(signalDefs[i].name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If its not an exception we care about, pass it along.
|
||||||
|
// This stops us from eating debugger breaks etc.
|
||||||
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
// Register as first handler in current chain
|
||||||
|
m_exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
|
||||||
|
// Pass in guarantee size to be filled
|
||||||
|
SetThreadStackGuarantee(&m_guaranteeSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
if (m_isSet) {
|
||||||
|
// Unregister handler and restore the old guarantee
|
||||||
|
RemoveVectoredExceptionHandler(m_exceptionHandlerHandle);
|
||||||
|
SetThreadStackGuarantee(&m_guaranteeSize);
|
||||||
|
m_exceptionHandlerHandle = CATCH_NULL;
|
||||||
|
m_isSet = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~FatalConditionHandler() {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
bool m_isSet;
|
||||||
|
ULONG m_guaranteeSize;
|
||||||
|
PVOID m_exceptionHandlerHandle;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Catch
|
} // namespace Catch
|
||||||
|
|
||||||
@@ -40,7 +93,10 @@ namespace Catch {
|
|||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
struct SignalDefs { int id; const char* name; };
|
struct SignalDefs {
|
||||||
|
int id;
|
||||||
|
const char* name;
|
||||||
|
};
|
||||||
extern SignalDefs signalDefs[];
|
extern SignalDefs signalDefs[];
|
||||||
SignalDefs signalDefs[] = {
|
SignalDefs signalDefs[] = {
|
||||||
{ SIGINT, "SIGINT - Terminal interrupt signal" },
|
{ SIGINT, "SIGINT - Terminal interrupt signal" },
|
||||||
@@ -49,35 +105,68 @@ namespace Catch {
|
|||||||
{ SIGSEGV, "SIGSEGV - Segmentation violation signal" },
|
{ SIGSEGV, "SIGSEGV - Segmentation violation signal" },
|
||||||
{ SIGTERM, "SIGTERM - Termination request signal" },
|
{ SIGTERM, "SIGTERM - Termination request signal" },
|
||||||
{ SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
|
{ SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FatalConditionHandler {
|
struct FatalConditionHandler {
|
||||||
|
|
||||||
|
static bool isSet;
|
||||||
|
static struct sigaction oldSigActions [sizeof(signalDefs)/sizeof(SignalDefs)];
|
||||||
|
static stack_t oldSigStack;
|
||||||
|
static char altStackMem[SIGSTKSZ];
|
||||||
|
|
||||||
static void handleSignal( int sig ) {
|
static void handleSignal( int sig ) {
|
||||||
for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
|
std::string name = "<unknown signal>";
|
||||||
if( sig == signalDefs[i].id )
|
for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
||||||
fatal( signalDefs[i].name, -sig );
|
SignalDefs &def = signalDefs[i];
|
||||||
fatal( "<unknown signal>", -sig );
|
if (sig == def.id) {
|
||||||
|
name = def.name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reset();
|
||||||
|
reportFatal(name);
|
||||||
|
raise( sig );
|
||||||
}
|
}
|
||||||
|
|
||||||
FatalConditionHandler() : m_isSet( true ) {
|
FatalConditionHandler() {
|
||||||
for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
|
isSet = true;
|
||||||
signal( signalDefs[i].id, handleSignal );
|
stack_t sigStack;
|
||||||
}
|
sigStack.ss_sp = altStackMem;
|
||||||
~FatalConditionHandler() {
|
sigStack.ss_size = SIGSTKSZ;
|
||||||
reset();
|
sigStack.ss_flags = 0;
|
||||||
}
|
sigaltstack(&sigStack, &oldSigStack);
|
||||||
void reset() {
|
struct sigaction sa = { 0 };
|
||||||
if( m_isSet ) {
|
|
||||||
for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
|
sa.sa_handler = handleSignal;
|
||||||
signal( signalDefs[i].id, SIG_DFL );
|
sa.sa_flags = SA_ONSTACK;
|
||||||
m_isSet = false;
|
for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
|
||||||
|
sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool m_isSet;
|
|
||||||
|
~FatalConditionHandler() {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
static void reset() {
|
||||||
|
if( isSet ) {
|
||||||
|
// Set signals back to previous values -- hopefully nobody overwrote them in the meantime
|
||||||
|
for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
|
||||||
|
sigaction(signalDefs[i].id, &oldSigActions[i], CATCH_NULL);
|
||||||
|
}
|
||||||
|
// Return the old stack
|
||||||
|
sigaltstack(&oldSigStack, CATCH_NULL);
|
||||||
|
isSet = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool FatalConditionHandler::isSet = false;
|
||||||
|
struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
|
||||||
|
stack_t FatalConditionHandler::oldSigStack = {};
|
||||||
|
char FatalConditionHandler::altStackMem[SIGSTKSZ] = {};
|
||||||
|
|
||||||
|
|
||||||
} // namespace Catch
|
} // namespace Catch
|
||||||
|
|
||||||
#endif // not Windows
|
#endif // not Windows
|
||||||
|
@@ -41,7 +41,7 @@ namespace Catch {
|
|||||||
Auto,
|
Auto,
|
||||||
Yes,
|
Yes,
|
||||||
No
|
No
|
||||||
}; };
|
}; };
|
||||||
|
|
||||||
class TestSpec;
|
class TestSpec;
|
||||||
|
|
||||||
@@ -62,6 +62,8 @@ namespace Catch {
|
|||||||
virtual RunTests::InWhatOrder runOrder() const = 0;
|
virtual RunTests::InWhatOrder runOrder() const = 0;
|
||||||
virtual unsigned int rngSeed() const = 0;
|
virtual unsigned int rngSeed() const = 0;
|
||||||
virtual UseColour::YesOrNo useColour() const = 0;
|
virtual UseColour::YesOrNo useColour() const = 0;
|
||||||
|
virtual std::vector<std::string> const& getSectionsToRun() const = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -248,7 +248,7 @@ namespace Catch
|
|||||||
virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
|
virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
|
||||||
|
|
||||||
virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
|
virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
|
||||||
|
|
||||||
virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; }
|
virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -51,9 +51,9 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( !config.testSpec().hasFilters() )
|
if( !config.testSpec().hasFilters() )
|
||||||
Catch::cout() << pluralise( matchedTests, "test case" ) << "\n" << std::endl;
|
Catch::cout() << pluralise( matchedTests, "test case" ) << '\n' << std::endl;
|
||||||
else
|
else
|
||||||
Catch::cout() << pluralise( matchedTests, "matching test case" ) << "\n" << std::endl;
|
Catch::cout() << pluralise( matchedTests, "matching test case" ) << '\n' << std::endl;
|
||||||
return matchedTests;
|
return matchedTests;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,8 +68,8 @@ namespace Catch {
|
|||||||
++it ) {
|
++it ) {
|
||||||
matchedTests++;
|
matchedTests++;
|
||||||
TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
|
TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
|
||||||
if( startsWith( testCaseInfo.name, "#" ) )
|
if( startsWith( testCaseInfo.name, '#' ) )
|
||||||
Catch::cout() << "\"" << testCaseInfo.name << "\"" << std::endl;
|
Catch::cout() << '"' << testCaseInfo.name << '"' << std::endl;
|
||||||
else
|
else
|
||||||
Catch::cout() << testCaseInfo.name << std::endl;
|
Catch::cout() << testCaseInfo.name << std::endl;
|
||||||
}
|
}
|
||||||
@@ -132,9 +132,9 @@ namespace Catch {
|
|||||||
.setInitialIndent( 0 )
|
.setInitialIndent( 0 )
|
||||||
.setIndent( oss.str().size() )
|
.setIndent( oss.str().size() )
|
||||||
.setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );
|
.setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );
|
||||||
Catch::cout() << oss.str() << wrapper << "\n";
|
Catch::cout() << oss.str() << wrapper << '\n';
|
||||||
}
|
}
|
||||||
Catch::cout() << pluralise( tagCounts.size(), "tag" ) << "\n" << std::endl;
|
Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
|
||||||
return tagCounts.size();
|
return tagCounts.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,9 +153,9 @@ namespace Catch {
|
|||||||
.setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
|
.setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
|
||||||
Catch::cout() << " "
|
Catch::cout() << " "
|
||||||
<< it->first
|
<< it->first
|
||||||
<< ":"
|
<< ':'
|
||||||
<< std::string( maxNameLen - it->first.size() + 2, ' ' )
|
<< std::string( maxNameLen - it->first.size() + 2, ' ' )
|
||||||
<< wrapper << "\n";
|
<< wrapper << '\n';
|
||||||
}
|
}
|
||||||
Catch::cout() << std::endl;
|
Catch::cout() << std::endl;
|
||||||
return factories.size();
|
return factories.size();
|
||||||
|
@@ -184,7 +184,7 @@ namespace Matchers {
|
|||||||
{
|
{
|
||||||
return m_caseSensitivity == CaseSensitive::No
|
return m_caseSensitivity == CaseSensitive::No
|
||||||
? " (case insensitive)"
|
? " (case insensitive)"
|
||||||
: "";
|
: std::string();
|
||||||
}
|
}
|
||||||
CaseSensitive::Choice m_caseSensitivity;
|
CaseSensitive::Choice m_caseSensitivity;
|
||||||
std::string m_str;
|
std::string m_str;
|
||||||
@@ -202,7 +202,7 @@ namespace Matchers {
|
|||||||
return m_data.m_str == m_data.adjustString( expr );;
|
return m_data.m_str == m_data.adjustString( expr );;
|
||||||
}
|
}
|
||||||
virtual std::string toString() const {
|
virtual std::string toString() const {
|
||||||
return "equals: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
|
return "equals: \"" + m_data.m_str + '"' + m_data.toStringSuffix();
|
||||||
}
|
}
|
||||||
|
|
||||||
CasedString m_data;
|
CasedString m_data;
|
||||||
@@ -219,7 +219,7 @@ namespace Matchers {
|
|||||||
return m_data.adjustString( expr ).find( m_data.m_str ) != std::string::npos;
|
return m_data.adjustString( expr ).find( m_data.m_str ) != std::string::npos;
|
||||||
}
|
}
|
||||||
virtual std::string toString() const {
|
virtual std::string toString() const {
|
||||||
return "contains: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
|
return "contains: \"" + m_data.m_str + '"' + m_data.toStringSuffix();
|
||||||
}
|
}
|
||||||
|
|
||||||
CasedString m_data;
|
CasedString m_data;
|
||||||
@@ -237,7 +237,7 @@ namespace Matchers {
|
|||||||
return startsWith( m_data.adjustString( expr ), m_data.m_str );
|
return startsWith( m_data.adjustString( expr ), m_data.m_str );
|
||||||
}
|
}
|
||||||
virtual std::string toString() const {
|
virtual std::string toString() const {
|
||||||
return "starts with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
|
return "starts with: \"" + m_data.m_str + '"' + m_data.toStringSuffix();
|
||||||
}
|
}
|
||||||
|
|
||||||
CasedString m_data;
|
CasedString m_data;
|
||||||
@@ -254,7 +254,7 @@ namespace Matchers {
|
|||||||
return endsWith( m_data.adjustString( expr ), m_data.m_str );
|
return endsWith( m_data.adjustString( expr ), m_data.m_str );
|
||||||
}
|
}
|
||||||
virtual std::string toString() const {
|
virtual std::string toString() const {
|
||||||
return "ends with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
|
return "ends with: \"" + m_data.m_str + '"' + m_data.toStringSuffix();
|
||||||
}
|
}
|
||||||
|
|
||||||
CasedString m_data;
|
CasedString m_data;
|
||||||
|
@@ -74,7 +74,7 @@ namespace Catch {
|
|||||||
return new T( config );
|
return new T( config );
|
||||||
}
|
}
|
||||||
virtual std::string getDescription() const {
|
virtual std::string getDescription() const {
|
||||||
return "";
|
return std::string();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -19,22 +19,20 @@ namespace Catch {
|
|||||||
|
|
||||||
template<typename T> class ExpressionLhs;
|
template<typename T> class ExpressionLhs;
|
||||||
|
|
||||||
struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
|
|
||||||
|
|
||||||
struct CopyableStream {
|
struct CopyableStream {
|
||||||
CopyableStream() {}
|
CopyableStream() {}
|
||||||
CopyableStream( CopyableStream const& other ) {
|
CopyableStream( CopyableStream const& other ) {
|
||||||
oss << other.oss.str();
|
oss << other.oss.str();
|
||||||
}
|
}
|
||||||
CopyableStream& operator=( CopyableStream const& other ) {
|
CopyableStream& operator=( CopyableStream const& other ) {
|
||||||
oss.str("");
|
oss.str(std::string());
|
||||||
oss << other.oss.str();
|
oss << other.oss.str();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ResultBuilder {
|
class ResultBuilder : public DecomposedExpression {
|
||||||
public:
|
public:
|
||||||
ResultBuilder( char const* macroName,
|
ResultBuilder( char const* macroName,
|
||||||
SourceLineInfo const& lineInfo,
|
SourceLineInfo const& lineInfo,
|
||||||
@@ -52,19 +50,15 @@ namespace Catch {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
|
|
||||||
template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
|
|
||||||
|
|
||||||
ResultBuilder& setResultType( ResultWas::OfType result );
|
ResultBuilder& setResultType( ResultWas::OfType result );
|
||||||
ResultBuilder& setResultType( bool result );
|
ResultBuilder& setResultType( bool result );
|
||||||
ResultBuilder& setLhs( std::string const& lhs );
|
|
||||||
ResultBuilder& setRhs( std::string const& rhs );
|
|
||||||
ResultBuilder& setOp( std::string const& op );
|
|
||||||
|
|
||||||
void endExpression();
|
void endExpression( DecomposedExpression const& expr );
|
||||||
|
|
||||||
|
virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE;
|
||||||
|
|
||||||
std::string reconstructExpression() const;
|
|
||||||
AssertionResult build() const;
|
AssertionResult build() const;
|
||||||
|
AssertionResult build( DecomposedExpression const& expr ) const;
|
||||||
|
|
||||||
void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
|
void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
|
||||||
void captureResult( ResultWas::OfType resultType );
|
void captureResult( ResultWas::OfType resultType );
|
||||||
@@ -76,14 +70,12 @@ namespace Catch {
|
|||||||
bool shouldDebugBreak() const;
|
bool shouldDebugBreak() const;
|
||||||
bool allowThrows() const;
|
bool allowThrows() const;
|
||||||
|
|
||||||
|
template<typename ArgT, typename MatcherT>
|
||||||
|
void captureMatch( ArgT const& arg, MatcherT const& matcher, char const* matcherString );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AssertionInfo m_assertionInfo;
|
AssertionInfo m_assertionInfo;
|
||||||
AssertionResultData m_data;
|
AssertionResultData m_data;
|
||||||
struct ExprComponents {
|
|
||||||
ExprComponents() : testFalse( false ) {}
|
|
||||||
bool testFalse;
|
|
||||||
std::string lhs, rhs, op;
|
|
||||||
} m_exprComponents;
|
|
||||||
CopyableStream m_stream;
|
CopyableStream m_stream;
|
||||||
|
|
||||||
bool m_shouldDebugBreak;
|
bool m_shouldDebugBreak;
|
||||||
@@ -106,6 +98,14 @@ namespace Catch {
|
|||||||
return ExpressionLhs<bool>( *this, value );
|
return ExpressionLhs<bool>( *this, value );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename ArgT, typename MatcherT>
|
||||||
|
inline void ResultBuilder::captureMatch( ArgT const& arg, MatcherT const& matcher,
|
||||||
|
char const* matcherString ) {
|
||||||
|
MatchExpression<ArgT const&, MatcherT const&> expr( arg, matcher, matcherString );
|
||||||
|
setResultType( matcher.match( arg ) );
|
||||||
|
endExpression( expr );
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Catch
|
} // namespace Catch
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
|
||||||
|
@@ -41,22 +41,10 @@ namespace Catch {
|
|||||||
m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
|
m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) {
|
|
||||||
m_exprComponents.lhs = lhs;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) {
|
|
||||||
m_exprComponents.rhs = rhs;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
ResultBuilder& ResultBuilder::setOp( std::string const& op ) {
|
|
||||||
m_exprComponents.op = op;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResultBuilder::endExpression() {
|
void ResultBuilder::endExpression( DecomposedExpression const& expr ) {
|
||||||
m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition );
|
AssertionResult result = build( expr );
|
||||||
captureExpression();
|
handleResult( result );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {
|
void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {
|
||||||
@@ -69,6 +57,7 @@ namespace Catch {
|
|||||||
setResultType( resultType );
|
setResultType( resultType );
|
||||||
captureExpression();
|
captureExpression();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) {
|
void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) {
|
||||||
if( expectedMessage.empty() )
|
if( expectedMessage.empty() )
|
||||||
captureExpectedException( Matchers::Impl::Generic::AllOf<std::string>() );
|
captureExpectedException( Matchers::Impl::Generic::AllOf<std::string>() );
|
||||||
@@ -78,7 +67,7 @@ namespace Catch {
|
|||||||
|
|
||||||
void ResultBuilder::captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher ) {
|
void ResultBuilder::captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher ) {
|
||||||
|
|
||||||
assert( m_exprComponents.testFalse == false );
|
assert( !isFalseTest( m_assertionInfo.resultDisposition ) );
|
||||||
AssertionResultData data = m_data;
|
AssertionResultData data = m_data;
|
||||||
data.resultType = ResultWas::Ok;
|
data.resultType = ResultWas::Ok;
|
||||||
data.reconstructedExpression = m_assertionInfo.capturedExpression;
|
data.reconstructedExpression = m_assertionInfo.capturedExpression;
|
||||||
@@ -96,6 +85,7 @@ namespace Catch {
|
|||||||
AssertionResult result = build();
|
AssertionResult result = build();
|
||||||
handleResult( result );
|
handleResult( result );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResultBuilder::handleResult( AssertionResult const& result )
|
void ResultBuilder::handleResult( AssertionResult const& result )
|
||||||
{
|
{
|
||||||
getResultCapture().assertionEnded( result );
|
getResultCapture().assertionEnded( result );
|
||||||
@@ -107,6 +97,7 @@ namespace Catch {
|
|||||||
m_shouldThrow = true;
|
m_shouldThrow = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResultBuilder::react() {
|
void ResultBuilder::react() {
|
||||||
if( m_shouldThrow )
|
if( m_shouldThrow )
|
||||||
throw Catch::TestFailureException();
|
throw Catch::TestFailureException();
|
||||||
@@ -117,43 +108,32 @@ namespace Catch {
|
|||||||
|
|
||||||
AssertionResult ResultBuilder::build() const
|
AssertionResult ResultBuilder::build() const
|
||||||
{
|
{
|
||||||
assert( m_data.resultType != ResultWas::Unknown );
|
return build( *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
// CAVEAT: The returned AssertionResult stores a pointer to the argument expr,
|
||||||
|
// a temporary DecomposedExpression, which in turn holds references to
|
||||||
|
// operands, possibly temporary as well.
|
||||||
|
// It should immediately be passed to handleResult; if the expression
|
||||||
|
// needs to be reported, its string expansion must be composed before
|
||||||
|
// the temporaries are destroyed.
|
||||||
|
AssertionResult ResultBuilder::build( DecomposedExpression const& expr ) const
|
||||||
|
{
|
||||||
|
assert( m_data.resultType != ResultWas::Unknown );
|
||||||
AssertionResultData data = m_data;
|
AssertionResultData data = m_data;
|
||||||
|
|
||||||
// Flip bool results if testFalse is set
|
// Flip bool results if FalseTest flag is set
|
||||||
if( m_exprComponents.testFalse ) {
|
if( isFalseTest( m_assertionInfo.resultDisposition ) ) {
|
||||||
if( data.resultType == ResultWas::Ok )
|
data.negate( expr.isBinaryExpression() );
|
||||||
data.resultType = ResultWas::ExpressionFailed;
|
|
||||||
else if( data.resultType == ResultWas::ExpressionFailed )
|
|
||||||
data.resultType = ResultWas::Ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data.message = m_stream.oss.str();
|
data.message = m_stream.oss.str();
|
||||||
data.reconstructedExpression = reconstructExpression();
|
data.decomposedExpression = &expr; // for lazy reconstruction
|
||||||
if( m_exprComponents.testFalse ) {
|
|
||||||
if( m_exprComponents.op == "" )
|
|
||||||
data.reconstructedExpression = "!" + data.reconstructedExpression;
|
|
||||||
else
|
|
||||||
data.reconstructedExpression = "!(" + data.reconstructedExpression + ")";
|
|
||||||
}
|
|
||||||
return AssertionResult( m_assertionInfo, data );
|
return AssertionResult( m_assertionInfo, data );
|
||||||
}
|
}
|
||||||
std::string ResultBuilder::reconstructExpression() const {
|
|
||||||
if( m_exprComponents.op == "" )
|
void ResultBuilder::reconstructExpression( std::string& dest ) const {
|
||||||
return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.lhs;
|
dest = m_assertionInfo.capturedExpression;
|
||||||
else if( m_exprComponents.op == "matches" )
|
|
||||||
return m_exprComponents.lhs + " " + m_exprComponents.rhs;
|
|
||||||
else if( m_exprComponents.op != "!" ) {
|
|
||||||
if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 &&
|
|
||||||
m_exprComponents.lhs.find("\n") == std::string::npos &&
|
|
||||||
m_exprComponents.rhs.find("\n") == std::string::npos )
|
|
||||||
return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs;
|
|
||||||
else
|
|
||||||
return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return "{can't expand - use " + m_assertionInfo.macroName + "_FALSE( " + m_assertionInfo.capturedExpression.substr(1) + " ) instead of " + m_assertionInfo.macroName + "( " + m_assertionInfo.capturedExpression + " ) for better diagnostics}";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
@@ -97,10 +97,11 @@ namespace Catch {
|
|||||||
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
m_trackerContext.startRun();
|
ITracker& rootTracker = m_trackerContext.startRun();
|
||||||
|
dynamic_cast<SectionTracker&>( rootTracker ).addInitialFilters( m_config->getSectionsToRun() );
|
||||||
do {
|
do {
|
||||||
m_trackerContext.startCycle();
|
m_trackerContext.startCycle();
|
||||||
m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, testInfo.name );
|
m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( testInfo.name, testInfo.lineInfo ) );
|
||||||
runCurrentTest( redirectedCout, redirectedCerr );
|
runCurrentTest( redirectedCout, redirectedCerr );
|
||||||
}
|
}
|
||||||
while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() );
|
while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() );
|
||||||
@@ -146,7 +147,7 @@ namespace Catch {
|
|||||||
m_messages.clear();
|
m_messages.clear();
|
||||||
|
|
||||||
// Reset working state
|
// Reset working state
|
||||||
m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
|
m_lastAssertionInfo = AssertionInfo( std::string(), m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
|
||||||
m_lastResult = result;
|
m_lastResult = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,10 +156,7 @@ namespace Catch {
|
|||||||
Counts& assertions
|
Counts& assertions
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( sectionInfo.name, sectionInfo.lineInfo ) );
|
||||||
oss << sectionInfo.name << "@" << sectionInfo.lineInfo;
|
|
||||||
|
|
||||||
ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, oss.str() );
|
|
||||||
if( !sectionTracker.isOpen() )
|
if( !sectionTracker.isOpen() )
|
||||||
return false;
|
return false;
|
||||||
m_activeSections.push_back( §ionTracker );
|
m_activeSections.push_back( §ionTracker );
|
||||||
@@ -217,7 +215,7 @@ namespace Catch {
|
|||||||
virtual std::string getCurrentTestName() const {
|
virtual std::string getCurrentTestName() const {
|
||||||
return m_activeTestCase
|
return m_activeTestCase
|
||||||
? m_activeTestCase->getTestCaseInfo().name
|
? m_activeTestCase->getTestCaseInfo().name
|
||||||
: "";
|
: std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const AssertionResult* getLastResult() const {
|
virtual const AssertionResult* getLastResult() const {
|
||||||
@@ -247,11 +245,11 @@ namespace Catch {
|
|||||||
deltaTotals.testCases.failed = 1;
|
deltaTotals.testCases.failed = 1;
|
||||||
m_reporter->testCaseEnded( TestCaseStats( testInfo,
|
m_reporter->testCaseEnded( TestCaseStats( testInfo,
|
||||||
deltaTotals,
|
deltaTotals,
|
||||||
"",
|
std::string(),
|
||||||
"",
|
std::string(),
|
||||||
false ) );
|
false ) );
|
||||||
m_totals.testCases.failed++;
|
m_totals.testCases.failed++;
|
||||||
testGroupEnded( "", m_totals, 1, 1 );
|
testGroupEnded( std::string(), m_totals, 1, 1 );
|
||||||
m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) );
|
m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,7 +268,7 @@ namespace Catch {
|
|||||||
Counts prevAssertions = m_totals.assertions;
|
Counts prevAssertions = m_totals.assertions;
|
||||||
double duration = 0;
|
double duration = 0;
|
||||||
try {
|
try {
|
||||||
m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
|
m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, std::string(), ResultDisposition::Normal );
|
||||||
|
|
||||||
seedRng( *m_config );
|
seedRng( *m_config );
|
||||||
|
|
||||||
|
@@ -61,7 +61,7 @@ namespace Catch {
|
|||||||
m_ofs.open( filename.c_str() );
|
m_ofs.open( filename.c_str() );
|
||||||
if( m_ofs.fail() ) {
|
if( m_ofs.fail() ) {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "Unable to open file: '" << filename << "'";
|
oss << "Unable to open file: '" << filename << '\'';
|
||||||
throw std::domain_error( oss.str() );
|
throw std::domain_error( oss.str() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -43,7 +43,7 @@ namespace Catch {
|
|||||||
|
|
||||||
void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
|
void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
|
||||||
|
|
||||||
if( !startsWith( alias, "[@" ) || !endsWith( alias, "]" ) ) {
|
if( !startsWith( alias, "[@" ) || !endsWith( alias, ']' ) ) {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo;
|
oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo;
|
||||||
throw std::domain_error( oss.str().c_str() );
|
throw std::domain_error( oss.str().c_str() );
|
||||||
@@ -51,7 +51,7 @@ namespace Catch {
|
|||||||
if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {
|
if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "error: tag alias, \"" << alias << "\" already registered.\n"
|
oss << "error: tag alias, \"" << alias << "\" already registered.\n"
|
||||||
<< "\tFirst seen at " << find(alias)->lineInfo << "\n"
|
<< "\tFirst seen at " << find(alias)->lineInfo << '\n'
|
||||||
<< "\tRedefined at " << lineInfo;
|
<< "\tRedefined at " << lineInfo;
|
||||||
throw std::domain_error( oss.str().c_str() );
|
throw std::domain_error( oss.str().c_str() );
|
||||||
}
|
}
|
||||||
|
@@ -29,7 +29,8 @@ namespace Catch {
|
|||||||
IsHidden = 1 << 1,
|
IsHidden = 1 << 1,
|
||||||
ShouldFail = 1 << 2,
|
ShouldFail = 1 << 2,
|
||||||
MayFail = 1 << 3,
|
MayFail = 1 << 3,
|
||||||
Throws = 1 << 4
|
Throws = 1 << 4,
|
||||||
|
NonPortable = 1 << 5
|
||||||
};
|
};
|
||||||
|
|
||||||
TestCaseInfo( std::string const& _name,
|
TestCaseInfo( std::string const& _name,
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
|
inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
|
||||||
if( startsWith( tag, "." ) ||
|
if( startsWith( tag, '.' ) ||
|
||||||
tag == "hide" ||
|
tag == "hide" ||
|
||||||
tag == "!hide" )
|
tag == "!hide" )
|
||||||
return TestCaseInfo::IsHidden;
|
return TestCaseInfo::IsHidden;
|
||||||
@@ -26,6 +26,8 @@ namespace Catch {
|
|||||||
return TestCaseInfo::ShouldFail;
|
return TestCaseInfo::ShouldFail;
|
||||||
else if( tag == "!mayfail" )
|
else if( tag == "!mayfail" )
|
||||||
return TestCaseInfo::MayFail;
|
return TestCaseInfo::MayFail;
|
||||||
|
else if( tag == "!nonportable" )
|
||||||
|
return TestCaseInfo::NonPortable;
|
||||||
else
|
else
|
||||||
return TestCaseInfo::None;
|
return TestCaseInfo::None;
|
||||||
}
|
}
|
||||||
@@ -100,7 +102,7 @@ namespace Catch {
|
|||||||
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) {
|
for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) {
|
||||||
oss << "[" << *it << "]";
|
oss << '[' << *it << ']';
|
||||||
std::string lcaseTag = toLower( *it );
|
std::string lcaseTag = toLower( *it );
|
||||||
testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
|
testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
|
||||||
testCaseInfo.lcaseTags.insert( lcaseTag );
|
testCaseInfo.lcaseTags.insert( lcaseTag );
|
||||||
|
@@ -78,7 +78,7 @@ namespace Catch {
|
|||||||
|
|
||||||
ss << Colour( Colour::Red )
|
ss << Colour( Colour::Red )
|
||||||
<< "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n"
|
<< "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n"
|
||||||
<< "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
|
<< "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << '\n'
|
||||||
<< "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl;
|
<< "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl;
|
||||||
|
|
||||||
throw std::runtime_error(ss.str());
|
throw std::runtime_error(ss.str());
|
||||||
@@ -110,7 +110,7 @@ namespace Catch {
|
|||||||
|
|
||||||
virtual void registerTest( TestCase const& testCase ) {
|
virtual void registerTest( TestCase const& testCase ) {
|
||||||
std::string name = testCase.getTestCaseInfo().name;
|
std::string name = testCase.getTestCaseInfo().name;
|
||||||
if( name == "" ) {
|
if( name.empty() ) {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "Anonymous test case " << ++m_unnamedCount;
|
oss << "Anonymous test case " << ++m_unnamedCount;
|
||||||
return registerTest( testCase.withName( oss.str() ) );
|
return registerTest( testCase.withName( oss.str() ) );
|
||||||
@@ -159,7 +159,7 @@ namespace Catch {
|
|||||||
|
|
||||||
inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
|
inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
|
||||||
std::string className = classOrQualifiedMethodName;
|
std::string className = classOrQualifiedMethodName;
|
||||||
if( startsWith( className, "&" ) )
|
if( startsWith( className, '&' ) )
|
||||||
{
|
{
|
||||||
std::size_t lastColons = className.rfind( "::" );
|
std::size_t lastColons = className.rfind( "::" );
|
||||||
std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
|
std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
|
||||||
|
@@ -15,15 +15,26 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
namespace TestCaseTracking {
|
namespace TestCaseTracking {
|
||||||
|
|
||||||
|
struct NameAndLocation {
|
||||||
|
std::string name;
|
||||||
|
SourceLineInfo location;
|
||||||
|
|
||||||
|
NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
|
||||||
|
: name( _name ),
|
||||||
|
location( _location )
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
struct ITracker : SharedImpl<> {
|
struct ITracker : SharedImpl<> {
|
||||||
virtual ~ITracker();
|
virtual ~ITracker();
|
||||||
|
|
||||||
// static queries
|
// static queries
|
||||||
virtual std::string name() const = 0;
|
virtual NameAndLocation const& nameAndLocation() const = 0;
|
||||||
|
|
||||||
// dynamic queries
|
// dynamic queries
|
||||||
virtual bool isComplete() const = 0; // Successfully completed or failed
|
virtual bool isComplete() const = 0; // Successfully completed or failed
|
||||||
@@ -39,15 +50,15 @@ namespace TestCaseTracking {
|
|||||||
virtual void markAsNeedingAnotherRun() = 0;
|
virtual void markAsNeedingAnotherRun() = 0;
|
||||||
|
|
||||||
virtual void addChild( Ptr<ITracker> const& child ) = 0;
|
virtual void addChild( Ptr<ITracker> const& child ) = 0;
|
||||||
virtual ITracker* findChild( std::string const& name ) = 0;
|
virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) = 0;
|
||||||
virtual void openChild() = 0;
|
virtual void openChild() = 0;
|
||||||
|
|
||||||
// Debug/ checking
|
// Debug/ checking
|
||||||
virtual bool isSectionTracker() const = 0;
|
virtual bool isSectionTracker() const = 0;
|
||||||
virtual bool isIndexTracker() const = 0;
|
virtual bool isIndexTracker() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TrackerContext {
|
class TrackerContext {
|
||||||
|
|
||||||
enum RunState {
|
enum RunState {
|
||||||
NotStarted,
|
NotStarted,
|
||||||
@@ -110,30 +121,32 @@ namespace TestCaseTracking {
|
|||||||
Failed
|
Failed
|
||||||
};
|
};
|
||||||
class TrackerHasName {
|
class TrackerHasName {
|
||||||
std::string m_name;
|
NameAndLocation m_nameAndLocation;
|
||||||
public:
|
public:
|
||||||
TrackerHasName( std::string const& name ) : m_name( name ) {}
|
TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {}
|
||||||
bool operator ()( Ptr<ITracker> const& tracker ) {
|
bool operator ()( Ptr<ITracker> const& tracker ) {
|
||||||
return tracker->name() == m_name;
|
return
|
||||||
|
tracker->nameAndLocation().name == m_nameAndLocation.name &&
|
||||||
|
tracker->nameAndLocation().location == m_nameAndLocation.location;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
typedef std::vector<Ptr<ITracker> > Children;
|
typedef std::vector<Ptr<ITracker> > Children;
|
||||||
std::string m_name;
|
NameAndLocation m_nameAndLocation;
|
||||||
TrackerContext& m_ctx;
|
TrackerContext& m_ctx;
|
||||||
ITracker* m_parent;
|
ITracker* m_parent;
|
||||||
Children m_children;
|
Children m_children;
|
||||||
CycleState m_runState;
|
CycleState m_runState;
|
||||||
public:
|
public:
|
||||||
TrackerBase( std::string const& name, TrackerContext& ctx, ITracker* parent )
|
TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
|
||||||
: m_name( name ),
|
: m_nameAndLocation( nameAndLocation ),
|
||||||
m_ctx( ctx ),
|
m_ctx( ctx ),
|
||||||
m_parent( parent ),
|
m_parent( parent ),
|
||||||
m_runState( NotStarted )
|
m_runState( NotStarted )
|
||||||
{}
|
{}
|
||||||
virtual ~TrackerBase();
|
virtual ~TrackerBase();
|
||||||
|
|
||||||
virtual std::string name() const CATCH_OVERRIDE {
|
virtual NameAndLocation const& nameAndLocation() const CATCH_OVERRIDE {
|
||||||
return m_name;
|
return m_nameAndLocation;
|
||||||
}
|
}
|
||||||
virtual bool isComplete() const CATCH_OVERRIDE {
|
virtual bool isComplete() const CATCH_OVERRIDE {
|
||||||
return m_runState == CompletedSuccessfully || m_runState == Failed;
|
return m_runState == CompletedSuccessfully || m_runState == Failed;
|
||||||
@@ -153,8 +166,8 @@ namespace TestCaseTracking {
|
|||||||
m_children.push_back( child );
|
m_children.push_back( child );
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ITracker* findChild( std::string const& name ) CATCH_OVERRIDE {
|
virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) CATCH_OVERRIDE {
|
||||||
Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( name ) );
|
Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( nameAndLocation ) );
|
||||||
return( it != m_children.end() )
|
return( it != m_children.end() )
|
||||||
? it->get()
|
? it->get()
|
||||||
: CATCH_NULL;
|
: CATCH_NULL;
|
||||||
@@ -174,7 +187,7 @@ namespace TestCaseTracking {
|
|||||||
|
|
||||||
virtual bool isSectionTracker() const CATCH_OVERRIDE { return false; }
|
virtual bool isSectionTracker() const CATCH_OVERRIDE { return false; }
|
||||||
virtual bool isIndexTracker() const CATCH_OVERRIDE { return false; }
|
virtual bool isIndexTracker() const CATCH_OVERRIDE { return false; }
|
||||||
|
|
||||||
void open() {
|
void open() {
|
||||||
m_runState = Executing;
|
m_runState = Executing;
|
||||||
moveToThis();
|
moveToThis();
|
||||||
@@ -232,59 +245,83 @@ namespace TestCaseTracking {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class SectionTracker : public TrackerBase {
|
class SectionTracker : public TrackerBase {
|
||||||
|
std::vector<std::string> m_filters;
|
||||||
public:
|
public:
|
||||||
SectionTracker( std::string const& name, TrackerContext& ctx, ITracker* parent )
|
SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
|
||||||
: TrackerBase( name, ctx, parent )
|
: TrackerBase( nameAndLocation, ctx, parent )
|
||||||
{}
|
{
|
||||||
|
if( parent ) {
|
||||||
|
while( !parent->isSectionTracker() )
|
||||||
|
parent = &parent->parent();
|
||||||
|
|
||||||
|
SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
|
||||||
|
addNextFilters( parentSection.m_filters );
|
||||||
|
}
|
||||||
|
}
|
||||||
virtual ~SectionTracker();
|
virtual ~SectionTracker();
|
||||||
|
|
||||||
virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; }
|
virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; }
|
||||||
|
|
||||||
static SectionTracker& acquire( TrackerContext& ctx, std::string const& name ) {
|
static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
|
||||||
SectionTracker* section = CATCH_NULL;
|
SectionTracker* section = CATCH_NULL;
|
||||||
|
|
||||||
ITracker& currentTracker = ctx.currentTracker();
|
ITracker& currentTracker = ctx.currentTracker();
|
||||||
if( ITracker* childTracker = currentTracker.findChild( name ) ) {
|
if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) {
|
||||||
assert( childTracker );
|
assert( childTracker );
|
||||||
assert( childTracker->isSectionTracker() );
|
assert( childTracker->isSectionTracker() );
|
||||||
section = static_cast<SectionTracker*>( childTracker );
|
section = static_cast<SectionTracker*>( childTracker );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
section = new SectionTracker( name, ctx, ¤tTracker );
|
section = new SectionTracker( nameAndLocation, ctx, ¤tTracker );
|
||||||
currentTracker.addChild( section );
|
currentTracker.addChild( section );
|
||||||
}
|
}
|
||||||
if( !ctx.completedCycle() && !section->isComplete() ) {
|
if( !ctx.completedCycle() )
|
||||||
|
section->tryOpen();
|
||||||
section->open();
|
|
||||||
}
|
|
||||||
return *section;
|
return *section;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tryOpen() {
|
||||||
|
if( !isComplete() && (m_filters.empty() || m_filters[0].empty() || m_filters[0] == m_nameAndLocation.name ) )
|
||||||
|
open();
|
||||||
|
}
|
||||||
|
|
||||||
|
void addInitialFilters( std::vector<std::string> const& filters ) {
|
||||||
|
if( !filters.empty() ) {
|
||||||
|
m_filters.push_back(""); // Root - should never be consulted
|
||||||
|
m_filters.push_back(""); // Test Case - not a section filter
|
||||||
|
std::copy( filters.begin(), filters.end(), std::back_inserter( m_filters ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void addNextFilters( std::vector<std::string> const& filters ) {
|
||||||
|
if( filters.size() > 1 )
|
||||||
|
std::copy( filters.begin()+1, filters.end(), std::back_inserter( m_filters ) );
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class IndexTracker : public TrackerBase {
|
class IndexTracker : public TrackerBase {
|
||||||
int m_size;
|
int m_size;
|
||||||
int m_index;
|
int m_index;
|
||||||
public:
|
public:
|
||||||
IndexTracker( std::string const& name, TrackerContext& ctx, ITracker* parent, int size )
|
IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size )
|
||||||
: TrackerBase( name, ctx, parent ),
|
: TrackerBase( nameAndLocation, ctx, parent ),
|
||||||
m_size( size ),
|
m_size( size ),
|
||||||
m_index( -1 )
|
m_index( -1 )
|
||||||
{}
|
{}
|
||||||
virtual ~IndexTracker();
|
virtual ~IndexTracker();
|
||||||
|
|
||||||
virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; }
|
virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; }
|
||||||
|
|
||||||
static IndexTracker& acquire( TrackerContext& ctx, std::string const& name, int size ) {
|
static IndexTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ) {
|
||||||
IndexTracker* tracker = CATCH_NULL;
|
IndexTracker* tracker = CATCH_NULL;
|
||||||
|
|
||||||
ITracker& currentTracker = ctx.currentTracker();
|
ITracker& currentTracker = ctx.currentTracker();
|
||||||
if( ITracker* childTracker = currentTracker.findChild( name ) ) {
|
if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) {
|
||||||
assert( childTracker );
|
assert( childTracker );
|
||||||
assert( childTracker->isIndexTracker() );
|
assert( childTracker->isIndexTracker() );
|
||||||
tracker = static_cast<IndexTracker*>( childTracker );
|
tracker = static_cast<IndexTracker*>( childTracker );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tracker = new IndexTracker( name, ctx, ¤tTracker, size );
|
tracker = new IndexTracker( nameAndLocation, ctx, ¤tTracker, size );
|
||||||
currentTracker.addChild( tracker );
|
currentTracker.addChild( tracker );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,7 +349,7 @@ namespace TestCaseTracking {
|
|||||||
};
|
};
|
||||||
|
|
||||||
inline ITracker& TrackerContext::startRun() {
|
inline ITracker& TrackerContext::startRun() {
|
||||||
m_rootTracker = new SectionTracker( "{root}", *this, CATCH_NULL );
|
m_rootTracker = new SectionTracker( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, CATCH_NULL );
|
||||||
m_currentTracker = CATCH_NULL;
|
m_currentTracker = CATCH_NULL;
|
||||||
m_runState = Executing;
|
m_runState = Executing;
|
||||||
return *m_rootTracker;
|
return *m_rootTracker;
|
||||||
|
@@ -87,6 +87,8 @@ namespace Catch {
|
|||||||
m_start = start;
|
m_start = start;
|
||||||
}
|
}
|
||||||
void escape() {
|
void escape() {
|
||||||
|
if( m_mode == None )
|
||||||
|
m_start = m_pos;
|
||||||
m_mode = EscapedName;
|
m_mode = EscapedName;
|
||||||
m_escapeChars.push_back( m_pos );
|
m_escapeChars.push_back( m_pos );
|
||||||
}
|
}
|
||||||
@@ -95,7 +97,7 @@ namespace Catch {
|
|||||||
void addPattern() {
|
void addPattern() {
|
||||||
std::string token = subString();
|
std::string token = subString();
|
||||||
for( size_t i = 0; i < m_escapeChars.size(); ++i )
|
for( size_t i = 0; i < m_escapeChars.size(); ++i )
|
||||||
token = token.substr( 0, m_escapeChars[i] ) + token.substr( m_escapeChars[i]+1 );
|
token = token.substr( 0, m_escapeChars[i]-i ) + token.substr( m_escapeChars[i]+1-i );
|
||||||
m_escapeChars.clear();
|
m_escapeChars.clear();
|
||||||
if( startsWith( token, "exclude:" ) ) {
|
if( startsWith( token, "exclude:" ) ) {
|
||||||
m_exclusion = true;
|
m_exclusion = true;
|
||||||
|
@@ -69,7 +69,7 @@ std::string toString( std::string const& value ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "\"" + s + "\"";
|
return '"' + s + '"';
|
||||||
}
|
}
|
||||||
std::string toString( std::wstring const& value ) {
|
std::string toString( std::wstring const& value ) {
|
||||||
|
|
||||||
@@ -90,19 +90,19 @@ std::string toString( char* const value ) {
|
|||||||
|
|
||||||
std::string toString( const wchar_t* const value )
|
std::string toString( const wchar_t* const value )
|
||||||
{
|
{
|
||||||
return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" );
|
return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string toString( wchar_t* const value )
|
std::string toString( wchar_t* const value )
|
||||||
{
|
{
|
||||||
return Catch::toString( static_cast<const wchar_t*>( value ) );
|
return Catch::toString( static_cast<const wchar_t*>( value ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string toString( int value ) {
|
std::string toString( int value ) {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << value;
|
oss << value;
|
||||||
if( value > Detail::hexThreshold )
|
if( value > Detail::hexThreshold )
|
||||||
oss << " (0x" << std::hex << value << ")";
|
oss << " (0x" << std::hex << value << ')';
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,7 +110,7 @@ std::string toString( unsigned long value ) {
|
|||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << value;
|
oss << value;
|
||||||
if( value > Detail::hexThreshold )
|
if( value > Detail::hexThreshold )
|
||||||
oss << " (0x" << std::hex << value << ")";
|
oss << " (0x" << std::hex << value << ')';
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +138,7 @@ std::string toString( const double value ) {
|
|||||||
return fpToString( value, 10 );
|
return fpToString( value, 10 );
|
||||||
}
|
}
|
||||||
std::string toString( const float value ) {
|
std::string toString( const float value ) {
|
||||||
return fpToString( value, 5 ) + "f";
|
return fpToString( value, 5 ) + 'f';
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string toString( bool value ) {
|
std::string toString( bool value ) {
|
||||||
@@ -146,9 +146,19 @@ std::string toString( bool value ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string toString( char value ) {
|
std::string toString( char value ) {
|
||||||
return value < ' '
|
if ( value == '\r' )
|
||||||
? toString( static_cast<unsigned int>( value ) )
|
return "'\\r'";
|
||||||
: Detail::makeString( value );
|
if ( value == '\f' )
|
||||||
|
return "'\\f'";
|
||||||
|
if ( value == '\n' )
|
||||||
|
return "'\\n'";
|
||||||
|
if ( value == '\t' )
|
||||||
|
return "'\\t'";
|
||||||
|
if ( '\0' <= value && value < ' ' )
|
||||||
|
return toString( static_cast<unsigned int>( value ) );
|
||||||
|
char chstr[] = "' '";
|
||||||
|
chstr[1] = value;
|
||||||
|
return chstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string toString( signed char value ) {
|
std::string toString( signed char value ) {
|
||||||
@@ -164,14 +174,14 @@ std::string toString( long long value ) {
|
|||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << value;
|
oss << value;
|
||||||
if( value > Detail::hexThreshold )
|
if( value > Detail::hexThreshold )
|
||||||
oss << " (0x" << std::hex << value << ")";
|
oss << " (0x" << std::hex << value << ')';
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
std::string toString( unsigned long long value ) {
|
std::string toString( unsigned long long value ) {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << value;
|
oss << value;
|
||||||
if( value > Detail::hexThreshold )
|
if( value > Detail::hexThreshold )
|
||||||
oss << " (0x" << std::hex << value << ")";
|
oss << " (0x" << std::hex << value << ')';
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -26,18 +26,18 @@ namespace Catch {
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
std::ostream& operator << ( std::ostream& os, Version const& version ) {
|
std::ostream& operator << ( std::ostream& os, Version const& version ) {
|
||||||
os << version.majorVersion << "."
|
os << version.majorVersion << '.'
|
||||||
<< version.minorVersion << "."
|
<< version.minorVersion << '.'
|
||||||
<< version.patchNumber;
|
<< version.patchNumber;
|
||||||
|
|
||||||
if( !version.branchName.empty() ) {
|
if( !version.branchName.empty() ) {
|
||||||
os << "-" << version.branchName
|
os << '-' << version.branchName
|
||||||
<< "." << version.buildNumber;
|
<< '.' << version.buildNumber;
|
||||||
}
|
}
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
Version libraryVersion( 1, 6, 1, "", 0 );
|
Version libraryVersion( 1, 7, 0, "", 0 );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -27,11 +27,11 @@ namespace Catch
|
|||||||
m_wildcard( NoWildcard ),
|
m_wildcard( NoWildcard ),
|
||||||
m_pattern( adjustCase( pattern ) )
|
m_pattern( adjustCase( pattern ) )
|
||||||
{
|
{
|
||||||
if( startsWith( m_pattern, "*" ) ) {
|
if( startsWith( m_pattern, '*' ) ) {
|
||||||
m_pattern = m_pattern.substr( 1 );
|
m_pattern = m_pattern.substr( 1 );
|
||||||
m_wildcard = WildcardAtStart;
|
m_wildcard = WildcardAtStart;
|
||||||
}
|
}
|
||||||
if( endsWith( m_pattern, "*" ) ) {
|
if( endsWith( m_pattern, '*' ) ) {
|
||||||
m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
|
m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
|
||||||
m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
|
m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
|
||||||
}
|
}
|
||||||
|
@@ -136,7 +136,7 @@ namespace Catch {
|
|||||||
XmlWriter& startElement( std::string const& name ) {
|
XmlWriter& startElement( std::string const& name ) {
|
||||||
ensureTagClosed();
|
ensureTagClosed();
|
||||||
newlineIfNecessary();
|
newlineIfNecessary();
|
||||||
stream() << m_indent << "<" << name;
|
stream() << m_indent << '<' << name;
|
||||||
m_tags.push_back( name );
|
m_tags.push_back( name );
|
||||||
m_indent += " ";
|
m_indent += " ";
|
||||||
m_tagIsOpen = true;
|
m_tagIsOpen = true;
|
||||||
@@ -165,12 +165,12 @@ namespace Catch {
|
|||||||
|
|
||||||
XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
|
XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
|
||||||
if( !name.empty() && !attribute.empty() )
|
if( !name.empty() && !attribute.empty() )
|
||||||
stream() << " " << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << "\"";
|
stream() << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlWriter& writeAttribute( std::string const& name, bool attribute ) {
|
XmlWriter& writeAttribute( std::string const& name, bool attribute ) {
|
||||||
stream() << " " << name << "=\"" << ( attribute ? "true" : "false" ) << "\"";
|
stream() << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,7 +202,7 @@ namespace Catch {
|
|||||||
|
|
||||||
XmlWriter& writeBlankLine() {
|
XmlWriter& writeBlankLine() {
|
||||||
ensureTagClosed();
|
ensureTagClosed();
|
||||||
stream() << "\n";
|
stream() << '\n';
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,7 +227,7 @@ namespace Catch {
|
|||||||
|
|
||||||
void newlineIfNecessary() {
|
void newlineIfNecessary() {
|
||||||
if( m_needsNewline ) {
|
if( m_needsNewline ) {
|
||||||
stream() << "\n";
|
stream() << '\n';
|
||||||
m_needsNewline = false;
|
m_needsNewline = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -108,12 +108,12 @@ namespace Catch {
|
|||||||
|
|
||||||
struct BySectionInfo {
|
struct BySectionInfo {
|
||||||
BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
|
BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
|
||||||
BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
|
BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
|
||||||
bool operator() ( Ptr<SectionNode> const& node ) const {
|
bool operator() ( Ptr<SectionNode> const& node ) const {
|
||||||
return node->stats.sectionInfo.lineInfo == m_other.lineInfo;
|
return node->stats.sectionInfo.lineInfo == m_other.lineInfo;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
void operator=( BySectionInfo const& );
|
void operator=( BySectionInfo const& );
|
||||||
SectionInfo const& m_other;
|
SectionInfo const& m_other;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -170,6 +170,12 @@ namespace Catch {
|
|||||||
assert( !m_sectionStack.empty() );
|
assert( !m_sectionStack.empty() );
|
||||||
SectionNode& sectionNode = *m_sectionStack.back();
|
SectionNode& sectionNode = *m_sectionStack.back();
|
||||||
sectionNode.assertions.push_back( assertionStats );
|
sectionNode.assertions.push_back( assertionStats );
|
||||||
|
// AssertionResult holds a pointer to a temporary DecomposedExpression,
|
||||||
|
// which getExpandedExpression() calls to build the expression string.
|
||||||
|
// Our section stack copy of the assertionResult will likely outlive the
|
||||||
|
// temporary, so it must be expanded or discarded now to avoid calling
|
||||||
|
// a destroyed object later.
|
||||||
|
prepareExpandedExpression( sectionNode.assertions.back().assertionResult );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
|
virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
|
||||||
@@ -204,6 +210,13 @@ namespace Catch {
|
|||||||
|
|
||||||
virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {}
|
virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {}
|
||||||
|
|
||||||
|
virtual void prepareExpandedExpression( AssertionResult& result ) const {
|
||||||
|
if( result.isOk() )
|
||||||
|
result.discardDecomposedExpression();
|
||||||
|
else
|
||||||
|
result.expandDecomposedExpression();
|
||||||
|
}
|
||||||
|
|
||||||
Ptr<IConfig const> m_config;
|
Ptr<IConfig const> m_config;
|
||||||
std::ostream& stream;
|
std::ostream& stream;
|
||||||
std::vector<AssertionStats> m_assertions;
|
std::vector<AssertionStats> m_assertions;
|
||||||
|
@@ -34,7 +34,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void noMatchingTestCases( std::string const& spec ) {
|
virtual void noMatchingTestCases( std::string const& spec ) {
|
||||||
stream << "No test cases matched '" << spec << "'" << std::endl;
|
stream << "No test cases matched '" << spec << '\'' << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void assertionStarting( AssertionInfo const& ) {
|
virtual void assertionStarting( AssertionInfo const& ) {
|
||||||
@@ -61,7 +61,7 @@ namespace Catch {
|
|||||||
|
|
||||||
virtual void testRunEnded( TestRunStats const& _testRunStats ) {
|
virtual void testRunEnded( TestRunStats const& _testRunStats ) {
|
||||||
printTotals( _testRunStats.totals );
|
printTotals( _testRunStats.totals );
|
||||||
stream << "\n" << std::endl;
|
stream << '\n' << std::endl;
|
||||||
StreamingReporterBase::testRunEnded( _testRunStats );
|
StreamingReporterBase::testRunEnded( _testRunStats );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,26 +161,26 @@ namespace Catch {
|
|||||||
|
|
||||||
void printSourceInfo() const {
|
void printSourceInfo() const {
|
||||||
Colour colourGuard( Colour::FileName );
|
Colour colourGuard( Colour::FileName );
|
||||||
stream << result.getSourceInfo() << ":";
|
stream << result.getSourceInfo() << ':';
|
||||||
}
|
}
|
||||||
|
|
||||||
void printResultType( Colour::Code colour, std::string passOrFail ) const {
|
void printResultType( Colour::Code colour, std::string passOrFail ) const {
|
||||||
if( !passOrFail.empty() ) {
|
if( !passOrFail.empty() ) {
|
||||||
{
|
{
|
||||||
Colour colourGuard( colour );
|
Colour colourGuard( colour );
|
||||||
stream << " " << passOrFail;
|
stream << ' ' << passOrFail;
|
||||||
}
|
}
|
||||||
stream << ":";
|
stream << ':';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void printIssue( std::string issue ) const {
|
void printIssue( std::string issue ) const {
|
||||||
stream << " " << issue;
|
stream << ' ' << issue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void printExpressionWas() {
|
void printExpressionWas() {
|
||||||
if( result.hasExpression() ) {
|
if( result.hasExpression() ) {
|
||||||
stream << ";";
|
stream << ';';
|
||||||
{
|
{
|
||||||
Colour colour( dimColour() );
|
Colour colour( dimColour() );
|
||||||
stream << " expression was:";
|
stream << " expression was:";
|
||||||
@@ -191,7 +191,7 @@ namespace Catch {
|
|||||||
|
|
||||||
void printOriginalExpression() const {
|
void printOriginalExpression() const {
|
||||||
if( result.hasExpression() ) {
|
if( result.hasExpression() ) {
|
||||||
stream << " " << result.getExpression();
|
stream << ' ' << result.getExpression();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,7 +207,7 @@ namespace Catch {
|
|||||||
|
|
||||||
void printMessage() {
|
void printMessage() {
|
||||||
if ( itMessage != messages.end() ) {
|
if ( itMessage != messages.end() ) {
|
||||||
stream << " '" << itMessage->message << "'";
|
stream << " '" << itMessage->message << '\'';
|
||||||
++itMessage;
|
++itMessage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -222,13 +222,13 @@ namespace Catch {
|
|||||||
|
|
||||||
{
|
{
|
||||||
Colour colourGuard( colour );
|
Colour colourGuard( colour );
|
||||||
stream << " with " << pluralise( N, "message" ) << ":";
|
stream << " with " << pluralise( N, "message" ) << ':';
|
||||||
}
|
}
|
||||||
|
|
||||||
for(; itMessage != itEnd; ) {
|
for(; itMessage != itEnd; ) {
|
||||||
// If this assertion is a warning ignore any INFO messages
|
// If this assertion is a warning ignore any INFO messages
|
||||||
if( printInfoMessages || itMessage->type != ResultWas::Info ) {
|
if( printInfoMessages || itMessage->type != ResultWas::Info ) {
|
||||||
stream << " '" << itMessage->message << "'";
|
stream << " '" << itMessage->message << '\'';
|
||||||
if ( ++itMessage != itEnd ) {
|
if ( ++itMessage != itEnd ) {
|
||||||
Colour colourGuard( dimColour() );
|
Colour colourGuard( dimColour() );
|
||||||
stream << " and";
|
stream << " and";
|
||||||
@@ -254,7 +254,7 @@ namespace Catch {
|
|||||||
// - green: Passed [both/all] N tests cases with M assertions.
|
// - green: Passed [both/all] N tests cases with M assertions.
|
||||||
|
|
||||||
std::string bothOrAll( std::size_t count ) const {
|
std::string bothOrAll( std::size_t count ) const {
|
||||||
return count == 1 ? "" : count == 2 ? "both " : "all " ;
|
return count == 1 ? std::string() : count == 2 ? "both " : "all " ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void printTotals( const Totals& totals ) const {
|
void printTotals( const Totals& totals ) const {
|
||||||
@@ -265,12 +265,12 @@ namespace Catch {
|
|||||||
Colour colour( Colour::ResultError );
|
Colour colour( Colour::ResultError );
|
||||||
const std::string qualify_assertions_failed =
|
const std::string qualify_assertions_failed =
|
||||||
totals.assertions.failed == totals.assertions.total() ?
|
totals.assertions.failed == totals.assertions.total() ?
|
||||||
bothOrAll( totals.assertions.failed ) : "";
|
bothOrAll( totals.assertions.failed ) : std::string();
|
||||||
stream <<
|
stream <<
|
||||||
"Failed " << bothOrAll( totals.testCases.failed )
|
"Failed " << bothOrAll( totals.testCases.failed )
|
||||||
<< pluralise( totals.testCases.failed, "test case" ) << ", "
|
<< pluralise( totals.testCases.failed, "test case" ) << ", "
|
||||||
"failed " << qualify_assertions_failed <<
|
"failed " << qualify_assertions_failed <<
|
||||||
pluralise( totals.assertions.failed, "assertion" ) << ".";
|
pluralise( totals.assertions.failed, "assertion" ) << '.';
|
||||||
}
|
}
|
||||||
else if( totals.assertions.total() == 0 ) {
|
else if( totals.assertions.total() == 0 ) {
|
||||||
stream <<
|
stream <<
|
||||||
@@ -282,14 +282,14 @@ namespace Catch {
|
|||||||
Colour colour( Colour::ResultError );
|
Colour colour( Colour::ResultError );
|
||||||
stream <<
|
stream <<
|
||||||
"Failed " << pluralise( totals.testCases.failed, "test case" ) << ", "
|
"Failed " << pluralise( totals.testCases.failed, "test case" ) << ", "
|
||||||
"failed " << pluralise( totals.assertions.failed, "assertion" ) << ".";
|
"failed " << pluralise( totals.assertions.failed, "assertion" ) << '.';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Colour colour( Colour::ResultSuccess );
|
Colour colour( Colour::ResultSuccess );
|
||||||
stream <<
|
stream <<
|
||||||
"Passed " << bothOrAll( totals.testCases.passed )
|
"Passed " << bothOrAll( totals.testCases.passed )
|
||||||
<< pluralise( totals.testCases.passed, "test case" ) <<
|
<< pluralise( totals.testCases.passed, "test case" ) <<
|
||||||
" with " << pluralise( totals.assertions.passed, "assertion" ) << ".";
|
" with " << pluralise( totals.assertions.passed, "assertion" ) << '.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -27,7 +27,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
|
virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
|
||||||
stream << "No test cases matched '" << spec << "'" << std::endl;
|
stream << "No test cases matched '" << spec << '\'' << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {
|
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {
|
||||||
@@ -69,12 +69,12 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
if( m_headerPrinted ) {
|
if( m_headerPrinted ) {
|
||||||
if( m_config->showDurations() == ShowDurations::Always )
|
if( m_config->showDurations() == ShowDurations::Always )
|
||||||
stream << "Completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
|
stream << "Completed in " << _sectionStats.durationInSeconds << 's' << std::endl;
|
||||||
m_headerPrinted = false;
|
m_headerPrinted = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if( m_config->showDurations() == ShowDurations::Always )
|
if( m_config->showDurations() == ShowDurations::Always )
|
||||||
stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
|
stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << 's' << std::endl;
|
||||||
}
|
}
|
||||||
StreamingReporterBase::sectionEnded( _sectionStats );
|
StreamingReporterBase::sectionEnded( _sectionStats );
|
||||||
}
|
}
|
||||||
@@ -88,7 +88,7 @@ namespace Catch {
|
|||||||
printSummaryDivider();
|
printSummaryDivider();
|
||||||
stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
|
stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
|
||||||
printTotals( _testGroupStats.totals );
|
printTotals( _testGroupStats.totals );
|
||||||
stream << "\n" << std::endl;
|
stream << '\n' << std::endl;
|
||||||
}
|
}
|
||||||
StreamingReporterBase::testGroupEnded( _testGroupStats );
|
StreamingReporterBase::testGroupEnded( _testGroupStats );
|
||||||
}
|
}
|
||||||
@@ -180,13 +180,13 @@ namespace Catch {
|
|||||||
printSourceInfo();
|
printSourceInfo();
|
||||||
if( stats.totals.assertions.total() > 0 ) {
|
if( stats.totals.assertions.total() > 0 ) {
|
||||||
if( result.isOk() )
|
if( result.isOk() )
|
||||||
stream << "\n";
|
stream << '\n';
|
||||||
printResultType();
|
printResultType();
|
||||||
printOriginalExpression();
|
printOriginalExpression();
|
||||||
printReconstructedExpression();
|
printReconstructedExpression();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
stream << "\n";
|
stream << '\n';
|
||||||
}
|
}
|
||||||
printMessage();
|
printMessage();
|
||||||
}
|
}
|
||||||
@@ -203,25 +203,25 @@ namespace Catch {
|
|||||||
Colour colourGuard( Colour::OriginalExpression );
|
Colour colourGuard( Colour::OriginalExpression );
|
||||||
stream << " ";
|
stream << " ";
|
||||||
stream << result.getExpressionInMacro();
|
stream << result.getExpressionInMacro();
|
||||||
stream << "\n";
|
stream << '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void printReconstructedExpression() const {
|
void printReconstructedExpression() const {
|
||||||
if( result.hasExpandedExpression() ) {
|
if( result.hasExpandedExpression() ) {
|
||||||
stream << "with expansion:\n";
|
stream << "with expansion:\n";
|
||||||
Colour colourGuard( Colour::ReconstructedExpression );
|
Colour colourGuard( Colour::ReconstructedExpression );
|
||||||
stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << "\n";
|
stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void printMessage() const {
|
void printMessage() const {
|
||||||
if( !messageLabel.empty() )
|
if( !messageLabel.empty() )
|
||||||
stream << messageLabel << ":" << "\n";
|
stream << messageLabel << ':' << '\n';
|
||||||
for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
|
for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
|
||||||
it != itEnd;
|
it != itEnd;
|
||||||
++it ) {
|
++it ) {
|
||||||
// If this assertion is a warning ignore any INFO messages
|
// If this assertion is a warning ignore any INFO messages
|
||||||
if( printInfoMessages || it->type != ResultWas::Info )
|
if( printInfoMessages || it->type != ResultWas::Info )
|
||||||
stream << Text( it->message, TextAttributes().setIndent(2) ) << "\n";
|
stream << Text( it->message, TextAttributes().setIndent(2) ) << '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void printSourceInfo() const {
|
void printSourceInfo() const {
|
||||||
@@ -253,7 +253,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void lazyPrintRunInfo() {
|
void lazyPrintRunInfo() {
|
||||||
stream << "\n" << getLineOfChars<'~'>() << "\n";
|
stream << '\n' << getLineOfChars<'~'>() << '\n';
|
||||||
Colour colour( Colour::SecondaryText );
|
Colour colour( Colour::SecondaryText );
|
||||||
stream << currentTestRunInfo->name
|
stream << currentTestRunInfo->name
|
||||||
<< " is a Catch v" << libraryVersion << " host application.\n"
|
<< " is a Catch v" << libraryVersion << " host application.\n"
|
||||||
@@ -287,19 +287,19 @@ namespace Catch {
|
|||||||
SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
|
SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
|
||||||
|
|
||||||
if( !lineInfo.empty() ){
|
if( !lineInfo.empty() ){
|
||||||
stream << getLineOfChars<'-'>() << "\n";
|
stream << getLineOfChars<'-'>() << '\n';
|
||||||
Colour colourGuard( Colour::FileName );
|
Colour colourGuard( Colour::FileName );
|
||||||
stream << lineInfo << "\n";
|
stream << lineInfo << '\n';
|
||||||
}
|
}
|
||||||
stream << getLineOfChars<'.'>() << "\n" << std::endl;
|
stream << getLineOfChars<'.'>() << '\n' << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void printClosedHeader( std::string const& _name ) {
|
void printClosedHeader( std::string const& _name ) {
|
||||||
printOpenHeader( _name );
|
printOpenHeader( _name );
|
||||||
stream << getLineOfChars<'.'>() << "\n";
|
stream << getLineOfChars<'.'>() << '\n';
|
||||||
}
|
}
|
||||||
void printOpenHeader( std::string const& _name ) {
|
void printOpenHeader( std::string const& _name ) {
|
||||||
stream << getLineOfChars<'-'>() << "\n";
|
stream << getLineOfChars<'-'>() << '\n';
|
||||||
{
|
{
|
||||||
Colour colourGuard( Colour::Headers );
|
Colour colourGuard( Colour::Headers );
|
||||||
printHeaderString( _name );
|
printHeaderString( _name );
|
||||||
@@ -316,7 +316,7 @@ namespace Catch {
|
|||||||
i = 0;
|
i = 0;
|
||||||
stream << Text( _string, TextAttributes()
|
stream << Text( _string, TextAttributes()
|
||||||
.setIndent( indent+i)
|
.setIndent( indent+i)
|
||||||
.setInitialIndent( indent ) ) << "\n";
|
.setInitialIndent( indent ) ) << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SummaryColumn {
|
struct SummaryColumn {
|
||||||
@@ -331,9 +331,9 @@ namespace Catch {
|
|||||||
std::string row = oss.str();
|
std::string row = oss.str();
|
||||||
for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {
|
for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {
|
||||||
while( it->size() < row.size() )
|
while( it->size() < row.size() )
|
||||||
*it = " " + *it;
|
*it = ' ' + *it;
|
||||||
while( it->size() > row.size() )
|
while( it->size() > row.size() )
|
||||||
row = " " + row;
|
row = ' ' + row;
|
||||||
}
|
}
|
||||||
rows.push_back( row );
|
rows.push_back( row );
|
||||||
return *this;
|
return *this;
|
||||||
@@ -353,8 +353,8 @@ namespace Catch {
|
|||||||
stream << Colour( Colour::ResultSuccess ) << "All tests passed";
|
stream << Colour( Colour::ResultSuccess ) << "All tests passed";
|
||||||
stream << " ("
|
stream << " ("
|
||||||
<< pluralise( totals.assertions.passed, "assertion" ) << " in "
|
<< pluralise( totals.assertions.passed, "assertion" ) << " in "
|
||||||
<< pluralise( totals.testCases.passed, "test case" ) << ")"
|
<< pluralise( totals.testCases.passed, "test case" ) << ')'
|
||||||
<< "\n";
|
<< '\n';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
@@ -389,10 +389,10 @@ namespace Catch {
|
|||||||
else if( value != "0" ) {
|
else if( value != "0" ) {
|
||||||
stream << Colour( Colour::LightGrey ) << " | ";
|
stream << Colour( Colour::LightGrey ) << " | ";
|
||||||
stream << Colour( it->colour )
|
stream << Colour( it->colour )
|
||||||
<< value << " " << it->label;
|
<< value << ' ' << it->label;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stream << "\n";
|
stream << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::size_t makeRatio( std::size_t number, std::size_t total ) {
|
static std::size_t makeRatio( std::size_t number, std::size_t total ) {
|
||||||
@@ -428,10 +428,10 @@ namespace Catch {
|
|||||||
else {
|
else {
|
||||||
stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );
|
stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );
|
||||||
}
|
}
|
||||||
stream << "\n";
|
stream << '\n';
|
||||||
}
|
}
|
||||||
void printSummaryDivider() {
|
void printSummaryDivider() {
|
||||||
stream << getLineOfChars<'-'>() << "\n";
|
stream << getLineOfChars<'-'>() << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -146,7 +146,7 @@ namespace Catch {
|
|||||||
SectionNode const& sectionNode ) {
|
SectionNode const& sectionNode ) {
|
||||||
std::string name = trim( sectionNode.stats.sectionInfo.name );
|
std::string name = trim( sectionNode.stats.sectionInfo.name );
|
||||||
if( !rootName.empty() )
|
if( !rootName.empty() )
|
||||||
name = rootName + "/" + name;
|
name = rootName + '/' + name;
|
||||||
|
|
||||||
if( !sectionNode.assertions.empty() ||
|
if( !sectionNode.assertions.empty() ||
|
||||||
!sectionNode.stdOut.empty() ||
|
!sectionNode.stdOut.empty() ||
|
||||||
@@ -224,14 +224,14 @@ namespace Catch {
|
|||||||
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
if( !result.getMessage().empty() )
|
if( !result.getMessage().empty() )
|
||||||
oss << result.getMessage() << "\n";
|
oss << result.getMessage() << '\n';
|
||||||
for( std::vector<MessageInfo>::const_iterator
|
for( std::vector<MessageInfo>::const_iterator
|
||||||
it = stats.infoMessages.begin(),
|
it = stats.infoMessages.begin(),
|
||||||
itEnd = stats.infoMessages.end();
|
itEnd = stats.infoMessages.end();
|
||||||
it != itEnd;
|
it != itEnd;
|
||||||
++it )
|
++it )
|
||||||
if( it->type == ResultWas::Info )
|
if( it->type == ResultWas::Info )
|
||||||
oss << it->message << "\n";
|
oss << it->message << '\n';
|
||||||
|
|
||||||
oss << "at " << result.getSourceInfo();
|
oss << "at " << result.getSourceInfo();
|
||||||
xml.writeText( oss.str(), false );
|
xml.writeText( oss.str(), false );
|
||||||
|
@@ -118,11 +118,11 @@ public: // IStreamingReporter
|
|||||||
++it )
|
++it )
|
||||||
(*it)->skipTest( testInfo );
|
(*it)->skipTest( testInfo );
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual MultipleReporters* tryAsMulti() CATCH_OVERRIDE {
|
virtual MultipleReporters* tryAsMulti() CATCH_OVERRIDE {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter ) {
|
Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter ) {
|
||||||
|
@@ -96,7 +96,7 @@ namespace Catch {
|
|||||||
if( assertionResult.hasExpression() ) {
|
if( assertionResult.hasExpression() ) {
|
||||||
m_xml.startElement( "Expression" )
|
m_xml.startElement( "Expression" )
|
||||||
.writeAttribute( "success", assertionResult.succeeded() )
|
.writeAttribute( "success", assertionResult.succeeded() )
|
||||||
.writeAttribute( "type", assertionResult.getTestMacroName() )
|
.writeAttribute( "type", assertionResult.getTestMacroName() )
|
||||||
.writeAttribute( "filename", assertionResult.getSourceInfo().file )
|
.writeAttribute( "filename", assertionResult.getSourceInfo().file )
|
||||||
.writeAttribute( "line", assertionResult.getSourceInfo().line );
|
.writeAttribute( "line", assertionResult.getSourceInfo().line );
|
||||||
|
|
||||||
|
9
projects/Benchmark/BenchMain.cpp
Normal file
9
projects/Benchmark/BenchMain.cpp
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
* Created by Martin on 16/01/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)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CATCH_CONFIG_MAIN
|
||||||
|
#include "catch.hpp"
|
46
projects/Benchmark/StringificationBench.cpp
Normal file
46
projects/Benchmark/StringificationBench.cpp
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Created by Martin on 16/01/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"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
TEST_CASE("Successful tests -- REQUIRE", "[Success]") {
|
||||||
|
const size_t sz = 1 * 1024 * 1024;
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<size_t> vec; vec.reserve(sz);
|
||||||
|
for (size_t i = 0; i < sz; ++i){
|
||||||
|
vec.push_back(i);
|
||||||
|
REQUIRE(vec.back() == i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
TEST_CASE("Successful tests -- CHECK", "[Success]") {
|
||||||
|
const size_t sz = 1 * 1024 * 1024;
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<size_t> vec; vec.reserve(sz);
|
||||||
|
for (size_t i = 0; i < sz; ++i){
|
||||||
|
vec.push_back(i);
|
||||||
|
CHECK(vec.back() == i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
TEST_CASE("Unsuccessful tests -- CHECK", "[Failure]") {
|
||||||
|
const size_t sz = 1024 * 1024;
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<size_t> vec; vec.reserve(sz);
|
||||||
|
for (size_t i = 0; i < sz; ++i){
|
||||||
|
vec.push_back(i);
|
||||||
|
CHECK(vec.size() == i);
|
||||||
|
}
|
||||||
|
}
|
4
projects/Benchmark/readme.txt
Normal file
4
projects/Benchmark/readme.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
This is very much a work in progress.
|
||||||
|
The past results are standardized to a developer's machine,
|
||||||
|
the benchmarking script is basic and there are only 3 benchmarks,
|
||||||
|
but this should get better in time. For now, at least there is something to go by.
|
@@ -0,0 +1,3 @@
|
|||||||
|
Successful tests -- CHECK: median: 3.38116 (s), stddev: 0.11567366292001534 (s)
|
||||||
|
Successful tests -- REQUIRE: median: 3.479955 (s), stddev: 0.16295972890734556 (s)
|
||||||
|
Unsuccessful tests -- CHECK: median: 1.966895 (s), stddev: 0.06323488524716572 (s)
|
@@ -0,0 +1,3 @@
|
|||||||
|
Successful tests -- CHECK: median: 1.30312 (s), stddev: 0.08759818557862176 (s)
|
||||||
|
Successful tests -- REQUIRE: median: 1.341535 (s), stddev: 0.1479193390143576 (s)
|
||||||
|
Unsuccessful tests -- CHECK: median: 1.967755 (s), stddev: 0.07921104121269959 (s)
|
@@ -0,0 +1,3 @@
|
|||||||
|
Successful tests -- CHECK: median: 1.2982 (s), stddev: 0.019540648829214084 (s)
|
||||||
|
Successful tests -- REQUIRE: median: 1.30102 (s), stddev: 0.014758430547392974 (s)
|
||||||
|
Unsuccessful tests -- CHECK: median: 15.520199999999999 (s), stddev: 0.09536359426485094 (s)
|
@@ -0,0 +1,3 @@
|
|||||||
|
Successful tests -- CHECK: median: 0.7689014999999999 (s), stddev: 0.02127512078801068 (s)
|
||||||
|
Successful tests -- REQUIRE: median: 0.772845 (s), stddev: 0.03011638381365052 (s)
|
||||||
|
Unsuccessful tests -- CHECK: median: 15.49 (s), stddev: 0.536088571143903 (s)
|
@@ -0,0 +1,3 @@
|
|||||||
|
Successful tests -- CHECK: median: 0.775769 (s), stddev: 0.014802129132136525 (s)
|
||||||
|
Successful tests -- REQUIRE: median: 0.785235 (s), stddev: 0.03532672836834896 (s)
|
||||||
|
Unsuccessful tests -- CHECK: median: 15.156600000000001 (s), stddev: 0.2832375673450742 (s)
|
@@ -140,3 +140,48 @@ TEST_CASE( "Approximate PI", "[Approx][PI]" )
|
|||||||
REQUIRE( divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 ) );
|
REQUIRE( divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 ) );
|
||||||
REQUIRE( divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 ) );
|
REQUIRE( divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
|
||||||
|
class StrongDoubleTypedef
|
||||||
|
{
|
||||||
|
double d_ = 0.0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit StrongDoubleTypedef(double d) : d_(d) {}
|
||||||
|
explicit operator double() const { return d_; }
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::ostream& operator<<( std::ostream& os, StrongDoubleTypedef td ) {
|
||||||
|
return os << "StrongDoubleTypedef(" << static_cast<double>(td) << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE
|
||||||
|
(
|
||||||
|
"Comparison with explicitly convertible types",
|
||||||
|
"[Approx]"
|
||||||
|
)
|
||||||
|
{
|
||||||
|
StrongDoubleTypedef td(10.0);
|
||||||
|
|
||||||
|
REQUIRE(td == Approx(10.0));
|
||||||
|
REQUIRE(Approx(10.0) == td);
|
||||||
|
|
||||||
|
REQUIRE(td != Approx(11.0));
|
||||||
|
REQUIRE(Approx(11.0) != td);
|
||||||
|
|
||||||
|
REQUIRE(td <= Approx(10.0));
|
||||||
|
REQUIRE(td <= Approx(11.0));
|
||||||
|
REQUIRE(Approx(10.0) <= td);
|
||||||
|
REQUIRE(Approx(9.0) <= td);
|
||||||
|
|
||||||
|
REQUIRE(td >= Approx(9.0));
|
||||||
|
REQUIRE(td >= Approx(10.0));
|
||||||
|
REQUIRE(Approx(10.0) >= td);
|
||||||
|
REQUIRE(Approx(11.0) >= td);
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@@ -88,10 +88,10 @@ struct Fixture
|
|||||||
}
|
}
|
||||||
|
|
||||||
SCENARIO_METHOD(Fixture,
|
SCENARIO_METHOD(Fixture,
|
||||||
"BDD tests requiring Fixtures to provide commonly-accessed data or methods",
|
"BDD tests requiring Fixtures to provide commonly-accessed data or methods",
|
||||||
"[bdd][fixtures]") {
|
"[bdd][fixtures]") {
|
||||||
const int before(counter());
|
const int before(counter());
|
||||||
GIVEN("No operations precede me") {
|
GIVEN("No operations precede me") {
|
||||||
REQUIRE(before == 0);
|
REQUIRE(before == 0);
|
||||||
WHEN("We get the count") {
|
WHEN("We get the count") {
|
||||||
const int after(counter());
|
const int after(counter());
|
||||||
|
@@ -584,11 +584,11 @@ MiscTests.cpp:<line number>: FAILED:
|
|||||||
CHECK( s1 == s2 )
|
CHECK( s1 == s2 )
|
||||||
with expansion:
|
with expansion:
|
||||||
"if ($b == 10) {
|
"if ($b == 10) {
|
||||||
$a= 20;
|
$a = 20;
|
||||||
}"
|
}"
|
||||||
==
|
==
|
||||||
"if ($b == 10) {
|
"if ($b == 10) {
|
||||||
$a = 20;
|
$a = 20;
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
|
|
||||||
@@ -613,8 +613,7 @@ due to unexpected exception with message:
|
|||||||
unexpected exception
|
unexpected exception
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
When unchecked exceptions are thrown during a CHECK the test should abort and
|
When unchecked exceptions are thrown during a CHECK the test should continue
|
||||||
fail
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
ExceptionTests.cpp:<line number>
|
ExceptionTests.cpp:<line number>
|
||||||
...............................................................................
|
...............................................................................
|
||||||
@@ -830,6 +829,6 @@ with expansion:
|
|||||||
"first" == "second"
|
"first" == "second"
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
test cases: 159 | 115 passed | 42 failed | 2 failed as expected
|
test cases: 157 | 113 passed | 42 failed | 2 failed as expected
|
||||||
assertions: 909 | 813 passed | 78 failed | 18 failed as expected
|
assertions: 913 | 817 passed | 78 failed | 18 failed as expected
|
||||||
|
|
||||||
|
@@ -2932,13 +2932,9 @@ TestMain.cpp:<line number>
|
|||||||
|
|
||||||
TestMain.cpp:<line number>:
|
TestMain.cpp:<line number>:
|
||||||
PASSED:
|
PASSED:
|
||||||
CHECK( Text( "abcdef\n", TextAttributes().setWidth( 10 ) ).toString() == "abcdef\n" )
|
CHECK( Text( "abcdef\n", TextAttributes().setWidth( 10 ) ).toString() == "abcdef" )
|
||||||
with expansion:
|
with expansion:
|
||||||
"abcdef
|
"abcdef" == "abcdef"
|
||||||
"
|
|
||||||
==
|
|
||||||
"abcdef
|
|
||||||
"
|
|
||||||
|
|
||||||
TestMain.cpp:<line number>:
|
TestMain.cpp:<line number>:
|
||||||
PASSED:
|
PASSED:
|
||||||
@@ -2948,13 +2944,19 @@ with expansion:
|
|||||||
|
|
||||||
TestMain.cpp:<line number>:
|
TestMain.cpp:<line number>:
|
||||||
PASSED:
|
PASSED:
|
||||||
CHECK( Text( "abcdef\n", TextAttributes().setWidth( 6 ) ).toString() == "abcdef\n" )
|
CHECK( Text( "abcdef\n", TextAttributes().setWidth( 6 ) ).toString() == "abcdef" )
|
||||||
with expansion:
|
with expansion:
|
||||||
"abcdef
|
"abcdef" == "abcdef"
|
||||||
"
|
|
||||||
|
TestMain.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
CHECK( Text( "abcdef\n", TextAttributes().setWidth( 5 ) ).toString() == "abcd-\nef" )
|
||||||
|
with expansion:
|
||||||
|
"abcd-
|
||||||
|
ef"
|
||||||
==
|
==
|
||||||
"abcdef
|
"abcd-
|
||||||
"
|
ef"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Long strings can be wrapped
|
Long strings can be wrapped
|
||||||
@@ -3024,24 +3026,107 @@ with expansion:
|
|||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Long strings can be wrapped
|
Long strings can be wrapped
|
||||||
With tabs
|
With wrap-before/ after characters
|
||||||
|
No wrapping
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
TestMain.cpp:<line number>
|
TestMain.cpp:<line number>
|
||||||
...............................................................................
|
...............................................................................
|
||||||
|
|
||||||
TestMain.cpp:<line number>:
|
TestMain.cpp:<line number>:
|
||||||
PASSED:
|
PASSED:
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 15 ) ).toString() == "one two three\n four\n five\n six" )
|
CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString )
|
||||||
with expansion:
|
with expansion:
|
||||||
"one two three
|
"one,two(three) <here>"
|
||||||
four
|
|
||||||
five
|
|
||||||
six"
|
|
||||||
==
|
==
|
||||||
"one two three
|
"one,two(three) <here>"
|
||||||
four
|
|
||||||
five
|
TestMain.cpp:<line number>:
|
||||||
six"
|
PASSED:
|
||||||
|
CHECK( Text( testString, TextAttributes().setWidth( 24 ) ).toString() == testString )
|
||||||
|
with expansion:
|
||||||
|
"one,two(three) <here>"
|
||||||
|
==
|
||||||
|
"one,two(three) <here>"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Long strings can be wrapped
|
||||||
|
With wrap-before/ after characters
|
||||||
|
Wrap before
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
TestMain.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
TestMain.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
CHECK( Text( testString, TextAttributes().setWidth( 11 ) ).toString() == "one,two\n(three)\n<here>" )
|
||||||
|
with expansion:
|
||||||
|
"one,two
|
||||||
|
(three)
|
||||||
|
<here>"
|
||||||
|
==
|
||||||
|
"one,two
|
||||||
|
(three)
|
||||||
|
<here>"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Long strings can be wrapped
|
||||||
|
With wrap-before/ after characters
|
||||||
|
Wrap after
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
TestMain.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
TestMain.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one,\ntwo\n(thre-\ne)\n<here>" )
|
||||||
|
with expansion:
|
||||||
|
"one,
|
||||||
|
two
|
||||||
|
(thre-
|
||||||
|
e)
|
||||||
|
<here>"
|
||||||
|
==
|
||||||
|
"one,
|
||||||
|
two
|
||||||
|
(thre-
|
||||||
|
e)
|
||||||
|
<here>"
|
||||||
|
|
||||||
|
TestMain.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
CHECK( Text( testString, TextAttributes().setWidth( 5 ) ).toString() == "one,\ntwo\n(thr-\nee)\n<her-\ne>" )
|
||||||
|
with expansion:
|
||||||
|
"one,
|
||||||
|
two
|
||||||
|
(thr-
|
||||||
|
ee)
|
||||||
|
<her-
|
||||||
|
e>"
|
||||||
|
==
|
||||||
|
"one,
|
||||||
|
two
|
||||||
|
(thr-
|
||||||
|
ee)
|
||||||
|
<her-
|
||||||
|
e>"
|
||||||
|
|
||||||
|
TestMain.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
CHECK( Text( testString, TextAttributes().setWidth( 4 ) ).toString() == "one,\ntwo\n(th-\nree)\n<he-\nre>" )
|
||||||
|
with expansion:
|
||||||
|
"one,
|
||||||
|
two
|
||||||
|
(th-
|
||||||
|
ree)
|
||||||
|
<he-
|
||||||
|
re>"
|
||||||
|
==
|
||||||
|
"one,
|
||||||
|
two
|
||||||
|
(th-
|
||||||
|
ree)
|
||||||
|
<he-
|
||||||
|
re>"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Long text is truncted
|
Long text is truncted
|
||||||
@@ -6458,11 +6543,11 @@ MiscTests.cpp:<line number>: FAILED:
|
|||||||
CHECK( s1 == s2 )
|
CHECK( s1 == s2 )
|
||||||
with expansion:
|
with expansion:
|
||||||
"if ($b == 10) {
|
"if ($b == 10) {
|
||||||
$a= 20;
|
$a = 20;
|
||||||
}"
|
}"
|
||||||
==
|
==
|
||||||
"if ($b == 10) {
|
"if ($b == 10) {
|
||||||
$a = 20;
|
$a = 20;
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
|
|
||||||
@@ -6478,36 +6563,32 @@ PASSED:
|
|||||||
CHECK_THAT( what, Contains( "[@zzz]" ) )
|
CHECK_THAT( what, Contains( "[@zzz]" ) )
|
||||||
with expansion:
|
with expansion:
|
||||||
"error: tag alias, "[@zzz]" already registered.
|
"error: tag alias, "[@zzz]" already registered.
|
||||||
First seen at file:2
|
First seen at file:2
|
||||||
Redefined at file:10" contains: "
|
Redefined at file:10" contains: "[@zzz]"
|
||||||
[@zzz]"
|
|
||||||
|
|
||||||
TagAliasTests.cpp:<line number>:
|
TagAliasTests.cpp:<line number>:
|
||||||
PASSED:
|
PASSED:
|
||||||
CHECK_THAT( what, Contains( "file" ) )
|
CHECK_THAT( what, Contains( "file" ) )
|
||||||
with expansion:
|
with expansion:
|
||||||
"error: tag alias, "[@zzz]" already registered.
|
"error: tag alias, "[@zzz]" already registered.
|
||||||
First seen at file:2
|
First seen at file:2
|
||||||
Redefined at file:10" contains:
|
Redefined at file:10" contains: "file"
|
||||||
"file"
|
|
||||||
|
|
||||||
TagAliasTests.cpp:<line number>:
|
TagAliasTests.cpp:<line number>:
|
||||||
PASSED:
|
PASSED:
|
||||||
CHECK_THAT( what, Contains( "2" ) )
|
CHECK_THAT( what, Contains( "2" ) )
|
||||||
with expansion:
|
with expansion:
|
||||||
"error: tag alias, "[@zzz]" already registered.
|
"error: tag alias, "[@zzz]" already registered.
|
||||||
First seen at file:2
|
First seen at file:2
|
||||||
Redefined at file:10" contains:
|
Redefined at file:10" contains: "2"
|
||||||
"2"
|
|
||||||
|
|
||||||
TagAliasTests.cpp:<line number>:
|
TagAliasTests.cpp:<line number>:
|
||||||
PASSED:
|
PASSED:
|
||||||
CHECK_THAT( what, Contains( "10" ) )
|
CHECK_THAT( what, Contains( "10" ) )
|
||||||
with expansion:
|
with expansion:
|
||||||
"error: tag alias, "[@zzz]" already registered.
|
"error: tag alias, "[@zzz]" already registered.
|
||||||
First seen at file:2
|
First seen at file:2
|
||||||
Redefined at file:10" contains:
|
Redefined at file:10" contains: "10"
|
||||||
"10"
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Tag alias can be registered against tag patterns
|
Tag alias can be registered against tag patterns
|
||||||
@@ -7701,8 +7782,7 @@ due to unexpected exception with message:
|
|||||||
unexpected exception
|
unexpected exception
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
When unchecked exceptions are thrown during a CHECK the test should abort and
|
When unchecked exceptions are thrown during a CHECK the test should continue
|
||||||
fail
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
ExceptionTests.cpp:<line number>
|
ExceptionTests.cpp:<line number>
|
||||||
...............................................................................
|
...............................................................................
|
||||||
@@ -8676,32 +8756,6 @@ with expansion:
|
|||||||
==
|
==
|
||||||
"{ StringMaker<has_maker> }"
|
"{ StringMaker<has_maker> }"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
toString( vectors<has_maker_and_toString )
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
ToStringWhich.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
ToStringWhich.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( Catch::toString( v ) == "{ StringMaker<has_maker_and_toString> }" )
|
|
||||||
with expansion:
|
|
||||||
"{ StringMaker<has_maker_and_toString> }"
|
|
||||||
==
|
|
||||||
"{ StringMaker<has_maker_and_toString> }"
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
toString( vectors<has_toString )
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
ToStringWhich.cpp:<line number>
|
|
||||||
...............................................................................
|
|
||||||
|
|
||||||
ToStringWhich.cpp:<line number>:
|
|
||||||
PASSED:
|
|
||||||
REQUIRE( Catch::toString( v ) == "{ {?} }" )
|
|
||||||
with expansion:
|
|
||||||
"{ {?} }" == "{ {?} }"
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
toString(enum w/operator<<)
|
toString(enum w/operator<<)
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -8971,6 +9025,6 @@ MiscTests.cpp:<line number>:
|
|||||||
PASSED:
|
PASSED:
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
test cases: 159 | 114 passed | 43 failed | 2 failed as expected
|
test cases: 157 | 112 passed | 43 failed | 2 failed as expected
|
||||||
assertions: 911 | 813 passed | 80 failed | 18 failed as expected
|
assertions: 915 | 817 passed | 80 failed | 18 failed as expected
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.1" encoding="UTF-8"?>
|
<?xml version="1.1" encoding="UTF-8"?>
|
||||||
<testsuites>
|
<testsuites>
|
||||||
<testsuite name="<exe-name>" errors="13" failures="68" tests="912" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
<testsuite name="<exe-name>" errors="13" failures="68" tests="916" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||||
<testcase classname="global" name="# A test name that starts with a #" time="{duration}"/>
|
<testcase classname="global" name="# A test name that starts with a #" time="{duration}"/>
|
||||||
<testcase classname="global" name="'Not' checks that should fail" time="{duration}">
|
<testcase classname="global" name="'Not' checks that should fail" time="{duration}">
|
||||||
<failure message="false != false" type="CHECK">
|
<failure message="false != false" type="CHECK">
|
||||||
@@ -242,7 +242,9 @@ ConditionTests.cpp:<line number>
|
|||||||
<testcase classname="Long strings can be wrapped" name="With newlines/Trailing newline" time="{duration}"/>
|
<testcase classname="Long strings can be wrapped" name="With newlines/Trailing newline" time="{duration}"/>
|
||||||
<testcase classname="Long strings can be wrapped" name="With newlines/Wrapped once" time="{duration}"/>
|
<testcase classname="Long strings can be wrapped" name="With newlines/Wrapped once" time="{duration}"/>
|
||||||
<testcase classname="Long strings can be wrapped" name="With newlines/Wrapped twice" time="{duration}"/>
|
<testcase classname="Long strings can be wrapped" name="With newlines/Wrapped twice" time="{duration}"/>
|
||||||
<testcase classname="Long strings can be wrapped" name="With tabs" time="{duration}"/>
|
<testcase classname="Long strings can be wrapped" name="With wrap-before/ after characters/No wrapping" time="{duration}"/>
|
||||||
|
<testcase classname="Long strings can be wrapped" name="With wrap-before/ after characters/Wrap before" time="{duration}"/>
|
||||||
|
<testcase classname="Long strings can be wrapped" name="With wrap-before/ after characters/Wrap after" time="{duration}"/>
|
||||||
<testcase classname="global" name="Long text is truncted" time="{duration}"/>
|
<testcase classname="global" name="Long text is truncted" time="{duration}"/>
|
||||||
<testcase classname="global" name="ManuallyRegistered" time="{duration}"/>
|
<testcase classname="global" name="ManuallyRegistered" time="{duration}"/>
|
||||||
<testcase classname="global" name="Matchers can be (AllOf) composed with the && operator" time="{duration}"/>
|
<testcase classname="global" name="Matchers can be (AllOf) composed with the && operator" time="{duration}"/>
|
||||||
@@ -500,7 +502,7 @@ unexpected exception
|
|||||||
ExceptionTests.cpp:<line number>
|
ExceptionTests.cpp:<line number>
|
||||||
</error>
|
</error>
|
||||||
</testcase>
|
</testcase>
|
||||||
<testcase classname="global" name="When unchecked exceptions are thrown during a CHECK the test should abort and fail" time="{duration}">
|
<testcase classname="global" name="When unchecked exceptions are thrown during a CHECK the test should continue" time="{duration}">
|
||||||
<error message="thisThrows() == 0" type="CHECK">
|
<error message="thisThrows() == 0" type="CHECK">
|
||||||
expected exception
|
expected exception
|
||||||
ExceptionTests.cpp:<line number>
|
ExceptionTests.cpp:<line number>
|
||||||
@@ -652,8 +654,6 @@ TrickyTests.cpp:<line number>
|
|||||||
<testcase classname="global" name="toString( has_maker_and_toString )" time="{duration}"/>
|
<testcase classname="global" name="toString( has_maker_and_toString )" time="{duration}"/>
|
||||||
<testcase classname="global" name="toString( has_toString )" time="{duration}"/>
|
<testcase classname="global" name="toString( has_toString )" time="{duration}"/>
|
||||||
<testcase classname="global" name="toString( vectors<has_maker )" time="{duration}"/>
|
<testcase classname="global" name="toString( vectors<has_maker )" time="{duration}"/>
|
||||||
<testcase classname="global" name="toString( vectors<has_maker_and_toString )" time="{duration}"/>
|
|
||||||
<testcase classname="global" name="toString( vectors<has_toString )" time="{duration}"/>
|
|
||||||
<testcase classname="global" name="toString(enum w/operator<<)" time="{duration}"/>
|
<testcase classname="global" name="toString(enum w/operator<<)" time="{duration}"/>
|
||||||
<testcase classname="global" name="toString(enum)" time="{duration}"/>
|
<testcase classname="global" name="toString(enum)" time="{duration}"/>
|
||||||
<testcase classname="global" name="vector<int> -> toString" time="{duration}"/>
|
<testcase classname="global" name="vector<int> -> toString" time="{duration}"/>
|
||||||
|
@@ -2987,14 +2987,10 @@ three four"
|
|||||||
<Section name="Trailing newline">
|
<Section name="Trailing newline">
|
||||||
<Expression success="true" type="CHECK" filename="projects/<exe-name>/TestMain.cpp" >
|
<Expression success="true" type="CHECK" filename="projects/<exe-name>/TestMain.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
Text( "abcdef\n", TextAttributes().setWidth( 10 ) ).toString() == "abcdef\n"
|
Text( "abcdef\n", TextAttributes().setWidth( 10 ) ).toString() == "abcdef"
|
||||||
</Original>
|
</Original>
|
||||||
<Expanded>
|
<Expanded>
|
||||||
"abcdef
|
"abcdef" == "abcdef"
|
||||||
"
|
|
||||||
==
|
|
||||||
"abcdef
|
|
||||||
"
|
|
||||||
</Expanded>
|
</Expanded>
|
||||||
</Expression>
|
</Expression>
|
||||||
<Expression success="true" type="CHECK" filename="projects/<exe-name>/TestMain.cpp" >
|
<Expression success="true" type="CHECK" filename="projects/<exe-name>/TestMain.cpp" >
|
||||||
@@ -3007,19 +3003,27 @@ three four"
|
|||||||
</Expression>
|
</Expression>
|
||||||
<Expression success="true" type="CHECK" filename="projects/<exe-name>/TestMain.cpp" >
|
<Expression success="true" type="CHECK" filename="projects/<exe-name>/TestMain.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
Text( "abcdef\n", TextAttributes().setWidth( 6 ) ).toString() == "abcdef\n"
|
Text( "abcdef\n", TextAttributes().setWidth( 6 ) ).toString() == "abcdef"
|
||||||
</Original>
|
</Original>
|
||||||
<Expanded>
|
<Expanded>
|
||||||
"abcdef
|
"abcdef" == "abcdef"
|
||||||
"
|
|
||||||
==
|
|
||||||
"abcdef
|
|
||||||
"
|
|
||||||
</Expanded>
|
</Expanded>
|
||||||
</Expression>
|
</Expression>
|
||||||
<OverallResults successes="3" failures="0" expectedFailures="0"/>
|
<Expression success="true" type="CHECK" filename="projects/<exe-name>/TestMain.cpp" >
|
||||||
|
<Original>
|
||||||
|
Text( "abcdef\n", TextAttributes().setWidth( 5 ) ).toString() == "abcd-\nef"
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
"abcd-
|
||||||
|
ef"
|
||||||
|
==
|
||||||
|
"abcd-
|
||||||
|
ef"
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<OverallResults successes="4" failures="0" expectedFailures="0"/>
|
||||||
</Section>
|
</Section>
|
||||||
<OverallResults successes="3" failures="0" expectedFailures="0"/>
|
<OverallResults successes="4" failures="0" expectedFailures="0"/>
|
||||||
</Section>
|
</Section>
|
||||||
<Section name="With newlines">
|
<Section name="With newlines">
|
||||||
<Section name="Wrapped once">
|
<Section name="Wrapped once">
|
||||||
@@ -3091,25 +3095,116 @@ four"
|
|||||||
</Section>
|
</Section>
|
||||||
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
||||||
</Section>
|
</Section>
|
||||||
<Section name="With tabs">
|
<Section name="With wrap-before/ after characters">
|
||||||
<Expression success="true" type="CHECK" filename="projects/<exe-name>/TestMain.cpp" >
|
<Section name="No wrapping">
|
||||||
<Original>
|
<Expression success="true" type="CHECK" filename="projects/<exe-name>/TestMain.cpp" >
|
||||||
Text( testString, TextAttributes().setWidth( 15 ) ).toString() == "one two three\n four\n five\n six"
|
<Original>
|
||||||
</Original>
|
Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString
|
||||||
<Expanded>
|
</Original>
|
||||||
"one two three
|
<Expanded>
|
||||||
four
|
"one,two(three) <here>"
|
||||||
five
|
|
||||||
six"
|
|
||||||
==
|
==
|
||||||
"one two three
|
"one,two(three) <here>"
|
||||||
four
|
</Expanded>
|
||||||
five
|
</Expression>
|
||||||
six"
|
<Expression success="true" type="CHECK" filename="projects/<exe-name>/TestMain.cpp" >
|
||||||
</Expanded>
|
<Original>
|
||||||
</Expression>
|
Text( testString, TextAttributes().setWidth( 24 ) ).toString() == testString
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
"one,two(three) <here>"
|
||||||
|
==
|
||||||
|
"one,two(three) <here>"
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||||
|
</Section>
|
||||||
|
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||||
|
</Section>
|
||||||
|
<Section name="With wrap-before/ after characters">
|
||||||
|
<Section name="Wrap before">
|
||||||
|
<Expression success="true" type="CHECK" filename="projects/<exe-name>/TestMain.cpp" >
|
||||||
|
<Original>
|
||||||
|
Text( testString, TextAttributes().setWidth( 11 ) ).toString() == "one,two\n(three)\n<here>"
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
"one,two
|
||||||
|
(three)
|
||||||
|
<here>"
|
||||||
|
==
|
||||||
|
"one,two
|
||||||
|
(three)
|
||||||
|
<here>"
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
||||||
|
</Section>
|
||||||
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
||||||
</Section>
|
</Section>
|
||||||
|
<Section name="With wrap-before/ after characters">
|
||||||
|
<Section name="Wrap after">
|
||||||
|
<Expression success="true" type="CHECK" filename="projects/<exe-name>/TestMain.cpp" >
|
||||||
|
<Original>
|
||||||
|
Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one,\ntwo\n(thre-\ne)\n<here>"
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
"one,
|
||||||
|
two
|
||||||
|
(thre-
|
||||||
|
e)
|
||||||
|
<here>"
|
||||||
|
==
|
||||||
|
"one,
|
||||||
|
two
|
||||||
|
(thre-
|
||||||
|
e)
|
||||||
|
<here>"
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="CHECK" filename="projects/<exe-name>/TestMain.cpp" >
|
||||||
|
<Original>
|
||||||
|
Text( testString, TextAttributes().setWidth( 5 ) ).toString() == "one,\ntwo\n(thr-\nee)\n<her-\ne>"
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
"one,
|
||||||
|
two
|
||||||
|
(thr-
|
||||||
|
ee)
|
||||||
|
<her-
|
||||||
|
e>"
|
||||||
|
==
|
||||||
|
"one,
|
||||||
|
two
|
||||||
|
(thr-
|
||||||
|
ee)
|
||||||
|
<her-
|
||||||
|
e>"
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="CHECK" filename="projects/<exe-name>/TestMain.cpp" >
|
||||||
|
<Original>
|
||||||
|
Text( testString, TextAttributes().setWidth( 4 ) ).toString() == "one,\ntwo\n(th-\nree)\n<he-\nre>"
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
"one,
|
||||||
|
two
|
||||||
|
(th-
|
||||||
|
ree)
|
||||||
|
<he-
|
||||||
|
re>"
|
||||||
|
==
|
||||||
|
"one,
|
||||||
|
two
|
||||||
|
(th-
|
||||||
|
ree)
|
||||||
|
<he-
|
||||||
|
re>"
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<OverallResults successes="3" failures="0" expectedFailures="0"/>
|
||||||
|
</Section>
|
||||||
|
<OverallResults successes="3" failures="0" expectedFailures="0"/>
|
||||||
|
</Section>
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="Long text is truncted">
|
<TestCase name="Long text is truncted">
|
||||||
@@ -8183,7 +8278,7 @@ there"
|
|||||||
</Exception>
|
</Exception>
|
||||||
<OverallResult success="false"/>
|
<OverallResult success="false"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="When unchecked exceptions are thrown during a CHECK the test should abort and fail">
|
<TestCase name="When unchecked exceptions are thrown during a CHECK the test should continue">
|
||||||
<Expression success="false" type="CHECK" filename="projects/<exe-name>/ExceptionTests.cpp" >
|
<Expression success="false" type="CHECK" filename="projects/<exe-name>/ExceptionTests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
thisThrows() == 0
|
thisThrows() == 0
|
||||||
@@ -9151,30 +9246,6 @@ there"
|
|||||||
</Expression>
|
</Expression>
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="toString( vectors<has_maker_and_toString )">
|
|
||||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ToStringWhich.cpp" >
|
|
||||||
<Original>
|
|
||||||
Catch::toString( v ) == "{ StringMaker<has_maker_and_toString> }"
|
|
||||||
</Original>
|
|
||||||
<Expanded>
|
|
||||||
"{ StringMaker<has_maker_and_toString> }"
|
|
||||||
==
|
|
||||||
"{ StringMaker<has_maker_and_toString> }"
|
|
||||||
</Expanded>
|
|
||||||
</Expression>
|
|
||||||
<OverallResult success="true"/>
|
|
||||||
</TestCase>
|
|
||||||
<TestCase name="toString( vectors<has_toString )">
|
|
||||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ToStringWhich.cpp" >
|
|
||||||
<Original>
|
|
||||||
Catch::toString( v ) == "{ {?} }"
|
|
||||||
</Original>
|
|
||||||
<Expanded>
|
|
||||||
"{ {?} }" == "{ {?} }"
|
|
||||||
</Expanded>
|
|
||||||
</Expression>
|
|
||||||
<OverallResult success="true"/>
|
|
||||||
</TestCase>
|
|
||||||
<TestCase name="toString(enum w/operator<<)">
|
<TestCase name="toString(enum w/operator<<)">
|
||||||
<Expression success="true" type="CHECK" filename="projects/<exe-name>/EnumToString.cpp" >
|
<Expression success="true" type="CHECK" filename="projects/<exe-name>/EnumToString.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
@@ -9432,7 +9503,7 @@ there"
|
|||||||
</Section>
|
</Section>
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<OverallResults successes="813" failures="81" expectedFailures="18"/>
|
<OverallResults successes="817" failures="81" expectedFailures="18"/>
|
||||||
</Group>
|
</Group>
|
||||||
<OverallResults successes="813" failures="80" expectedFailures="18"/>
|
<OverallResults successes="817" failures="80" expectedFailures="18"/>
|
||||||
</Catch>
|
</Catch>
|
||||||
|
@@ -210,29 +210,29 @@ TEST_CASE( "Comparisons with int literals don't warn when mixing signed/ unsigne
|
|||||||
|
|
||||||
TEST_CASE( "comparisons between int variables", "" )
|
TEST_CASE( "comparisons between int variables", "" )
|
||||||
{
|
{
|
||||||
long long_var = 1L;
|
long long_var = 1L;
|
||||||
unsigned char unsigned_char_var = 1;
|
unsigned char unsigned_char_var = 1;
|
||||||
unsigned short unsigned_short_var = 1;
|
unsigned short unsigned_short_var = 1;
|
||||||
unsigned int unsigned_int_var = 1;
|
unsigned int unsigned_int_var = 1;
|
||||||
unsigned long unsigned_long_var = 1L;
|
unsigned long unsigned_long_var = 1L;
|
||||||
|
|
||||||
REQUIRE( long_var == unsigned_char_var );
|
REQUIRE( long_var == unsigned_char_var );
|
||||||
REQUIRE( long_var == unsigned_short_var );
|
REQUIRE( long_var == unsigned_short_var );
|
||||||
REQUIRE( long_var == unsigned_int_var );
|
REQUIRE( long_var == unsigned_int_var );
|
||||||
REQUIRE( long_var == unsigned_long_var );
|
REQUIRE( long_var == unsigned_long_var );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "comparisons between const int variables", "" )
|
TEST_CASE( "comparisons between const int variables", "" )
|
||||||
{
|
{
|
||||||
const unsigned char unsigned_char_var = 1;
|
const unsigned char unsigned_char_var = 1;
|
||||||
const unsigned short unsigned_short_var = 1;
|
const unsigned short unsigned_short_var = 1;
|
||||||
const unsigned int unsigned_int_var = 1;
|
const unsigned int unsigned_int_var = 1;
|
||||||
const unsigned long unsigned_long_var = 1L;
|
const unsigned long unsigned_long_var = 1L;
|
||||||
|
|
||||||
REQUIRE( unsigned_char_var == 1 );
|
REQUIRE( unsigned_char_var == 1 );
|
||||||
REQUIRE( unsigned_short_var == 1 );
|
REQUIRE( unsigned_short_var == 1 );
|
||||||
REQUIRE( unsigned_int_var == 1 );
|
REQUIRE( unsigned_int_var == 1 );
|
||||||
REQUIRE( unsigned_long_var == 1 );
|
REQUIRE( unsigned_long_var == 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Comparisons between unsigned ints and negative signed ints match c++ standard behaviour", "" )
|
TEST_CASE( "Comparisons between unsigned ints and negative signed ints match c++ standard behaviour", "" )
|
||||||
|
@@ -15,9 +15,9 @@ namespace
|
|||||||
{
|
{
|
||||||
inline int thisThrows()
|
inline int thisThrows()
|
||||||
{
|
{
|
||||||
if( Catch::alwaysTrue() )
|
if( Catch::alwaysTrue() )
|
||||||
throw std::domain_error( "expected exception" );
|
throw std::domain_error( "expected exception" );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int thisDoesntThrow()
|
int thisDoesntThrow()
|
||||||
@@ -26,60 +26,64 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "When checked exceptions are thrown they can be expected or unexpected", "" )
|
TEST_CASE( "When checked exceptions are thrown they can be expected or unexpected", "[!throws]" )
|
||||||
{
|
{
|
||||||
REQUIRE_THROWS_AS( thisThrows(), std::domain_error );
|
REQUIRE_THROWS_AS( thisThrows(), std::domain_error );
|
||||||
REQUIRE_NOTHROW( thisDoesntThrow() );
|
REQUIRE_NOTHROW( thisDoesntThrow() );
|
||||||
REQUIRE_THROWS( thisThrows() );
|
REQUIRE_THROWS( thisThrows() );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Expected exceptions that don't throw or unexpected exceptions fail the test", "[.][failing]" )
|
TEST_CASE( "Expected exceptions that don't throw or unexpected exceptions fail the test", "[.][failing][!throws]" )
|
||||||
{
|
{
|
||||||
CHECK_THROWS_AS( thisThrows(), std::string );
|
CHECK_THROWS_AS( thisThrows(), std::string );
|
||||||
CHECK_THROWS_AS( thisDoesntThrow(), std::domain_error );
|
CHECK_THROWS_AS( thisDoesntThrow(), std::domain_error );
|
||||||
CHECK_NOTHROW( thisThrows() );
|
CHECK_NOTHROW( thisThrows() );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "When unchecked exceptions are thrown directly they are always failures", "[.][failing]" )
|
TEST_CASE( "When unchecked exceptions are thrown directly they are always failures", "[.][failing][!throws]" )
|
||||||
{
|
{
|
||||||
if( Catch::alwaysTrue() )
|
if( Catch::alwaysTrue() )
|
||||||
throw std::domain_error( "unexpected exception" );
|
throw std::domain_error( "unexpected exception" );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "An unchecked exception reports the line of the last assertion", "[.][failing]" )
|
TEST_CASE( "An unchecked exception reports the line of the last assertion", "[.][failing][!throws]" )
|
||||||
{
|
{
|
||||||
CHECK( 1 == 1 );
|
CHECK( 1 == 1 );
|
||||||
if( Catch::alwaysTrue() )
|
if( Catch::alwaysTrue() )
|
||||||
throw std::domain_error( "unexpected exception" );
|
throw std::domain_error( "unexpected exception" );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "When unchecked exceptions are thrown from sections they are always failures", "[.][failing]" )
|
TEST_CASE( "When unchecked exceptions are thrown from sections they are always failures", "[.][failing][!throws]" )
|
||||||
{
|
{
|
||||||
SECTION( "section name", "" )
|
SECTION( "section name", "" )
|
||||||
{
|
{
|
||||||
if( Catch::alwaysTrue() )
|
if( Catch::alwaysTrue() )
|
||||||
throw std::domain_error( "unexpected exception" );
|
throw std::domain_error( "unexpected exception" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "When unchecked exceptions are thrown from functions they are always failures", "[.][failing]" )
|
TEST_CASE( "When unchecked exceptions are thrown from functions they are always failures", "[.][failing][!throws]" )
|
||||||
{
|
{
|
||||||
CHECK( thisThrows() == 0 );
|
CHECK( thisThrows() == 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "When unchecked exceptions are thrown during a REQUIRE the test should abort fail", "[.][failing]" )
|
TEST_CASE( "When unchecked exceptions are thrown during a REQUIRE the test should abort fail", "[.][failing][!throws]" )
|
||||||
{
|
{
|
||||||
REQUIRE( thisThrows() == 0 );
|
REQUIRE( thisThrows() == 0 );
|
||||||
FAIL( "This should never happen" );
|
FAIL( "This should never happen" );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "When unchecked exceptions are thrown during a CHECK the test should abort and fail", "[.][failing]" )
|
TEST_CASE( "When unchecked exceptions are thrown during a CHECK the test should continue", "[.][failing][!throws]" )
|
||||||
{
|
{
|
||||||
CHECK( thisThrows() == 0 );
|
try {
|
||||||
FAIL( "This should never happen" );
|
CHECK(thisThrows() == 0);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
FAIL( "This should never happen" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "When unchecked exceptions are thrown, but caught, they do not affect the test", "" )
|
TEST_CASE( "When unchecked exceptions are thrown, but caught, they do not affect the test", "[!throws]" )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -139,50 +143,50 @@ CATCH_TRANSLATE_EXCEPTION( double& ex )
|
|||||||
return Catch::toString( ex );
|
return Catch::toString( ex );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Non-std exceptions can be translated", "[.][failing]" )
|
TEST_CASE("Non-std exceptions can be translated", "[.][failing][!throws]" )
|
||||||
{
|
{
|
||||||
if( Catch::alwaysTrue() )
|
if( Catch::alwaysTrue() )
|
||||||
throw CustomException( "custom exception" );
|
throw CustomException( "custom exception" );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Custom std-exceptions can be custom translated", "[.][failing]" )
|
TEST_CASE("Custom std-exceptions can be custom translated", "[.][failing][!throws]" )
|
||||||
{
|
{
|
||||||
if( Catch::alwaysTrue() )
|
if( Catch::alwaysTrue() )
|
||||||
throw CustomException( "custom std exception" );
|
throw CustomException( "custom std exception" );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void throwCustom() {
|
inline void throwCustom() {
|
||||||
if( Catch::alwaysTrue() )
|
if( Catch::alwaysTrue() )
|
||||||
throw CustomException( "custom exception - not std" );
|
throw CustomException( "custom exception - not std" );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Custom exceptions can be translated when testing for nothrow", "[.][failing]" )
|
TEST_CASE( "Custom exceptions can be translated when testing for nothrow", "[.][failing][!throws]" )
|
||||||
{
|
{
|
||||||
REQUIRE_NOTHROW( throwCustom() );
|
REQUIRE_NOTHROW( throwCustom() );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Custom exceptions can be translated when testing for throwing as something else", "[.][failing]" )
|
TEST_CASE( "Custom exceptions can be translated when testing for throwing as something else", "[.][failing][!throws]" )
|
||||||
{
|
{
|
||||||
REQUIRE_THROWS_AS( throwCustom(), std::exception );
|
REQUIRE_THROWS_AS( throwCustom(), std::exception );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST_CASE( "Unexpected exceptions can be translated", "[.][failing]" )
|
TEST_CASE( "Unexpected exceptions can be translated", "[.][failing][!throws]" )
|
||||||
{
|
{
|
||||||
if( Catch::alwaysTrue() )
|
if( Catch::alwaysTrue() )
|
||||||
throw double( 3.14 );
|
throw double( 3.14 );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int thisFunctionNotImplemented( int ) {
|
inline int thisFunctionNotImplemented( int ) {
|
||||||
CATCH_NOT_IMPLEMENTED;
|
CATCH_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "NotImplemented exception", "" )
|
TEST_CASE( "NotImplemented exception", "[!throws]" )
|
||||||
{
|
{
|
||||||
REQUIRE_THROWS( thisFunctionNotImplemented( 7 ) );
|
REQUIRE_THROWS( thisFunctionNotImplemented( 7 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Exception messages can be tested for", "" ) {
|
TEST_CASE( "Exception messages can be tested for", "[!throws]" ) {
|
||||||
using namespace Catch::Matchers;
|
using namespace Catch::Matchers;
|
||||||
SECTION( "exact match" )
|
SECTION( "exact match" )
|
||||||
REQUIRE_THROWS_WITH( thisThrows(), "expected exception" );
|
REQUIRE_THROWS_WITH( thisThrows(), "expected exception" );
|
||||||
@@ -196,7 +200,7 @@ TEST_CASE( "Exception messages can be tested for", "" ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Mismatching exception messages failing the test", "[.][failing]" ) {
|
TEST_CASE( "Mismatching exception messages failing the test", "[.][failing][!throws]" ) {
|
||||||
REQUIRE_THROWS_WITH( thisThrows(), "expected exception" );
|
REQUIRE_THROWS_WITH( thisThrows(), "expected exception" );
|
||||||
REQUIRE_THROWS_WITH( thisThrows(), "should fail" );
|
REQUIRE_THROWS_WITH( thisThrows(), "should fail" );
|
||||||
REQUIRE_THROWS_WITH( thisThrows(), "expected exception" );
|
REQUIRE_THROWS_WITH( thisThrows(), "expected exception" );
|
||||||
|
@@ -36,16 +36,21 @@ using namespace Catch;
|
|||||||
// REQUIRE( C_A_T_C_H_Context().i() == 42 );
|
// REQUIRE( C_A_T_C_H_Context().i() == 42 );
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
Catch::TestCaseTracking::NameAndLocation makeNAL( std::string const& name ) {
|
||||||
|
return Catch::TestCaseTracking::NameAndLocation( name, Catch::SourceLineInfo() );
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE( "Tracker", "" ) {
|
TEST_CASE( "Tracker", "" ) {
|
||||||
|
|
||||||
TrackerContext ctx;
|
TrackerContext ctx;
|
||||||
ctx.startRun();
|
ctx.startRun();
|
||||||
ctx.startCycle();
|
ctx.startCycle();
|
||||||
|
|
||||||
ITracker& testCase = SectionTracker::acquire( ctx, "Testcase" );
|
|
||||||
|
ITracker& testCase = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) );
|
||||||
REQUIRE( testCase.isOpen() );
|
REQUIRE( testCase.isOpen() );
|
||||||
|
|
||||||
ITracker& s1 = SectionTracker::acquire( ctx, "S1" );
|
ITracker& s1 = SectionTracker::acquire( ctx, makeNAL( "S1" ) );
|
||||||
REQUIRE( s1.isOpen() );
|
REQUIRE( s1.isOpen() );
|
||||||
|
|
||||||
SECTION( "successfully close one section", "" ) {
|
SECTION( "successfully close one section", "" ) {
|
||||||
@@ -70,10 +75,10 @@ TEST_CASE( "Tracker", "" ) {
|
|||||||
|
|
||||||
SECTION( "re-enter after failed section", "" ) {
|
SECTION( "re-enter after failed section", "" ) {
|
||||||
ctx.startCycle();
|
ctx.startCycle();
|
||||||
ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
|
ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) );
|
||||||
REQUIRE( testCase2.isOpen() );
|
REQUIRE( testCase2.isOpen() );
|
||||||
|
|
||||||
ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
|
ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) );
|
||||||
REQUIRE( s1b.isOpen() == false );
|
REQUIRE( s1b.isOpen() == false );
|
||||||
|
|
||||||
testCase2.close();
|
testCase2.close();
|
||||||
@@ -83,13 +88,13 @@ TEST_CASE( "Tracker", "" ) {
|
|||||||
}
|
}
|
||||||
SECTION( "re-enter after failed section and find next section", "" ) {
|
SECTION( "re-enter after failed section and find next section", "" ) {
|
||||||
ctx.startCycle();
|
ctx.startCycle();
|
||||||
ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
|
ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) );
|
||||||
REQUIRE( testCase2.isOpen() );
|
REQUIRE( testCase2.isOpen() );
|
||||||
|
|
||||||
ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
|
ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) );
|
||||||
REQUIRE( s1b.isOpen() == false );
|
REQUIRE( s1b.isOpen() == false );
|
||||||
|
|
||||||
ITracker& s2 = SectionTracker::acquire( ctx, "S2" );
|
ITracker& s2 = SectionTracker::acquire( ctx, makeNAL( "S2" ) );
|
||||||
REQUIRE( s2.isOpen() );
|
REQUIRE( s2.isOpen() );
|
||||||
|
|
||||||
s2.close();
|
s2.close();
|
||||||
@@ -104,7 +109,7 @@ TEST_CASE( "Tracker", "" ) {
|
|||||||
SECTION( "successfully close one section, then find another", "" ) {
|
SECTION( "successfully close one section, then find another", "" ) {
|
||||||
s1.close();
|
s1.close();
|
||||||
|
|
||||||
ITracker& s2 = SectionTracker::acquire( ctx, "S2" );
|
ITracker& s2 = SectionTracker::acquire( ctx, makeNAL( "S2" ) );
|
||||||
REQUIRE( s2.isOpen() == false );
|
REQUIRE( s2.isOpen() == false );
|
||||||
|
|
||||||
testCase.close();
|
testCase.close();
|
||||||
@@ -112,13 +117,13 @@ TEST_CASE( "Tracker", "" ) {
|
|||||||
|
|
||||||
SECTION( "Re-enter - skips S1 and enters S2", "" ) {
|
SECTION( "Re-enter - skips S1 and enters S2", "" ) {
|
||||||
ctx.startCycle();
|
ctx.startCycle();
|
||||||
ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
|
ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) );
|
||||||
REQUIRE( testCase2.isOpen() );
|
REQUIRE( testCase2.isOpen() );
|
||||||
|
|
||||||
ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
|
ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) );
|
||||||
REQUIRE( s1b.isOpen() == false );
|
REQUIRE( s1b.isOpen() == false );
|
||||||
|
|
||||||
ITracker& s2b = SectionTracker::acquire( ctx, "S2" );
|
ITracker& s2b = SectionTracker::acquire( ctx, makeNAL( "S2" ) );
|
||||||
REQUIRE( s2b.isOpen() );
|
REQUIRE( s2b.isOpen() );
|
||||||
|
|
||||||
REQUIRE( ctx.completedCycle() == false );
|
REQUIRE( ctx.completedCycle() == false );
|
||||||
@@ -145,13 +150,13 @@ TEST_CASE( "Tracker", "" ) {
|
|||||||
|
|
||||||
// Need a final cycle
|
// Need a final cycle
|
||||||
ctx.startCycle();
|
ctx.startCycle();
|
||||||
ITracker& testCase3 = SectionTracker::acquire( ctx, "Testcase" );
|
ITracker& testCase3 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) );
|
||||||
REQUIRE( testCase3.isOpen() );
|
REQUIRE( testCase3.isOpen() );
|
||||||
|
|
||||||
ITracker& s1c = SectionTracker::acquire( ctx, "S1" );
|
ITracker& s1c = SectionTracker::acquire( ctx, makeNAL( "S1" ) );
|
||||||
REQUIRE( s1c.isOpen() == false );
|
REQUIRE( s1c.isOpen() == false );
|
||||||
|
|
||||||
ITracker& s2c = SectionTracker::acquire( ctx, "S2" );
|
ITracker& s2c = SectionTracker::acquire( ctx, makeNAL( "S2" ) );
|
||||||
REQUIRE( s2c.isOpen() == false );
|
REQUIRE( s2c.isOpen() == false );
|
||||||
|
|
||||||
testCase3.close();
|
testCase3.close();
|
||||||
@@ -161,7 +166,7 @@ TEST_CASE( "Tracker", "" ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SECTION( "open a nested section", "" ) {
|
SECTION( "open a nested section", "" ) {
|
||||||
ITracker& s2 = SectionTracker::acquire( ctx, "S2" );
|
ITracker& s2 = SectionTracker::acquire( ctx, makeNAL( "S2" ) );
|
||||||
REQUIRE( s2.isOpen() );
|
REQUIRE( s2.isOpen() );
|
||||||
|
|
||||||
s2.close();
|
s2.close();
|
||||||
@@ -177,7 +182,7 @@ TEST_CASE( "Tracker", "" ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SECTION( "start a generator", "" ) {
|
SECTION( "start a generator", "" ) {
|
||||||
IndexTracker& g1 = IndexTracker::acquire( ctx, "G1", 2 );
|
IndexTracker& g1 = IndexTracker::acquire( ctx, makeNAL( "G1" ), 2 );
|
||||||
REQUIRE( g1.isOpen() );
|
REQUIRE( g1.isOpen() );
|
||||||
REQUIRE( g1.index() == 0 );
|
REQUIRE( g1.index() == 0 );
|
||||||
|
|
||||||
@@ -193,14 +198,14 @@ TEST_CASE( "Tracker", "" ) {
|
|||||||
|
|
||||||
SECTION( "Re-enter for second generation", "" ) {
|
SECTION( "Re-enter for second generation", "" ) {
|
||||||
ctx.startCycle();
|
ctx.startCycle();
|
||||||
ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
|
ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) );
|
||||||
REQUIRE( testCase2.isOpen() );
|
REQUIRE( testCase2.isOpen() );
|
||||||
|
|
||||||
ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
|
ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) );
|
||||||
REQUIRE( s1b.isOpen() );
|
REQUIRE( s1b.isOpen() );
|
||||||
|
|
||||||
|
|
||||||
IndexTracker& g1b = IndexTracker::acquire( ctx, "G1", 2 );
|
IndexTracker& g1b = IndexTracker::acquire( ctx, makeNAL( "G1" ), 2 );
|
||||||
REQUIRE( g1b.isOpen() );
|
REQUIRE( g1b.isOpen() );
|
||||||
REQUIRE( g1b.index() == 1 );
|
REQUIRE( g1b.index() == 1 );
|
||||||
|
|
||||||
@@ -214,7 +219,7 @@ TEST_CASE( "Tracker", "" ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
SECTION( "Start a new inner section", "" ) {
|
SECTION( "Start a new inner section", "" ) {
|
||||||
ITracker& s2 = SectionTracker::acquire( ctx, "S2" );
|
ITracker& s2 = SectionTracker::acquire( ctx, makeNAL( "S2" ) );
|
||||||
REQUIRE( s2.isOpen() );
|
REQUIRE( s2.isOpen() );
|
||||||
|
|
||||||
s2.close();
|
s2.close();
|
||||||
@@ -228,19 +233,19 @@ TEST_CASE( "Tracker", "" ) {
|
|||||||
|
|
||||||
SECTION( "Re-enter for second generation", "" ) {
|
SECTION( "Re-enter for second generation", "" ) {
|
||||||
ctx.startCycle();
|
ctx.startCycle();
|
||||||
ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
|
ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) );
|
||||||
REQUIRE( testCase2.isOpen() );
|
REQUIRE( testCase2.isOpen() );
|
||||||
|
|
||||||
ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
|
ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) );
|
||||||
REQUIRE( s1b.isOpen() );
|
REQUIRE( s1b.isOpen() );
|
||||||
|
|
||||||
// generator - next value
|
// generator - next value
|
||||||
IndexTracker& g1b = IndexTracker::acquire( ctx, "G1", 2 );
|
IndexTracker& g1b = IndexTracker::acquire( ctx, makeNAL( "G1" ), 2 );
|
||||||
REQUIRE( g1b.isOpen() );
|
REQUIRE( g1b.isOpen() );
|
||||||
REQUIRE( g1b.index() == 1 );
|
REQUIRE( g1b.index() == 1 );
|
||||||
|
|
||||||
// inner section again
|
// inner section again
|
||||||
ITracker& s2b = SectionTracker::acquire( ctx, "S2" );
|
ITracker& s2b = SectionTracker::acquire( ctx, makeNAL( "S2" ) );
|
||||||
REQUIRE( s2b.isOpen() );
|
REQUIRE( s2b.isOpen() );
|
||||||
|
|
||||||
s2b.close();
|
s2b.close();
|
||||||
@@ -256,7 +261,7 @@ TEST_CASE( "Tracker", "" ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SECTION( "Fail an inner section", "" ) {
|
SECTION( "Fail an inner section", "" ) {
|
||||||
ITracker& s2 = SectionTracker::acquire( ctx, "S2" );
|
ITracker& s2 = SectionTracker::acquire( ctx, makeNAL( "S2" ) );
|
||||||
REQUIRE( s2.isOpen() );
|
REQUIRE( s2.isOpen() );
|
||||||
|
|
||||||
s2.fail();
|
s2.fail();
|
||||||
@@ -271,19 +276,19 @@ TEST_CASE( "Tracker", "" ) {
|
|||||||
|
|
||||||
SECTION( "Re-enter for second generation", "" ) {
|
SECTION( "Re-enter for second generation", "" ) {
|
||||||
ctx.startCycle();
|
ctx.startCycle();
|
||||||
ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
|
ITracker& testCase2 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) );
|
||||||
REQUIRE( testCase2.isOpen() );
|
REQUIRE( testCase2.isOpen() );
|
||||||
|
|
||||||
ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
|
ITracker& s1b = SectionTracker::acquire( ctx, makeNAL( "S1" ) );
|
||||||
REQUIRE( s1b.isOpen() );
|
REQUIRE( s1b.isOpen() );
|
||||||
|
|
||||||
// generator - still same value
|
// generator - still same value
|
||||||
IndexTracker& g1b = IndexTracker::acquire( ctx, "G1", 2 );
|
IndexTracker& g1b = IndexTracker::acquire( ctx, makeNAL( "G1" ), 2 );
|
||||||
REQUIRE( g1b.isOpen() );
|
REQUIRE( g1b.isOpen() );
|
||||||
REQUIRE( g1b.index() == 0 );
|
REQUIRE( g1b.index() == 0 );
|
||||||
|
|
||||||
// inner section again - this time won't open
|
// inner section again - this time won't open
|
||||||
ITracker& s2b = SectionTracker::acquire( ctx, "S2" );
|
ITracker& s2b = SectionTracker::acquire( ctx, makeNAL( "S2" ) );
|
||||||
REQUIRE( s2b.isOpen() == false );
|
REQUIRE( s2b.isOpen() == false );
|
||||||
|
|
||||||
s1b.close();
|
s1b.close();
|
||||||
@@ -295,19 +300,19 @@ TEST_CASE( "Tracker", "" ) {
|
|||||||
|
|
||||||
// Another cycle - now should complete
|
// Another cycle - now should complete
|
||||||
ctx.startCycle();
|
ctx.startCycle();
|
||||||
ITracker& testCase3 = SectionTracker::acquire( ctx, "Testcase" );
|
ITracker& testCase3 = SectionTracker::acquire( ctx, makeNAL( "Testcase" ) );
|
||||||
REQUIRE( testCase3.isOpen() );
|
REQUIRE( testCase3.isOpen() );
|
||||||
|
|
||||||
ITracker& s1c = SectionTracker::acquire( ctx, "S1" );
|
ITracker& s1c = SectionTracker::acquire( ctx, makeNAL( "S1" ) );
|
||||||
REQUIRE( s1c.isOpen() );
|
REQUIRE( s1c.isOpen() );
|
||||||
|
|
||||||
// generator - now next value
|
// generator - now next value
|
||||||
IndexTracker& g1c = IndexTracker::acquire( ctx, "G1", 2 );
|
IndexTracker& g1c = IndexTracker::acquire( ctx, makeNAL( "G1" ), 2 );
|
||||||
REQUIRE( g1c.isOpen() );
|
REQUIRE( g1c.isOpen() );
|
||||||
REQUIRE( g1c.index() == 1 );
|
REQUIRE( g1c.index() == 1 );
|
||||||
|
|
||||||
// inner section - now should open again
|
// inner section - now should open again
|
||||||
ITracker& s2c = SectionTracker::acquire( ctx, "S2" );
|
ITracker& s2c = SectionTracker::acquire( ctx, makeNAL( "S2" ) );
|
||||||
REQUIRE( s2c.isOpen() );
|
REQUIRE( s2c.isOpen() );
|
||||||
|
|
||||||
s2c.close();
|
s2c.close();
|
||||||
|
@@ -0,0 +1,2 @@
|
|||||||
|
// This file is only here to verify (to the extent possible) the self sufficiency of the header
|
||||||
|
#include "internal/catch_test_case_tracker.hpp"
|
@@ -196,13 +196,13 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]"
|
|||||||
}
|
}
|
||||||
|
|
||||||
SECTION( "use-colour", "") {
|
SECTION( "use-colour", "") {
|
||||||
|
|
||||||
using Catch::UseColour;
|
using Catch::UseColour;
|
||||||
|
|
||||||
SECTION( "without option", "" ) {
|
SECTION( "without option", "" ) {
|
||||||
const char* argv[] = { "test" };
|
const char* argv[] = { "test" };
|
||||||
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
||||||
|
|
||||||
REQUIRE( config.useColour == UseColour::Auto );
|
REQUIRE( config.useColour == UseColour::Auto );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,14 +216,14 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]"
|
|||||||
SECTION( "yes", "" ) {
|
SECTION( "yes", "" ) {
|
||||||
const char* argv[] = { "test", "--use-colour", "yes" };
|
const char* argv[] = { "test", "--use-colour", "yes" };
|
||||||
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
||||||
|
|
||||||
REQUIRE( config.useColour == UseColour::Yes );
|
REQUIRE( config.useColour == UseColour::Yes );
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION( "no", "" ) {
|
SECTION( "no", "" ) {
|
||||||
const char* argv[] = { "test", "--use-colour", "no" };
|
const char* argv[] = { "test", "--use-colour", "no" };
|
||||||
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
||||||
|
|
||||||
REQUIRE( config.useColour == UseColour::No );
|
REQUIRE( config.useColour == UseColour::No );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,9 +299,10 @@ TEST_CASE( "Long strings can be wrapped", "[wrap]" ) {
|
|||||||
CHECK( Text( testString, TextAttributes().setWidth( 10 ) ).toString() == testString );
|
CHECK( Text( testString, TextAttributes().setWidth( 10 ) ).toString() == testString );
|
||||||
}
|
}
|
||||||
SECTION( "Trailing newline" , "" ) {
|
SECTION( "Trailing newline" , "" ) {
|
||||||
CHECK( Text( "abcdef\n", TextAttributes().setWidth( 10 ) ).toString() == "abcdef\n" );
|
CHECK( Text( "abcdef\n", TextAttributes().setWidth( 10 ) ).toString() == "abcdef" );
|
||||||
CHECK( Text( "abcdef", TextAttributes().setWidth( 6 ) ).toString() == "abcdef" );
|
CHECK( Text( "abcdef", TextAttributes().setWidth( 6 ) ).toString() == "abcdef" );
|
||||||
CHECK( Text( "abcdef\n", TextAttributes().setWidth( 6 ) ).toString() == "abcdef\n" );
|
CHECK( Text( "abcdef\n", TextAttributes().setWidth( 6 ) ).toString() == "abcdef" );
|
||||||
|
CHECK( Text( "abcdef\n", TextAttributes().setWidth( 5 ) ).toString() == "abcd-\nef" );
|
||||||
}
|
}
|
||||||
SECTION( "Wrapped once", "" ) {
|
SECTION( "Wrapped once", "" ) {
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" );
|
CHECK( Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" );
|
||||||
@@ -313,16 +314,23 @@ TEST_CASE( "Long strings can be wrapped", "[wrap]" ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION( "With tabs", "" ) {
|
SECTION( "With wrap-before/ after characters", "" ) {
|
||||||
|
std::string testString = "one,two(three) <here>";
|
||||||
|
|
||||||
// guide: 1234567890123456789
|
SECTION( "No wrapping", "" ) {
|
||||||
std::string testString = "one two \tthree four five six";
|
CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString );
|
||||||
|
CHECK( Text( testString, TextAttributes().setWidth( 24 ) ).toString() == testString );
|
||||||
CHECK( Text( testString, TextAttributes().setWidth( 15 ) ).toString()
|
}
|
||||||
== "one two three\n four\n five\n six" );
|
SECTION( "Wrap before", "" ) {
|
||||||
|
CHECK( Text( testString, TextAttributes().setWidth( 11 ) ).toString() == "one,two\n(three)\n<here>" );
|
||||||
|
}
|
||||||
|
SECTION( "Wrap after", "" ) {
|
||||||
|
CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one,\ntwo\n(thre-\ne)\n<here>" );
|
||||||
|
CHECK( Text( testString, TextAttributes().setWidth( 5 ) ).toString() == "one,\ntwo\n(thr-\nee)\n<her-\ne>" );
|
||||||
|
CHECK( Text( testString, TextAttributes().setWidth( 4 ) ).toString() == "one,\ntwo\n(th-\nree)\n<he-\nre>" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace Catch;
|
using namespace Catch;
|
||||||
|
@@ -37,19 +37,21 @@ TEST_CASE( "toString( has_toString )", "[toString]" ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call the overload
|
// Call the overload
|
||||||
TEST_CASE( "toString( has_maker )", "[toString]" ) {
|
TEST_CASE( "toString( has_maker )", "toString]" ) {
|
||||||
has_maker item;
|
has_maker item;
|
||||||
REQUIRE( Catch::toString( item ) == "StringMaker<has_maker>" );
|
REQUIRE( Catch::toString( item ) == "StringMaker<has_maker>" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the overload
|
// Call the overload
|
||||||
TEST_CASE( "toString( has_maker_and_toString )", "[toString]" ) {
|
TEST_CASE( "toString( has_maker_and_toString )", "[.][toString]" ) {
|
||||||
has_maker_and_toString item;
|
has_maker_and_toString item;
|
||||||
REQUIRE( Catch::toString( item ) == "toString( has_maker_and_toString )" );
|
REQUIRE( Catch::toString( item ) == "toString( has_maker_and_toString )" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vectors...
|
// Vectors...
|
||||||
TEST_CASE( "toString( vectors<has_toString )", "[toString]" ) {
|
|
||||||
|
// Don't run this in approval tests as it is sensitive to two phase lookup differences
|
||||||
|
TEST_CASE( "toString( vectors<has_toString )", "[.][toString][!nonportable]" ) {
|
||||||
std::vector<has_toString> v(1);
|
std::vector<has_toString> v(1);
|
||||||
// This invokes template<T> toString which actually gives us '{ ? }'
|
// This invokes template<T> toString which actually gives us '{ ? }'
|
||||||
REQUIRE( Catch::toString( v ) == "{ {?} }" );
|
REQUIRE( Catch::toString( v ) == "{ {?} }" );
|
||||||
@@ -61,7 +63,8 @@ TEST_CASE( "toString( vectors<has_maker )", "[toString]" ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST_CASE( "toString( vectors<has_maker_and_toString )", "[toString]" ) {
|
// Don't run this in approval tests as it is sensitive to two phase lookup differences
|
||||||
|
TEST_CASE( "toString( vectors<has_maker_and_toString )", "[.][toString][!nonportable]" ) {
|
||||||
std::vector<has_maker_and_toString> v(1);
|
std::vector<has_maker_and_toString> v(1);
|
||||||
// Note: This invokes the template<T> toString -> StringMaker
|
// Note: This invokes the template<T> toString -> StringMaker
|
||||||
REQUIRE( Catch::toString( v ) == "{ StringMaker<has_maker_and_toString> }" );
|
REQUIRE( Catch::toString( v ) == "{ StringMaker<has_maker_and_toString> }" );
|
||||||
|
10
scripts/approvalTests.py
Normal file → Executable file
10
scripts/approvalTests.py
Normal file → Executable file
@@ -137,15 +137,15 @@ print("Running approvals against executable:")
|
|||||||
print(" " + cmdPath)
|
print(" " + cmdPath)
|
||||||
|
|
||||||
# Standard console reporter
|
# Standard console reporter
|
||||||
approve("console.std", ["~[c++11]", "--order", "lex"])
|
approve("console.std", ["~[c++11]~[!nonportable]", "--order", "lex"])
|
||||||
# console reporter, include passes, warn about No Assertions
|
# console reporter, include passes, warn about No Assertions
|
||||||
approve("console.sw", ["~[c++11]", "-s", "-w", "NoAssertions", "--order", "lex"])
|
approve("console.sw", ["~[c++11]~[!nonportable]", "-s", "-w", "NoAssertions", "--order", "lex"])
|
||||||
# console reporter, include passes, warn about No Assertions, limit failures to first 4
|
# console reporter, include passes, warn about No Assertions, limit failures to first 4
|
||||||
approve("console.swa4", ["~[c++11]", "-s", "-w", "NoAssertions", "-x", "4", "--order", "lex"])
|
approve("console.swa4", ["~[c++11]~[!nonportable]", "-s", "-w", "NoAssertions", "-x", "4", "--order", "lex"])
|
||||||
# junit reporter, include passes, warn about No Assertions
|
# junit reporter, include passes, warn about No Assertions
|
||||||
approve("junit.sw", ["~[c++11]", "-s", "-w", "NoAssertions", "-r", "junit", "--order", "lex"])
|
approve("junit.sw", ["~[c++11]~[!nonportable]", "-s", "-w", "NoAssertions", "-r", "junit", "--order", "lex"])
|
||||||
# xml reporter, include passes, warn about No Assertions
|
# xml reporter, include passes, warn about No Assertions
|
||||||
approve("xml.sw", ["~[c++11]", "-s", "-w", "NoAssertions", "-r", "xml", "--order", "lex"])
|
approve("xml.sw", ["~[c++11]~[!nonportable]", "-s", "-w", "NoAssertions", "-r", "xml", "--order", "lex"])
|
||||||
|
|
||||||
if overallResult != 0:
|
if overallResult != 0:
|
||||||
print("If these differenecs are expected run approve.py to approve new baselines")
|
print("If these differenecs are expected run approve.py to approve new baselines")
|
||||||
|
0
scripts/approve.py
Normal file → Executable file
0
scripts/approve.py
Normal file → Executable file
56
scripts/benchmarkRunner.py
Executable file
56
scripts/benchmarkRunner.py
Executable file
@@ -0,0 +1,56 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import subprocess, os, sys
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
from collections import defaultdict
|
||||||
|
from statistics import median, stdev
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
def get_commit_hash():
|
||||||
|
res = subprocess.run('git rev-parse HEAD'.split(), check=True, stdout=subprocess.PIPE, universal_newlines=True)
|
||||||
|
return res.stdout.strip()
|
||||||
|
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print('Usage: {} benchmark-binary'.format(sys.argv[0]))
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
num_runs = 10
|
||||||
|
data = defaultdict(list)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_file(file):
|
||||||
|
|
||||||
|
def recursive_search(node):
|
||||||
|
if node.tag == 'TestCase':
|
||||||
|
results = node.find('OverallResult')
|
||||||
|
time = results.get('durationInSeconds')
|
||||||
|
data[node.get('name')].append(float(time))
|
||||||
|
elif node.tag in ('Group', 'Catch'):
|
||||||
|
for child in node:
|
||||||
|
recursive_search(child)
|
||||||
|
|
||||||
|
tree = ET.parse(file)
|
||||||
|
recursive_search(tree.getroot())
|
||||||
|
|
||||||
|
def run_benchmarks(binary):
|
||||||
|
call = [binary] + '-d yes -r xml -o'.split()
|
||||||
|
for i in range(num_runs):
|
||||||
|
file = 'temp{}.xml'.format(i)
|
||||||
|
print('Run number {}'.format(i))
|
||||||
|
subprocess.run(call + [file])
|
||||||
|
parse_file(file)
|
||||||
|
# Remove file right after parsing, because benchmark output can be big
|
||||||
|
os.remove(file)
|
||||||
|
|
||||||
|
|
||||||
|
# Run benchmarks
|
||||||
|
run_benchmarks(sys.argv[1])
|
||||||
|
|
||||||
|
result_file = '{:%Y-%m-%dT%H-%M-%S}-{}.result'.format(datetime.now(), get_commit_hash())
|
||||||
|
|
||||||
|
|
||||||
|
print('Writing results to {}'.format(result_file))
|
||||||
|
with open(result_file, 'w') as file:
|
||||||
|
for k in sorted(data):
|
||||||
|
file.write('{}: median: {} (s), stddev: {} (s)\n'.format(k, median(data[k]), stdev(data[k])))
|
1
scripts/fixTrailingWhitespace.py → scripts/fixWhitespace.py
Normal file → Executable file
1
scripts/fixTrailingWhitespace.py → scripts/fixWhitespace.py
Normal file → Executable file
@@ -24,6 +24,7 @@ def fixFile( path ):
|
|||||||
changed = 0
|
changed = 0
|
||||||
for line in f:
|
for line in f:
|
||||||
trimmed = line.rstrip() + "\n"
|
trimmed = line.rstrip() + "\n"
|
||||||
|
trimmed = trimmed.replace('\t', ' ')
|
||||||
if trimmed != line:
|
if trimmed != line:
|
||||||
changed = changed +1
|
changed = changed +1
|
||||||
lines.append( trimmed )
|
lines.append( trimmed )
|
0
scripts/generateSingleHeader.py
Normal file → Executable file
0
scripts/generateSingleHeader.py
Normal file → Executable file
0
scripts/majorRelease.py
Normal file → Executable file
0
scripts/majorRelease.py
Normal file → Executable file
0
scripts/minorRelease.py
Normal file → Executable file
0
scripts/minorRelease.py
Normal file → Executable file
0
scripts/patchRelease.py
Normal file → Executable file
0
scripts/patchRelease.py
Normal file → Executable file
@@ -75,6 +75,8 @@ class Version:
|
|||||||
f.write( line + "\n" )
|
f.write( line + "\n" )
|
||||||
|
|
||||||
def updateReadmeFile(self):
|
def updateReadmeFile(self):
|
||||||
|
versionParser = re.compile( r'\*v\d+\.\d+\.\d+\*' )
|
||||||
|
downloadParser = re.compile( r'<a href=\"https://github.com/philsquared/Catch/releases/download/v\d+\.\d+\.\d+/catch.hpp\">' )
|
||||||
f = open( readmePath, 'r' )
|
f = open( readmePath, 'r' )
|
||||||
lines = []
|
lines = []
|
||||||
for line in f:
|
for line in f:
|
||||||
@@ -82,8 +84,7 @@ class Version:
|
|||||||
f.close()
|
f.close()
|
||||||
f = open( readmePath, 'w' )
|
f = open( readmePath, 'w' )
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if line.startswith( "*v" ):
|
line = versionParser.sub( '*v{0}*'.format(self.getVersionString()), line)
|
||||||
f.write( '*v{0}*\n'.format( self.getVersionString() ) )
|
line = downloadParser.sub( r'<a href="https://github.com/philsquared/Catch/releases/download/v{0}/catch.hpp">'.format(self.getVersionString()) , line)
|
||||||
else:
|
f.write( line + "\n" )
|
||||||
f.write( line + "\n" )
|
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user