mirror of
https://github.com/catchorg/Catch2.git
synced 2025-07-29 18:27:41 +02:00
Compare commits
107 Commits
Author | SHA1 | Date | |
---|---|---|---|
0c015aa887 | |||
f69f821853 | |||
485dbdc0e7 | |||
0afd52b98d | |||
38b05f1400 | |||
db9866677e | |||
4101ff314a | |||
68da5a6d19 | |||
e4a25ad5ff | |||
5d6c744d38 | |||
5dd0639520 | |||
a2515755c3 | |||
807941eb31 | |||
a2e20b07f8 | |||
ace70407a2 | |||
613e1466f9 | |||
e95bf48445 | |||
932a405e18 | |||
9a037204fa | |||
374c050a42 | |||
8b8e3ee117 | |||
af1ed708e4 | |||
041498b221 | |||
d5a5883a10 | |||
6fea473414 | |||
68e7fdce20 | |||
b4c9bf5802 | |||
e952fa8946 | |||
84a178f0b0 | |||
f9db24a824 | |||
9bee606dd6 | |||
be4f6ab8e1 | |||
fd6c7aee6d | |||
cd6de9cd34 | |||
40f6a5b8a4 | |||
95b0eb2b6c | |||
0b28d3daf2 | |||
8435dcbb61 | |||
99347df70e | |||
658b5f63ef | |||
c6535a080e | |||
673ec550f5 | |||
ff78e7c45a | |||
da023b2f9a | |||
470561cbbd | |||
417202b743 | |||
0952b76e16 | |||
bbeb192ec9 | |||
e4f4335b07 | |||
8c07899715 | |||
d5c623b3b6 | |||
061a183036 | |||
70ac6dbb9f | |||
593161ddd8 | |||
71e500f4b5 | |||
ad942885ce | |||
e058a37614 | |||
72b72ca937 | |||
a8a6b3159d | |||
9e2616aeac | |||
c5ffd2e3f0 | |||
0f24a8c06f | |||
b0260c615d | |||
a63ce953a0 | |||
b753f05d74 | |||
9bab7c8229 | |||
d8c4512b25 | |||
2e08bfe9cc | |||
d2a59ad37b | |||
10dfca34ac | |||
45d4096756 | |||
4e6938d78e | |||
1ca8cefa9a | |||
ca66dd243c | |||
44632c3d71 | |||
aa28196e8b | |||
5d8055319e | |||
b1835e1de9 | |||
8cd413572a | |||
30e4dbef1c | |||
90b3946e9c | |||
9202a77498 | |||
d8230a8d4d | |||
c6178601c5 | |||
2e0ae01b05 | |||
1f71d1f760 | |||
fe690a68ef | |||
c9a37c59c4 | |||
3cfef738e7 | |||
5cb9e47034 | |||
044b616127 | |||
f88049169e | |||
7b13a8f85a | |||
6da5e0862a | |||
2049113935 | |||
d4ae1b18c0 | |||
2081caa452 | |||
a5a013811c | |||
1400127d6f | |||
7fed25ad1f | |||
5530303be7 | |||
29fa1edcc7 | |||
1cb8bafb1f | |||
0837132ce3 | |||
26df0781a5 | |||
3523c39f44 | |||
2585d280d1 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -26,3 +26,4 @@ Build
|
||||
.idea
|
||||
cmake-build-debug
|
||||
cmake-build-release
|
||||
.vs
|
@ -70,6 +70,7 @@ set(TEST_SOURCES
|
||||
${SELF_TEST_DIR}/ToStringWhich.cpp
|
||||
${SELF_TEST_DIR}/TrickyTests.cpp
|
||||
${SELF_TEST_DIR}/VariadicMacrosTests.cpp
|
||||
${SELF_TEST_DIR}/MatchersTests.cpp
|
||||
)
|
||||
CheckFileList(TEST_SOURCES ${SELF_TEST_DIR})
|
||||
|
||||
@ -134,6 +135,7 @@ set(INTERNAL_HEADERS
|
||||
${HEADER_DIR}/internal/catch_debugger.h
|
||||
${HEADER_DIR}/internal/catch_debugger.hpp
|
||||
${HEADER_DIR}/internal/catch_default_main.hpp
|
||||
${HEADER_DIR}/internal/catch_errno_guard.hpp
|
||||
${HEADER_DIR}/internal/catch_evaluate.hpp
|
||||
${HEADER_DIR}/internal/catch_exception_translator_registry.hpp
|
||||
${HEADER_DIR}/internal/catch_expression_lhs.hpp
|
||||
@ -154,6 +156,9 @@ set(INTERNAL_HEADERS
|
||||
${HEADER_DIR}/internal/catch_legacy_reporter_adapter.hpp
|
||||
${HEADER_DIR}/internal/catch_list.hpp
|
||||
${HEADER_DIR}/internal/catch_matchers.hpp
|
||||
${HEADER_DIR}/internal/catch_matchers_string.h
|
||||
${HEADER_DIR}/internal/catch_matchers_string.hpp
|
||||
${HEADER_DIR}/internal/catch_matchers_vector.h
|
||||
${HEADER_DIR}/internal/catch_message.h
|
||||
${HEADER_DIR}/internal/catch_message.hpp
|
||||
${HEADER_DIR}/internal/catch_notimplemented_exception.h
|
||||
@ -206,11 +211,13 @@ CheckFileList(INTERNAL_HEADERS ${HEADER_DIR}/internal)
|
||||
|
||||
# Please keep these ordered alphabetically
|
||||
set(REPORTER_HEADERS
|
||||
${HEADER_DIR}/reporters/catch_reporter_automake.hpp
|
||||
${HEADER_DIR}/reporters/catch_reporter_bases.hpp
|
||||
${HEADER_DIR}/reporters/catch_reporter_compact.hpp
|
||||
${HEADER_DIR}/reporters/catch_reporter_console.hpp
|
||||
${HEADER_DIR}/reporters/catch_reporter_junit.hpp
|
||||
${HEADER_DIR}/reporters/catch_reporter_multi.hpp
|
||||
${HEADER_DIR}/reporters/catch_reporter_tap.hpp
|
||||
${HEADER_DIR}/reporters/catch_reporter_teamcity.hpp
|
||||
${HEADER_DIR}/reporters/catch_reporter_xml.hpp
|
||||
)
|
||||
@ -247,7 +254,7 @@ if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
|
||||
target_compile_options( Benchmark PRIVATE -Wall -Wextra )
|
||||
endif()
|
||||
if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
|
||||
target_compile_options( SelfTest PRIVATE /W4 )
|
||||
target_compile_options( SelfTest PRIVATE /W4 /w44265 /WX )
|
||||
target_compile_options( Benchmark PRIVATE /W4 )
|
||||
endif()
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||

|
||||
|
||||
*v1.7.2*
|
||||
[](https://github.com/philsquared/catch/releases)
|
||||
[](https://travis-ci.org/philsquared/Catch)
|
||||
[](https://ci.appveyor.com/project/philsquared/catch/branch/master)
|
||||
|
||||
Build status (on Travis CI) [](https://travis-ci.org/philsquared/Catch)
|
||||
|
||||
<a href="https://github.com/philsquared/Catch/releases/download/v1.7.2/catch.hpp">The latest, single header, version can be downloaded directly using this link</a>
|
||||
<a href="https://github.com/philsquared/Catch/releases/download/v1.8.2/catch.hpp">The latest, single header, version can be downloaded directly using this link</a>
|
||||
|
||||
## What's the Catch?
|
||||
|
||||
|
45
appveyor.yml
Normal file
45
appveyor.yml
Normal file
@ -0,0 +1,45 @@
|
||||
# version string format -- This will be overwritten later anyway
|
||||
version: "{build}"
|
||||
|
||||
# Disable the dead branch for v2 development
|
||||
branches:
|
||||
except:
|
||||
- develop-v2
|
||||
|
||||
os:
|
||||
- Visual Studio 2013
|
||||
- Visual Studio 2015
|
||||
|
||||
init:
|
||||
- git config --global core.autocrlf input
|
||||
# Set build version to git commit-hash
|
||||
- ps: Update-AppveyorBuild -Version "$($env:APPVEYOR_REPO_BRANCH) - $($env:APPVEYOR_REPO_COMMIT)"
|
||||
|
||||
# fetch repository as zip archive
|
||||
shallow_clone: true
|
||||
|
||||
# Win32 and x64 are CMake-compatible solution platform names.
|
||||
# This allows us to pass %PLATFORM% to CMake -A.
|
||||
platform:
|
||||
- Win32
|
||||
- x64
|
||||
|
||||
# build Configurations, i.e. Debug, Release, etc.
|
||||
configuration:
|
||||
- Debug
|
||||
- Release
|
||||
|
||||
#Cmake will autodetect the compiler, but we set the arch
|
||||
before_build:
|
||||
- echo Running cmake...
|
||||
- cmake -H. -BBuild -A%PLATFORM%
|
||||
|
||||
# build with MSBuild
|
||||
build:
|
||||
project: Build\CatchSelfTest.sln # path to Visual Studio solution or project
|
||||
parallel: true # enable MSBuild parallel builds
|
||||
verbosity: normal # MSBuild verbosity level {quiet|minimal|normal|detailed}
|
||||
|
||||
test_script:
|
||||
- cd Build
|
||||
- ctest -V -j 2 -C %CONFIGURATION%
|
BIN
catch-hand-icon.png
Normal file
BIN
catch-hand-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 52 KiB |
BIN
catch-icon-tiny.png
Normal file
BIN
catch-icon-tiny.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 19 KiB |
Binary file not shown.
Before Width: | Height: | Size: 5.7 KiB |
@ -3,17 +3,19 @@ These are the currently documented areas of the framework. There is more to come
|
||||
Before looking at this material be sure to read the [tutorial](tutorial.md)
|
||||
|
||||
* [Assertion macros](assertions.md)
|
||||
* [Matchers](matchers.md)
|
||||
* [Logging macros](logging.md)
|
||||
* [Test cases and sections](test-cases-and-sections.md)
|
||||
* [Test fixtures](test-fixtures.md)
|
||||
* [Command line](command-line.md)
|
||||
* [Build systems](build-systems.md)
|
||||
* [Supplying your own main()](own-main.md)
|
||||
* [Event Listeners](event-listeners.md)
|
||||
* [Configuration](configuration.md)
|
||||
* [String Conversions](tostring.md)
|
||||
* [Command line](command-line.md)
|
||||
* [Build systems](build-systems.md)
|
||||
* [Why are my tests slow to compile?](slow-compiles.md)
|
||||
* [Known limitations](limitations.md)
|
||||
|
||||
|
||||
Other
|
||||
|
||||
* [Why Catch?](why-catch.md)
|
||||
|
@ -53,13 +53,32 @@ Catch provides a way to perform tolerant comparisons of floating point values th
|
||||
REQUIRE( performComputation() == Approx( 2.1 ) );
|
||||
```
|
||||
|
||||
By default a small epsilon value is used that covers many simple cases of rounding errors. When this is insufficent the epsilon value (the amount within which a difference either way is ignored) can be specified by calling the ```epsilon()``` method on the ```Approx``` instance. e.g.:
|
||||
This way `Approx` is constructed with reasonable defaults, covering most simple cases of rounding errors. If these are insufficient, each `Approx` instance has 3 tuning knobs, that can be used to customize it for your computation.
|
||||
|
||||
```
|
||||
REQUIRE( 22/7 == Approx( 3.141 ).epsilon( 0.01 ) );
|
||||
* __epsilon__ - epsilon serves to set the percentage by which a result can be erroneous, before it is rejected. By default set to `std::numeric_limits<float>::epsilon()*100`.
|
||||
* __margin__ - margin serves to set the the absolute value by which a result can be erroneous before it is rejected. By default set to `0.0`.
|
||||
* __scale__ - scale serves to adjust the base for comparison used by epsilon, can be used when By default set to `1.0`.
|
||||
|
||||
#### epsilon example
|
||||
```cpp
|
||||
Approx target = Approx(100).epsilon(0.01);
|
||||
100.0 == target; // Obviously true
|
||||
200.0 == target; // Obviously still false
|
||||
100.5 == target; // True, because we set target to allow up to 1% error
|
||||
```
|
||||
|
||||
When dealing with very large or very small numbers it can be useful to specify a scale, which can be achieved by calling the ```scale()``` method on the ```Approx``` instance.
|
||||
#### margin example
|
||||
_Margin check is used only if the relative (epsilon and scale based) check fails._
|
||||
```cpp
|
||||
Approx target = Approx(100).margin(5);
|
||||
100.0 == target; // Obviously true
|
||||
200.0 == target; // Obviously still false
|
||||
104.0 == target; // True, because we set target to allow absolute error up to 5
|
||||
```
|
||||
|
||||
#### scale
|
||||
Scale can be useful if the computation leading to the result worked on different scale, than is used by the results (and thus expected errors are on a different scale than would be expected based on the results alone).
|
||||
|
||||
|
||||
## Exceptions
|
||||
|
||||
@ -105,13 +124,11 @@ REQUIRE_NOTHROW([&](){
|
||||
|
||||
## Matcher expressions
|
||||
|
||||
To support Matchers a slightly different form is used. Matchers will be more fully documented elsewhere. *Note that Matchers are still at early stage development and are subject to change.*
|
||||
To support Matchers a slightly different form is used. Matchers have [their own documentation](matchers.md).
|
||||
|
||||
* **REQUIRE_THAT(** _lhs_, _matcher expression_ **)** and
|
||||
* **CHECK_THAT(** _lhs_, _matcher expression_ **)**
|
||||
|
||||
Currently only string matchers are implemented and consist of: `Contains`, `Equals`, `StartsWith` and `EndsWith`.
|
||||
|
||||
Matchers can be composed using `&&`, `||` and `!` operators.
|
||||
|
||||
---
|
||||
|
@ -4,7 +4,7 @@ Build Systems may refer to low-level tools, like CMake, or larger systems that r
|
||||
|
||||
# Continuous Integration systems
|
||||
|
||||
Probably the most important aspect to using Catch with a build server is the use of different reporters. Catch comes bundled with three reporters that should cover the majority of build servers out there - although adding more for better integration with some is always a possibility (as has been done with TeamCity).
|
||||
Probably the most important aspect to using Catch with a build server is the use of different reporters. Catch comes bundled with three reporters that should cover the majority of build servers out there - although adding more for better integration with some is always a possibility (currently we also offer TeamCity, TAP and Automake reporters).
|
||||
|
||||
Two of these reporters are built in (XML and JUnit) and the third (TeamCity) is included as a separate header. It's possible that the other two may be split out in the future too - as that would make the core of Catch smaller for those that don't need them.
|
||||
|
||||
@ -26,14 +26,8 @@ The advantage of this format is that the JUnit Ant schema is widely understood b
|
||||
|
||||
The disadvantage is that this schema was designed to correspond to how JUnit works - and there is a significant mismatch with how Catch works. Additionally the format is not streamable (because opening elements hold counts of failed and passing tests as attributes) - so the whole test run must complete before it can be written.
|
||||
|
||||
## TeamCity Reporter
|
||||
```-r teamcity```
|
||||
|
||||
The TeamCity Reporter writes TeamCity service messages to stdout. In order to be able to use this reporter an additional header must also be included.
|
||||
|
||||
```catch_reporter_teamcity.hpp``` can be found in the ```include\reporters``` directory. It should be included in the same file that ```#define```s ```CATCH_CONFIG_MAIN``` or ```CATCH_CONFIG_RUNNER```. The ```#include``` should be placed after ```#include```ing Catch itself.
|
||||
|
||||
e.g.:
|
||||
## Other reporters
|
||||
Other reporters are not part of the single-header distribution and need to be downloaded and included separately. All reporters are stored in `include/reporters` directory in the git repository, and are named `catch_reporter_*.hpp`. For example, to use the TeamCity reporter you need to download `include/reporters/catch_reporter_teamcity.hpp` and include it after Catch itself.
|
||||
|
||||
```
|
||||
#define CATCH_CONFIG_MAIN
|
||||
@ -41,8 +35,23 @@ e.g.:
|
||||
#include "catch_reporter_teamcity.hpp"
|
||||
```
|
||||
|
||||
### TeamCity Reporter
|
||||
```-r teamcity```
|
||||
|
||||
The TeamCity Reporter writes TeamCity service messages to stdout. In order to be able to use this reporter an additional header must also be included.
|
||||
|
||||
Being specific to TeamCity this is the best reporter to use with it - but it is completely unsuitable for any other purpose. It is a streaming format (it writes as it goes) - although test results don't appear in the TeamCity interface until the completion of a suite (usually the whole test run).
|
||||
|
||||
### Automake Reporter
|
||||
```-r automake```
|
||||
|
||||
The Automake Reporter writes out the [meta tags](https://www.gnu.org/software/automake/manual/html_node/Log-files-generation-and-test-results-recording.html#Log-files-generation-and-test-results-recording) expected by automake via `make check`.
|
||||
|
||||
### TAP (Test Anything Protocol) Reporter
|
||||
```-r tap```
|
||||
|
||||
Because of the incremental nature of Catch's test suites and ability to run specific tests, our implementation of TAP reporter writes out the number of tests in a suite last.
|
||||
|
||||
# Low-level tools
|
||||
|
||||
## CMake
|
||||
|
@ -222,7 +222,7 @@ Prints the command line arguments to stdout
|
||||
|
||||
<a id="run-section"></a>
|
||||
## Specify the section to run
|
||||
<pre>-s, --section <section name></pre>
|
||||
<pre>-c, --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.
|
||||
|
@ -74,8 +74,17 @@ All C++11 support can be disabled with `CATCH_CONFIG_NO_CPP11`
|
||||
|
||||
CATCH_CONFIG_COUNTER // Use __COUNTER__ to generate unique names for test cases
|
||||
CATCH_CONFIG_WINDOWS_SEH // Enable SEH handling on Windows
|
||||
CATCH_CONFIG_FAST_COMPILE // Sacrifices some (extremely minor) features for compilation speed
|
||||
CATCH_CONFIG_POSIX_SIGNALS // Enable handling POSIX signals
|
||||
CATCH_CONFIG_WINDOWS_CRTDBG // Enable leak checking using Windows's CRT Debug Heap
|
||||
|
||||
Currently Catch enables `CATCH_CONFIG_WINDOWS_SEH` only when compiled with MSVC, because some versions of MinGW do not have the necessary Win32 API supports.
|
||||
Currently Catch enables `CATCH_CONFIG_WINDOWS_SEH` only when compiled with MSVC, because some versions of MinGW do not have the necessary Win32 API support.
|
||||
|
||||
At this moment, `CATCH_CONFIG_FAST_COMPILE` changes only the behaviour of the `-b` (`--break`) flag, making it break into debugger in a stack frame *below* the actual test, unlike the default behaviour, where the break into debugger occurs in the same stack frame as the actual test. `CATCH_CONFIG_FAST_COMPILE` has to be either defined, or not defined, in all translation units that are linked into single test binary, or the behaviour of setting `-b` flag will be unpredictable.
|
||||
|
||||
`CATCH_CONFIG_POSIX_SIGNALS` is on by default, except when Catch is compiled under `Cygwin`, where it is disabled by default (but can be force-enabled by defining `CATCH_CONFIG_POSIX_SIGNALS`).
|
||||
|
||||
`CATCH_CONFIG_WINDOWS_CRTDBG` is off by default. If enabled, Windows's CRT is used to check for memory leaks, and displays them after the tests finish running.
|
||||
|
||||
Just as with the C++11 conformance toggles, these toggles can be disabled by using `_NO_` form of the toggle, e.g. `CATCH_CONFIG_NO_WINDOWS_SEH`.
|
||||
|
||||
|
73
docs/event-listeners.md
Normal file
73
docs/event-listeners.md
Normal file
@ -0,0 +1,73 @@
|
||||
# Event Listeners
|
||||
|
||||
A `Listener` is a class you can register with Catch that will then be passed events,
|
||||
such as a test case starting or ending, as they happen during a test run.
|
||||
`Listeners` are actually types of `Reporters`, with a few small differences:
|
||||
|
||||
1. Once registered in code they are automatically used - you don't need to specify them on the command line
|
||||
2. They are called in addition to (just before) any reporters, and you can register multiple listeners.
|
||||
3. They derive from `Catch::TestEventListenerBase`, which has default stubs for all the events,
|
||||
so you are not forced to implement events you're not interested in.
|
||||
4. You register a listener with `CATCH_REGISTER_LISTENER`
|
||||
|
||||
|
||||
## Implementing a Listener
|
||||
|
||||
In your main source file (i.e. the one that has the `#define` for `CATCH_CONFIG_MAIN` or `CATCH_CONFIG_RUNNER`),
|
||||
simply derive a class from `Catch::TestEventListenerBase` and implement the methods you are interested in.
|
||||
Then register it using `INTERNAL_CATCH_REGISTER_LISTENER`.
|
||||
|
||||
For example:
|
||||
|
||||
```c++
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
||||
|
||||
struct MyListener : Catch::TestEventListenerBase {
|
||||
|
||||
using TestEventListenerBase::TestEventListenerBase; // inherit constructor
|
||||
|
||||
virtual void testCaseStarting( Catch::TestCaseInfo const& testInfo ) override {
|
||||
// Perform some setup before a test case is run
|
||||
}
|
||||
|
||||
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) override {
|
||||
// Tear-down after a test case is run
|
||||
}
|
||||
};
|
||||
CATCH_REGISTER_LISTENER( MyListener )
|
||||
```
|
||||
|
||||
_Note that you should not use any assertion macros within a Listener!_
|
||||
|
||||
## Events that can be hooked
|
||||
|
||||
The following are the methods that can be overriden in the Listener:
|
||||
|
||||
```c++
|
||||
// The whole test run, starting and ending
|
||||
virtual void testRunStarting( TestRunInfo const& testRunInfo );
|
||||
virtual void testRunEnded( TestRunStats const& testRunStats );
|
||||
|
||||
// Test cases starting and ending
|
||||
virtual void testCaseStarting( TestCaseInfo const& testInfo );
|
||||
virtual void testCaseEnded( TestCaseStats const& testCaseStats );
|
||||
|
||||
// Sections starting and ending
|
||||
virtual void sectionStarting( SectionInfo const& sectionInfo );
|
||||
virtual void sectionEnded( SectionStats const& sectionStats );
|
||||
|
||||
// Assertions before/ after
|
||||
virtual void assertionStarting( AssertionInfo const& assertionInfo );
|
||||
virtual bool assertionEnded( AssertionStats const& assertionStats );
|
||||
|
||||
// A test is being skipped (because it is "hidden")
|
||||
virtual void skipTest( TestCaseInfo const& testInfo );
|
||||
```
|
||||
|
||||
More information about the events (e.g. name of the test case) is contained in the structs passed as arguments -
|
||||
just look in the source code to see what fields are available.
|
||||
|
||||
---
|
||||
|
||||
[Home](Readme.md)
|
@ -26,6 +26,10 @@ The message is always reported but does not fail the test.
|
||||
|
||||
The message is reported and the test case fails.
|
||||
|
||||
**FAIL_CHECK(** _message expression_ **)**
|
||||
|
||||
AS `FAIL`, but does not abort the test
|
||||
|
||||
## Quickly capture a variable value
|
||||
|
||||
**CAPTURE(** _expression_ **)**
|
||||
|
103
docs/matchers.md
Normal file
103
docs/matchers.md
Normal file
@ -0,0 +1,103 @@
|
||||
# Matchers
|
||||
|
||||
Matchers are an alternative way to do assertions which are easily extensible and composable.
|
||||
This makes them well suited to use with more complex types (such as collections) or your own custom types.
|
||||
Matchers were first popularised by the [Hamcrest](https://en.wikipedia.org/wiki/Hamcrest) family of frameworks.
|
||||
|
||||
## In use
|
||||
|
||||
Matchers are introduced with the `REQUIRE_THAT` or `CHECK_THAT` macros, which take two arguments.
|
||||
The first argument is the thing (object or value) under test. The second part is a match _expression_,
|
||||
which consists of either a single matcher or one or more matchers combined using `&&`, `||` or `!` operators.
|
||||
|
||||
For example, to assert that a string ends with a certain substring:
|
||||
|
||||
```c++
|
||||
std::string str = getStringFromSomewhere();
|
||||
REQUIRE_THAT( str, EndsWith( "as a service" ) );
|
||||
```
|
||||
|
||||
The matcher objects can take multiple arguments, allowing more fine tuning.
|
||||
The built-in string matchers, for example, take a second argument specifying whether the comparison is
|
||||
case sensitive or not:
|
||||
|
||||
```c++
|
||||
REQUIRE_THAT( str, EndsWith( "as a service", Catch::CaseSensitive::No ) );
|
||||
```
|
||||
|
||||
And matchers can be combined:
|
||||
|
||||
```c++
|
||||
REQUIRE_THAT( str,
|
||||
EndsWith( "as a service" ) ||
|
||||
(StartsWith( "Big data" ) && !Contains( "web scale" ) ) );
|
||||
```
|
||||
|
||||
## Built in matchers
|
||||
Currently Catch has some string matchers and some vector matchers.
|
||||
The string matchers are `StartsWith`, `EndsWith`, `Contains` and `Equals`. Each of them also takes an optional second argument, that decides case sensitivity (by-default, they are case sensitive).
|
||||
The vector matchers are `Contains`, `VectorContains` and `Equals`. `VectorContains` looks for a single element in the matched vector, `Contains` looks for a set (vector) of elements inside the matched vector.
|
||||
|
||||
|
||||
## Custom matchers
|
||||
It's easy to provide your own matchers to extend Catch or just to work with your own types.
|
||||
|
||||
You need to provide two things:
|
||||
1. A matcher class, derived from `Catch::MatcherBase<T>` - where `T` is the type being tested.
|
||||
The constructor takes and stores any arguments needed (e.g. something to compare against) and you must
|
||||
override two methods: `match()` and `describe()`.
|
||||
2. A simple builder function. This is what is actually called from the test code and allows overloading.
|
||||
|
||||
Here's an example for asserting that an integer falls within a given range
|
||||
(note that it is all inline for the sake of keeping the example short):
|
||||
|
||||
```c++
|
||||
// The matcher class
|
||||
class IntRange : public Catch::MatcherBase<int> {
|
||||
int m_begin, m_end;
|
||||
public:
|
||||
IntRange( int begin, int end ) : m_begin( begin ), m_end( end ) {}
|
||||
|
||||
// Performs the test for this matcher
|
||||
virtual bool match( int const& i ) const override {
|
||||
return i >= m_begin && i <= m_end;
|
||||
}
|
||||
|
||||
// Produces a string describing what this matcher does. It should
|
||||
// include any provided data (the begin/ end in this case) and
|
||||
// be written as if it were stating a fact (in the output it will be
|
||||
// preceded by the value under test).
|
||||
virtual std::string describe() const {
|
||||
std::ostringstream ss;
|
||||
ss << "is between " << m_begin << " and " << m_end;
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
|
||||
// The builder function
|
||||
inline IntRange IsBetween( int begin, int end ) {
|
||||
return IntRange( begin, end );
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
// Usage
|
||||
TEST_CASE("Integers are within a range")
|
||||
{
|
||||
CHECK_THAT( 3, IsBetween( 1, 10 ) );
|
||||
CHECK_THAT( 100, IsBetween( 1, 10 ) );
|
||||
}
|
||||
```
|
||||
|
||||
Running this test gives the following in the console:
|
||||
|
||||
```
|
||||
/**/TestFile.cpp:123: FAILED:
|
||||
CHECK_THAT( 100, IsBetween( 1, 10 ) )
|
||||
with expansion:
|
||||
100 is between 1 and 10
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
[Home](Readme.md)
|
@ -34,6 +34,9 @@ A, single-header, JSON parsing library that takes advantage of what C++ has to o
|
||||
### [MNMLSTC Core](https://github.com/mnmlstc/core)
|
||||
a small and easy to use C++11 library that adds a functionality set that will be available in C++14 and later, as well as some useful additions
|
||||
|
||||
### [SOCI](https://github.com/SOCI/soci)
|
||||
The C++ Database Access Library
|
||||
|
||||
### [Ppconsul](https://github.com/oliora/ppconsul)
|
||||
A C++ client library for Consul. Consul is a distributed tool for discovering and configuring services in your infrastructure
|
||||
|
||||
@ -45,6 +48,9 @@ A thread safe header only mocking framework for C++14
|
||||
|
||||
## Applications & Tools
|
||||
|
||||
### [ArangoDB](https://github.com/arangodb/arangodb)
|
||||
ArangoDB is a native multi-model database with flexible data models for documents, graphs, and key-values.
|
||||
|
||||
### [MAME](https://github.com/mamedev/mame)
|
||||
MAME originally stood for Multiple Arcade Machine Emulator
|
||||
|
||||
|
@ -1,3 +1,85 @@
|
||||
# 1.8.2
|
||||
|
||||
|
||||
### Improvements and minor changes
|
||||
* TAP reporter now behaves as if `-s` was always set
|
||||
* This should be more consistent with the protocol desired behaviour.
|
||||
* Compact reporter now obeys `-d yes` argument (#780)
|
||||
* The format is "XXX.123 s: <section-name>" (3 decimal places are always present).
|
||||
* Before it did not report the durations at all.
|
||||
* XML reporter now behaves the same way as Console reporter in regards to `INFO`
|
||||
* This means it reports `INFO` messages on success, if output on success (`-s`) is enabled.
|
||||
* Previously it only reported `INFO` messages on failure.
|
||||
* `CAPTURE(expr)` now stringifies `expr` in the same way assertion macros do (#639)
|
||||
* Listeners are now finally [documented](event-listeners.md).
|
||||
* Listeners provide a way to hook into events generated by running your tests, including start and end of run, every test case, every section and every assertion.
|
||||
|
||||
|
||||
### Fixes:
|
||||
* Catch no longer attempts to reconstruct expression that led to a fatal error (#810)
|
||||
* This fixes possible signal/SEH loop when processing expressions, where the signal was triggered by expression decomposition.
|
||||
* Fixed (C4265) missing virtual destructor warning in Matchers (#844)
|
||||
* `std::string`s are now taken by `const&` everywhere (#842).
|
||||
* Previously some places were taking them by-value.
|
||||
* Catch should no longer change errno (#835).
|
||||
* This was caused by libstdc++ bug that we now work around.
|
||||
* Catch now provides `FAIL_CHECK( ... )` macro (#765).
|
||||
* Same as `FAIL( ... )`, but does not abort the test.
|
||||
* Functions like `fabs`, `tolower`, `memset`, `isalnum` are now used with `std::` qualification (#543).
|
||||
* Clara no longer assumes first argument (binary name) is always present (#729)
|
||||
* If it is missing, empty string is used as default.
|
||||
* Clara no longer reads 1 character past argument string (#830)
|
||||
|
||||
|
||||
### Other notes:
|
||||
* We have added VS 2013 and 2015 to our CI
|
||||
* Catch Classic (1.x.x) now contains its own, forked, version of Clara (the argument parser).
|
||||
|
||||
|
||||
|
||||
# 1.8.1
|
||||
|
||||
### Fixes
|
||||
|
||||
Cygwin issue with `gettimeofday` - `#define` was not early enough
|
||||
|
||||
# 1.8.0
|
||||
|
||||
### New features/ minor changes
|
||||
|
||||
* Matchers have new, simpler (and documented) interface.
|
||||
* Catch provides string and vector matchers.
|
||||
* For details see [Matchers documentation](docs/matchers.md).
|
||||
* Changed console reporter test duration reporting format (#322)
|
||||
* Old format: `Some simple comparisons between doubles completed in 0.000123s`
|
||||
* New format: `xxx.123s: Some simple comparisons between doubles` _(There will always be exactly 3 decimal places)_
|
||||
* Added opt-in leak detection under MSVC + Windows (#439)
|
||||
* Enable it by compiling Catch's main with `CATCH_CONFIG_WINDOWS_CRTDBG`
|
||||
* Introduced new compile-time flag, `CATCH_CONFIG_FAST_COMPILE`, trading features for compilation speed.
|
||||
* Moves debug breaks out of tests and into implementation, speeding up test compilation time (~10% on linux).
|
||||
* _More changes are coming_
|
||||
* Added [TAP (Test Anything Protocol)](https://testanything.org/) and [Automake](https://www.gnu.org/software/automake/manual/html_node/Log-files-generation-and-test-results-recording.html#Log-files-generation-and-test-results-recording) reporters.
|
||||
* These are not present in the default single-include header and need to be downloaded from GitHub separately.
|
||||
* For details see [documentation about integrating with build systems](build-systems.md).
|
||||
* XML reporter now reports filename as part of the `Section` and `TestCase` tags.
|
||||
* `Approx` now supports an optional margin of absolute error
|
||||
* It has also received [new documentation](docs/assertions.md).
|
||||
|
||||
### Fixes
|
||||
* Silenced C4312 ("conversion from int to 'ClassName *") warnings in the evaluate layer.
|
||||
* Fixed C4512 ("assignment operator could not be generated") warnings under VS2013.
|
||||
* Cygwin compatibility fixes
|
||||
* Signal handling is no longer compiled by default.
|
||||
* Usage of `gettimeofday` inside Catch should no longer cause compilation errors.
|
||||
* Improved `-Wparentheses` supression for gcc (#674)
|
||||
* When compiled with gcc 4.8 or newer, the supression is localized to assertions only
|
||||
* Otherwise it is supressed for the whole TU
|
||||
* Fixed test spec parser issue (with escapes in multiple names)
|
||||
|
||||
### Other
|
||||
* Various documentation fixes and improvements
|
||||
|
||||
|
||||
# 1.7.2
|
||||
|
||||
### Fixes and minor improvements
|
||||
@ -31,9 +113,6 @@ Other:
|
||||
* Fixed possible infinite recursion in Windows SEH.
|
||||
* Fixed possible compilation error caused by Catch's operator overloads being ambiguous in regards to user-defined templated operators.
|
||||
|
||||
# Older versions
|
||||
Release notes were not maintained prior to v1.6.0, but you should be able to work them out from the Git history
|
||||
|
||||
## 1.7.0
|
||||
|
||||
### Features/ Changes:
|
||||
@ -102,6 +181,9 @@ Release notes were not maintained prior to v1.6.0, but you should be able to wor
|
||||
* Tweaks and changes to scripts - particularly for Approval test - to make them more portable
|
||||
|
||||
|
||||
# Older versions
|
||||
Release notes were not maintained prior to v1.6.0, but you should be able to work them out from the Git history
|
||||
|
||||
---
|
||||
|
||||
[Home](Readme.md)
|
||||
|
@ -56,6 +56,8 @@ tests-factorial.cpp:11: failed: Factorial(0) == 1 for: 0 == 1
|
||||
Failed 1 test case, failed 1 assertion.
|
||||
```
|
||||
|
||||
## Other possible solutions
|
||||
You can also opt to sacrifice some features in order to speed-up Catch's compilation times. For details see the [documentation on Catch's compile-time configuration](configuration.md#other-toggles).
|
||||
|
||||
---
|
||||
|
||||
|
@ -38,10 +38,10 @@ All tag names beginning with non-alphanumeric characters are reserved by Catch.
|
||||
|
||||
* `[!throws]` - lets Catch know that this test is likely to throw an exception even if successful. This causes the test to be excluded when running with `-e` or `--nothrow`.
|
||||
|
||||
* `[!shouldfail]` - reverse the failing logic of the test: if the test is successful if it fails, and vice-versa.
|
||||
|
||||
* `[!mayfail]` - doesn't fail the test if any given assertion fails (but still reports it). This can be useful to flag a work-in-progress, or a known issue that you don't want to immediately fix but still want to track in the your tests.
|
||||
|
||||
* `[!shouldfail]` - like `[!mayfail]` but *fails* the test if it *passes*. This can be useful if you want to be notified of accidental, or third-party, fixes.
|
||||
|
||||
* `[!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]`.
|
||||
|
@ -36,7 +36,8 @@
|
||||
#include "internal/catch_generators.hpp"
|
||||
#include "internal/catch_interfaces_exception.h"
|
||||
#include "internal/catch_approx.hpp"
|
||||
#include "internal/catch_matchers.hpp"
|
||||
#include "internal/catch_matchers_string.h"
|
||||
#include "internal/catch_matchers_vector.h"
|
||||
#include "internal/catch_compiler_capabilities.h"
|
||||
#include "internal/catch_interfaces_tag_alias_registry.h"
|
||||
|
||||
@ -50,6 +51,29 @@
|
||||
#endif
|
||||
|
||||
#ifdef CATCH_IMPL
|
||||
|
||||
// !TBD: Move the leak detector code into a separate header
|
||||
#ifdef CATCH_CONFIG_WINDOWS_CRTDBG
|
||||
#include <crtdbg.h>
|
||||
class LeakDetector {
|
||||
public:
|
||||
LeakDetector() {
|
||||
int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
|
||||
flag |= _CRTDBG_LEAK_CHECK_DF;
|
||||
flag |= _CRTDBG_ALLOC_MEM_DF;
|
||||
_CrtSetDbgFlag(flag);
|
||||
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
|
||||
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
|
||||
// Change this to leaking allocation's number to break there
|
||||
_CrtSetBreakAlloc(-1);
|
||||
}
|
||||
};
|
||||
#else
|
||||
class LeakDetector {};
|
||||
#endif
|
||||
|
||||
LeakDetector leakDetector;
|
||||
|
||||
#include "internal/catch_impl.hpp"
|
||||
#endif
|
||||
|
||||
@ -92,8 +116,8 @@
|
||||
#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
|
||||
#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg )
|
||||
#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
|
||||
#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
|
||||
#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
|
||||
#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << Catch::toString(msg), "CATCH_CAPTURE" )
|
||||
#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << Catch::toString(msg), "CATCH_CAPTURE" )
|
||||
|
||||
#ifdef CATCH_CONFIG_VARIADIC_MACROS
|
||||
#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
|
||||
@ -102,6 +126,7 @@
|
||||
#define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
|
||||
#define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
|
||||
#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ )
|
||||
#define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, "CATCH_FAIL_CHECK", __VA_ARGS__ )
|
||||
#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ )
|
||||
#else
|
||||
#define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
|
||||
@ -110,6 +135,7 @@
|
||||
#define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description )
|
||||
#define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
|
||||
#define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg )
|
||||
#define CATCH_FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, "CATCH_FAIL_CHECK", msg )
|
||||
#define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg )
|
||||
#endif
|
||||
#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
|
||||
@ -161,24 +187,26 @@
|
||||
#define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
|
||||
#define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg )
|
||||
#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
|
||||
#define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
|
||||
#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
|
||||
#define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << Catch::toString(msg), "CAPTURE" )
|
||||
#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << Catch::toString(msg), "CAPTURE" )
|
||||
|
||||
#ifdef CATCH_CONFIG_VARIADIC_MACROS
|
||||
#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
|
||||
#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
|
||||
#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
|
||||
#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
|
||||
#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
|
||||
#define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ )
|
||||
#define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ )
|
||||
#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
|
||||
#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
|
||||
#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
|
||||
#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
|
||||
#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
|
||||
#define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ )
|
||||
#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, "FAIL_CHECK", __VA_ARGS__ )
|
||||
#define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ )
|
||||
#else
|
||||
#define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
|
||||
#define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
|
||||
#define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
|
||||
#define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
|
||||
#define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description )
|
||||
#define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
|
||||
#define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg )
|
||||
#define FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, "FAIL_CHECK", msg )
|
||||
#define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg )
|
||||
#endif
|
||||
#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
|
||||
|
9
include/external/clara.h
vendored
9
include/external/clara.h
vendored
@ -41,6 +41,7 @@
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
|
||||
// Use optional outer namespace
|
||||
#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
|
||||
@ -397,7 +398,7 @@ namespace Clara {
|
||||
_dest = _source;
|
||||
}
|
||||
char toLowerCh(char c) {
|
||||
return static_cast<char>( ::tolower( c ) );
|
||||
return static_cast<char>( std::tolower( c ) );
|
||||
}
|
||||
inline void convertInto( std::string const& _source, bool& _dest ) {
|
||||
std::string sourceLC = _source;
|
||||
@ -553,12 +554,13 @@ namespace Clara {
|
||||
}
|
||||
|
||||
void parseIntoTokens( std::string const& arg, std::vector<Token>& tokens ) {
|
||||
for( std::size_t i = 0; i <= arg.size(); ++i ) {
|
||||
for( std::size_t i = 0; i < arg.size(); ++i ) {
|
||||
char c = arg[i];
|
||||
if( c == '"' )
|
||||
inQuotes = !inQuotes;
|
||||
mode = handleMode( i, c, arg, tokens );
|
||||
}
|
||||
mode = handleMode( arg.size(), '\0', arg, tokens );
|
||||
}
|
||||
Mode handleMode( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
|
||||
switch( mode ) {
|
||||
@ -591,6 +593,7 @@ namespace Clara {
|
||||
default: from = i; return ShortOpt;
|
||||
}
|
||||
}
|
||||
|
||||
Mode handleOpt( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
|
||||
if( std::string( ":=\0", 3 ).find( c ) == std::string::npos )
|
||||
return mode;
|
||||
@ -924,7 +927,7 @@ namespace Clara {
|
||||
}
|
||||
|
||||
std::vector<Parser::Token> parseInto( std::vector<std::string> const& args, ConfigT& config ) const {
|
||||
std::string processName = args[0];
|
||||
std::string processName = args.empty() ? std::string() : args[0];
|
||||
std::size_t lastSlash = processName.find_last_of( "/\\" );
|
||||
if( lastSlash != std::string::npos )
|
||||
processName = processName.substr( lastSlash+1 );
|
||||
|
@ -24,12 +24,14 @@ namespace Detail {
|
||||
public:
|
||||
explicit Approx ( double value )
|
||||
: m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
|
||||
m_margin( 0.0 ),
|
||||
m_scale( 1.0 ),
|
||||
m_value( value )
|
||||
{}
|
||||
|
||||
Approx( Approx const& other )
|
||||
: m_epsilon( other.m_epsilon ),
|
||||
m_margin( other.m_margin ),
|
||||
m_scale( other.m_scale ),
|
||||
m_value( other.m_value )
|
||||
{}
|
||||
@ -41,6 +43,7 @@ namespace Detail {
|
||||
Approx operator()( double value ) {
|
||||
Approx approx( value );
|
||||
approx.epsilon( m_epsilon );
|
||||
approx.margin( m_margin );
|
||||
approx.scale( m_scale );
|
||||
return approx;
|
||||
}
|
||||
@ -50,7 +53,11 @@ namespace Detail {
|
||||
friend bool operator == ( const T& lhs, Approx const& rhs ) {
|
||||
// Thanks to Richard Harris for his help refining this formula
|
||||
auto lhs_v = double(lhs);
|
||||
return std::fabs( lhs_v - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( std::fabs(lhs_v), std::fabs(rhs.m_value) ) );
|
||||
bool relativeOK = std::fabs(lhs_v - rhs.m_value) < rhs.m_epsilon * (rhs.m_scale + (std::max)(std::fabs(lhs_v), std::fabs(rhs.m_value)));
|
||||
if (relativeOK) {
|
||||
return true;
|
||||
}
|
||||
return std::fabs(lhs_v - rhs.m_value) < rhs.m_margin;
|
||||
}
|
||||
|
||||
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||
@ -94,7 +101,11 @@ namespace Detail {
|
||||
#else
|
||||
friend bool operator == ( double lhs, Approx const& rhs ) {
|
||||
// Thanks to Richard Harris for his help refining this formula
|
||||
return std::fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( std::fabs(lhs), std::fabs(rhs.m_value) ) );
|
||||
bool relativeOK = std::fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( std::fabs(lhs), std::fabs(rhs.m_value) ) );
|
||||
if (relativeOK) {
|
||||
return true;
|
||||
}
|
||||
return std::fabs(lhs - rhs.m_value) < rhs.m_margin;
|
||||
}
|
||||
|
||||
friend bool operator == ( Approx const& lhs, double rhs ) {
|
||||
@ -135,6 +146,11 @@ namespace Detail {
|
||||
return *this;
|
||||
}
|
||||
|
||||
Approx& margin( double newMargin ) {
|
||||
m_margin = newMargin;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Approx& scale( double newScale ) {
|
||||
m_scale = newScale;
|
||||
return *this;
|
||||
@ -148,6 +164,7 @@ namespace Detail {
|
||||
|
||||
private:
|
||||
double m_epsilon;
|
||||
double m_margin;
|
||||
double m_scale;
|
||||
double m_value;
|
||||
};
|
||||
|
@ -32,6 +32,9 @@ namespace Catch {
|
||||
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& );
|
||||
|
||||
private:
|
||||
DecomposedExpression& operator = (DecomposedExpression const&);
|
||||
};
|
||||
|
||||
struct AssertionInfo
|
||||
|
@ -19,6 +19,14 @@
|
||||
#include "catch_type_traits.hpp"
|
||||
|
||||
|
||||
#if defined(CATCH_CONFIG_FAST_COMPILE)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// We can speedup compilation significantly by breaking into debugger lower in
|
||||
// the callstack, because then we don't have to expand CATCH_BREAK_INTO_DEBUGGER
|
||||
// macro in each assertion
|
||||
#define INTERNAL_CATCH_REACT( resultBuilder ) \
|
||||
resultBuilder.react();
|
||||
#else
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// In the event of a failure works out if the debugger needs to be invoked
|
||||
// and/or an exception thrown and takes appropriate action.
|
||||
@ -26,7 +34,8 @@
|
||||
// source code rather than in Catch library code
|
||||
#define INTERNAL_CATCH_REACT( resultBuilder ) \
|
||||
if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
|
||||
resultBuilder.react();
|
||||
resultBuilder.react();
|
||||
#endif
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -36,6 +45,7 @@
|
||||
try { \
|
||||
CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
|
||||
( __catchResult <= expr ).endExpression(); \
|
||||
CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
|
||||
} \
|
||||
catch( ... ) { \
|
||||
__catchResult.useActiveException( resultDisposition ); \
|
||||
|
@ -24,8 +24,6 @@
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
#include "catch_compiler_capabilities.h"
|
||||
|
||||
namespace Catch {
|
||||
|
||||
struct IConfig;
|
||||
|
@ -27,6 +27,7 @@
|
||||
// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
|
||||
// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
|
||||
// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
|
||||
// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
|
||||
// ****************
|
||||
// Note to maintainers: if new toggles are added please document them
|
||||
// in configuration.md, too
|
||||
@ -62,11 +63,30 @@
|
||||
# endif
|
||||
|
||||
# if defined(CATCH_CPP11_OR_GREATER)
|
||||
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
|
||||
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
|
||||
_Pragma( "clang diagnostic push" ) \
|
||||
_Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
|
||||
# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
|
||||
_Pragma( "clang diagnostic pop" )
|
||||
# endif
|
||||
|
||||
#endif // __clang__
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Cygwin
|
||||
#ifdef __CYGWIN__
|
||||
|
||||
# if !defined(CATCH_CONFIG_POSIX_SIGNALS)
|
||||
# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
|
||||
# endif
|
||||
|
||||
// Required for some versions of Cygwin to declare gettimeofday
|
||||
// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
|
||||
# define _BSD_SOURCE
|
||||
|
||||
#endif // __CYGWIN__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Borland
|
||||
#ifdef __BORLANDC__
|
||||
@ -92,14 +112,24 @@
|
||||
// GCC
|
||||
#ifdef __GNUC__
|
||||
|
||||
# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
# define CATCH_GCC_HAS_NEW_PRAGMA
|
||||
# endif
|
||||
|
||||
# if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
|
||||
# endif
|
||||
|
||||
# if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) && defined(CATCH_CPP11_OR_GREATER)
|
||||
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "GCC diagnostic ignored \"-Wparentheses\"" )
|
||||
# if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) && defined(CATCH_GCC_HAS_NEW_PRAGMA)
|
||||
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
|
||||
_Pragma( "GCC diagnostic push" ) \
|
||||
_Pragma( "GCC diagnostic ignored \"-Wparentheses\"" )
|
||||
# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
|
||||
_Pragma( "GCC diagnostic pop" )
|
||||
# endif
|
||||
|
||||
|
||||
|
||||
// - otherwise more recent versions define __cplusplus >= 201103L
|
||||
// and will get picked up below
|
||||
|
||||
@ -239,9 +269,14 @@
|
||||
#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH)
|
||||
# define CATCH_CONFIG_WINDOWS_SEH
|
||||
#endif
|
||||
// This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
|
||||
#if !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
|
||||
# define CATCH_CONFIG_POSIX_SIGNALS
|
||||
#endif
|
||||
|
||||
#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
|
||||
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
|
||||
# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
|
||||
#endif
|
||||
|
||||
// noexcept support:
|
||||
|
@ -9,6 +9,7 @@
|
||||
#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
|
||||
|
||||
#include "catch_console_colour.hpp"
|
||||
#include "catch_errno_guard.hpp"
|
||||
|
||||
namespace Catch {
|
||||
namespace {
|
||||
@ -148,6 +149,7 @@ namespace {
|
||||
};
|
||||
|
||||
IColourImpl* platformColourInstance() {
|
||||
ErrnoGuard guard;
|
||||
Ptr<IConfig const> config = getCurrentContext().getConfig();
|
||||
UseColour::YesOrNo colourMode = config
|
||||
? config->useColour()
|
||||
|
@ -10,6 +10,7 @@
|
||||
#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
|
||||
|
||||
#include "catch_debugger.h"
|
||||
#include "catch_errno_guard.hpp"
|
||||
|
||||
#ifdef CATCH_PLATFORM_MAC
|
||||
|
||||
@ -72,6 +73,9 @@
|
||||
// be strace, for example) in /proc/$PID/status, so just get it from
|
||||
// there instead.
|
||||
bool isDebuggerActive(){
|
||||
// Libstdc++ has a bug, where std::ifstream sets errno to 0
|
||||
// This way our users can properly assert over errno values
|
||||
ErrnoGuard guard;
|
||||
std::ifstream in("/proc/self/status");
|
||||
for( std::string line; std::getline(in, line); ) {
|
||||
static const int PREFIX_LEN = 11;
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
// Standard C/C++ main entry point
|
||||
int main (int argc, char * argv[]) {
|
||||
int result = Catch::Session().run( argc, argv );
|
||||
int result = Catch::Session().run( argc, argv );
|
||||
return ( result < 0xff ? result : 0xff );
|
||||
}
|
||||
|
||||
|
25
include/internal/catch_errno_guard.hpp
Normal file
25
include/internal/catch_errno_guard.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Created by Martin on 06/03/2017.
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef TWOBLUECUBES_CATCH_ERRNO_GUARD_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_ERRNO_GUARD_HPP_INCLUDED
|
||||
|
||||
#include <cerrno>
|
||||
|
||||
|
||||
namespace Catch {
|
||||
|
||||
class ErrnoGuard {
|
||||
public:
|
||||
ErrnoGuard():m_oldErrno(errno){}
|
||||
~ErrnoGuard() { errno = m_oldErrno; }
|
||||
private:
|
||||
int m_oldErrno;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_ERRNO_GUARD_HPP_INCLUDED
|
@ -11,6 +11,7 @@
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
|
||||
#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
|
||||
#endif
|
||||
|
||||
#include <cstddef>
|
||||
|
@ -27,6 +27,8 @@ class ExpressionLhs : public DecomposedExpression {
|
||||
public:
|
||||
ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ), m_truthy(false) {}
|
||||
|
||||
ExpressionLhs& operator = ( const ExpressionLhs& );
|
||||
|
||||
template<typename RhsT>
|
||||
BinaryExpression<T, Internal::IsEqualTo, RhsT const&>
|
||||
operator == ( RhsT const& rhs ) {
|
||||
@ -105,6 +107,8 @@ public:
|
||||
BinaryExpression( ResultBuilder& rb, LhsT lhs, RhsT rhs )
|
||||
: m_rb( rb ), m_lhs( lhs ), m_rhs( rhs ) {}
|
||||
|
||||
BinaryExpression& operator = ( BinaryExpression& );
|
||||
|
||||
void endExpression() const {
|
||||
m_rb
|
||||
.setResultType( Internal::compare<Op>( m_lhs, m_rhs ) )
|
||||
|
@ -53,7 +53,6 @@ namespace Catch {
|
||||
static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
|
||||
for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
||||
if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
|
||||
reset();
|
||||
reportFatal(signalDefs[i].name);
|
||||
}
|
||||
}
|
||||
@ -103,6 +102,17 @@ namespace Catch {
|
||||
|
||||
#else // Not Windows - assumed to be POSIX compatible //////////////////////////
|
||||
|
||||
# if !defined(CATCH_CONFIG_POSIX_SIGNALS)
|
||||
|
||||
namespace Catch {
|
||||
struct FatalConditionHandler {
|
||||
void reset() {}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
# else // CATCH_CONFIG_POSIX_SIGNALS is defined
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
namespace Catch {
|
||||
@ -183,6 +193,8 @@ namespace Catch {
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
# endif // CATCH_CONFIG_POSIX_SIGNALS
|
||||
|
||||
#endif // not Windows
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "catch_result_builder.hpp"
|
||||
#include "catch_tag_alias_registry.hpp"
|
||||
#include "catch_test_case_tracker.hpp"
|
||||
#include "catch_matchers_string.hpp"
|
||||
|
||||
#include "../reporters/catch_reporter_multi.hpp"
|
||||
#include "../reporters/catch_reporter_xml.hpp"
|
||||
@ -90,11 +91,7 @@ namespace Catch {
|
||||
TestSpec::NamePattern::~NamePattern() {}
|
||||
TestSpec::TagPattern::~TagPattern() {}
|
||||
TestSpec::ExcludedPattern::~ExcludedPattern() {}
|
||||
|
||||
Matchers::Impl::StdString::Equals::~Equals() {}
|
||||
Matchers::Impl::StdString::Contains::~Contains() {}
|
||||
Matchers::Impl::StdString::StartsWith::~StartsWith() {}
|
||||
Matchers::Impl::StdString::EndsWith::~EndsWith() {}
|
||||
Matchers::Impl::MatcherUntypedBase::~MatcherUntypedBase() {}
|
||||
|
||||
void Config::dummy() {}
|
||||
|
||||
|
@ -8,318 +8,169 @@
|
||||
#ifndef TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
|
||||
|
||||
#include "catch_common.h"
|
||||
|
||||
namespace Catch {
|
||||
namespace Matchers {
|
||||
namespace Impl {
|
||||
|
||||
namespace Generic {
|
||||
template<typename ExpressionT> class AllOf;
|
||||
template<typename ExpressionT> class AnyOf;
|
||||
template<typename ExpressionT> class Not;
|
||||
}
|
||||
template<typename ArgT> struct MatchAllOf;
|
||||
template<typename ArgT> struct MatchAnyOf;
|
||||
template<typename ArgT> struct MatchNotOf;
|
||||
|
||||
template<typename ExpressionT>
|
||||
struct Matcher : SharedImpl<IShared>
|
||||
{
|
||||
typedef ExpressionT ExpressionType;
|
||||
|
||||
virtual ~Matcher() {}
|
||||
virtual Ptr<Matcher> clone() const = 0;
|
||||
virtual bool match( ExpressionT const& expr ) const = 0;
|
||||
virtual std::string toString() const = 0;
|
||||
|
||||
Generic::AllOf<ExpressionT> operator && ( Matcher<ExpressionT> const& other ) const;
|
||||
Generic::AnyOf<ExpressionT> operator || ( Matcher<ExpressionT> const& other ) const;
|
||||
Generic::Not<ExpressionT> operator ! () const;
|
||||
};
|
||||
|
||||
template<typename DerivedT, typename ExpressionT>
|
||||
struct MatcherImpl : Matcher<ExpressionT> {
|
||||
|
||||
virtual Ptr<Matcher<ExpressionT> > clone() const {
|
||||
return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) );
|
||||
}
|
||||
};
|
||||
|
||||
namespace Generic {
|
||||
template<typename ExpressionT>
|
||||
class Not : public MatcherImpl<Not<ExpressionT>, ExpressionT> {
|
||||
class MatcherUntypedBase {
|
||||
public:
|
||||
explicit Not( Matcher<ExpressionT> const& matcher ) : m_matcher(matcher.clone()) {}
|
||||
Not( Not const& other ) : m_matcher( other.m_matcher ) {}
|
||||
|
||||
virtual bool match( ExpressionT const& expr ) const CATCH_OVERRIDE {
|
||||
return !m_matcher->match( expr );
|
||||
std::string toString() const {
|
||||
if( m_cachedToString.empty() )
|
||||
m_cachedToString = describe();
|
||||
return m_cachedToString;
|
||||
}
|
||||
|
||||
virtual std::string toString() const CATCH_OVERRIDE {
|
||||
return "not " + m_matcher->toString();
|
||||
}
|
||||
protected:
|
||||
virtual ~MatcherUntypedBase();
|
||||
virtual std::string describe() const = 0;
|
||||
mutable std::string m_cachedToString;
|
||||
private:
|
||||
Ptr< Matcher<ExpressionT> > m_matcher;
|
||||
MatcherUntypedBase& operator = ( MatcherUntypedBase const& );
|
||||
};
|
||||
|
||||
template<typename ExpressionT>
|
||||
class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> {
|
||||
public:
|
||||
template<typename ObjectT>
|
||||
struct MatcherMethod {
|
||||
virtual bool match( ObjectT const& arg ) const = 0;
|
||||
};
|
||||
template<typename PtrT>
|
||||
struct MatcherMethod<PtrT*> {
|
||||
virtual bool match( PtrT* arg ) const = 0;
|
||||
};
|
||||
|
||||
AllOf() {}
|
||||
AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {}
|
||||
template<typename ObjectT, typename ComparatorT = ObjectT>
|
||||
struct MatcherBase : MatcherUntypedBase, MatcherMethod<ObjectT> {
|
||||
|
||||
AllOf& add( Matcher<ExpressionT> const& matcher ) {
|
||||
m_matchers.push_back( matcher.clone() );
|
||||
return *this;
|
||||
}
|
||||
virtual bool match( ExpressionT const& expr ) const
|
||||
{
|
||||
for( std::size_t i = 0; i < m_matchers.size(); ++i )
|
||||
if( !m_matchers[i]->match( expr ) )
|
||||
|
||||
MatchAllOf<ComparatorT> operator && ( MatcherBase const& other ) const;
|
||||
MatchAnyOf<ComparatorT> operator || ( MatcherBase const& other ) const;
|
||||
MatchNotOf<ComparatorT> operator ! () const;
|
||||
};
|
||||
|
||||
template<typename ArgT>
|
||||
struct MatchAllOf : MatcherBase<ArgT> {
|
||||
virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
|
||||
for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
|
||||
if (!m_matchers[i]->match(arg))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
virtual std::string toString() const {
|
||||
std::ostringstream oss;
|
||||
oss << "( ";
|
||||
virtual std::string describe() const CATCH_OVERRIDE {
|
||||
std::string description;
|
||||
description.reserve( 4 + m_matchers.size()*32 );
|
||||
description += "( ";
|
||||
for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
|
||||
if( i != 0 )
|
||||
oss << " and ";
|
||||
oss << m_matchers[i]->toString();
|
||||
description += " and ";
|
||||
description += m_matchers[i]->toString();
|
||||
}
|
||||
oss << " )";
|
||||
return oss.str();
|
||||
description += " )";
|
||||
return description;
|
||||
}
|
||||
|
||||
AllOf operator && ( Matcher<ExpressionT> const& other ) const {
|
||||
AllOf allOfExpr( *this );
|
||||
allOfExpr.add( other );
|
||||
return allOfExpr;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
|
||||
};
|
||||
|
||||
template<typename ExpressionT>
|
||||
class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> {
|
||||
public:
|
||||
|
||||
AnyOf() {}
|
||||
AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {}
|
||||
|
||||
AnyOf& add( Matcher<ExpressionT> const& matcher ) {
|
||||
m_matchers.push_back( matcher.clone() );
|
||||
MatchAllOf<ArgT>& operator && ( MatcherBase<ArgT> const& other ) {
|
||||
m_matchers.push_back( &other );
|
||||
return *this;
|
||||
}
|
||||
virtual bool match( ExpressionT const& expr ) const
|
||||
{
|
||||
for( std::size_t i = 0; i < m_matchers.size(); ++i )
|
||||
if( m_matchers[i]->match( expr ) )
|
||||
|
||||
std::vector<MatcherBase<ArgT> const*> m_matchers;
|
||||
};
|
||||
template<typename ArgT>
|
||||
struct MatchAnyOf : MatcherBase<ArgT> {
|
||||
|
||||
virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
|
||||
for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
|
||||
if (m_matchers[i]->match(arg))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
virtual std::string toString() const {
|
||||
std::ostringstream oss;
|
||||
oss << "( ";
|
||||
virtual std::string describe() const CATCH_OVERRIDE {
|
||||
std::string description;
|
||||
description.reserve( 4 + m_matchers.size()*32 );
|
||||
description += "( ";
|
||||
for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
|
||||
if( i != 0 )
|
||||
oss << " or ";
|
||||
oss << m_matchers[i]->toString();
|
||||
description += " or ";
|
||||
description += m_matchers[i]->toString();
|
||||
}
|
||||
oss << " )";
|
||||
return oss.str();
|
||||
description += " )";
|
||||
return description;
|
||||
}
|
||||
|
||||
AnyOf operator || ( Matcher<ExpressionT> const& other ) const {
|
||||
AnyOf anyOfExpr( *this );
|
||||
anyOfExpr.add( other );
|
||||
return anyOfExpr;
|
||||
MatchAnyOf<ArgT>& operator || ( MatcherBase<ArgT> const& other ) {
|
||||
m_matchers.push_back( &other );
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
|
||||
std::vector<MatcherBase<ArgT> const*> m_matchers;
|
||||
};
|
||||
|
||||
} // namespace Generic
|
||||
template<typename ArgT>
|
||||
struct MatchNotOf : MatcherBase<ArgT> {
|
||||
|
||||
template<typename ExpressionT>
|
||||
Generic::AllOf<ExpressionT> Matcher<ExpressionT>::operator && ( Matcher<ExpressionT> const& other ) const {
|
||||
Generic::AllOf<ExpressionT> allOfExpr;
|
||||
allOfExpr.add( *this );
|
||||
allOfExpr.add( other );
|
||||
return allOfExpr;
|
||||
}
|
||||
|
||||
template<typename ExpressionT>
|
||||
Generic::AnyOf<ExpressionT> Matcher<ExpressionT>::operator || ( Matcher<ExpressionT> const& other ) const {
|
||||
Generic::AnyOf<ExpressionT> anyOfExpr;
|
||||
anyOfExpr.add( *this );
|
||||
anyOfExpr.add( other );
|
||||
return anyOfExpr;
|
||||
}
|
||||
|
||||
template<typename ExpressionT>
|
||||
Generic::Not<ExpressionT> Matcher<ExpressionT>::operator ! () const {
|
||||
return Generic::Not<ExpressionT>( *this );
|
||||
}
|
||||
|
||||
|
||||
namespace StdString {
|
||||
|
||||
inline std::string makeString( std::string const& str ) { return str; }
|
||||
inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); }
|
||||
|
||||
struct CasedString
|
||||
{
|
||||
CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
|
||||
: m_caseSensitivity( caseSensitivity ),
|
||||
m_str( adjustString( str ) )
|
||||
{}
|
||||
std::string adjustString( std::string const& str ) const {
|
||||
return m_caseSensitivity == CaseSensitive::No
|
||||
? toLower( str )
|
||||
: str;
|
||||
MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
|
||||
|
||||
virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
|
||||
return !m_underlyingMatcher.match( arg );
|
||||
}
|
||||
std::string toStringSuffix() const
|
||||
{
|
||||
return m_caseSensitivity == CaseSensitive::No
|
||||
? " (case insensitive)"
|
||||
: std::string();
|
||||
|
||||
virtual std::string describe() const CATCH_OVERRIDE {
|
||||
return "not " + m_underlyingMatcher.toString();
|
||||
}
|
||||
CaseSensitive::Choice m_caseSensitivity;
|
||||
std::string m_str;
|
||||
MatcherBase<ArgT> const& m_underlyingMatcher;
|
||||
};
|
||||
|
||||
struct Equals : MatcherImpl<Equals, std::string> {
|
||||
Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
|
||||
: m_data( str, caseSensitivity )
|
||||
{}
|
||||
Equals( Equals const& other ) : m_data( other.m_data ){}
|
||||
template<typename ObjectT, typename ComparatorT>
|
||||
MatchAllOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator && ( MatcherBase const& other ) const {
|
||||
return MatchAllOf<ComparatorT>() && *this && other;
|
||||
}
|
||||
template<typename ObjectT, typename ComparatorT>
|
||||
MatchAnyOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator || ( MatcherBase const& other ) const {
|
||||
return MatchAnyOf<ComparatorT>() || *this || other;
|
||||
}
|
||||
template<typename ObjectT, typename ComparatorT>
|
||||
MatchNotOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator ! () const {
|
||||
return MatchNotOf<ComparatorT>( *this );
|
||||
}
|
||||
|
||||
virtual ~Equals();
|
||||
|
||||
virtual bool match( std::string const& expr ) const {
|
||||
return m_data.m_str == m_data.adjustString( expr );;
|
||||
}
|
||||
virtual std::string toString() const {
|
||||
return "equals: \"" + m_data.m_str + '"' + m_data.toStringSuffix();
|
||||
}
|
||||
|
||||
CasedString m_data;
|
||||
};
|
||||
|
||||
struct Contains : MatcherImpl<Contains, std::string> {
|
||||
Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
|
||||
: m_data( substr, caseSensitivity ){}
|
||||
Contains( Contains const& other ) : m_data( other.m_data ){}
|
||||
|
||||
virtual ~Contains();
|
||||
|
||||
virtual bool match( std::string const& expr ) const {
|
||||
return m_data.adjustString( expr ).find( m_data.m_str ) != std::string::npos;
|
||||
}
|
||||
virtual std::string toString() const {
|
||||
return "contains: \"" + m_data.m_str + '"' + m_data.toStringSuffix();
|
||||
}
|
||||
|
||||
CasedString m_data;
|
||||
};
|
||||
|
||||
struct StartsWith : MatcherImpl<StartsWith, std::string> {
|
||||
StartsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
|
||||
: m_data( substr, caseSensitivity ){}
|
||||
|
||||
StartsWith( StartsWith const& other ) : m_data( other.m_data ){}
|
||||
|
||||
virtual ~StartsWith();
|
||||
|
||||
virtual bool match( std::string const& expr ) const {
|
||||
return startsWith( m_data.adjustString( expr ), m_data.m_str );
|
||||
}
|
||||
virtual std::string toString() const {
|
||||
return "starts with: \"" + m_data.m_str + '"' + m_data.toStringSuffix();
|
||||
}
|
||||
|
||||
CasedString m_data;
|
||||
};
|
||||
|
||||
struct EndsWith : MatcherImpl<EndsWith, std::string> {
|
||||
EndsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
|
||||
: m_data( substr, caseSensitivity ){}
|
||||
EndsWith( EndsWith const& other ) : m_data( other.m_data ){}
|
||||
|
||||
virtual ~EndsWith();
|
||||
|
||||
virtual bool match( std::string const& expr ) const {
|
||||
return endsWith( m_data.adjustString( expr ), m_data.m_str );
|
||||
}
|
||||
virtual std::string toString() const {
|
||||
return "ends with: \"" + m_data.m_str + '"' + m_data.toStringSuffix();
|
||||
}
|
||||
|
||||
CasedString m_data;
|
||||
};
|
||||
} // namespace StdString
|
||||
} // namespace Impl
|
||||
|
||||
|
||||
// The following functions create the actual matcher objects.
|
||||
// This allows the types to be inferred
|
||||
template<typename ExpressionT>
|
||||
inline Impl::Generic::Not<ExpressionT> Not( Impl::Matcher<ExpressionT> const& m ) {
|
||||
return Impl::Generic::Not<ExpressionT>( m );
|
||||
// - deprecated: prefer ||, && and !
|
||||
template<typename T>
|
||||
inline Impl::MatchNotOf<T> Not( Impl::MatcherBase<T> const& underlyingMatcher ) {
|
||||
return Impl::MatchNotOf<T>( underlyingMatcher );
|
||||
}
|
||||
|
||||
template<typename ExpressionT>
|
||||
inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
|
||||
Impl::Matcher<ExpressionT> const& m2 ) {
|
||||
return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 );
|
||||
template<typename T>
|
||||
inline Impl::MatchAllOf<T> AllOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2 ) {
|
||||
return Impl::MatchAllOf<T>() && m1 && m2;
|
||||
}
|
||||
template<typename ExpressionT>
|
||||
inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
|
||||
Impl::Matcher<ExpressionT> const& m2,
|
||||
Impl::Matcher<ExpressionT> const& m3 ) {
|
||||
return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
|
||||
template<typename T>
|
||||
inline Impl::MatchAllOf<T> AllOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2, Impl::MatcherBase<T> const& m3 ) {
|
||||
return Impl::MatchAllOf<T>() && m1 && m2 && m3;
|
||||
}
|
||||
template<typename ExpressionT>
|
||||
inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
|
||||
Impl::Matcher<ExpressionT> const& m2 ) {
|
||||
return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 );
|
||||
template<typename T>
|
||||
inline Impl::MatchAnyOf<T> AnyOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2 ) {
|
||||
return Impl::MatchAnyOf<T>() || m1 || m2;
|
||||
}
|
||||
template<typename ExpressionT>
|
||||
inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
|
||||
Impl::Matcher<ExpressionT> const& m2,
|
||||
Impl::Matcher<ExpressionT> const& m3 ) {
|
||||
return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
|
||||
}
|
||||
|
||||
inline Impl::StdString::Equals Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
|
||||
return Impl::StdString::Equals( str, caseSensitivity );
|
||||
}
|
||||
inline Impl::StdString::Equals Equals( const char* str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
|
||||
return Impl::StdString::Equals( Impl::StdString::makeString( str ), caseSensitivity );
|
||||
}
|
||||
inline Impl::StdString::Contains Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
|
||||
return Impl::StdString::Contains( substr, caseSensitivity );
|
||||
}
|
||||
inline Impl::StdString::Contains Contains( const char* substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
|
||||
return Impl::StdString::Contains( Impl::StdString::makeString( substr ), caseSensitivity );
|
||||
}
|
||||
inline Impl::StdString::StartsWith StartsWith( std::string const& substr ) {
|
||||
return Impl::StdString::StartsWith( substr );
|
||||
}
|
||||
inline Impl::StdString::StartsWith StartsWith( const char* substr ) {
|
||||
return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) );
|
||||
}
|
||||
inline Impl::StdString::EndsWith EndsWith( std::string const& substr ) {
|
||||
return Impl::StdString::EndsWith( substr );
|
||||
}
|
||||
inline Impl::StdString::EndsWith EndsWith( const char* substr ) {
|
||||
return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) );
|
||||
template<typename T>
|
||||
inline Impl::MatchAnyOf<T> AnyOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2, Impl::MatcherBase<T> const& m3 ) {
|
||||
return Impl::MatchAnyOf<T>() || m1 || m2 || m3;
|
||||
}
|
||||
|
||||
} // namespace Matchers
|
||||
|
||||
using namespace Matchers;
|
||||
using Matchers::Impl::MatcherBase;
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
|
67
include/internal/catch_matchers_string.h
Normal file
67
include/internal/catch_matchers_string.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Created by Phil Nash on 08/02/2017.
|
||||
* Copyright (c) 2017 Two Blue Cubes Ltd. All rights reserved.
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED
|
||||
|
||||
#include "catch_matchers.hpp"
|
||||
|
||||
namespace Catch {
|
||||
namespace Matchers {
|
||||
|
||||
namespace StdString {
|
||||
|
||||
struct CasedString
|
||||
{
|
||||
CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );
|
||||
std::string adjustString( std::string const& str ) const;
|
||||
std::string caseSensitivitySuffix() const;
|
||||
|
||||
CaseSensitive::Choice m_caseSensitivity;
|
||||
std::string m_str;
|
||||
};
|
||||
|
||||
struct StringMatcherBase : MatcherBase<std::string> {
|
||||
StringMatcherBase( std::string const& operation, CasedString const& comparator );
|
||||
virtual std::string describe() const CATCH_OVERRIDE;
|
||||
|
||||
CasedString m_comparator;
|
||||
std::string m_operation;
|
||||
};
|
||||
|
||||
struct EqualsMatcher : StringMatcherBase {
|
||||
EqualsMatcher( CasedString const& comparator );
|
||||
virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
|
||||
};
|
||||
struct ContainsMatcher : StringMatcherBase {
|
||||
ContainsMatcher( CasedString const& comparator );
|
||||
virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
|
||||
};
|
||||
struct StartsWithMatcher : StringMatcherBase {
|
||||
StartsWithMatcher( CasedString const& comparator );
|
||||
virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
|
||||
};
|
||||
struct EndsWithMatcher : StringMatcherBase {
|
||||
EndsWithMatcher( CasedString const& comparator );
|
||||
virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
|
||||
};
|
||||
|
||||
} // namespace StdString
|
||||
|
||||
|
||||
// The following functions create the actual matcher objects.
|
||||
// This allows the types to be inferred
|
||||
|
||||
StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
|
||||
StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
|
||||
StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
|
||||
StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
|
||||
|
||||
} // namespace Matchers
|
||||
} // namespace Catch
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED
|
93
include/internal/catch_matchers_string.hpp
Normal file
93
include/internal/catch_matchers_string.hpp
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Created by Phil Nash on 08/02/2017.
|
||||
* Copyright (c) 2017 Two Blue Cubes Ltd. All rights reserved.
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#include "catch_matchers.hpp"
|
||||
|
||||
namespace Catch {
|
||||
namespace Matchers {
|
||||
|
||||
namespace StdString {
|
||||
|
||||
CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
|
||||
: m_caseSensitivity( caseSensitivity ),
|
||||
m_str( adjustString( str ) )
|
||||
{}
|
||||
std::string CasedString::adjustString( std::string const& str ) const {
|
||||
return m_caseSensitivity == CaseSensitive::No
|
||||
? toLower( str )
|
||||
: str;
|
||||
}
|
||||
std::string CasedString::caseSensitivitySuffix() const {
|
||||
return m_caseSensitivity == CaseSensitive::No
|
||||
? " (case insensitive)"
|
||||
: std::string();
|
||||
}
|
||||
|
||||
|
||||
StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )
|
||||
: m_comparator( comparator ),
|
||||
m_operation( operation ) {
|
||||
}
|
||||
|
||||
std::string StringMatcherBase::describe() const {
|
||||
std::string description;
|
||||
description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
|
||||
m_comparator.caseSensitivitySuffix().size());
|
||||
description += m_operation;
|
||||
description += ": \"";
|
||||
description += m_comparator.m_str;
|
||||
description += "\"";
|
||||
description += m_comparator.caseSensitivitySuffix();
|
||||
return description;
|
||||
}
|
||||
|
||||
EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {}
|
||||
|
||||
bool EqualsMatcher::match( std::string const& source ) const {
|
||||
return m_comparator.adjustString( source ) == m_comparator.m_str;
|
||||
}
|
||||
|
||||
|
||||
ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {}
|
||||
|
||||
bool ContainsMatcher::match( std::string const& source ) const {
|
||||
return contains( m_comparator.adjustString( source ), m_comparator.m_str );
|
||||
}
|
||||
|
||||
|
||||
StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {}
|
||||
|
||||
bool StartsWithMatcher::match( std::string const& source ) const {
|
||||
return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
|
||||
}
|
||||
|
||||
|
||||
EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {}
|
||||
|
||||
bool EndsWithMatcher::match( std::string const& source ) const {
|
||||
return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
|
||||
}
|
||||
|
||||
} // namespace StdString
|
||||
|
||||
|
||||
StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
|
||||
return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
|
||||
}
|
||||
StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
|
||||
return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
|
||||
}
|
||||
StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
|
||||
return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
|
||||
}
|
||||
StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
|
||||
return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
|
||||
}
|
||||
|
||||
} // namespace Matchers
|
||||
} // namespace Catch
|
101
include/internal/catch_matchers_vector.h
Normal file
101
include/internal/catch_matchers_vector.h
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Created by Phil Nash on 21/02/2017.
|
||||
* Copyright (c) 2017 Two Blue Cubes Ltd. All rights reserved.
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
|
||||
|
||||
#include "catch_matchers.hpp"
|
||||
|
||||
namespace Catch {
|
||||
namespace Matchers {
|
||||
|
||||
namespace Vector {
|
||||
|
||||
template<typename T>
|
||||
struct ContainsElementMatcher : MatcherBase<std::vector<T>, T> {
|
||||
|
||||
ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
|
||||
|
||||
bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
|
||||
return std::find(v.begin(), v.end(), m_comparator) != v.end();
|
||||
}
|
||||
|
||||
virtual std::string describe() const CATCH_OVERRIDE {
|
||||
return "Contains: " + Catch::toString( m_comparator );
|
||||
}
|
||||
|
||||
T const& m_comparator;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ContainsMatcher : MatcherBase<std::vector<T>, std::vector<T> > {
|
||||
|
||||
ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
|
||||
|
||||
bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
|
||||
// !TBD: see note in EqualsMatcher
|
||||
if (m_comparator.size() > v.size())
|
||||
return false;
|
||||
for (size_t i = 0; i < m_comparator.size(); ++i)
|
||||
if (std::find(v.begin(), v.end(), m_comparator[i]) == v.end())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
virtual std::string describe() const CATCH_OVERRIDE {
|
||||
return "Contains: " + Catch::toString( m_comparator );
|
||||
}
|
||||
|
||||
std::vector<T> const& m_comparator;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct EqualsMatcher : MatcherBase<std::vector<T>, std::vector<T> > {
|
||||
|
||||
EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
|
||||
|
||||
bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
|
||||
// !TBD: This currently works if all elements can be compared using !=
|
||||
// - a more general approach would be via a compare template that defaults
|
||||
// to using !=. but could be specialised for, e.g. std::vector<T> etc
|
||||
// - then just call that directly
|
||||
if (m_comparator.size() != v.size())
|
||||
return false;
|
||||
for (size_t i = 0; i < v.size(); ++i)
|
||||
if (m_comparator[i] != v[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
virtual std::string describe() const CATCH_OVERRIDE {
|
||||
return "Equals: " + Catch::toString( m_comparator );
|
||||
}
|
||||
std::vector<T> const& m_comparator;
|
||||
};
|
||||
|
||||
} // namespace Vector
|
||||
|
||||
// The following functions create the actual matcher objects.
|
||||
// This allows the types to be inferred
|
||||
|
||||
template<typename T>
|
||||
Vector::ContainsMatcher<T> Contains( std::vector<T> const& comparator ) {
|
||||
return Vector::ContainsMatcher<T>( comparator );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Vector::ContainsElementMatcher<T> VectorContains( T const& comparator ) {
|
||||
return Vector::ContainsElementMatcher<T>( comparator );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Vector::EqualsMatcher<T> Equals( std::vector<T> const& comparator ) {
|
||||
return Vector::EqualsMatcher<T>( comparator );
|
||||
}
|
||||
|
||||
} // namespace Matchers
|
||||
} // namespace Catch
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
|
@ -104,65 +104,68 @@ namespace Catch {
|
||||
namespace Matchers {
|
||||
namespace Impl {
|
||||
namespace NSStringMatchers {
|
||||
|
||||
template<typename MatcherT>
|
||||
struct StringHolder : MatcherImpl<MatcherT, NSString*>{
|
||||
|
||||
struct StringHolder : MatcherBase<NSString*>{
|
||||
StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
|
||||
StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
|
||||
StringHolder() {
|
||||
arcSafeRelease( m_substr );
|
||||
}
|
||||
|
||||
virtual bool match( NSString* arg ) const CATCH_OVERRIDE {
|
||||
return false;
|
||||
}
|
||||
|
||||
NSString* m_substr;
|
||||
};
|
||||
|
||||
struct Equals : StringHolder<Equals> {
|
||||
struct Equals : StringHolder {
|
||||
Equals( NSString* substr ) : StringHolder( substr ){}
|
||||
|
||||
virtual bool match( ExpressionType const& str ) const {
|
||||
virtual bool match( NSString* str ) const CATCH_OVERRIDE {
|
||||
return (str != nil || m_substr == nil ) &&
|
||||
[str isEqualToString:m_substr];
|
||||
}
|
||||
|
||||
virtual std::string toString() const {
|
||||
virtual std::string describe() const CATCH_OVERRIDE {
|
||||
return "equals string: " + Catch::toString( m_substr );
|
||||
}
|
||||
};
|
||||
|
||||
struct Contains : StringHolder<Contains> {
|
||||
struct Contains : StringHolder {
|
||||
Contains( NSString* substr ) : StringHolder( substr ){}
|
||||
|
||||
virtual bool match( ExpressionType const& str ) const {
|
||||
virtual bool match( NSString* str ) const {
|
||||
return (str != nil || m_substr == nil ) &&
|
||||
[str rangeOfString:m_substr].location != NSNotFound;
|
||||
}
|
||||
|
||||
virtual std::string toString() const {
|
||||
virtual std::string describe() const CATCH_OVERRIDE {
|
||||
return "contains string: " + Catch::toString( m_substr );
|
||||
}
|
||||
};
|
||||
|
||||
struct StartsWith : StringHolder<StartsWith> {
|
||||
struct StartsWith : StringHolder {
|
||||
StartsWith( NSString* substr ) : StringHolder( substr ){}
|
||||
|
||||
virtual bool match( ExpressionType const& str ) const {
|
||||
virtual bool match( NSString* str ) const {
|
||||
return (str != nil || m_substr == nil ) &&
|
||||
[str rangeOfString:m_substr].location == 0;
|
||||
}
|
||||
|
||||
virtual std::string toString() const {
|
||||
virtual std::string describe() const CATCH_OVERRIDE {
|
||||
return "starts with: " + Catch::toString( m_substr );
|
||||
}
|
||||
};
|
||||
struct EndsWith : StringHolder<EndsWith> {
|
||||
struct EndsWith : StringHolder {
|
||||
EndsWith( NSString* substr ) : StringHolder( substr ){}
|
||||
|
||||
virtual bool match( ExpressionType const& str ) const {
|
||||
virtual bool match( NSString* str ) const {
|
||||
return (str != nil || m_substr == nil ) &&
|
||||
[str rangeOfString:m_substr].location == [str length] - [m_substr length];
|
||||
}
|
||||
|
||||
virtual std::string toString() const {
|
||||
virtual std::string describe() const CATCH_OVERRIDE {
|
||||
return "ends with: " + Catch::toString( m_substr );
|
||||
}
|
||||
};
|
||||
|
@ -92,7 +92,11 @@ namespace Catch {
|
||||
#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
|
||||
namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
|
||||
|
||||
// Deprecated - use the form without INTERNAL_
|
||||
#define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \
|
||||
namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
|
||||
|
||||
#define CATCH_REGISTER_LISTENER( listenerType ) \
|
||||
namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
|
||||
|
@ -64,7 +64,7 @@ namespace Catch {
|
||||
void captureResult( ResultWas::OfType resultType );
|
||||
void captureExpression();
|
||||
void captureExpectedException( std::string const& expectedMessage );
|
||||
void captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher );
|
||||
void captureExpectedException( Matchers::Impl::MatcherBase<std::string> const& matcher );
|
||||
void handleResult( AssertionResult const& result );
|
||||
void react();
|
||||
bool shouldDebugBreak() const;
|
||||
@ -106,6 +106,7 @@ namespace Catch {
|
||||
endExpression( expr );
|
||||
}
|
||||
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
|
||||
|
@ -60,12 +60,13 @@ namespace Catch {
|
||||
|
||||
void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) {
|
||||
if( expectedMessage.empty() )
|
||||
captureExpectedException( Matchers::Impl::Generic::AllOf<std::string>() );
|
||||
captureExpectedException( Matchers::Impl::MatchAllOf<std::string>() );
|
||||
else
|
||||
captureExpectedException( Matchers::Equals( expectedMessage ) );
|
||||
}
|
||||
|
||||
void ResultBuilder::captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher ) {
|
||||
|
||||
void ResultBuilder::captureExpectedException( Matchers::Impl::MatcherBase<std::string> const& matcher ) {
|
||||
|
||||
assert( !isFalseTest( m_assertionInfo.resultDisposition ) );
|
||||
AssertionResultData data = m_data;
|
||||
@ -99,6 +100,15 @@ namespace Catch {
|
||||
}
|
||||
|
||||
void ResultBuilder::react() {
|
||||
#if defined(CATCH_CONFIG_FAST_COMPILE)
|
||||
if (m_shouldDebugBreak) {
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// To inspect the state during test, you need to go one level up the callstack
|
||||
// To go back to the test and change execution, jump over the throw statement
|
||||
///////////////////////////////////////////////////////////////////
|
||||
CATCH_BREAK_INTO_DEBUGGER();
|
||||
}
|
||||
#endif
|
||||
if( m_shouldThrow )
|
||||
throw Catch::TestFailureException();
|
||||
}
|
||||
|
@ -224,10 +224,14 @@ namespace Catch {
|
||||
}
|
||||
|
||||
virtual void handleFatalErrorCondition( std::string const& message ) {
|
||||
ResultBuilder resultBuilder = makeUnexpectedResultBuilder();
|
||||
resultBuilder.setResultType( ResultWas::FatalErrorCondition );
|
||||
resultBuilder << message;
|
||||
resultBuilder.captureExpression();
|
||||
// Don't rebuild the result -- the stringification itself can cause more fatal errors
|
||||
// Instead, fake a result data.
|
||||
AssertionResultData tempResult;
|
||||
tempResult.resultType = ResultWas::FatalErrorCondition;
|
||||
tempResult.message = message;
|
||||
AssertionResult result(m_lastAssertionInfo, tempResult);
|
||||
|
||||
getResultCapture().assertionEnded(result);
|
||||
|
||||
handleUnfinishedSections();
|
||||
|
||||
|
@ -24,6 +24,12 @@
|
||||
#elif defined __GNUC__
|
||||
# pragma GCC diagnostic ignored "-Wvariadic-macros"
|
||||
# pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
|
||||
// For newer version we can use __Pragma to disable the warnings locally
|
||||
# if __GNUC__ == 4 && __GNUC_MINOR__ >= 4 && __GNUC_MINOR__ <= 7
|
||||
# pragma GCC diagnostic ignored "-Wparentheses"
|
||||
# endif
|
||||
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wpadded"
|
||||
#endif
|
||||
|
@ -15,7 +15,7 @@
|
||||
namespace Catch {
|
||||
|
||||
struct TagAlias {
|
||||
TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
|
||||
TagAlias( std::string const& _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
|
||||
|
||||
std::string tag;
|
||||
SourceLineInfo lineInfo;
|
||||
|
@ -97,7 +97,7 @@ namespace Catch {
|
||||
void addPattern() {
|
||||
std::string token = subString();
|
||||
for( size_t i = 0; i < m_escapeChars.size(); ++i )
|
||||
token = token.substr( 0, m_escapeChars[i]-i ) + token.substr( m_escapeChars[i]+1-i );
|
||||
token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 );
|
||||
m_escapeChars.clear();
|
||||
if( startsWith( token, "exclude:" ) ) {
|
||||
m_exclusion = true;
|
||||
|
@ -15,9 +15,13 @@
|
||||
#endif
|
||||
|
||||
#ifdef CATCH_PLATFORM_WINDOWS
|
||||
#include "catch_windows_h_proxy.h"
|
||||
|
||||
# include "catch_windows_h_proxy.h"
|
||||
|
||||
#else
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#endif
|
||||
|
||||
namespace Catch {
|
||||
|
@ -37,7 +37,7 @@ namespace Catch {
|
||||
return os;
|
||||
}
|
||||
|
||||
Version libraryVersion( 1, 7, 2, "", 0 );
|
||||
Version libraryVersion( 1, 8, 2, "", 0 );
|
||||
|
||||
}
|
||||
|
||||
|
62
include/reporters/catch_reporter_automake.hpp
Normal file
62
include/reporters/catch_reporter_automake.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Created by Justin R. Wilson on 2/19/2017.
|
||||
* Copyright 2017 Justin R. Wilson. All rights reserved.
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
|
||||
|
||||
// Don't #include any Catch headers here - we can assume they are already
|
||||
// included before this header.
|
||||
// This is not good practice in general but is necessary in this case so this
|
||||
// file can be distributed as a single header that works with the main
|
||||
// Catch single header.
|
||||
|
||||
namespace Catch {
|
||||
|
||||
struct AutomakeReporter : StreamingReporterBase {
|
||||
AutomakeReporter( ReporterConfig const& _config )
|
||||
: StreamingReporterBase( _config )
|
||||
{}
|
||||
|
||||
virtual ~AutomakeReporter();
|
||||
|
||||
static std::string getDescription() {
|
||||
return "Reports test results in the format of Automake .trs files";
|
||||
}
|
||||
|
||||
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
|
||||
|
||||
virtual bool assertionEnded( AssertionStats const& /*_assertionStats*/ ) CATCH_OVERRIDE { return true; }
|
||||
|
||||
virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE {
|
||||
// Possible values to emit are PASS, XFAIL, SKIP, FAIL, XPASS and ERROR.
|
||||
stream << ":test-result: ";
|
||||
if (_testCaseStats.totals.assertions.allPassed()) {
|
||||
stream << "PASS";
|
||||
} else if (_testCaseStats.totals.assertions.allOk()) {
|
||||
stream << "XFAIL";
|
||||
} else {
|
||||
stream << "FAIL";
|
||||
}
|
||||
stream << ' ' << _testCaseStats.testInfo.name << '\n';
|
||||
StreamingReporterBase::testCaseEnded( _testCaseStats );
|
||||
}
|
||||
|
||||
virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
|
||||
stream << ":test-result: SKIP " << testInfo.name << '\n';
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#ifdef CATCH_IMPL
|
||||
AutomakeReporter::~AutomakeReporter() {}
|
||||
#endif
|
||||
|
||||
INTERNAL_CATCH_REGISTER_REPORTER( "automake", AutomakeReporter)
|
||||
|
||||
} // end namespace Catch
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
|
@ -9,11 +9,38 @@
|
||||
#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
|
||||
|
||||
#include "../internal/catch_interfaces_reporter.h"
|
||||
#include "../internal/catch_errno_guard.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <cfloat>
|
||||
#include <cstdio>
|
||||
#include <assert.h>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
namespace {
|
||||
// Because formatting using c++ streams is stateful, drop down to C is required
|
||||
// Alternatively we could use stringstream, but its performance is... not good.
|
||||
std::string getFormattedDuration( double duration ) {
|
||||
// Max exponent + 1 is required to represent the whole part
|
||||
// + 1 for decimal point
|
||||
// + 3 for the 3 decimal places
|
||||
// + 1 for null terminator
|
||||
const size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
|
||||
char buffer[maxDoubleSize];
|
||||
|
||||
// Save previous errno, to prevent sprintf from overwriting it
|
||||
ErrnoGuard guard;
|
||||
#ifdef _MSC_VER
|
||||
sprintf_s(buffer, "%.3f", duration);
|
||||
#else
|
||||
sprintf(buffer, "%.3f", duration);
|
||||
#endif
|
||||
return std::string(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
|
||||
|
||||
StreamingReporterBase( ReporterConfig const& _config )
|
||||
|
@ -37,8 +37,7 @@ namespace Catch {
|
||||
stream << "No test cases matched '" << spec << '\'' << std::endl;
|
||||
}
|
||||
|
||||
virtual void assertionStarting( AssertionInfo const& ) {
|
||||
}
|
||||
virtual void assertionStarting( AssertionInfo const& ) {}
|
||||
|
||||
virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
|
||||
AssertionResult const& result = _assertionStats.assertionResult;
|
||||
@ -59,6 +58,12 @@ namespace Catch {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void sectionEnded(SectionStats const& _sectionStats) CATCH_OVERRIDE {
|
||||
if (m_config->showDurations() == ShowDurations::Always) {
|
||||
stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void testRunEnded( TestRunStats const& _testRunStats ) {
|
||||
printTotals( _testRunStats.totals );
|
||||
stream << '\n' << std::endl;
|
||||
@ -164,7 +169,7 @@ namespace Catch {
|
||||
stream << result.getSourceInfo() << ':';
|
||||
}
|
||||
|
||||
void printResultType( Colour::Code colour, std::string passOrFail ) const {
|
||||
void printResultType( Colour::Code colour, std::string const& passOrFail ) const {
|
||||
if( !passOrFail.empty() ) {
|
||||
{
|
||||
Colour colourGuard( colour );
|
||||
@ -174,7 +179,7 @@ namespace Catch {
|
||||
}
|
||||
}
|
||||
|
||||
void printIssue( std::string issue ) const {
|
||||
void printIssue( std::string const& issue ) const {
|
||||
stream << ' ' << issue;
|
||||
}
|
||||
|
||||
|
@ -13,8 +13,12 @@
|
||||
#include "../internal/catch_reporter_registrars.hpp"
|
||||
#include "../internal/catch_console_colour.hpp"
|
||||
|
||||
#include <cfloat>
|
||||
#include <cstdio>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
|
||||
struct ConsoleReporter : StreamingReporterBase {
|
||||
ConsoleReporter( ReporterConfig const& _config )
|
||||
: StreamingReporterBase( _config ),
|
||||
@ -36,18 +40,15 @@ namespace Catch {
|
||||
virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE {
|
||||
AssertionResult const& result = _assertionStats.assertionResult;
|
||||
|
||||
bool printInfoMessages = true;
|
||||
bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
|
||||
|
||||
// Drop out if result was successful and we're not printing those
|
||||
if( !m_config->includeSuccessfulResults() && result.isOk() ) {
|
||||
if( result.getResultType() != ResultWas::Warning )
|
||||
return false;
|
||||
printInfoMessages = false;
|
||||
}
|
||||
// Drop out if result was successful but we're not printing them.
|
||||
if( !includeResults && result.getResultType() != ResultWas::Warning )
|
||||
return false;
|
||||
|
||||
lazyPrint();
|
||||
|
||||
AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
|
||||
AssertionPrinter printer( stream, _assertionStats, includeResults );
|
||||
printer.print();
|
||||
stream << std::endl;
|
||||
return true;
|
||||
@ -67,14 +68,11 @@ namespace Catch {
|
||||
stream << "\nNo assertions in test case";
|
||||
stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
|
||||
}
|
||||
if( m_headerPrinted ) {
|
||||
if( m_config->showDurations() == ShowDurations::Always )
|
||||
stream << "Completed in " << _sectionStats.durationInSeconds << 's' << std::endl;
|
||||
m_headerPrinted = false;
|
||||
if( m_config->showDurations() == ShowDurations::Always ) {
|
||||
stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
|
||||
}
|
||||
else {
|
||||
if( m_config->showDurations() == ShowDurations::Always )
|
||||
stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << 's' << std::endl;
|
||||
if( m_headerPrinted ) {
|
||||
m_headerPrinted = false;
|
||||
}
|
||||
StreamingReporterBase::sectionEnded( _sectionStats );
|
||||
}
|
||||
|
259
include/reporters/catch_reporter_tap.hpp
Normal file
259
include/reporters/catch_reporter_tap.hpp
Normal file
@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Created by Colton Wolkins on 2015-08-15.
|
||||
* Copyright 2015 Martin Moene. All rights reserved.
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED
|
||||
|
||||
|
||||
// Don't #include any Catch headers here - we can assume they are already
|
||||
// included before this header.
|
||||
// This is not good practice in general but is necessary in this case so this
|
||||
// file can be distributed as a single header that works with the main
|
||||
// Catch single header.
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
struct TAPReporter : StreamingReporterBase {
|
||||
|
||||
TAPReporter( ReporterConfig const& _config )
|
||||
: StreamingReporterBase( _config ),
|
||||
counter(0)
|
||||
{}
|
||||
|
||||
virtual ~TAPReporter();
|
||||
|
||||
static std::string getDescription() {
|
||||
return "Reports test results in TAP format, suitable for test harneses";
|
||||
}
|
||||
|
||||
virtual ReporterPreferences getPreferences() const {
|
||||
ReporterPreferences prefs;
|
||||
prefs.shouldRedirectStdOut = false;
|
||||
return prefs;
|
||||
}
|
||||
|
||||
virtual void noMatchingTestCases( std::string const& spec ) {
|
||||
stream << "# No test cases matched '" << spec << "'" << std::endl;
|
||||
}
|
||||
|
||||
virtual void assertionStarting( AssertionInfo const& ) {}
|
||||
|
||||
virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
|
||||
++counter;
|
||||
|
||||
AssertionPrinter printer( stream, _assertionStats, counter );
|
||||
printer.print();
|
||||
stream << " # " << currentTestCaseInfo->name ;
|
||||
|
||||
stream << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void testRunEnded( TestRunStats const& _testRunStats ) {
|
||||
printTotals( _testRunStats.totals );
|
||||
stream << "\n" << std::endl;
|
||||
StreamingReporterBase::testRunEnded( _testRunStats );
|
||||
}
|
||||
|
||||
private:
|
||||
size_t counter;
|
||||
class AssertionPrinter {
|
||||
void operator= ( AssertionPrinter const& );
|
||||
public:
|
||||
AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, size_t counter )
|
||||
: stream( _stream )
|
||||
, stats( _stats )
|
||||
, result( _stats.assertionResult )
|
||||
, messages( _stats.infoMessages )
|
||||
, itMessage( _stats.infoMessages.begin() )
|
||||
, printInfoMessages( true )
|
||||
, counter(counter)
|
||||
{}
|
||||
|
||||
void print() {
|
||||
itMessage = messages.begin();
|
||||
|
||||
switch( result.getResultType() ) {
|
||||
case ResultWas::Ok:
|
||||
printResultType( passedString() );
|
||||
printOriginalExpression();
|
||||
printReconstructedExpression();
|
||||
if ( ! result.hasExpression() )
|
||||
printRemainingMessages( Colour::None );
|
||||
else
|
||||
printRemainingMessages();
|
||||
break;
|
||||
case ResultWas::ExpressionFailed:
|
||||
if (result.isOk()) {
|
||||
printResultType(passedString());
|
||||
} else {
|
||||
printResultType(failedString());
|
||||
}
|
||||
printOriginalExpression();
|
||||
printReconstructedExpression();
|
||||
if (result.isOk()) {
|
||||
printIssue(" # TODO");
|
||||
}
|
||||
printRemainingMessages();
|
||||
break;
|
||||
case ResultWas::ThrewException:
|
||||
printResultType( failedString() );
|
||||
printIssue( "unexpected exception with message:" );
|
||||
printMessage();
|
||||
printExpressionWas();
|
||||
printRemainingMessages();
|
||||
break;
|
||||
case ResultWas::FatalErrorCondition:
|
||||
printResultType( failedString() );
|
||||
printIssue( "fatal error condition with message:" );
|
||||
printMessage();
|
||||
printExpressionWas();
|
||||
printRemainingMessages();
|
||||
break;
|
||||
case ResultWas::DidntThrowException:
|
||||
printResultType( failedString() );
|
||||
printIssue( "expected exception, got none" );
|
||||
printExpressionWas();
|
||||
printRemainingMessages();
|
||||
break;
|
||||
case ResultWas::Info:
|
||||
printResultType( "info" );
|
||||
printMessage();
|
||||
printRemainingMessages();
|
||||
break;
|
||||
case ResultWas::Warning:
|
||||
printResultType( "warning" );
|
||||
printMessage();
|
||||
printRemainingMessages();
|
||||
break;
|
||||
case ResultWas::ExplicitFailure:
|
||||
printResultType( failedString() );
|
||||
printIssue( "explicitly" );
|
||||
printRemainingMessages( Colour::None );
|
||||
break;
|
||||
// These cases are here to prevent compiler warnings
|
||||
case ResultWas::Unknown:
|
||||
case ResultWas::FailureBit:
|
||||
case ResultWas::Exception:
|
||||
printResultType( "** internal error **" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static Colour::Code dimColour() { return Colour::FileName; }
|
||||
|
||||
static const char* failedString() { return "not ok"; }
|
||||
static const char* passedString() { return "ok"; }
|
||||
|
||||
void printSourceInfo() const {
|
||||
Colour colourGuard( dimColour() );
|
||||
stream << result.getSourceInfo() << ":";
|
||||
}
|
||||
|
||||
void printResultType( std::string const& passOrFail ) const {
|
||||
if( !passOrFail.empty() ) {
|
||||
stream << passOrFail << ' ' << counter << " -";
|
||||
}
|
||||
}
|
||||
|
||||
void printIssue( std::string const& issue ) const {
|
||||
stream << " " << issue;
|
||||
}
|
||||
|
||||
void printExpressionWas() {
|
||||
if( result.hasExpression() ) {
|
||||
stream << ";";
|
||||
{
|
||||
Colour colour( dimColour() );
|
||||
stream << " expression was:";
|
||||
}
|
||||
printOriginalExpression();
|
||||
}
|
||||
}
|
||||
|
||||
void printOriginalExpression() const {
|
||||
if( result.hasExpression() ) {
|
||||
stream << " " << result.getExpression();
|
||||
}
|
||||
}
|
||||
|
||||
void printReconstructedExpression() const {
|
||||
if( result.hasExpandedExpression() ) {
|
||||
{
|
||||
Colour colour( dimColour() );
|
||||
stream << " for: ";
|
||||
}
|
||||
std::string expr = result.getExpandedExpression();
|
||||
std::replace( expr.begin(), expr.end(), '\n', ' ');
|
||||
stream << expr;
|
||||
}
|
||||
}
|
||||
|
||||
void printMessage() {
|
||||
if ( itMessage != messages.end() ) {
|
||||
stream << " '" << itMessage->message << "'";
|
||||
++itMessage;
|
||||
}
|
||||
}
|
||||
|
||||
void printRemainingMessages( Colour::Code colour = dimColour() ) {
|
||||
if (itMessage == messages.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// using messages.end() directly yields compilation error:
|
||||
std::vector<MessageInfo>::const_iterator itEnd = messages.end();
|
||||
const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
|
||||
|
||||
{
|
||||
Colour colourGuard( colour );
|
||||
stream << " with " << pluralise( N, "message" ) << ":";
|
||||
}
|
||||
|
||||
for(; itMessage != itEnd; ) {
|
||||
// If this assertion is a warning ignore any INFO messages
|
||||
if( printInfoMessages || itMessage->type != ResultWas::Info ) {
|
||||
stream << " '" << itMessage->message << "'";
|
||||
if ( ++itMessage != itEnd ) {
|
||||
Colour colourGuard( dimColour() );
|
||||
stream << " and";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::ostream& stream;
|
||||
AssertionStats const& stats;
|
||||
AssertionResult const& result;
|
||||
std::vector<MessageInfo> messages;
|
||||
std::vector<MessageInfo>::const_iterator itMessage;
|
||||
bool printInfoMessages;
|
||||
size_t counter;
|
||||
};
|
||||
|
||||
void printTotals( const Totals& totals ) const {
|
||||
if( totals.testCases.total() == 0 ) {
|
||||
stream << "1..0 # Skipped: No tests ran.";
|
||||
} else {
|
||||
stream << "1.." << counter;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef CATCH_IMPL
|
||||
TAPReporter::~TAPReporter() {}
|
||||
#endif
|
||||
|
||||
INTERNAL_CATCH_REGISTER_REPORTER( "tap", TAPReporter )
|
||||
|
||||
} // end namespace Catch
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED
|
@ -36,6 +36,12 @@ namespace Catch {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
void writeSourceInfo( SourceLineInfo const& sourceInfo ) {
|
||||
m_xml
|
||||
.writeAttribute( "filename", sourceInfo.file )
|
||||
.writeAttribute( "line", sourceInfo.line );
|
||||
}
|
||||
|
||||
public: // StreamingReporterBase
|
||||
|
||||
virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE {
|
||||
@ -65,6 +71,8 @@ namespace Catch {
|
||||
.writeAttribute( "description", testInfo.description )
|
||||
.writeAttribute( "tags", testInfo.tagsAsString );
|
||||
|
||||
writeSourceInfo( testInfo.lineInfo );
|
||||
|
||||
if ( m_config->showDurations() == ShowDurations::Always )
|
||||
m_testCaseTimer.start();
|
||||
m_xml.ensureTagClosed();
|
||||
@ -76,6 +84,7 @@ namespace Catch {
|
||||
m_xml.startElement( "Section" )
|
||||
.writeAttribute( "name", trim( sectionInfo.name ) )
|
||||
.writeAttribute( "description", sectionInfo.description );
|
||||
writeSourceInfo( sectionInfo.lineInfo );
|
||||
m_xml.ensureTagClosed();
|
||||
}
|
||||
}
|
||||
@ -83,71 +92,77 @@ namespace Catch {
|
||||
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { }
|
||||
|
||||
virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
|
||||
const AssertionResult& assertionResult = assertionStats.assertionResult;
|
||||
|
||||
// Print any info messages in <Info> tags.
|
||||
if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
|
||||
AssertionResult const& result = assertionStats.assertionResult;
|
||||
|
||||
bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
|
||||
|
||||
if( includeResults ) {
|
||||
// Print any info messages in <Info> tags.
|
||||
for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
|
||||
it != itEnd;
|
||||
++it ) {
|
||||
it != itEnd;
|
||||
++it ) {
|
||||
if( it->type == ResultWas::Info ) {
|
||||
m_xml.scopedElement( "Info" )
|
||||
.writeText( it->message );
|
||||
.writeText( it->message );
|
||||
} else if ( it->type == ResultWas::Warning ) {
|
||||
m_xml.scopedElement( "Warning" )
|
||||
.writeText( it->message );
|
||||
.writeText( it->message );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Drop out if result was successful but we're not printing them.
|
||||
if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) )
|
||||
if( !includeResults && result.getResultType() != ResultWas::Warning )
|
||||
return true;
|
||||
|
||||
|
||||
// Print the expression if there is one.
|
||||
if( assertionResult.hasExpression() ) {
|
||||
if( result.hasExpression() ) {
|
||||
m_xml.startElement( "Expression" )
|
||||
.writeAttribute( "success", assertionResult.succeeded() )
|
||||
.writeAttribute( "type", assertionResult.getTestMacroName() )
|
||||
.writeAttribute( "filename", assertionResult.getSourceInfo().file )
|
||||
.writeAttribute( "line", assertionResult.getSourceInfo().line );
|
||||
.writeAttribute( "success", result.succeeded() )
|
||||
.writeAttribute( "type", result.getTestMacroName() );
|
||||
|
||||
writeSourceInfo( result.getSourceInfo() );
|
||||
|
||||
m_xml.scopedElement( "Original" )
|
||||
.writeText( assertionResult.getExpression() );
|
||||
.writeText( result.getExpression() );
|
||||
m_xml.scopedElement( "Expanded" )
|
||||
.writeText( assertionResult.getExpandedExpression() );
|
||||
.writeText( result.getExpandedExpression() );
|
||||
}
|
||||
|
||||
// And... Print a result applicable to each result type.
|
||||
switch( assertionResult.getResultType() ) {
|
||||
switch( result.getResultType() ) {
|
||||
case ResultWas::ThrewException:
|
||||
m_xml.scopedElement( "Exception" )
|
||||
.writeAttribute( "filename", assertionResult.getSourceInfo().file )
|
||||
.writeAttribute( "line", assertionResult.getSourceInfo().line )
|
||||
.writeText( assertionResult.getMessage() );
|
||||
m_xml.startElement( "Exception" );
|
||||
writeSourceInfo( result.getSourceInfo() );
|
||||
m_xml.writeText( result.getMessage() );
|
||||
m_xml.endElement();
|
||||
break;
|
||||
case ResultWas::FatalErrorCondition:
|
||||
m_xml.scopedElement( "FatalErrorCondition" )
|
||||
.writeAttribute( "filename", assertionResult.getSourceInfo().file )
|
||||
.writeAttribute( "line", assertionResult.getSourceInfo().line )
|
||||
.writeText( assertionResult.getMessage() );
|
||||
m_xml.startElement( "FatalErrorCondition" );
|
||||
writeSourceInfo( result.getSourceInfo() );
|
||||
m_xml.writeText( result.getMessage() );
|
||||
m_xml.endElement();
|
||||
break;
|
||||
case ResultWas::Info:
|
||||
m_xml.scopedElement( "Info" )
|
||||
.writeText( assertionResult.getMessage() );
|
||||
.writeText( result.getMessage() );
|
||||
break;
|
||||
case ResultWas::Warning:
|
||||
// Warning will already have been written
|
||||
break;
|
||||
case ResultWas::ExplicitFailure:
|
||||
m_xml.scopedElement( "Failure" )
|
||||
.writeText( assertionResult.getMessage() );
|
||||
m_xml.startElement( "Failure" );
|
||||
writeSourceInfo( result.getSourceInfo() );
|
||||
m_xml.writeText( result.getMessage() );
|
||||
m_xml.endElement();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( assertionResult.hasExpression() )
|
||||
if( result.hasExpression() )
|
||||
m_xml.endElement();
|
||||
|
||||
return true;
|
||||
|
@ -141,6 +141,16 @@ TEST_CASE( "Approximate PI", "[Approx][PI]" )
|
||||
REQUIRE( divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 ) );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_CASE( "Absolute margin", "[Approx]" ) {
|
||||
REQUIRE( 104.0 != Approx(100.0) );
|
||||
REQUIRE( 104.0 == Approx(100.0).margin(5) );
|
||||
REQUIRE( 104.0 != Approx(100.0).margin(3) );
|
||||
REQUIRE( 100.3 != Approx(100.0) );
|
||||
REQUIRE( 100.3 == Approx(100.0).margin(0.5) );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
|
||||
|
168
projects/SelfTest/Baselines/automake.std.approved.txt
Normal file
168
projects/SelfTest/Baselines/automake.std.approved.txt
Normal file
@ -0,0 +1,168 @@
|
||||
:test-result: PASS # A test name that starts with a #
|
||||
:test-result: PASS #542
|
||||
:test-result: PASS #809
|
||||
:test-result: FAIL 'Not' checks that should fail
|
||||
:test-result: PASS 'Not' checks that should succeed
|
||||
:test-result: PASS (unimplemented) static bools can be evaluated
|
||||
:test-result: FAIL A METHOD_AS_TEST_CASE based test run that fails
|
||||
:test-result: PASS A METHOD_AS_TEST_CASE based test run that succeeds
|
||||
:test-result: FAIL A TEST_CASE_METHOD based test run that fails
|
||||
:test-result: PASS A TEST_CASE_METHOD based test run that succeeds
|
||||
:test-result: FAIL A couple of nested sections followed by a failure
|
||||
:test-result: FAIL A failing expression with a non streamable type is still captured
|
||||
:test-result: PASS AllOf matcher
|
||||
:test-result: PASS An empty test with no assertions
|
||||
:test-result: PASS An expression with side-effects should only be evaluated once
|
||||
:test-result: FAIL An unchecked exception reports the line of the last assertion
|
||||
:test-result: PASS Anonymous test case 1
|
||||
:test-result: PASS AnyOf matcher
|
||||
:test-result: PASS Approximate PI
|
||||
:test-result: PASS Approximate comparisons with different epsilons
|
||||
:test-result: PASS Approximate comparisons with floats
|
||||
:test-result: PASS Approximate comparisons with ints
|
||||
:test-result: PASS Approximate comparisons with mixed numeric types
|
||||
:test-result: PASS Assertions then sections
|
||||
:test-result: PASS Character pretty printing
|
||||
:test-result: PASS Comparing function pointers
|
||||
:test-result: PASS Comparing member function pointers
|
||||
:test-result: PASS Comparisons between ints where one side is computed
|
||||
:test-result: PASS Comparisons between unsigned ints and negative signed ints match c++ standard behaviour
|
||||
:test-result: PASS Comparisons with int literals don't warn when mixing signed/ unsigned
|
||||
:test-result: FAIL Contains string matcher
|
||||
:test-result: FAIL Custom exceptions can be translated when testing for nothrow
|
||||
:test-result: FAIL Custom exceptions can be translated when testing for throwing as something else
|
||||
:test-result: FAIL Custom std-exceptions can be custom translated
|
||||
:test-result: PASS Demonstrate that a non-const == is not used
|
||||
:test-result: FAIL EndsWith string matcher
|
||||
:test-result: XFAIL Equality checks that should fail
|
||||
:test-result: PASS Equality checks that should succeed
|
||||
:test-result: PASS Equals
|
||||
:test-result: FAIL Equals string matcher
|
||||
:test-result: PASS Exception messages can be tested for
|
||||
:test-result: FAIL Expected exceptions that don't throw or unexpected exceptions fail the test
|
||||
:test-result: FAIL FAIL aborts the test
|
||||
:test-result: FAIL FAIL does not require an argument
|
||||
:test-result: PASS Factorials are computed
|
||||
:test-result: PASS Generator over a range of pairs
|
||||
:test-result: PASS Generators over two ranges
|
||||
:test-result: PASS Greater-than inequalities with different epsilons
|
||||
:test-result: PASS INFO and WARN do not abort tests
|
||||
:test-result: FAIL INFO gets logged on failure
|
||||
:test-result: FAIL INFO gets logged on failure, even if captured before successful assertions
|
||||
:test-result: XFAIL Inequality checks that should fail
|
||||
:test-result: PASS Inequality checks that should succeed
|
||||
:test-result: PASS Less-than inequalities with different epsilons
|
||||
:test-result: PASS Long strings can be wrapped
|
||||
:test-result: PASS Long text is truncted
|
||||
:test-result: PASS ManuallyRegistered
|
||||
:test-result: PASS Matchers can be (AllOf) composed with the && operator
|
||||
:test-result: PASS Matchers can be (AnyOf) composed with the || operator
|
||||
:test-result: PASS Matchers can be composed with both && and ||
|
||||
:test-result: FAIL Matchers can be composed with both && and || - failing
|
||||
:test-result: PASS Matchers can be negated (Not) with the ! operator
|
||||
:test-result: FAIL Matchers can be negated (Not) with the ! operator - failing
|
||||
:test-result: FAIL Mismatching exception messages failing the test
|
||||
:test-result: PASS Nice descriptive name
|
||||
:test-result: FAIL Non-std exceptions can be translated
|
||||
:test-result: PASS NotImplemented exception
|
||||
:test-result: PASS Objects that evaluated in boolean contexts can be checked
|
||||
:test-result: PASS Operators at different namespace levels not hijacked by Koenig lookup
|
||||
:test-result: FAIL Ordering comparison checks that should fail
|
||||
:test-result: PASS Ordering comparison checks that should succeed
|
||||
:test-result: FAIL Output from all sections is reported
|
||||
:test-result: PASS Parse test names and tags
|
||||
:test-result: PASS Parsing a std::pair
|
||||
:test-result: PASS Pointers can be compared to null
|
||||
:test-result: PASS Pointers can be converted to strings
|
||||
:test-result: PASS Process can be configured on command line
|
||||
:test-result: FAIL SCOPED_INFO is reset for each loop
|
||||
:test-result: PASS SUCCEED counts as a test pass
|
||||
:test-result: PASS SUCCESS does not require an argument
|
||||
:test-result: PASS Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or methods
|
||||
:test-result: PASS Scenario: Do that thing with the thing
|
||||
:test-result: PASS Scenario: This is a really long scenario name to see how the list command deals with wrapping
|
||||
:test-result: PASS Scenario: Vector resizing affects size and capacity
|
||||
A string sent directly to stdout
|
||||
A string sent directly to stderr
|
||||
:test-result: PASS Sends stuff to stdout and stderr
|
||||
:test-result: PASS Some simple comparisons between doubles
|
||||
Message from section one
|
||||
Message from section two
|
||||
:test-result: PASS Standard output from all sections is reported
|
||||
:test-result: FAIL StartsWith string matcher
|
||||
:test-result: PASS String matchers
|
||||
hello
|
||||
hello
|
||||
:test-result: PASS Strings can be rendered with colour
|
||||
:test-result: FAIL Tabs and newlines show in output
|
||||
:test-result: PASS Tag alias can be registered against tag patterns
|
||||
:test-result: PASS Test case with one argument
|
||||
:test-result: PASS Test enum bit values
|
||||
:test-result: PASS Text can be formatted using the Text class
|
||||
:test-result: PASS The NO_FAIL macro reports a failure but does not fail the test
|
||||
:test-result: FAIL This test 'should' fail but doesn't
|
||||
:test-result: PASS Tracker
|
||||
:test-result: FAIL Unexpected exceptions can be translated
|
||||
:test-result: PASS Use a custom approx
|
||||
:test-result: PASS Variadic macros
|
||||
:test-result: PASS When checked exceptions are thrown they can be expected or unexpected
|
||||
:test-result: FAIL When unchecked exceptions are thrown directly they are always failures
|
||||
:test-result: FAIL When unchecked exceptions are thrown during a CHECK the test should continue
|
||||
:test-result: FAIL When unchecked exceptions are thrown during a REQUIRE the test should abort fail
|
||||
:test-result: FAIL When unchecked exceptions are thrown from functions they are always failures
|
||||
:test-result: FAIL When unchecked exceptions are thrown from sections they are always failures
|
||||
:test-result: PASS When unchecked exceptions are thrown, but caught, they do not affect the test
|
||||
:test-result: PASS Where the LHS is not a simple value
|
||||
:test-result: PASS Where there is more to the expression after the RHS
|
||||
:test-result: PASS X/level/0/a
|
||||
:test-result: PASS X/level/0/b
|
||||
:test-result: PASS X/level/1/a
|
||||
:test-result: PASS X/level/1/b
|
||||
:test-result: PASS XmlEncode
|
||||
:test-result: PASS atomic if
|
||||
:test-result: PASS boolean member
|
||||
:test-result: PASS checkedElse
|
||||
:test-result: FAIL checkedElse, failing
|
||||
:test-result: PASS checkedIf
|
||||
:test-result: FAIL checkedIf, failing
|
||||
:test-result: PASS comparisons between const int variables
|
||||
:test-result: PASS comparisons between int variables
|
||||
:test-result: PASS even more nested SECTION tests
|
||||
:test-result: PASS first tag
|
||||
spanner:test-result: PASS has printf
|
||||
:test-result: FAIL just failure
|
||||
:test-result: PASS just info
|
||||
:test-result: FAIL looped SECTION tests
|
||||
:test-result: FAIL looped tests
|
||||
:test-result: FAIL more nested SECTION tests
|
||||
:test-result: PASS nested SECTION tests
|
||||
:test-result: PASS non streamable - with conv. op
|
||||
:test-result: PASS not allowed
|
||||
:test-result: PASS null strings
|
||||
:test-result: PASS pair<pair<int,const char *,pair<std::string,int> > -> toString
|
||||
:test-result: PASS pointer to class
|
||||
:test-result: PASS random SECTION tests
|
||||
:test-result: PASS replaceInPlace
|
||||
:test-result: PASS second tag
|
||||
:test-result: FAIL send a single char to INFO
|
||||
:test-result: FAIL sends information to INFO
|
||||
:test-result: PASS std::pair<int,const std::string> -> toString
|
||||
:test-result: PASS std::pair<int,std::string> -> toString
|
||||
:test-result: PASS std::vector<std::pair<std::string,int> > -> toString
|
||||
:test-result: FAIL string literals of different sizes can be compared
|
||||
:test-result: PASS toString on const wchar_t const pointer returns the string contents
|
||||
:test-result: PASS toString on const wchar_t pointer returns the string contents
|
||||
:test-result: PASS toString on wchar_t const pointer returns the string contents
|
||||
:test-result: PASS toString on wchar_t returns the string contents
|
||||
:test-result: PASS toString( has_maker )
|
||||
:test-result: PASS toString( has_maker_and_toString )
|
||||
:test-result: PASS toString( has_toString )
|
||||
:test-result: PASS toString( vectors<has_maker )
|
||||
:test-result: SKIP toString( vectors<has_maker_and_toString )
|
||||
:test-result: SKIP toString( vectors<has_toString )
|
||||
:test-result: PASS toString(enum w/operator<<)
|
||||
:test-result: PASS toString(enum)
|
||||
:test-result: PASS vector<int> -> toString
|
||||
:test-result: PASS vector<string> -> toString
|
||||
:test-result: PASS vectors can be sized and resized
|
||||
:test-result: PASS xmlentitycheck
|
@ -3,6 +3,17 @@
|
||||
<exe-name> is a <version> host application.
|
||||
Run with -? for options
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#835 -- errno should not be touched by Catch
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
CHECK( f() == 0 )
|
||||
with expansion:
|
||||
1 == 0
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
'Not' checks that should fail
|
||||
-------------------------------------------------------------------------------
|
||||
@ -105,10 +116,10 @@ due to unexpected exception with message:
|
||||
-------------------------------------------------------------------------------
|
||||
Contains string matcher
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), Contains( "not there" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" contains: "not there"
|
||||
@ -148,10 +159,10 @@ due to unexpected exception with message:
|
||||
-------------------------------------------------------------------------------
|
||||
EndsWith string matcher
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), EndsWith( "this" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" ends with: "this"
|
||||
@ -230,10 +241,10 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Equals string matcher
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), Equals( "something else" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" equals: "something else"
|
||||
@ -276,6 +287,20 @@ MessageTests.cpp:<line number>
|
||||
|
||||
MessageTests.cpp:<line number>: FAILED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
FAIL_CHECK does not abort the test
|
||||
-------------------------------------------------------------------------------
|
||||
MessageTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MessageTests.cpp:<line number>: FAILED:
|
||||
explicitly with message:
|
||||
This is a failure
|
||||
|
||||
MessageTests.cpp:<line number>:
|
||||
warning:
|
||||
This message appears in the output
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
INFO and WARN do not abort tests
|
||||
-------------------------------------------------------------------------------
|
||||
@ -355,10 +380,10 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers can be composed with both && and || - failing
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "random" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" ( ( contains: "string" or
|
||||
@ -367,10 +392,10 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers can be negated (Not) with the ! operator - failing
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), !Contains( "substring" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" not contains: "substring"
|
||||
@ -564,10 +589,10 @@ Message from section two
|
||||
-------------------------------------------------------------------------------
|
||||
StartsWith string matcher
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), StartsWith( "string" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" starts with: "string"
|
||||
@ -602,6 +627,67 @@ ExceptionTests.cpp:<line number>: FAILED:
|
||||
due to unexpected exception with message:
|
||||
3.14
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector matchers that fail
|
||||
Contains (element)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( v, VectorContains( -1 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Contains: -1
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( empty, VectorContains( 1 ) )
|
||||
with expansion:
|
||||
{ } Contains: 1
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector matchers that fail
|
||||
Contains (vector)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( empty, Contains( v) )
|
||||
with expansion:
|
||||
{ } Contains: { 1, 2, 3 }
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( v, Contains( v2 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Contains: { 1, 2, 4 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector matchers that fail
|
||||
Equals
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( v, Equals( v2 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Equals: { 1, 2 }
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( v2, Equals( v ) )
|
||||
with expansion:
|
||||
{ 1, 2 } Equals: { 1, 2, 3 }
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( empty, Equals( v ) )
|
||||
with expansion:
|
||||
{ } Equals: { 1, 2, 3 }
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( v, Equals( empty ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Equals: { }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
When unchecked exceptions are thrown directly they are always failures
|
||||
-------------------------------------------------------------------------------
|
||||
@ -829,6 +915,6 @@ with expansion:
|
||||
"first" == "second"
|
||||
|
||||
===============================================================================
|
||||
test cases: 161 | 117 passed | 42 failed | 2 failed as expected
|
||||
assertions: 932 | 836 passed | 78 failed | 18 failed as expected
|
||||
test cases: 166 | 119 passed | 44 failed | 3 failed as expected
|
||||
assertions: 961 | 855 passed | 87 failed | 19 failed as expected
|
||||
|
||||
|
@ -48,6 +48,23 @@ PASSED:
|
||||
with expansion:
|
||||
42 == {?}
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#835 -- errno should not be touched by Catch
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
CHECK( f() == 0 )
|
||||
with expansion:
|
||||
1 == 0
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( (*__error()) == 1 )
|
||||
with expansion:
|
||||
1 == 1
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
'Not' checks that should fail
|
||||
-------------------------------------------------------------------------------
|
||||
@ -305,12 +322,48 @@ with expansion:
|
||||
{?} == {?}
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
AllOf matcher
|
||||
Absolute margin
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
ApproxTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
ApproxTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( 104.0 != Approx(100.0) )
|
||||
with expansion:
|
||||
104.0 != Approx( 100.0 )
|
||||
|
||||
ApproxTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( 104.0 == Approx(100.0).margin(5) )
|
||||
with expansion:
|
||||
104.0 == Approx( 100.0 )
|
||||
|
||||
ApproxTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( 104.0 != Approx(100.0).margin(3) )
|
||||
with expansion:
|
||||
104.0 != Approx( 100.0 )
|
||||
|
||||
ApproxTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( 100.3 != Approx(100.0) )
|
||||
with expansion:
|
||||
100.3 != Approx( 100.0 )
|
||||
|
||||
ApproxTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( 100.3 == Approx(100.0).margin(0.5) )
|
||||
with expansion:
|
||||
100.3 == Approx( 100.0 )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
AllOf matcher
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching(), AllOf( Catch::Contains( "string" ), Catch::Contains( "abc" ) ) )
|
||||
with expansion:
|
||||
@ -364,17 +417,17 @@ with message:
|
||||
-------------------------------------------------------------------------------
|
||||
AnyOf matcher
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "string" ), Catch::Contains( "not there" ) ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" ( contains: "string" or contains:
|
||||
"not there" )
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "not there" ), Catch::Contains( "string" ) ) )
|
||||
with expansion:
|
||||
@ -567,6 +620,32 @@ PASSED:
|
||||
with expansion:
|
||||
true
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Capture and info messages
|
||||
Capture should stringify like assertions
|
||||
-------------------------------------------------------------------------------
|
||||
ToStringGeneralTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ToStringGeneralTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( true )
|
||||
with message:
|
||||
i := 2
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Capture and info messages
|
||||
Info should NOT stringify the way assertions do
|
||||
-------------------------------------------------------------------------------
|
||||
ToStringGeneralTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ToStringGeneralTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( true )
|
||||
with message:
|
||||
3
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Character pretty printing
|
||||
Specifically escaped
|
||||
@ -848,10 +927,10 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Contains string matcher
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), Contains( "not there" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" contains: "not there"
|
||||
@ -903,10 +982,10 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
EndsWith string matcher
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), EndsWith( "this" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" ends with: "this"
|
||||
@ -1033,10 +1112,10 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Equals
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching(), Equals( "this string contains 'abc' as a substring" ) )
|
||||
with expansion:
|
||||
@ -1046,26 +1125,14 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Equals string matcher
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), Equals( "something else" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" equals: "something else"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Equals string matcher, with NULL
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( "", Equals(0) )
|
||||
with expansion:
|
||||
"" equals: ""
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Exception messages can be tested for
|
||||
exact match
|
||||
@ -1149,6 +1216,20 @@ MessageTests.cpp:<line number>
|
||||
|
||||
MessageTests.cpp:<line number>: FAILED:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
FAIL_CHECK does not abort the test
|
||||
-------------------------------------------------------------------------------
|
||||
MessageTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MessageTests.cpp:<line number>: FAILED:
|
||||
explicitly with message:
|
||||
This is a failure
|
||||
|
||||
MessageTests.cpp:<line number>:
|
||||
warning:
|
||||
This message appears in the output
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Factorials are computed
|
||||
-------------------------------------------------------------------------------
|
||||
@ -3268,7 +3349,7 @@ with expansion:
|
||||
re>"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Long text is truncted
|
||||
Long text is truncated
|
||||
-------------------------------------------------------------------------------
|
||||
TestMain.cpp:<line number>
|
||||
...............................................................................
|
||||
@ -4293,10 +4374,10 @@ with message:
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers can be (AllOf) composed with the && operator
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching(), Contains( "string" ) && Contains( "abc" ) && Contains( "substring" ) && Contains( "contains" ) )
|
||||
with expansion:
|
||||
@ -4306,17 +4387,17 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers can be (AnyOf) composed with the || operator
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" ( contains: "string" or contains:
|
||||
"different" or contains: "random" )
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching2(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) )
|
||||
with expansion:
|
||||
@ -4326,10 +4407,10 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers can be composed with both && and ||
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "substring" ) )
|
||||
with expansion:
|
||||
@ -4339,10 +4420,10 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers can be composed with both && and || - failing
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "random" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" ( ( contains: "string" or
|
||||
@ -4351,10 +4432,10 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers can be negated (Not) with the ! operator
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching(), !Contains( "different" ) )
|
||||
with expansion:
|
||||
@ -4363,10 +4444,10 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers can be negated (Not) with the ! operator - failing
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), !Contains( "substring" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" not contains: "substring"
|
||||
@ -5790,6 +5871,23 @@ MessageTests.cpp:<line number>:
|
||||
warning:
|
||||
toString(p): 0x<hex digits>
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Process can be configured on command line
|
||||
empty args don't cause a crash
|
||||
-------------------------------------------------------------------------------
|
||||
TestMain.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
TestMain.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_NOTHROW( parser.parseInto( std::vector<std::string>(), config ) )
|
||||
|
||||
TestMain.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK( config.processName == "" )
|
||||
with expansion:
|
||||
"" == ""
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Process can be configured on command line
|
||||
default - no arguments
|
||||
@ -5801,6 +5899,12 @@ TestMain.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_NOTHROW( parseIntoConfig( argv, config ) )
|
||||
|
||||
TestMain.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK( config.processName == "test" )
|
||||
with expansion:
|
||||
"test" == "test"
|
||||
|
||||
TestMain.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK( config.shouldDebugBreak == false )
|
||||
@ -6632,10 +6736,10 @@ No assertions in section 'two'
|
||||
-------------------------------------------------------------------------------
|
||||
StartsWith string matcher
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), StartsWith( "string" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" starts with: "string"
|
||||
@ -6643,28 +6747,28 @@ with expansion:
|
||||
-------------------------------------------------------------------------------
|
||||
String matchers
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( testStringForMatching(), Contains( "string" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" contains: "string"
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching(), Contains( "abc" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" contains: "abc"
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching(), StartsWith( "this" ) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" starts with: "this"
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( testStringForMatching(), EndsWith( "substring" ) )
|
||||
with expansion:
|
||||
@ -7892,6 +7996,142 @@ PASSED:
|
||||
with message:
|
||||
no assertions
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector matchers
|
||||
Contains (element)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( v, VectorContains( 1 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Contains: 1
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( v, VectorContains( 2 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Contains: 2
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector matchers
|
||||
Contains (vector)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( v, Contains( v2 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Contains: { 1, 2 }
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( v, Contains( v2 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Contains: { 1, 2, 3 }
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( v, Contains( empty) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Contains: { }
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( empty, Contains( empty) )
|
||||
with expansion:
|
||||
{ } Contains: { }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector matchers
|
||||
Equals
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( v, Equals( v ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Equals: { 1, 2, 3 }
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( empty, Equals( empty ) )
|
||||
with expansion:
|
||||
{ } Equals: { }
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
CHECK_THAT( v, Equals( v2 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Equals: { 1, 2, 3 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector matchers that fail
|
||||
Contains (element)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( v, VectorContains( -1 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Contains: -1
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( empty, VectorContains( 1 ) )
|
||||
with expansion:
|
||||
{ } Contains: 1
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector matchers that fail
|
||||
Contains (vector)
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( empty, Contains( v) )
|
||||
with expansion:
|
||||
{ } Contains: { 1, 2, 3 }
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( v, Contains( v2 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Contains: { 1, 2, 4 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector matchers that fail
|
||||
Equals
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( v, Equals( v2 ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Equals: { 1, 2 }
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( v2, Equals( v ) )
|
||||
with expansion:
|
||||
{ 1, 2 } Equals: { 1, 2, 3 }
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( empty, Equals( v ) )
|
||||
with expansion:
|
||||
{ } Equals: { 1, 2, 3 }
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( v, Equals( empty ) )
|
||||
with expansion:
|
||||
{ 1, 2, 3 } Equals: { }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
When checked exceptions are thrown they can be expected or unexpected
|
||||
-------------------------------------------------------------------------------
|
||||
@ -9164,6 +9404,6 @@ MiscTests.cpp:<line number>:
|
||||
PASSED:
|
||||
|
||||
===============================================================================
|
||||
test cases: 161 | 116 passed | 43 failed | 2 failed as expected
|
||||
assertions: 934 | 836 passed | 80 failed | 18 failed as expected
|
||||
test cases: 166 | 118 passed | 45 failed | 3 failed as expected
|
||||
assertions: 963 | 855 passed | 89 failed | 19 failed as expected
|
||||
|
||||
|
@ -48,6 +48,23 @@ PASSED:
|
||||
with expansion:
|
||||
42 == {?}
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#835 -- errno should not be touched by Catch
|
||||
-------------------------------------------------------------------------------
|
||||
MiscTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MiscTests.cpp:<line number>: FAILED:
|
||||
CHECK( f() == 0 )
|
||||
with expansion:
|
||||
1 == 0
|
||||
|
||||
MiscTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( (*__error()) == 1 )
|
||||
with expansion:
|
||||
1 == 1
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
'Not' checks that should fail
|
||||
-------------------------------------------------------------------------------
|
||||
@ -69,6 +86,6 @@ ConditionTests.cpp:<line number>: FAILED:
|
||||
CHECK_FALSE( true )
|
||||
|
||||
===============================================================================
|
||||
test cases: 4 | 3 passed | 1 failed
|
||||
assertions: 10 | 6 passed | 4 failed
|
||||
test cases: 5 | 3 passed | 1 failed | 1 failed as expected
|
||||
assertions: 12 | 7 passed | 4 failed | 1 failed as expected
|
||||
|
||||
|
@ -1,9 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuitesspanner>
|
||||
<testsuite name="<exe-name>" errors="13" failures="68" tests="935" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||
<testsuite name="<exe-name>" errors="13" failures="77" tests="964" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||
<testcase classname="global" name="# A test name that starts with a #" time="{duration}"/>
|
||||
<testcase classname="global" name="#542" time="{duration}"/>
|
||||
<testcase classname="global" name="#809" time="{duration}"/>
|
||||
<testcase classname="global" name="#835 -- errno should not be touched by Catch" time="{duration}">
|
||||
<failure message="1 == 0" type="CHECK">
|
||||
MiscTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="global" name="'Not' checks that should fail" time="{duration}">
|
||||
<failure message="false != false" type="CHECK">
|
||||
ConditionTests.cpp:<line number>
|
||||
@ -63,6 +68,7 @@ TrickyTests.cpp:<line number>
|
||||
TrickyTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="global" name="Absolute margin" time="{duration}"/>
|
||||
<testcase classname="global" name="AllOf matcher" time="{duration}"/>
|
||||
<testcase classname="global" name="An expression with side-effects should only be evaluated once" time="{duration}"/>
|
||||
<testcase classname="global" name="An unchecked exception reports the line of the last assertion" time="{duration}">
|
||||
@ -82,6 +88,8 @@ ExceptionTests.cpp:<line number>
|
||||
<testcase classname="Assertions then sections" name="A section" time="{duration}"/>
|
||||
<testcase classname="Assertions then sections" name="A section/Another section" time="{duration}"/>
|
||||
<testcase classname="Assertions then sections" name="A section/Another other section" time="{duration}"/>
|
||||
<testcase classname="Capture and info messages" name="Capture should stringify like assertions" time="{duration}"/>
|
||||
<testcase classname="Capture and info messages" name="Info should NOT stringify the way assertions do" time="{duration}"/>
|
||||
<testcase classname="Character pretty printing" name="Specifically escaped" time="{duration}"/>
|
||||
<testcase classname="Character pretty printing" name="General chars" time="{duration}"/>
|
||||
<testcase classname="Character pretty printing" name="Low ASCII" time="{duration}"/>
|
||||
@ -92,7 +100,7 @@ ExceptionTests.cpp:<line number>
|
||||
<testcase classname="global" name="Comparisons with int literals don't warn when mixing signed/ unsigned" time="{duration}"/>
|
||||
<testcase classname="global" name="Contains string matcher" time="{duration}">
|
||||
<failure message=""this string contains 'abc' as a substring" contains: "not there"" type="CHECK_THAT">
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="global" name="Custom exceptions can be translated when testing for nothrow" time="{duration}">
|
||||
@ -116,7 +124,7 @@ ExceptionTests.cpp:<line number>
|
||||
<testcase classname="global" name="Demonstrate that a non-const == is not used" time="{duration}"/>
|
||||
<testcase classname="global" name="EndsWith string matcher" time="{duration}">
|
||||
<failure message=""this string contains 'abc' as a substring" ends with: "this"" type="CHECK_THAT">
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="global" name="Equality checks that should fail" time="{duration}">
|
||||
@ -164,10 +172,9 @@ ConditionTests.cpp:<line number>
|
||||
<testcase classname="global" name="Equals" time="{duration}"/>
|
||||
<testcase classname="global" name="Equals string matcher" time="{duration}">
|
||||
<failure message=""this string contains 'abc' as a substring" equals: "something else"" type="CHECK_THAT">
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="global" name="Equals string matcher, with NULL" time="{duration}"/>
|
||||
<testcase classname="Exception messages can be tested for" name="exact match" time="{duration}"/>
|
||||
<testcase classname="Exception messages can be tested for" name="different case" time="{duration}"/>
|
||||
<testcase classname="Exception messages can be tested for" name="wildcarded" time="{duration}"/>
|
||||
@ -192,6 +199,12 @@ MessageTests.cpp:<line number>
|
||||
</testcase>
|
||||
<testcase classname="global" name="FAIL does not require an argument" time="{duration}">
|
||||
<failure type="FAIL">
|
||||
MessageTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="global" name="FAIL_CHECK does not abort the test" time="{duration}">
|
||||
<failure type="FAIL_CHECK">
|
||||
This is a failure
|
||||
MessageTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
@ -250,20 +263,20 @@ ConditionTests.cpp:<line number>
|
||||
<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 truncated" 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 (AnyOf) composed with the || operator" time="{duration}"/>
|
||||
<testcase classname="global" name="Matchers can be composed with both && and ||" time="{duration}"/>
|
||||
<testcase classname="global" name="Matchers can be composed with both && and || - failing" time="{duration}">
|
||||
<failure message=""this string contains 'abc' as a substring" ( ( contains: "string" or contains: "different" ) and contains: "random" )" type="CHECK_THAT">
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="global" name="Matchers can be negated (Not) with the ! operator" time="{duration}"/>
|
||||
<testcase classname="global" name="Matchers can be negated (Not) with the ! operator - failing" time="{duration}">
|
||||
<failure message=""this string contains 'abc' as a substring" not contains: "substring"" type="CHECK_THAT">
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="global" name="Mismatching exception messages failing the test" time="{duration}">
|
||||
@ -387,6 +400,7 @@ MessageTests.cpp:<line number>
|
||||
<testcase classname="global" name="Parsing a std::pair" time="{duration}"/>
|
||||
<testcase classname="global" name="Pointers can be compared to null" time="{duration}"/>
|
||||
<testcase classname="global" name="Pointers can be converted to strings" time="{duration}"/>
|
||||
<testcase classname="Process can be configured on command line" name="empty args don't cause a crash" time="{duration}"/>
|
||||
<testcase classname="Process can be configured on command line" name="default - no arguments" time="{duration}"/>
|
||||
<testcase classname="Process can be configured on command line" name="test lists/1 test" time="{duration}"/>
|
||||
<testcase classname="Process can be configured on command line" name="test lists/Specify one test case exclusion using exclude:" time="{duration}"/>
|
||||
@ -446,7 +460,7 @@ Message from section two
|
||||
</testcase>
|
||||
<testcase classname="global" name="StartsWith string matcher" time="{duration}">
|
||||
<failure message=""this string contains 'abc' as a substring" starts with: "string"" type="CHECK_THAT">
|
||||
MiscTests.cpp:<line number>
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="global" name="String matchers" time="{duration}"/>
|
||||
@ -500,6 +514,39 @@ ExceptionTests.cpp:<line number>
|
||||
</testcase>
|
||||
<testcase classname="global" name="Use a custom approx" time="{duration}"/>
|
||||
<testcase classname="Variadic macros" name="Section with one argument" time="{duration}"/>
|
||||
<testcase classname="Vector matchers" name="Contains (element)" time="{duration}"/>
|
||||
<testcase classname="Vector matchers" name="Contains (vector)" time="{duration}"/>
|
||||
<testcase classname="Vector matchers" name="Equals" time="{duration}"/>
|
||||
<testcase classname="Vector matchers that fail" name="Contains (element)" time="{duration}">
|
||||
<failure message="{ 1, 2, 3 } Contains: -1" type="CHECK_THAT">
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
<failure message="{ } Contains: 1" type="CHECK_THAT">
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="Vector matchers that fail" name="Contains (vector)" time="{duration}">
|
||||
<failure message="{ } Contains: { 1, 2, 3 }" type="CHECK_THAT">
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
<failure message="{ 1, 2, 3 } Contains: { 1, 2, 4 }" type="CHECK_THAT">
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="Vector matchers that fail" name="Equals" time="{duration}">
|
||||
<failure message="{ 1, 2, 3 } Equals: { 1, 2 }" type="CHECK_THAT">
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
<failure message="{ 1, 2 } Equals: { 1, 2, 3 }" type="CHECK_THAT">
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
<failure message="{ } Equals: { 1, 2, 3 }" type="CHECK_THAT">
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
<failure message="{ 1, 2, 3 } Equals: { }" type="CHECK_THAT">
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="global" name="When checked exceptions are thrown they can be expected or unexpected" time="{duration}"/>
|
||||
<testcase classname="global" name="When unchecked exceptions are thrown directly they are always failures" time="{duration}">
|
||||
<error type="TEST_CASE">
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -248,15 +248,6 @@ TEST_CASE( "Comparisons between unsigned ints and negative signed ints match c++
|
||||
CHECK( minInt > 2u );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct Ex
|
||||
{
|
||||
Ex( T ){}
|
||||
|
||||
bool operator == ( const T& ) const { return true; }
|
||||
T operator * ( const T& ) const { return T(); }
|
||||
};
|
||||
|
||||
TEST_CASE( "Comparisons between ints where one side is computed", "" )
|
||||
{
|
||||
CHECK( 54 == 6*9 );
|
||||
|
@ -11,6 +11,10 @@
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4702) // Unreachable code -- MSVC 19 (VS 2015) sees right through the indirection
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
inline int thisThrows()
|
||||
|
168
projects/SelfTest/MatchersTests.cpp
Normal file
168
projects/SelfTest/MatchersTests.cpp
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Created by Phil on 21/02/2017.
|
||||
* Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#include "catch.hpp"
|
||||
|
||||
inline const char* testStringForMatching()
|
||||
{
|
||||
return "this string contains 'abc' as a substring";
|
||||
}
|
||||
inline const char* testStringForMatching2()
|
||||
{
|
||||
return "some completely different text that contains one common word";
|
||||
}
|
||||
|
||||
using namespace Catch::Matchers;
|
||||
|
||||
TEST_CASE("String matchers", "[matchers]" )
|
||||
{
|
||||
REQUIRE_THAT( testStringForMatching(), Contains( "string" ) );
|
||||
CHECK_THAT( testStringForMatching(), Contains( "abc" ) );
|
||||
|
||||
CHECK_THAT( testStringForMatching(), StartsWith( "this" ) );
|
||||
CHECK_THAT( testStringForMatching(), EndsWith( "substring" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Contains string matcher", "[.][failing][matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), Contains( "not there" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("StartsWith string matcher", "[.][failing][matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), StartsWith( "string" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("EndsWith string matcher", "[.][failing][matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), EndsWith( "this" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Equals string matcher", "[.][failing][matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), Equals( "something else" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("AllOf matcher", "[matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), AllOf( Catch::Contains( "string" ), Catch::Contains( "abc" ) ) );
|
||||
}
|
||||
TEST_CASE("AnyOf matcher", "[matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "string" ), Catch::Contains( "not there" ) ) );
|
||||
CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "not there" ), Catch::Contains( "string" ) ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Equals", "[matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), Equals( "this string contains 'abc' as a substring" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be (AllOf) composed with the && operator", "[matchers][operators][operator&&]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(),
|
||||
Contains( "string" ) &&
|
||||
Contains( "abc" ) &&
|
||||
Contains( "substring" ) &&
|
||||
Contains( "contains" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be (AnyOf) composed with the || operator", "[matchers][operators][operator||]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) );
|
||||
CHECK_THAT( testStringForMatching2(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be composed with both && and ||", "[matchers][operators][operator||][operator&&]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "substring" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be composed with both && and || - failing", "[matchers][operators][operator||][operator&&][.failing]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "random" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be negated (Not) with the ! operator", "[matchers][operators][not]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), !Contains( "different" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be negated (Not) with the ! operator - failing", "[matchers][operators][not][.failing]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), !Contains( "substring" ) );
|
||||
}
|
||||
|
||||
TEST_CASE( "Vector matchers", "[matchers][vector]" ) {
|
||||
std::vector<int> v;
|
||||
v.push_back( 1 );
|
||||
v.push_back( 2 );
|
||||
v.push_back( 3 );
|
||||
|
||||
std::vector<int> v2;
|
||||
v2.push_back( 1 );
|
||||
v2.push_back( 2 );
|
||||
|
||||
std::vector<int> empty;
|
||||
|
||||
SECTION( "Contains (element)" ) {
|
||||
CHECK_THAT( v, VectorContains( 1 ) );
|
||||
CHECK_THAT( v, VectorContains( 2 ) );
|
||||
}
|
||||
SECTION( "Contains (vector)" ) {
|
||||
CHECK_THAT( v, Contains( v2 ) );
|
||||
v2.push_back( 3 ); // now exactly matches
|
||||
CHECK_THAT( v, Contains( v2 ) );
|
||||
|
||||
CHECK_THAT( v, Contains( empty) );
|
||||
CHECK_THAT( empty, Contains( empty) );
|
||||
}
|
||||
|
||||
SECTION( "Equals" ) {
|
||||
|
||||
// Same vector
|
||||
CHECK_THAT( v, Equals( v ) );
|
||||
|
||||
CHECK_THAT( empty, Equals( empty ) );
|
||||
|
||||
// Different vector with same elements
|
||||
v2.push_back( 3 );
|
||||
CHECK_THAT( v, Equals( v2 ) );
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE( "Vector matchers that fail", "[matchers][vector][.][failing]" ) {
|
||||
std::vector<int> v;
|
||||
v.push_back( 1 );
|
||||
v.push_back( 2 );
|
||||
v.push_back( 3 );
|
||||
|
||||
std::vector<int> v2;
|
||||
v2.push_back( 1 );
|
||||
v2.push_back( 2 );
|
||||
|
||||
std::vector<int> empty;
|
||||
|
||||
SECTION( "Contains (element)" ) {
|
||||
CHECK_THAT( v, VectorContains( -1 ) );
|
||||
CHECK_THAT( empty, VectorContains( 1 ) );
|
||||
}
|
||||
SECTION( "Contains (vector)" ) {
|
||||
CHECK_THAT( empty, Contains( v) );
|
||||
v2.push_back( 4 );
|
||||
CHECK_THAT( v, Contains( v2 ) );
|
||||
}
|
||||
|
||||
SECTION( "Equals" ) {
|
||||
|
||||
CHECK_THAT( v, Equals( v2 ) );
|
||||
CHECK_THAT( v2, Equals( v ) );
|
||||
CHECK_THAT( empty, Equals( v ) );
|
||||
CHECK_THAT( v, Equals( empty ) );
|
||||
}
|
||||
}
|
@ -53,6 +53,13 @@ TEST_CASE( "INFO gets logged on failure, even if captured before successful asse
|
||||
TEST_CASE( "FAIL aborts the test", "[failing][messages][.]" )
|
||||
{
|
||||
FAIL( "This is a " << "failure" ); // This should output the message and abort
|
||||
WARN( "We should never see this");
|
||||
}
|
||||
|
||||
TEST_CASE( "FAIL_CHECK does not abort the test", "[failing][messages][.]" )
|
||||
{
|
||||
FAIL_CHECK( "This is a " << "failure" ); // This should output the message then continue
|
||||
WARN( "This message appears in the output");
|
||||
}
|
||||
|
||||
#ifdef CATCH_CONFIG_VARIADIC_MACROS
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "../include/internal/catch_xmlwriter.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <cerrno>
|
||||
|
||||
TEST_CASE( "random SECTION tests", "[.][sections][failing]" )
|
||||
{
|
||||
@ -204,100 +205,6 @@ TEST_CASE( "atomic if", "[failing][0]")
|
||||
REQUIRE(x == 0);
|
||||
}
|
||||
|
||||
inline const char* testStringForMatching()
|
||||
{
|
||||
return "this string contains 'abc' as a substring";
|
||||
}
|
||||
inline const char* testStringForMatching2()
|
||||
{
|
||||
return "some completely different text that contains one common word";
|
||||
}
|
||||
|
||||
using namespace Catch::Matchers;
|
||||
|
||||
TEST_CASE("String matchers", "[matchers]" )
|
||||
{
|
||||
REQUIRE_THAT( testStringForMatching(), Contains( "string" ) );
|
||||
CHECK_THAT( testStringForMatching(), Contains( "abc" ) );
|
||||
|
||||
CHECK_THAT( testStringForMatching(), StartsWith( "this" ) );
|
||||
CHECK_THAT( testStringForMatching(), EndsWith( "substring" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Contains string matcher", "[.][failing][matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), Contains( "not there" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("StartsWith string matcher", "[.][failing][matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), StartsWith( "string" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("EndsWith string matcher", "[.][failing][matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), EndsWith( "this" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Equals string matcher", "[.][failing][matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), Equals( "something else" ) );
|
||||
}
|
||||
TEST_CASE("Equals string matcher, with NULL", "[matchers]")
|
||||
{
|
||||
REQUIRE_THAT("", Equals(CATCH_NULL));
|
||||
}
|
||||
TEST_CASE("AllOf matcher", "[matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), AllOf( Catch::Contains( "string" ), Catch::Contains( "abc" ) ) );
|
||||
}
|
||||
TEST_CASE("AnyOf matcher", "[matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "string" ), Catch::Contains( "not there" ) ) );
|
||||
CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "not there" ), Catch::Contains( "string" ) ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Equals", "[matchers]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), Equals( "this string contains 'abc' as a substring" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be (AllOf) composed with the && operator", "[matchers][operators][operator&&]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(),
|
||||
Contains( "string" ) &&
|
||||
Contains( "abc" ) &&
|
||||
Contains( "substring" ) &&
|
||||
Contains( "contains" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be (AnyOf) composed with the || operator", "[matchers][operators][operator||]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) );
|
||||
CHECK_THAT( testStringForMatching2(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be composed with both && and ||", "[matchers][operators][operator||][operator&&]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "substring" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be composed with both && and || - failing", "[matchers][operators][operator||][operator&&][.failing]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "random" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be negated (Not) with the ! operator", "[matchers][operators][not]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), !Contains( "different" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be negated (Not) with the ! operator - failing", "[matchers][operators][not][.failing]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(), !Contains( "substring" ) );
|
||||
}
|
||||
|
||||
|
||||
inline unsigned int Factorial( unsigned int number )
|
||||
{
|
||||
// return number <= 1 ? number : Factorial(number-1)*number;
|
||||
@ -487,3 +394,14 @@ TEST_CASE( "This test 'should' fail but doesn't", "[.][failing][!shouldfail]" )
|
||||
TEST_CASE( "# A test name that starts with a #" ) {
|
||||
SUCCEED( "yay" );
|
||||
}
|
||||
|
||||
|
||||
static int f() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST_CASE( "#835 -- errno should not be touched by Catch", "[!shouldfail]" ) {
|
||||
errno = 1;
|
||||
CHECK(f() == 0);
|
||||
REQUIRE(errno == 1); // Check that f() doesn't touch errno.
|
||||
}
|
||||
|
@ -9,6 +9,9 @@
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
||||
#include "../include/reporters/catch_reporter_teamcity.hpp"
|
||||
#include "../include/reporters/catch_reporter_tap.hpp"
|
||||
#include "../include/reporters/catch_reporter_automake.hpp"
|
||||
|
||||
|
||||
// Some example tag aliases
|
||||
CATCH_REGISTER_TAG_ALIAS( "[@nhf]", "[failing]~[.]" )
|
||||
@ -48,10 +51,18 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]"
|
||||
|
||||
Catch::ConfigData config;
|
||||
|
||||
SECTION( "empty args don't cause a crash" ) {
|
||||
Catch::Clara::CommandLine<Catch::ConfigData> parser = Catch::makeCommandLineParser();
|
||||
CHECK_NOTHROW( parser.parseInto( std::vector<std::string>(), config ) );
|
||||
|
||||
CHECK( config.processName == "" );
|
||||
}
|
||||
|
||||
SECTION( "default - no arguments", "" ) {
|
||||
const char* argv[] = { "test" };
|
||||
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
|
||||
|
||||
CHECK( config.processName == "test" );
|
||||
CHECK( config.shouldDebugBreak == false );
|
||||
CHECK( config.abortAfter == -1 );
|
||||
CHECK( config.noThrow == false );
|
||||
@ -468,7 +479,7 @@ TEST_CASE( "Text can be formatted using the Text class", "" ) {
|
||||
CHECK( Text( "hi there", narrow ).toString() == "hi\nthere" );
|
||||
}
|
||||
|
||||
TEST_CASE( "Long text is truncted", "[Text][Truncated]" ) {
|
||||
TEST_CASE( "Long text is truncated", "[Text][Truncated]" ) {
|
||||
|
||||
std::string longLine( 90, '*' );
|
||||
|
||||
|
@ -38,3 +38,17 @@ TEST_CASE( "Character pretty printing" ){
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE( "Capture and info messages" ) {
|
||||
SECTION("Capture should stringify like assertions") {
|
||||
int i = 2;
|
||||
CAPTURE(i);
|
||||
REQUIRE(true);
|
||||
}
|
||||
SECTION("Info should NOT stringify the way assertions do") {
|
||||
int i = 3;
|
||||
INFO(i);
|
||||
REQUIRE(true);
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,8 @@
|
||||
#pragma clang diagnostic ignored "-Wpadded"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "catch.hpp"
|
||||
|
||||
#ifdef __clang__
|
||||
|
@ -148,5 +148,5 @@ approve("junit.sw", ["~[c++11]~[!nonportable]", "-s", "-w", "NoAssertions", "-r"
|
||||
approve("xml.sw", ["~[c++11]~[!nonportable]", "-s", "-w", "NoAssertions", "-r", "xml", "--order", "lex"])
|
||||
|
||||
if overallResult != 0:
|
||||
print("If these differenecs are expected run approve.py to approve new baselines")
|
||||
print("If these differences are expected, run approve.py to approve new baselines.")
|
||||
exit(overallResult)
|
||||
|
148
scripts/benchmarkCompile.py
Executable file
148
scripts/benchmarkCompile.py
Executable file
@ -0,0 +1,148 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import time, subprocess, sys, os, shutil, glob, random
|
||||
import argparse
|
||||
|
||||
def median(lst):
|
||||
lst = sorted(lst)
|
||||
mid, odd = divmod(len(lst), 2)
|
||||
if odd:
|
||||
return lst[mid]
|
||||
else:
|
||||
return (lst[mid - 1] + lst[mid]) / 2.0
|
||||
|
||||
def mean(lst):
|
||||
return float(sum(lst)) / max(len(lst), 1)
|
||||
|
||||
compiler_path = ''
|
||||
flags = []
|
||||
|
||||
main_file = r'''
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
||||
'''
|
||||
main_name = 'catch-main.cpp'
|
||||
|
||||
dir_name = 'benchmark-dir'
|
||||
|
||||
files = 20
|
||||
test_cases_in_file = 20
|
||||
sections_in_file = 4
|
||||
assertions_per_section = 5
|
||||
|
||||
checks = [
|
||||
'a != b', 'a != c', 'a != d', 'a != e', 'b != c', 'b != d', 'b != e', 'c != d', 'c != e', 'd != e', 'a + a == a',
|
||||
'a + b == b', 'a + c == c', 'a + d == d', 'a + e == e', 'b + a == b', 'b + b == c', 'b + c == d',
|
||||
'b + d == e', 'c + a == c', 'c + b == d', 'c + c == e', 'd + a == d', 'd + b == e', 'e + a == e',
|
||||
'a + a + a == a', 'b + c == a + d', 'c + a + a == a + b + b + a',
|
||||
'a < b', 'b < c', 'c < d', 'd < e', 'a >= a', 'd >= b',
|
||||
]
|
||||
|
||||
def create_temp_dir():
|
||||
if os.path.exists(dir_name):
|
||||
shutil.rmtree(dir_name)
|
||||
os.mkdir(dir_name)
|
||||
|
||||
def copy_catch(path_to_catch):
|
||||
shutil.copy(path_to_catch, dir_name)
|
||||
|
||||
def create_catch_main():
|
||||
with open(main_name, 'w') as f:
|
||||
f.write(main_file)
|
||||
|
||||
def compile_main():
|
||||
start_t = time.time()
|
||||
subprocess.check_call([compiler_path, main_name, '-c'] + flags)
|
||||
end_t = time.time()
|
||||
return end_t - start_t
|
||||
|
||||
def compile_files():
|
||||
cpp_files = glob.glob('*.cpp')
|
||||
start_t = time.time()
|
||||
subprocess.check_call([compiler_path, '-c'] + flags + cpp_files)
|
||||
end_t = time.time()
|
||||
return end_t - start_t
|
||||
|
||||
def link_files():
|
||||
obj_files = glob.glob('*.o')
|
||||
start_t = time.time()
|
||||
subprocess.check_call([compiler_path] + flags + obj_files)
|
||||
end_t = time.time()
|
||||
return end_t - start_t
|
||||
|
||||
def benchmark(func):
|
||||
results = [func() for i in range(10)]
|
||||
return mean(results), median(results)
|
||||
|
||||
def char_range(start, end):
|
||||
for c in range(ord(start), ord(end)):
|
||||
yield chr(c)
|
||||
|
||||
def generate_sections(fd):
|
||||
for i in range(sections_in_file):
|
||||
fd.write(' SECTION("Section {}") {{\n'.format(i))
|
||||
fd.write('\n'.join(' CHECK({});'.format(check) for check in random.sample(checks, assertions_per_section)))
|
||||
fd.write(' }\n')
|
||||
|
||||
|
||||
def generate_file(file_no):
|
||||
with open('tests{}.cpp'.format(file_no), 'w') as f:
|
||||
f.write('#include "catch.hpp"\n\n')
|
||||
for i in range(test_cases_in_file):
|
||||
f.write('TEST_CASE("File {} test {}", "[.compile]"){{\n'.format(file_no, i))
|
||||
for i, c in enumerate(char_range('a', 'f')):
|
||||
f.write(' int {} = {};\n'.format(c, i))
|
||||
generate_sections(f)
|
||||
f.write('}\n\n')
|
||||
|
||||
|
||||
def generate_files():
|
||||
create_catch_main()
|
||||
for i in range(files):
|
||||
generate_file(i)
|
||||
|
||||
|
||||
options = ['all', 'main', 'files', 'link']
|
||||
|
||||
parser = argparse.ArgumentParser(description='Benchmarks Catch\'s compile times against some synthetic tests')
|
||||
# Add first arg -- benchmark type
|
||||
parser.add_argument('benchmark_kind', nargs='?', default='all', choices=options, help='What kind of benchmark to run, default: all')
|
||||
|
||||
# Args to allow changing header/compiler
|
||||
parser.add_argument('-I', '--catch-header', default='catch.hpp', help = 'Path to catch.hpp, default: catch.hpp')
|
||||
parser.add_argument('-c', '--compiler', default='g++', help = 'Compiler to use, default: g++')
|
||||
|
||||
parser.add_argument('-f', '--flags', nargs='*', help = 'Flags to be passed to the compiler')
|
||||
|
||||
# Allow creating files only, without running the whole thing
|
||||
parser.add_argument('-g', '--generate-files', action='store_true', help='Generate test files and quit')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
compiler_path = args.compiler
|
||||
catch_path = args.catch_header
|
||||
|
||||
if args.generate_files:
|
||||
create_temp_dir()
|
||||
copy_catch(catch_path)
|
||||
os.chdir(dir_name)
|
||||
# now create the fake test files
|
||||
generate_files()
|
||||
# Early exit
|
||||
print('Finished generating files')
|
||||
exit(1)
|
||||
|
||||
os.chdir(dir_name)
|
||||
|
||||
if args.flags:
|
||||
flags = args.flags
|
||||
|
||||
print('Time needed for ...')
|
||||
if args.benchmark_kind in ('all', 'main'):
|
||||
print(' ... compiling main, mean: {:.2f}, median: {:.2f} s'.format(*benchmark(compile_main)))
|
||||
if args.benchmark_kind in ('all', 'files'):
|
||||
print(' ... compiling test files, mean: {:.2f}, median: {:.2f} s'.format(*benchmark(compile_files)))
|
||||
if args.benchmark_kind in ('all', 'link'):
|
||||
print(' ... linking everything, mean: {:.2f}, median: {:.2f} s'.format(*benchmark(link_files)))
|
@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import sys
|
||||
@ -12,7 +12,7 @@ from scriptCommon import catchPath
|
||||
from releaseCommon import Version
|
||||
|
||||
|
||||
includesParser = re.compile( r'\s*#include\s*"(.*)"' )
|
||||
includesParser = re.compile( r'\s*#\s*include\s*"(.*)"' )
|
||||
guardParser = re.compile( r'\s*#.*TWOBLUECUBES_CATCH_.*_INCLUDED')
|
||||
defineParser = re.compile( r'\s*#define')
|
||||
ifParser = re.compile( r'\s*#ifndef TWOBLUECUBES_CATCH_.*_INCLUDED')
|
||||
@ -65,7 +65,7 @@ def parseFile( path, filename ):
|
||||
if headerFile != "tbc_text_format.h" and headerFile != "clara.h":
|
||||
seenHeaders.add( headerFile )
|
||||
write( "// #included from: {0}\n".format( header ) )
|
||||
if( headerPath == "internal" and path.endswith( "internal/" ) ):
|
||||
if headerPath == "internal" and path.endswith("internal/"):
|
||||
headerPath = ""
|
||||
sep = ""
|
||||
if os.path.exists( path + headerPath + sep + headerFile ):
|
||||
|
@ -75,7 +75,6 @@ class Version:
|
||||
f.write( line + "\n" )
|
||||
|
||||
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' )
|
||||
lines = []
|
||||
@ -84,7 +83,6 @@ class Version:
|
||||
f.close()
|
||||
f = open( readmePath, 'w' )
|
||||
for line in lines:
|
||||
line = versionParser.sub( '*v{0}*'.format(self.getVersionString()), line)
|
||||
line = downloadParser.sub( r'<a href="https://github.com/philsquared/Catch/releases/download/v{0}/catch.hpp">'.format(self.getVersionString()) , line)
|
||||
f.write( line + "\n" )
|
||||
|
||||
|
@ -25,13 +25,13 @@ issues = {}
|
||||
def getIssueTitle( issueNumber ):
|
||||
try:
|
||||
s = urllib2.urlopen("https://api.github.com/repos/philsquared/catch/issues/" + issueNumber ).read()
|
||||
except e:
|
||||
except:
|
||||
return "#HTTP Error#"
|
||||
|
||||
try:
|
||||
j = json.loads( s )
|
||||
return j["title"]
|
||||
except e:
|
||||
except:
|
||||
return "#JSON Error#"
|
||||
|
||||
for line in lines:
|
||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user