mirror of
https://github.com/catchorg/Catch2.git
synced 2025-10-07 04:21:07 +02:00
Compare commits
76 Commits
v2.0.0-dev
...
v2.0.1
Author | SHA1 | Date | |
---|---|---|---|
|
19ab2117c5 | ||
|
4acf112c19 | ||
|
53f6d3fc8e | ||
|
cf76a795cc | ||
|
811f4d13d7 | ||
|
7423a481eb | ||
|
46c7c9d3a0 | ||
|
b119ebdde1 | ||
|
1c43fb64c1 | ||
|
8b40c26434 | ||
|
fe05062f9e | ||
|
31cc62e6b7 | ||
|
a49e6fdc27 | ||
|
2d91035404 | ||
|
accf9859b4 | ||
|
22ac9d2184 | ||
|
00af677577 | ||
|
ae21020640 | ||
|
11f716f28d | ||
|
c3ddd4a7e2 | ||
|
c43ce85416 | ||
|
4220f2eef2 | ||
|
c1a91caf00 | ||
|
96c5de678d | ||
|
e68485e196 | ||
|
88e912b4d1 | ||
|
44244713f1 | ||
|
eea9e1efd7 | ||
|
2a3606f8e3 | ||
|
a6cf19abff | ||
|
601b2888ec | ||
|
3049445d78 | ||
|
c672512979 | ||
|
57b4e0b64c | ||
|
06586b7180 | ||
|
93b3d2cb8f | ||
|
a90473df28 | ||
|
75a77b6f8c | ||
|
5af918eefd | ||
|
c9d9699ca8 | ||
|
296955c437 | ||
|
664cbf702c | ||
|
fb6700df54 | ||
|
05b1ca2884 | ||
|
da6c2a6914 | ||
|
c2b7bd15c0 | ||
|
ba6845a865 | ||
|
2eb93f47f7 | ||
|
276393e4e5 | ||
|
c7d9f02d5b | ||
|
9c07718b5f | ||
|
5ca44b6872 | ||
|
a04bd6d436 | ||
|
784f6dfb34 | ||
|
7818e2666d | ||
|
cd30dd1a70 | ||
|
8e8c0c1675 | ||
|
b6e7c9bd7a | ||
|
180d9242f5 | ||
|
b7bd52cc98 | ||
|
b07a2bdf87 | ||
|
c03e8fce92 | ||
|
27640a5a96 | ||
|
dd3867bbcd | ||
|
387f8d254d | ||
|
c65eccd68e | ||
|
61c5675c11 | ||
|
70e4af9d44 | ||
|
8f41bdb92d | ||
|
7fa5d9ca94 | ||
|
feaf355489 | ||
|
2ce6c74f8f | ||
|
9688891868 | ||
|
4f21bb72ff | ||
|
b435e0d7c7 | ||
|
ba0a09fd9e |
@@ -9,6 +9,7 @@ set(CATCH_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
|||||||
set(SELF_TEST_DIR ${CATCH_DIR}/projects/SelfTest)
|
set(SELF_TEST_DIR ${CATCH_DIR}/projects/SelfTest)
|
||||||
set(BENCHMARK_DIR ${CATCH_DIR}/projects/Benchmark)
|
set(BENCHMARK_DIR ${CATCH_DIR}/projects/Benchmark)
|
||||||
set(HEADER_DIR ${CATCH_DIR}/include)
|
set(HEADER_DIR ${CATCH_DIR}/include)
|
||||||
|
set(CATCH_VERSION_NUMBER 2.0.1)
|
||||||
|
|
||||||
if(USE_CPP14)
|
if(USE_CPP14)
|
||||||
message(STATUS "Enabling C++14")
|
message(STATUS "Enabling C++14")
|
||||||
@@ -275,33 +276,21 @@ set(HEADERS
|
|||||||
${REPORTER_HEADERS}
|
${REPORTER_HEADERS}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
set(BENCH_SOURCES
|
|
||||||
${BENCHMARK_DIR}/BenchMain.cpp
|
|
||||||
${BENCHMARK_DIR}/StringificationBench.cpp
|
|
||||||
)
|
|
||||||
CheckFileList(BENCH_SOURCES ${BENCHMARK_DIR})
|
|
||||||
|
|
||||||
# Provide some groupings for IDEs
|
# Provide some groupings for IDEs
|
||||||
SOURCE_GROUP("Tests" FILES ${TEST_SOURCES})
|
SOURCE_GROUP("Tests" FILES ${TEST_SOURCES})
|
||||||
SOURCE_GROUP("Surrogates" FILES ${SURROGATE_SOURCES})
|
SOURCE_GROUP("Surrogates" FILES ${SURROGATE_SOURCES})
|
||||||
SOURCE_GROUP("Benchmarks" FILES ${BENCH_SOURCES})
|
|
||||||
|
|
||||||
# configure the executable
|
# configure the executable
|
||||||
include_directories(${HEADER_DIR})
|
include_directories(${HEADER_DIR})
|
||||||
|
|
||||||
add_definitions( -DCATCH_CONFIG_FULL_PROJECT )
|
|
||||||
|
|
||||||
# Projects consuming Catch via ExternalProject_Add might want to use install step
|
# Projects consuming Catch via ExternalProject_Add might want to use install step
|
||||||
# without building all of our selftests.
|
# without building all of our selftests.
|
||||||
if (NOT NO_SELFTEST)
|
if (NOT NO_SELFTEST)
|
||||||
add_executable(SelfTest ${TEST_SOURCES} ${IMPL_SOURCES} ${REPORTER_SOURCES} ${SURROGATE_SOURCES} ${HEADERS})
|
add_executable(SelfTest ${TEST_SOURCES} ${IMPL_SOURCES} ${REPORTER_SOURCES} ${SURROGATE_SOURCES} ${HEADERS})
|
||||||
add_executable(Benchmark ${BENCH_SOURCES} ${IMPL_SOURCES} ${REPORTER_SOURCES} ${HEADERS})
|
|
||||||
|
|
||||||
# Add desired warnings
|
# Add desired warnings
|
||||||
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
|
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
|
||||||
target_compile_options( SelfTest PRIVATE -Wall -Wextra -Wunreachable-code )
|
target_compile_options( SelfTest PRIVATE -Wall -Wextra -Wunreachable-code )
|
||||||
target_compile_options( Benchmark PRIVATE -Wall -Wextra -Wunreachable-code )
|
|
||||||
endif()
|
endif()
|
||||||
# Clang specific warning go here
|
# Clang specific warning go here
|
||||||
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||||
@@ -309,8 +298,7 @@ if (NOT NO_SELFTEST)
|
|||||||
target_compile_options( SelfTest PRIVATE -Wweak-vtables -Wexit-time-destructors -Wglobal-constructors -Wmissing-noreturn )
|
target_compile_options( SelfTest PRIVATE -Wweak-vtables -Wexit-time-destructors -Wglobal-constructors -Wmissing-noreturn )
|
||||||
endif()
|
endif()
|
||||||
if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
|
if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
|
||||||
target_compile_options( SelfTest PRIVATE /W4 /w44265 /WX )
|
target_compile_options( SelfTest PRIVATE /W4 /w44265 /WX /w44061 /w44062 )
|
||||||
target_compile_options( Benchmark PRIVATE /W4 )
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
@@ -331,3 +319,17 @@ endif() # !NO_SELFTEST
|
|||||||
|
|
||||||
|
|
||||||
install(DIRECTORY "single_include/" DESTINATION "include/catch")
|
install(DIRECTORY "single_include/" DESTINATION "include/catch")
|
||||||
|
|
||||||
|
## Provide some pkg-config integration
|
||||||
|
# Don't bother on Windows
|
||||||
|
if(NOT WIN32 OR NOT CMAKE_HOST_SYSTEM_NAME MATCHES Windows)
|
||||||
|
|
||||||
|
set(PKGCONFIG_INSTALL_DIR
|
||||||
|
"${CMAKE_INSTALL_PREFIX}/share/pkgconfig"
|
||||||
|
CACHE PATH "Path where catch.pc is installed"
|
||||||
|
)
|
||||||
|
|
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/catch.pc.in ${CMAKE_CURRENT_BINARY_DIR}/catch.pc @ONLY)
|
||||||
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/catch.pc DESTINATION ${PKGCONFIG_INSTALL_DIR})
|
||||||
|
|
||||||
|
endif()
|
||||||
|
22
README.md
22
README.md
@@ -1,17 +1,23 @@
|
|||||||
<a id="top"></a>
|
<a id="top"></a>
|
||||||

|

|
||||||
|
|
||||||
[](https://github.com/philsquared/catch/releases)
|
[](https://github.com/catchorg/catch2/releases)
|
||||||
[](https://travis-ci.org/philsquared/Catch?branch=catch2)
|
[](https://travis-ci.org/philsquared/Catch)
|
||||||
[](https://ci.appveyor.com/project/philsquared/catch/branch/catch2)
|
[](https://ci.appveyor.com/project/philsquared/catch)
|
||||||
|
|
||||||
<a href="https://github.com/philsquared/Catch/releases/download/v2.0.0-develop.4/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
|
<a href="https://github.com/catchorg/Catch2/releases/download/v2.0.1/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
|
||||||
|
|
||||||
|
## Catch2 is released!
|
||||||
|
|
||||||
|
If you've been using an earlier version of Catch, please see the
|
||||||
|
Breaking Changes section of [the release notes](https://github.com/catchorg/Catch2/releases/tag/v2.0.1)
|
||||||
|
before moving to Catch2.
|
||||||
|
|
||||||
## What's the Catch?
|
## What's the Catch?
|
||||||
|
|
||||||
Catch stands for C++ Automated Test Cases in Headers and is a
|
Catch2 stands for C++ Automated Test Cases in a Header and is a
|
||||||
multi-paradigm test framework for C++. which also supports Objective-C
|
multi-paradigm test framework for C++. which also supports Objective-C
|
||||||
and, maybe, C.
|
(and maybe C).
|
||||||
It is primarily distributed as a single header file, although certain
|
It is primarily distributed as a single header file, although certain
|
||||||
extensions may require additional headers.
|
extensions may require additional headers.
|
||||||
|
|
||||||
@@ -23,6 +29,6 @@ This documentation comprises these three parts:
|
|||||||
* [Reference section](docs/Readme.md#top) - all the details
|
* [Reference section](docs/Readme.md#top) - all the details
|
||||||
|
|
||||||
## More
|
## More
|
||||||
* Issues and bugs can be raised on the [Issue tracker on GitHub](https://github.com/philsquared/Catch/issues)
|
* Issues and bugs can be raised on the [Issue tracker on GitHub](https://github.com/catchorg/Catch2/issues)
|
||||||
* For discussion or questions please use [the dedicated Google Groups forum](https://groups.google.com/forum/?fromgroups#!forum/catch-forum)
|
* For discussion or questions please use [the dedicated Google Groups forum](https://groups.google.com/forum/?fromgroups#!forum/catch-forum)
|
||||||
* See [who else is using Catch](docs/opensource-users.md#top)
|
* See [who else is using Catch2](docs/opensource-users.md#top)
|
||||||
|
9
catch.pc.in
Normal file
9
catch.pc.in
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
prefix=@CMAKE_INSTALL_PREFIX@
|
||||||
|
exec_prefix=${prefix}
|
||||||
|
|
||||||
|
Name: Catch
|
||||||
|
Description: Testing library for C++
|
||||||
|
Requires:
|
||||||
|
Version: @CATCH_VERSION_NUMBER@
|
||||||
|
Libs:
|
||||||
|
Cflags: -I${prefix}/@INCLUDE_INSTALL_DIR@/include
|
@@ -4,7 +4,7 @@ from conans import ConanFile
|
|||||||
|
|
||||||
class CatchConan(ConanFile):
|
class CatchConan(ConanFile):
|
||||||
name = "Catch"
|
name = "Catch"
|
||||||
version = "2.0.0-develop.5"
|
version = "2.0.1"
|
||||||
description = "A modern, C++-native, header-only, framework for unit-tests, TDD and BDD"
|
description = "A modern, C++-native, header-only, framework for unit-tests, TDD and BDD"
|
||||||
author = "philsquared"
|
author = "philsquared"
|
||||||
generators = "cmake"
|
generators = "cmake"
|
||||||
@@ -14,3 +14,6 @@ class CatchConan(ConanFile):
|
|||||||
|
|
||||||
def package(self):
|
def package(self):
|
||||||
self.copy(pattern="catch.hpp", src="single_include", dst="include")
|
self.copy(pattern="catch.hpp", src="single_include", dst="include")
|
||||||
|
|
||||||
|
def package_id(self):
|
||||||
|
self.info.header_only()
|
||||||
|
@@ -36,6 +36,8 @@
|
|||||||
# -- adds fixture class name to the test name #
|
# -- adds fixture class name to the test name #
|
||||||
# PARSE_CATCH_TESTS_ADD_TARGET_IN_TEST_NAME (Default ON) #
|
# PARSE_CATCH_TESTS_ADD_TARGET_IN_TEST_NAME (Default ON) #
|
||||||
# -- adds cmake target name to the test name #
|
# -- adds cmake target name to the test name #
|
||||||
|
# PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS (Default OFF) #
|
||||||
|
# -- causes CMake to rerun when file with tests changes so that new tests will be discovered #
|
||||||
# #
|
# #
|
||||||
#==================================================================================================#
|
#==================================================================================================#
|
||||||
|
|
||||||
@@ -45,6 +47,7 @@ option(PARSE_CATCH_TESTS_VERBOSE "Print Catch to CTest parser debug messages" OF
|
|||||||
option(PARSE_CATCH_TESTS_NO_HIDDEN_TESTS "Exclude tests with [!hide], [.] or [.foo] tags" OFF)
|
option(PARSE_CATCH_TESTS_NO_HIDDEN_TESTS "Exclude tests with [!hide], [.] or [.foo] tags" OFF)
|
||||||
option(PARSE_CATCH_TESTS_ADD_FIXTURE_IN_TEST_NAME "Add fixture class name to the test name" ON)
|
option(PARSE_CATCH_TESTS_ADD_FIXTURE_IN_TEST_NAME "Add fixture class name to the test name" ON)
|
||||||
option(PARSE_CATCH_TESTS_ADD_TARGET_IN_TEST_NAME "Add target name to the test name" ON)
|
option(PARSE_CATCH_TESTS_ADD_TARGET_IN_TEST_NAME "Add target name to the test name" ON)
|
||||||
|
option(PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS "Add test file to CMAKE_CONFIGURE_DEPENDS property" OFF)
|
||||||
|
|
||||||
function(PrintDebugMessage)
|
function(PrintDebugMessage)
|
||||||
if(PARSE_CATCH_TESTS_VERBOSE)
|
if(PARSE_CATCH_TESTS_VERBOSE)
|
||||||
@@ -85,6 +88,15 @@ function(ParseFile SourceFile TestTarget)
|
|||||||
# Find definition of test names
|
# Find definition of test names
|
||||||
string(REGEX MATCHALL "[ \t]*(CATCH_)?(TEST_CASE_METHOD|SCENARIO|TEST_CASE)[ \t]*\\([^\)]+\\)+[ \t\n]*{+[ \t]*(//[^\n]*[Tt][Ii][Mm][Ee][Oo][Uu][Tt][ \t]*[0-9]+)*" Tests "${Contents}")
|
string(REGEX MATCHALL "[ \t]*(CATCH_)?(TEST_CASE_METHOD|SCENARIO|TEST_CASE)[ \t]*\\([^\)]+\\)+[ \t\n]*{+[ \t]*(//[^\n]*[Tt][Ii][Mm][Ee][Oo][Uu][Tt][ \t]*[0-9]+)*" Tests "${Contents}")
|
||||||
|
|
||||||
|
if(PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS AND Tests)
|
||||||
|
PrintDebugMessage("Adding ${SourceFile} to CMAKE_CONFIGURE_DEPENDS property")
|
||||||
|
set_property(
|
||||||
|
DIRECTORY
|
||||||
|
APPEND
|
||||||
|
PROPERTY CMAKE_CONFIGURE_DEPENDS ${SourceFile}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
foreach(TestName ${Tests})
|
foreach(TestName ${Tests})
|
||||||
# Strip newlines
|
# Strip newlines
|
||||||
string(REGEX REPLACE "\\\\\n|\n" "" TestName "${TestName}")
|
string(REGEX REPLACE "\\\\\n|\n" "" TestName "${TestName}")
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
<a id="top"></a>
|
<a id="top"></a>
|
||||||
# Reference
|
# Reference
|
||||||
|
|
||||||
To get the most out of Catch, start with the [tutorial](tutorial.md#top).
|
To get the most out of Catch2, start with the [tutorial](tutorial.md#top).
|
||||||
Once you're up and running consider the following reference material.
|
Once you're up and running consider the following reference material.
|
||||||
|
|
||||||
Writing tests:
|
Writing tests:
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
<a id="top"></a>
|
<a id="top"></a>
|
||||||
# Assertion Macros
|
# Assertion Macros
|
||||||
|
|
||||||
**Contents**
|
**Contents**<br>
|
||||||
[Natural Expressions](#natural-expressions)
|
[Natural Expressions](#natural-expressions)<br>
|
||||||
[Exceptions](#exceptions)
|
[Exceptions](#exceptions)<br>
|
||||||
[Matcher expressions](#matcher-expressions)
|
[Matcher expressions](#matcher-expressions)<br>
|
||||||
[Thread Safety](#thread-safety)
|
[Thread Safety](#thread-safety)<br>
|
||||||
|
|
||||||
Most test frameworks have a large collection of assertion macros to capture all possible conditional forms (```_EQUALS```, ```_NOTEQUALS```, ```_GREATER_THAN``` etc).
|
Most test frameworks have a large collection of assertion macros to capture all possible conditional forms (```_EQUALS```, ```_NOTEQUALS```, ```_GREATER_THAN``` etc).
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ This way `Approx` is constructed with reasonable defaults, covering most simple
|
|||||||
|
|
||||||
* __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`.
|
* __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`.
|
* __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`.
|
* __scale__ - scale serves to adjust the epsilon's multiplicator. By default set to `0.0`.
|
||||||
|
|
||||||
#### epsilon example
|
#### epsilon example
|
||||||
```cpp
|
```cpp
|
||||||
@@ -84,7 +84,12 @@ Approx target = Approx(100).margin(5);
|
|||||||
```
|
```
|
||||||
|
|
||||||
#### scale
|
#### 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).
|
Scale can be useful if the computation leading to the result worked
|
||||||
|
on different scale than is used by the results. Since allowed difference
|
||||||
|
between Approx's value and compared value is based primarily on Approx's value
|
||||||
|
(the allowed difference is computed as
|
||||||
|
`(Approx::scale + Approx::value) * epsilon`), the resulting comparison could
|
||||||
|
need rescaling to be correct.
|
||||||
|
|
||||||
|
|
||||||
## Exceptions
|
## Exceptions
|
||||||
|
@@ -16,7 +16,7 @@ The XML Reporter writes in an XML format that is specific to Catch.
|
|||||||
|
|
||||||
The advantage of this format is that it corresponds well to the way Catch works (especially the more unusual features, such as nested sections) and is a fully streaming format - that is it writes output as it goes, without having to store up all its results before it can start writing.
|
The advantage of this format is that it corresponds well to the way Catch works (especially the more unusual features, such as nested sections) and is a fully streaming format - that is it writes output as it goes, without having to store up all its results before it can start writing.
|
||||||
|
|
||||||
The disadvantage is that, being specific to Catch, no existing build servers understand the format natively. It can be used as input to an XSLT transformation that could covert it to, say, HTML - although this loses the streaming advantage, of course.
|
The disadvantage is that, being specific to Catch, no existing build servers understand the format natively. It can be used as input to an XSLT transformation that could convert it to, say, HTML - although this loses the streaming advantage, of course.
|
||||||
|
|
||||||
### JUnit Reporter
|
### JUnit Reporter
|
||||||
```-r junit```
|
```-r junit```
|
||||||
|
@@ -1,29 +1,29 @@
|
|||||||
<a id="top"></a>
|
<a id="top"></a>
|
||||||
# Command line
|
# Command line
|
||||||
|
|
||||||
**Contents**
|
**Contents**<br>
|
||||||
[Specifying which tests to run](#specifying-which-tests-to-run)
|
[Specifying which tests to run](#specifying-which-tests-to-run)<br>
|
||||||
[Choosing a reporter to use](#choosing-a-reporter-to-use)
|
[Choosing a reporter to use](#choosing-a-reporter-to-use)<br>
|
||||||
[Breaking into the debugger](#breaking-into-the-debugger)
|
[Breaking into the debugger](#breaking-into-the-debugger)<br>
|
||||||
[Showing results for successful tests](#showing-results-for-successful-tests)
|
[Showing results for successful tests](#showing-results-for-successful-tests)<br>
|
||||||
[Aborting after a certain number of failures](#aborting-after-a-certain-number-of-failures)
|
[Aborting after a certain number of failures](#aborting-after-a-certain-number-of-failures)<br>
|
||||||
[Listing available tests, tags or reporters](#listing-available-tests-tags-or-reporters)
|
[Listing available tests, tags or reporters](#listing-available-tests-tags-or-reporters)<br>
|
||||||
[Sending output to a file](#sending-output-to-a-file)
|
[Sending output to a file](#sending-output-to-a-file)<br>
|
||||||
[Naming a test run](#naming-a-test-run)
|
[Naming a test run](#naming-a-test-run)<br>
|
||||||
[Eliding assertions expected to throw](#eliding-assertions-expected-to-throw)
|
[Eliding assertions expected to throw](#eliding-assertions-expected-to-throw)<br>
|
||||||
[Make whitespace visible](#make-whitespace-visible)
|
[Make whitespace visible](#make-whitespace-visible)<br>
|
||||||
[Warnings](#warnings)
|
[Warnings](#warnings)<br>
|
||||||
[Reporting timings](#reporting-timings)
|
[Reporting timings](#reporting-timings)<br>
|
||||||
[Load test names to run from a file](#load-test-names-to-run-from-a-file)
|
[Load test names to run from a file](#load-test-names-to-run-from-a-file)<br>
|
||||||
[Just test names](#just-test-names)
|
[Just test names](#just-test-names)<br>
|
||||||
[Specify the order test cases are run](#specify-the-order-test-cases-are-run)
|
[Specify the order test cases are run](#specify-the-order-test-cases-are-run)<br>
|
||||||
[Specify a seed for the Random Number Generator](#specify-a-seed-for-the-random-number-generator)
|
[Specify a seed for the Random Number Generator](#specify-a-seed-for-the-random-number-generator)<br>
|
||||||
[Identify framework and version according to the libIdentify standard](#identify-framework-and-version-according-to-the-libidentify-standard)
|
[Identify framework and version according to the libIdentify standard](#identify-framework-and-version-according-to-the-libidentify-standard)<br>
|
||||||
[Wait for key before continuing](#wait-for-key-before-continuing)
|
[Wait for key before continuing](#wait-for-key-before-continuing)<br>
|
||||||
[Specify multiples of clock resolution to run benchmarks for](#specify-multiples-of-clock-resolution-to-run-benchmarks-for)
|
[Specify multiples of clock resolution to run benchmarks for](#specify-multiples-of-clock-resolution-to-run-benchmarks-for)<br>
|
||||||
[Usage](#usage)
|
[Usage](#usage)<br>
|
||||||
[Specify the section to run](#specify-the-section-to-run)
|
[Specify the section to run](#specify-the-section-to-run)<br>
|
||||||
[Filenames as tags](#filenames-as-tags)
|
[Filenames as tags](#filenames-as-tags)<br>
|
||||||
|
|
||||||
Catch works quite nicely without any command line options at all - but for those times when you want greater control the following options are available.
|
Catch works quite nicely without any command line options at all - but for those times when you want greater control the following options are available.
|
||||||
Click one of the followings links to take you straight to that option - or scroll on to browse the available options.
|
Click one of the followings links to take you straight to that option - or scroll on to browse the available options.
|
||||||
|
@@ -1,15 +1,15 @@
|
|||||||
<a id="top"></a>
|
<a id="top"></a>
|
||||||
# Compile-time configuration
|
# Compile-time configuration
|
||||||
|
|
||||||
**Contents**
|
**Contents**<br>
|
||||||
[main()/ implementation](#main-implementation)
|
[main()/ implementation](#main-implementation)<br>
|
||||||
[Prefixing Catch macros](#prefixing-catch-macros)
|
[Prefixing Catch macros](#prefixing-catch-macros)<br>
|
||||||
[Terminal colour](#terminal-colour)
|
[Terminal colour](#terminal-colour)<br>
|
||||||
[Console width](#console-width)
|
[Console width](#console-width)<br>
|
||||||
[stdout](#stdout)
|
[stdout](#stdout)<br>
|
||||||
[Other toggles](#other-toggles)
|
[Other toggles](#other-toggles)<br>
|
||||||
[Windows header clutter](#windows-header-clutter)
|
[Windows header clutter](#windows-header-clutter)<br>
|
||||||
[Enabling stringification](#enabling-stringification)
|
[Enabling stringification](#enabling-stringification)<br>
|
||||||
|
|
||||||
Catch is designed to "just work" as much as possible. For most people the only configuration needed is telling Catch which source file should host all the implementation code (```CATCH_CONFIG_MAIN```).
|
Catch is designed to "just work" as much as possible. For most people the only configuration needed is telling Catch which source file should host all the implementation code (```CATCH_CONFIG_MAIN```).
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ When `CATCH_CONFIG_DISABLE_MATCHERS` is defined, all mentions of Catch's Matcher
|
|||||||
_Note: If you define `CATCH_CONFIG_DISABLE_MATCHERS` in the same file as Catch's main is implemented, your test executable will fail to link if you use Matchers anywhere._
|
_Note: If you define `CATCH_CONFIG_DISABLE_MATCHERS` in the same file as Catch's main is implemented, your test executable will fail to link if you use Matchers anywhere._
|
||||||
|
|
||||||
### `CATCH_CONFIG_DISABLE_STRINGIFICATION`
|
### `CATCH_CONFIG_DISABLE_STRINGIFICATION`
|
||||||
This toggle enables a workaround for VS 2017 bug. For details see [known limitations](limitations.md#Visual Studio 2017 -- raw string literal in assert fails to compile)
|
This toggle enables a workaround for VS 2017 bug. For details see [known limitations](limitations.md#visual-studio-2017----raw-string-literal-in-assert-fails-to-compile).
|
||||||
|
|
||||||
### `CATCH_CONFIG_DISABLE`
|
### `CATCH_CONFIG_DISABLE`
|
||||||
This toggle removes most of Catch from given file. This means that `TEST_CASE`s are not registered and assertions are turned into no-ops. Useful for keeping tests within implementation files (ie for functions with internal linkage), instead of in external files.
|
This toggle removes most of Catch from given file. This means that `TEST_CASE`s are not registered and assertions are turned into no-ops. Useful for keeping tests within implementation files (ie for functions with internal linkage), instead of in external files.
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
<a id="top"></a>
|
<a id="top"></a>
|
||||||
# Open Source projects using Catch
|
# Open Source projects using Catch
|
||||||
|
|
||||||
Catch is great for open source. With it's [liberal license](../LICENSE.txt) and single-header, dependency-free, distribution
|
Catch is great for open source. With its [liberal license](../LICENSE.txt) and single-header, dependency-free, distribution
|
||||||
it's easy to just drop the header into your project and start writing tests - what's not to like?
|
it's easy to just drop the header into your project and start writing tests - what's not to like?
|
||||||
|
|
||||||
As a result Catch is now being used in many Open Source projects, including some quite well known ones.
|
As a result Catch is now being used in many Open Source projects, including some quite well known ones.
|
||||||
|
@@ -39,34 +39,20 @@ If you still want Catch to process the command line, but you want to programatic
|
|||||||
int main( int argc, char* argv[] )
|
int main( int argc, char* argv[] )
|
||||||
{
|
{
|
||||||
Catch::Session session; // There must be exactly one instance
|
Catch::Session session; // There must be exactly one instance
|
||||||
|
|
||||||
// writing to session.configData() here sets defaults
|
// writing to session.configData() here sets defaults
|
||||||
// this is the preferred way to set them
|
// this is the preferred way to set them
|
||||||
|
|
||||||
// Verify that all tests, aliases, etc registered properly
|
|
||||||
const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
|
|
||||||
if ( !exceptions.empty() ) {
|
|
||||||
// iterate over all exceptions and notify user
|
|
||||||
for ( const auto& ex_ptr : exceptions ) {
|
|
||||||
try {
|
|
||||||
std::rethrow_exception(ex_ptr);
|
|
||||||
} catch (std::exception const& ex) {
|
|
||||||
Catch::cerr() << ex.what();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Indicate that an error occured before main
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int returnCode = session.applyCommandLine( argc, argv );
|
int returnCode = session.applyCommandLine( argc, argv );
|
||||||
if( returnCode != 0 ) // Indicates a command line error
|
if( returnCode != 0 ) // Indicates a command line error
|
||||||
return returnCode;
|
return returnCode;
|
||||||
|
|
||||||
// writing to session.configData() or session.Config() here
|
// writing to session.configData() or session.Config() here
|
||||||
// overrides command line args
|
// overrides command line args
|
||||||
// only do this if you know you need to
|
// only do this if you know you need to
|
||||||
|
|
||||||
int numFailed = session.run();
|
int numFailed = session.run();
|
||||||
|
|
||||||
// numFailed is clamped to 255 as some unices only use the lower 8 bits.
|
// numFailed is clamped to 255 as some unices only use the lower 8 bits.
|
||||||
// This clamping has already been applied, so just return it here
|
// This clamping has already been applied, so just return it here
|
||||||
// You can also do any post run clean-up here
|
// You can also do any post run clean-up here
|
||||||
@@ -80,7 +66,44 @@ To take full control of the config simply omit the call to ```applyCommandLine()
|
|||||||
|
|
||||||
## Adding your own command line options
|
## Adding your own command line options
|
||||||
|
|
||||||
Catch embeds a powerful command line parser which you can also use to parse your own options out. This capability is still in active development but will be documented here when it is ready.
|
Catch embeds a powerful command line parser called [Clara](https://github.com/philsquared/Clara).
|
||||||
|
As of Catch2 (and Clara 1.0) Clara allows you to write _composable_ option and argument parsers,
|
||||||
|
so extending Catch's own command line options is now easy.
|
||||||
|
|
||||||
|
```c++
|
||||||
|
#define CATCH_CONFIG_RUNNER
|
||||||
|
#include "catch.hpp"
|
||||||
|
|
||||||
|
int main( int argc, char* argv[] )
|
||||||
|
{
|
||||||
|
Catch::Session session; // There must be exactly one instance
|
||||||
|
|
||||||
|
int height = 0; // Some user variable you want to be able to set
|
||||||
|
|
||||||
|
// Build a new parser on top of Catch's
|
||||||
|
auto cli
|
||||||
|
= session.cli() // Get Catch's composite command line parser
|
||||||
|
| Opt( height, "height" ) // bind variable to a new option, with a hint string
|
||||||
|
["-g"]["--height"] // the option names it will respond to
|
||||||
|
("how high?"); // description string for the help output
|
||||||
|
|
||||||
|
// Now pass the new composite back to Catch so it uses that
|
||||||
|
session.cli( cli );
|
||||||
|
|
||||||
|
// Let Catch (using Clara) parse the command line
|
||||||
|
int returnCode = session.applyCommandLine( argc, argv );
|
||||||
|
if( returnCode != 0 ) // Indicates a command line error
|
||||||
|
return returnCode;
|
||||||
|
|
||||||
|
// if set on the command line then 'height' is now set at this point
|
||||||
|
if( height > 0 )
|
||||||
|
std::cout << "height: " << height << std::endl;
|
||||||
|
|
||||||
|
return session.run();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
See the [Clara documentation](https://github.com/philsquared/Clara/blob/master/README.md) for more details.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<a id="top"></a>
|
<a id="top"></a>
|
||||||
# 2.0.0 (in progress)
|
# 2.0.1
|
||||||
|
|
||||||
## Breaking changes
|
## Breaking changes
|
||||||
* Removed C++98 support
|
* Removed C++98 support
|
||||||
@@ -25,6 +25,11 @@
|
|||||||
* `std::pair` and `std::tuple` are no longer stringified by default
|
* `std::pair` and `std::tuple` are no longer stringified by default
|
||||||
* This is done to avoid dragging in `<tuple>` and `<utility>` headers in common path
|
* This is done to avoid dragging in `<tuple>` and `<utility>` headers in common path
|
||||||
* Their stringification can be enabled per-file via new configuration macros
|
* Their stringification can be enabled per-file via new configuration macros
|
||||||
|
* `Approx` is subtly different and hopefully behaves more as users would expect
|
||||||
|
* `Approx::scale` defaults to `0.0`
|
||||||
|
* `Approx::epsilon` no longer applies to the larger of the two compared values, but only to the `Approx`'s value
|
||||||
|
* `INFINITY == Approx(INFINITY)` returns true
|
||||||
|
|
||||||
|
|
||||||
## Improvements
|
## Improvements
|
||||||
* Reporters and Listeners can be defined in files different from the main file
|
* Reporters and Listeners can be defined in files different from the main file
|
||||||
@@ -57,6 +62,8 @@
|
|||||||
* The Reporter/Listener interface provides default, empty, implementation to preserve backward compatibility
|
* The Reporter/Listener interface provides default, empty, implementation to preserve backward compatibility
|
||||||
* Stringification of `std::chrono::duration` and `std::chrono::time_point` is now supported
|
* Stringification of `std::chrono::duration` and `std::chrono::time_point` is now supported
|
||||||
* Needs to be enabled by a per-file compile time configuration option
|
* Needs to be enabled by a per-file compile time configuration option
|
||||||
|
* Add `pkg-config` support to CMake install command
|
||||||
|
|
||||||
|
|
||||||
## Fixes
|
## Fixes
|
||||||
* Don't use console colour if running in XCode
|
* Don't use console colour if running in XCode
|
||||||
@@ -67,6 +74,8 @@
|
|||||||
* Implemented a workaround for `std::uncaught_exception` issues in libcxxrt
|
* Implemented a workaround for `std::uncaught_exception` issues in libcxxrt
|
||||||
* These issues caused incorrect section traversals
|
* These issues caused incorrect section traversals
|
||||||
* The workaround is only partial, user's test can still trigger the issue by using `throw;` to rethrow an exception
|
* The workaround is only partial, user's test can still trigger the issue by using `throw;` to rethrow an exception
|
||||||
|
* Suppressed C4061 warning under MSVC
|
||||||
|
|
||||||
|
|
||||||
## Internal changes
|
## Internal changes
|
||||||
* The development version now uses .cpp files instead of header files containing implementation.
|
* The development version now uses .cpp files instead of header files containing implementation.
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
<a id="top"></a>
|
<a id="top"></a>
|
||||||
# Why do my tests take so long to compile?
|
# Why do my tests take so long to compile?
|
||||||
|
|
||||||
**Contents**
|
**Contents**<br>
|
||||||
[Short answer](#short-answer)
|
[Short answer](#short-answer)<br>
|
||||||
[Long answer](#long-answer)
|
[Long answer](#long-answer)<br>
|
||||||
[Practical example](#practical-example)
|
[Practical example](#practical-example)<br>
|
||||||
[Other possible solutions](#other-possible-solutions)
|
[Other possible solutions](#other-possible-solutions)<br>
|
||||||
|
|
||||||
Several people have reported that test code written with Catch takes much longer to compile than they would expect. Why is that?
|
Several people have reported that test code written with Catch takes much longer to compile than they would expect. Why is that?
|
||||||
|
|
||||||
|
@@ -39,13 +39,13 @@ 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`.
|
* `[!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`.
|
||||||
|
|
||||||
* `[!mayfail]` - doesn't fail the test if any given assertion fails (but still reports it). This can be useful to flag a work-in-progress, or a known issue that you don't want to immediately fix but still want to track in the your tests.
|
* `[!mayfail]` - doesn't fail the test if any given assertion fails (but still reports it). This can be useful to flag a work-in-progress, or a known issue that you don't want to immediately fix but still want to track in 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.
|
* `[!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.
|
* `[!nonportable]` - Indicates that behaviour may vary between platforms or compilers.
|
||||||
|
|
||||||
* `[#<filename>]` - running with `-#` or `--filenames-as-tags` causes Catch to add the filename, prefixed with `#` (and with any extension stripped) as a tag. e.g. tests in testfile.cpp would all be tagged `[#testfile]`.
|
* `[#<filename>]` - running with `-#` or `--filenames-as-tags` causes Catch to add the filename, prefixed with `#` (and with any extension stripped), as a tag to all contained tests, e.g. tests in testfile.cpp would all be tagged `[#testfile]`.
|
||||||
|
|
||||||
* `[@<alias>]` - tag aliases all begin with `@` (see below).
|
* `[@<alias>]` - tag aliases all begin with `@` (see below).
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ All tag names beginning with non-alphanumeric characters are reserved by Catch.
|
|||||||
|
|
||||||
## Tag aliases
|
## Tag aliases
|
||||||
|
|
||||||
Between tag expressions and wildcarded test names (as well as combinations of the two) quite complex patterns can be constructed to direct which test cases are run. If a complex pattern is used often it is convenient to be able to create an alias for the expression. this can be done, in code, using the following form:
|
Between tag expressions and wildcarded test names (as well as combinations of the two) quite complex patterns can be constructed to direct which test cases are run. If a complex pattern is used often it is convenient to be able to create an alias for the expression. This can be done, in code, using the following form:
|
||||||
|
|
||||||
CATCH_REGISTER_TAG_ALIAS( <alias string>, <tag expression> )
|
CATCH_REGISTER_TAG_ALIAS( <alias string>, <tag expression> )
|
||||||
|
|
||||||
|
@@ -1,27 +1,27 @@
|
|||||||
<a id="top"></a>
|
<a id="top"></a>
|
||||||
# Tutorial
|
# Tutorial
|
||||||
|
|
||||||
**Contents**
|
**Contents**<br>
|
||||||
[Getting Catch](#getting-catch)
|
[Getting Catch2](#getting-catch2)<br>
|
||||||
[Where to put it?](#where-to-put-it)
|
[Where to put it?](#where-to-put-it)<br>
|
||||||
[Writing tests](#writing-tests)
|
[Writing tests](#writing-tests)<br>
|
||||||
[Test cases and sections](#test-cases-and-sections)
|
[Test cases and sections](#test-cases-and-sections)<br>
|
||||||
[BDD-Style](#bdd-style)
|
[BDD-Style](#bdd-style)<br>
|
||||||
[Scaling up](#scaling-up)
|
[Scaling up](#scaling-up)<br>
|
||||||
[Next steps](#next-steps)
|
[Next steps](#next-steps)<br>
|
||||||
|
|
||||||
## Getting Catch
|
## Getting Catch2
|
||||||
|
|
||||||
The simplest way to get Catch is to download the latest [single header version](https://raw.githubusercontent.com/philsquared/Catch/master/single_include/catch.hpp). The single header is generated by merging a set of individual headers but it is still just normal source code in a header file.
|
The simplest way to get Catch2 is to download the latest [single header version](https://raw.githubusercontent.com/CatchOrg/Catch2/master/single_include/catch.hpp). The single header is generated by merging a set of individual headers but it is still just normal source code in a header file.
|
||||||
|
|
||||||
The full source for Catch, including test projects, documentation, and other things, is hosted on GitHub. [http://catch-lib.net](http://catch-lib.net) will redirect you there.
|
The full source for Catch2, including test projects, documentation, and other things, is hosted on GitHub. [http://catch-lib.net](http://catch-lib.net) will redirect you there.
|
||||||
|
|
||||||
|
|
||||||
## Where to put it?
|
## Where to put it?
|
||||||
|
|
||||||
Catch is header only. All you need to do is drop the file(s) somewhere reachable from your project - either in some central location you can set your header search path to find, or directly into your project tree itself! This is a particularly good option for other Open-Source projects that want to use Catch for their test suite. See [this blog entry for more on that](http://www.levelofindirection.com/journal/2011/5/27/unit-testing-in-c-and-objective-c-just-got-ridiculously-easi.html).
|
Catch2 is header only. All you need to do is drop the file somewhere reachable from your project - either in some central location you can set your header search path to find, or directly into your project tree itself! This is a particularly good option for other Open-Source projects that want to use Catch for their test suite. See [this blog entry for more on that](http://www.levelofindirection.com/journal/2011/5/27/unit-testing-in-c-and-objective-c-just-got-ridiculously-easi.html).
|
||||||
|
|
||||||
The rest of this tutorial will assume that the Catch single-include header (or the include folder) is available unqualified - but you may need to prefix it with a folder name if necessary.
|
The rest of this tutorial will assume that the Catch2 single-include header (or the include folder) is available unqualified - but you may need to prefix it with a folder name if necessary.
|
||||||
|
|
||||||
## Writing tests
|
## Writing tests
|
||||||
|
|
||||||
|
25
include/external/clara.hpp
vendored
25
include/external/clara.hpp
vendored
@@ -1,4 +1,4 @@
|
|||||||
// v1.0
|
// v1.0-develop.2
|
||||||
// See https://github.com/philsquared/Clara
|
// See https://github.com/philsquared/Clara
|
||||||
|
|
||||||
#ifndef CATCH_CLARA_HPP_INCLUDED
|
#ifndef CATCH_CLARA_HPP_INCLUDED
|
||||||
@@ -409,6 +409,14 @@ namespace detail {
|
|||||||
std::string token;
|
std::string token;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline auto isOptPrefix( char c ) -> bool {
|
||||||
|
return c == '-'
|
||||||
|
#ifdef CATCH_PLATFORM_WINDOWS
|
||||||
|
|| c == '/'
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
// Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
|
// Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
|
||||||
class TokenStream {
|
class TokenStream {
|
||||||
using Iterator = std::vector<std::string>::const_iterator;
|
using Iterator = std::vector<std::string>::const_iterator;
|
||||||
@@ -425,7 +433,7 @@ namespace detail {
|
|||||||
|
|
||||||
if( it != itEnd ) {
|
if( it != itEnd ) {
|
||||||
auto const &next = *it;
|
auto const &next = *it;
|
||||||
if( next[0] == '-' || next[0] == '/' ) {
|
if( isOptPrefix( next[0] ) ) {
|
||||||
auto delimiterPos = next.find_first_of( " :=" );
|
auto delimiterPos = next.find_first_of( " :=" );
|
||||||
if( delimiterPos != std::string::npos ) {
|
if( delimiterPos != std::string::npos ) {
|
||||||
m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
|
m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
|
||||||
@@ -915,9 +923,11 @@ namespace detail {
|
|||||||
};
|
};
|
||||||
|
|
||||||
inline auto normaliseOpt( std::string const &optName ) -> std::string {
|
inline auto normaliseOpt( std::string const &optName ) -> std::string {
|
||||||
|
#ifdef CATCH_PLATFORM_WINDOWS
|
||||||
if( optName[0] == '/' )
|
if( optName[0] == '/' )
|
||||||
return "-" + optName.substr( 1 );
|
return "-" + optName.substr( 1 );
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
return optName;
|
return optName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -958,11 +968,7 @@ namespace detail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto isMatch( std::string const &optToken ) const -> bool {
|
auto isMatch( std::string const &optToken ) const -> bool {
|
||||||
#ifdef CATCH_PLATFORM_WINDOWS
|
|
||||||
auto normalisedToken = normaliseOpt( optToken );
|
auto normalisedToken = normaliseOpt( optToken );
|
||||||
#else
|
|
||||||
auto const &normalisedToken = optToken;
|
|
||||||
#endif
|
|
||||||
for( auto const &name : m_optNames ) {
|
for( auto const &name : m_optNames ) {
|
||||||
if( normaliseOpt( name ) == normalisedToken )
|
if( normaliseOpt( name ) == normalisedToken )
|
||||||
return true;
|
return true;
|
||||||
@@ -1012,8 +1018,13 @@ namespace detail {
|
|||||||
for( auto const &name : m_optNames ) {
|
for( auto const &name : m_optNames ) {
|
||||||
if( name.empty() )
|
if( name.empty() )
|
||||||
return Result::logicError( "Option name cannot be empty" );
|
return Result::logicError( "Option name cannot be empty" );
|
||||||
|
#ifdef CATCH_PLATFORM_WINDOWS
|
||||||
if( name[0] != '-' && name[0] != '/' )
|
if( name[0] != '-' && name[0] != '/' )
|
||||||
return Result::logicError( "Option name must begin with '-' or '/'" );
|
return Result::logicError( "Option name must begin with '-' or '/'" );
|
||||||
|
#else
|
||||||
|
if( name[0] != '-' )
|
||||||
|
return Result::logicError( "Option name must begin with '-'" );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return ParserRefImpl::validate();
|
return ParserRefImpl::validate();
|
||||||
}
|
}
|
||||||
@@ -1103,7 +1114,7 @@ namespace detail {
|
|||||||
size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
|
size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
|
||||||
size_t optWidth = 0;
|
size_t optWidth = 0;
|
||||||
for( auto const &cols : rows )
|
for( auto const &cols : rows )
|
||||||
optWidth = std::max(optWidth, cols.left.size() + 2);
|
optWidth = (std::max)(optWidth, cols.left.size() + 2);
|
||||||
|
|
||||||
for( auto const &cols : rows ) {
|
for( auto const &cols : rows ) {
|
||||||
auto row =
|
auto row =
|
||||||
|
@@ -8,22 +8,26 @@
|
|||||||
|
|
||||||
#include "catch_approx.h"
|
#include "catch_approx.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Performs equivalent check of std::fabs(lhs - rhs) <= margin
|
||||||
|
// But without the subtraction to allow for INFINITY in comparison
|
||||||
|
bool marginComparison(double lhs, double rhs, double margin) {
|
||||||
|
return (lhs + margin >= rhs) && (rhs + margin >= lhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
namespace Detail {
|
namespace Detail {
|
||||||
|
|
||||||
double max(double lhs, double rhs) {
|
|
||||||
if (lhs < rhs) {
|
|
||||||
return rhs;
|
|
||||||
}
|
|
||||||
return lhs;
|
|
||||||
}
|
|
||||||
|
|
||||||
Approx::Approx ( double value )
|
Approx::Approx ( double value )
|
||||||
: m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
|
: m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
|
||||||
m_margin( 0.0 ),
|
m_margin( 0.0 ),
|
||||||
m_scale( 1.0 ),
|
m_scale( 0.0 ),
|
||||||
m_value( value )
|
m_value( value )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@@ -37,6 +41,12 @@ namespace Detail {
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Approx::equalityComparisonImpl(const double other) const {
|
||||||
|
// First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
|
||||||
|
// Thanks to Richard Harris for his help refining the scaled margin value
|
||||||
|
return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace Detail
|
} // end namespace Detail
|
||||||
|
|
||||||
std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
|
std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
|
||||||
|
@@ -8,18 +8,18 @@
|
|||||||
#ifndef TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
|
#ifndef TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
|
||||||
#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
|
#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include "catch_enforce.h"
|
||||||
#include "catch_tostring.h"
|
#include "catch_tostring.h"
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
namespace Detail {
|
namespace Detail {
|
||||||
|
|
||||||
double max(double lhs, double rhs);
|
|
||||||
|
|
||||||
class Approx {
|
class Approx {
|
||||||
|
private:
|
||||||
|
bool equalityComparisonImpl(double other) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Approx ( double value );
|
explicit Approx ( double value );
|
||||||
|
|
||||||
@@ -41,13 +41,8 @@ namespace Detail {
|
|||||||
|
|
||||||
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||||
friend bool operator == ( const T& lhs, Approx const& rhs ) {
|
friend bool operator == ( const T& lhs, Approx const& rhs ) {
|
||||||
// Thanks to Richard Harris for his help refining this formula
|
|
||||||
auto lhs_v = static_cast<double>(lhs);
|
auto lhs_v = static_cast<double>(lhs);
|
||||||
bool relativeOK = std::fabs(lhs_v - rhs.m_value) < rhs.m_epsilon * (rhs.m_scale + (max)(std::fabs(lhs_v), std::fabs(rhs.m_value)));
|
return rhs.equalityComparisonImpl(lhs_v);
|
||||||
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>
|
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||||
@@ -87,13 +82,21 @@ namespace Detail {
|
|||||||
|
|
||||||
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||||
Approx& epsilon( T const& newEpsilon ) {
|
Approx& epsilon( T const& newEpsilon ) {
|
||||||
m_epsilon = static_cast<double>(newEpsilon);
|
double epsilonAsDouble = static_cast<double>(newEpsilon);
|
||||||
|
CATCH_ENFORCE(epsilonAsDouble >= 0 && epsilonAsDouble <= 1.0,
|
||||||
|
"Invalid Approx::epsilon: " << epsilonAsDouble
|
||||||
|
<< ", Approx::epsilon has to be between 0 and 1");
|
||||||
|
m_epsilon = epsilonAsDouble;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||||
Approx& margin( T const& newMargin ) {
|
Approx& margin( T const& newMargin ) {
|
||||||
m_margin = static_cast<double>(newMargin);
|
double marginAsDouble = static_cast<double>(newMargin);
|
||||||
|
CATCH_ENFORCE(marginAsDouble >= 0,
|
||||||
|
"Invalid Approx::margin: " << marginAsDouble
|
||||||
|
<< ", Approx::Margin has to be non-negative.");
|
||||||
|
m_margin = marginAsDouble;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -54,8 +54,8 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string AssertionResult::getExpression() const {
|
std::string AssertionResult::getExpression() const {
|
||||||
if (isFalseTest(m_info.resultDisposition))
|
if( isFalseTest( m_info.resultDisposition ) )
|
||||||
return '!' + std::string(m_info.capturedExpression);
|
return "!(" + std::string(m_info.capturedExpression) + ")";
|
||||||
else
|
else
|
||||||
return m_info.capturedExpression;
|
return m_info.capturedExpression;
|
||||||
}
|
}
|
||||||
|
@@ -82,7 +82,7 @@
|
|||||||
|
|
||||||
// Universal Windows platform does not support SEH
|
// Universal Windows platform does not support SEH
|
||||||
// Or console colours (or console at all...)
|
// Or console colours (or console at all...)
|
||||||
# if (WINAPI_FAMILY == WINAPI_FAMILY_APP)
|
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
|
||||||
# define CATCH_CONFIG_COLOUR_NONE
|
# define CATCH_CONFIG_COLOUR_NONE
|
||||||
# else
|
# else
|
||||||
# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
|
# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
|
||||||
@@ -92,17 +92,16 @@
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// All supported compilers support COUNTER macro,
|
// Use of __COUNTER__ is suppressed during code analysis in
|
||||||
//but user still might want to turn it off
|
// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
|
||||||
#define CATCH_INTERNAL_CONFIG_COUNTER
|
// handled by it.
|
||||||
|
// Otherwise all supported compilers support COUNTER macro,
|
||||||
|
// but user still might want to turn it off
|
||||||
|
#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
|
||||||
|
#define CATCH_INTERNAL_CONFIG_COUNTER
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
|
||||||
// Now set the actual defines based on the above + anything the user has configured
|
|
||||||
|
|
||||||
// Use of __COUNTER__ is suppressed if __JETBRAINS_IDE__ is #defined (meaning we're being parsed by a JetBrains IDE for
|
|
||||||
// analytics) because, at time of writing, __COUNTER__ is not properly handled by it.
|
|
||||||
// This does not affect compilation
|
|
||||||
#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) && !defined(__JETBRAINS_IDE__)
|
|
||||||
# define CATCH_CONFIG_COUNTER
|
# define CATCH_CONFIG_COUNTER
|
||||||
#endif
|
#endif
|
||||||
#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH)
|
#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH)
|
||||||
|
@@ -77,7 +77,7 @@ namespace Catch {
|
|||||||
|
|
||||||
// Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
|
// Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
|
||||||
template<typename LhsT, typename RhsT>
|
template<typename LhsT, typename RhsT>
|
||||||
auto compareEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return lhs == rhs; };
|
auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return lhs == rhs; };
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
|
auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -106,36 +106,36 @@ namespace Catch {
|
|||||||
ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
|
ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
|
||||||
|
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
auto operator == ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
|
auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
||||||
return BinaryExpr<LhsT, RhsT&>( compareEqual( m_lhs, rhs ), m_lhs, "==", rhs );
|
return BinaryExpr<LhsT, RhsT const&>( compareEqual( m_lhs, rhs ), m_lhs, "==", rhs );
|
||||||
}
|
}
|
||||||
auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
|
auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
|
||||||
return BinaryExpr<LhsT, bool>( m_lhs == rhs, m_lhs, "==", rhs );
|
return BinaryExpr<LhsT, bool>( m_lhs == rhs, m_lhs, "==", rhs );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
auto operator != ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
|
auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
||||||
return BinaryExpr<LhsT, RhsT&>( compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs );
|
return BinaryExpr<LhsT, RhsT const&>( compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs );
|
||||||
}
|
}
|
||||||
auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
|
auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
|
||||||
return BinaryExpr<LhsT, bool>( m_lhs != rhs, m_lhs, "!=", rhs );
|
return BinaryExpr<LhsT, bool>( m_lhs != rhs, m_lhs, "!=", rhs );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
auto operator > ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
|
auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
||||||
return BinaryExpr<LhsT, RhsT&>( m_lhs > rhs, m_lhs, ">", rhs );
|
return BinaryExpr<LhsT, RhsT const&>( m_lhs > rhs, m_lhs, ">", rhs );
|
||||||
}
|
}
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
auto operator < ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
|
auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
||||||
return BinaryExpr<LhsT, RhsT&>( m_lhs < rhs, m_lhs, "<", rhs );
|
return BinaryExpr<LhsT, RhsT const&>( m_lhs < rhs, m_lhs, "<", rhs );
|
||||||
}
|
}
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
auto operator >= ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
|
auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
||||||
return BinaryExpr<LhsT, RhsT&>( m_lhs >= rhs, m_lhs, ">=", rhs );
|
return BinaryExpr<LhsT, RhsT const&>( m_lhs >= rhs, m_lhs, ">=", rhs );
|
||||||
}
|
}
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
auto operator <= ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
|
auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
||||||
return BinaryExpr<LhsT, RhsT&>( m_lhs <= rhs, m_lhs, "<=", rhs );
|
return BinaryExpr<LhsT, RhsT const&>( m_lhs <= rhs, m_lhs, "<=", rhs );
|
||||||
}
|
}
|
||||||
|
|
||||||
auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
|
auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
|
||||||
@@ -162,4 +162,8 @@ namespace Catch {
|
|||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_DECOMPOSER_H_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_DECOMPOSER_H_INCLUDED
|
||||||
|
@@ -25,7 +25,7 @@ namespace Catch {
|
|||||||
return std::rand() % n;
|
return std::rand() % n;
|
||||||
}
|
}
|
||||||
RandomNumberGenerator::result_type RandomNumberGenerator::operator()() const {
|
RandomNumberGenerator::result_type RandomNumberGenerator::operator()() const {
|
||||||
return std::rand() % max();
|
return std::rand() % (max)();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -20,10 +20,10 @@ namespace Catch {
|
|||||||
unsigned int rngSeed();
|
unsigned int rngSeed();
|
||||||
|
|
||||||
struct RandomNumberGenerator {
|
struct RandomNumberGenerator {
|
||||||
using result_type = std::ptrdiff_t;
|
using result_type = unsigned int;
|
||||||
|
|
||||||
static constexpr result_type min() { return 0; }
|
static constexpr result_type (min)() { return 0; }
|
||||||
static constexpr result_type max() { return 1000000; }
|
static constexpr result_type (max)() { return 1000000; }
|
||||||
|
|
||||||
result_type operator()( result_type n ) const;
|
result_type operator()( result_type n ) const;
|
||||||
result_type operator()() const;
|
result_type operator()() const;
|
||||||
|
@@ -116,8 +116,26 @@ namespace Catch {
|
|||||||
|
|
||||||
Session::Session() {
|
Session::Session() {
|
||||||
static bool alreadyInstantiated = false;
|
static bool alreadyInstantiated = false;
|
||||||
if( alreadyInstantiated )
|
if( alreadyInstantiated ) {
|
||||||
CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" );
|
try { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
|
||||||
|
catch(...) { getMutableRegistryHub().registerStartupException(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
|
||||||
|
if ( !exceptions.empty() ) {
|
||||||
|
m_startupExceptions = true;
|
||||||
|
Colour colourGuard( Colour::Red );
|
||||||
|
Catch::cerr() << "Errors occured during startup!" << '\n';
|
||||||
|
// iterate over all exceptions and notify user
|
||||||
|
for ( const auto& ex_ptr : exceptions ) {
|
||||||
|
try {
|
||||||
|
std::rethrow_exception(ex_ptr);
|
||||||
|
} catch ( std::exception const& ex ) {
|
||||||
|
Catch::cerr() << Column( ex.what() ).indent(2) << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
alreadyInstantiated = true;
|
alreadyInstantiated = true;
|
||||||
m_cli = makeCommandLineParser( m_configData );
|
m_cli = makeCommandLineParser( m_configData );
|
||||||
}
|
}
|
||||||
@@ -140,6 +158,9 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Session::applyCommandLine( int argc, char* argv[] ) {
|
int Session::applyCommandLine( int argc, char* argv[] ) {
|
||||||
|
if( m_startupExceptions )
|
||||||
|
return 1;
|
||||||
|
|
||||||
auto result = m_cli.parse( clara::Args( argc, argv ) );
|
auto result = m_cli.parse( clara::Args( argc, argv ) );
|
||||||
if( !result ) {
|
if( !result ) {
|
||||||
Catch::cerr()
|
Catch::cerr()
|
||||||
@@ -165,19 +186,8 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Session::run( int argc, char* argv[] ) {
|
int Session::run( int argc, char* argv[] ) {
|
||||||
const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
|
if( m_startupExceptions )
|
||||||
if ( !exceptions.empty() ) {
|
|
||||||
Catch::cerr() << "Errors occured during startup!" << '\n';
|
|
||||||
// iterate over all exceptions and notify user
|
|
||||||
for ( const auto& ex_ptr : exceptions ) {
|
|
||||||
try {
|
|
||||||
std::rethrow_exception(ex_ptr);
|
|
||||||
} catch ( std::exception const& ex ) {
|
|
||||||
Catch::cerr() << ex.what() << '\n';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
int returnCode = applyCommandLine( argc, argv );
|
int returnCode = applyCommandLine( argc, argv );
|
||||||
if( returnCode == 0 )
|
if( returnCode == 0 )
|
||||||
returnCode = run();
|
returnCode = run();
|
||||||
@@ -236,6 +246,9 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Session::runInternal() {
|
int Session::runInternal() {
|
||||||
|
if( m_startupExceptions )
|
||||||
|
return 1;
|
||||||
|
|
||||||
if( m_configData.showHelp || m_configData.libIdentify )
|
if( m_configData.showHelp || m_configData.libIdentify )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@@ -45,6 +45,7 @@ namespace Catch {
|
|||||||
clara::Parser m_cli;
|
clara::Parser m_cli;
|
||||||
ConfigData m_configData;
|
ConfigData m_configData;
|
||||||
std::shared_ptr<Config> m_config;
|
std::shared_ptr<Config> m_config;
|
||||||
|
bool m_startupExceptions = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
@@ -37,7 +37,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Version const& libraryVersion() {
|
Version const& libraryVersion() {
|
||||||
static Version version( 2, 0, 0, "develop", 5 );
|
static Version version( 2, 0, 1, "", 0 );
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -17,6 +17,14 @@
|
|||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
|
||||||
|
// Note that 4062 (not all labels are handled
|
||||||
|
// and default is missing) is enabled
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -639,3 +647,7 @@ namespace Catch {
|
|||||||
ConsoleReporter::~ConsoleReporter() {}
|
ConsoleReporter::~ConsoleReporter() {}
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
@@ -133,6 +133,7 @@ namespace Catch {
|
|||||||
<< "]\n";
|
<< "]\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stream.flush();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,6 +147,7 @@ namespace Catch {
|
|||||||
StreamingReporterBase::testCaseStarting( testInfo );
|
StreamingReporterBase::testCaseStarting( testInfo );
|
||||||
stream << "##teamcity[testStarted name='"
|
stream << "##teamcity[testStarted name='"
|
||||||
<< escape( testInfo.name ) << "']\n";
|
<< escape( testInfo.name ) << "']\n";
|
||||||
|
stream.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void testCaseEnded( TestCaseStats const& testCaseStats ) override {
|
void testCaseEnded( TestCaseStats const& testCaseStats ) override {
|
||||||
@@ -161,6 +163,7 @@ namespace Catch {
|
|||||||
stream << "##teamcity[testFinished name='"
|
stream << "##teamcity[testFinished name='"
|
||||||
<< escape( testCaseStats.testInfo.name ) << "' duration='"
|
<< escape( testCaseStats.testInfo.name ) << "' duration='"
|
||||||
<< m_testTimer.getElapsedMilliseconds() << "']\n";
|
<< m_testTimer.getElapsedMilliseconds() << "']\n";
|
||||||
|
stream.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -13,6 +13,13 @@
|
|||||||
#include "internal/catch_xmlwriter.h"
|
#include "internal/catch_xmlwriter.h"
|
||||||
#include "../internal/catch_timer.h"
|
#include "../internal/catch_timer.h"
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
|
||||||
|
// Note that 4062 (not all labels are handled
|
||||||
|
// and default is missing) is enabled
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
class XmlReporter : public StreamingReporterBase<XmlReporter> {
|
class XmlReporter : public StreamingReporterBase<XmlReporter> {
|
||||||
public:
|
public:
|
||||||
@@ -223,3 +230,7 @@ namespace Catch {
|
|||||||
CATCH_REGISTER_REPORTER( "xml", XmlReporter )
|
CATCH_REGISTER_REPORTER( "xml", XmlReporter )
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#include "catch.hpp"
|
#include "catch.hpp"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
TEST_CASE
|
TEST_CASE
|
||||||
(
|
(
|
||||||
@@ -24,6 +26,8 @@ TEST_CASE
|
|||||||
REQUIRE( Approx( d ) == 1.23 );
|
REQUIRE( Approx( d ) == 1.23 );
|
||||||
REQUIRE( Approx( d ) != 1.22 );
|
REQUIRE( Approx( d ) != 1.22 );
|
||||||
REQUIRE( Approx( d ) != 1.24 );
|
REQUIRE( Approx( d ) != 1.24 );
|
||||||
|
|
||||||
|
REQUIRE(INFINITY == Approx(INFINITY));
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -104,7 +108,7 @@ TEST_CASE
|
|||||||
|
|
||||||
REQUIRE( 1.0f == Approx( 1 ) );
|
REQUIRE( 1.0f == Approx( 1 ) );
|
||||||
REQUIRE( 0 == Approx( dZero) );
|
REQUIRE( 0 == Approx( dZero) );
|
||||||
REQUIRE( 0 == Approx( dSmall ).epsilon( 0.001 ) );
|
REQUIRE( 0 == Approx( dSmall ).margin( 0.001 ) );
|
||||||
REQUIRE( 1.234f == Approx( dMedium ) );
|
REQUIRE( 1.234f == Approx( dMedium ) );
|
||||||
REQUIRE( dMedium == Approx( 1.234f ) );
|
REQUIRE( dMedium == Approx( 1.234f ) );
|
||||||
}
|
}
|
||||||
@@ -118,7 +122,7 @@ TEST_CASE
|
|||||||
{
|
{
|
||||||
double d = 1.23;
|
double d = 1.23;
|
||||||
|
|
||||||
Approx approx = Approx::custom().epsilon( 0.005 );
|
Approx approx = Approx::custom().epsilon( 0.01 );
|
||||||
|
|
||||||
REQUIRE( d == approx( 1.23 ) );
|
REQUIRE( d == approx( 1.23 ) );
|
||||||
REQUIRE( d == approx( 1.22 ) );
|
REQUIRE( d == approx( 1.22 ) );
|
||||||
@@ -146,12 +150,47 @@ TEST_CASE( "Approximate PI", "[Approx][PI]" )
|
|||||||
TEST_CASE( "Absolute margin", "[Approx]" ) {
|
TEST_CASE( "Absolute margin", "[Approx]" ) {
|
||||||
REQUIRE( 104.0 != Approx(100.0) );
|
REQUIRE( 104.0 != Approx(100.0) );
|
||||||
REQUIRE( 104.0 == Approx(100.0).margin(5) );
|
REQUIRE( 104.0 == Approx(100.0).margin(5) );
|
||||||
|
REQUIRE( 104.0 == Approx(100.0).margin(4) );
|
||||||
REQUIRE( 104.0 != Approx(100.0).margin(3) );
|
REQUIRE( 104.0 != Approx(100.0).margin(3) );
|
||||||
REQUIRE( 100.3 != Approx(100.0) );
|
REQUIRE( 100.3 != Approx(100.0) );
|
||||||
REQUIRE( 100.3 == Approx(100.0).margin(0.5) );
|
REQUIRE( 100.3 == Approx(100.0).margin(0.5) );
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
TEST_CASE("Approx with exactly-representable margin", "[Approx]") {
|
||||||
|
CHECK( 0.25f == Approx(0.0f).margin(0.25f) );
|
||||||
|
|
||||||
|
CHECK( 0.0f == Approx(0.25f).margin(0.25f) );
|
||||||
|
CHECK( 0.5f == Approx(0.25f).margin(0.25f) );
|
||||||
|
|
||||||
|
CHECK( 245.0f == Approx(245.25f).margin(0.25f) );
|
||||||
|
CHECK( 245.5f == Approx(245.25f).margin(0.25f) );
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Approx setters validate their arguments", "[Approx]") {
|
||||||
|
REQUIRE_NOTHROW(Approx(0).margin(0));
|
||||||
|
REQUIRE_NOTHROW(Approx(0).margin(1234656));
|
||||||
|
|
||||||
|
REQUIRE_THROWS_AS(Approx(0).margin(-2), std::domain_error);
|
||||||
|
|
||||||
|
REQUIRE_NOTHROW(Approx(0).epsilon(0));
|
||||||
|
REQUIRE_NOTHROW(Approx(0).epsilon(1));
|
||||||
|
|
||||||
|
REQUIRE_THROWS_AS(Approx(0).epsilon(-0.001), std::domain_error);
|
||||||
|
REQUIRE_THROWS_AS(Approx(0).epsilon(1.0001), std::domain_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Default scale is invisible to comparison", "[Approx]") {
|
||||||
|
REQUIRE(101.000001 != Approx(100).epsilon(0.01));
|
||||||
|
REQUIRE(std::pow(10, -5) != Approx(std::pow(10, -7)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Epsilon only applies to Approx's value", "[Approx]") {
|
||||||
|
REQUIRE(101.01 != Approx(100).epsilon(0.01));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Assorted miscellaneous tests", "[Approx]") {
|
||||||
|
REQUIRE(INFINITY == Approx(INFINITY));
|
||||||
|
}
|
||||||
|
|
||||||
class StrongDoubleTypedef
|
class StrongDoubleTypedef
|
||||||
{
|
{
|
||||||
@@ -187,5 +226,3 @@ TEST_CASE( "Comparison with explicitly convertible types", "[Approx]" )
|
|||||||
REQUIRE(Approx(11.0) >= td);
|
REQUIRE(Approx(11.0) >= td);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
@@ -58,6 +58,8 @@ with expansion:
|
|||||||
|
|
||||||
ConditionTests.cpp:<line number>: FAILED:
|
ConditionTests.cpp:<line number>: FAILED:
|
||||||
CHECK_FALSE( true )
|
CHECK_FALSE( true )
|
||||||
|
with expansion:
|
||||||
|
!true
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>: FAILED:
|
ConditionTests.cpp:<line number>: FAILED:
|
||||||
CHECK( !trueValue )
|
CHECK( !trueValue )
|
||||||
@@ -76,8 +78,6 @@ with expansion:
|
|||||||
|
|
||||||
ConditionTests.cpp:<line number>: FAILED:
|
ConditionTests.cpp:<line number>: FAILED:
|
||||||
CHECK_FALSE( 1 == 1 )
|
CHECK_FALSE( 1 == 1 )
|
||||||
with expansion:
|
|
||||||
!(1 == 1)
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
A METHOD_AS_TEST_CASE based test run that fails
|
A METHOD_AS_TEST_CASE based test run that fails
|
||||||
@@ -1003,6 +1003,6 @@ with expansion:
|
|||||||
"{?}" == "1"
|
"{?}" == "1"
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
test cases: 179 | 128 passed | 47 failed | 4 failed as expected
|
test cases: 185 | 134 passed | 47 failed | 4 failed as expected
|
||||||
assertions: 884 | 767 passed | 96 failed | 21 failed as expected
|
assertions: 904 | 787 passed | 96 failed | 21 failed as expected
|
||||||
|
|
||||||
|
@@ -235,6 +235,8 @@ with expansion:
|
|||||||
|
|
||||||
ConditionTests.cpp:<line number>: FAILED:
|
ConditionTests.cpp:<line number>: FAILED:
|
||||||
CHECK_FALSE( true )
|
CHECK_FALSE( true )
|
||||||
|
with expansion:
|
||||||
|
!true
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>: FAILED:
|
ConditionTests.cpp:<line number>: FAILED:
|
||||||
CHECK( !trueValue )
|
CHECK( !trueValue )
|
||||||
@@ -253,8 +255,6 @@ with expansion:
|
|||||||
|
|
||||||
ConditionTests.cpp:<line number>: FAILED:
|
ConditionTests.cpp:<line number>: FAILED:
|
||||||
CHECK_FALSE( 1 == 1 )
|
CHECK_FALSE( 1 == 1 )
|
||||||
with expansion:
|
|
||||||
!(1 == 1)
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
'Not' checks that should succeed
|
'Not' checks that should succeed
|
||||||
@@ -279,6 +279,8 @@ with expansion:
|
|||||||
ConditionTests.cpp:<line number>:
|
ConditionTests.cpp:<line number>:
|
||||||
PASSED:
|
PASSED:
|
||||||
REQUIRE_FALSE( false )
|
REQUIRE_FALSE( false )
|
||||||
|
with expansion:
|
||||||
|
!false
|
||||||
|
|
||||||
ConditionTests.cpp:<line number>:
|
ConditionTests.cpp:<line number>:
|
||||||
PASSED:
|
PASSED:
|
||||||
@@ -301,8 +303,6 @@ with expansion:
|
|||||||
ConditionTests.cpp:<line number>:
|
ConditionTests.cpp:<line number>:
|
||||||
PASSED:
|
PASSED:
|
||||||
REQUIRE_FALSE( 1 == 2 )
|
REQUIRE_FALSE( 1 == 2 )
|
||||||
with expansion:
|
|
||||||
!(1 == 2)
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
(unimplemented) static bools can be evaluated
|
(unimplemented) static bools can be evaluated
|
||||||
@@ -490,6 +490,12 @@ PASSED:
|
|||||||
with expansion:
|
with expansion:
|
||||||
104.0 == Approx( 100.0 )
|
104.0 == Approx( 100.0 )
|
||||||
|
|
||||||
|
ApproxTests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( 104.0 == Approx(100.0).margin(4) )
|
||||||
|
with expansion:
|
||||||
|
104.0 == Approx( 100.0 )
|
||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
ApproxTests.cpp:<line number>:
|
||||||
PASSED:
|
PASSED:
|
||||||
REQUIRE( 104.0 != Approx(100.0).margin(3) )
|
REQUIRE( 104.0 != Approx(100.0).margin(3) )
|
||||||
@@ -552,6 +558,76 @@ PASSED:
|
|||||||
with message:
|
with message:
|
||||||
anonymous test case
|
anonymous test case
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Approx setters validate their arguments
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
ApproxTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
ApproxTests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE_NOTHROW( Approx(0).margin(0) )
|
||||||
|
|
||||||
|
ApproxTests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE_NOTHROW( Approx(0).margin(1234656) )
|
||||||
|
|
||||||
|
ApproxTests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE_THROWS_AS( Approx(0).margin(-2), std::domain_error )
|
||||||
|
|
||||||
|
ApproxTests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE_NOTHROW( Approx(0).epsilon(0) )
|
||||||
|
|
||||||
|
ApproxTests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE_NOTHROW( Approx(0).epsilon(1) )
|
||||||
|
|
||||||
|
ApproxTests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE_THROWS_AS( Approx(0).epsilon(-0.001), std::domain_error )
|
||||||
|
|
||||||
|
ApproxTests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE_THROWS_AS( Approx(0).epsilon(1.0001), std::domain_error )
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Approx with exactly-representable margin
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
ApproxTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
ApproxTests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
CHECK( 0.25f == Approx(0.0f).margin(0.25f) )
|
||||||
|
with expansion:
|
||||||
|
0.25f == Approx( 0.0 )
|
||||||
|
|
||||||
|
ApproxTests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
CHECK( 0.0f == Approx(0.25f).margin(0.25f) )
|
||||||
|
with expansion:
|
||||||
|
0.0f == Approx( 0.25 )
|
||||||
|
|
||||||
|
ApproxTests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
CHECK( 0.5f == Approx(0.25f).margin(0.25f) )
|
||||||
|
with expansion:
|
||||||
|
0.5f == Approx( 0.25 )
|
||||||
|
|
||||||
|
ApproxTests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
CHECK( 245.0f == Approx(245.25f).margin(0.25f) )
|
||||||
|
with expansion:
|
||||||
|
245.0f == Approx( 245.25 )
|
||||||
|
|
||||||
|
ApproxTests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
CHECK( 245.5f == Approx(245.25f).margin(0.25f) )
|
||||||
|
with expansion:
|
||||||
|
245.5f == Approx( 245.25 )
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Approximate PI
|
Approximate PI
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -644,7 +720,7 @@ with expansion:
|
|||||||
|
|
||||||
ApproxTests.cpp:<line number>:
|
ApproxTests.cpp:<line number>:
|
||||||
PASSED:
|
PASSED:
|
||||||
REQUIRE( 0 == Approx( dSmall ).epsilon( 0.001 ) )
|
REQUIRE( 0 == Approx( dSmall ).margin( 0.001 ) )
|
||||||
with expansion:
|
with expansion:
|
||||||
0 == Approx( 0.00001 )
|
0 == Approx( 0.00001 )
|
||||||
|
|
||||||
@@ -738,6 +814,36 @@ PASSED:
|
|||||||
with expansion:
|
with expansion:
|
||||||
true
|
true
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Assorted miscellaneous tests
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
ApproxTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
ApproxTests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( INFINITY == Approx(INFINITY) )
|
||||||
|
with expansion:
|
||||||
|
inff == Approx( inf )
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Bitfields can be captured (#1027)
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
TrickyTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
TrickyTests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( y.v == 0 )
|
||||||
|
with expansion:
|
||||||
|
0 == 0
|
||||||
|
|
||||||
|
TrickyTests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( 0 == y.v )
|
||||||
|
with expansion:
|
||||||
|
0 == 0
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Capture and info messages
|
Capture and info messages
|
||||||
Capture should stringify like assertions
|
Capture should stringify like assertions
|
||||||
@@ -1215,6 +1321,24 @@ ExceptionTests.cpp:<line number>: FAILED:
|
|||||||
due to unexpected exception with message:
|
due to unexpected exception with message:
|
||||||
custom std exception
|
custom std exception
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Default scale is invisible to comparison
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
ApproxTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
ApproxTests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( 101.000001 != Approx(100).epsilon(0.01) )
|
||||||
|
with expansion:
|
||||||
|
101.000001 != Approx( 100.0 )
|
||||||
|
|
||||||
|
ApproxTests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( std::pow(10, -5) != Approx(std::pow(10, -7)) )
|
||||||
|
with expansion:
|
||||||
|
0.00001 != Approx( 0.0000001 )
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
EndsWith string matcher
|
EndsWith string matcher
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -1226,6 +1350,18 @@ MatchersTests.cpp:<line number>: FAILED:
|
|||||||
with expansion:
|
with expansion:
|
||||||
"this string contains 'abc' as a substring" ends with: "this"
|
"this string contains 'abc' as a substring" ends with: "this"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Epsilon only applies to Approx's value
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
ApproxTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
ApproxTests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( 101.01 != Approx(100).epsilon(0.01) )
|
||||||
|
with expansion:
|
||||||
|
101.01 != Approx( 100.0 )
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Equality checks that should fail
|
Equality checks that should fail
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -4183,6 +4319,12 @@ PASSED:
|
|||||||
with expansion:
|
with expansion:
|
||||||
Approx( 1.23 ) != 1.24
|
Approx( 1.23 ) != 1.24
|
||||||
|
|
||||||
|
ApproxTests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
REQUIRE( INFINITY == Approx(INFINITY) )
|
||||||
|
with expansion:
|
||||||
|
inff == Approx( inf )
|
||||||
|
|
||||||
Message from section one
|
Message from section one
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Standard output from all sections is reported
|
Standard output from all sections is reported
|
||||||
@@ -7490,6 +7632,6 @@ MiscTests.cpp:<line number>:
|
|||||||
PASSED:
|
PASSED:
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
test cases: 179 | 126 passed | 49 failed | 4 failed as expected
|
test cases: 185 | 132 passed | 49 failed | 4 failed as expected
|
||||||
assertions: 883 | 763 passed | 99 failed | 21 failed as expected
|
assertions: 903 | 783 passed | 99 failed | 21 failed as expected
|
||||||
|
|
||||||
|
@@ -235,6 +235,8 @@ with expansion:
|
|||||||
|
|
||||||
ConditionTests.cpp:<line number>: FAILED:
|
ConditionTests.cpp:<line number>: FAILED:
|
||||||
CHECK_FALSE( true )
|
CHECK_FALSE( true )
|
||||||
|
with expansion:
|
||||||
|
!true
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
test cases: 9 | 6 passed | 1 failed | 2 failed as expected
|
test cases: 9 | 6 passed | 1 failed | 2 failed as expected
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<testsuitesloose text artifact
|
<testsuitesloose text artifact
|
||||||
>
|
>
|
||||||
<testsuite name="<exe-name>" errors="15" failures="85" tests="884" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
<testsuite name="<exe-name>" errors="15" failures="85" tests="904" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||||
<testcase classname="<exe-name>.global" name="# A test name that starts with a #" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="# A test name that starts with a #" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="#1005: Comparing pointer to int and long (NULL can be either on various systems)" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="#1005: Comparing pointer to int and long (NULL can be either on various systems)" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="#748 - captures with unexpected exceptions/outside assertions" time="{duration}">
|
<testcase classname="<exe-name>.global" name="#748 - captures with unexpected exceptions/outside assertions" time="{duration}">
|
||||||
@@ -100,6 +100,8 @@ ExceptionTests.cpp:<line number>
|
|||||||
</error>
|
</error>
|
||||||
</testcase>
|
</testcase>
|
||||||
<testcase classname="<exe-name>.global" name="Anonymous test case 1" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="Anonymous test case 1" time="{duration}"/>
|
||||||
|
<testcase classname="<exe-name>.global" name="Approx setters validate their arguments" time="{duration}"/>
|
||||||
|
<testcase classname="<exe-name>.global" name="Approx with exactly-representable margin" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="Approximate PI" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="Approximate PI" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="Approximate comparisons with different epsilons" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="Approximate comparisons with different epsilons" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="Approximate comparisons with floats" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="Approximate comparisons with floats" time="{duration}"/>
|
||||||
@@ -109,6 +111,8 @@ ExceptionTests.cpp:<line number>
|
|||||||
<testcase classname="<exe-name>.global" name="Assertions then sections/A section" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="Assertions then sections/A section" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="Assertions then sections/A section/Another section" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="Assertions then sections/A section/Another section" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="Assertions then sections/A section/Another other section" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="Assertions then sections/A section/Another other section" time="{duration}"/>
|
||||||
|
<testcase classname="<exe-name>.global" name="Assorted miscellaneous tests" time="{duration}"/>
|
||||||
|
<testcase classname="<exe-name>.global" name="Bitfields can be captured (#1027)" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="Capture and info messages/Capture should stringify like assertions" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="Capture and info messages/Capture should stringify like assertions" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="Capture and info messages/Info should NOT stringify the way assertions do" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="Capture and info messages/Info should NOT stringify the way assertions do" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="Character pretty printing/Specifically escaped" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="Character pretty printing/Specifically escaped" time="{duration}"/>
|
||||||
@@ -143,11 +147,13 @@ custom std exception
|
|||||||
ExceptionTests.cpp:<line number>
|
ExceptionTests.cpp:<line number>
|
||||||
</error>
|
</error>
|
||||||
</testcase>
|
</testcase>
|
||||||
|
<testcase classname="<exe-name>.global" name="Default scale is invisible to comparison" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="EndsWith string matcher" time="{duration}">
|
<testcase classname="<exe-name>.global" name="EndsWith string matcher" time="{duration}">
|
||||||
<failure message=""this string contains 'abc' as a substring" ends with: "this"" type="CHECK_THAT">
|
<failure message=""this string contains 'abc' as a substring" ends with: "this"" type="CHECK_THAT">
|
||||||
MatchersTests.cpp:<line number>
|
MatchersTests.cpp:<line number>
|
||||||
</failure>
|
</failure>
|
||||||
</testcase>
|
</testcase>
|
||||||
|
<testcase classname="<exe-name>.global" name="Epsilon only applies to Approx's value" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="Equality checks that should fail" time="{duration}">
|
<testcase classname="<exe-name>.global" name="Equality checks that should fail" time="{duration}">
|
||||||
<failure message="7 == 6" type="CHECK">
|
<failure message="7 == 6" type="CHECK">
|
||||||
ConditionTests.cpp:<line number>
|
ConditionTests.cpp:<line number>
|
||||||
|
@@ -214,7 +214,7 @@
|
|||||||
</Expression>
|
</Expression>
|
||||||
<Expression success="false" type="CHECK_FALSE" filename="projects/<exe-name>/ConditionTests.cpp" >
|
<Expression success="false" type="CHECK_FALSE" filename="projects/<exe-name>/ConditionTests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
!true
|
!(true)
|
||||||
</Original>
|
</Original>
|
||||||
<Expanded>
|
<Expanded>
|
||||||
!true
|
!true
|
||||||
@@ -230,7 +230,7 @@
|
|||||||
</Expression>
|
</Expression>
|
||||||
<Expression success="false" type="CHECK_FALSE" filename="projects/<exe-name>/ConditionTests.cpp" >
|
<Expression success="false" type="CHECK_FALSE" filename="projects/<exe-name>/ConditionTests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
!trueValue
|
!(trueValue)
|
||||||
</Original>
|
</Original>
|
||||||
<Expanded>
|
<Expanded>
|
||||||
!true
|
!true
|
||||||
@@ -246,7 +246,7 @@
|
|||||||
</Expression>
|
</Expression>
|
||||||
<Expression success="false" type="CHECK_FALSE" filename="projects/<exe-name>/ConditionTests.cpp" >
|
<Expression success="false" type="CHECK_FALSE" filename="projects/<exe-name>/ConditionTests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
!1 == 1
|
!(1 == 1)
|
||||||
</Original>
|
</Original>
|
||||||
<Expanded>
|
<Expanded>
|
||||||
!(1 == 1)
|
!(1 == 1)
|
||||||
@@ -281,7 +281,7 @@
|
|||||||
</Expression>
|
</Expression>
|
||||||
<Expression success="true" type="REQUIRE_FALSE" filename="projects/<exe-name>/ConditionTests.cpp" >
|
<Expression success="true" type="REQUIRE_FALSE" filename="projects/<exe-name>/ConditionTests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
!false
|
!(false)
|
||||||
</Original>
|
</Original>
|
||||||
<Expanded>
|
<Expanded>
|
||||||
!false
|
!false
|
||||||
@@ -297,7 +297,7 @@
|
|||||||
</Expression>
|
</Expression>
|
||||||
<Expression success="true" type="REQUIRE_FALSE" filename="projects/<exe-name>/ConditionTests.cpp" >
|
<Expression success="true" type="REQUIRE_FALSE" filename="projects/<exe-name>/ConditionTests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
!falseValue
|
!(falseValue)
|
||||||
</Original>
|
</Original>
|
||||||
<Expanded>
|
<Expanded>
|
||||||
!false
|
!false
|
||||||
@@ -313,7 +313,7 @@
|
|||||||
</Expression>
|
</Expression>
|
||||||
<Expression success="true" type="REQUIRE_FALSE" filename="projects/<exe-name>/ConditionTests.cpp" >
|
<Expression success="true" type="REQUIRE_FALSE" filename="projects/<exe-name>/ConditionTests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
!1 == 2
|
!(1 == 2)
|
||||||
</Original>
|
</Original>
|
||||||
<Expanded>
|
<Expanded>
|
||||||
!(1 == 2)
|
!(1 == 2)
|
||||||
@@ -393,7 +393,7 @@
|
|||||||
</Expression>
|
</Expression>
|
||||||
<Expression success="true" type="REQUIRE_FALSE" filename="projects/<exe-name>/TrickyTests.cpp" >
|
<Expression success="true" type="REQUIRE_FALSE" filename="projects/<exe-name>/TrickyTests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
!is_true<false>::value
|
!(is_true<false>::value)
|
||||||
</Original>
|
</Original>
|
||||||
<Expanded>
|
<Expanded>
|
||||||
!false
|
!false
|
||||||
@@ -495,6 +495,14 @@
|
|||||||
104.0 == Approx( 100.0 )
|
104.0 == Approx( 100.0 )
|
||||||
</Expanded>
|
</Expanded>
|
||||||
</Expression>
|
</Expression>
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
|
<Original>
|
||||||
|
104.0 == Approx(100.0).margin(4)
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
104.0 == Approx( 100.0 )
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ApproxTests.cpp" >
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
104.0 != Approx(100.0).margin(3)
|
104.0 != Approx(100.0).margin(3)
|
||||||
@@ -568,6 +576,108 @@
|
|||||||
<TestCase name="Anonymous test case 1" filename="projects/<exe-name>/VariadicMacrosTests.cpp" >
|
<TestCase name="Anonymous test case 1" filename="projects/<exe-name>/VariadicMacrosTests.cpp" >
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
|
<TestCase name="Approx setters validate their arguments" tags="[Approx]" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
|
<Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
|
<Original>
|
||||||
|
Approx(0).margin(0)
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
Approx(0).margin(0)
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
|
<Original>
|
||||||
|
Approx(0).margin(1234656)
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
Approx(0).margin(1234656)
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
|
<Original>
|
||||||
|
Approx(0).margin(-2), std::domain_error
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
Approx(0).margin(-2), std::domain_error
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
|
<Original>
|
||||||
|
Approx(0).epsilon(0)
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
Approx(0).epsilon(0)
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
|
<Original>
|
||||||
|
Approx(0).epsilon(1)
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
Approx(0).epsilon(1)
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
|
<Original>
|
||||||
|
Approx(0).epsilon(-0.001), std::domain_error
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
Approx(0).epsilon(-0.001), std::domain_error
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
|
<Original>
|
||||||
|
Approx(0).epsilon(1.0001), std::domain_error
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
Approx(0).epsilon(1.0001), std::domain_error
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<OverallResult success="true"/>
|
||||||
|
</TestCase>
|
||||||
|
<TestCase name="Approx with exactly-representable margin" tags="[Approx]" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
|
<Expression success="true" type="CHECK" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
|
<Original>
|
||||||
|
0.25f == Approx(0.0f).margin(0.25f)
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
0.25f == Approx( 0.0 )
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="CHECK" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
|
<Original>
|
||||||
|
0.0f == Approx(0.25f).margin(0.25f)
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
0.0f == Approx( 0.25 )
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="CHECK" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
|
<Original>
|
||||||
|
0.5f == Approx(0.25f).margin(0.25f)
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
0.5f == Approx( 0.25 )
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="CHECK" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
|
<Original>
|
||||||
|
245.0f == Approx(245.25f).margin(0.25f)
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
245.0f == Approx( 245.25 )
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="CHECK" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
|
<Original>
|
||||||
|
245.5f == Approx(245.25f).margin(0.25f)
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
245.5f == Approx( 245.25 )
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<OverallResult success="true"/>
|
||||||
|
</TestCase>
|
||||||
<TestCase name="Approximate PI" tags="[Approx][PI]" filename="projects/<exe-name>/ApproxTests.cpp" >
|
<TestCase name="Approximate PI" tags="[Approx][PI]" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ApproxTests.cpp" >
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
@@ -663,7 +773,7 @@
|
|||||||
</Expression>
|
</Expression>
|
||||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ApproxTests.cpp" >
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
0 == Approx( dSmall ).epsilon( 0.001 )
|
0 == Approx( dSmall ).margin( 0.001 )
|
||||||
</Original>
|
</Original>
|
||||||
<Expanded>
|
<Expanded>
|
||||||
0 == Approx( 0.00001 )
|
0 == Approx( 0.00001 )
|
||||||
@@ -750,6 +860,36 @@
|
|||||||
</Section>
|
</Section>
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
|
<TestCase name="Assorted miscellaneous tests" tags="[Approx]" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
|
<Original>
|
||||||
|
INFINITY == Approx(INFINITY)
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
inff == Approx( inf )
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<OverallResult success="true"/>
|
||||||
|
</TestCase>
|
||||||
|
<TestCase name="Bitfields can be captured (#1027)" filename="projects/<exe-name>/TrickyTests.cpp" >
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/TrickyTests.cpp" >
|
||||||
|
<Original>
|
||||||
|
y.v == 0
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
0 == 0
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/TrickyTests.cpp" >
|
||||||
|
<Original>
|
||||||
|
0 == y.v
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
0 == 0
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<OverallResult success="true"/>
|
||||||
|
</TestCase>
|
||||||
<TestCase name="Capture and info messages" filename="projects/<exe-name>/ToStringGeneralTests.cpp" >
|
<TestCase name="Capture and info messages" filename="projects/<exe-name>/ToStringGeneralTests.cpp" >
|
||||||
<Section name="Capture should stringify like assertions" filename="projects/<exe-name>/ToStringGeneralTests.cpp" >
|
<Section name="Capture should stringify like assertions" filename="projects/<exe-name>/ToStringGeneralTests.cpp" >
|
||||||
<Info>
|
<Info>
|
||||||
@@ -956,7 +1096,7 @@
|
|||||||
</Expression>
|
</Expression>
|
||||||
<Expression success="true" type="REQUIRE_FALSE" filename="projects/<exe-name>/TrickyTests.cpp" >
|
<Expression success="true" type="REQUIRE_FALSE" filename="projects/<exe-name>/TrickyTests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
!std::vector<int>{1, 2} == std::vector<int>{1, 2, 3}
|
!(std::vector<int>{1, 2} == std::vector<int>{1, 2, 3})
|
||||||
</Original>
|
</Original>
|
||||||
<Expanded>
|
<Expanded>
|
||||||
!({ 1, 2 } == { 1, 2, 3 })
|
!({ 1, 2 } == { 1, 2, 3 })
|
||||||
@@ -964,7 +1104,7 @@
|
|||||||
</Expression>
|
</Expression>
|
||||||
<Expression success="true" type="CHECK_FALSE" filename="projects/<exe-name>/TrickyTests.cpp" >
|
<Expression success="true" type="CHECK_FALSE" filename="projects/<exe-name>/TrickyTests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
!std::vector<int>{1, 2} == std::vector<int>{1, 2, 3}
|
!(std::vector<int>{1, 2} == std::vector<int>{1, 2, 3})
|
||||||
</Original>
|
</Original>
|
||||||
<Expanded>
|
<Expanded>
|
||||||
!({ 1, 2 } == { 1, 2, 3 })
|
!({ 1, 2 } == { 1, 2, 3 })
|
||||||
@@ -1336,6 +1476,25 @@
|
|||||||
</Exception>
|
</Exception>
|
||||||
<OverallResult success="false"/>
|
<OverallResult success="false"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
|
<TestCase name="Default scale is invisible to comparison" tags="[Approx]" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
|
<Original>
|
||||||
|
101.000001 != Approx(100).epsilon(0.01)
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
101.000001 != Approx( 100.0 )
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
|
<Original>
|
||||||
|
std::pow(10, -5) != Approx(std::pow(10, -7))
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
0.00001 != Approx( 0.0000001 )
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<OverallResult success="true"/>
|
||||||
|
</TestCase>
|
||||||
<TestCase name="EndsWith string matcher" tags="[.][failing][matchers]" filename="projects/<exe-name>/MatchersTests.cpp" >
|
<TestCase name="EndsWith string matcher" tags="[.][failing][matchers]" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||||
<Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
<Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
@@ -1347,6 +1506,17 @@
|
|||||||
</Expression>
|
</Expression>
|
||||||
<OverallResult success="false"/>
|
<OverallResult success="false"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
|
<TestCase name="Epsilon only applies to Approx's value" tags="[Approx]" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
|
<Original>
|
||||||
|
101.01 != Approx(100).epsilon(0.01)
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
101.01 != Approx( 100.0 )
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<OverallResult success="true"/>
|
||||||
|
</TestCase>
|
||||||
<TestCase name="Equality checks that should fail" tags="[!mayfail][.][failing]" filename="projects/<exe-name>/ConditionTests.cpp" >
|
<TestCase name="Equality checks that should fail" tags="[!mayfail][.][failing]" filename="projects/<exe-name>/ConditionTests.cpp" >
|
||||||
<Expression success="false" type="CHECK" filename="projects/<exe-name>/ConditionTests.cpp" >
|
<Expression success="false" type="CHECK" filename="projects/<exe-name>/ConditionTests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
@@ -1794,7 +1964,7 @@
|
|||||||
</Expression>
|
</Expression>
|
||||||
<Expression success="true" type="REQUIRE_FALSE" filename="projects/<exe-name>/ApproxTests.cpp" >
|
<Expression success="true" type="REQUIRE_FALSE" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
!d >= Approx( 1.24 )
|
!(d >= Approx( 1.24 ))
|
||||||
</Original>
|
</Original>
|
||||||
<Expanded>
|
<Expanded>
|
||||||
!(1.23 >= Approx( 1.24 ))
|
!(1.23 >= Approx( 1.24 ))
|
||||||
@@ -2211,7 +2381,7 @@
|
|||||||
</Expression>
|
</Expression>
|
||||||
<Expression success="true" type="REQUIRE_FALSE" filename="projects/<exe-name>/ApproxTests.cpp" >
|
<Expression success="true" type="REQUIRE_FALSE" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
!d <= Approx( 1.22 )
|
!(d <= Approx( 1.22 ))
|
||||||
</Original>
|
</Original>
|
||||||
<Expanded>
|
<Expanded>
|
||||||
!(1.23 <= Approx( 1.22 ))
|
!(1.23 <= Approx( 1.22 ))
|
||||||
@@ -2354,7 +2524,7 @@
|
|||||||
</Expression>
|
</Expression>
|
||||||
<Expression success="true" type="CHECK_FALSE" filename="projects/<exe-name>/TrickyTests.cpp" >
|
<Expression success="true" type="CHECK_FALSE" filename="projects/<exe-name>/TrickyTests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
!False
|
!(False)
|
||||||
</Original>
|
</Original>
|
||||||
<Expanded>
|
<Expanded>
|
||||||
!{?}
|
!{?}
|
||||||
@@ -4776,6 +4946,14 @@ A string sent directly to stderr
|
|||||||
Approx( 1.23 ) != 1.24
|
Approx( 1.23 ) != 1.24
|
||||||
</Expanded>
|
</Expanded>
|
||||||
</Expression>
|
</Expression>
|
||||||
|
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||||
|
<Original>
|
||||||
|
INFINITY == Approx(INFINITY)
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
inff == Approx( inf )
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="Standard output from all sections is reported" tags="[.][messages]" filename="projects/<exe-name>/MessageTests.cpp" >
|
<TestCase name="Standard output from all sections is reported" tags="[.][messages]" filename="projects/<exe-name>/MessageTests.cpp" >
|
||||||
@@ -7614,7 +7792,7 @@ loose text artifact
|
|||||||
<Section name="replace no chars" filename="projects/<exe-name>/TestMain.cpp" >
|
<Section name="replace no chars" filename="projects/<exe-name>/TestMain.cpp" >
|
||||||
<Expression success="true" type="CHECK_FALSE" filename="projects/<exe-name>/TestMain.cpp" >
|
<Expression success="true" type="CHECK_FALSE" filename="projects/<exe-name>/TestMain.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
!Catch::replaceInPlace( letters, "x", "z" )
|
!(Catch::replaceInPlace( letters, "x", "z" ))
|
||||||
</Original>
|
</Original>
|
||||||
<Expanded>
|
<Expanded>
|
||||||
!false
|
!false
|
||||||
@@ -8268,7 +8446,7 @@ loose text artifact
|
|||||||
</Section>
|
</Section>
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<OverallResults successes="763" failures="100" expectedFailures="21"/>
|
<OverallResults successes="783" failures="100" expectedFailures="21"/>
|
||||||
</Group>
|
</Group>
|
||||||
<OverallResults successes="763" failures="99" expectedFailures="21"/>
|
<OverallResults successes="783" failures="99" expectedFailures="21"/>
|
||||||
</Catch>
|
</Catch>
|
||||||
|
@@ -168,7 +168,7 @@ namespace ObjectWithConversions
|
|||||||
{
|
{
|
||||||
struct Object
|
struct Object
|
||||||
{
|
{
|
||||||
operator unsigned int() {return 0xc0000000;}
|
operator unsigned int() const {return 0xc0000000;}
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -436,3 +436,12 @@ TEST_CASE("#925: comparing function pointer to function address failed to compil
|
|||||||
TestClass test;
|
TestClass test;
|
||||||
REQUIRE(utility::synchronizing_callback != test.testMethod_uponComplete_arg);
|
REQUIRE(utility::synchronizing_callback != test.testMethod_uponComplete_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE( "Bitfields can be captured (#1027)" ) {
|
||||||
|
struct Y {
|
||||||
|
uint32_t v : 1;
|
||||||
|
};
|
||||||
|
Y y{ 0 };
|
||||||
|
REQUIRE( y.v == 0 );
|
||||||
|
REQUIRE( 0 == y.v );
|
||||||
|
}
|
||||||
|
@@ -45,6 +45,13 @@ errnoParser = re.compile(r'''
|
|||||||
\(\*_errno\(\)\)
|
\(\*_errno\(\)\)
|
||||||
''', re.VERBOSE)
|
''', re.VERBOSE)
|
||||||
sinceEpochParser = re.compile(r'\d+ .+ since epoch')
|
sinceEpochParser = re.compile(r'\d+ .+ since epoch')
|
||||||
|
infParser = re.compile(r'''
|
||||||
|
\(\(float\)\(1e\+300\ \*\ 1e\+300\)\) # MSVC INFINITY macro
|
||||||
|
|
|
||||||
|
\(__builtin_inff\(\)\) # Linux (ubuntu) INFINITY macro
|
||||||
|
|
|
||||||
|
__builtin_huge_valf\(\) # OSX macro
|
||||||
|
''', re.VERBOSE)
|
||||||
|
|
||||||
if len(sys.argv) == 2:
|
if len(sys.argv) == 2:
|
||||||
cmdPath = sys.argv[1]
|
cmdPath = sys.argv[1]
|
||||||
@@ -102,6 +109,7 @@ def filterLine(line):
|
|||||||
line = specialCaseParser.sub('file:\g<1>', line)
|
line = specialCaseParser.sub('file:\g<1>', line)
|
||||||
line = errnoParser.sub('errno', line)
|
line = errnoParser.sub('errno', line)
|
||||||
line = sinceEpochParser.sub('{since-epoch-report}', line)
|
line = sinceEpochParser.sub('{since-epoch-report}', line)
|
||||||
|
line = infParser.sub('INFINITY', line)
|
||||||
return line
|
return line
|
||||||
|
|
||||||
|
|
||||||
|
@@ -15,6 +15,7 @@ versionPath = os.path.join( rootPath, "internal/catch_version.cpp" )
|
|||||||
readmePath = os.path.join( catchPath, "README.md" )
|
readmePath = os.path.join( catchPath, "README.md" )
|
||||||
conanPath = os.path.join(catchPath, 'conanfile.py')
|
conanPath = os.path.join(catchPath, 'conanfile.py')
|
||||||
conanTestPath = os.path.join(catchPath, 'test_package', 'conanfile.py')
|
conanTestPath = os.path.join(catchPath, 'test_package', 'conanfile.py')
|
||||||
|
cmakePath = os.path.join(catchPath, 'CMakeLists.txt')
|
||||||
|
|
||||||
class Version:
|
class Version:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -126,6 +127,17 @@ def updateConanTestFile(version):
|
|||||||
for line in lines:
|
for line in lines:
|
||||||
f.write( line + "\n" )
|
f.write( line + "\n" )
|
||||||
|
|
||||||
|
def updateCmakeFile(version):
|
||||||
|
cmakeParser = re.compile(r'set(CATCH_VERSION_NUMBER \d+\.\d+\.\d+)')
|
||||||
|
with open(cmakePath, 'r') as file:
|
||||||
|
lines = file.readlines()
|
||||||
|
with open(cmakePath, 'w') as file:
|
||||||
|
for line in lines:
|
||||||
|
if 'set(CATCH_VERSION_NUMBER ' in line:
|
||||||
|
file.write('set(CATCH_VERSION_NUMBER {0})\n'.format(version.getVersionString()))
|
||||||
|
else:
|
||||||
|
file.write(line)
|
||||||
|
|
||||||
def performUpdates(version):
|
def performUpdates(version):
|
||||||
# First update version file, so we can regenerate single header and
|
# First update version file, so we can regenerate single header and
|
||||||
# have it ready for upload to wandbox, when updating readme
|
# have it ready for upload to wandbox, when updating readme
|
||||||
@@ -134,3 +146,4 @@ def performUpdates(version):
|
|||||||
updateReadmeFile(version)
|
updateReadmeFile(version)
|
||||||
updateConanFile(version)
|
updateConanFile(version)
|
||||||
updateConanTestFile(version)
|
updateConanTestFile(version)
|
||||||
|
updateCmakeFile(version)
|
||||||
|
@@ -30,7 +30,7 @@ headingExcludeRelease = [2,3,4,5] # use level 1 headers for release-notes.md
|
|||||||
documentsDefault = os.path.join(os.path.relpath(catchPath), 'docs/*.md')
|
documentsDefault = os.path.join(os.path.relpath(catchPath), 'docs/*.md')
|
||||||
releaseNotesName = 'release-notes.md'
|
releaseNotesName = 'release-notes.md'
|
||||||
|
|
||||||
contentTitle = '**Contents** '
|
contentTitle = '**Contents**'
|
||||||
contentLineNo = 4
|
contentLineNo = 4
|
||||||
contentLineNdx = contentLineNo - 1
|
contentLineNdx = contentLineNo - 1
|
||||||
|
|
||||||
@@ -210,14 +210,14 @@ def createToc(headlines, hyperlink=True, top_link=False, no_toc_header=False):
|
|||||||
if not no_toc_header:
|
if not no_toc_header:
|
||||||
if top_link:
|
if top_link:
|
||||||
processed.append('<a class="mk-toclify" id="table-of-contents"></a>\n')
|
processed.append('<a class="mk-toclify" id="table-of-contents"></a>\n')
|
||||||
processed.append(contentTitle)
|
processed.append(contentTitle + '<br>')
|
||||||
|
|
||||||
for line in headlines:
|
for line in headlines:
|
||||||
if hyperlink:
|
if hyperlink:
|
||||||
item = '[%s](#%s) ' % (line[0], line[1])
|
item = '[%s](#%s)' % (line[0], line[1])
|
||||||
else:
|
else:
|
||||||
item = '%s- %s' % ((line[2]-1)*' ', line[0])
|
item = '%s- %s' % ((line[2]-1)*' ', line[0])
|
||||||
processed.append(item)
|
processed.append(item + '<br>')
|
||||||
processed.append('\n')
|
processed.append('\n')
|
||||||
return processed
|
return processed
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Catch v2.0.0-develop.5
|
* Catch v2.0.1
|
||||||
* Generated: 2017-10-12 13:05:08.135067
|
* Generated: 2017-11-03 11:53:39.642003
|
||||||
* ----------------------------------------------------------
|
* ----------------------------------------------------------
|
||||||
* This file has been merged from multiple headers. Please don't edit it directly
|
* This file has been merged from multiple headers. Please don't edit it directly
|
||||||
* Copyright (c) 2017 Two Blue Cubes Ltd. All rights reserved.
|
* Copyright (c) 2017 Two Blue Cubes Ltd. All rights reserved.
|
||||||
@@ -155,7 +155,7 @@
|
|||||||
|
|
||||||
// Universal Windows platform does not support SEH
|
// Universal Windows platform does not support SEH
|
||||||
// Or console colours (or console at all...)
|
// Or console colours (or console at all...)
|
||||||
# if (WINAPI_FAMILY == WINAPI_FAMILY_APP)
|
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
|
||||||
# define CATCH_CONFIG_COLOUR_NONE
|
# define CATCH_CONFIG_COLOUR_NONE
|
||||||
# else
|
# else
|
||||||
# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
|
# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
|
||||||
@@ -165,16 +165,16 @@
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// All supported compilers support COUNTER macro,
|
// Use of __COUNTER__ is suppressed during code analysis in
|
||||||
//but user still might want to turn it off
|
// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
|
||||||
#define CATCH_INTERNAL_CONFIG_COUNTER
|
// handled by it.
|
||||||
|
// Otherwise all supported compilers support COUNTER macro,
|
||||||
|
// but user still might want to turn it off
|
||||||
|
#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
|
||||||
|
#define CATCH_INTERNAL_CONFIG_COUNTER
|
||||||
|
#endif
|
||||||
|
|
||||||
// Now set the actual defines based on the above + anything the user has configured
|
#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
|
||||||
|
|
||||||
// Use of __COUNTER__ is suppressed if __JETBRAINS_IDE__ is #defined (meaning we're being parsed by a JetBrains IDE for
|
|
||||||
// analytics) because, at time of writing, __COUNTER__ is not properly handled by it.
|
|
||||||
// This does not affect compilation
|
|
||||||
#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) && !defined(__JETBRAINS_IDE__)
|
|
||||||
# define CATCH_CONFIG_COUNTER
|
# define CATCH_CONFIG_COUNTER
|
||||||
#endif
|
#endif
|
||||||
#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH)
|
#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH)
|
||||||
@@ -1037,7 +1037,7 @@ namespace Catch {
|
|||||||
|
|
||||||
// Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
|
// Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
|
||||||
template<typename LhsT, typename RhsT>
|
template<typename LhsT, typename RhsT>
|
||||||
auto compareEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return lhs == rhs; };
|
auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return lhs == rhs; };
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
|
auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -1065,36 +1065,36 @@ namespace Catch {
|
|||||||
ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
|
ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
|
||||||
|
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
auto operator == ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
|
auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
||||||
return BinaryExpr<LhsT, RhsT&>( compareEqual( m_lhs, rhs ), m_lhs, "==", rhs );
|
return BinaryExpr<LhsT, RhsT const&>( compareEqual( m_lhs, rhs ), m_lhs, "==", rhs );
|
||||||
}
|
}
|
||||||
auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
|
auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
|
||||||
return BinaryExpr<LhsT, bool>( m_lhs == rhs, m_lhs, "==", rhs );
|
return BinaryExpr<LhsT, bool>( m_lhs == rhs, m_lhs, "==", rhs );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
auto operator != ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
|
auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
||||||
return BinaryExpr<LhsT, RhsT&>( compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs );
|
return BinaryExpr<LhsT, RhsT const&>( compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs );
|
||||||
}
|
}
|
||||||
auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
|
auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
|
||||||
return BinaryExpr<LhsT, bool>( m_lhs != rhs, m_lhs, "!=", rhs );
|
return BinaryExpr<LhsT, bool>( m_lhs != rhs, m_lhs, "!=", rhs );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
auto operator > ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
|
auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
||||||
return BinaryExpr<LhsT, RhsT&>( m_lhs > rhs, m_lhs, ">", rhs );
|
return BinaryExpr<LhsT, RhsT const&>( m_lhs > rhs, m_lhs, ">", rhs );
|
||||||
}
|
}
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
auto operator < ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
|
auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
||||||
return BinaryExpr<LhsT, RhsT&>( m_lhs < rhs, m_lhs, "<", rhs );
|
return BinaryExpr<LhsT, RhsT const&>( m_lhs < rhs, m_lhs, "<", rhs );
|
||||||
}
|
}
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
auto operator >= ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
|
auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
||||||
return BinaryExpr<LhsT, RhsT&>( m_lhs >= rhs, m_lhs, ">=", rhs );
|
return BinaryExpr<LhsT, RhsT const&>( m_lhs >= rhs, m_lhs, ">=", rhs );
|
||||||
}
|
}
|
||||||
template<typename RhsT>
|
template<typename RhsT>
|
||||||
auto operator <= ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
|
auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
|
||||||
return BinaryExpr<LhsT, RhsT&>( m_lhs <= rhs, m_lhs, "<=", rhs );
|
return BinaryExpr<LhsT, RhsT const&>( m_lhs <= rhs, m_lhs, "<=", rhs );
|
||||||
}
|
}
|
||||||
|
|
||||||
auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
|
auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
|
||||||
@@ -1121,6 +1121,10 @@ namespace Catch {
|
|||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
// end catch_decomposer.h
|
// end catch_decomposer.h
|
||||||
// start catch_assertioninfo.h
|
// start catch_assertioninfo.h
|
||||||
|
|
||||||
@@ -1816,16 +1820,30 @@ namespace Catch {
|
|||||||
// end catch_interfaces_exception.h
|
// end catch_interfaces_exception.h
|
||||||
// start catch_approx.h
|
// start catch_approx.h
|
||||||
|
|
||||||
#include <cmath>
|
// start catch_enforce.h
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#define CATCH_PREPARE_EXCEPTION( type, msg ) \
|
||||||
|
type( static_cast<std::ostringstream&&>( std::ostringstream() << msg ).str() )
|
||||||
|
#define CATCH_INTERNAL_ERROR( msg ) \
|
||||||
|
throw CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg);
|
||||||
|
#define CATCH_ERROR( msg ) \
|
||||||
|
throw CATCH_PREPARE_EXCEPTION( std::domain_error, msg )
|
||||||
|
#define CATCH_ENFORCE( condition, msg ) \
|
||||||
|
do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false)
|
||||||
|
|
||||||
|
// end catch_enforce.h
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
namespace Detail {
|
namespace Detail {
|
||||||
|
|
||||||
double max(double lhs, double rhs);
|
|
||||||
|
|
||||||
class Approx {
|
class Approx {
|
||||||
|
private:
|
||||||
|
bool equalityComparisonImpl(double other) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Approx ( double value );
|
explicit Approx ( double value );
|
||||||
|
|
||||||
@@ -1846,13 +1864,8 @@ namespace Detail {
|
|||||||
|
|
||||||
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||||
friend bool operator == ( const T& lhs, Approx const& rhs ) {
|
friend bool operator == ( const T& lhs, Approx const& rhs ) {
|
||||||
// Thanks to Richard Harris for his help refining this formula
|
|
||||||
auto lhs_v = static_cast<double>(lhs);
|
auto lhs_v = static_cast<double>(lhs);
|
||||||
bool relativeOK = std::fabs(lhs_v - rhs.m_value) < rhs.m_epsilon * (rhs.m_scale + (max)(std::fabs(lhs_v), std::fabs(rhs.m_value)));
|
return rhs.equalityComparisonImpl(lhs_v);
|
||||||
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>
|
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||||
@@ -1892,13 +1905,21 @@ namespace Detail {
|
|||||||
|
|
||||||
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||||
Approx& epsilon( T const& newEpsilon ) {
|
Approx& epsilon( T const& newEpsilon ) {
|
||||||
m_epsilon = static_cast<double>(newEpsilon);
|
double epsilonAsDouble = static_cast<double>(newEpsilon);
|
||||||
|
CATCH_ENFORCE(epsilonAsDouble >= 0 && epsilonAsDouble <= 1.0,
|
||||||
|
"Invalid Approx::epsilon: " << epsilonAsDouble
|
||||||
|
<< ", Approx::epsilon has to be between 0 and 1");
|
||||||
|
m_epsilon = epsilonAsDouble;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||||
Approx& margin( T const& newMargin ) {
|
Approx& margin( T const& newMargin ) {
|
||||||
m_margin = static_cast<double>(newMargin);
|
double marginAsDouble = static_cast<double>(newMargin);
|
||||||
|
CATCH_ENFORCE(marginAsDouble >= 0,
|
||||||
|
"Invalid Approx::margin: " << marginAsDouble
|
||||||
|
<< ", Approx::Margin has to be non-negative.");
|
||||||
|
m_margin = marginAsDouble;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2643,21 +2664,6 @@ return @ desc; \
|
|||||||
|
|
||||||
// start catch_reporter_bases.hpp
|
// start catch_reporter_bases.hpp
|
||||||
|
|
||||||
// start catch_enforce.h
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
#define CATCH_PREPARE_EXCEPTION( type, msg ) \
|
|
||||||
type( static_cast<std::ostringstream&&>( std::ostringstream() << msg ).str() )
|
|
||||||
#define CATCH_INTERNAL_ERROR( msg ) \
|
|
||||||
throw CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg);
|
|
||||||
#define CATCH_ERROR( msg ) \
|
|
||||||
throw CATCH_PREPARE_EXCEPTION( std::domain_error, msg )
|
|
||||||
#define CATCH_ENFORCE( condition, msg ) \
|
|
||||||
do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false)
|
|
||||||
|
|
||||||
// end catch_enforce.h
|
|
||||||
// start catch_interfaces_reporter.h
|
// start catch_interfaces_reporter.h
|
||||||
|
|
||||||
// start catch_config.hpp
|
// start catch_config.hpp
|
||||||
@@ -3974,22 +3980,26 @@ namespace Catch {
|
|||||||
// Cpp files will be included in the single-header file here
|
// Cpp files will be included in the single-header file here
|
||||||
// start catch_approx.cpp
|
// start catch_approx.cpp
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Performs equivalent check of std::fabs(lhs - rhs) <= margin
|
||||||
|
// But without the subtraction to allow for INFINITY in comparison
|
||||||
|
bool marginComparison(double lhs, double rhs, double margin) {
|
||||||
|
return (lhs + margin >= rhs) && (rhs + margin >= lhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
namespace Detail {
|
namespace Detail {
|
||||||
|
|
||||||
double max(double lhs, double rhs) {
|
|
||||||
if (lhs < rhs) {
|
|
||||||
return rhs;
|
|
||||||
}
|
|
||||||
return lhs;
|
|
||||||
}
|
|
||||||
|
|
||||||
Approx::Approx ( double value )
|
Approx::Approx ( double value )
|
||||||
: m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
|
: m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
|
||||||
m_margin( 0.0 ),
|
m_margin( 0.0 ),
|
||||||
m_scale( 1.0 ),
|
m_scale( 0.0 ),
|
||||||
m_value( value )
|
m_value( value )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@@ -4003,6 +4013,12 @@ namespace Detail {
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Approx::equalityComparisonImpl(const double other) const {
|
||||||
|
// First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
|
||||||
|
// Thanks to Richard Harris for his help refining the scaled margin value
|
||||||
|
return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace Detail
|
} // end namespace Detail
|
||||||
|
|
||||||
std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
|
std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
|
||||||
@@ -4226,8 +4242,8 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string AssertionResult::getExpression() const {
|
std::string AssertionResult::getExpression() const {
|
||||||
if (isFalseTest(m_info.resultDisposition))
|
if( isFalseTest( m_info.resultDisposition ) )
|
||||||
return '!' + std::string(m_info.capturedExpression);
|
return "!(" + std::string(m_info.capturedExpression) + ")";
|
||||||
else
|
else
|
||||||
return m_info.capturedExpression;
|
return m_info.capturedExpression;
|
||||||
}
|
}
|
||||||
@@ -4334,7 +4350,7 @@ namespace Catch {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// start clara.hpp
|
// start clara.hpp
|
||||||
// v1.0
|
// v1.0-develop.2
|
||||||
// See https://github.com/philsquared/Clara
|
// See https://github.com/philsquared/Clara
|
||||||
|
|
||||||
|
|
||||||
@@ -4737,6 +4753,14 @@ namespace detail {
|
|||||||
std::string token;
|
std::string token;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline auto isOptPrefix( char c ) -> bool {
|
||||||
|
return c == '-'
|
||||||
|
#ifdef CATCH_PLATFORM_WINDOWS
|
||||||
|
|| c == '/'
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
// Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
|
// Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
|
||||||
class TokenStream {
|
class TokenStream {
|
||||||
using Iterator = std::vector<std::string>::const_iterator;
|
using Iterator = std::vector<std::string>::const_iterator;
|
||||||
@@ -4753,7 +4777,7 @@ namespace detail {
|
|||||||
|
|
||||||
if( it != itEnd ) {
|
if( it != itEnd ) {
|
||||||
auto const &next = *it;
|
auto const &next = *it;
|
||||||
if( next[0] == '-' || next[0] == '/' ) {
|
if( isOptPrefix( next[0] ) ) {
|
||||||
auto delimiterPos = next.find_first_of( " :=" );
|
auto delimiterPos = next.find_first_of( " :=" );
|
||||||
if( delimiterPos != std::string::npos ) {
|
if( delimiterPos != std::string::npos ) {
|
||||||
m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
|
m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
|
||||||
@@ -5241,9 +5265,11 @@ namespace detail {
|
|||||||
};
|
};
|
||||||
|
|
||||||
inline auto normaliseOpt( std::string const &optName ) -> std::string {
|
inline auto normaliseOpt( std::string const &optName ) -> std::string {
|
||||||
|
#ifdef CATCH_PLATFORM_WINDOWS
|
||||||
if( optName[0] == '/' )
|
if( optName[0] == '/' )
|
||||||
return "-" + optName.substr( 1 );
|
return "-" + optName.substr( 1 );
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
return optName;
|
return optName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5284,11 +5310,7 @@ namespace detail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto isMatch( std::string const &optToken ) const -> bool {
|
auto isMatch( std::string const &optToken ) const -> bool {
|
||||||
#ifdef CATCH_PLATFORM_WINDOWS
|
|
||||||
auto normalisedToken = normaliseOpt( optToken );
|
auto normalisedToken = normaliseOpt( optToken );
|
||||||
#else
|
|
||||||
auto const &normalisedToken = optToken;
|
|
||||||
#endif
|
|
||||||
for( auto const &name : m_optNames ) {
|
for( auto const &name : m_optNames ) {
|
||||||
if( normaliseOpt( name ) == normalisedToken )
|
if( normaliseOpt( name ) == normalisedToken )
|
||||||
return true;
|
return true;
|
||||||
@@ -5338,8 +5360,13 @@ namespace detail {
|
|||||||
for( auto const &name : m_optNames ) {
|
for( auto const &name : m_optNames ) {
|
||||||
if( name.empty() )
|
if( name.empty() )
|
||||||
return Result::logicError( "Option name cannot be empty" );
|
return Result::logicError( "Option name cannot be empty" );
|
||||||
|
#ifdef CATCH_PLATFORM_WINDOWS
|
||||||
if( name[0] != '-' && name[0] != '/' )
|
if( name[0] != '-' && name[0] != '/' )
|
||||||
return Result::logicError( "Option name must begin with '-' or '/'" );
|
return Result::logicError( "Option name must begin with '-' or '/'" );
|
||||||
|
#else
|
||||||
|
if( name[0] != '-' )
|
||||||
|
return Result::logicError( "Option name must begin with '-'" );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return ParserRefImpl::validate();
|
return ParserRefImpl::validate();
|
||||||
}
|
}
|
||||||
@@ -5428,7 +5455,7 @@ namespace detail {
|
|||||||
size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
|
size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
|
||||||
size_t optWidth = 0;
|
size_t optWidth = 0;
|
||||||
for( auto const &cols : rows )
|
for( auto const &cols : rows )
|
||||||
optWidth = std::max(optWidth, cols.left.size() + 2);
|
optWidth = (std::max)(optWidth, cols.left.size() + 2);
|
||||||
|
|
||||||
for( auto const &cols : rows ) {
|
for( auto const &cols : rows ) {
|
||||||
auto row =
|
auto row =
|
||||||
@@ -7188,10 +7215,10 @@ namespace Catch {
|
|||||||
unsigned int rngSeed();
|
unsigned int rngSeed();
|
||||||
|
|
||||||
struct RandomNumberGenerator {
|
struct RandomNumberGenerator {
|
||||||
using result_type = std::ptrdiff_t;
|
using result_type = unsigned int;
|
||||||
|
|
||||||
static constexpr result_type min() { return 0; }
|
static constexpr result_type (min)() { return 0; }
|
||||||
static constexpr result_type max() { return 1000000; }
|
static constexpr result_type (max)() { return 1000000; }
|
||||||
|
|
||||||
result_type operator()( result_type n ) const;
|
result_type operator()( result_type n ) const;
|
||||||
result_type operator()() const;
|
result_type operator()() const;
|
||||||
@@ -7222,7 +7249,7 @@ namespace Catch {
|
|||||||
return std::rand() % n;
|
return std::rand() % n;
|
||||||
}
|
}
|
||||||
RandomNumberGenerator::result_type RandomNumberGenerator::operator()() const {
|
RandomNumberGenerator::result_type RandomNumberGenerator::operator()() const {
|
||||||
return std::rand() % max();
|
return std::rand() % (max)();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -8038,6 +8065,7 @@ namespace Catch {
|
|||||||
clara::Parser m_cli;
|
clara::Parser m_cli;
|
||||||
ConfigData m_configData;
|
ConfigData m_configData;
|
||||||
std::shared_ptr<Config> m_config;
|
std::shared_ptr<Config> m_config;
|
||||||
|
bool m_startupExceptions = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
@@ -8169,8 +8197,26 @@ namespace Catch {
|
|||||||
|
|
||||||
Session::Session() {
|
Session::Session() {
|
||||||
static bool alreadyInstantiated = false;
|
static bool alreadyInstantiated = false;
|
||||||
if( alreadyInstantiated )
|
if( alreadyInstantiated ) {
|
||||||
CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" );
|
try { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
|
||||||
|
catch(...) { getMutableRegistryHub().registerStartupException(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
|
||||||
|
if ( !exceptions.empty() ) {
|
||||||
|
m_startupExceptions = true;
|
||||||
|
Colour colourGuard( Colour::Red );
|
||||||
|
Catch::cerr() << "Errors occured during startup!" << '\n';
|
||||||
|
// iterate over all exceptions and notify user
|
||||||
|
for ( const auto& ex_ptr : exceptions ) {
|
||||||
|
try {
|
||||||
|
std::rethrow_exception(ex_ptr);
|
||||||
|
} catch ( std::exception const& ex ) {
|
||||||
|
Catch::cerr() << Column( ex.what() ).indent(2) << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
alreadyInstantiated = true;
|
alreadyInstantiated = true;
|
||||||
m_cli = makeCommandLineParser( m_configData );
|
m_cli = makeCommandLineParser( m_configData );
|
||||||
}
|
}
|
||||||
@@ -8193,6 +8239,9 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Session::applyCommandLine( int argc, char* argv[] ) {
|
int Session::applyCommandLine( int argc, char* argv[] ) {
|
||||||
|
if( m_startupExceptions )
|
||||||
|
return 1;
|
||||||
|
|
||||||
auto result = m_cli.parse( clara::Args( argc, argv ) );
|
auto result = m_cli.parse( clara::Args( argc, argv ) );
|
||||||
if( !result ) {
|
if( !result ) {
|
||||||
Catch::cerr()
|
Catch::cerr()
|
||||||
@@ -8218,19 +8267,8 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Session::run( int argc, char* argv[] ) {
|
int Session::run( int argc, char* argv[] ) {
|
||||||
const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
|
if( m_startupExceptions )
|
||||||
if ( !exceptions.empty() ) {
|
|
||||||
Catch::cerr() << "Errors occured during startup!" << '\n';
|
|
||||||
// iterate over all exceptions and notify user
|
|
||||||
for ( const auto& ex_ptr : exceptions ) {
|
|
||||||
try {
|
|
||||||
std::rethrow_exception(ex_ptr);
|
|
||||||
} catch ( std::exception const& ex ) {
|
|
||||||
Catch::cerr() << ex.what() << '\n';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
int returnCode = applyCommandLine( argc, argv );
|
int returnCode = applyCommandLine( argc, argv );
|
||||||
if( returnCode == 0 )
|
if( returnCode == 0 )
|
||||||
returnCode = run();
|
returnCode = run();
|
||||||
@@ -8289,6 +8327,9 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Session::runInternal() {
|
int Session::runInternal() {
|
||||||
|
if( m_startupExceptions )
|
||||||
|
return 1;
|
||||||
|
|
||||||
if( m_configData.showHelp || m_configData.libIdentify )
|
if( m_configData.showHelp || m_configData.libIdentify )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -9785,7 +9826,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Version const& libraryVersion() {
|
Version const& libraryVersion() {
|
||||||
static Version version( 2, 0, 0, "develop", 5 );
|
static Version version( 2, 0, 1, "", 0 );
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10453,6 +10494,13 @@ namespace Catch {
|
|||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
|
||||||
|
// Note that 4062 (not all labels are handled
|
||||||
|
// and default is missing) is enabled
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -11074,6 +11122,10 @@ namespace Catch {
|
|||||||
ConsoleReporter::~ConsoleReporter() {}
|
ConsoleReporter::~ConsoleReporter() {}
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
// end catch_reporter_console.cpp
|
// end catch_reporter_console.cpp
|
||||||
// start catch_reporter_junit.cpp
|
// start catch_reporter_junit.cpp
|
||||||
|
|
||||||
@@ -11415,6 +11467,13 @@ namespace Catch {
|
|||||||
// end catch_reporter_multi.cpp
|
// end catch_reporter_multi.cpp
|
||||||
// start catch_reporter_xml.cpp
|
// start catch_reporter_xml.cpp
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
|
||||||
|
// Note that 4062 (not all labels are handled
|
||||||
|
// and default is missing) is enabled
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
class XmlReporter : public StreamingReporterBase<XmlReporter> {
|
class XmlReporter : public StreamingReporterBase<XmlReporter> {
|
||||||
public:
|
public:
|
||||||
@@ -11624,6 +11683,10 @@ namespace Catch {
|
|||||||
CATCH_REGISTER_REPORTER( "xml", XmlReporter )
|
CATCH_REGISTER_REPORTER( "xml", XmlReporter )
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
// end catch_reporter_xml.cpp
|
// end catch_reporter_xml.cpp
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
@@ -10,7 +10,7 @@ class CatchConanTest(ConanFile):
|
|||||||
settings = "os", "compiler", "arch", "build_type"
|
settings = "os", "compiler", "arch", "build_type"
|
||||||
username = getenv("CONAN_USERNAME", "philsquared")
|
username = getenv("CONAN_USERNAME", "philsquared")
|
||||||
channel = getenv("CONAN_CHANNEL", "testing")
|
channel = getenv("CONAN_CHANNEL", "testing")
|
||||||
requires = "Catch/2.0.0-develop.5@%s/%s" % (username, channel)
|
requires = "Catch/2.0.1@%s/%s" % (username, channel)
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
cmake = CMake(self)
|
cmake = CMake(self)
|
||||||
|
41
third_party/clara.hpp
vendored
41
third_party/clara.hpp
vendored
@@ -1,4 +1,4 @@
|
|||||||
// v1.0
|
// v1.0-develop.2
|
||||||
// See https://github.com/philsquared/Clara
|
// See https://github.com/philsquared/Clara
|
||||||
|
|
||||||
#ifndef CLARA_HPP_INCLUDED
|
#ifndef CLARA_HPP_INCLUDED
|
||||||
@@ -409,6 +409,14 @@ namespace detail {
|
|||||||
std::string token;
|
std::string token;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline auto isOptPrefix( char c ) -> bool {
|
||||||
|
return c == '-'
|
||||||
|
#ifdef CLARA_PLATFORM_WINDOWS
|
||||||
|
|| c == '/'
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
// Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
|
// Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
|
||||||
class TokenStream {
|
class TokenStream {
|
||||||
using Iterator = std::vector<std::string>::const_iterator;
|
using Iterator = std::vector<std::string>::const_iterator;
|
||||||
@@ -425,7 +433,7 @@ namespace detail {
|
|||||||
|
|
||||||
if( it != itEnd ) {
|
if( it != itEnd ) {
|
||||||
auto const &next = *it;
|
auto const &next = *it;
|
||||||
if( next[0] == '-' || next[0] == '/' ) {
|
if( isOptPrefix( next[0] ) ) {
|
||||||
auto delimiterPos = next.find_first_of( " :=" );
|
auto delimiterPos = next.find_first_of( " :=" );
|
||||||
if( delimiterPos != std::string::npos ) {
|
if( delimiterPos != std::string::npos ) {
|
||||||
m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
|
m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
|
||||||
@@ -915,9 +923,11 @@ namespace detail {
|
|||||||
};
|
};
|
||||||
|
|
||||||
inline auto normaliseOpt( std::string const &optName ) -> std::string {
|
inline auto normaliseOpt( std::string const &optName ) -> std::string {
|
||||||
|
#ifdef CLARA_PLATFORM_WINDOWS
|
||||||
if( optName[0] == '/' )
|
if( optName[0] == '/' )
|
||||||
return "-" + optName.substr( 1 );
|
return "-" + optName.substr( 1 );
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
return optName;
|
return optName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -958,11 +968,7 @@ namespace detail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto isMatch( std::string const &optToken ) const -> bool {
|
auto isMatch( std::string const &optToken ) const -> bool {
|
||||||
#ifdef CLARA_PLATFORM_WINDOWS
|
|
||||||
auto normalisedToken = normaliseOpt( optToken );
|
auto normalisedToken = normaliseOpt( optToken );
|
||||||
#else
|
|
||||||
auto const &normalisedToken = optToken;
|
|
||||||
#endif
|
|
||||||
for( auto const &name : m_optNames ) {
|
for( auto const &name : m_optNames ) {
|
||||||
if( normaliseOpt( name ) == normalisedToken )
|
if( normaliseOpt( name ) == normalisedToken )
|
||||||
return true;
|
return true;
|
||||||
@@ -1012,8 +1018,13 @@ namespace detail {
|
|||||||
for( auto const &name : m_optNames ) {
|
for( auto const &name : m_optNames ) {
|
||||||
if( name.empty() )
|
if( name.empty() )
|
||||||
return Result::logicError( "Option name cannot be empty" );
|
return Result::logicError( "Option name cannot be empty" );
|
||||||
|
#ifdef CLARA_PLATFORM_WINDOWS
|
||||||
if( name[0] != '-' && name[0] != '/' )
|
if( name[0] != '-' && name[0] != '/' )
|
||||||
return Result::logicError( "Option name must begin with '-' or '/'" );
|
return Result::logicError( "Option name must begin with '-' or '/'" );
|
||||||
|
#else
|
||||||
|
if( name[0] != '-' )
|
||||||
|
return Result::logicError( "Option name must begin with '-'" );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return ParserRefImpl::validate();
|
return ParserRefImpl::validate();
|
||||||
}
|
}
|
||||||
@@ -1103,7 +1114,7 @@ namespace detail {
|
|||||||
size_t consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
|
size_t consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
|
||||||
size_t optWidth = 0;
|
size_t optWidth = 0;
|
||||||
for( auto const &cols : rows )
|
for( auto const &cols : rows )
|
||||||
optWidth = std::max(optWidth, cols.left.size() + 2);
|
optWidth = (std::max)(optWidth, cols.left.size() + 2);
|
||||||
|
|
||||||
for( auto const &cols : rows ) {
|
for( auto const &cols : rows ) {
|
||||||
auto row =
|
auto row =
|
||||||
@@ -1142,10 +1153,15 @@ namespace detail {
|
|||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
};
|
};
|
||||||
const size_t totalParsers = m_options.size() + m_args.size();
|
const size_t totalParsers = m_options.size() + m_args.size();
|
||||||
ParserInfo parseInfos[totalParsers];
|
assert( totalParsers < 512 );
|
||||||
size_t i = 0;
|
// ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
|
||||||
for( auto const& opt : m_options ) parseInfos[i++].parser = &opt;
|
ParserInfo parseInfos[512];
|
||||||
for( auto const& arg : m_args ) parseInfos[i++].parser = &arg;
|
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
|
||||||
|
for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
|
||||||
|
}
|
||||||
|
|
||||||
m_exeName.set( exeName );
|
m_exeName.set( exeName );
|
||||||
|
|
||||||
@@ -1153,7 +1169,8 @@ namespace detail {
|
|||||||
while( result.value().remainingTokens() ) {
|
while( result.value().remainingTokens() ) {
|
||||||
bool tokenParsed = false;
|
bool tokenParsed = false;
|
||||||
|
|
||||||
for( auto& parseInfo : parseInfos ) {
|
for( size_t i = 0; i < totalParsers; ++i ) {
|
||||||
|
auto& parseInfo = parseInfos[i];
|
||||||
if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {
|
if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {
|
||||||
result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
|
result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
|
||||||
if (!result)
|
if (!result)
|
||||||
|
Reference in New Issue
Block a user