mirror of
https://github.com/catchorg/Catch2.git
synced 2025-09-11 07:55:39 +02:00
Compare commits
27 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
7c37501b07 | ||
![]() |
4a1ca1ab55 | ||
![]() |
91b617c462 | ||
![]() |
45e552528d | ||
![]() |
3978e9653b | ||
![]() |
d6fce7bf34 | ||
![]() |
c3c82f539c | ||
![]() |
c7653811a6 | ||
![]() |
79417b9afc | ||
![]() |
11cdd72db9 | ||
![]() |
0c39409da7 | ||
![]() |
edfac75347 | ||
![]() |
ac94bd0520 | ||
![]() |
d4eec016a9 | ||
![]() |
36fb856163 | ||
![]() |
4e32e0a563 | ||
![]() |
1e2270b370 | ||
![]() |
5096e39297 | ||
![]() |
15ccced6da | ||
![]() |
682617b5b7 | ||
![]() |
15150c7b46 | ||
![]() |
5ce355a38c | ||
![]() |
edde6f4736 | ||
![]() |
6bc5d172ee | ||
![]() |
3079b514d4 | ||
![]() |
e99f1efd28 | ||
![]() |
5347ff9e5f |
@@ -47,7 +47,7 @@ class BuilderSettings(object):
|
||||
|
||||
@property
|
||||
def reference(self):
|
||||
""" Read project version from branch create Conan referece
|
||||
""" Read project version from branch create Conan reference
|
||||
"""
|
||||
return os.getenv("CONAN_REFERENCE", "Catch2/{}".format(self._version))
|
||||
|
||||
|
2
.github/pull_request_template.md
vendored
2
.github/pull_request_template.md
vendored
@@ -12,7 +12,7 @@ at docs/contributing.md. It will tell you how to properly test your changes.
|
||||
<!--
|
||||
Describe the what and the why of your pull request. Remember that these two
|
||||
are usually a bit different. As an example, if you have made various changes
|
||||
to decrease the number of new strings allocated, thats what. The why probably
|
||||
to decrease the number of new strings allocated, that's what. The why probably
|
||||
was that you have a large set of tests and found that this speeds them up.
|
||||
-->
|
||||
|
||||
|
@@ -19,7 +19,7 @@ set(CMAKE_REQUIRED_QUIET ${codecov_FIND_QUIETLY})
|
||||
|
||||
get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
|
||||
foreach (LANG ${ENABLED_LANGUAGES})
|
||||
# Gcov evaluation is dependend on the used compiler. Check gcov support for
|
||||
# Gcov evaluation is dependent on the used compiler. Check gcov support for
|
||||
# each compiler that is used. If gcov binary was already found for this
|
||||
# compiler, do not try to find it again.
|
||||
if (NOT GCOV_${CMAKE_${LANG}_COMPILER_ID}_BIN)
|
||||
|
@@ -74,7 +74,7 @@ set(CMAKE_REQUIRED_QUIET ${codecov_FIND_QUIETLY})
|
||||
|
||||
get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
|
||||
foreach (LANG ${ENABLED_LANGUAGES})
|
||||
# Coverage flags are not dependend on language, but the used compiler. So
|
||||
# Coverage flags are not dependent on language, but the used compiler. So
|
||||
# instead of searching flags foreach language, search flags foreach compiler
|
||||
# used.
|
||||
set(COMPILER ${CMAKE_${LANG}_COMPILER_ID})
|
||||
|
@@ -6,7 +6,7 @@ if(NOT DEFINED PROJECT_NAME)
|
||||
set(NOT_SUBPROJECT ON)
|
||||
endif()
|
||||
|
||||
project(Catch2 LANGUAGES CXX VERSION 2.7.1)
|
||||
project(Catch2 LANGUAGES CXX VERSION 2.7.2)
|
||||
|
||||
# Provide path for scripts
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
|
||||
@@ -205,4 +205,15 @@ if (NOT_SUBPROJECT)
|
||||
${PKGCONFIG_INSTALL_DIR}
|
||||
)
|
||||
|
||||
# CPack/CMake started taking the package version from project version 3.12
|
||||
# So we need to set the version manually for older CMake versions
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.12.0")
|
||||
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
|
||||
endif()
|
||||
|
||||
set(CPACK_PACKAGE_CONTACT "https://github.com/catchorg/Catch2/")
|
||||
|
||||
|
||||
include( CPack )
|
||||
|
||||
endif(NOT_SUBPROJECT)
|
||||
|
@@ -5,11 +5,11 @@
|
||||
[](https://travis-ci.org/catchorg/Catch2)
|
||||
[](https://ci.appveyor.com/project/catchorg/catch2)
|
||||
[](https://codecov.io/gh/catchorg/Catch2)
|
||||
[](https://wandbox.org/permlink/ZFBZ5XbLA9F1gzKi)
|
||||
[](https://wandbox.org/permlink/rsEsNO9M0flb5NlQ)
|
||||
[](https://discord.gg/4CWS9zD)
|
||||
|
||||
|
||||
<a href="https://github.com/catchorg/Catch2/releases/download/v2.7.1/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.7.2/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
|
||||
|
||||
## Catch2 is released!
|
||||
|
||||
|
@@ -22,6 +22,39 @@ function(add_command NAME)
|
||||
set(script "${script}${NAME}(${_args})\n" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
macro(_add_catch_test_labels LINE)
|
||||
# convert to list of tags
|
||||
string(REPLACE "][" "]\\;[" tags ${line})
|
||||
|
||||
add_command(
|
||||
set_tests_properties "${prefix}${test}${suffix}"
|
||||
PROPERTIES
|
||||
LABELS "${tags}"
|
||||
)
|
||||
endmacro()
|
||||
|
||||
macro(_add_catch_test LINE)
|
||||
set(test ${line})
|
||||
# use escape commas to handle properly test cases with commans inside the name
|
||||
string(REPLACE "," "\\," test_name ${test})
|
||||
# ...and add to script
|
||||
add_command(
|
||||
add_test "${prefix}${test}${suffix}"
|
||||
${TEST_EXECUTOR}
|
||||
"${TEST_EXECUTABLE}"
|
||||
"${test_name}"
|
||||
${extra_args}
|
||||
)
|
||||
|
||||
add_command(
|
||||
set_tests_properties "${prefix}${test}${suffix}"
|
||||
PROPERTIES
|
||||
WORKING_DIRECTORY "${TEST_WORKING_DIR}"
|
||||
${properties}
|
||||
)
|
||||
list(APPEND tests "${prefix}${test}${suffix}")
|
||||
endmacro()
|
||||
|
||||
# Run test executable to get list of available tests
|
||||
if(NOT EXISTS "${TEST_EXECUTABLE}")
|
||||
message(FATAL_ERROR
|
||||
@@ -29,7 +62,7 @@ if(NOT EXISTS "${TEST_EXECUTABLE}")
|
||||
)
|
||||
endif()
|
||||
execute_process(
|
||||
COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-test-names-only
|
||||
COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-tests
|
||||
OUTPUT_VARIABLE output
|
||||
RESULT_VARIABLE result
|
||||
)
|
||||
@@ -47,27 +80,22 @@ elseif(${result} LESS 0)
|
||||
endif()
|
||||
|
||||
string(REPLACE "\n" ";" output "${output}")
|
||||
set(test)
|
||||
set(tags_regex "(\\[([^\\[]*)\\])+$")
|
||||
|
||||
# Parse output
|
||||
foreach(line ${output})
|
||||
set(test ${line})
|
||||
# use escape commas to handle properly test cases with commans inside the name
|
||||
string(REPLACE "," "\\," test_name ${test})
|
||||
# ...and add to script
|
||||
add_command(add_test
|
||||
"${prefix}${test}${suffix}"
|
||||
${TEST_EXECUTOR}
|
||||
"${TEST_EXECUTABLE}"
|
||||
"${test_name}"
|
||||
${extra_args}
|
||||
)
|
||||
add_command(set_tests_properties
|
||||
"${prefix}${test}${suffix}"
|
||||
PROPERTIES
|
||||
WORKING_DIRECTORY "${TEST_WORKING_DIR}"
|
||||
${properties}
|
||||
)
|
||||
list(APPEND tests "${prefix}${test}${suffix}")
|
||||
# lines without leading whitespaces are catch output not tests
|
||||
if(${line} MATCHES "^[ \t]+")
|
||||
# strip leading spaces and tabs
|
||||
string(REGEX REPLACE "^[ \t]+" "" line ${line})
|
||||
|
||||
if(${line} MATCHES "${tags_regex}")
|
||||
_add_catch_test_labels(${line})
|
||||
else()
|
||||
_add_catch_test(${line})
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Create a list of all discovered tests, which users may use to e.g. set
|
||||
|
@@ -44,9 +44,19 @@
|
||||
# set(OptionalCatchTestLauncher ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${NUMPROC}) #
|
||||
# just before calling this ParseAndAddCatchTests function #
|
||||
# #
|
||||
# The AdditionalCatchParameters optional variable can be used to pass extra argument to the test #
|
||||
# command. For example, to include successful tests in the output, one can write #
|
||||
# set(AdditionalCatchParameters --success) #
|
||||
# #
|
||||
# After the script, the ParseAndAddCatchTests_TESTS property for the target, and for each source #
|
||||
# file in the target is set, and contains the list of the tests extracted from that target, or #
|
||||
# from that file. This is useful, for example to add further labels or properties to the tests. #
|
||||
# #
|
||||
#==================================================================================================#
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.8)
|
||||
if (CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.8)
|
||||
message(FATAL_ERROR "ParseAndAddCatchTests requires CMake 2.8.8 or newer")
|
||||
endif()
|
||||
|
||||
option(PARSE_CATCH_TESTS_VERBOSE "Print Catch to CTest parser debug messages" OFF)
|
||||
option(PARSE_CATCH_TESTS_NO_HIDDEN_TESTS "Exclude tests with [!hide], [.] or [.foo] tags" OFF)
|
||||
@@ -54,7 +64,7 @@ option(PARSE_CATCH_TESTS_ADD_FIXTURE_IN_TEST_NAME "Add fixture class name to the
|
||||
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(ParseAndAddCatchTests_PrintDebugMessage)
|
||||
if(PARSE_CATCH_TESTS_VERBOSE)
|
||||
message(STATUS "ParseAndAddCatchTests: ${ARGV}")
|
||||
endif()
|
||||
@@ -65,7 +75,7 @@ endfunction()
|
||||
# - full line comments (i.e. // ... )
|
||||
# contents have been read into '${CppCode}'.
|
||||
# !keep partial line comments
|
||||
function(RemoveComments CppCode)
|
||||
function(ParseAndAddCatchTests_RemoveComments CppCode)
|
||||
string(ASCII 2 CMakeBeginBlockComment)
|
||||
string(ASCII 3 CMakeEndBlockComment)
|
||||
string(REGEX REPLACE "/\\*" "${CMakeBeginBlockComment}" ${CppCode} "${${CppCode}}")
|
||||
@@ -77,24 +87,29 @@ function(RemoveComments CppCode)
|
||||
endfunction()
|
||||
|
||||
# Worker function
|
||||
function(ParseFile SourceFile TestTarget)
|
||||
function(ParseAndAddCatchTests_ParseFile SourceFile TestTarget)
|
||||
# If SourceFile is an object library, do not scan it (as it is not a file). Exit without giving a warning about a missing file.
|
||||
if(SourceFile MATCHES "\\\$<TARGET_OBJECTS:.+>")
|
||||
ParseAndAddCatchTests_PrintDebugMessage("Detected OBJECT library: ${SourceFile} this will not be scanned for tests.")
|
||||
return()
|
||||
endif()
|
||||
# According to CMake docs EXISTS behavior is well-defined only for full paths.
|
||||
get_filename_component(SourceFile ${SourceFile} ABSOLUTE)
|
||||
if(NOT EXISTS ${SourceFile})
|
||||
message(WARNING "Cannot find source file: ${SourceFile}")
|
||||
return()
|
||||
endif()
|
||||
PrintDebugMessage("parsing ${SourceFile}")
|
||||
ParseAndAddCatchTests_PrintDebugMessage("parsing ${SourceFile}")
|
||||
file(STRINGS ${SourceFile} Contents NEWLINE_CONSUME)
|
||||
|
||||
# Remove block and fullline comments
|
||||
RemoveComments(Contents)
|
||||
ParseAndAddCatchTests_RemoveComments(Contents)
|
||||
|
||||
# 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}")
|
||||
|
||||
if(PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS AND Tests)
|
||||
PrintDebugMessage("Adding ${SourceFile} to CMAKE_CONFIGURE_DEPENDS property")
|
||||
ParseAndAddCatchTests_PrintDebugMessage("Adding ${SourceFile} to CMAKE_CONFIGURE_DEPENDS property")
|
||||
set_property(
|
||||
DIRECTORY
|
||||
APPEND
|
||||
@@ -155,7 +170,6 @@ function(ParseFile SourceFile TestTarget)
|
||||
|
||||
list(APPEND Labels ${Tags})
|
||||
|
||||
list(FIND Labels "!hide" IndexOfHideLabel)
|
||||
set(HiddenTagFound OFF)
|
||||
foreach(label ${Labels})
|
||||
string(REGEX MATCH "^!hide|^\\." result ${label})
|
||||
@@ -165,26 +179,34 @@ function(ParseFile SourceFile TestTarget)
|
||||
endif(result)
|
||||
endforeach(label)
|
||||
if(PARSE_CATCH_TESTS_NO_HIDDEN_TESTS AND ${HiddenTagFound} AND ${CMAKE_VERSION} VERSION_LESS "3.9")
|
||||
PrintDebugMessage("Skipping test \"${CTestName}\" as it has [!hide], [.] or [.foo] label")
|
||||
ParseAndAddCatchTests_PrintDebugMessage("Skipping test \"${CTestName}\" as it has [!hide], [.] or [.foo] label")
|
||||
else()
|
||||
PrintDebugMessage("Adding test \"${CTestName}\"")
|
||||
ParseAndAddCatchTests_PrintDebugMessage("Adding test \"${CTestName}\"")
|
||||
if(Labels)
|
||||
PrintDebugMessage("Setting labels to ${Labels}")
|
||||
ParseAndAddCatchTests_PrintDebugMessage("Setting labels to ${Labels}")
|
||||
endif()
|
||||
|
||||
# Escape commas in the test spec
|
||||
string(REPLACE "," "\\," Name ${Name})
|
||||
|
||||
# Add the test and set its properties
|
||||
add_test(NAME "\"${CTestName}\"" COMMAND ${OptionalCatchTestLauncher} ${TestTarget} ${Name} ${AdditionalCatchParameters})
|
||||
add_test(NAME "\"${CTestName}\"" COMMAND ${OptionalCatchTestLauncher} $<TARGET_FILE:${TestTarget}> ${Name} ${AdditionalCatchParameters})
|
||||
# Old CMake versions do not document VERSION_GREATER_EQUAL, so we use VERSION_GREATER with 3.8 instead
|
||||
if(PARSE_CATCH_TESTS_NO_HIDDEN_TESTS AND ${HiddenTagFound} AND ${CMAKE_VERSION} VERSION_GREATER "3.8")
|
||||
PrintDebugMessage("Setting DISABLED test property")
|
||||
ParseAndAddCatchTests_PrintDebugMessage("Setting DISABLED test property")
|
||||
set_tests_properties("\"${CTestName}\"" PROPERTIES DISABLED ON)
|
||||
else()
|
||||
set_tests_properties("\"${CTestName}\"" PROPERTIES FAIL_REGULAR_EXPRESSION "No tests ran"
|
||||
LABELS "${Labels}")
|
||||
endif()
|
||||
set_property(
|
||||
TARGET ${TestTarget}
|
||||
APPEND
|
||||
PROPERTY ParseAndAddCatchTests_TESTS "\"${CTestName}\"")
|
||||
set_property(
|
||||
SOURCE ${SourceFile}
|
||||
APPEND
|
||||
PROPERTY ParseAndAddCatchTests_TESTS "\"${CTestName}\"")
|
||||
endif()
|
||||
|
||||
|
||||
@@ -193,11 +215,11 @@ endfunction()
|
||||
|
||||
# entry point
|
||||
function(ParseAndAddCatchTests TestTarget)
|
||||
PrintDebugMessage("Started parsing ${TestTarget}")
|
||||
ParseAndAddCatchTests_PrintDebugMessage("Started parsing ${TestTarget}")
|
||||
get_target_property(SourceFiles ${TestTarget} SOURCES)
|
||||
PrintDebugMessage("Found the following sources: ${SourceFiles}")
|
||||
ParseAndAddCatchTests_PrintDebugMessage("Found the following sources: ${SourceFiles}")
|
||||
foreach(SourceFile ${SourceFiles})
|
||||
ParseFile(${SourceFile} ${TestTarget})
|
||||
ParseAndAddCatchTests_ParseFile(${SourceFile} ${TestTarget})
|
||||
endforeach()
|
||||
PrintDebugMessage("Finished parsing ${TestTarget}")
|
||||
ParseAndAddCatchTests_PrintDebugMessage("Finished parsing ${TestTarget}")
|
||||
endfunction()
|
||||
|
@@ -27,7 +27,7 @@
|
||||
[Override output colouring](#override-output-colouring)<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.
|
||||
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 following links to take you straight to that option - or scroll on to browse the available options.
|
||||
|
||||
<a href="#specifying-which-tests-to-run"> ` <test-spec> ...`</a><br />
|
||||
<a href="#usage"> ` -h, -?, --help`</a><br />
|
||||
|
@@ -89,7 +89,7 @@ them yourself, their signatures are:
|
||||
By default, when Catch's stringification machinery has to stringify
|
||||
a type that does not specialize `StringMaker`, does not overload `operator<<`,
|
||||
is not an enumeration and is not a range, it uses `"{?}"`. This can be
|
||||
overriden by defining `CATCH_CONFIG_FALLBACK_STRINGIFIER` to name of a
|
||||
overridden by defining `CATCH_CONFIG_FALLBACK_STRINGIFIER` to name of a
|
||||
function that should perform the stringification instead.
|
||||
|
||||
All types that do not provide `StringMaker` specialization or `operator<<`
|
||||
|
@@ -75,8 +75,34 @@ before you do so, you need to check that the introduced changes are indeed
|
||||
intentional.
|
||||
|
||||
|
||||
## Code constructs to watch out for
|
||||
|
||||
*this document is still in-progress...*
|
||||
This section is a (sadly incomplete) listing of various constructs that
|
||||
are problematic and are not always caught by our CI infrastructure.
|
||||
|
||||
### Naked exceptions and exceptions-related function
|
||||
|
||||
If you are throwing an exception, it should be done via `CATCH_ERROR`
|
||||
or `CATCH_RUNTIME_ERROR` in `catch_enforce.h`. These macros will handle
|
||||
the differences between compilation with or without exceptions for you.
|
||||
However, some platforms (IAR) also have problems with exceptions-related
|
||||
functions, such as `std::current_exceptions`. We do not have IAR in our
|
||||
CI, but luckily there should not be too many reasons to use these.
|
||||
However, if you do, they should be kept behind a
|
||||
`CATCH_CONFIG_DISABLE_EXCEPTIONS` macro.
|
||||
|
||||
### Unqualified usage of functions from C's stdlib
|
||||
|
||||
If you are using a function from C's stdlib, please include the header
|
||||
as `<cfoo>` and call the function qualified. The common knowledge that
|
||||
there is no difference is wrong, QNX and VxWorks won't compile if you
|
||||
include the header as `<cfoo>` and call the function unqualified.
|
||||
|
||||
|
||||
----
|
||||
|
||||
_This documentation will always be in-progress as new information comes
|
||||
up, but we are trying to keep it as up to date as possible._
|
||||
|
||||
---
|
||||
|
||||
|
@@ -29,13 +29,13 @@ struct MyListener : Catch::TestEventListenerBase {
|
||||
|
||||
using TestEventListenerBase::TestEventListenerBase; // inherit constructor
|
||||
|
||||
virtual void testCaseStarting( Catch::TestCaseInfo const& testInfo ) override {
|
||||
void testCaseStarting( Catch::TestCaseInfo const& testInfo ) override {
|
||||
// Perform some setup before a test case is run
|
||||
}
|
||||
|
||||
virtual void testCaseEnded( Catch::TestCaseStats const& testCaseStats ) override {
|
||||
void testCaseEnded( Catch::TestCaseStats const& testCaseStats ) override {
|
||||
// Tear-down after a test case is run
|
||||
}
|
||||
}
|
||||
};
|
||||
CATCH_REGISTER_LISTENER( MyListener )
|
||||
```
|
||||
|
@@ -85,7 +85,7 @@ Second unscoped info
|
||||
|
||||
## Streaming macros
|
||||
|
||||
All these macros allow heterogenous sequences of values to be streaming using the insertion operator (```<<```) in the same way that std::ostream, std::cout, etc support it.
|
||||
All these macros allow heterogeneous sequences of values to be streaming using the insertion operator (```<<```) in the same way that std::ostream, std::cout, etc support it.
|
||||
|
||||
E.g.:
|
||||
```c++
|
||||
|
@@ -92,7 +92,7 @@ public:
|
||||
IntRange( int begin, int end ) : m_begin( begin ), m_end( end ) {}
|
||||
|
||||
// Performs the test for this matcher
|
||||
virtual bool match( int const& i ) const override {
|
||||
bool match( int const& i ) const override {
|
||||
return i >= m_begin && i <= m_end;
|
||||
}
|
||||
|
||||
|
@@ -30,7 +30,7 @@ CHECKED_IF( a == b ) {
|
||||
|
||||
`CHECK_NOFAIL( expr )` is a variant of `CHECK` that does not fail the test
|
||||
case if _expr_ evaluates to `false`. This can be useful for checking some
|
||||
assumption, that might be violated without the test neccessarily failing.
|
||||
assumption, that might be violated without the test necessarily failing.
|
||||
|
||||
Example output:
|
||||
```
|
||||
@@ -120,7 +120,7 @@ constructor, or before Catch2's session is created in user's own main._
|
||||
`ANON_TEST_CASE` is a `TEST_CASE` replacement that will autogenerate
|
||||
unique name. The advantage of this is that you do not have to think
|
||||
of a name for the test case,`the disadvantage is that the name doesn't
|
||||
neccessarily remain stable across different links, and thus it might be
|
||||
necessarily remain stable across different links, and thus it might be
|
||||
hard to run directly.
|
||||
|
||||
Example:
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
# Release notes
|
||||
**Contents**<br>
|
||||
[2.7.2](#272)<br>
|
||||
[2.7.1](#271)<br>
|
||||
[2.7.0](#270)<br>
|
||||
[2.6.1](#261)<br>
|
||||
@@ -22,6 +23,28 @@
|
||||
[Older versions](#older-versions)<br>
|
||||
[Even Older versions](#even-older-versions)<br>
|
||||
|
||||
|
||||
## 2.7.2
|
||||
|
||||
### Improvements
|
||||
* Added an approximate vector matcher (#1499)
|
||||
|
||||
### Fixes
|
||||
* Filters will no longer be shown if there were none
|
||||
* Fixed compilation error when using Homebrew GCC on OS X (#1588, #1589)
|
||||
* Fixed the console reporter not showing messages that start with a newline (#1455, #1470)
|
||||
* Modified JUnit reporter's output so that rng seed and filters are reported according to the JUnit schema (#1598)
|
||||
* Fixed some obscure warnings and static analysis passes
|
||||
|
||||
### Miscellaneous
|
||||
* Various improvements to `ParseAndAddCatchTests` (#1559, #1601)
|
||||
* When a target is parsed, it receives `ParseAndAddCatchTests_TESTS` property which summarizes found tests
|
||||
* Fixed problem with tests not being found if the `OptionalCatchTestLauncher` variables is used
|
||||
* Including the script will no longer forcefully modify `CMAKE_MINIMUM_REQUIRED_VERSION`
|
||||
* CMake object libraries are ignored when parsing to avoid needless warnings
|
||||
* `CatchAddTests` now adds test's tags to their CTest labels (#1600)
|
||||
* Added basic CPack support to our build
|
||||
|
||||
## 2.7.1
|
||||
|
||||
### Improvements
|
||||
@@ -56,7 +79,7 @@
|
||||
* Running tests will no longer open the specified output file twice (#1545)
|
||||
* This would cause trouble when the file was not a file, but rather a named pipe
|
||||
* Fixes the CLion/Resharper integration with Catch
|
||||
* Fixed `-Wunreachable-code` occuring with (old) ccache+cmake+clang combination (#1540)
|
||||
* Fixed `-Wunreachable-code` occurring with (old) ccache+cmake+clang combination (#1540)
|
||||
* Fixed `-Wdefaulted-function-deleted` warning with Clang 8 (#1537)
|
||||
* Catch2's type traits and helpers are now properly namespaced inside `Catch::` (#1548)
|
||||
* Fixed std{out,err} redirection for failing test (#1514, #1525)
|
||||
@@ -738,7 +761,7 @@ Cygwin issue with `gettimeofday` - `#define` was not early enough
|
||||
* Usage of `gettimeofday` inside Catch should no longer cause compilation errors.
|
||||
* Improved `-Wparentheses` suppression for gcc (#674)
|
||||
* When compiled with gcc 4.8 or newer, the suppression is localized to assertions only
|
||||
* Otherwise it is supressed for the whole TU
|
||||
* Otherwise it is suppressed for the whole TU
|
||||
* Fixed test spec parser issue (with escapes in multiple names)
|
||||
|
||||
##### Other
|
||||
@@ -821,7 +844,7 @@ Other:
|
||||
|
||||
##### Other:
|
||||
* Types with overloaded `&&` operator are no longer evaluated twice when used in an assertion macro.
|
||||
* The use of `__COUNTER__` is supressed when Catch is parsed by CLion
|
||||
* The use of `__COUNTER__` is suppressed when Catch is parsed by CLion
|
||||
* This change is not active when compiling a binary
|
||||
* Approval tests can now be run on Windows
|
||||
* CMake will now warn if a file is present in the `include` folder but not is not enumerated as part of the project
|
||||
|
@@ -32,7 +32,7 @@ Once a release is ready, release notes need to be written. They should summarize
|
||||
|
||||
### Commit and push update to GitHub
|
||||
|
||||
After version number is incremented, single-include header is regenerated and release notes are updated, changes should be commited and pushed to GitHub.
|
||||
After version number is incremented, single-include header is regenerated and release notes are updated, changes should be committed and pushed to GitHub.
|
||||
|
||||
|
||||
### Release on GitHub
|
||||
|
@@ -305,7 +305,7 @@ struct MyListener : Catch::TestEventListenerBase {
|
||||
~MyListener();
|
||||
|
||||
// The whole test run starting
|
||||
virtual void testRunStarting( Catch::TestRunInfo const& testRunInfo ) override {
|
||||
void testRunStarting( Catch::TestRunInfo const& testRunInfo ) override {
|
||||
std::cout
|
||||
<< std::boolalpha
|
||||
<< "\nEvent: testRunStarting:\n";
|
||||
@@ -313,7 +313,7 @@ struct MyListener : Catch::TestEventListenerBase {
|
||||
}
|
||||
|
||||
// The whole test run ending
|
||||
virtual void testRunEnded( Catch::TestRunStats const& testRunStats ) override {
|
||||
void testRunEnded( Catch::TestRunStats const& testRunStats ) override {
|
||||
std::cout
|
||||
<< dashed_line
|
||||
<< "\nEvent: testRunEnded:\n";
|
||||
@@ -321,7 +321,7 @@ struct MyListener : Catch::TestEventListenerBase {
|
||||
}
|
||||
|
||||
// A test is being skipped (because it is "hidden")
|
||||
virtual void skipTest( Catch::TestCaseInfo const& testInfo ) override {
|
||||
void skipTest( Catch::TestCaseInfo const& testInfo ) override {
|
||||
std::cout
|
||||
<< dashed_line
|
||||
<< "\nEvent: skipTest:\n";
|
||||
@@ -329,7 +329,7 @@ struct MyListener : Catch::TestEventListenerBase {
|
||||
}
|
||||
|
||||
// Test cases starting
|
||||
virtual void testCaseStarting( Catch::TestCaseInfo const& testInfo ) override {
|
||||
void testCaseStarting( Catch::TestCaseInfo const& testInfo ) override {
|
||||
std::cout
|
||||
<< dashed_line
|
||||
<< "\nEvent: testCaseStarting:\n";
|
||||
@@ -337,30 +337,30 @@ struct MyListener : Catch::TestEventListenerBase {
|
||||
}
|
||||
|
||||
// Test cases ending
|
||||
virtual void testCaseEnded( Catch::TestCaseStats const& testCaseStats ) override {
|
||||
void testCaseEnded( Catch::TestCaseStats const& testCaseStats ) override {
|
||||
std::cout << "\nEvent: testCaseEnded:\n";
|
||||
print( std::cout, 1, "testCaseStats", testCaseStats );
|
||||
}
|
||||
|
||||
// Sections starting
|
||||
virtual void sectionStarting( Catch::SectionInfo const& sectionInfo ) override {
|
||||
void sectionStarting( Catch::SectionInfo const& sectionInfo ) override {
|
||||
std::cout << "\nEvent: sectionStarting:\n";
|
||||
print( std::cout, 1, "- sectionInfo", sectionInfo );
|
||||
}
|
||||
|
||||
// Sections ending
|
||||
virtual void sectionEnded( Catch::SectionStats const& sectionStats ) override {
|
||||
void sectionEnded( Catch::SectionStats const& sectionStats ) override {
|
||||
std::cout << "\nEvent: sectionEnded:\n";
|
||||
print( std::cout, 1, "- sectionStats", sectionStats );
|
||||
}
|
||||
|
||||
// Assertions before/ after
|
||||
virtual void assertionStarting( Catch::AssertionInfo const& assertionInfo ) override {
|
||||
void assertionStarting( Catch::AssertionInfo const& assertionInfo ) override {
|
||||
std::cout << "\nEvent: assertionStarting:\n";
|
||||
print( std::cout, 1, "- assertionInfo", assertionInfo );
|
||||
}
|
||||
|
||||
virtual bool assertionEnded( Catch::AssertionStats const& assertionStats ) override {
|
||||
bool assertionEnded( Catch::AssertionStats const& assertionStats ) override {
|
||||
std::cout << "\nEvent: assertionEnded:\n";
|
||||
print( std::cout, 1, "- assertionStats", assertionStats );
|
||||
return true;
|
||||
|
@@ -11,7 +11,7 @@
|
||||
|
||||
#define CATCH_VERSION_MAJOR 2
|
||||
#define CATCH_VERSION_MINOR 7
|
||||
#define CATCH_VERSION_PATCH 1
|
||||
#define CATCH_VERSION_PATCH 2
|
||||
|
||||
#ifdef __clang__
|
||||
# pragma clang system_header
|
||||
|
3
include/external/clara.hpp
vendored
3
include/external/clara.hpp
vendored
@@ -111,6 +111,9 @@ public:
|
||||
m_suffix = false;
|
||||
auto width = m_column.m_width - indent();
|
||||
m_end = m_pos;
|
||||
if (line()[m_pos] == '\n') {
|
||||
++m_end;
|
||||
}
|
||||
while (m_end < line().size() && line()[m_end] != '\n')
|
||||
++m_end;
|
||||
|
||||
|
@@ -55,18 +55,18 @@ namespace Detail {
|
||||
return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
|
||||
}
|
||||
|
||||
void Approx::setMargin(double margin) {
|
||||
CATCH_ENFORCE(margin >= 0,
|
||||
"Invalid Approx::margin: " << margin << '.'
|
||||
void Approx::setMargin(double newMargin) {
|
||||
CATCH_ENFORCE(newMargin >= 0,
|
||||
"Invalid Approx::margin: " << newMargin << '.'
|
||||
<< " Approx::Margin has to be non-negative.");
|
||||
m_margin = margin;
|
||||
m_margin = newMargin;
|
||||
}
|
||||
|
||||
void Approx::setEpsilon(double epsilon) {
|
||||
CATCH_ENFORCE(epsilon >= 0 && epsilon <= 1.0,
|
||||
"Invalid Approx::epsilon: " << epsilon << '.'
|
||||
void Approx::setEpsilon(double newEpsilon) {
|
||||
CATCH_ENFORCE(newEpsilon >= 0 && newEpsilon <= 1.0,
|
||||
"Invalid Approx::epsilon: " << newEpsilon << '.'
|
||||
<< " Approx::epsilon has to be in [0, 1]");
|
||||
m_epsilon = epsilon;
|
||||
m_epsilon = newEpsilon;
|
||||
}
|
||||
|
||||
} // end namespace Detail
|
||||
|
@@ -16,10 +16,7 @@ namespace Catch {
|
||||
m_stream( openStream() )
|
||||
{
|
||||
TestSpecParser parser(ITagAliasRegistry::get());
|
||||
if (data.testsOrTags.empty()) {
|
||||
parser.parse("~[.]"); // All not hidden tests
|
||||
}
|
||||
else {
|
||||
if (!data.testsOrTags.empty()) {
|
||||
m_hasTestFilters = true;
|
||||
for( auto const& testOrTags : data.testsOrTags )
|
||||
parser.parse( testOrTags );
|
||||
|
@@ -85,7 +85,7 @@ namespace Catch {
|
||||
std::vector<std::string> const& getTestsOrTags() const override;
|
||||
std::vector<std::string> const& getSectionsToRun() const override;
|
||||
|
||||
virtual TestSpec const& testSpec() const override;
|
||||
TestSpec const& testSpec() const override;
|
||||
bool hasTestFilters() const override;
|
||||
|
||||
bool showHelp() const;
|
||||
|
@@ -69,7 +69,7 @@ namespace {
|
||||
originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
|
||||
}
|
||||
|
||||
virtual void use( Colour::Code _colourCode ) override {
|
||||
void use( Colour::Code _colourCode ) override {
|
||||
switch( _colourCode ) {
|
||||
case Colour::None: return setTextAttribute( originalForegroundAttributes );
|
||||
case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
|
||||
@@ -132,7 +132,7 @@ namespace {
|
||||
// https://github.com/philsquared/Catch/pull/131
|
||||
class PosixColourImpl : public IColourImpl {
|
||||
public:
|
||||
virtual void use( Colour::Code _colourCode ) override {
|
||||
void use( Colour::Code _colourCode ) override {
|
||||
switch( _colourCode ) {
|
||||
case Colour::None:
|
||||
case Colour::White: return setColour( "[0m" );
|
||||
|
@@ -13,27 +13,27 @@ namespace Catch {
|
||||
class Context : public IMutableContext, NonCopyable {
|
||||
|
||||
public: // IContext
|
||||
virtual IResultCapture* getResultCapture() override {
|
||||
IResultCapture* getResultCapture() override {
|
||||
return m_resultCapture;
|
||||
}
|
||||
virtual IRunner* getRunner() override {
|
||||
IRunner* getRunner() override {
|
||||
return m_runner;
|
||||
}
|
||||
|
||||
virtual IConfigPtr const& getConfig() const override {
|
||||
IConfigPtr const& getConfig() const override {
|
||||
return m_config;
|
||||
}
|
||||
|
||||
virtual ~Context() override;
|
||||
~Context() override;
|
||||
|
||||
public: // IMutableContext
|
||||
virtual void setResultCapture( IResultCapture* resultCapture ) override {
|
||||
void setResultCapture( IResultCapture* resultCapture ) override {
|
||||
m_resultCapture = resultCapture;
|
||||
}
|
||||
virtual void setRunner( IRunner* runner ) override {
|
||||
void setRunner( IRunner* runner ) override {
|
||||
m_runner = runner;
|
||||
}
|
||||
virtual void setConfig( IConfigPtr const& config ) override {
|
||||
void setConfig( IConfigPtr const& config ) override {
|
||||
m_config = config;
|
||||
}
|
||||
|
||||
|
@@ -18,19 +18,23 @@
|
||||
# include <stdbool.h>
|
||||
# include <sys/types.h>
|
||||
# include <unistd.h>
|
||||
# include <sys/sysctl.h>
|
||||
# include <cstddef>
|
||||
# include <ostream>
|
||||
|
||||
namespace Catch {
|
||||
#ifdef __apple_build_version__
|
||||
// These headers will only compile with AppleClang (XCode)
|
||||
// For other compilers (Clang, GCC, ... ) we need to exclude them
|
||||
# include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
namespace Catch {
|
||||
#ifdef __apple_build_version__
|
||||
// The following function is taken directly from the following technical note:
|
||||
// http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
|
||||
// https://developer.apple.com/library/archive/qa/qa1361/_index.html
|
||||
|
||||
// Returns true if the current process is being debugged (either
|
||||
// running under the debugger or has a debugger attached post facto).
|
||||
bool isDebuggerActive(){
|
||||
|
||||
int mib[4];
|
||||
struct kinfo_proc info;
|
||||
std::size_t size;
|
||||
@@ -60,6 +64,12 @@ namespace Catch {
|
||||
|
||||
return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
|
||||
}
|
||||
#else
|
||||
bool isDebuggerActive() {
|
||||
// We need to find another way to determine this for non-appleclang compilers on macOS
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
} // namespace Catch
|
||||
|
||||
#elif defined(CATCH_PLATFORM_LINUX)
|
||||
|
@@ -19,7 +19,7 @@ namespace Catch {
|
||||
public:
|
||||
~ExceptionTranslatorRegistry();
|
||||
virtual void registerTranslator( const IExceptionTranslator* translator );
|
||||
virtual std::string translateActiveException() const override;
|
||||
std::string translateActiveException() const override;
|
||||
std::string tryTranslators() const;
|
||||
|
||||
private:
|
||||
|
@@ -45,7 +45,7 @@ public:
|
||||
|
||||
// The following functions create the actual matcher objects.
|
||||
// The user has to explicitly specify type to the function, because
|
||||
// infering std::function<bool(T const&)> is hard (but possible) and
|
||||
// inferring std::function<bool(T const&)> is hard (but possible) and
|
||||
// requires a lot of TMP.
|
||||
template<typename T>
|
||||
Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") {
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#define TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
|
||||
|
||||
#include "catch_matchers.h"
|
||||
#include "catch_approx.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -16,28 +17,6 @@ namespace Catch {
|
||||
namespace Matchers {
|
||||
|
||||
namespace Vector {
|
||||
namespace Detail {
|
||||
template <typename InputIterator, typename T>
|
||||
size_t count(InputIterator first, InputIterator last, T const& item) {
|
||||
size_t cnt = 0;
|
||||
for (; first != last; ++first) {
|
||||
if (*first == item) {
|
||||
++cnt;
|
||||
}
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
template <typename InputIterator, typename T>
|
||||
bool contains(InputIterator first, InputIterator last, T const& item) {
|
||||
for (; first != last; ++first) {
|
||||
if (*first == item) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct ContainsElementMatcher : MatcherBase<std::vector<T>> {
|
||||
|
||||
@@ -112,6 +91,42 @@ namespace Matchers {
|
||||
std::vector<T> const& m_comparator;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ApproxMatcher : MatcherBase<std::vector<T>> {
|
||||
|
||||
ApproxMatcher(std::vector<T> const& comparator) : m_comparator( comparator ) {}
|
||||
|
||||
bool match(std::vector<T> const &v) const override {
|
||||
if (m_comparator.size() != v.size())
|
||||
return false;
|
||||
for (std::size_t i = 0; i < v.size(); ++i)
|
||||
if (m_comparator[i] != approx(v[i]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
std::string describe() const override {
|
||||
return "is approx: " + ::Catch::Detail::stringify( m_comparator );
|
||||
}
|
||||
template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||
ApproxMatcher& epsilon( T const& newEpsilon ) {
|
||||
approx.epsilon(newEpsilon);
|
||||
return *this;
|
||||
}
|
||||
template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||
ApproxMatcher& margin( T const& newMargin ) {
|
||||
approx.margin(newMargin);
|
||||
return *this;
|
||||
}
|
||||
template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||
ApproxMatcher& scale( T const& newScale ) {
|
||||
approx.scale(newScale);
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::vector<T> const& m_comparator;
|
||||
mutable Catch::Detail::Approx approx = Catch::Detail::Approx::custom();
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> {
|
||||
UnorderedEqualsMatcher(std::vector<T> const& target) : m_target(target) {}
|
||||
@@ -121,28 +136,7 @@ namespace Matchers {
|
||||
if (m_target.size() != vec.size()) {
|
||||
return false;
|
||||
}
|
||||
auto lfirst = m_target.begin(), llast = m_target.end();
|
||||
auto rfirst = vec.begin(), rlast = vec.end();
|
||||
// Cut common prefix to optimize checking of permuted parts
|
||||
while (lfirst != llast && *lfirst == *rfirst) {
|
||||
++lfirst; ++rfirst;
|
||||
}
|
||||
if (lfirst == llast) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (auto mid = lfirst; mid != llast; ++mid) {
|
||||
// Skip already counted items
|
||||
if (Detail::contains(lfirst, mid, *mid)) {
|
||||
continue;
|
||||
}
|
||||
size_t num_vec = Detail::count(rfirst, rlast, *mid);
|
||||
if (num_vec == 0 || Detail::count(lfirst, llast, *mid) != num_vec) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
|
||||
}
|
||||
|
||||
std::string describe() const override {
|
||||
@@ -172,6 +166,11 @@ namespace Matchers {
|
||||
return Vector::EqualsMatcher<T>( comparator );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Vector::ApproxMatcher<T> Approx( std::vector<T> const& comparator ) {
|
||||
return Vector::ApproxMatcher<T>( comparator );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const& target) {
|
||||
return Vector::UnorderedEqualsMatcher<T>(target);
|
||||
|
@@ -71,7 +71,7 @@ namespace Catch {
|
||||
if (strerror_s(buffer, errno)) {
|
||||
CATCH_RUNTIME_ERROR("Could not translate errno to a string");
|
||||
}
|
||||
CATCH_RUNTIME_ERROR("Coul dnot open the temp file: '" << m_buffer << "' because: " << buffer);
|
||||
CATCH_RUNTIME_ERROR("Could not open the temp file: '" << m_buffer << "' because: " << buffer);
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
@@ -18,11 +18,11 @@ namespace Catch {
|
||||
|
||||
class ReporterFactory : public IReporterFactory {
|
||||
|
||||
virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override {
|
||||
IStreamingReporterPtr create( ReporterConfig const& config ) const override {
|
||||
return std::unique_ptr<T>( new T( config ) );
|
||||
}
|
||||
|
||||
virtual std::string getDescription() const override {
|
||||
std::string getDescription() const override {
|
||||
return T::getDescription();
|
||||
}
|
||||
};
|
||||
@@ -39,10 +39,10 @@ namespace Catch {
|
||||
|
||||
class ListenerFactory : public IReporterFactory {
|
||||
|
||||
virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override {
|
||||
IStreamingReporterPtr create( ReporterConfig const& config ) const override {
|
||||
return std::unique_ptr<T>( new T( config ) );
|
||||
}
|
||||
virtual std::string getDescription() const override {
|
||||
std::string getDescription() const override {
|
||||
return std::string();
|
||||
}
|
||||
};
|
||||
|
@@ -72,7 +72,10 @@ namespace Catch {
|
||||
|
||||
auto const& allTestCases = getAllTestCasesSorted(*config);
|
||||
for (auto const& testCase : allTestCases) {
|
||||
if (!context.aborting() && matchTest(testCase, testSpec, *config))
|
||||
bool matching = (!testSpec.hasFilters() && !testCase.isHidden()) ||
|
||||
(testSpec.hasFilters() && matchTest(testCase, testSpec, *config));
|
||||
|
||||
if (!context.aborting() && matching)
|
||||
totals += context.runTest(testCase);
|
||||
else
|
||||
context.reporter().skipTest(testCase);
|
||||
|
@@ -43,7 +43,7 @@ namespace Catch {
|
||||
void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
|
||||
CATCH_ENFORCE( !isReservedTag(tag),
|
||||
"Tag name: [" << tag << "] is not allowed.\n"
|
||||
<< "Tag names starting with non alpha-numeric characters are reserved\n"
|
||||
<< "Tag names starting with non alphanumeric characters are reserved\n"
|
||||
<< _lineInfo );
|
||||
}
|
||||
}
|
||||
|
@@ -54,9 +54,12 @@ namespace Catch {
|
||||
std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
|
||||
std::vector<TestCase> filtered;
|
||||
filtered.reserve( testCases.size() );
|
||||
for( auto const& testCase : testCases )
|
||||
if( matchTest( testCase, testSpec, config ) )
|
||||
filtered.push_back( testCase );
|
||||
for (auto const& testCase : testCases) {
|
||||
if ((!testSpec.hasFilters() && !testCase.isHidden()) ||
|
||||
(testSpec.hasFilters() && matchTest(testCase, testSpec, config))) {
|
||||
filtered.push_back(testCase);
|
||||
}
|
||||
}
|
||||
return filtered;
|
||||
}
|
||||
std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
|
||||
|
@@ -32,11 +32,6 @@ namespace TestCaseTracking {
|
||||
ITracker::~ITracker() = default;
|
||||
|
||||
|
||||
TrackerContext& TrackerContext::instance() {
|
||||
static TrackerContext s_instance;
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
ITracker& TrackerContext::startRun() {
|
||||
m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr );
|
||||
m_currentTracker = nullptr;
|
||||
|
@@ -71,8 +71,6 @@ namespace TestCaseTracking {
|
||||
|
||||
public:
|
||||
|
||||
static TrackerContext& instance();
|
||||
|
||||
ITracker& startRun();
|
||||
void endRun();
|
||||
|
||||
|
@@ -33,7 +33,7 @@ namespace Catch {
|
||||
public:
|
||||
NamePattern( std::string const& name );
|
||||
virtual ~NamePattern();
|
||||
virtual bool matches( TestCaseInfo const& testCase ) const override;
|
||||
bool matches( TestCaseInfo const& testCase ) const override;
|
||||
private:
|
||||
WildcardPattern m_wildcardPattern;
|
||||
};
|
||||
@@ -42,7 +42,7 @@ namespace Catch {
|
||||
public:
|
||||
TagPattern( std::string const& tag );
|
||||
virtual ~TagPattern();
|
||||
virtual bool matches( TestCaseInfo const& testCase ) const override;
|
||||
bool matches( TestCaseInfo const& testCase ) const override;
|
||||
private:
|
||||
std::string m_tag;
|
||||
};
|
||||
@@ -51,7 +51,7 @@ namespace Catch {
|
||||
public:
|
||||
ExcludedPattern( PatternPtr const& underlyingPattern );
|
||||
virtual ~ExcludedPattern();
|
||||
virtual bool matches( TestCaseInfo const& testCase ) const override;
|
||||
bool matches( TestCaseInfo const& testCase ) const override;
|
||||
private:
|
||||
PatternPtr m_underlyingPattern;
|
||||
};
|
||||
|
@@ -37,7 +37,7 @@ namespace Catch {
|
||||
}
|
||||
|
||||
Version const& libraryVersion() {
|
||||
static Version version( 2, 7, 1, "", 0 );
|
||||
static Version version( 2, 7, 2, "", 0 );
|
||||
return version;
|
||||
}
|
||||
|
||||
|
@@ -76,22 +76,6 @@ namespace Catch {
|
||||
void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) {
|
||||
CumulativeReporterBase::testRunStarting( runInfo );
|
||||
xml.startElement( "testsuites" );
|
||||
|
||||
if ( m_config->hasTestFilters() || m_config->rngSeed() != 0 )
|
||||
xml.startElement("properties");
|
||||
|
||||
if ( m_config->hasTestFilters() ) {
|
||||
xml.scopedElement( "property" )
|
||||
.writeAttribute( "name" , "filters" )
|
||||
.writeAttribute( "value" , serializeFilters( m_config->getTestsOrTags() ) );
|
||||
}
|
||||
|
||||
if( m_config->rngSeed() != 0 ) {
|
||||
xml.scopedElement( "property" )
|
||||
.writeAttribute( "name", "random-seed" )
|
||||
.writeAttribute( "value", m_config->rngSeed() );
|
||||
xml.endElement();
|
||||
}
|
||||
}
|
||||
|
||||
void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {
|
||||
@@ -130,6 +114,7 @@ namespace Catch {
|
||||
|
||||
void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
|
||||
XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
|
||||
|
||||
TestGroupStats const& stats = groupNode.value;
|
||||
xml.writeAttribute( "name", stats.groupInfo.name );
|
||||
xml.writeAttribute( "errors", unexpectedExceptions );
|
||||
@@ -142,6 +127,21 @@ namespace Catch {
|
||||
xml.writeAttribute( "time", suiteTime );
|
||||
xml.writeAttribute( "timestamp", getCurrentTimestamp() );
|
||||
|
||||
// Write properties if there are any
|
||||
if (m_config->hasTestFilters() || m_config->rngSeed() != 0) {
|
||||
auto properties = xml.scopedElement("properties");
|
||||
if (m_config->hasTestFilters()) {
|
||||
xml.scopedElement("property")
|
||||
.writeAttribute("name", "filters")
|
||||
.writeAttribute("value", serializeFilters(m_config->getTestsOrTags()));
|
||||
}
|
||||
if (m_config->rngSeed() != 0) {
|
||||
xml.scopedElement("property")
|
||||
.writeAttribute("name", "random-seed")
|
||||
.writeAttribute("value", m_config->rngSeed());
|
||||
}
|
||||
}
|
||||
|
||||
// Write test cases
|
||||
for( auto const& child : groupNode.children )
|
||||
writeTestCase( *child );
|
||||
|
@@ -322,6 +322,9 @@ endif()
|
||||
|
||||
# configure unit tests via CTest
|
||||
add_test(NAME RunTests COMMAND $<TARGET_FILE:SelfTest>)
|
||||
set_tests_properties(RunTests PROPERTIES
|
||||
FAIL_REGULAR_EXPRESSION "Filters:"
|
||||
)
|
||||
|
||||
add_test(NAME ListTests COMMAND $<TARGET_FILE:SelfTest> --list-tests --verbosity high)
|
||||
set_tests_properties(ListTests PROPERTIES
|
||||
|
@@ -14,6 +14,9 @@ Compilation.tests.cpp:<line number>: passed: std::memcmp(uarr, "123", sizeof(uar
|
||||
Compilation.tests.cpp:<line number>: passed: std::memcmp(sarr, "456", sizeof(sarr)) == 0 for: 0 == 0 with 2 messages: 'uarr := "123"' and 'sarr := "456"'
|
||||
Compilation.tests.cpp:<line number>: passed:
|
||||
Compilation.tests.cpp:<line number>: passed: h1 == h2 for: [1403 helper] == [1403 helper]
|
||||
Message.tests.cpp:<line number>: warning: '
|
||||
This info message starts with a linebreak' with 1 message: '
|
||||
This warning message starts with a linebreak'
|
||||
This would not be caught previously
|
||||
Nor would this
|
||||
Tricky.tests.cpp:<line number>: failed: explicitly with 1 message: '1514'
|
||||
@@ -323,9 +326,9 @@ Matchers.tests.cpp:<line number>: passed: testStringForMatching(), Equals("this
|
||||
Matchers.tests.cpp:<line number>: passed: testStringForMatching(), Equals("this string contains 'ABC' as a substring", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" equals: "this string contains 'abc' as a substring" (case insensitive)
|
||||
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Equals("this string contains 'ABC' as a substring") for: "this string contains 'abc' as a substring" equals: "this string contains 'ABC' as a substring"
|
||||
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Equals("something else", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" equals: "something else" (case insensitive)
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(WhatException{}) == "This exception has overriden what() method" for: "This exception has overriden what() method"
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(WhatException{}) == "This exception has overridden what() method" for: "This exception has overridden what() method"
|
||||
==
|
||||
"This exception has overriden what() method"
|
||||
"This exception has overridden what() method"
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(OperatorException{}) == "OperatorException" for: "OperatorException" == "OperatorException"
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(StringMakerException{}) == "StringMakerException" for: "StringMakerException"
|
||||
==
|
||||
@@ -1186,6 +1189,15 @@ Approx.tests.cpp:<line number>: passed: approx( d ) == 1.22 for: Approx( 1.23 )
|
||||
Approx.tests.cpp:<line number>: passed: approx( d ) == 1.24 for: Approx( 1.23 ) == 1.24
|
||||
Approx.tests.cpp:<line number>: passed: approx( d ) != 1.25 for: Approx( 1.23 ) != 1.25
|
||||
VariadicMacros.tests.cpp:<line number>: passed: with 1 message: 'no assertions'
|
||||
Matchers.tests.cpp:<line number>: passed: empty, Approx(empty) for: { } is approx: { }
|
||||
Matchers.tests.cpp:<line number>: passed: v1, Approx(v1) for: { 1.0, 2.0, 3.0 } is approx: { 1.0, 2.0, 3.0 }
|
||||
Matchers.tests.cpp:<line number>: passed: v1, !Approx(temp) for: { 1.0, 2.0, 3.0 } not is approx: { 1.0, 2.0, 3.0, 4.0 }
|
||||
Matchers.tests.cpp:<line number>: passed: v1, !Approx(v2) for: { 1.0, 2.0, 3.0 } not is approx: { 1.5, 2.5, 3.5 }
|
||||
Matchers.tests.cpp:<line number>: passed: v1, Approx(v2).margin(0.5) for: { 1.0, 2.0, 3.0 } is approx: { 1.5, 2.5, 3.5 }
|
||||
Matchers.tests.cpp:<line number>: passed: v1, Approx(v2).epsilon(0.5) for: { 1.0, 2.0, 3.0 } is approx: { 1.5, 2.5, 3.5 }
|
||||
Matchers.tests.cpp:<line number>: passed: v1, Approx(v2).epsilon(0.1).scale(500) for: { 1.0, 2.0, 3.0 } is approx: { 1.5, 2.5, 3.5 }
|
||||
Matchers.tests.cpp:<line number>: failed: empty, Approx(t1) for: { } is approx: { 1.0, 2.0 }
|
||||
Matchers.tests.cpp:<line number>: failed: v1, Approx(v2) for: { 2.0, 4.0, 6.0 } is approx: { 1.0, 3.0, 5.0 }
|
||||
Matchers.tests.cpp:<line number>: passed: v, VectorContains(1) for: { 1, 2, 3 } Contains: 1
|
||||
Matchers.tests.cpp:<line number>: passed: v, VectorContains(2) for: { 1, 2, 3 } Contains: 2
|
||||
Matchers.tests.cpp:<line number>: passed: v, Contains(v2) for: { 1, 2, 3 } Contains: { 1, 2 }
|
||||
@@ -1502,5 +1514,5 @@ Misc.tests.cpp:<line number>: passed: v.size() == 5 for: 5 == 5
|
||||
Misc.tests.cpp:<line number>: passed: v.capacity() >= 5 for: 5 >= 5
|
||||
Misc.tests.cpp:<line number>: passed:
|
||||
Misc.tests.cpp:<line number>: passed:
|
||||
Failed 77 test cases, failed 138 assertions.
|
||||
Failed 79 test cases, failed 141 assertions.
|
||||
|
||||
|
@@ -1,6 +1,4 @@
|
||||
Filters: ~[!nonportable]~[!benchmark]~[approvals]
|
||||
This would not be caught previously
|
||||
Nor would this
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<exe-name> is a <version> host application.
|
||||
@@ -8,6 +6,18 @@ Run with -? for options
|
||||
|
||||
Randomness seeded to: 1
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#1455 - INFO and WARN can start with a linebreak
|
||||
-------------------------------------------------------------------------------
|
||||
Message.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Message.tests.cpp:<line number>: warning:
|
||||
|
||||
This warning message starts with a linebreak
|
||||
|
||||
This would not be caught previously
|
||||
Nor would this
|
||||
-------------------------------------------------------------------------------
|
||||
#1514: stderr/stdout is not captured in tests aborted by an exception
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -851,6 +861,30 @@ Exception.tests.cpp:<line number>: FAILED:
|
||||
due to unexpected exception with message:
|
||||
3.14
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector Approx matcher -- failing
|
||||
Empty and non empty vectors are not approx equal
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Matchers.tests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( empty, Approx(t1) )
|
||||
with expansion:
|
||||
{ } is approx: { 1.0, 2.0 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector Approx matcher -- failing
|
||||
Just different vectors
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Matchers.tests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( v1, Approx(v2) )
|
||||
with expansion:
|
||||
{ 2.0, 4.0, 6.0 } is approx: { 1.0, 3.0, 5.0 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector matchers that fail
|
||||
Contains (element)
|
||||
@@ -1265,6 +1299,6 @@ due to unexpected exception with message:
|
||||
Why would you throw a std::string?
|
||||
|
||||
===============================================================================
|
||||
test cases: 257 | 191 passed | 62 failed | 4 failed as expected
|
||||
assertions: 1419 | 1276 passed | 122 failed | 21 failed as expected
|
||||
test cases: 260 | 193 passed | 63 failed | 4 failed as expected
|
||||
assertions: 1428 | 1283 passed | 124 failed | 21 failed as expected
|
||||
|
||||
|
@@ -134,6 +134,21 @@ Compilation.tests.cpp:<line number>: PASSED:
|
||||
with expansion:
|
||||
[1403 helper] == [1403 helper]
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#1455 - INFO and WARN can start with a linebreak
|
||||
-------------------------------------------------------------------------------
|
||||
Message.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Message.tests.cpp:<line number>: warning:
|
||||
|
||||
This info message starts with a linebreak
|
||||
|
||||
This warning message starts with a linebreak
|
||||
|
||||
|
||||
No assertions in test case '#1455 - INFO and WARN can start with a linebreak'
|
||||
|
||||
This would not be caught previously
|
||||
Nor would this
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -2391,11 +2406,11 @@ ToStringGeneral.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( ::Catch::Detail::stringify(WhatException{}) == "This exception has overriden what() method" )
|
||||
REQUIRE( ::Catch::Detail::stringify(WhatException{}) == "This exception has overridden what() method" )
|
||||
with expansion:
|
||||
"This exception has overriden what() method"
|
||||
"This exception has overridden what() method"
|
||||
==
|
||||
"This exception has overriden what() method"
|
||||
"This exception has overridden what() method"
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( ::Catch::Detail::stringify(OperatorException{}) == "OperatorException" )
|
||||
@@ -8705,6 +8720,96 @@ VariadicMacros.tests.cpp:<line number>: PASSED:
|
||||
with message:
|
||||
no assertions
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector Approx matcher
|
||||
Empty vector is roughly equal to an empty vector
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( empty, Approx(empty) )
|
||||
with expansion:
|
||||
{ } is approx: { }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector Approx matcher
|
||||
Vectors with elements
|
||||
A vector is approx equal to itself
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( v1, Approx(v1) )
|
||||
with expansion:
|
||||
{ 1.0, 2.0, 3.0 } is approx: { 1.0, 2.0, 3.0 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector Approx matcher
|
||||
Vectors with elements
|
||||
Different length
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( v1, !Approx(temp) )
|
||||
with expansion:
|
||||
{ 1.0, 2.0, 3.0 } not is approx: { 1.0, 2.0, 3.0, 4.0 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector Approx matcher
|
||||
Vectors with elements
|
||||
Same length, different elements
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( v1, !Approx(v2) )
|
||||
with expansion:
|
||||
{ 1.0, 2.0, 3.0 } not is approx: { 1.5, 2.5, 3.5 }
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( v1, Approx(v2).margin(0.5) )
|
||||
with expansion:
|
||||
{ 1.0, 2.0, 3.0 } is approx: { 1.5, 2.5, 3.5 }
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( v1, Approx(v2).epsilon(0.5) )
|
||||
with expansion:
|
||||
{ 1.0, 2.0, 3.0 } is approx: { 1.5, 2.5, 3.5 }
|
||||
|
||||
Matchers.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_THAT( v1, Approx(v2).epsilon(0.1).scale(500) )
|
||||
with expansion:
|
||||
{ 1.0, 2.0, 3.0 } is approx: { 1.5, 2.5, 3.5 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector Approx matcher -- failing
|
||||
Empty and non empty vectors are not approx equal
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Matchers.tests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( empty, Approx(t1) )
|
||||
with expansion:
|
||||
{ } is approx: { 1.0, 2.0 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector Approx matcher -- failing
|
||||
Just different vectors
|
||||
-------------------------------------------------------------------------------
|
||||
Matchers.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Matchers.tests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( v1, Approx(v2) )
|
||||
with expansion:
|
||||
{ 2.0, 4.0, 6.0 } is approx: { 1.0, 3.0, 5.0 }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Vector matchers
|
||||
Contains (element)
|
||||
@@ -11113,6 +11218,6 @@ Misc.tests.cpp:<line number>
|
||||
Misc.tests.cpp:<line number>: PASSED:
|
||||
|
||||
===============================================================================
|
||||
test cases: 257 | 176 passed | 77 failed | 4 failed as expected
|
||||
assertions: 1435 | 1276 passed | 138 failed | 21 failed as expected
|
||||
test cases: 260 | 177 passed | 79 failed | 4 failed as expected
|
||||
assertions: 1445 | 1283 passed | 141 failed | 21 failed as expected
|
||||
|
||||
|
@@ -134,6 +134,21 @@ Compilation.tests.cpp:<line number>: PASSED:
|
||||
with expansion:
|
||||
[1403 helper] == [1403 helper]
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
#1455 - INFO and WARN can start with a linebreak
|
||||
-------------------------------------------------------------------------------
|
||||
Message.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Message.tests.cpp:<line number>: warning:
|
||||
|
||||
This info message starts with a linebreak
|
||||
|
||||
This warning message starts with a linebreak
|
||||
|
||||
|
||||
No assertions in test case '#1455 - INFO and WARN can start with a linebreak'
|
||||
|
||||
This would not be caught previously
|
||||
Nor would this
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -336,12 +351,7 @@ Condition.tests.cpp:<line number>: FAILED:
|
||||
Condition.tests.cpp:<line number>: FAILED:
|
||||
CHECK( true != true )
|
||||
|
||||
Condition.tests.cpp:<line number>: FAILED:
|
||||
CHECK( !true )
|
||||
with expansion:
|
||||
false
|
||||
|
||||
===============================================================================
|
||||
test cases: 17 | 13 passed | 2 failed | 2 failed as expected
|
||||
test cases: 18 | 13 passed | 3 failed | 2 failed as expected
|
||||
assertions: 40 | 33 passed | 4 failed | 3 failed as expected
|
||||
|
||||
|
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuites>
|
||||
<properties>
|
||||
<property name="filters" value="~[!nonportable]~[!benchmark]~[approvals]"/>
|
||||
<property name="random-seed" value="1"/>
|
||||
</properties>
|
||||
loose text artifact
|
||||
<testsuite name="<exe-name>" errors="17" failures="122" tests="1436" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||
<testsuitesloose text artifact
|
||||
>
|
||||
<testsuite name="<exe-name>" errors="17" failures="125" tests="1446" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||
<properties>
|
||||
<property name="filters" value="~[!nonportable]~[!benchmark]~[approvals]"/>
|
||||
<property name="random-seed" value="1"/>
|
||||
</properties>
|
||||
<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="#1027" time="{duration}"/>
|
||||
@@ -14,6 +14,7 @@ loose text artifact
|
||||
<testcase classname="<exe-name>.global" name="#1238" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.(Fixture_1245<int, int>)" name="#1245" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="#1403" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="#1455 - INFO and WARN can start with a linebreak" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="#1514: stderr/stdout is not captured in tests aborted by an exception" time="{duration}">
|
||||
<failure type="FAIL">
|
||||
1514
|
||||
@@ -740,6 +741,20 @@ Exception.tests.cpp:<line number>
|
||||
</testcase>
|
||||
<testcase classname="<exe-name>.global" name="Use a custom approx" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Variadic macros/Section with one argument" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Vector Approx matcher/Empty vector is roughly equal to an empty vector" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Vector Approx matcher/Vectors with elements/A vector is approx equal to itself" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Vector Approx matcher/Vectors with elements/Different length" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Vector Approx matcher/Vectors with elements/Same length, different elements" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Vector Approx matcher -- failing/Empty and non empty vectors are not approx equal" time="{duration}">
|
||||
<failure message="{ } is approx: { 1.0, 2.0 }" type="CHECK_THAT">
|
||||
Matchers.tests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="<exe-name>.global" name="Vector Approx matcher -- failing/Just different vectors" time="{duration}">
|
||||
<failure message="{ 2.0, 4.0, 6.0 } is approx: { 1.0, 3.0, 5.0 }" type="CHECK_THAT">
|
||||
Matchers.tests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="<exe-name>.global" name="Vector matchers/Contains (element)" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Vector matchers/Contains (vector)" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Vector matchers/Contains (element), composed" time="{duration}"/>
|
||||
|
@@ -142,6 +142,17 @@
|
||||
</Expression>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="#1455 - INFO and WARN can start with a linebreak" tags="[.][messages]" filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
|
||||
<Info>
|
||||
|
||||
This info message starts with a linebreak
|
||||
</Info>
|
||||
<Warning>
|
||||
|
||||
This warning message starts with a linebreak
|
||||
</Warning>
|
||||
<OverallResult success="false"/>
|
||||
</TestCase>
|
||||
<TestCase name="#1514: stderr/stdout is not captured in tests aborted by an exception" tags="[.][output-capture][regression]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
|
||||
<Failure filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
|
||||
1514
|
||||
@@ -2888,12 +2899,12 @@ Nor would this
|
||||
<TestCase name="Exception as a value (e.g. in REQUIRE_THROWS_MATCHES) can be stringified" tags="[exception][toString]" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
::Catch::Detail::stringify(WhatException{}) == "This exception has overriden what() method"
|
||||
::Catch::Detail::stringify(WhatException{}) == "This exception has overridden what() method"
|
||||
</Original>
|
||||
<Expanded>
|
||||
"This exception has overriden what() method"
|
||||
"This exception has overridden what() method"
|
||||
==
|
||||
"This exception has overriden what() method"
|
||||
"This exception has overridden what() method"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
@@ -10702,6 +10713,111 @@ Message from section two
|
||||
</Section>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Vector Approx matcher" tags="[approx][matchers][vector]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Section name="Empty vector is roughly equal to an empty vector" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
empty, Approx(empty)
|
||||
</Original>
|
||||
<Expanded>
|
||||
{ } is approx: { }
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="Vectors with elements" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Section name="A vector is approx equal to itself" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
v1, Approx(v1)
|
||||
</Original>
|
||||
<Expanded>
|
||||
{ 1.0, 2.0, 3.0 } is approx: { 1.0, 2.0, 3.0 }
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="Vectors with elements" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Section name="Different length" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
v1, !Approx(temp)
|
||||
</Original>
|
||||
<Expanded>
|
||||
{ 1.0, 2.0, 3.0 } not is approx: { 1.0, 2.0, 3.0, 4.0 }
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="Vectors with elements" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Section name="Same length, different elements" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
v1, !Approx(v2)
|
||||
</Original>
|
||||
<Expanded>
|
||||
{ 1.0, 2.0, 3.0 } not is approx: { 1.5, 2.5, 3.5 }
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
v1, Approx(v2).margin(0.5)
|
||||
</Original>
|
||||
<Expanded>
|
||||
{ 1.0, 2.0, 3.0 } is approx: { 1.5, 2.5, 3.5 }
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
v1, Approx(v2).epsilon(0.5)
|
||||
</Original>
|
||||
<Expanded>
|
||||
{ 1.0, 2.0, 3.0 } is approx: { 1.5, 2.5, 3.5 }
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
v1, Approx(v2).epsilon(0.1).scale(500)
|
||||
</Original>
|
||||
<Expanded>
|
||||
{ 1.0, 2.0, 3.0 } is approx: { 1.5, 2.5, 3.5 }
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="4" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<OverallResults successes="4" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Vector Approx matcher -- failing" tags="[.][approx][failing][matchers][vector]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Section name="Empty and non empty vectors are not approx equal" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
empty, Approx(t1)
|
||||
</Original>
|
||||
<Expanded>
|
||||
{ } is approx: { 1.0, 2.0 }
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="0" failures="1" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="Just different vectors" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Original>
|
||||
v1, Approx(v2)
|
||||
</Original>
|
||||
<Expanded>
|
||||
{ 2.0, 4.0, 6.0 } is approx: { 1.0, 3.0, 5.0 }
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="0" failures="1" expectedFailures="0"/>
|
||||
</Section>
|
||||
<OverallResult success="false"/>
|
||||
</TestCase>
|
||||
<TestCase name="Vector matchers" tags="[matchers][vector]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Section name="Contains (element)" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
<Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
|
||||
@@ -13388,7 +13504,7 @@ loose text artifact
|
||||
</Section>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<OverallResults successes="1276" failures="139" expectedFailures="21"/>
|
||||
<OverallResults successes="1283" failures="142" expectedFailures="21"/>
|
||||
</Group>
|
||||
<OverallResults successes="1276" failures="138" expectedFailures="21"/>
|
||||
<OverallResults successes="1283" failures="141" expectedFailures="21"/>
|
||||
</Catch>
|
||||
|
@@ -8,21 +8,6 @@
|
||||
#include "internal/catch_suppress_warnings.h"
|
||||
#include "internal/catch_test_case_tracker.h"
|
||||
|
||||
|
||||
namespace Catch
|
||||
{
|
||||
class LocalContext {
|
||||
|
||||
public:
|
||||
TrackerContext& operator()() const {
|
||||
return TrackerContext::instance();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
// -------------------
|
||||
|
||||
#include "catch.hpp"
|
||||
|
||||
using namespace Catch;
|
||||
|
@@ -213,6 +213,16 @@ namespace { namespace MatchersTests {
|
||||
v2.push_back(1);
|
||||
v2.push_back(2);
|
||||
|
||||
std::vector<double> v3;
|
||||
v3.push_back(1);
|
||||
v3.push_back(2);
|
||||
v3.push_back(3);
|
||||
|
||||
std::vector<double> v4;
|
||||
v4.push_back(1 + 1e-8);
|
||||
v4.push_back(2 + 1e-8);
|
||||
v4.push_back(3 + 1e-8);
|
||||
|
||||
std::vector<int> empty;
|
||||
|
||||
SECTION("Contains (element)") {
|
||||
@@ -265,6 +275,16 @@ namespace { namespace MatchersTests {
|
||||
v2.push_back(1);
|
||||
v2.push_back(2);
|
||||
|
||||
std::vector<double> v3;
|
||||
v3.push_back(1);
|
||||
v3.push_back(2);
|
||||
v3.push_back(3);
|
||||
|
||||
std::vector<double> v4;
|
||||
v4.push_back(1.1);
|
||||
v4.push_back(2.1);
|
||||
v4.push_back(3.1);
|
||||
|
||||
std::vector<int> empty;
|
||||
|
||||
SECTION("Contains (element)") {
|
||||
@@ -436,6 +456,44 @@ namespace { namespace MatchersTests {
|
||||
REQUIRE_THAT("foo", Predicate<const char*>([] (const char* const&) { return true; }));
|
||||
}
|
||||
|
||||
TEST_CASE("Vector Approx matcher", "[matchers][approx][vector]") {
|
||||
using Catch::Matchers::Approx;
|
||||
SECTION("Empty vector is roughly equal to an empty vector") {
|
||||
std::vector<double> empty;
|
||||
REQUIRE_THAT(empty, Approx(empty));
|
||||
}
|
||||
SECTION("Vectors with elements") {
|
||||
std::vector<double> v1({1., 2., 3.});
|
||||
SECTION("A vector is approx equal to itself") {
|
||||
REQUIRE_THAT(v1, Approx(v1));
|
||||
}
|
||||
std::vector<double> v2({1.5, 2.5, 3.5});
|
||||
SECTION("Different length") {
|
||||
auto temp(v1);
|
||||
temp.push_back(4);
|
||||
REQUIRE_THAT(v1, !Approx(temp));
|
||||
}
|
||||
SECTION("Same length, different elements") {
|
||||
REQUIRE_THAT(v1, !Approx(v2));
|
||||
REQUIRE_THAT(v1, Approx(v2).margin(0.5));
|
||||
REQUIRE_THAT(v1, Approx(v2).epsilon(0.5));
|
||||
REQUIRE_THAT(v1, Approx(v2).epsilon(0.1).scale(500));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Vector Approx matcher -- failing", "[matchers][approx][vector][.failing]") {
|
||||
using Catch::Matchers::Approx;
|
||||
SECTION("Empty and non empty vectors are not approx equal") {
|
||||
std::vector<double> empty, t1({1, 2});
|
||||
CHECK_THAT(empty, Approx(t1));
|
||||
}
|
||||
SECTION("Just different vectors") {
|
||||
std::vector<double> v1({2., 4., 6.}), v2({1., 3., 5.});
|
||||
CHECK_THAT(v1, Approx(v2));
|
||||
}
|
||||
}
|
||||
|
||||
} } // namespace MatchersTests
|
||||
|
||||
#endif // CATCH_CONFIG_DISABLE_MATCHERS
|
||||
|
@@ -14,6 +14,13 @@ TEST_CASE( "INFO and WARN do not abort tests", "[messages][.]" ) {
|
||||
WARN( "this is a " << "warning" ); // This should always output the message but then continue
|
||||
}
|
||||
|
||||
TEST_CASE( "#1455 - INFO and WARN can start with a linebreak", "[messages][.]" ) {
|
||||
// Previously these would be hidden from the console reporter output,
|
||||
// because it would fail at properly reflowing the text
|
||||
INFO( "\nThis info message starts with a linebreak" );
|
||||
WARN( "\nThis warning message starts with a linebreak" );
|
||||
}
|
||||
|
||||
TEST_CASE( "SUCCEED counts as a test pass", "[messages]" ) {
|
||||
SUCCEED( "this is a " << "success" );
|
||||
}
|
||||
@@ -220,9 +227,9 @@ TEST_CASE( "CAPTURE can deal with complex expressions", "[messages][capture]" )
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct helper_1436 {
|
||||
helper_1436(T1 t1, T2 t2):
|
||||
t1{ t1 },
|
||||
t2{ t2 }
|
||||
helper_1436(T1 t1_, T2 t2_):
|
||||
t1{ t1_ },
|
||||
t2{ t2_ }
|
||||
{}
|
||||
T1 t1;
|
||||
T2 t2;
|
||||
|
@@ -132,7 +132,7 @@ namespace {
|
||||
|
||||
struct WhatException : std::exception {
|
||||
char const* what() const noexcept override {
|
||||
return "This exception has overriden what() method";
|
||||
return "This exception has overridden what() method";
|
||||
}
|
||||
~WhatException() override;
|
||||
};
|
||||
@@ -170,7 +170,7 @@ StringMakerException::~StringMakerException() = default;
|
||||
|
||||
|
||||
TEST_CASE("Exception as a value (e.g. in REQUIRE_THROWS_MATCHES) can be stringified", "[toString][exception]") {
|
||||
REQUIRE(::Catch::Detail::stringify(WhatException{}) == "This exception has overriden what() method");
|
||||
REQUIRE(::Catch::Detail::stringify(WhatException{}) == "This exception has overridden what() method");
|
||||
REQUIRE(::Catch::Detail::stringify(OperatorException{}) == "OperatorException");
|
||||
REQUIRE(::Catch::Detail::stringify(StringMakerException{}) == "StringMakerException");
|
||||
}
|
||||
|
@@ -70,7 +70,7 @@ OC_TEST_CASE( "Matches work with OC types (NSString so far)", "[!shouldfail]" )
|
||||
{
|
||||
using namespace Catch::Matchers;
|
||||
|
||||
REQUIRE_THAT( @"This is a string", Equals( @"This isnt a string" ) );
|
||||
REQUIRE_THAT( @"This is a string", Equals( @"This isn't a string" ) );
|
||||
REQUIRE_THAT( @"This is a string", Contains( @"is a" ) );
|
||||
REQUIRE_THAT( @"This is a string", StartsWith( @"This" ) );
|
||||
REQUIRE_THAT( @"This is a string", EndsWith( @"string" ) );
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Catch v2.7.1
|
||||
* Generated: 2019-04-05 18:22:37.720122
|
||||
* Catch v2.7.2
|
||||
* Generated: 2019-04-22 23:13:14.687465
|
||||
* ----------------------------------------------------------
|
||||
* This file has been merged from multiple headers. Please don't edit it directly
|
||||
* Copyright (c) 2019 Two Blue Cubes Ltd. All rights reserved.
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#define CATCH_VERSION_MAJOR 2
|
||||
#define CATCH_VERSION_MINOR 7
|
||||
#define CATCH_VERSION_PATCH 1
|
||||
#define CATCH_VERSION_PATCH 2
|
||||
|
||||
#ifdef __clang__
|
||||
# pragma clang system_header
|
||||
@@ -3113,7 +3113,7 @@ public:
|
||||
|
||||
// The following functions create the actual matcher objects.
|
||||
// The user has to explicitly specify type to the function, because
|
||||
// infering std::function<bool(T const&)> is hard (but possible) and
|
||||
// inferring std::function<bool(T const&)> is hard (but possible) and
|
||||
// requires a lot of TMP.
|
||||
template<typename T>
|
||||
Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") {
|
||||
@@ -3201,28 +3201,6 @@ namespace Catch {
|
||||
namespace Matchers {
|
||||
|
||||
namespace Vector {
|
||||
namespace Detail {
|
||||
template <typename InputIterator, typename T>
|
||||
size_t count(InputIterator first, InputIterator last, T const& item) {
|
||||
size_t cnt = 0;
|
||||
for (; first != last; ++first) {
|
||||
if (*first == item) {
|
||||
++cnt;
|
||||
}
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
template <typename InputIterator, typename T>
|
||||
bool contains(InputIterator first, InputIterator last, T const& item) {
|
||||
for (; first != last; ++first) {
|
||||
if (*first == item) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct ContainsElementMatcher : MatcherBase<std::vector<T>> {
|
||||
|
||||
@@ -3297,6 +3275,42 @@ namespace Matchers {
|
||||
std::vector<T> const& m_comparator;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ApproxMatcher : MatcherBase<std::vector<T>> {
|
||||
|
||||
ApproxMatcher(std::vector<T> const& comparator) : m_comparator( comparator ) {}
|
||||
|
||||
bool match(std::vector<T> const &v) const override {
|
||||
if (m_comparator.size() != v.size())
|
||||
return false;
|
||||
for (std::size_t i = 0; i < v.size(); ++i)
|
||||
if (m_comparator[i] != approx(v[i]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
std::string describe() const override {
|
||||
return "is approx: " + ::Catch::Detail::stringify( m_comparator );
|
||||
}
|
||||
template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||
ApproxMatcher& epsilon( T const& newEpsilon ) {
|
||||
approx.epsilon(newEpsilon);
|
||||
return *this;
|
||||
}
|
||||
template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||
ApproxMatcher& margin( T const& newMargin ) {
|
||||
approx.margin(newMargin);
|
||||
return *this;
|
||||
}
|
||||
template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
|
||||
ApproxMatcher& scale( T const& newScale ) {
|
||||
approx.scale(newScale);
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::vector<T> const& m_comparator;
|
||||
mutable Catch::Detail::Approx approx = Catch::Detail::Approx::custom();
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> {
|
||||
UnorderedEqualsMatcher(std::vector<T> const& target) : m_target(target) {}
|
||||
@@ -3306,28 +3320,7 @@ namespace Matchers {
|
||||
if (m_target.size() != vec.size()) {
|
||||
return false;
|
||||
}
|
||||
auto lfirst = m_target.begin(), llast = m_target.end();
|
||||
auto rfirst = vec.begin(), rlast = vec.end();
|
||||
// Cut common prefix to optimize checking of permuted parts
|
||||
while (lfirst != llast && *lfirst == *rfirst) {
|
||||
++lfirst; ++rfirst;
|
||||
}
|
||||
if (lfirst == llast) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (auto mid = lfirst; mid != llast; ++mid) {
|
||||
// Skip already counted items
|
||||
if (Detail::contains(lfirst, mid, *mid)) {
|
||||
continue;
|
||||
}
|
||||
size_t num_vec = Detail::count(rfirst, rlast, *mid);
|
||||
if (num_vec == 0 || Detail::count(lfirst, llast, *mid) != num_vec) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
|
||||
}
|
||||
|
||||
std::string describe() const override {
|
||||
@@ -3357,6 +3350,11 @@ namespace Matchers {
|
||||
return Vector::EqualsMatcher<T>( comparator );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Vector::ApproxMatcher<T> Approx( std::vector<T> const& comparator ) {
|
||||
return Vector::ApproxMatcher<T>( comparator );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const& target) {
|
||||
return Vector::UnorderedEqualsMatcher<T>(target);
|
||||
@@ -4535,7 +4533,7 @@ namespace Catch {
|
||||
public:
|
||||
NamePattern( std::string const& name );
|
||||
virtual ~NamePattern();
|
||||
virtual bool matches( TestCaseInfo const& testCase ) const override;
|
||||
bool matches( TestCaseInfo const& testCase ) const override;
|
||||
private:
|
||||
WildcardPattern m_wildcardPattern;
|
||||
};
|
||||
@@ -4544,7 +4542,7 @@ namespace Catch {
|
||||
public:
|
||||
TagPattern( std::string const& tag );
|
||||
virtual ~TagPattern();
|
||||
virtual bool matches( TestCaseInfo const& testCase ) const override;
|
||||
bool matches( TestCaseInfo const& testCase ) const override;
|
||||
private:
|
||||
std::string m_tag;
|
||||
};
|
||||
@@ -4553,7 +4551,7 @@ namespace Catch {
|
||||
public:
|
||||
ExcludedPattern( PatternPtr const& underlyingPattern );
|
||||
virtual ~ExcludedPattern();
|
||||
virtual bool matches( TestCaseInfo const& testCase ) const override;
|
||||
bool matches( TestCaseInfo const& testCase ) const override;
|
||||
private:
|
||||
PatternPtr m_underlyingPattern;
|
||||
};
|
||||
@@ -4728,7 +4726,7 @@ namespace Catch {
|
||||
std::vector<std::string> const& getTestsOrTags() const override;
|
||||
std::vector<std::string> const& getSectionsToRun() const override;
|
||||
|
||||
virtual TestSpec const& testSpec() const override;
|
||||
TestSpec const& testSpec() const override;
|
||||
bool hasTestFilters() const override;
|
||||
|
||||
bool showHelp() const;
|
||||
@@ -5419,11 +5417,11 @@ namespace Catch {
|
||||
|
||||
class ReporterFactory : public IReporterFactory {
|
||||
|
||||
virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override {
|
||||
IStreamingReporterPtr create( ReporterConfig const& config ) const override {
|
||||
return std::unique_ptr<T>( new T( config ) );
|
||||
}
|
||||
|
||||
virtual std::string getDescription() const override {
|
||||
std::string getDescription() const override {
|
||||
return T::getDescription();
|
||||
}
|
||||
};
|
||||
@@ -5440,10 +5438,10 @@ namespace Catch {
|
||||
|
||||
class ListenerFactory : public IReporterFactory {
|
||||
|
||||
virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override {
|
||||
IStreamingReporterPtr create( ReporterConfig const& config ) const override {
|
||||
return std::unique_ptr<T>( new T( config ) );
|
||||
}
|
||||
virtual std::string getDescription() const override {
|
||||
std::string getDescription() const override {
|
||||
return std::string();
|
||||
}
|
||||
};
|
||||
@@ -5844,8 +5842,6 @@ namespace TestCaseTracking {
|
||||
|
||||
public:
|
||||
|
||||
static TrackerContext& instance();
|
||||
|
||||
ITracker& startRun();
|
||||
void endRun();
|
||||
|
||||
@@ -5991,18 +5987,18 @@ namespace Detail {
|
||||
return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
|
||||
}
|
||||
|
||||
void Approx::setMargin(double margin) {
|
||||
CATCH_ENFORCE(margin >= 0,
|
||||
"Invalid Approx::margin: " << margin << '.'
|
||||
void Approx::setMargin(double newMargin) {
|
||||
CATCH_ENFORCE(newMargin >= 0,
|
||||
"Invalid Approx::margin: " << newMargin << '.'
|
||||
<< " Approx::Margin has to be non-negative.");
|
||||
m_margin = margin;
|
||||
m_margin = newMargin;
|
||||
}
|
||||
|
||||
void Approx::setEpsilon(double epsilon) {
|
||||
CATCH_ENFORCE(epsilon >= 0 && epsilon <= 1.0,
|
||||
"Invalid Approx::epsilon: " << epsilon << '.'
|
||||
void Approx::setEpsilon(double newEpsilon) {
|
||||
CATCH_ENFORCE(newEpsilon >= 0 && newEpsilon <= 1.0,
|
||||
"Invalid Approx::epsilon: " << newEpsilon << '.'
|
||||
<< " Approx::epsilon has to be in [0, 1]");
|
||||
m_epsilon = epsilon;
|
||||
m_epsilon = newEpsilon;
|
||||
}
|
||||
|
||||
} // end namespace Detail
|
||||
@@ -6638,6 +6634,9 @@ public:
|
||||
m_suffix = false;
|
||||
auto width = m_column.m_width - indent();
|
||||
m_end = m_pos;
|
||||
if (line()[m_pos] == '\n') {
|
||||
++m_end;
|
||||
}
|
||||
while (m_end < line().size() && line()[m_end] != '\n')
|
||||
++m_end;
|
||||
|
||||
@@ -8042,10 +8041,7 @@ namespace Catch {
|
||||
m_stream( openStream() )
|
||||
{
|
||||
TestSpecParser parser(ITagAliasRegistry::get());
|
||||
if (data.testsOrTags.empty()) {
|
||||
parser.parse("~[.]"); // All not hidden tests
|
||||
}
|
||||
else {
|
||||
if (!data.testsOrTags.empty()) {
|
||||
m_hasTestFilters = true;
|
||||
for( auto const& testOrTags : data.testsOrTags )
|
||||
parser.parse( testOrTags );
|
||||
@@ -8163,7 +8159,7 @@ namespace {
|
||||
originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
|
||||
}
|
||||
|
||||
virtual void use( Colour::Code _colourCode ) override {
|
||||
void use( Colour::Code _colourCode ) override {
|
||||
switch( _colourCode ) {
|
||||
case Colour::None: return setTextAttribute( originalForegroundAttributes );
|
||||
case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
|
||||
@@ -8226,7 +8222,7 @@ namespace {
|
||||
// https://github.com/philsquared/Catch/pull/131
|
||||
class PosixColourImpl : public IColourImpl {
|
||||
public:
|
||||
virtual void use( Colour::Code _colourCode ) override {
|
||||
void use( Colour::Code _colourCode ) override {
|
||||
switch( _colourCode ) {
|
||||
case Colour::None:
|
||||
case Colour::White: return setColour( "[0m" );
|
||||
@@ -8337,27 +8333,27 @@ namespace Catch {
|
||||
class Context : public IMutableContext, NonCopyable {
|
||||
|
||||
public: // IContext
|
||||
virtual IResultCapture* getResultCapture() override {
|
||||
IResultCapture* getResultCapture() override {
|
||||
return m_resultCapture;
|
||||
}
|
||||
virtual IRunner* getRunner() override {
|
||||
IRunner* getRunner() override {
|
||||
return m_runner;
|
||||
}
|
||||
|
||||
virtual IConfigPtr const& getConfig() const override {
|
||||
IConfigPtr const& getConfig() const override {
|
||||
return m_config;
|
||||
}
|
||||
|
||||
virtual ~Context() override;
|
||||
~Context() override;
|
||||
|
||||
public: // IMutableContext
|
||||
virtual void setResultCapture( IResultCapture* resultCapture ) override {
|
||||
void setResultCapture( IResultCapture* resultCapture ) override {
|
||||
m_resultCapture = resultCapture;
|
||||
}
|
||||
virtual void setRunner( IRunner* runner ) override {
|
||||
void setRunner( IRunner* runner ) override {
|
||||
m_runner = runner;
|
||||
}
|
||||
virtual void setConfig( IConfigPtr const& config ) override {
|
||||
void setConfig( IConfigPtr const& config ) override {
|
||||
m_config = config;
|
||||
}
|
||||
|
||||
@@ -8423,19 +8419,23 @@ namespace Catch {
|
||||
# include <stdbool.h>
|
||||
# include <sys/types.h>
|
||||
# include <unistd.h>
|
||||
# include <sys/sysctl.h>
|
||||
# include <cstddef>
|
||||
# include <ostream>
|
||||
|
||||
namespace Catch {
|
||||
#ifdef __apple_build_version__
|
||||
// These headers will only compile with AppleClang (XCode)
|
||||
// For other compilers (Clang, GCC, ... ) we need to exclude them
|
||||
# include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
namespace Catch {
|
||||
#ifdef __apple_build_version__
|
||||
// The following function is taken directly from the following technical note:
|
||||
// http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
|
||||
// https://developer.apple.com/library/archive/qa/qa1361/_index.html
|
||||
|
||||
// Returns true if the current process is being debugged (either
|
||||
// running under the debugger or has a debugger attached post facto).
|
||||
bool isDebuggerActive(){
|
||||
|
||||
int mib[4];
|
||||
struct kinfo_proc info;
|
||||
std::size_t size;
|
||||
@@ -8465,6 +8465,12 @@ namespace Catch {
|
||||
|
||||
return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
|
||||
}
|
||||
#else
|
||||
bool isDebuggerActive() {
|
||||
// We need to find another way to determine this for non-appleclang compilers on macOS
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
} // namespace Catch
|
||||
|
||||
#elif defined(CATCH_PLATFORM_LINUX)
|
||||
@@ -8569,7 +8575,7 @@ namespace Catch {
|
||||
public:
|
||||
~ExceptionTranslatorRegistry();
|
||||
virtual void registerTranslator( const IExceptionTranslator* translator );
|
||||
virtual std::string translateActiveException() const override;
|
||||
std::string translateActiveException() const override;
|
||||
std::string tryTranslators() const;
|
||||
|
||||
private:
|
||||
@@ -9842,7 +9848,7 @@ namespace Catch {
|
||||
if (strerror_s(buffer, errno)) {
|
||||
CATCH_RUNTIME_ERROR("Could not translate errno to a string");
|
||||
}
|
||||
CATCH_RUNTIME_ERROR("Coul dnot open the temp file: '" << m_buffer << "' because: " << buffer);
|
||||
CATCH_RUNTIME_ERROR("Could not open the temp file: '" << m_buffer << "' because: " << buffer);
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -10920,7 +10926,10 @@ namespace Catch {
|
||||
|
||||
auto const& allTestCases = getAllTestCasesSorted(*config);
|
||||
for (auto const& testCase : allTestCases) {
|
||||
if (!context.aborting() && matchTest(testCase, testSpec, *config))
|
||||
bool matching = (!testSpec.hasFilters() && !testCase.isHidden()) ||
|
||||
(testSpec.hasFilters() && matchTest(testCase, testSpec, *config));
|
||||
|
||||
if (!context.aborting() && matching)
|
||||
totals += context.runTest(testCase);
|
||||
else
|
||||
context.reporter().skipTest(testCase);
|
||||
@@ -11646,7 +11655,7 @@ namespace Catch {
|
||||
void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
|
||||
CATCH_ENFORCE( !isReservedTag(tag),
|
||||
"Tag name: [" << tag << "] is not allowed.\n"
|
||||
<< "Tag names starting with non alpha-numeric characters are reserved\n"
|
||||
<< "Tag names starting with non alphanumeric characters are reserved\n"
|
||||
<< _lineInfo );
|
||||
}
|
||||
}
|
||||
@@ -11828,9 +11837,12 @@ namespace Catch {
|
||||
std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
|
||||
std::vector<TestCase> filtered;
|
||||
filtered.reserve( testCases.size() );
|
||||
for( auto const& testCase : testCases )
|
||||
if( matchTest( testCase, testSpec, config ) )
|
||||
filtered.push_back( testCase );
|
||||
for (auto const& testCase : testCases) {
|
||||
if ((!testSpec.hasFilters() && !testCase.isHidden()) ||
|
||||
(testSpec.hasFilters() && matchTest(testCase, testSpec, config))) {
|
||||
filtered.push_back(testCase);
|
||||
}
|
||||
}
|
||||
return filtered;
|
||||
}
|
||||
std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
|
||||
@@ -11906,11 +11918,6 @@ namespace TestCaseTracking {
|
||||
|
||||
ITracker::~ITracker() = default;
|
||||
|
||||
TrackerContext& TrackerContext::instance() {
|
||||
static TrackerContext s_instance;
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
ITracker& TrackerContext::startRun() {
|
||||
m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr );
|
||||
m_currentTracker = nullptr;
|
||||
@@ -12692,7 +12699,7 @@ namespace Catch {
|
||||
}
|
||||
|
||||
Version const& libraryVersion() {
|
||||
static Version version( 2, 7, 1, "", 0 );
|
||||
static Version version( 2, 7, 2, "", 0 );
|
||||
return version;
|
||||
}
|
||||
|
||||
@@ -14051,22 +14058,6 @@ namespace Catch {
|
||||
void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) {
|
||||
CumulativeReporterBase::testRunStarting( runInfo );
|
||||
xml.startElement( "testsuites" );
|
||||
|
||||
if ( m_config->hasTestFilters() || m_config->rngSeed() != 0 )
|
||||
xml.startElement("properties");
|
||||
|
||||
if ( m_config->hasTestFilters() ) {
|
||||
xml.scopedElement( "property" )
|
||||
.writeAttribute( "name" , "filters" )
|
||||
.writeAttribute( "value" , serializeFilters( m_config->getTestsOrTags() ) );
|
||||
}
|
||||
|
||||
if( m_config->rngSeed() != 0 ) {
|
||||
xml.scopedElement( "property" )
|
||||
.writeAttribute( "name", "random-seed" )
|
||||
.writeAttribute( "value", m_config->rngSeed() );
|
||||
xml.endElement();
|
||||
}
|
||||
}
|
||||
|
||||
void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {
|
||||
@@ -14105,6 +14096,7 @@ namespace Catch {
|
||||
|
||||
void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
|
||||
XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
|
||||
|
||||
TestGroupStats const& stats = groupNode.value;
|
||||
xml.writeAttribute( "name", stats.groupInfo.name );
|
||||
xml.writeAttribute( "errors", unexpectedExceptions );
|
||||
@@ -14117,6 +14109,21 @@ namespace Catch {
|
||||
xml.writeAttribute( "time", suiteTime );
|
||||
xml.writeAttribute( "timestamp", getCurrentTimestamp() );
|
||||
|
||||
// Write properties if there are any
|
||||
if (m_config->hasTestFilters() || m_config->rngSeed() != 0) {
|
||||
auto properties = xml.scopedElement("properties");
|
||||
if (m_config->hasTestFilters()) {
|
||||
xml.scopedElement("property")
|
||||
.writeAttribute("name", "filters")
|
||||
.writeAttribute("value", serializeFilters(m_config->getTestsOrTags()));
|
||||
}
|
||||
if (m_config->rngSeed() != 0) {
|
||||
xml.scopedElement("property")
|
||||
.writeAttribute("name", "random-seed")
|
||||
.writeAttribute("value", m_config->rngSeed());
|
||||
}
|
||||
}
|
||||
|
||||
// Write test cases
|
||||
for( auto const& child : groupNode.children )
|
||||
writeTestCase( *child );
|
||||
|
3
third_party/clara.hpp
vendored
3
third_party/clara.hpp
vendored
@@ -110,6 +110,9 @@ namespace clara { namespace TextFlow {
|
||||
m_suffix = false;
|
||||
auto width = m_column.m_width-indent();
|
||||
m_end = m_pos;
|
||||
if (line()[m_pos] == '\n') {
|
||||
++m_end;
|
||||
}
|
||||
while( m_end < line().size() && line()[m_end] != '\n' )
|
||||
++m_end;
|
||||
|
||||
|
Reference in New Issue
Block a user