Compare commits

...

41 Commits

Author SHA1 Message Date
Martin Hořeňovský
6ccd467094 v2.5.0 2018-11-26 20:50:38 +01:00
Martin Hořeňovský
34dcd2c436 Remove remains of the old conan things from release script 2018-11-26 20:47:40 +01:00
Martin Hořeňovský
16656c4c9e Update the release process documentation 2018-11-26 20:41:14 +01:00
Martin Hořeňovský
df019cc113 Turn "deprecations" into "deprecations and planned changes"
This captures the intent better, as some changes are indeed plain
deprecations leading to removal, but other changes can be viewed
as minor tune-ups instead.
2018-11-24 18:04:56 +01:00
Martin Hořeňovský
695e6eafc5 Merge pull request #1448 from catchorg/dev-redo-capturer-parsing
Fix CAPTURE macro for nontrivial uses
2018-11-21 21:21:03 +01:00
Martin Hořeňovský
59087f74d9 Fix CAPTURE macro for nontrivial uses
The previous implemetation was just plain broken for most of
possible uses, the new one should work (even though it is ugly
as all hell, and should be improved ASAP).

Fixes #1436
2018-11-21 16:48:09 +01:00
Martin Hořeňovský
62460fafe6 Merge pull request #1443 from uilianries/feature/conanio
Conan recipe Update + Conan package upload
2018-11-19 15:34:40 +01:00
Uilian Ries
ac0a83a35d Update Conan recipe
- Apply new conventions introduced on Conan 1.8
- Removed outdated settings
- Update license to follow SPDX format

Closes #926
Closes #943
2018-11-19 15:27:47 +01:00
Martin Hořeňovský
77f29c2f1c Add more deprecations 2018-11-17 21:13:56 +01:00
Martin Hořeňovský
c6a89f14c2 Add std::isnan polyfill, fixing compilation under Embarcadero
Fixes #1438
2018-11-17 20:52:18 +01:00
Martin Hořeňovský
a9d5b7193d Add note about release signing to release docs 2018-11-17 14:41:34 +01:00
Martin Hořeňovský
396e0951c8 Add ToC to "Test cases and sections" documentation 2018-11-17 11:09:15 +01:00
Martin Hořeňovský
68860ff129 Add deprecations documentation 2018-11-17 11:08:38 +01:00
Martin Hořeňovský
99b37a4c62 Merge pull request #1445 from thecppzoo/master
operator<< works from the global namespace
2018-11-17 10:36:37 +01:00
Martin Hořeňovský
1dccd26de7 Fix link in documentation 2018-11-17 10:21:46 +01:00
thecppzoo
3f3238edf0 operator<< works from the global namespace
Since https://github.com/catchorg/Catch2/pull/1405 was merged and propagated to the single include declaring a user operator<< in the global namespace makes it available to Catch2 string converters.
2018-11-16 16:45:13 -08:00
Martin Hořeňovský
450dd0562b Merge pull request #1437 from JoeyGrajciar/type_params_tests_v2
Type parametrised test cases v2
2018-11-16 21:24:19 +01:00
Martin Hořeňovský
00d4f5d3c6 Add documentation for templated tests 2018-11-16 21:21:30 +01:00
Jozef Grajciar
2d906a92cb Add support for templated tests
This adds support for templated tests and test methods via
`TEMPLATE_TEST_CASE` and `TEMPLATE_TEST_CASE_METHOD` macros. These
work mostly just like their regular counterparts*, but take an
unlimited** number of types as their last arguments.

* Unlike the plain `TEST_CASE*` macros, the `TEMPLATE*` variants
require a tag string.

** In practice there is limit of about 300 types.
2018-11-16 21:21:23 +01:00
Jozef Grajciar
489a41012e ConsoleReporter: minor formatting fix
PASSED will now appear on the same line as filename and line number,
just like the case with FAILED message formatting
2018-11-10 19:35:25 +01:00
Martin Hořeňovský
eccbffec0f Add MSVC warning 5038 (Wreorder equivalent) to CMakeLists 2018-11-05 20:07:33 +01:00
Martin Hořeňovský
c51f2edfb1 Make TestEventListenerBase register all verbosities
This is a temporarily workaround until we can nuke the current
verbosities system from the orbit and replace it with something
actually sane.

Fixes #1426
2018-11-05 20:05:17 +01:00
Martin Hořeňovský
de6bfb5c25 Remove obsolete comment 2018-11-05 20:05:17 +01:00
Antonio Borondo
87950d9cfa Fix Cute test framework URL 2018-11-05 19:38:37 +01:00
Martin Hořeňovský
d0eb9dfb9b Remove unused partial specialization for MatcherMethod<T>
No matcher actually uses it, and there is no good reason for it,
as the best it can do for user is removing a single indirection
when using the pointer inside the matcher. Given the overhead of
other code that will be running during such time, it is completely
meaningless.

This also fixes compilation for PredicateMatcher<const char*>.
2018-11-04 00:00:36 +01:00
Martin Hořeňovský
03d122a35c v2.4.2 2018-10-26 21:14:16 +02:00
Martin Hořeňovský
1d9b506e39 Add documentation for some miscellaneous and less important macros
Fixes #1367
2018-10-26 20:50:32 +02:00
Martin Hořeňovský
779e83bc20 Update Clara to v1.1.5 to fix TextFlow bugs 2018-10-26 18:48:28 +02:00
Stephane Del Pino
544c7d7cbf Add the optional variable OptionalCatchTestLauncher
This variable is set to allow the use of the nice ParseAndAddCatchTests script
in the case where a launcher is needed to execute  the script.

This is introduced to allow to launch unit tests using mpi. In this case one can
write for instance
  set(OptionalCatchTestLauncher ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${NUMPROC})
before calling the ParseAndAddCatchTests function.
2018-10-25 15:51:15 +02:00
Maciej Patro
8b3c09c137 Catch's CLI now checks whether requested reporter exists
Fixes #1351
2018-10-25 15:43:30 +02:00
Maciej Patro
b7f41237b1 Remove unused parameter from listReporters() 2018-10-25 15:43:30 +02:00
MaciejPatro
1faccd601d Improve path normalization for approvalTests.py
This fixes 3 problems:

* Relative paths on Windows are now supported
* Out-of-tree (paths starting with ../) builds are now supported
* Path separator normalization no longer affects non-path components of input (problem with Compact reporter)


Fixes #1379 
Fixes #1222 
Fixes #1200 
Fixes #1194
2018-10-19 12:46:06 +02:00
Jozef Grajciar
ab98afe68b Catch::LeakDetector: added cleanup call to destructor
simple code with provided main function which just returns 0
leaks memory due to fact that singletons are not cleaned up

running valgrind on such simple application reports that 752 bytes
are still available in 11 blocks

this commit adds destructor to Catch::LeakDetector which calls
Catch::cleanUp()
2018-10-18 11:47:21 +02:00
Martin Hořeňovský
054d356332 Add STATIC_REQUIRE assertion
By default, it expands into a `static_assert` + `SUCCEED` pair, but
it can also be deferred to runtime by defining
`CATCH_CONFIG_RUNTIME_STATIC_REQUIRE`, which causes it to expand
into plain old `REQUIRE`.

Closes #1362
Closes #1356
2018-10-16 16:16:00 +02:00
Maciej Patro
0144ae9ad2 Fix catch_discover_tests() - now should correctly find tests with commas | Related to #1327 2018-10-16 16:06:31 +02:00
JoeyGrajciar
e1307016f0 Session::applyCommandLine overload on wchar_t (#1401)
* Session::applyCommandLine overload on wchar_t

This allows users on Windows to use Catch::Session::applyCommandLine
with wchar_t * arguments of application.

With this change Session::run became templated so both char and wchar_t
version have the same implementation.
2018-10-13 19:29:53 +02:00
Martin Hořeňovský
6b9ca0888a Add tests for #1404 2018-10-13 16:53:44 +02:00
Jozef Grajciar
9f8b848fe5 XmlReporter: add information about rng-seed
Xml result of reported will now contain value of rng-seed in case it
is not zero.
The value will be stored in element Randomness and it's attribute seed.

Relates to #1402
2018-10-13 16:53:44 +02:00
Martin Hořeňovský
aaaac35d92 Add tests for #1403 2018-10-13 16:53:30 +02:00
Eddie
6cede0101a Fix different operator<< overload sets used for SFINAE and insertion 2018-10-13 16:53:30 +02:00
Miguel Gaio
f1faaa9c10 Fix convert from char on ARM build
Some platforms set the signedness of char to unsigned (eg. ARM).
Convert from char should not assume the signedness of char.

Fix build issue with -Werror,-Wtautological-unsigned-zero-compare flags.

Signed-off-by: Miguel Gaio <mgaio35@gmail.com>
2018-10-13 12:56:05 +02:00
71 changed files with 5136 additions and 3191 deletions

94
.conan/build.py Normal file
View File

@@ -0,0 +1,94 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import re
from cpt.packager import ConanMultiPackager
from cpt.ci_manager import CIManager
from cpt.printer import Printer
class BuilderSettings(object):
@property
def username(self):
""" Set catchorg as package's owner
"""
return os.getenv("CONAN_USERNAME", "catchorg")
@property
def login_username(self):
""" Set Bintray login username
"""
return os.getenv("CONAN_LOGIN_USERNAME", "horenmar")
@property
def upload(self):
""" Set Catch2 repository to be used on upload.
The upload server address could be customized by env var
CONAN_UPLOAD. If not defined, the method will check the branch name.
Only master or CONAN_STABLE_BRANCH_PATTERN will be accepted.
The master branch will be pushed to testing channel, because it does
not match the stable pattern. Otherwise it will upload to stable
channel.
"""
return os.getenv("CONAN_UPLOAD", "https://api.bintray.com/conan/horenmar/Catch2")
@property
def upload_only_when_stable(self):
""" Force to upload when running over tag branch
"""
return os.getenv("CONAN_UPLOAD_ONLY_WHEN_STABLE", "True").lower() in ["true", "1", "yes"]
@property
def stable_branch_pattern(self):
""" Only upload the package the branch name is like a tag
"""
return os.getenv("CONAN_STABLE_BRANCH_PATTERN", r"v\d+\.\d+\.\d+")
@property
def reference(self):
""" Read project version from branch create Conan referece
"""
return os.getenv("CONAN_REFERENCE", "Catch2/{}@{}/{}".format(self._version, self.username, self.channel))
@property
def channel(self):
""" Default Conan package channel when not stable
"""
return os.getenv("CONAN_CHANNEL", "testing")
@property
def _version(self):
""" Get version name from cmake file
"""
pattern = re.compile(r"project\(Catch2 LANGUAGES CXX VERSION (\d+\.\d+\.\d+)\)")
version = "latest"
with open("CMakeLists.txt") as file:
for line in file:
result = pattern.search(line)
if result:
version = result.group(1)
return version
@property
def _branch(self):
""" Get branch name from CI manager
"""
printer = Printer(None)
ci_manager = CIManager(printer)
return ci_manager.get_branch()
if __name__ == "__main__":
settings = BuilderSettings()
builder = ConanMultiPackager(
reference=settings.reference,
channel=settings.channel,
upload=settings.upload,
upload_only_when_stable=settings.upload_only_when_stable,
stable_branch_pattern=settings.stable_branch_pattern,
login_username=settings.login_username,
username=settings.username,
test_folder=os.path.join(".conan", "test_package"))
builder.add()
builder.run()

View File

@@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 3.2.0)
project(test_package CXX)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup(TARGETS)
find_package(Catch2 REQUIRED CONFIG)
add_executable(${PROJECT_NAME} test_package.cpp)
target_link_libraries(${PROJECT_NAME} CONAN_PKG::Catch2)
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 11)

View File

@@ -0,0 +1,19 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from conans import ConanFile, CMake
import os
class TestPackageConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
generators = "cmake"
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
def test(self):
assert os.path.isfile(os.path.join(self.deps_cpp_info["Catch2"].rootpath, "licenses", "LICENSE.txt"))
bin_path = os.path.join("bin", "test_package")
self.run("%s -s" % bin_path, run_environment=True)

View File

@@ -0,0 +1,15 @@
#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>
int Factorial( int number ) {
return number <= 1 ? 1 : Factorial( number - 1 ) * number;
}
TEST_CASE( "Factorial Tests", "[single-file]" ) {
REQUIRE( Factorial(0) == 1 );
REQUIRE( Factorial(1) == 1 );
REQUIRE( Factorial(2) == 2 );
REQUIRE( Factorial(3) == 6 );
REQUIRE( Factorial(10) == 3628800 );
}

1
.gitignore vendored
View File

@@ -27,3 +27,4 @@ Build
.vs
cmake-build-*
benchmark-dir
.conan/test_package/build

View File

@@ -271,6 +271,19 @@ matrix:
packages: ['clang-6.0', 'libstdc++-8-dev']
env: COMPILER='clang++-6.0' CPP17=1 EXAMPLES=1 COVERAGE=1 EXTRAS=1
# 8/ Conan
- language: python
python:
- "3.7"
dist: xenial
install:
- pip install conan conan-package-tools
env:
- CONAN_GCC_VERSIONS=8
- CONAN_DOCKER_IMAGE=conanio/gcc8
script:
- python .conan/build.py
install:
- DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
- mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR}

View File

@@ -6,7 +6,7 @@ if(NOT DEFINED PROJECT_NAME)
set(NOT_SUBPROJECT ON)
endif()
project(Catch2 LANGUAGES CXX VERSION 2.4.1)
project(Catch2 LANGUAGES CXX VERSION 2.5.0)
# Provide path for scripts
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")

View File

@@ -5,11 +5,11 @@
[![Build Status](https://travis-ci.org/catchorg/Catch2.svg?branch=master)](https://travis-ci.org/catchorg/Catch2)
[![Build status](https://ci.appveyor.com/api/projects/status/github/catchorg/Catch2?svg=true)](https://ci.appveyor.com/project/catchorg/catch2)
[![codecov](https://codecov.io/gh/catchorg/Catch2/branch/master/graph/badge.svg)](https://codecov.io/gh/catchorg/Catch2)
[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/E0msqwbW7U4PVbHn)
[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/7lDqHmzKQxA2eaM0)
[![Join the chat in Discord: https://discord.gg/4CWS9zD](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/4CWS9zD)
<a href="https://github.com/catchorg/Catch2/releases/download/v2.4.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.5.0/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
## Catch2 is released!

View File

@@ -3,19 +3,15 @@ from conans import ConanFile, CMake
class CatchConan(ConanFile):
name = "Catch"
version = "2.4.1"
name = "Catch2"
description = "A modern, C++-native, header-only, framework for unit-tests, TDD and BDD"
author = "philsquared"
generators = "cmake"
# Only needed until conan 1.5 is released
settings = "compiler", "arch"
exports_sources = "single_include/*", "CMakeLists.txt", "CMake/catch2.pc.in", "LICENSE.txt"
topics = ("conan", "catch2", "header-only", "unit-test", "tdd", "bdd")
url = "https://github.com/catchorg/Catch2"
license = "Boost Software License - Version 1.0. http://www.boost.org/LICENSE_1_0.txt"
def build(self):
pass
homepage = url
license = "BSL-1.0"
exports = "LICENSE.txt"
exports_sources = ("single_include/*", "CMakeLists.txt", "CMake/*", "contrib/*")
generators = "cmake"
def package(self):
cmake = CMake(self)

View File

@@ -51,12 +51,14 @@ string(REPLACE "\n" ";" output "${output}")
# 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}"
"${test_name}"
${extra_args}
)
add_command(set_tests_properties

View File

@@ -39,6 +39,11 @@
# PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS (Default OFF) #
# -- causes CMake to rerun when file with tests changes so that new tests will be discovered #
# #
# One can also set (locally) the optional variable OptionalCatchTestLauncher to precise the way #
# a test should be run. For instance to use test MPI, one can write #
# set(OptionalCatchTestLauncher ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${NUMPROC}) #
# just before calling this ParseAndAddCatchTests function #
# #
#==================================================================================================#
cmake_minimum_required(VERSION 2.8.8)
@@ -168,7 +173,7 @@ function(ParseFile SourceFile TestTarget)
endif()
# Add the test and set its properties
add_test(NAME "\"${CTestName}\"" COMMAND ${TestTarget} ${Name} ${AdditionalCatchParameters})
add_test(NAME "\"${CTestName}\"" COMMAND ${OptionalCatchTestLauncher} ${TestTarget} ${Name} ${AdditionalCatchParameters})
set_tests_properties("\"${CTestName}\"" PROPERTIES FAIL_REGULAR_EXPRESSION "No tests ran"
LABELS "${Labels}")
endif()

View File

@@ -13,6 +13,7 @@ Writing tests:
* [Reporters](reporters.md#top)
* [Event Listeners](event-listeners.md#top)
* [Data Generators](generators.md#top)
* [Other macros](other-macros.md#top)
Fine tuning:
* [Supplying your own main()](own-main.md#top)
@@ -35,3 +36,4 @@ Other:
* [Open Source Projects using Catch](opensource-users.md#top)
* [Contributing](contributing.md#top)
* [Release Notes](release-notes.md#top)
* [Deprecations and incoming changes](deprecations.md#top)

View File

@@ -172,6 +172,16 @@ step will be re-ran when the test files change, letting new tests be
automatically discovered. Defaults to `OFF`.
Optionally, one can specify a launching command to run tests by setting the
variable `OptionalCatchTestLauncher` before calling `ParseAndAddCatchTests`. For
instance to run some tests using `MPI` and other sequentially, one can write
```cmake
set(OptionalCatchTestLauncher ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${NUMPROC})
ParseAndAddCatchTests(mpi_foo)
unset(OptionalCatchTestLauncher)
ParseAndAddCatchTests(bar)
```
## CMake project options
Catch2's CMake project also provides some options for other projects

88
docs/deprecations.md Normal file
View File

@@ -0,0 +1,88 @@
<a id="top"></a>
# Deprecations and incoming changes
This page documents current deprecations and upcoming planned changes
inside Catch2. The difference between these is that a deprecated feature
will be removed, while a planned change to a feature means that the
feature will behave differently, but will still be present. Obviously,
either of these is a breaking change, and thus will not happen until
at least the next major release.
## Deprecations
### `--list-*` return values
The return codes of the `--list-*` family of command line arguments
will no longer be equal to the number of tests/tags/etc found, instead
it will be 0 for success and non-zero for failure.
### `--list-test-names-only`
`--list-test-names-only` command line argument will be removed.
### `ANON_TEST_CASE`
`ANON_TEST_CASE` is scheduled for removal, as it can be fully replaced
by a `TEST_CASE` with no arguments.
### Secondary description amongst tags
Currently, the tags part of `TEST_CASE` (and others) macro can also
contain text that is not part of tags. This text is then separated into
a "description" of the test case, but the description is then never used
apart from writing it out for `--list-tests -v high`.
Because it isn't actually used nor documented, and brings complications
to Catch2's internals, description support will be removed.
## Planned changes
### Reporter verbosities
The current implementation of verbosities, where the reporter is checked
up-front whether it supports the requested verbosity, is fundamentally
misguided and will be changed. The new implementation will no longer check
whether the specified reporter supports the requested verbosity, instead
it will be up to the reporters to deal with verbosities as they see fit
(with an expectation that unsupported verbosities will be, at most,
warnings, but not errors).
### Output format of `--list-*` command line parameters
The various list operations will be piped through reporters. This means
that e.g. XML reporter will write the output as machine-parseable XML,
while the Console reporter will keep the current, human-oriented output.
### `CHECKED_IF` and `CHECKED_ELSE`
To make the `CHECKED_IF` and `CHECKED_ELSE` macros more useful, they will
be marked as "OK to fail" (`Catch::ResultDisposition::SuppressFail` flag
will be added), which means that their failure will not fail the test,
making the `else` actually useful.
### Change semantics of `[.]` and tag exclusion
Currently, given these 2 tests
```cpp
TEST_CASE("A", "[.][foo]") {}
TEST_CASE("B", "[.][bar]") {}
```
specifying `[foo]` as the testspec will run test "A" and specifying
`~[foo]` will run test "B", even though it is hidden. Also, specifying
`~[baz]` will run both tests. This behaviour is often surprising and will
be changed so that hidden tests are included in a run only if they
positively match a testspec.
---
[Home](Readme.md#top)

View File

@@ -57,20 +57,37 @@ The message is reported and the test case fails.
AS `FAIL`, but does not abort the test
## Quickly capture a variable value
## Quickly capture value of variables or expressions
**CAPTURE(** _expression_ **)**
**CAPTURE(** _expression1_, _expression2_, ... **)**
Sometimes you just want to log the name and value of a variable. While you can easily do this with the INFO macro, above, as a convenience the CAPTURE macro handles the stringising of the variable name for you (actually it works with any expression, not just variables).
Sometimes you just want to log a value of variable, or expression. For
convenience, we provide the `CAPTURE` macro, that can take a variable,
or an expression, and prints out that variable/expression and its value
at the time of capture.
E.g.
```c++
CAPTURE( theAnswer );
e.g. `CAPTURE( theAnswer );` will log message "theAnswer := 42", while
```cpp
int a = 1, b = 2, c = 3;
CAPTURE( a, b, c, a + b, c > b, a == 1);
```
will log a total of 6 messages:
```
a := 1
b := 2
c := 3
a + b := 3
c > b := true
a == 1 := true
```
This would log something like:
You can also capture expressions that use commas inside parentheses
(e.g. function calls), brackets, or braces (e.g. initializers). To
properly capture expression that contains template parameters list
(in other words, it contains commas between angle brackets), you need
to enclose the expression inside parentheses:
`CAPTURE( (std::pair<int, int>{1, 2}) );`
<pre>"theAnswer := 42"</pre>
---

150
docs/other-macros.md Normal file
View File

@@ -0,0 +1,150 @@
<a id="top"></a>
# Other macros
This page serves as a reference for macros that are not documented
elsewhere. For now, these macros are separated into 2 rough categories,
"assertion related macros" and "test case related macros".
## Assertion related macros
* `CHECKED_IF` and `CHECKED_ELSE`
`CHECKED_IF( expr )` is an `if` replacement, that also applies Catch2's
stringification machinery to the _expr_ and records the result. As with
`if`, the block after a `CHECKED_IF` is entered only if the expression
evaluates to `true`. `CHECKED_ELSE( expr )` work similarly, but the block
is entered only if the _expr_ evaluated to `false`.
Example:
```cpp
int a = ...;
int b = ...;
CHECKED_IF( a == b ) {
// This block is entered when a == b
} CHECKED_ELSE ( a == b ) {
// This block is entered when a != b
}
```
* `CHECK_NOFAIL`
`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.
Example output:
```
main.cpp:6:
FAILED - but was ok:
CHECK_NOFAIL( 1 == 2 )
main.cpp:7:
PASSED:
CHECK( 2 == 2 )
```
* `SUCCEED`
`SUCCEED( msg )` is mostly equivalent with `INFO( msg ); REQUIRE( true );`.
In other words, `SUCCEED` is for cases where just reaching a certain line
means that the test has been a success.
Example usage:
```cpp
TEST_CASE( "SUCCEED showcase" ) {
int I = 1;
SUCCEED( "I is " << I );
}
```
* `STATIC_REQUIRE`
`STATIC_REQUIRE( expr )` is a macro that can be used the same way as a
`static_assert`, but also registers the success with Catch2, so it is
reported as a success at runtime. The whole check can also be deferred
to the runtime, by defining `CATCH_CONFIG_RUNTIME_STATIC_REQUIRE` before
including the Catch2 header.
Example:
```cpp
TEST_CASE("STATIC_REQUIRE showcase", "[traits]") {
STATIC_REQUIRE( std::is_void<void>::value );
STATIC_REQUIRE_FALSE( std::is_void<int>::value );
}
```
## Test case related macros
* `METHOD_AS_TEST_CASE`
`METHOD_AS_TEST_CASE( member-function-pointer, description )` lets you
register a member function of a class as a Catch2 test case. The class
will be separately instantiated for each method registered in this way.
```cpp
class TestClass {
std::string s;
public:
TestClass()
:s( "hello" )
{}
void testCase() {
REQUIRE( s == "hello" );
}
};
METHOD_AS_TEST_CASE( TestClass::testCase, "Use class's method as a test case", "[class]" )
```
* `REGISTER_TEST_CASE`
`REGISTER_TEST_CASE( function, description )` let's you register
a `function` as a test case. The function has to have `void()` signature,
the description can contain both name and tags.
Example:
```cpp
REGISTER_TEST_CASE( someFunction, "ManuallyRegistered", "[tags]" );
```
_Note that the registration still has to happen before Catch2's session
is initiated. This means that it either needs to be done in a global
constructor, or before Catch2's session is created in user's own main._
* `ANON_TEST_CASE`
`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
hard to run directly.
Example:
```cpp
ANON_TEST_CASE() {
SUCCEED("Hello from anonymous test case");
}
```
* `DYNAMIC_SECTION`
`DYNAMIC_SECTION` is a `SECTION` where the user can use `operator<<` to
create the final name for that section. This can be useful with e.g.
generators, or when creating a `SECTION` dynamically, within a loop.
Example:
```cpp
TEST_CASE( "looped SECTION tests" ) {
int a = 1;
for( int b = 0; b < 10; ++b ) {
DYNAMIC_SECTION( "b is currently: " << b ) {
CHECK( b > a );
}
}
}
```

View File

@@ -2,6 +2,8 @@
# Release notes
**Contents**<br>
[2.5.0](#250)<br>
[2.4.2](#242)<br>
[2.4.1](#241)<br>
[2.4.0](#240)<br>
[2.3.0](#230)<br>
@@ -16,6 +18,50 @@
[Older versions](#older-versions)<br>
[Even Older versions](#even-older-versions)<br>
## 2.5.0
### Improvements
* Added support for templated tests via `TEMPLATE_TEST_CASE` (#1437)
### Fixes
* Fixed compilation of `PredicateMatcher<const char*>` by removing partial specialization of `MatcherMethod<T*>`
* Listeners now implicitly support any verbosity (#1426)
* Fixed compilation with Embarcadero builder by introducing `Catch::isnan` polyfill (#1438)
* Fixed `CAPTURE` asserting for non-trivial captures (#1436, #1448)
### Miscellaneous
* We should now be providing first party Conan support via https://bintray.com/catchorg/Catch2 (#1443)
* Added new section "deprecations and planned changes" to the documentation
* It contains summary of what is deprecated and might change with next major version
* From this release forward, the released headers should be pgp signed (#430)
* KeyID `E29C 46F3 B8A7 5028 6079 3B7D ECC9 C20E 314B 2360`
* or https://codingnest.com/files/horenmar-publickey.asc
## 2.4.2
### Improvements
* XmlReporter now also outputs the RNG seed that was used in a run (#1404)
* `Catch::Session::applyCommandLine` now also accepts `wchar_t` arguments.
* However, Catch2 still does not support unicode.
* Added `STATIC_REQUIRE` macro (#1356, #1362)
* Catch2's singleton's are now cleaned up even if tests are run (#1411)
* This is mostly useful as a FP prevention for users who define their own main.
* Specifying an invalid reporter via `-r` is now reported sooner (#1351, #1422)
### Fixes
* Stringification no longer assumes that `char` is signed (#1399, #1407)
* This caused a `Wtautological-compare` warning.
* SFINAE for `operator<<` no longer sees different overload set than the actual insertion (#1403)
### Contrib
* `catch_discover_tests` correctly adds tests with comma in name (#1327, #1409)
* Added a new customization point in how the tests are launched to `catch_discover_tests`
## 2.4.1

View File

@@ -8,11 +8,11 @@ When enough changes have accumulated, it is time to release new version of Catch
These steps are necessary and have to be performed before each new release. They serve to make sure that the new release is correct and linked-to from the standard places.
### Approval testing
### Testing
Catch's releases are primarily validated against output from previous release, stored in `projects/SelfTest/Baselines`. To validate current sources, build the SelfTest binary and pass it to the `approvalTests.py` script: `approvalTests.py <path/to/SelfTest>`.
There should be no differences, as Approval tests should be updated when changes to Catch are made, but if there are, then they need to be manually reviewed and either approved (using `approve.py`) or Catch requires other fixes.
All of the tests are currently run in our CI setup based on TravisCI and
AppVeyor. As long as the last commit tested green, the release can
proceed.
### Incrementing version number
@@ -27,7 +27,7 @@ version numbers everywhere and pushing the new version to Wandbox.
### Release notes
Once a release is ready, release notes need to be written. They should summarize changes done since last release. For rough idea of expected notes see previous releases. Once written, release notes should be placed in `docs/release-notes.md`.
Once a release is ready, release notes need to be written. They should summarize changes done since last release. For rough idea of expected notes see previous releases. Once written, release notes should be added to `docs/release-notes.md`.
### Commit and push update to GitHub
@@ -43,11 +43,8 @@ description should contain the release notes for the current release.
Single header version of `catch.hpp` *needs* to be attached as a binary,
as that is where the official download link links to. Preferably
it should use linux line endings. All non-bundled reporters (Automake,
TAP, TeamCity) should also be attached as binaries, as they are dependent
on a specific version of the single-include header.
TAP, TeamCity) should also be attached as binaries, as they might be
dependent on a specific version of the single-include header.
## Optional steps
Because Catch's [vcpkg](https://github.com/Microsoft/vcpkg) port updates
itself automagically, there are no optional steps at this time.
Since 2.5.0, the release tag and the "binaries" (headers) should be PGP
signed.

View File

@@ -1,6 +1,12 @@
<a id="top"></a>
# Test cases and sections
**Contents**<br>
[Tags](#tags)<br>
[Tag aliases](#tag-aliases)<br>
[BDD-style test cases](#bdd-style-test-cases)<br>
[Type parametrised test cases](#type-parametrised-test-cases)<br>
While Catch fully supports the traditional, xUnit, style of class-based fixtures containing test case methods this is not the preferred style.
Instead Catch provides a powerful mechanism for nesting test case sections within a test case. For a more detailed discussion see the [tutorial](tutorial.md#test-cases-and-sections).
@@ -86,6 +92,65 @@ When any of these macros are used the console reporter recognises them and forma
Other than the additional prefixes and the formatting in the console reporter these macros behave exactly as ```TEST_CASE```s and ```SECTION```s. As such there is nothing enforcing the correct sequencing of these macros - that's up to the programmer!
## Type parametrised test cases
In addition to `TEST_CASE`s, Catch2 also supports test cases parametrised
by type, in the form of `TEMPLATE_TEST_CASE`.
* **TEMPLATE_TEST_CASE(** _test name_ , _tags_, _type1_, _type2_, ..., _typen_ **)**
_test name_ and _tag_ are exactly the same as they are in `TEST_CASE`,
with the difference that the tag string must be provided (however, it
can be empty). _type1_ through _typen_ is the list of types for which
this test case should run, and, inside the test code, the current type
is available as the `TestType` type.
Because of limitations of the C++ preprocessor, if you want to specify
a type with multiple template parameters, you need to enclose it in
parentheses, e.g. `std::map<int, std::string>` needs to be passed as
`(std::map<int, std::string>)`.
Example:
```cpp
TEMPLATE_TEST_CASE( "vectors can be sized and resized", "[vector][template]", int, std::string, (std::tuple<int,float>) ) {
std::vector<TestType> v( 5 );
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 5 );
SECTION( "resizing bigger changes size and capacity" ) {
v.resize( 10 );
REQUIRE( v.size() == 10 );
REQUIRE( v.capacity() >= 10 );
}
SECTION( "resizing smaller changes size but not capacity" ) {
v.resize( 0 );
REQUIRE( v.size() == 0 );
REQUIRE( v.capacity() >= 5 );
SECTION( "We can use the 'swap trick' to reset the capacity" ) {
std::vector<TestType> empty;
empty.swap( v );
REQUIRE( v.capacity() == 0 );
}
}
SECTION( "reserving smaller does not change size or capacity" ) {
v.reserve( 0 );
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 5 );
}
}
```
_While there is an upper limit on the number of types you can specify
in single `TEMPLATE_TEST_CASE`, the limit is very high and should not
be encountered in practice._
---
[Home](Readme.md#top)

View File

@@ -30,6 +30,36 @@ class UniqueTestsFixture {
The two test cases here will create uniquely-named derived classes of UniqueTestsFixture and thus can access the `getID()` protected method and `conn` member variables. This ensures that both the test cases are able to create a DBConnection using the same method (DRY principle) and that any ID's created are unique such that the order that tests are executed does not matter.
Catch2 also provides `TEMPLATE_TEST_CASE_METHOD` that can be used together
with templated fixtures to perform tests for multiple different types.
However, unlike `TEST_CASE_METHOD`, `TEMPLATE_TEST_CASE_METHOD` requires
the tag specification to be non-empty, as it is followed by further macros
arguments.
Also note that, because of limitations of the C++ preprocessor, if you
want to specify a type with multiple template parameters, you need to
enclose it in parentheses, e.g. `std::map<int, std::string>` needs to be
passed as `(std::map<int, std::string>)`.
Example:
```cpp
template< typename T >
struct Template_Fixture {
Template_Fixture(): m_a(1) {}
T m_a;
};
TEMPLATE_TEST_CASE_METHOD(Template_Fixture,"A TEMPLATE_TEST_CASE_METHOD based test run that succeeds", "[class][template]", int, float, double) {
REQUIRE( Template_Fixture<TestType>::m_a == 1 );
}
```
_While there is an upper limit on the number of types you can specify
in single `TEMPLATE_TEST_CASE`, the limit is very high and should not
be encountered in practice._
---
[Home](Readme.md#top)

View File

@@ -23,7 +23,7 @@ std::ostream& operator << ( std::ostream& os, T const& value ) {
(where ```T``` is your type and ```convertMyTypeToString``` is where you'll write whatever code is necessary to make your type printable - it doesn't have to be in another function).
You should put this function in the same namespace as your type and have it declared before including Catch's header.
You should put this function in the same namespace as your type, or the global namespace, and have it declared before including Catch's header.
## Catch::StringMaker specialisation
If you don't want to provide an ```operator <<``` overload, or you want to convert your type differently for testing purposes, you can provide a specialization for `Catch::StringMaker<T>`:

View File

@@ -8,6 +8,7 @@
[Test cases and sections](#test-cases-and-sections)<br>
[BDD-Style](#bdd-style)<br>
[Scaling up](#scaling-up)<br>
[Type parametrised test cases](#type-parametrised-test-cases)<br>
[Next steps](#next-steps)<br>
## Getting Catch2
@@ -22,7 +23,7 @@ The full source for Catch2, including test projects, documentation, and other th
## Where to put it?
Catch2 is header only. All you need to do is drop the file somewhere reachable from your project - either in some central location you can set your header search path to find, or directly into your project tree itself! This is a particularly good option for other Open-Source projects that want to use Catch for their test suite. See [this blog entry for more on that](http://www.levelofindirection.com/journal/2011/5/27/unit-testing-in-c-and-objective-c-just-got-ridiculously-easi.html).
Catch2 is header only. All you need to do is drop the file somewhere reachable from your project - either in some central location you can set your header search path to find, or directly into your project tree itself! This is a particularly good option for other Open-Source projects that want to use Catch for their test suite. See [this blog entry for more on that](http://www.levelofindirection.com/journal/2011/5/27/unit-testing-in-c-and-objective-c-just-got-ridiculously-easi.html).
The rest of this tutorial will assume that the Catch2 single-include header (or the include folder) is available unqualified - but you may need to prefix it with a folder name if necessary.
@@ -31,7 +32,7 @@ package, you need to include the header as `#include <catch2/catch.hpp>`_
## Writing tests
Let's start with a really simple example ([code](../examples/010-TestCase.cpp)). Say you have written a function to calculate factorials and now you want to test it (let's leave aside TDD for now).
Let's start with a really simple example ([code](../examples/010-TestCase.cpp)). Say you have written a function to calculate factorials and now you want to test it (let's leave aside TDD for now).
```c++
unsigned int Factorial( unsigned int number ) {
@@ -122,31 +123,31 @@ Catch takes a different approach (to both NUnit and xUnit) that is a more natura
TEST_CASE( "vectors can be sized and resized", "[vector]" ) {
std::vector<int> v( 5 );
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 5 );
SECTION( "resizing bigger changes size and capacity" ) {
v.resize( 10 );
REQUIRE( v.size() == 10 );
REQUIRE( v.capacity() >= 10 );
}
SECTION( "resizing smaller changes size but not capacity" ) {
v.resize( 0 );
REQUIRE( v.size() == 0 );
REQUIRE( v.capacity() >= 5 );
}
SECTION( "reserving bigger changes capacity but not size" ) {
v.reserve( 10 );
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 10 );
}
SECTION( "reserving smaller does not change size or capacity" ) {
v.reserve( 0 );
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 5 );
}
@@ -163,13 +164,13 @@ The power of sections really shows, however, when we need to execute a sequence
```c++
SECTION( "reserving bigger changes capacity but not size" ) {
v.reserve( 10 );
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 10 );
SECTION( "reserving smaller again does not change capacity" ) {
v.reserve( 7 );
REQUIRE( v.capacity() >= 10 );
}
}
@@ -188,13 +189,13 @@ SCENARIO( "vectors can be sized and resized", "[vector]" ) {
GIVEN( "A vector with some items" ) {
std::vector<int> v( 5 );
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 5 );
WHEN( "the size is increased" ) {
v.resize( 10 );
THEN( "the size and capacity change" ) {
REQUIRE( v.size() == 10 );
REQUIRE( v.capacity() >= 10 );
@@ -202,7 +203,7 @@ SCENARIO( "vectors can be sized and resized", "[vector]" ) {
}
WHEN( "the size is reduced" ) {
v.resize( 0 );
THEN( "the size changes but not capacity" ) {
REQUIRE( v.size() == 0 );
REQUIRE( v.capacity() >= 5 );
@@ -210,7 +211,7 @@ SCENARIO( "vectors can be sized and resized", "[vector]" ) {
}
WHEN( "more capacity is reserved" ) {
v.reserve( 10 );
THEN( "the capacity changes but not the size" ) {
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 10 );
@@ -218,7 +219,7 @@ SCENARIO( "vectors can be sized and resized", "[vector]" ) {
}
WHEN( "less capacity is reserved" ) {
v.reserve( 0 );
THEN( "neither size nor capacity are changed" ) {
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 5 );
@@ -256,6 +257,16 @@ In fact it is usually a good idea to put the block with the ```#define``` [in it
Do not write your tests in header files!
## Type parametrised test cases
Test cases in Catch2 can be also parametrised by type, via the
`TEMPLATE_TEST_CASE` macro, which behaves in the same way the `TEST_CASE`
macro, but is run for every type.
For more details, see our documentation on [test cases and
sections](test-cases-and-sections.md#type-parametrised-test-cases).
## Next steps
This has been a brief introduction to get you up and running with Catch, and to point out some of the key differences between Catch and other frameworks you may already be familiar with. This will get you going quite far already and you are now in a position to dive in and write some tests.

View File

@@ -6,7 +6,7 @@ including (but not limited to),
[Google Test](http://code.google.com/p/googletest/),
[Boost.Test](http://www.boost.org/doc/libs/1_49_0/libs/test/doc/html/index.html),
[CppUnit](http://sourceforge.net/apps/mediawiki/cppunit/index.php?title=Main_Page),
[Cute](http://r2.ifs.hsr.ch/cute),
[Cute](http://www.cute-test.com),
[many, many more](http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#C.2B.2B).
So what does Catch bring to the party that differentiates it from these? Apart from a Catchy name, of course.

View File

@@ -10,8 +10,8 @@
#define TWOBLUECUBES_CATCH_HPP_INCLUDED
#define CATCH_VERSION_MAJOR 2
#define CATCH_VERSION_MINOR 4
#define CATCH_VERSION_PATCH 1
#define CATCH_VERSION_MINOR 5
#define CATCH_VERSION_PATCH 0
#ifdef __clang__
# pragma clang system_header
@@ -145,6 +145,24 @@
#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
#else
#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
#endif
#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
#define CATCH_STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__ , #__VA_ARGS__ ); CATCH_SUCCEED( #__VA_ARGS__ )
#define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ )
#else
#define CATCH_STATIC_REQUIRE( ... ) CATCH_REQUIRE( __VA_ARGS__ )
#define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ )
#endif
// "BDD-style" convenience wrappers
#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
@@ -205,6 +223,23 @@
#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
#else
#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
#endif
#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
#define STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__, #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )
#define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" )
#else
#define STATIC_REQUIRE( ... ) REQUIRE( __VA_ARGS__ )
#define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ )
#endif
#endif
#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
@@ -275,6 +310,14 @@ using Catch::Detail::Approx;
#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) )
#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className )
#else
#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) ) )
#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className ) )
#endif
// "BDD-style" convenience wrappers
#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
@@ -285,6 +328,9 @@ using Catch::Detail::Approx;
#define CATCH_THEN( desc )
#define CATCH_AND_THEN( desc )
#define CATCH_STATIC_REQUIRE( ... ) (void)(0)
#define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)
// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
#else
@@ -335,6 +381,17 @@ using Catch::Detail::Approx;
#define SUCCEED( ... ) (void)(0)
#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) )
#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className )
#else
#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) ) )
#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className ) )
#endif
#define STATIC_REQUIRE( ... ) (void)(0)
#define STATIC_REQUIRE_FALSE( ... ) (void)(0)
#endif
#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )

View File

@@ -5,7 +5,7 @@
//
// See https://github.com/philsquared/Clara for more details
// Clara v1.1.4
// Clara v1.1.5
#ifndef CATCH_CLARA_HPP_INCLUDED
#define CATCH_CLARA_HPP_INCLUDED
@@ -34,8 +34,8 @@
//
// A single-header library for wrapping and laying out basic text, by Phil Nash
//
// This work is licensed under the BSD 2-Clause license.
// See the accompanying LICENSE file, or the one at https://opensource.org/licenses/BSD-2-Clause
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// This project is hosted at https://github.com/philsquared/textflowcpp
@@ -52,317 +52,326 @@
#endif
namespace Catch { namespace clara { namespace TextFlow {
namespace Catch {
namespace clara {
namespace TextFlow {
inline auto isWhitespace( char c ) -> bool {
static std::string chars = " \t\n\r";
return chars.find( c ) != std::string::npos;
}
inline auto isBreakableBefore( char c ) -> bool {
static std::string chars = "[({<|";
return chars.find( c ) != std::string::npos;
}
inline auto isBreakableAfter( char c ) -> bool {
static std::string chars = "])}>.,:;*+-=&/\\";
return chars.find( c ) != std::string::npos;
}
inline auto isWhitespace(char c) -> bool {
static std::string chars = " \t\n\r";
return chars.find(c) != std::string::npos;
}
inline auto isBreakableBefore(char c) -> bool {
static std::string chars = "[({<|";
return chars.find(c) != std::string::npos;
}
inline auto isBreakableAfter(char c) -> bool {
static std::string chars = "])}>.,:;*+-=&/\\";
return chars.find(c) != std::string::npos;
}
class Columns;
class Columns;
class Column {
std::vector<std::string> m_strings;
size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
size_t m_indent = 0;
size_t m_initialIndent = std::string::npos;
class Column {
std::vector<std::string> m_strings;
size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
size_t m_indent = 0;
size_t m_initialIndent = std::string::npos;
public:
class iterator {
friend Column;
public:
class iterator {
friend Column;
Column const& m_column;
size_t m_stringIndex = 0;
size_t m_pos = 0;
Column const& m_column;
size_t m_stringIndex = 0;
size_t m_pos = 0;
size_t m_len = 0;
size_t m_end = 0;
bool m_suffix = false;
size_t m_len = 0;
size_t m_end = 0;
bool m_suffix = false;
iterator( Column const& column, size_t stringIndex )
: m_column( column ),
m_stringIndex( stringIndex )
{}
iterator(Column const& column, size_t stringIndex)
: m_column(column),
m_stringIndex(stringIndex) {}
auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
auto isBoundary( size_t at ) const -> bool {
assert( at > 0 );
assert( at <= line().size() );
auto isBoundary(size_t at) const -> bool {
assert(at > 0);
assert(at <= line().size());
return at == line().size() ||
( isWhitespace( line()[at] ) && !isWhitespace( line()[at-1] ) ) ||
isBreakableBefore( line()[at] ) ||
isBreakableAfter( line()[at-1] );
}
return at == line().size() ||
(isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||
isBreakableBefore(line()[at]) ||
isBreakableAfter(line()[at - 1]);
}
void calcLength() {
assert( m_stringIndex < m_column.m_strings.size() );
void calcLength() {
assert(m_stringIndex < m_column.m_strings.size());
m_suffix = false;
auto width = m_column.m_width-indent();
m_end = m_pos;
while( m_end < line().size() && line()[m_end] != '\n' )
++m_end;
m_suffix = false;
auto width = m_column.m_width - indent();
m_end = m_pos;
while (m_end < line().size() && line()[m_end] != '\n')
++m_end;
if( m_end < m_pos + width ) {
m_len = m_end - m_pos;
}
else {
size_t len = width;
while (len > 0 && !isBoundary(m_pos + len))
--len;
while (len > 0 && isWhitespace( line()[m_pos + len - 1] ))
--len;
if (m_end < m_pos + width) {
m_len = m_end - m_pos;
} else {
size_t len = width;
while (len > 0 && !isBoundary(m_pos + len))
--len;
while (len > 0 && isWhitespace(line()[m_pos + len - 1]))
--len;
if (len > 0) {
m_len = len;
} else {
m_suffix = true;
m_len = width - 1;
}
}
}
if (len > 0) {
m_len = len;
} else {
m_suffix = true;
m_len = width - 1;
}
}
}
auto indent() const -> size_t {
auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
return initial == std::string::npos ? m_column.m_indent : initial;
}
auto indent() const -> size_t {
auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
return initial == std::string::npos ? m_column.m_indent : initial;
}
auto addIndentAndSuffix(std::string const &plain) const -> std::string {
return std::string( indent(), ' ' ) + (m_suffix ? plain + "-" : plain);
}
auto addIndentAndSuffix(std::string const &plain) const -> std::string {
return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain);
}
public:
explicit iterator( Column const& column ) : m_column( column ) {
assert( m_column.m_width > m_column.m_indent );
assert( m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent );
calcLength();
if( m_len == 0 )
m_stringIndex++; // Empty string
}
public:
using difference_type = std::ptrdiff_t;
using value_type = std::string;
using pointer = value_type * ;
using reference = value_type & ;
using iterator_category = std::forward_iterator_tag;
auto operator *() const -> std::string {
assert( m_stringIndex < m_column.m_strings.size() );
assert( m_pos <= m_end );
if( m_pos + m_column.m_width < m_end )
return addIndentAndSuffix(line().substr(m_pos, m_len));
else
return addIndentAndSuffix(line().substr(m_pos, m_end - m_pos));
}
explicit iterator(Column const& column) : m_column(column) {
assert(m_column.m_width > m_column.m_indent);
assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);
calcLength();
if (m_len == 0)
m_stringIndex++; // Empty string
}
auto operator ++() -> iterator& {
m_pos += m_len;
if( m_pos < line().size() && line()[m_pos] == '\n' )
m_pos += 1;
else
while( m_pos < line().size() && isWhitespace( line()[m_pos] ) )
++m_pos;
auto operator *() const -> std::string {
assert(m_stringIndex < m_column.m_strings.size());
assert(m_pos <= m_end);
return addIndentAndSuffix(line().substr(m_pos, m_len));
}
if( m_pos == line().size() ) {
m_pos = 0;
++m_stringIndex;
}
if( m_stringIndex < m_column.m_strings.size() )
calcLength();
return *this;
}
auto operator ++(int) -> iterator {
iterator prev( *this );
operator++();
return prev;
}
auto operator ++() -> iterator& {
m_pos += m_len;
if (m_pos < line().size() && line()[m_pos] == '\n')
m_pos += 1;
else
while (m_pos < line().size() && isWhitespace(line()[m_pos]))
++m_pos;
auto operator ==( iterator const& other ) const -> bool {
return
m_pos == other.m_pos &&
m_stringIndex == other.m_stringIndex &&
&m_column == &other.m_column;
}
auto operator !=( iterator const& other ) const -> bool {
return !operator==( other );
}
};
using const_iterator = iterator;
if (m_pos == line().size()) {
m_pos = 0;
++m_stringIndex;
}
if (m_stringIndex < m_column.m_strings.size())
calcLength();
return *this;
}
auto operator ++(int) -> iterator {
iterator prev(*this);
operator++();
return prev;
}
explicit Column( std::string const& text ) { m_strings.push_back( text ); }
auto operator ==(iterator const& other) const -> bool {
return
m_pos == other.m_pos &&
m_stringIndex == other.m_stringIndex &&
&m_column == &other.m_column;
}
auto operator !=(iterator const& other) const -> bool {
return !operator==(other);
}
};
using const_iterator = iterator;
auto width( size_t newWidth ) -> Column& {
assert( newWidth > 0 );
m_width = newWidth;
return *this;
}
auto indent( size_t newIndent ) -> Column& {
m_indent = newIndent;
return *this;
}
auto initialIndent( size_t newIndent ) -> Column& {
m_initialIndent = newIndent;
return *this;
}
explicit Column(std::string const& text) { m_strings.push_back(text); }
auto width() const -> size_t { return m_width; }
auto begin() const -> iterator { return iterator( *this ); }
auto end() const -> iterator { return { *this, m_strings.size() }; }
auto width(size_t newWidth) -> Column& {
assert(newWidth > 0);
m_width = newWidth;
return *this;
}
auto indent(size_t newIndent) -> Column& {
m_indent = newIndent;
return *this;
}
auto initialIndent(size_t newIndent) -> Column& {
m_initialIndent = newIndent;
return *this;
}
inline friend std::ostream& operator << ( std::ostream& os, Column const& col ) {
bool first = true;
for( auto line : col ) {
if( first )
first = false;
else
os << "\n";
os << line;
}
return os;
}
auto width() const -> size_t { return m_width; }
auto begin() const -> iterator { return iterator(*this); }
auto end() const -> iterator { return { *this, m_strings.size() }; }
auto operator + ( Column const& other ) -> Columns;
inline friend std::ostream& operator << (std::ostream& os, Column const& col) {
bool first = true;
for (auto line : col) {
if (first)
first = false;
else
os << "\n";
os << line;
}
return os;
}
auto toString() const -> std::string {
std::ostringstream oss;
oss << *this;
return oss.str();
}
};
auto operator + (Column const& other)->Columns;
class Spacer : public Column {
auto toString() const -> std::string {
std::ostringstream oss;
oss << *this;
return oss.str();
}
};
public:
explicit Spacer( size_t spaceWidth ) : Column( "" ) {
width( spaceWidth );
}
};
class Spacer : public Column {
class Columns {
std::vector<Column> m_columns;
public:
explicit Spacer(size_t spaceWidth) : Column("") {
width(spaceWidth);
}
};
public:
class Columns {
std::vector<Column> m_columns;
class iterator {
friend Columns;
struct EndTag {};
public:
std::vector<Column> const& m_columns;
std::vector<Column::iterator> m_iterators;
size_t m_activeIterators;
class iterator {
friend Columns;
struct EndTag {};
iterator( Columns const& columns, EndTag )
: m_columns( columns.m_columns ),
m_activeIterators( 0 )
{
m_iterators.reserve( m_columns.size() );
std::vector<Column> const& m_columns;
std::vector<Column::iterator> m_iterators;
size_t m_activeIterators;
for( auto const& col : m_columns )
m_iterators.push_back( col.end() );
}
iterator(Columns const& columns, EndTag)
: m_columns(columns.m_columns),
m_activeIterators(0) {
m_iterators.reserve(m_columns.size());
public:
explicit iterator( Columns const& columns )
: m_columns( columns.m_columns ),
m_activeIterators( m_columns.size() )
{
m_iterators.reserve( m_columns.size() );
for (auto const& col : m_columns)
m_iterators.push_back(col.end());
}
for( auto const& col : m_columns )
m_iterators.push_back( col.begin() );
}
public:
using difference_type = std::ptrdiff_t;
using value_type = std::string;
using pointer = value_type * ;
using reference = value_type & ;
using iterator_category = std::forward_iterator_tag;
auto operator ==( iterator const& other ) const -> bool {
return m_iterators == other.m_iterators;
}
auto operator !=( iterator const& other ) const -> bool {
return m_iterators != other.m_iterators;
}
auto operator *() const -> std::string {
std::string row, padding;
explicit iterator(Columns const& columns)
: m_columns(columns.m_columns),
m_activeIterators(m_columns.size()) {
m_iterators.reserve(m_columns.size());
for( size_t i = 0; i < m_columns.size(); ++i ) {
auto width = m_columns[i].width();
if( m_iterators[i] != m_columns[i].end() ) {
std::string col = *m_iterators[i];
row += padding + col;
if( col.size() < width )
padding = std::string( width - col.size(), ' ' );
else
padding = "";
}
else {
padding += std::string( width, ' ' );
}
}
return row;
}
auto operator ++() -> iterator& {
for( size_t i = 0; i < m_columns.size(); ++i ) {
if (m_iterators[i] != m_columns[i].end())
++m_iterators[i];
}
return *this;
}
auto operator ++(int) -> iterator {
iterator prev( *this );
operator++();
return prev;
}
};
using const_iterator = iterator;
for (auto const& col : m_columns)
m_iterators.push_back(col.begin());
}
auto begin() const -> iterator { return iterator( *this ); }
auto end() const -> iterator { return { *this, iterator::EndTag() }; }
auto operator ==(iterator const& other) const -> bool {
return m_iterators == other.m_iterators;
}
auto operator !=(iterator const& other) const -> bool {
return m_iterators != other.m_iterators;
}
auto operator *() const -> std::string {
std::string row, padding;
auto operator += ( Column const& col ) -> Columns& {
m_columns.push_back( col );
return *this;
}
auto operator + ( Column const& col ) -> Columns {
Columns combined = *this;
combined += col;
return combined;
}
for (size_t i = 0; i < m_columns.size(); ++i) {
auto width = m_columns[i].width();
if (m_iterators[i] != m_columns[i].end()) {
std::string col = *m_iterators[i];
row += padding + col;
if (col.size() < width)
padding = std::string(width - col.size(), ' ');
else
padding = "";
} else {
padding += std::string(width, ' ');
}
}
return row;
}
auto operator ++() -> iterator& {
for (size_t i = 0; i < m_columns.size(); ++i) {
if (m_iterators[i] != m_columns[i].end())
++m_iterators[i];
}
return *this;
}
auto operator ++(int) -> iterator {
iterator prev(*this);
operator++();
return prev;
}
};
using const_iterator = iterator;
inline friend std::ostream& operator << ( std::ostream& os, Columns const& cols ) {
auto begin() const -> iterator { return iterator(*this); }
auto end() const -> iterator { return { *this, iterator::EndTag() }; }
bool first = true;
for( auto line : cols ) {
if( first )
first = false;
else
os << "\n";
os << line;
}
return os;
}
auto operator += (Column const& col) -> Columns& {
m_columns.push_back(col);
return *this;
}
auto operator + (Column const& col) -> Columns {
Columns combined = *this;
combined += col;
return combined;
}
auto toString() const -> std::string {
std::ostringstream oss;
oss << *this;
return oss.str();
}
};
inline friend std::ostream& operator << (std::ostream& os, Columns const& cols) {
inline auto Column::operator + ( Column const& other ) -> Columns {
Columns cols;
cols += *this;
cols += other;
return cols;
}
}}} // namespace Catch::clara::TextFlow
bool first = true;
for (auto line : cols) {
if (first)
first = false;
else
os << "\n";
os << line;
}
return os;
}
auto toString() const -> std::string {
std::ostringstream oss;
oss << *this;
return oss.str();
}
};
inline auto Column::operator + (Column const& other) -> Columns {
Columns cols;
cols += *this;
cols += other;
return cols;
}
}
}
}
#endif // CATCH_CLARA_TEXTFLOW_HPP_INCLUDED
// ----------- end of #include from clara_textflow.hpp -----------
// ........... back in clara.hpp
#include <string>
#include <memory>
#include <set>
#include <algorithm>

View File

@@ -10,6 +10,9 @@
#include "catch_string_manip.h"
#include "catch_interfaces_registry_hub.h"
#include "catch_interfaces_reporter.h"
#include <fstream>
#include <ctime>
@@ -105,6 +108,18 @@ namespace Catch {
return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" );
return ParserResult::ok( ParseResultType::Matched );
};
auto const setReporter = [&]( std::string const& reporter ) {
IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
auto lcReporter = toLower( reporter );
auto result = factories.find( lcReporter );
if( factories.end() != result )
config.reporterName = lcReporter;
else
return ParserResult::runtimeError( "Unrecognized reporter, '" + reporter + "'. Check available with --list-reporters" );
return ParserResult::ok( ParseResultType::Matched );
};
auto cli
= ExeName( config.processName )
@@ -130,7 +145,7 @@ namespace Catch {
| Opt( config.outputFilename, "filename" )
["-o"]["--out"]
( "output filename" )
| Opt( config.reporterName, "name" )
| Opt( setReporter, "name" )
["-r"]["--reporter"]
( "reporter to use (defaults to console)" )
| Opt( config.name, "name" )

View File

@@ -22,6 +22,10 @@
#include <string>
#include <cstdint>
// We need a dummy global operator<< so we can bring it into Catch namespace later
struct Catch_global_namespace_dummy {};
std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
namespace Catch {
struct CaseSensitive { enum Choice {
@@ -63,6 +67,11 @@ namespace Catch {
std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
// Bring in operator<< from global namespace into Catch namespace
// This is necessary because the overload of operator<< above makes
// lookup stop at namespace Catch
using ::operator<<;
// Use this in variadic streaming macros to allow
// >> +StreamEndStop
// as well as

View File

@@ -136,6 +136,13 @@
# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
# endif
// MSVC traditional preprocessor needs some workaround for __VA_ARGS__
// _MSVC_TRADITIONAL == 0 means new conformant preprocessor
// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
# endif
#endif // _MSC_VER
////////////////////////////////////////////////////////////////////////////////
@@ -150,6 +157,12 @@
# define CATCH_INTERNAL_CONFIG_NO_WCHAR
#endif // __DJGPP__
////////////////////////////////////////////////////////////////////////////////
// Embarcadero C++Build
#if defined(__BORLANDC__)
#define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN
#endif
////////////////////////////////////////////////////////////////////////////////
// Use of __COUNTER__ is suppressed during code analysis in
@@ -231,6 +244,10 @@
# define CATCH_CONFIG_DISABLE_EXCEPTIONS
#endif
#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN)
# define CATCH_CONFIG_POLYFILL_ISNAN
#endif
#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
@@ -254,6 +271,9 @@
#define CATCH_CATCH_ANON(type) catch (type)
#endif
#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)
#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#endif
#endif // TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED

View File

@@ -6,6 +6,7 @@
*/
#include "catch_leak_detector.h"
#include "catch_interfaces_registry_hub.h"
#ifdef CATCH_CONFIG_WINDOWS_CRTDBG
@@ -30,3 +31,7 @@ namespace Catch {
Catch::LeakDetector::LeakDetector() {}
#endif
Catch::LeakDetector::~LeakDetector() {
Catch::cleanUp();
}

View File

@@ -11,6 +11,7 @@ namespace Catch {
struct LeakDetector {
LeakDetector();
~LeakDetector();
};
}

View File

@@ -124,7 +124,7 @@ namespace Catch {
return tagCounts.size();
}
std::size_t listReporters( Config const& /*config*/ ) {
std::size_t listReporters() {
Catch::cout() << "Available reporters:\n";
IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
std::size_t maxNameLen = 0;
@@ -155,7 +155,7 @@ namespace Catch {
if( config.listTags() )
listedCount = listedCount.valueOr(0) + listTags( config );
if( config.listReporters() )
listedCount = listedCount.valueOr(0) + listReporters( config );
listedCount = listedCount.valueOr(0) + listReporters();
return listedCount;
}

View File

@@ -29,7 +29,7 @@ namespace Catch {
std::size_t listTags( Config const& config );
std::size_t listReporters( Config const& /*config*/ );
std::size_t listReporters();
Option<std::size_t> list( Config const& config );

View File

@@ -43,10 +43,6 @@ namespace Matchers {
struct MatcherMethod {
virtual bool match( ObjectT const& arg ) const = 0;
};
template<typename PtrT>
struct MatcherMethod<PtrT*> {
virtual bool match( PtrT* arg ) const = 0;
};
#ifdef __clang__
# pragma clang diagnostic pop

View File

@@ -7,6 +7,7 @@
#include "catch_matchers_floating.h"
#include "catch_enforce.h"
#include "catch_polyfills.hpp"
#include "catch_to_string.hpp"
#include "catch_tostring.h"
@@ -57,7 +58,7 @@ template <typename FP>
bool almostEqualUlps(FP lhs, FP rhs, int maxUlpDiff) {
// Comparison with NaN should always be false.
// This way we can rule it out before getting into the ugly details
if (std::isnan(lhs) || std::isnan(rhs)) {
if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
return false;
}

View File

@@ -11,6 +11,7 @@
#include "catch_uncaught_exceptions.h"
#include <cassert>
#include <stack>
namespace Catch {
@@ -60,19 +61,48 @@ namespace Catch {
Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {
auto start = std::string::npos;
for( size_t pos = 0; pos <= names.size(); ++pos ) {
auto trimmed = [&] (size_t start, size_t end) {
while (names[start] == ',' || isspace(names[start])) {
++start;
}
while (names[end] == ',' || isspace(names[end])) {
--end;
}
return names.substr(start, end - start + 1);
};
size_t start = 0;
std::stack<char> openings;
for (size_t pos = 0; pos < names.size(); ++pos) {
char c = names[pos];
if( pos == names.size() || c == ' ' || c == '\t' || c == ',' || c == ']' ) {
if( start != std::string::npos ) {
m_messages.push_back( MessageInfo( macroName, lineInfo, resultType ) );
m_messages.back().message = names.substr( start, pos-start) + " := ";
start = std::string::npos;
switch (c) {
case '[':
case '{':
case '(':
// It is basically impossible to disambiguate between
// comparison and start of template args in this context
// case '<':
openings.push(c);
break;
case ']':
case '}':
case ')':
// case '>':
openings.pop();
break;
case ',':
if (start != pos && openings.size() == 0) {
m_messages.emplace_back(macroName, lineInfo, resultType);
m_messages.back().message = trimmed(start, pos);
m_messages.back().message += " := ";
start = pos;
}
}
else if( c != '[' && c != ']' && start == std::string::npos )
start = pos;
}
assert(openings.size() == 0 && "Mismatched openings");
m_messages.emplace_back(macroName, lineInfo, resultType);
m_messages.back().message = trimmed(start, names.size() - 1);
m_messages.back().message += " := ";
}
Capturer::~Capturer() {
if ( !uncaught_exceptions() ){
@@ -82,7 +112,7 @@ namespace Catch {
}
}
void Capturer::captureValue( size_t index, StringRef value ) {
void Capturer::captureValue( size_t index, std::string const& value ) {
assert( index < m_messages.size() );
m_messages[index].message += value;
m_resultCapture.pushScopedMessage( m_messages[index] );

View File

@@ -77,16 +77,16 @@ namespace Catch {
Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
~Capturer();
void captureValue( size_t index, StringRef value );
void captureValue( size_t index, std::string const& value );
template<typename T>
void captureValues( size_t index, T&& value ) {
void captureValues( size_t index, T const& value ) {
captureValue( index, Catch::Detail::stringify( value ) );
}
template<typename T, typename... Ts>
void captureValues( size_t index, T&& value, Ts&&... values ) {
captureValues( index, value );
void captureValues( size_t index, T const& value, Ts const&... values ) {
captureValue( index, Catch::Detail::stringify(value) );
captureValues( index+1, values... );
}
};

View File

@@ -0,0 +1,31 @@
/*
* Created by Martin on 17/11/2017.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include "catch_polyfills.hpp"
#include <cmath>
namespace Catch {
#if !defined(CATCH_CONFIG_POLYFILL_ISNAN)
bool isnan(float f) {
return std::isnan(f);
}
bool isnan(double d) {
return std::isnan(d);
}
#else
// For now we only use this for embarcadero
bool isnan(float f) {
return std::_isnan(f);
}
bool isnan(double d) {
return std::_isnan(d);
}
#endif
} // end namespace Catch

View File

@@ -0,0 +1,15 @@
/*
* Created by Martin on 17/11/2017.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_POLYFILLS_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_POLYFILLS_HPP_INCLUDED
namespace Catch {
bool isnan(float f);
bool isnan(double d);
}
#endif // TWOBLUECUBES_CATCH_POLYFILLS_HPP_INCLUDED

View File

@@ -0,0 +1,74 @@
/*
* Created by Jozef on 12/11/2018.
* Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_PREPROCESSOR_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_PREPROCESSOR_HPP_INCLUDED
#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__
#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))
#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))
#define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))
#define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))
#define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))
#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__
// MSVC needs more evaluations
#define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))
#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))
#else
#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__)
#endif
#define CATCH_REC_END(...)
#define CATCH_REC_OUT
#define CATCH_EMPTY()
#define CATCH_DEFER(id) id CATCH_EMPTY()
#define CATCH_REC_GET_END2() 0, CATCH_REC_END
#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2
#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1
#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT
#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0)
#define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)
#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ )
#define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )
#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ )
#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )
// Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,
// and passes userdata as the first parameter to each invocation,
// e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)
#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
#define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
#define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)
#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name, __VA_ARGS__)
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name,...) Name " - " #__VA_ARGS__
#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME(Name,...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
#else
// MSVC is adding extra space and needs more calls to properly remove ()
#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name,...) Name " -" #__VA_ARGS__
#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME1(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, __VA_ARGS__)
#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME1(Name, INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
#endif
#endif // TWOBLUECUBES_CATCH_PREPROCESSOR_HPP_INCLUDED

View File

@@ -54,8 +54,6 @@ namespace Catch {
Catch::Totals runTests(std::shared_ptr<Config> const& config) {
// FixMe: Add listeners in order first, then add reporters.
auto reporter = makeReporter(config);
RunContext context(config, std::move(reporter));
@@ -185,22 +183,8 @@ namespace Catch {
return 0;
}
void Session::useConfigData( ConfigData const& configData ) {
m_configData = configData;
m_config.reset();
}
int Session::run( int argc, char* argv[] ) {
if( m_startupExceptions )
return 1;
int returnCode = applyCommandLine( argc, argv );
if( returnCode == 0 )
returnCode = run();
return returnCode;
}
#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
int Session::run( int argc, wchar_t* const argv[] ) {
int Session::applyCommandLine( int argc, wchar_t const * const * argv ) {
char **utf8Argv = new char *[ argc ];
@@ -212,7 +196,7 @@ namespace Catch {
WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
}
int returnCode = run( argc, utf8Argv );
int returnCode = applyCommandLine( argc, utf8Argv );
for ( int i = 0; i < argc; ++i )
delete [] utf8Argv[ i ];
@@ -222,6 +206,12 @@ namespace Catch {
return returnCode;
}
#endif
void Session::useConfigData( ConfigData const& configData ) {
m_configData = configData;
m_config.reset();
}
int Session::run() {
if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
Catch::cout() << "...waiting for enter/ return before starting" << std::endl;

View File

@@ -26,13 +26,22 @@ namespace Catch {
void libIdentify();
int applyCommandLine( int argc, char const * const * argv );
#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
int applyCommandLine( int argc, wchar_t const * const * argv );
#endif
void useConfigData( ConfigData const& configData );
int run( int argc, char* argv[] );
#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
int run( int argc, wchar_t* const argv[] );
#endif
template<typename CharT>
int run(int argc, CharT const * const argv[]) {
if (m_startupExceptions)
return 1;
int returnCode = applyCommandLine(argc, argv);
if (returnCode == 0)
returnCode = run();
return returnCode;
}
int run();
clara::Parser const& cli() const;

View File

@@ -12,6 +12,8 @@
#include "catch_interfaces_testcase.h"
#include "catch_compiler_capabilities.h"
#include "catch_stringref.h"
#include "catch_type_traits.hpp"
#include "catch_preprocessor.hpp"
namespace Catch {
@@ -47,22 +49,28 @@ struct AutoReg : NonCopyable {
} // end namespace Catch
#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
#if defined(CATCH_CONFIG_DISABLE)
#define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
static void TestName()
#define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
namespace{ \
struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
void test(); \
}; \
} \
void TestName::test()
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION( TestName, ... ) \
template<typename TestType> \
static void TestName()
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
namespace{ \
template<typename TestType> \
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
void test(); \
}; \
} \
template<typename TestType> \
void TestName::test()
#endif
///////////////////////////////////////////////////////////////////////////////
@@ -85,7 +93,7 @@ struct AutoReg : NonCopyable {
#define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
namespace{ \
struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
void test(); \
}; \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
@@ -101,5 +109,75 @@ struct AutoReg : NonCopyable {
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, ... )\
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
template<typename TestType> \
static void TestFunc();\
namespace {\
template<typename...Types> \
struct TestName{\
template<typename...Ts> \
TestName(Ts...names){\
CATCH_INTERNAL_CHECK_UNIQUE_TYPES(CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)) \
using expander = int[];\
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ names, Tags } ), 0)... };/* NOLINT */ \
}\
};\
INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestName, Name, __VA_ARGS__) \
}\
CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
template<typename TestType> \
static void TestFunc()
#if defined(CATCH_CPP17_OR_GREATER)
#define CATCH_INTERNAL_CHECK_UNIQUE_TYPES(...) static_assert(Catch::is_unique<__VA_ARGS__>,"Duplicate type detected in declaration of template test case");
#else
#define CATCH_INTERNAL_CHECK_UNIQUE_TYPES(...) static_assert(Catch::is_unique<__VA_ARGS__>::value,"Duplicate type detected in declaration of template test case");
#endif
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, __VA_ARGS__ )
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, __VA_ARGS__ ) )
#endif
#define INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestName, Name, ...)\
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
TestName<CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)>(CATCH_REC_LIST_UD(INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME,Name, __VA_ARGS__));\
return 0;\
}();
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, ... ) \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
namespace{ \
template<typename TestType> \
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
void test();\
};\
template<typename...Types> \
struct TestNameClass{\
template<typename...Ts> \
TestNameClass(Ts...names){\
CATCH_INTERNAL_CHECK_UNIQUE_TYPES(CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)) \
using expander = int[];\
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ names, Tags } ), 0)... };/* NOLINT */ \
}\
};\
INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestNameClass, Name, __VA_ARGS__)\
}\
CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS\
template<typename TestType> \
void TestName<TestType>::test()
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, __VA_ARGS__ )
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, __VA_ARGS__ ) )
#endif
#endif // TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED

View File

@@ -20,6 +20,7 @@
#include "catch_tostring.h"
#include "catch_interfaces_config.h"
#include "catch_context.h"
#include "catch_polyfills.hpp"
#include <cmath>
#include <iomanip>
@@ -68,7 +69,7 @@ namespace Detail {
template<typename T>
std::string fpToString( T value, int precision ) {
if (std::isnan(value)) {
if (Catch::isnan(value)) {
return "nan";
}
@@ -205,7 +206,7 @@ std::string StringMaker<bool>::convert(bool b) {
return b ? "true" : "false";
}
std::string StringMaker<char>::convert(char value) {
std::string StringMaker<signed char>::convert(signed char value) {
if (value == '\r') {
return "'\\r'";
} else if (value == '\f') {
@@ -222,8 +223,8 @@ std::string StringMaker<char>::convert(char value) {
return chstr;
}
}
std::string StringMaker<signed char>::convert(signed char c) {
return ::Catch::Detail::stringify(static_cast<char>(c));
std::string StringMaker<char>::convert(char c) {
return ::Catch::Detail::stringify(static_cast<signed char>(c));
}
std::string StringMaker<unsigned char>::convert(unsigned char c) {
return ::Catch::Detail::stringify(static_cast<char>(c));

View File

@@ -29,15 +29,7 @@
#pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
#endif
// We need a dummy global operator<< so we can bring it into Catch namespace later
struct Catch_global_namespace_dummy {};
std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
namespace Catch {
// Bring in operator<< from global namespace into Catch namespace
using ::operator<<;
namespace Detail {
extern const std::string unprintableString;

View File

@@ -0,0 +1,38 @@
/*
* Created by Jozef on 12/11/2018.
* Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED
namespace Catch{
#ifdef CATCH_CPP17_OR_GREATER
template <typename...>
inline constexpr auto is_unique = std::true_type{};
template <typename T, typename... Rest>
inline constexpr auto is_unique<T, Rest...> = std::bool_constant<
(!std::is_same_v<T, Rest> && ...) && is_unique<Rest...>
>{};
#else
template <typename...>
struct is_unique : std::true_type{};
template <typename T0, typename T1, typename... Rest>
struct is_unique<T0, T1, Rest...> : std::integral_constant
<bool,
!std::is_same<T0, T1>::value
&& is_unique<T0, Rest...>::value
&& is_unique<T1, Rest...>::value
>{};
#endif
}
#endif // TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED

View File

@@ -37,7 +37,7 @@ namespace Catch {
}
Version const& libraryVersion() {
static Version version( 2, 4, 1, "", 0 );
static Version version( 2, 5, 0, "", 0 );
return version;
}

View File

@@ -30,7 +30,7 @@ namespace Catch {
// + 1 for null terminator
const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
char buffer[maxDoubleSize];
// Save previous errno, to prevent sprintf from overwriting it
ErrnoGuard guard;
#ifdef _MSC_VER
@@ -45,6 +45,10 @@ namespace Catch {
TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)
:StreamingReporterBase(_config) {}
std::set<Verbosity> TestEventListenerBase::getSupportedVerbosities() {
return { Verbosity::Quiet, Verbosity::Normal, Verbosity::High };
}
void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}
bool TestEventListenerBase::assertionEnded(AssertionStats const &) {

View File

@@ -217,7 +217,7 @@ namespace Catch {
node->children.push_back(m_rootSection);
m_testCases.push_back(node);
m_rootSection.reset();
assert(m_deepestSection);
m_deepestSection->stdOut = testCaseStats.stdOut;
m_deepestSection->stdErr = testCaseStats.stdErr;
@@ -266,6 +266,8 @@ namespace Catch {
struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {
TestEventListenerBase( ReporterConfig const& _config );
static std::set<Verbosity> getSupportedVerbosities();
void assertionStarting(AssertionInfo const&) override;
bool assertionEnded(AssertionStats const&) override;
};

View File

@@ -111,8 +111,6 @@ public:
void print() const {
printSourceInfo();
if (stats.totals.assertions.total() > 0) {
if (result.isOk())
stream << '\n';
printResultType();
printOriginalExpression();
printReconstructedExpression();

View File

@@ -55,6 +55,9 @@ namespace Catch {
m_xml.startElement( "Catch" );
if( !m_config->name().empty() )
m_xml.writeAttribute( "name", m_config->name() );
if( m_config->rngSeed() != 0 )
m_xml.scopedElement( "Randomness" )
.writeAttribute( "seed", m_config->rngSeed() );
}
void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) {

View File

@@ -123,6 +123,8 @@ set(INTERNAL_HEADERS
${HEADER_DIR}/internal/catch_option.hpp
${HEADER_DIR}/internal/catch_output_redirect.h
${HEADER_DIR}/internal/catch_platform.h
${HEADER_DIR}/internal/catch_polyfills.hpp
${HEADER_DIR}/internal/catch_preprocessor.hpp
${HEADER_DIR}/internal/catch_random_number_generator.h
${HEADER_DIR}/internal/catch_reenable_warnings.h
${HEADER_DIR}/internal/catch_reporter_registrars.hpp
@@ -153,6 +155,7 @@ set(INTERNAL_HEADERS
${HEADER_DIR}/internal/catch_to_string.hpp
${HEADER_DIR}/internal/catch_tostring.h
${HEADER_DIR}/internal/catch_totals.h
${HEADER_DIR}/internal/catch_type_traits.hpp
${HEADER_DIR}/internal/catch_uncaught_exceptions.h
${HEADER_DIR}/internal/catch_user_interfaces.h
${HEADER_DIR}/internal/catch_version.h
@@ -196,6 +199,7 @@ set(IMPL_SOURCES
${HEADER_DIR}/internal/catch_output_redirect.cpp
${HEADER_DIR}/internal/catch_registry_hub.cpp
${HEADER_DIR}/internal/catch_interfaces_reporter.cpp
${HEADER_DIR}/internal/catch_polyfills.cpp
${HEADER_DIR}/internal/catch_random_number_generator.cpp
${HEADER_DIR}/internal/catch_reporter_registry.cpp
${HEADER_DIR}/internal/catch_result_type.cpp
@@ -303,7 +307,7 @@ if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
endif()
if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
STRING(REGEX REPLACE "/W[0-9]" "/W4" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) # override default warning level
target_compile_options( SelfTest PRIVATE /w44265 /w44061 /w44062 )
target_compile_options( SelfTest PRIVATE /w44265 /w44061 /w44062 /w45038 )
if (CATCH_ENABLE_WERROR)
target_compile_options( SelfTest PRIVATE /WX)
endif()

View File

@@ -2,8 +2,12 @@
// Test that Catch's prefixed macros compile and run properly.
#define CATCH_CONFIG_MAIN
// This won't provide full coverage, but it might be worth checking
// the other branch as well
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch.hpp>
#include <type_traits>
#include <stdexcept>
[[noreturn]]
@@ -23,7 +27,7 @@ CATCH_TEST_CASE("PrefixedMacros") {
CATCH_REQUIRE_THROWS_WITH(this_throws(), "Some msg");
CATCH_REQUIRE_THROWS_MATCHES(this_throws(), std::runtime_error, Predicate<std::runtime_error>([](std::runtime_error const&) { return true; }));
CATCH_REQUIRE_NOTHROW(this_doesnt_throw());
CATCH_CHECK( 1 == 1 );
CATCH_CHECK_FALSE( 1 != 1 );
CATCH_CHECKED_IF( 1 == 1 ) {
@@ -31,15 +35,15 @@ CATCH_TEST_CASE("PrefixedMacros") {
} CATCH_CHECKED_ELSE ( 1 == 1 ) {
CATCH_SUCCEED("don't care");
}
CATCH_CHECK_NOFAIL(1 == 2);
CATCH_CHECK_THROWS(this_throws());
CATCH_CHECK_THROWS_AS(this_throws(), std::runtime_error);
CATCH_CHECK_THROWS_WITH(this_throws(), "Some msg");
CATCH_CHECK_THROWS_MATCHES(this_throws(), std::runtime_error, Predicate<std::runtime_error>([](std::runtime_error const&) { return true; }));
CATCH_CHECK_NOTHROW(this_doesnt_throw());
CATCH_CHECK_NOTHROW(this_doesnt_throw());
CATCH_REQUIRE_THAT("abcd", Equals("abcd"));
CATCH_CHECK_THAT("bdef", Equals("bdef"));
@@ -52,6 +56,9 @@ CATCH_TEST_CASE("PrefixedMacros") {
CATCH_FAIL_CHECK( "failure" );
}
}
CATCH_STATIC_REQUIRE( std::is_void<void>::value );
CATCH_STATIC_REQUIRE_FALSE( std::is_void<int>::value );
}
CATCH_ANON_TEST_CASE() {

View File

@@ -13,6 +13,7 @@ Misc.tests.cpp:<line number>: passed:
Compilation.tests.cpp:<line number>: passed: std::memcmp(uarr, "123", sizeof(uarr)) == 0 for: 0 == 0 with 2 messages: 'uarr := "123"' and 'sarr := "456"'
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]
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42' with 1 message: 'expected exception'
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42'; expression was: thisThrows() with 1 message: 'expected exception'
Exception.tests.cpp:<line number>: passed: thisThrows() with 1 message: 'answer := 42'
@@ -158,6 +159,12 @@ Generators.tests.cpp:<line number>: passed: x < y for: 10 < 109
Generators.tests.cpp:<line number>: passed: x < y for: 10 < 110
Class.tests.cpp:<line number>: failed: s == "world" for: "hello" == "world"
Class.tests.cpp:<line number>: passed: s == "hello" for: "hello" == "hello"
Class.tests.cpp:<line number>: failed: Template_Fixture<TestType>::m_a == 2 for: 1.0 == 2
Class.tests.cpp:<line number>: failed: Template_Fixture<TestType>::m_a == 2 for: 1.0f == 2
Class.tests.cpp:<line number>: failed: Template_Fixture<TestType>::m_a == 2 for: 1 == 2
Class.tests.cpp:<line number>: passed: Template_Fixture<TestType>::m_a == 1 for: 1.0 == 1
Class.tests.cpp:<line number>: passed: Template_Fixture<TestType>::m_a == 1 for: 1.0f == 1
Class.tests.cpp:<line number>: passed: Template_Fixture<TestType>::m_a == 1 for: 1 == 1
Class.tests.cpp:<line number>: failed: m_a == 2 for: 1 == 2
Class.tests.cpp:<line number>: passed: m_a == 1 for: 1 == 1
Approx.tests.cpp:<line number>: passed: d == 1.23_a for: 1.23 == Approx( 1.23 )
@@ -221,18 +228,20 @@ Approx.tests.cpp:<line number>: passed: NAN != Approx(NAN) for: nanf != Approx(
Approx.tests.cpp:<line number>: passed: !(NAN == Approx(NAN)) for: !(nanf == Approx( nan ))
Tricky.tests.cpp:<line number>: passed: y.v == 0 for: 0 == 0
Tricky.tests.cpp:<line number>: passed: 0 == y.v for: 0 == 0
Message.tests.cpp:<line number>: passed: with 7 messages: 'a := 1' and 'b := 2' and 'c := 3' and 'a + b := 3' and 'a+b := 3' and 'c > b := true' and 'a == 1 := true'
Message.tests.cpp:<line number>: passed: with 7 messages: 'std::vector<int>{1, 2, 3}[0, 1, 2] := 3' and 'std::vector<int>{1, 2, 3}[(0, 1)] := 2' and 'std::vector<int>{1, 2, 3}[0] := 1' and '(helper_1436<int, int>{12, -12}) := { 12, -12 }' and '(helper_1436<int, int>(-12, 12)) := { -12, 12 }' and '(1, 2) := 2' and '(2, 3) := 3'
ToStringGeneral.tests.cpp:<line number>: passed: true with 1 message: 'i := 2'
ToStringGeneral.tests.cpp:<line number>: passed: true with 1 message: '3'
ToStringGeneral.tests.cpp:<line number>: passed: tab == '/t' for: '/t' == '/t'
ToStringGeneral.tests.cpp:<line number>: passed: newline == '/n' for: '/n' == '/n'
ToStringGeneral.tests.cpp:<line number>: passed: carr_return == '/r' for: '/r' == '/r'
ToStringGeneral.tests.cpp:<line number>: passed: form_feed == '/f' for: '/f' == '/f'
ToStringGeneral.tests.cpp:<line number>: passed: tab == '\t' for: '\t' == '\t'
ToStringGeneral.tests.cpp:<line number>: passed: newline == '\n' for: '\n' == '\n'
ToStringGeneral.tests.cpp:<line number>: passed: carr_return == '\r' for: '\r' == '\r'
ToStringGeneral.tests.cpp:<line number>: passed: form_feed == '\f' for: '\f' == '\f'
ToStringGeneral.tests.cpp:<line number>: passed: space == ' ' for: ' ' == ' '
ToStringGeneral.tests.cpp:<line number>: passed: c == chars[i] for: 'a' == 'a'
ToStringGeneral.tests.cpp:<line number>: passed: c == chars[i] for: 'z' == 'z'
ToStringGeneral.tests.cpp:<line number>: passed: c == chars[i] for: 'A' == 'A'
ToStringGeneral.tests.cpp:<line number>: passed: c == chars[i] for: 'Z' == 'Z'
ToStringGeneral.tests.cpp:<line number>: passed: null_terminator == '/0' for: 0 == 0
ToStringGeneral.tests.cpp:<line number>: passed: null_terminator == '\0' for: 0 == 0
ToStringGeneral.tests.cpp:<line number>: passed: c == i for: 2 == 2
ToStringGeneral.tests.cpp:<line number>: passed: c == i for: 3 == 3
ToStringGeneral.tests.cpp:<line number>: passed: c == i for: 4 == 4
@@ -495,6 +504,8 @@ Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'c
Tricky.tests.cpp:<line number>: passed: True for: {?}
Tricky.tests.cpp:<line number>: passed: !False for: true
Tricky.tests.cpp:<line number>: passed: !(False) for: !{?}
Compilation.tests.cpp:<line number>: passed: with 1 message: 'std::is_void<void>::value'
Compilation.tests.cpp:<line number>: passed: with 1 message: '!(std::is_void<int>::value)'
Condition.tests.cpp:<line number>: failed: data.int_seven > 7 for: 7 > 7
Condition.tests.cpp:<line number>: failed: data.int_seven < 7 for: 7 < 7
Condition.tests.cpp:<line number>: failed: data.int_seven > 8 for: 7 > 8
@@ -676,6 +687,7 @@ Condition.tests.cpp:<line number>: passed: cpc != 0 for: 0x<hex digits> != 0
Condition.tests.cpp:<line number>: passed: returnsNull() == 0 for: {null string} == 0
Condition.tests.cpp:<line number>: passed: returnsConstNull() == 0 for: {null string} == 0
Condition.tests.cpp:<line number>: passed: 0 != p for: 0 != 0x<hex digits>
Matchers.tests.cpp:<line number>: passed: "foo", Predicate<const char*>([] (const char* const&) { return true; }) for: "foo" matches undescribed predicate
CmdLine.tests.cpp:<line number>: passed: result for: {?}
CmdLine.tests.cpp:<line number>: passed: config.processName == "" for: "" == ""
CmdLine.tests.cpp:<line number>: passed: result for: {?}
@@ -704,6 +716,8 @@ CmdLine.tests.cpp:<line number>: passed: config.reporterName == "xml" for: "xml"
CmdLine.tests.cpp:<line number>: passed: cli.parse({"test", "--reporter", "junit"}) for: {?}
CmdLine.tests.cpp:<line number>: passed: config.reporterName == "junit" for: "junit" == "junit"
CmdLine.tests.cpp:<line number>: passed: !(cli.parse({ "test", "-r", "xml", "-r", "junit" })) for: !{?}
CmdLine.tests.cpp:<line number>: passed: !result for: true
CmdLine.tests.cpp:<line number>: passed: result.errorMessage(), Contains("Unrecognized reporter") for: "Unrecognized reporter, 'unsupported'. Check available with --list-reporters" contains: "Unrecognized reporter"
CmdLine.tests.cpp:<line number>: passed: cli.parse({"test", "-b"}) for: {?}
CmdLine.tests.cpp:<line number>: passed: config.shouldDebugBreak == true for: true == true
CmdLine.tests.cpp:<line number>: passed: cli.parse({"test", "--break"}) for: {?}
@@ -865,6 +879,74 @@ TagAlias.tests.cpp:<line number>: passed: registry.add( "[no ampersat]", "", Cat
TagAlias.tests.cpp:<line number>: passed: registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) )
TagAlias.tests.cpp:<line number>: passed: registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) )
TagAlias.tests.cpp:<line number>: passed: registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) )
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: v.size() == 10 for: 10 == 10
Misc.tests.cpp:<line number>: passed: v.capacity() >= 10 for: 10 >= 10
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: v.size() == 0 for: 0 == 0
Misc.tests.cpp:<line number>: passed: v.capacity() >= 5 for: 5 >= 5
Misc.tests.cpp:<line number>: passed: v.capacity() == 0 for: 0 == 0
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: v.size() == 5 for: 5 == 5
Misc.tests.cpp:<line number>: passed: v.capacity() >= 10 for: 10 >= 10
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: v.size() == 5 for: 5 == 5
Misc.tests.cpp:<line number>: passed: v.capacity() >= 5 for: 5 >= 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: v.size() == 10 for: 10 == 10
Misc.tests.cpp:<line number>: passed: v.capacity() >= 10 for: 10 >= 10
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: v.size() == 0 for: 0 == 0
Misc.tests.cpp:<line number>: passed: v.capacity() >= 5 for: 5 >= 5
Misc.tests.cpp:<line number>: passed: v.capacity() == 0 for: 0 == 0
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: v.size() == 5 for: 5 == 5
Misc.tests.cpp:<line number>: passed: v.capacity() >= 10 for: 10 >= 10
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: v.size() == 5 for: 5 == 5
Misc.tests.cpp:<line number>: passed: v.capacity() >= 5 for: 5 >= 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: v.size() == 10 for: 10 == 10
Misc.tests.cpp:<line number>: passed: v.capacity() >= 10 for: 10 >= 10
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: v.size() == 0 for: 0 == 0
Misc.tests.cpp:<line number>: passed: v.capacity() >= 5 for: 5 >= 5
Misc.tests.cpp:<line number>: passed: v.capacity() == 0 for: 0 == 0
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: v.size() == 5 for: 5 == 5
Misc.tests.cpp:<line number>: passed: v.capacity() >= 10 for: 10 >= 10
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: v.size() == 5 for: 5 == 5
Misc.tests.cpp:<line number>: passed: v.capacity() >= 5 for: 5 >= 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: v.size() == 10 for: 10 == 10
Misc.tests.cpp:<line number>: passed: v.capacity() >= 10 for: 10 >= 10
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: v.size() == 0 for: 0 == 0
Misc.tests.cpp:<line number>: passed: v.capacity() >= 5 for: 5 >= 5
Misc.tests.cpp:<line number>: passed: v.capacity() == 0 for: 0 == 0
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: v.size() == 5 for: 5 == 5
Misc.tests.cpp:<line number>: passed: v.capacity() >= 10 for: 10 >= 10
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: v.size() == 5 for: 5 == 5
Misc.tests.cpp:<line number>: passed: v.capacity() >= 5 for: 5 >= 5
VariadicMacros.tests.cpp:<line number>: passed: with 1 message: 'no assertions'
Tricky.tests.cpp:<line number>: passed: 0x<hex digits> == bit30and31 for: 3221225472 (0x<hex digits>) == 3221225472
Message.tests.cpp:<line number>: failed - but was ok: 1 == 2
@@ -1064,50 +1146,50 @@ Xml.tests.cpp:<line number>: passed: encode( stringWithQuotes ) == stringWithQuo
Xml.tests.cpp:<line number>: passed: encode( stringWithQuotes, Catch::XmlEncode::ForAttributes ) == "don't &quot;quote&quot; me on that" for: "don't &quot;quote&quot; me on that"
==
"don't &quot;quote&quot; me on that"
Xml.tests.cpp:<line number>: passed: encode( "[/x01]" ) == "[//x01]" for: "[/x01]" == "[/x01]"
Xml.tests.cpp:<line number>: passed: encode( "[/x7F]" ) == "[//x7F]" for: "[/x7F]" == "[/x7F]"
Xml.tests.cpp:<line number>: passed: encode( "[\x01]" ) == "[\\x01]" for: "[\x01]" == "[\x01]"
Xml.tests.cpp:<line number>: passed: encode( "[\x7F]" ) == "[\\x7F]" for: "[\x7F]" == "[\x7F]"
Xml.tests.cpp:<line number>: passed: encode(u8"Here be 👾") == u8"Here be 👾" for: "Here be 👾" == "Here be 👾"
Xml.tests.cpp:<line number>: passed: encode(u8"šš") == u8"šš" for: "šš" == "šš"
Xml.tests.cpp:<line number>: passed: encode("/xDF/xBF") == "/xDF/xBF" for: "߿" == "߿"
Xml.tests.cpp:<line number>: passed: encode("/xE0/xA0/x80") == "/xE0/xA0/x80" for: "ࠀ" == "ࠀ"
Xml.tests.cpp:<line number>: passed: encode("/xED/x9F/xBF") == "/xED/x9F/xBF" for: "퟿" == "퟿"
Xml.tests.cpp:<line number>: passed: encode("/xEE/x80/x80") == "/xEE/x80/x80" for: "" == ""
Xml.tests.cpp:<line number>: passed: encode("/xEF/xBF/xBF") == "/xEF/xBF/xBF" for: "￿" == "￿"
Xml.tests.cpp:<line number>: passed: encode("/xF0/x90/x80/x80") == "/xF0/x90/x80/x80" for: "𐀀" == "𐀀"
Xml.tests.cpp:<line number>: passed: encode("/xF4/x8F/xBF/xBF") == "/xF4/x8F/xBF/xBF" for: "􏿿" == "􏿿"
Xml.tests.cpp:<line number>: passed: encode("Here /xFF be 👾") == u8"Here //xFF be 👾" for: "Here /xFF be 👾" == "Here /xFF be 👾"
Xml.tests.cpp:<line number>: passed: encode("/xFF") == "//xFF" for: "/xFF" == "/xFF"
Xml.tests.cpp:<line number>: passed: encode("/xC5/xC5/xA0") == u8"//xC5Š" for: "/xC5Š" == "/xC5Š"
Xml.tests.cpp:<line number>: passed: encode("/xF4/x90/x80/x80") == u8"//xF4//x90//x80//x80" for: "/xF4/x90/x80/x80" == "/xF4/x90/x80/x80"
Xml.tests.cpp:<line number>: passed: encode("/xC0/x80") == u8"//xC0//x80" for: "/xC0/x80" == "/xC0/x80"
Xml.tests.cpp:<line number>: passed: encode("/xF0/x80/x80/x80") == u8"//xF0//x80//x80//x80" for: "/xF0/x80/x80/x80" == "/xF0/x80/x80/x80"
Xml.tests.cpp:<line number>: passed: encode("/xC1/xBF") == u8"//xC1//xBF" for: "/xC1/xBF" == "/xC1/xBF"
Xml.tests.cpp:<line number>: passed: encode("/xE0/x9F/xBF") == u8"//xE0//x9F//xBF" for: "/xE0/x9F/xBF" == "/xE0/x9F/xBF"
Xml.tests.cpp:<line number>: passed: encode("/xF0/x8F/xBF/xBF") == u8"//xF0//x8F//xBF//xBF" for: "/xF0/x8F/xBF/xBF" == "/xF0/x8F/xBF/xBF"
Xml.tests.cpp:<line number>: passed: encode("/xED/xA0/x80") == "/xED/xA0/x80" for: "<22><><EFBFBD>" == "<22><><EFBFBD>"
Xml.tests.cpp:<line number>: passed: encode("/xED/xAF/xBF") == "/xED/xAF/xBF" for: "<22><><EFBFBD>" == "<22><><EFBFBD>"
Xml.tests.cpp:<line number>: passed: encode("/xED/xB0/x80") == "/xED/xB0/x80" for: "<22><><EFBFBD>" == "<22><><EFBFBD>"
Xml.tests.cpp:<line number>: passed: encode("/xED/xBF/xBF") == "/xED/xBF/xBF" for: "<22><><EFBFBD>" == "<22><><EFBFBD>"
Xml.tests.cpp:<line number>: passed: encode("/x80") == u8"//x80" for: "/x80" == "/x80"
Xml.tests.cpp:<line number>: passed: encode("/x81") == u8"//x81" for: "/x81" == "/x81"
Xml.tests.cpp:<line number>: passed: encode("/xBC") == u8"//xBC" for: "/xBC" == "/xBC"
Xml.tests.cpp:<line number>: passed: encode("/xBF") == u8"//xBF" for: "/xBF" == "/xBF"
Xml.tests.cpp:<line number>: passed: encode("/xF5/x80/x80/x80") == u8"//xF5//x80//x80//x80" for: "/xF5/x80/x80/x80" == "/xF5/x80/x80/x80"
Xml.tests.cpp:<line number>: passed: encode("/xF6/x80/x80/x80") == u8"//xF6//x80//x80//x80" for: "/xF6/x80/x80/x80" == "/xF6/x80/x80/x80"
Xml.tests.cpp:<line number>: passed: encode("/xF7/x80/x80/x80") == u8"//xF7//x80//x80//x80" for: "/xF7/x80/x80/x80" == "/xF7/x80/x80/x80"
Xml.tests.cpp:<line number>: passed: encode("/xDE") == u8"//xDE" for: "/xDE" == "/xDE"
Xml.tests.cpp:<line number>: passed: encode("/xDF") == u8"//xDF" for: "/xDF" == "/xDF"
Xml.tests.cpp:<line number>: passed: encode("/xE0") == u8"//xE0" for: "/xE0" == "/xE0"
Xml.tests.cpp:<line number>: passed: encode("/xEF") == u8"//xEF" for: "/xEF" == "/xEF"
Xml.tests.cpp:<line number>: passed: encode("/xF0") == u8"//xF0" for: "/xF0" == "/xF0"
Xml.tests.cpp:<line number>: passed: encode("/xF4") == u8"//xF4" for: "/xF4" == "/xF4"
Xml.tests.cpp:<line number>: passed: encode("/xE0/x80") == u8"//xE0//x80" for: "/xE0/x80" == "/xE0/x80"
Xml.tests.cpp:<line number>: passed: encode("/xE0/xBF") == u8"//xE0//xBF" for: "/xE0/xBF" == "/xE0/xBF"
Xml.tests.cpp:<line number>: passed: encode("/xE1/x80") == u8"//xE1//x80" for: "/xE1/x80" == "/xE1/x80"
Xml.tests.cpp:<line number>: passed: encode("/xF0/x80") == u8"//xF0//x80" for: "/xF0/x80" == "/xF0/x80"
Xml.tests.cpp:<line number>: passed: encode("/xF4/x80") == u8"//xF4//x80" for: "/xF4/x80" == "/xF4/x80"
Xml.tests.cpp:<line number>: passed: encode("/xF0/x80/x80") == u8"//xF0//x80//x80" for: "/xF0/x80/x80" == "/xF0/x80/x80"
Xml.tests.cpp:<line number>: passed: encode("/xF4/x80/x80") == u8"//xF4//x80//x80" for: "/xF4/x80/x80" == "/xF4/x80/x80"
Xml.tests.cpp:<line number>: passed: encode("\xDF\xBF") == "\xDF\xBF" for: "߿" == "߿"
Xml.tests.cpp:<line number>: passed: encode("\xE0\xA0\x80") == "\xE0\xA0\x80" for: "ࠀ" == "ࠀ"
Xml.tests.cpp:<line number>: passed: encode("\xED\x9F\xBF") == "\xED\x9F\xBF" for: "퟿" == "퟿"
Xml.tests.cpp:<line number>: passed: encode("\xEE\x80\x80") == "\xEE\x80\x80" for: "" == ""
Xml.tests.cpp:<line number>: passed: encode("\xEF\xBF\xBF") == "\xEF\xBF\xBF" for: "￿" == "￿"
Xml.tests.cpp:<line number>: passed: encode("\xF0\x90\x80\x80") == "\xF0\x90\x80\x80" for: "𐀀" == "𐀀"
Xml.tests.cpp:<line number>: passed: encode("\xF4\x8F\xBF\xBF") == "\xF4\x8F\xBF\xBF" for: "􏿿" == "􏿿"
Xml.tests.cpp:<line number>: passed: encode("Here \xFF be 👾") == u8"Here \\xFF be 👾" for: "Here \xFF be 👾" == "Here \xFF be 👾"
Xml.tests.cpp:<line number>: passed: encode("\xFF") == "\\xFF" for: "\xFF" == "\xFF"
Xml.tests.cpp:<line number>: passed: encode("\xC5\xC5\xA0") == u8"\\xC5Š" for: "\xC5Š" == "\xC5Š"
Xml.tests.cpp:<line number>: passed: encode("\xF4\x90\x80\x80") == u8"\\xF4\\x90\\x80\\x80" for: "\xF4\x90\x80\x80" == "\xF4\x90\x80\x80"
Xml.tests.cpp:<line number>: passed: encode("\xC0\x80") == u8"\\xC0\\x80" for: "\xC0\x80" == "\xC0\x80"
Xml.tests.cpp:<line number>: passed: encode("\xF0\x80\x80\x80") == u8"\\xF0\\x80\\x80\\x80" for: "\xF0\x80\x80\x80" == "\xF0\x80\x80\x80"
Xml.tests.cpp:<line number>: passed: encode("\xC1\xBF") == u8"\\xC1\\xBF" for: "\xC1\xBF" == "\xC1\xBF"
Xml.tests.cpp:<line number>: passed: encode("\xE0\x9F\xBF") == u8"\\xE0\\x9F\\xBF" for: "\xE0\x9F\xBF" == "\xE0\x9F\xBF"
Xml.tests.cpp:<line number>: passed: encode("\xF0\x8F\xBF\xBF") == u8"\\xF0\\x8F\\xBF\\xBF" for: "\xF0\x8F\xBF\xBF" == "\xF0\x8F\xBF\xBF"
Xml.tests.cpp:<line number>: passed: encode("\xED\xA0\x80") == "\xED\xA0\x80" for: "<22><><EFBFBD>" == "<22><><EFBFBD>"
Xml.tests.cpp:<line number>: passed: encode("\xED\xAF\xBF") == "\xED\xAF\xBF" for: "<22><><EFBFBD>" == "<22><><EFBFBD>"
Xml.tests.cpp:<line number>: passed: encode("\xED\xB0\x80") == "\xED\xB0\x80" for: "<22><><EFBFBD>" == "<22><><EFBFBD>"
Xml.tests.cpp:<line number>: passed: encode("\xED\xBF\xBF") == "\xED\xBF\xBF" for: "<22><><EFBFBD>" == "<22><><EFBFBD>"
Xml.tests.cpp:<line number>: passed: encode("\x80") == u8"\\x80" for: "\x80" == "\x80"
Xml.tests.cpp:<line number>: passed: encode("\x81") == u8"\\x81" for: "\x81" == "\x81"
Xml.tests.cpp:<line number>: passed: encode("\xBC") == u8"\\xBC" for: "\xBC" == "\xBC"
Xml.tests.cpp:<line number>: passed: encode("\xBF") == u8"\\xBF" for: "\xBF" == "\xBF"
Xml.tests.cpp:<line number>: passed: encode("\xF5\x80\x80\x80") == u8"\\xF5\\x80\\x80\\x80" for: "\xF5\x80\x80\x80" == "\xF5\x80\x80\x80"
Xml.tests.cpp:<line number>: passed: encode("\xF6\x80\x80\x80") == u8"\\xF6\\x80\\x80\\x80" for: "\xF6\x80\x80\x80" == "\xF6\x80\x80\x80"
Xml.tests.cpp:<line number>: passed: encode("\xF7\x80\x80\x80") == u8"\\xF7\\x80\\x80\\x80" for: "\xF7\x80\x80\x80" == "\xF7\x80\x80\x80"
Xml.tests.cpp:<line number>: passed: encode("\xDE") == u8"\\xDE" for: "\xDE" == "\xDE"
Xml.tests.cpp:<line number>: passed: encode("\xDF") == u8"\\xDF" for: "\xDF" == "\xDF"
Xml.tests.cpp:<line number>: passed: encode("\xE0") == u8"\\xE0" for: "\xE0" == "\xE0"
Xml.tests.cpp:<line number>: passed: encode("\xEF") == u8"\\xEF" for: "\xEF" == "\xEF"
Xml.tests.cpp:<line number>: passed: encode("\xF0") == u8"\\xF0" for: "\xF0" == "\xF0"
Xml.tests.cpp:<line number>: passed: encode("\xF4") == u8"\\xF4" for: "\xF4" == "\xF4"
Xml.tests.cpp:<line number>: passed: encode("\xE0\x80") == u8"\\xE0\\x80" for: "\xE0\x80" == "\xE0\x80"
Xml.tests.cpp:<line number>: passed: encode("\xE0\xBF") == u8"\\xE0\\xBF" for: "\xE0\xBF" == "\xE0\xBF"
Xml.tests.cpp:<line number>: passed: encode("\xE1\x80") == u8"\\xE1\\x80" for: "\xE1\x80" == "\xE1\x80"
Xml.tests.cpp:<line number>: passed: encode("\xF0\x80") == u8"\\xF0\\x80" for: "\xF0\x80" == "\xF0\x80"
Xml.tests.cpp:<line number>: passed: encode("\xF4\x80") == u8"\\xF4\\x80" for: "\xF4\x80" == "\xF4\x80"
Xml.tests.cpp:<line number>: passed: encode("\xF0\x80\x80") == u8"\\xF0\\x80\\x80" for: "\xF0\x80\x80" == "\xF0\x80\x80"
Xml.tests.cpp:<line number>: passed: encode("\xF4\x80\x80") == u8"\\xF4\\x80\\x80" for: "\xF4\x80\x80" == "\xF4\x80\x80"
ToStringVector.tests.cpp:<line number>: passed: Catch::Detail::stringify( empty ) == "{ }" for: "{ }" == "{ }"
ToStringVector.tests.cpp:<line number>: passed: Catch::Detail::stringify( oneValue ) == "{ 42 }" for: "{ 42 }" == "{ 42 }"
ToStringVector.tests.cpp:<line number>: passed: Catch::Detail::stringify( twoValues ) == "{ 42, 250 }" for: "{ 42, 250 }" == "{ 42, 250 }"
@@ -1167,7 +1249,7 @@ Misc.tests.cpp:<line number>: passed:
Misc.tests.cpp:<line number>: passed: makeString( false ) != static_cast<char*>(0) for: "valid string" != {null string}
Misc.tests.cpp:<line number>: passed: makeString( true ) == static_cast<char*>(0) for: {null string} == {null string}
Tricky.tests.cpp:<line number>: passed: ptr.get() == 0 for: 0 == 0
ToStringPair.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( pair ) == "{ { 42, /"Arthur/" }, { /"Ford/", 24 } }" for: "{ { 42, "Arthur" }, { "Ford", 24 } }"
ToStringPair.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( pair ) == "{ { 42, \"Arthur\" }, { \"Ford\", 24 } }" for: "{ { 42, "Arthur" }, { "Ford", 24 } }"
==
"{ { 42, "Arthur" }, { "Ford", 24 } }"
Tricky.tests.cpp:<line number>: passed: p == 0 for: 0 == 0
@@ -1191,18 +1273,18 @@ String.tests.cpp:<line number>: passed: s == "didn|'t" for: "didn|'t" == "didn|'
Misc.tests.cpp:<line number>: failed: false with 1 message: '3'
Message.tests.cpp:<line number>: failed: false with 2 messages: 'hi' and 'i := 7'
ToStringGeneral.tests.cpp:<line number>: passed: Catch::Detail::stringify( emptyMap ) == "{ }" for: "{ }" == "{ }"
ToStringGeneral.tests.cpp:<line number>: passed: Catch::Detail::stringify( map ) == "{ { /"one/", 1 } }" for: "{ { "one", 1 } }" == "{ { "one", 1 } }"
ToStringGeneral.tests.cpp:<line number>: passed: Catch::Detail::stringify( map ) == "{ { /"abc/", 1 }, { /"def/", 2 }, { /"ghi/", 3 } }" for: "{ { "abc", 1 }, { "def", 2 }, { "ghi", 3 } }"
ToStringGeneral.tests.cpp:<line number>: passed: Catch::Detail::stringify( map ) == "{ { \"one\", 1 } }" for: "{ { "one", 1 } }" == "{ { "one", 1 } }"
ToStringGeneral.tests.cpp:<line number>: passed: Catch::Detail::stringify( map ) == "{ { \"abc\", 1 }, { \"def\", 2 }, { \"ghi\", 3 } }" for: "{ { "abc", 1 }, { "def", 2 }, { "ghi", 3 } }"
==
"{ { "abc", 1 }, { "def", 2 }, { "ghi", 3 } }"
ToStringPair.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(value) == "{ 34, /"xyzzy/" }" for: "{ 34, "xyzzy" }" == "{ 34, "xyzzy" }"
ToStringPair.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( value ) == "{ 34, /"xyzzy/" }" for: "{ 34, "xyzzy" }" == "{ 34, "xyzzy" }"
ToStringPair.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(value) == "{ 34, \"xyzzy\" }" for: "{ 34, "xyzzy" }" == "{ 34, "xyzzy" }"
ToStringPair.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( value ) == "{ 34, \"xyzzy\" }" for: "{ 34, "xyzzy" }" == "{ 34, "xyzzy" }"
ToStringGeneral.tests.cpp:<line number>: passed: Catch::Detail::stringify( emptySet ) == "{ }" for: "{ }" == "{ }"
ToStringGeneral.tests.cpp:<line number>: passed: Catch::Detail::stringify( set ) == "{ /"one/" }" for: "{ "one" }" == "{ "one" }"
ToStringGeneral.tests.cpp:<line number>: passed: Catch::Detail::stringify( set ) == "{ /"abc/", /"def/", /"ghi/" }" for: "{ "abc", "def", "ghi" }"
ToStringGeneral.tests.cpp:<line number>: passed: Catch::Detail::stringify( set ) == "{ \"one\" }" for: "{ "one" }" == "{ "one" }"
ToStringGeneral.tests.cpp:<line number>: passed: Catch::Detail::stringify( set ) == "{ \"abc\", \"def\", \"ghi\" }" for: "{ "abc", "def", "ghi" }"
==
"{ "abc", "def", "ghi" }"
ToStringPair.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( pr ) == "{ { /"green/", 55 } }" for: "{ { "green", 55 } }"
ToStringPair.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( pr ) == "{ { \"green\", 55 } }" for: "{ { "green", 55 } }"
==
"{ { "green", 55 } }"
Tricky.tests.cpp:<line number>: failed: std::string( "first" ) == "second" for: "first" == "second"
@@ -1241,10 +1323,10 @@ Generators.tests.cpp:<line number>: passed: data.str.size() == data.len for: 3 =
Generators.tests.cpp:<line number>: passed: data.str.size() == data.len for: 5 == 5
Generators.tests.cpp:<line number>: passed: data.str.size() == data.len for: 4 == 4
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'Why would you throw a std::string?'
Misc.tests.cpp:<line number>: passed: result == "/"wide load/"" for: ""wide load"" == ""wide load""
Misc.tests.cpp:<line number>: passed: result == "/"wide load/"" for: ""wide load"" == ""wide load""
Misc.tests.cpp:<line number>: passed: result == "/"wide load/"" for: ""wide load"" == ""wide load""
Misc.tests.cpp:<line number>: passed: result == "/"wide load/"" for: ""wide load"" == ""wide load""
Misc.tests.cpp:<line number>: passed: result == "\"wide load\"" for: ""wide load"" == ""wide load""
Misc.tests.cpp:<line number>: passed: result == "\"wide load\"" for: ""wide load"" == ""wide load""
Misc.tests.cpp:<line number>: passed: result == "\"wide load\"" for: ""wide load"" == ""wide load""
Misc.tests.cpp:<line number>: passed: result == "\"wide load\"" for: ""wide load"" == ""wide load""
EnumToString.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(e0) == "E2/V0" for: "E2/V0" == "E2/V0"
EnumToString.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(e1) == "E2/V1" for: "E2/V1" == "E2/V1"
EnumToString.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(e3) == "Unknown enum value 10" for: "Unknown enum value 10"
@@ -1261,17 +1343,17 @@ ToStringTuple.tests.cpp:<line number>: passed: "{ }" == ::Catch::Detail::stringi
ToStringTuple.tests.cpp:<line number>: passed: "1.2f" == ::Catch::Detail::stringify(float(1.2)) for: "1.2f" == "1.2f"
ToStringTuple.tests.cpp:<line number>: passed: "{ 1.2f, 0 }" == ::Catch::Detail::stringify(type{1.2f,0}) for: "{ 1.2f, 0 }" == "{ 1.2f, 0 }"
ToStringTuple.tests.cpp:<line number>: passed: "{ 0 }" == ::Catch::Detail::stringify(type{0}) for: "{ 0 }" == "{ 0 }"
ToStringTuple.tests.cpp:<line number>: passed: "{ 0, 42, /"Catch me/" }" == ::Catch::Detail::stringify(value) for: "{ 0, 42, "Catch me" }"
ToStringTuple.tests.cpp:<line number>: passed: "{ 0, 42, \"Catch me\" }" == ::Catch::Detail::stringify(value) for: "{ 0, 42, "Catch me" }"
==
"{ 0, 42, "Catch me" }"
ToStringTuple.tests.cpp:<line number>: passed: "{ /"hello/", /"world/" }" == ::Catch::Detail::stringify(type{"hello","world"}) for: "{ "hello", "world" }"
ToStringTuple.tests.cpp:<line number>: passed: "{ \"hello\", \"world\" }" == ::Catch::Detail::stringify(type{"hello","world"}) for: "{ "hello", "world" }"
==
"{ "hello", "world" }"
ToStringTuple.tests.cpp:<line number>: passed: "{ { 42 }, { }, 1.2f }" == ::Catch::Detail::stringify(value) for: "{ { 42 }, { }, 1.2f }"
==
"{ { 42 }, { }, 1.2f }"
ToStringVector.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(v) == "{ }" for: "{ }" == "{ }"
ToStringVector.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(v) == "{ { /"hello/" }, { /"world/" } }" for: "{ { "hello" }, { "world" } }"
ToStringVector.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(v) == "{ { \"hello\" }, { \"world\" } }" for: "{ { "hello" }, { "world" } }"
==
"{ { "hello" }, { "world" } }"
ToStringVector.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(bools) == "{ }" for: "{ }" == "{ }"
@@ -1284,8 +1366,8 @@ ToStringVector.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(vv) =
ToStringVector.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(vv) == "{ 42 }" for: "{ 42 }" == "{ 42 }"
ToStringVector.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(vv) == "{ 42, 250 }" for: "{ 42, 250 }" == "{ 42, 250 }"
ToStringVector.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(vv) == "{ }" for: "{ }" == "{ }"
ToStringVector.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(vv) == "{ /"hello/" }" for: "{ "hello" }" == "{ "hello" }"
ToStringVector.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(vv) == "{ /"hello/", /"world/" }" for: "{ "hello", "world" }"
ToStringVector.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(vv) == "{ \"hello\" }" for: "{ "hello" }" == "{ "hello" }"
ToStringVector.tests.cpp:<line number>: passed: ::Catch::Detail::stringify(vv) == "{ \"hello\", \"world\" }" for: "{ "hello", "world" }"
==
"{ "hello", "world" }"
Misc.tests.cpp:<line number>: passed: v.size() == 5 for: 5 == 5
@@ -1307,5 +1389,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 62 test cases, failed 122 assertions.
Failed 65 test cases, failed 125 assertions.

View File

@@ -3,6 +3,8 @@
<exe-name> is a <version> host application.
Run with -? for options
Randomness seeded to: 1
-------------------------------------------------------------------------------
#748 - captures with unexpected exceptions
outside assertions
@@ -90,6 +92,39 @@ Class.tests.cpp:<line number>: FAILED:
with expansion:
"hello" == "world"
-------------------------------------------------------------------------------
A TEMPLATE_TEST_CASE_METHOD based test run that fails - double
-------------------------------------------------------------------------------
Class.tests.cpp:<line number>
...............................................................................
Class.tests.cpp:<line number>: FAILED:
REQUIRE( Template_Fixture<TestType>::m_a == 2 )
with expansion:
1.0 == 2
-------------------------------------------------------------------------------
A TEMPLATE_TEST_CASE_METHOD based test run that fails - float
-------------------------------------------------------------------------------
Class.tests.cpp:<line number>
...............................................................................
Class.tests.cpp:<line number>: FAILED:
REQUIRE( Template_Fixture<TestType>::m_a == 2 )
with expansion:
1.0f == 2
-------------------------------------------------------------------------------
A TEMPLATE_TEST_CASE_METHOD based test run that fails - int
-------------------------------------------------------------------------------
Class.tests.cpp:<line number>
...............................................................................
Class.tests.cpp:<line number>: FAILED:
REQUIRE( Template_Fixture<TestType>::m_a == 2 )
with expansion:
1 == 2
-------------------------------------------------------------------------------
A TEST_CASE_METHOD based test run that fails
-------------------------------------------------------------------------------
@@ -390,8 +425,7 @@ Message.tests.cpp:<line number>: FAILED:
explicitly with message:
This is a failure
Message.tests.cpp:<line number>:
warning:
Message.tests.cpp:<line number>: warning:
This message appears in the output
-------------------------------------------------------------------------------
@@ -400,8 +434,7 @@ INFO and WARN do not abort tests
Message.tests.cpp:<line number>
...............................................................................
Message.tests.cpp:<line number>:
warning:
Message.tests.cpp:<line number>: warning:
this is a warning
-------------------------------------------------------------------------------
@@ -526,8 +559,7 @@ Nice descriptive name
Misc.tests.cpp:<line number>
...............................................................................
Misc.tests.cpp:<line number>:
warning:
Misc.tests.cpp:<line number>: warning:
This one ran
-------------------------------------------------------------------------------
@@ -907,8 +939,7 @@ Where the LHS is not a simple value
Tricky.tests.cpp:<line number>
...............................................................................
Tricky.tests.cpp:<line number>:
warning:
Tricky.tests.cpp:<line number>: warning:
Uncomment the code in this test to check that it gives a sensible compiler
error
@@ -918,8 +949,7 @@ Where there is more to the expression after the RHS
Tricky.tests.cpp:<line number>
...............................................................................
Tricky.tests.cpp:<line number>:
warning:
Tricky.tests.cpp:<line number>: warning:
Uncomment the code in this test to check that it gives a sensible compiler
error
@@ -1096,6 +1126,6 @@ due to unexpected exception with message:
Why would you throw a std::string?
===============================================================================
test cases: 213 | 160 passed | 49 failed | 4 failed as expected
assertions: 1228 | 1099 passed | 108 failed | 21 failed as expected
test cases: 228 | 172 passed | 52 failed | 4 failed as expected
assertions: 1310 | 1178 passed | 111 failed | 21 failed as expected

File diff suppressed because it is too large Load Diff

View File

@@ -3,14 +3,15 @@
<exe-name> is a <version> host application.
Run with -? for options
Randomness seeded to: 1
-------------------------------------------------------------------------------
# A test name that starts with a #
-------------------------------------------------------------------------------
Misc.tests.cpp:<line number>
...............................................................................
Misc.tests.cpp:<line number>:
PASSED:
Misc.tests.cpp:<line number>: PASSED:
with message:
yay
@@ -21,14 +22,12 @@ with message:
Decomposition.tests.cpp:<line number>
...............................................................................
Decomposition.tests.cpp:<line number>:
PASSED:
Decomposition.tests.cpp:<line number>: PASSED:
REQUIRE( fptr == 0 )
with expansion:
0 == 0
Decomposition.tests.cpp:<line number>:
PASSED:
Decomposition.tests.cpp:<line number>: PASSED:
REQUIRE( fptr == 0l )
with expansion:
0 == 0
@@ -39,14 +38,12 @@ with expansion:
Compilation.tests.cpp:<line number>
...............................................................................
Compilation.tests.cpp:<line number>:
PASSED:
Compilation.tests.cpp:<line number>: PASSED:
REQUIRE( y.v == 0 )
with expansion:
0 == 0
Compilation.tests.cpp:<line number>:
PASSED:
Compilation.tests.cpp:<line number>: PASSED:
REQUIRE( 0 == y.v )
with expansion:
0 == 0
@@ -57,38 +54,32 @@ with expansion:
Compilation.tests.cpp:<line number>
...............................................................................
Compilation.tests.cpp:<line number>:
PASSED:
Compilation.tests.cpp:<line number>: PASSED:
REQUIRE( t1 == t2 )
with expansion:
{?} == {?}
Compilation.tests.cpp:<line number>:
PASSED:
Compilation.tests.cpp:<line number>: PASSED:
REQUIRE( t1 != t2 )
with expansion:
{?} != {?}
Compilation.tests.cpp:<line number>:
PASSED:
Compilation.tests.cpp:<line number>: PASSED:
REQUIRE( t1 < t2 )
with expansion:
{?} < {?}
Compilation.tests.cpp:<line number>:
PASSED:
Compilation.tests.cpp:<line number>: PASSED:
REQUIRE( t1 > t2 )
with expansion:
{?} > {?}
Compilation.tests.cpp:<line number>:
PASSED:
Compilation.tests.cpp:<line number>: PASSED:
REQUIRE( t1 <= t2 )
with expansion:
{?} <= {?}
Compilation.tests.cpp:<line number>:
PASSED:
Compilation.tests.cpp:<line number>: PASSED:
REQUIRE( t1 >= t2 )
with expansion:
{?} >= {?}
@@ -99,8 +90,7 @@ with expansion:
Misc.tests.cpp:<line number>
...............................................................................
Misc.tests.cpp:<line number>:
PASSED:
Misc.tests.cpp:<line number>: PASSED:
-------------------------------------------------------------------------------
#1238
@@ -108,8 +98,7 @@ PASSED:
Compilation.tests.cpp:<line number>
...............................................................................
Compilation.tests.cpp:<line number>:
PASSED:
Compilation.tests.cpp:<line number>: PASSED:
REQUIRE( std::memcmp(uarr, "123", sizeof(uarr)) == 0 )
with expansion:
0 == 0
@@ -117,8 +106,7 @@ with messages:
uarr := "123"
sarr := "456"
Compilation.tests.cpp:<line number>:
PASSED:
Compilation.tests.cpp:<line number>: PASSED:
REQUIRE( std::memcmp(sarr, "456", sizeof(sarr)) == 0 )
with expansion:
0 == 0
@@ -132,8 +120,18 @@ with messages:
Compilation.tests.cpp:<line number>
...............................................................................
Compilation.tests.cpp:<line number>:
PASSED:
Compilation.tests.cpp:<line number>: PASSED:
-------------------------------------------------------------------------------
#1403
-------------------------------------------------------------------------------
Compilation.tests.cpp:<line number>
...............................................................................
Compilation.tests.cpp:<line number>: PASSED:
REQUIRE( h1 == h2 )
with expansion:
[1403 helper] == [1403 helper]
-------------------------------------------------------------------------------
#748 - captures with unexpected exceptions
@@ -167,8 +165,7 @@ due to unexpected exception with messages:
Exception.tests.cpp:<line number>
...............................................................................
Exception.tests.cpp:<line number>:
PASSED:
Exception.tests.cpp:<line number>: PASSED:
REQUIRE_THROWS( thisThrows() )
with message:
answer := 42
@@ -179,8 +176,7 @@ with message:
Compilation.tests.cpp:<line number>
...............................................................................
Compilation.tests.cpp:<line number>:
PASSED:
Compilation.tests.cpp:<line number>: PASSED:
REQUIRE( 42 == f )
with expansion:
42 == {?}
@@ -191,38 +187,31 @@ with expansion:
Compilation.tests.cpp:<line number>
...............................................................................
Compilation.tests.cpp:<line number>:
PASSED:
Compilation.tests.cpp:<line number>: PASSED:
REQUIRE( a == t )
with expansion:
3 == 3
Compilation.tests.cpp:<line number>:
PASSED:
Compilation.tests.cpp:<line number>: PASSED:
CHECK( a == t )
with expansion:
3 == 3
Compilation.tests.cpp:<line number>:
PASSED:
Compilation.tests.cpp:<line number>: PASSED:
REQUIRE_THROWS( throws_int(true) )
Compilation.tests.cpp:<line number>:
PASSED:
Compilation.tests.cpp:<line number>: PASSED:
CHECK_THROWS_AS( throws_int(true), int )
Compilation.tests.cpp:<line number>:
PASSED:
Compilation.tests.cpp:<line number>: PASSED:
REQUIRE_NOTHROW( throws_int(false) )
Compilation.tests.cpp:<line number>:
PASSED:
Compilation.tests.cpp:<line number>: PASSED:
REQUIRE_THAT( "aaa", Catch::EndsWith("aaa") )
with expansion:
"aaa" ends with: "aaa"
Compilation.tests.cpp:<line number>:
PASSED:
Compilation.tests.cpp:<line number>: PASSED:
REQUIRE( templated_tests<int>(3) )
with expansion:
true
@@ -238,8 +227,7 @@ Misc.tests.cpp:<line number>: FAILED:
with expansion:
1 == 0
Misc.tests.cpp:<line number>:
PASSED:
Misc.tests.cpp:<line number>: PASSED:
REQUIRE( errno == 1 )
with expansion:
1 == 1
@@ -250,8 +238,7 @@ with expansion:
Compilation.tests.cpp:<line number>
...............................................................................
Compilation.tests.cpp:<line number>:
PASSED:
Compilation.tests.cpp:<line number>: PASSED:
REQUIRE( x == 4 )
with expansion:
{?} == 4
@@ -265,8 +252,7 @@ with message:
Misc.tests.cpp:<line number>
...............................................................................
Misc.tests.cpp:<line number>:
PASSED:
Misc.tests.cpp:<line number>: PASSED:
with message:
Everything is OK
@@ -277,8 +263,7 @@ with message:
Misc.tests.cpp:<line number>
...............................................................................
Misc.tests.cpp:<line number>:
PASSED:
Misc.tests.cpp:<line number>: PASSED:
with message:
Everything is OK
@@ -289,8 +274,7 @@ with message:
Misc.tests.cpp:<line number>
...............................................................................
Misc.tests.cpp:<line number>:
PASSED:
Misc.tests.cpp:<line number>: PASSED:
with message:
Everything is OK
@@ -301,8 +285,7 @@ with message:
Misc.tests.cpp:<line number>
...............................................................................
Misc.tests.cpp:<line number>:
PASSED:
Misc.tests.cpp:<line number>: PASSED:
with message:
Everything is OK
@@ -313,8 +296,7 @@ with message:
Misc.tests.cpp:<line number>
...............................................................................
Misc.tests.cpp:<line number>:
PASSED:
Misc.tests.cpp:<line number>: PASSED:
with message:
Everything is OK
@@ -341,6 +323,6 @@ with expansion:
!true
===============================================================================
test cases: 14 | 11 passed | 1 failed | 2 failed as expected
assertions: 38 | 31 passed | 4 failed | 3 failed as expected
test cases: 15 | 12 passed | 1 failed | 2 failed as expected
assertions: 39 | 32 passed | 4 failed | 3 failed as expected

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuitesloose text artifact
>
<testsuite name="<exe-name>" errors="17" failures="106" tests="1243" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testsuite name="<exe-name>" errors="17" failures="109" tests="1325" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testcase classname="<exe-name>.global" name="# A test name that starts with a #" time="{duration}"/>
<testcase classname="<exe-name>.global" name="#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}"/>
@@ -9,6 +9,7 @@
<testcase classname="<exe-name>.global" name="#1175 - Hidden Test" time="{duration}"/>
<testcase classname="<exe-name>.global" name="#1238" time="{duration}"/>
<testcase classname="<exe-name>.(Fixture_1245&lt;int, int>)" name="#1245" time="{duration}"/>
<testcase classname="<exe-name>.global" name="#1403" time="{duration}"/>
<testcase classname="<exe-name>.global" name="#748 - captures with unexpected exceptions/outside assertions" time="{duration}">
<error type="TEST_CASE">
expected exception
@@ -76,6 +77,24 @@ Class.tests.cpp:<line number>
</failure>
</testcase>
<testcase classname="<exe-name>.TestClass" name="A METHOD_AS_TEST_CASE based test run that succeeds" time="{duration}"/>
<testcase classname="<exe-name>.Template_Fixture" name="A TEMPLATE_TEST_CASE_METHOD based test run that fails - double" time="{duration}">
<failure message="1.0 == 2" type="REQUIRE">
Class.tests.cpp:<line number>
</failure>
</testcase>
<testcase classname="<exe-name>.Template_Fixture" name="A TEMPLATE_TEST_CASE_METHOD based test run that fails - float" time="{duration}">
<failure message="1.0f == 2" type="REQUIRE">
Class.tests.cpp:<line number>
</failure>
</testcase>
<testcase classname="<exe-name>.Template_Fixture" name="A TEMPLATE_TEST_CASE_METHOD based test run that fails - int" time="{duration}">
<failure message="1 == 2" type="REQUIRE">
Class.tests.cpp:<line number>
</failure>
</testcase>
<testcase classname="<exe-name>.Template_Fixture" name="A TEMPLATE_TEST_CASE_METHOD based test run that succeeds - double" time="{duration}"/>
<testcase classname="<exe-name>.Template_Fixture" name="A TEMPLATE_TEST_CASE_METHOD based test run that succeeds - float" time="{duration}"/>
<testcase classname="<exe-name>.Template_Fixture" name="A TEMPLATE_TEST_CASE_METHOD based test run that succeeds - int" time="{duration}"/>
<testcase classname="<exe-name>.Fixture" name="A TEST_CASE_METHOD based test run that fails" time="{duration}">
<failure message="1 == 2" type="REQUIRE">
Class.tests.cpp:<line number>
@@ -122,6 +141,8 @@ Exception.tests.cpp:<line number>
<testcase classname="<exe-name>.global" name="Assertions then sections/A section/Another other section" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Assorted miscellaneous tests" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Bitfields can be captured (#1027)" time="{duration}"/>
<testcase classname="<exe-name>.global" name="CAPTURE can deal with complex expressions" time="{duration}"/>
<testcase classname="<exe-name>.global" name="CAPTURE can deal with complex expressions involving commas" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Capture and info messages/Capture should stringify like assertions" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Capture and info messages/Info should NOT stringify the way assertions do" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Character pretty printing/Specifically escaped" time="{duration}"/>
@@ -374,6 +395,7 @@ Exception.tests.cpp:<line number>
</error>
</testcase>
<testcase classname="<exe-name>.global" name="Objects that evaluated in boolean contexts can be checked" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Optionally static assertions" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Ordering comparison checks that should fail" time="{duration}">
<failure message="7 > 7" type="CHECK">
Condition.tests.cpp:<line number>
@@ -478,6 +500,7 @@ Message.tests.cpp:<line number>
<testcase classname="<exe-name>.global" name="Parse test names and tags/empty quoted name" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Parse test names and tags/quoted string followed by tag exclusion" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Pointers can be compared to null" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Predicate matcher can accept const char*" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Process can be configured on command line/empty args don't cause a crash" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Process can be configured on command line/default - no arguments" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Process can be configured on command line/test lists/Specify one test case using" time="{duration}"/>
@@ -487,6 +510,7 @@ Message.tests.cpp:<line number>
<testcase classname="<exe-name>.global" name="Process can be configured on command line/reporter/-r/xml" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Process can be configured on command line/reporter/--reporter/junit" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Process can be configured on command line/reporter/Only one reporter is accepted" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Process can be configured on command line/reporter/must match one of the available ones" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Process can be configured on command line/debugger/-b" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Process can be configured on command line/debugger/--break" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Process can be configured on command line/abort/-a aborts after first failure" time="{duration}"/>
@@ -592,6 +616,30 @@ Misc.tests.cpp:<line number>
</testcase>
<testcase classname="<exe-name>.global" name="Tag alias can be registered against tag patterns/The same tag alias can only be registered once" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Tag alias can be registered against tag patterns/Tag aliases must be of the form [@name]" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - float" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - float/resizing bigger changes size and capacity" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - float/resizing smaller changes size but not capacity" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - float/resizing smaller changes size but not capacity/We can use the 'swap trick' to reset the capacity" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - float/reserving bigger changes capacity but not size" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - float/reserving smaller does not change size or capacity" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - int" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - int/resizing bigger changes size and capacity" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - int/resizing smaller changes size but not capacity" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - int/resizing smaller changes size but not capacity/We can use the 'swap trick' to reset the capacity" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - int/reserving bigger changes capacity but not size" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - int/reserving smaller does not change size or capacity" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - std::string" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - std::string/resizing bigger changes size and capacity" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - std::string/resizing smaller changes size but not capacity" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - std::string/resizing smaller changes size but not capacity/We can use the 'swap trick' to reset the capacity" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - std::string/reserving bigger changes capacity but not size" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - std::string/reserving smaller does not change size or capacity" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - std::tuple&lt;int,float>" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - std::tuple&lt;int,float>/resizing bigger changes size and capacity" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - std::tuple&lt;int,float>/resizing smaller changes size but not capacity" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - std::tuple&lt;int,float>/resizing smaller changes size but not capacity/We can use the 'swap trick' to reset the capacity" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - std::tuple&lt;int,float>/reserving bigger changes capacity but not size" time="{duration}"/>
<testcase classname="<exe-name>.global" name="TemplateTest: vectors can be sized and resized - std::tuple&lt;int,float>/reserving smaller does not change size or capacity" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Test case with one argument" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Test enum bit values" time="{duration}"/>
<testcase classname="<exe-name>.global" name="The NO_FAIL macro reports a failure but does not fail the test" time="{duration}"/>

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Catch name="<exe-name>">
<Randomness seed="1"/>
<Group name="<exe-name>">
<TestCase name="# A test name that starts with a #" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<OverallResult success="true"/>
@@ -130,6 +131,17 @@
<TestCase name="#1245" tags="[compilation]" filename="projects/<exe-name>/UsageTests/Compilation.tests.cpp" >
<OverallResult success="true"/>
</TestCase>
<TestCase name="#1403" tags="[compilation]" filename="projects/<exe-name>/UsageTests/Compilation.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Compilation.tests.cpp" >
<Original>
h1 == h2
</Original>
<Expanded>
[1403 helper] == [1403 helper]
</Expanded>
</Expression>
<OverallResult success="true"/>
</TestCase>
<TestCase name="#748 - captures with unexpected exceptions" tags="[!shouldfail][!throws][.][failing]" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
<Section name="outside assertions" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
<Info>
@@ -1335,6 +1347,72 @@
</Expression>
<OverallResult success="true"/>
</TestCase>
<TestCase name="A TEMPLATE_TEST_CASE_METHOD based test run that fails - double" tags="[.][class][failing][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
<Expression success="false" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
<Original>
Template_Fixture&lt;TestType>::m_a == 2
</Original>
<Expanded>
1.0 == 2
</Expanded>
</Expression>
<OverallResult success="false"/>
</TestCase>
<TestCase name="A TEMPLATE_TEST_CASE_METHOD based test run that fails - float" tags="[.][class][failing][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
<Expression success="false" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
<Original>
Template_Fixture&lt;TestType>::m_a == 2
</Original>
<Expanded>
1.0f == 2
</Expanded>
</Expression>
<OverallResult success="false"/>
</TestCase>
<TestCase name="A TEMPLATE_TEST_CASE_METHOD based test run that fails - int" tags="[.][class][failing][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
<Expression success="false" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
<Original>
Template_Fixture&lt;TestType>::m_a == 2
</Original>
<Expanded>
1 == 2
</Expanded>
</Expression>
<OverallResult success="false"/>
</TestCase>
<TestCase name="A TEMPLATE_TEST_CASE_METHOD based test run that succeeds - double" tags="[class][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
<Original>
Template_Fixture&lt;TestType>::m_a == 1
</Original>
<Expanded>
1.0 == 1
</Expanded>
</Expression>
<OverallResult success="true"/>
</TestCase>
<TestCase name="A TEMPLATE_TEST_CASE_METHOD based test run that succeeds - float" tags="[class][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
<Original>
Template_Fixture&lt;TestType>::m_a == 1
</Original>
<Expanded>
1.0f == 1
</Expanded>
</Expression>
<OverallResult success="true"/>
</TestCase>
<TestCase name="A TEMPLATE_TEST_CASE_METHOD based test run that succeeds - int" tags="[class][template]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
<Original>
Template_Fixture&lt;TestType>::m_a == 1
</Original>
<Expanded>
1 == 1
</Expanded>
</Expression>
<OverallResult success="true"/>
</TestCase>
<TestCase name="A TEST_CASE_METHOD based test run that fails" tags="[.][class][failing]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
<Expression success="false" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
<Original>
@@ -1908,6 +1986,54 @@
</Expression>
<OverallResult success="true"/>
</TestCase>
<TestCase name="CAPTURE can deal with complex expressions" tags="[capture][messages]" filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
<Info>
a := 1
</Info>
<Info>
b := 2
</Info>
<Info>
c := 3
</Info>
<Info>
a + b := 3
</Info>
<Info>
a+b := 3
</Info>
<Info>
c > b := true
</Info>
<Info>
a == 1 := true
</Info>
<OverallResult success="true"/>
</TestCase>
<TestCase name="CAPTURE can deal with complex expressions involving commas" tags="[capture][messages]" filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
<Info>
std::vector&lt;int>{1, 2, 3}[0, 1, 2] := 3
</Info>
<Info>
std::vector&lt;int>{1, 2, 3}[(0, 1)] := 2
</Info>
<Info>
std::vector&lt;int>{1, 2, 3}[0] := 1
</Info>
<Info>
(helper_1436&lt;int, int>{12, -12}) := { 12, -12 }
</Info>
<Info>
(helper_1436&lt;int, int>(-12, 12)) := { -12, 12 }
</Info>
<Info>
(1, 2) := 2
</Info>
<Info>
(2, 3) := 3
</Info>
<OverallResult success="true"/>
</TestCase>
<TestCase name="Capture and info messages" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
<Section name="Capture should stringify like assertions" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
<Info>
@@ -4397,6 +4523,9 @@
</Expression>
<OverallResult success="true"/>
</TestCase>
<TestCase name="Optionally static assertions" tags="[compilation]" filename="projects/<exe-name>/UsageTests/Compilation.tests.cpp" >
<OverallResult success="true"/>
</TestCase>
<TestCase name="Ordering comparison checks that should fail" tags="[.][failing]" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
<Expression success="false" type="CHECK" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
<Original>
@@ -5949,6 +6078,17 @@
</Expression>
<OverallResult success="true"/>
</TestCase>
<TestCase name="Predicate matcher can accept const char*" tags="[compilation][matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
<Original>
"foo", Predicate&lt;const char*>([] (const char* const&amp;) { return true; })
</Original>
<Expanded>
"foo" matches undescribed predicate
</Expanded>
</Expression>
<OverallResult success="true"/>
</TestCase>
<TestCase name="Process can be configured on command line" tags="[command-line][config]" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
<Section name="empty args don't cause a crash" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
@@ -6222,6 +6362,28 @@
</Section>
<OverallResults successes="1" failures="0" expectedFailures="0"/>
</Section>
<Section name="reporter" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
<Section name="must match one of the available ones" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
<Original>
!result
</Original>
<Expanded>
true
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
<Original>
result.errorMessage(), Contains("Unrecognized reporter")
</Original>
<Expanded>
"Unrecognized reporter, 'unsupported'. Check available with --list-reporters" contains: "Unrecognized reporter"
</Expanded>
</Expression>
<OverallResults successes="2" failures="0" expectedFailures="0"/>
</Section>
<OverallResults successes="2" failures="0" expectedFailures="0"/>
</Section>
<Section name="debugger" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
<Section name="-b" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
@@ -7643,6 +7805,622 @@ Message from section two
</Section>
<OverallResult success="true"/>
</TestCase>
<TestCase name="TemplateTest: vectors can be sized and resized - float" tags="[template][vector]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<Section name="resizing bigger changes size and capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 10
</Original>
<Expanded>
10 == 10
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 10
</Original>
<Expanded>
10 >= 10
</Expanded>
</Expression>
<OverallResults successes="2" failures="0" expectedFailures="0"/>
</Section>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<Section name="resizing smaller changes size but not capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 0
</Original>
<Expanded>
0 == 0
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<Section name="We can use the 'swap trick' to reset the capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() == 0
</Original>
<Expanded>
0 == 0
</Expanded>
</Expression>
<OverallResults successes="1" failures="0" expectedFailures="0"/>
</Section>
<OverallResults successes="3" failures="0" expectedFailures="0"/>
</Section>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<Section name="reserving bigger changes capacity but not size" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 10
</Original>
<Expanded>
10 >= 10
</Expanded>
</Expression>
<OverallResults successes="2" failures="0" expectedFailures="0"/>
</Section>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<Section name="reserving smaller does not change size or capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<OverallResults successes="2" failures="0" expectedFailures="0"/>
</Section>
<OverallResult success="true"/>
</TestCase>
<TestCase name="TemplateTest: vectors can be sized and resized - int" tags="[template][vector]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<Section name="resizing bigger changes size and capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 10
</Original>
<Expanded>
10 == 10
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 10
</Original>
<Expanded>
10 >= 10
</Expanded>
</Expression>
<OverallResults successes="2" failures="0" expectedFailures="0"/>
</Section>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<Section name="resizing smaller changes size but not capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 0
</Original>
<Expanded>
0 == 0
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<Section name="We can use the 'swap trick' to reset the capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() == 0
</Original>
<Expanded>
0 == 0
</Expanded>
</Expression>
<OverallResults successes="1" failures="0" expectedFailures="0"/>
</Section>
<OverallResults successes="3" failures="0" expectedFailures="0"/>
</Section>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<Section name="reserving bigger changes capacity but not size" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 10
</Original>
<Expanded>
10 >= 10
</Expanded>
</Expression>
<OverallResults successes="2" failures="0" expectedFailures="0"/>
</Section>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<Section name="reserving smaller does not change size or capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<OverallResults successes="2" failures="0" expectedFailures="0"/>
</Section>
<OverallResult success="true"/>
</TestCase>
<TestCase name="TemplateTest: vectors can be sized and resized - std::string" tags="[template][vector]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<Section name="resizing bigger changes size and capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 10
</Original>
<Expanded>
10 == 10
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 10
</Original>
<Expanded>
10 >= 10
</Expanded>
</Expression>
<OverallResults successes="2" failures="0" expectedFailures="0"/>
</Section>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<Section name="resizing smaller changes size but not capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 0
</Original>
<Expanded>
0 == 0
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<Section name="We can use the 'swap trick' to reset the capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() == 0
</Original>
<Expanded>
0 == 0
</Expanded>
</Expression>
<OverallResults successes="1" failures="0" expectedFailures="0"/>
</Section>
<OverallResults successes="3" failures="0" expectedFailures="0"/>
</Section>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<Section name="reserving bigger changes capacity but not size" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 10
</Original>
<Expanded>
10 >= 10
</Expanded>
</Expression>
<OverallResults successes="2" failures="0" expectedFailures="0"/>
</Section>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<Section name="reserving smaller does not change size or capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<OverallResults successes="2" failures="0" expectedFailures="0"/>
</Section>
<OverallResult success="true"/>
</TestCase>
<TestCase name="TemplateTest: vectors can be sized and resized - std::tuple&lt;int,float>" tags="[template][vector]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<Section name="resizing bigger changes size and capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 10
</Original>
<Expanded>
10 == 10
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 10
</Original>
<Expanded>
10 >= 10
</Expanded>
</Expression>
<OverallResults successes="2" failures="0" expectedFailures="0"/>
</Section>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<Section name="resizing smaller changes size but not capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 0
</Original>
<Expanded>
0 == 0
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<Section name="We can use the 'swap trick' to reset the capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() == 0
</Original>
<Expanded>
0 == 0
</Expanded>
</Expression>
<OverallResults successes="1" failures="0" expectedFailures="0"/>
</Section>
<OverallResults successes="3" failures="0" expectedFailures="0"/>
</Section>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<Section name="reserving bigger changes capacity but not size" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 10
</Original>
<Expanded>
10 >= 10
</Expanded>
</Expression>
<OverallResults successes="2" failures="0" expectedFailures="0"/>
</Section>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<Section name="reserving smaller does not change size or capacity" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.size() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
<Original>
v.capacity() >= 5
</Original>
<Expanded>
5 >= 5
</Expanded>
</Expression>
<OverallResults successes="2" failures="0" expectedFailures="0"/>
</Section>
<OverallResult success="true"/>
</TestCase>
<TestCase name="Test case with one argument" filename="projects/<exe-name>/UsageTests/VariadicMacros.tests.cpp" >
<OverallResult success="true"/>
</TestCase>
@@ -11321,7 +12099,7 @@ loose text artifact
</Section>
<OverallResult success="true"/>
</TestCase>
<OverallResults successes="1099" failures="123" expectedFailures="21"/>
<OverallResults successes="1178" failures="126" expectedFailures="21"/>
</Group>
<OverallResults successes="1099" failures="122" expectedFailures="21"/>
<OverallResults successes="1178" failures="125" expectedFailures="21"/>
</Catch>

View File

@@ -280,7 +280,6 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]"
CHECK(config.processName == "");
}
SECTION("default - no arguments") {
auto result = cli.parse({"test"});
CHECK(result);
@@ -345,8 +344,15 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]"
SECTION("Only one reporter is accepted") {
REQUIRE_FALSE(cli.parse({ "test", "-r", "xml", "-r", "junit" }));
}
}
SECTION("must match one of the available ones") {
auto result = cli.parse({"test", "--reporter", "unsupported"});
CHECK(!result);
#ifndef CATCH_CONFIG_DISABLE_MATCHERS
REQUIRE_THAT(result.errorMessage(), Contains("Unrecognized reporter"));
#endif
}
}
SECTION("debugger") {
SECTION("-b") {

View File

@@ -39,6 +39,13 @@ struct Fixture
int m_a;
};
template< typename T >
struct Template_Fixture {
Template_Fixture(): m_a(1) {}
T m_a;
};
#endif
@@ -51,6 +58,10 @@ TEST_CASE_METHOD( Fixture, "A TEST_CASE_METHOD based test run that succeeds", "[
REQUIRE( m_a == 1 );
}
TEMPLATE_TEST_CASE_METHOD(Template_Fixture, "A TEMPLATE_TEST_CASE_METHOD based test run that succeeds", "[class][template]", int, float, double) {
REQUIRE( Template_Fixture<TestType>::m_a == 1 );
}
// We should be able to write our tests within a different namespace
namespace Inner
{
@@ -58,6 +69,13 @@ namespace Inner
{
REQUIRE( m_a == 2 );
}
TEMPLATE_TEST_CASE_METHOD(Template_Fixture,"A TEMPLATE_TEST_CASE_METHOD based test run that fails", "[.][class][template][failing]", int, float, double)
{
REQUIRE( Template_Fixture<TestType>::m_a == 2 );
}
}
}} // namespace ClassTests

View File

@@ -5,6 +5,26 @@
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include <type_traits>
// Setup for #1403 -- look for global overloads of operator << for classes
// in a different namespace.
#include <ostream>
namespace foo {
struct helper_1403 {
bool operator==(helper_1403) const { return true; }
};
}
#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wmissing-declarations"
#endif
std::ostream& operator<<(std::ostream& out, foo::helper_1403 const&) {
return out << "[1403 helper]";
}
///////////////////////////////
#include "catch.hpp"
#include <cstring>
@@ -154,4 +174,16 @@ namespace { namespace CompilationTests {
SUCCEED();
}
TEST_CASE("#1403", "[compilation]") {
::foo::helper_1403 h1, h2;
REQUIRE(h1 == h2);
}
TEST_CASE("Optionally static assertions", "[compilation]") {
STATIC_REQUIRE( std::is_void<void>::value );
STATIC_REQUIRE_FALSE( std::is_void<int>::value );
}
}} // namespace CompilationTests

View File

@@ -432,6 +432,10 @@ namespace { namespace MatchersTests {
CHECK_THAT(actual, !UnorderedEquals(expected));
}
TEST_CASE("Predicate matcher can accept const char*", "[matchers][compilation]") {
REQUIRE_THAT("foo", Predicate<const char*>([] (const char* const&) { return true; }));
}
} } // namespace MatchersTests
#endif // CATCH_CONFIG_DISABLE_MATCHERS

View File

@@ -9,10 +9,6 @@
#include "catch.hpp"
#include <iostream>
#ifdef __clang__
#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
#endif
TEST_CASE( "INFO and WARN do not abort tests", "[messages][.]" ) {
INFO( "this is a " << "message" ); // This should output the message if a failure occurs
WARN( "this is a " << "warning" ); // This should always output the message but then continue
@@ -135,3 +131,60 @@ TEST_CASE( "Pointers can be converted to strings", "[messages][.][approvals]" )
WARN( "actual address of p: " << &p );
WARN( "toString(p): " << ::Catch::Detail::stringify( &p ) );
}
TEST_CASE( "CAPTURE can deal with complex expressions", "[messages][capture]" ) {
int a = 1;
int b = 2;
int c = 3;
CAPTURE( a, b, c, a + b, a+b, c > b, a == 1 );
SUCCEED();
}
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-value" // In (1, 2), the "1" is unused ...
#endif
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-value" // All the comma operators are side-effect free
#endif
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4709) // comma in indexing operator
#endif
template <typename T1, typename T2>
struct helper_1436 {
helper_1436(T1 t1, T2 t2):
t1{ t1 },
t2{ t2 }
{}
T1 t1;
T2 t2;
};
template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& out, helper_1436<T1, T2> const& helper) {
out << "{ " << helper.t1 << ", " << helper.t2 << " }";
return out;
}
TEST_CASE("CAPTURE can deal with complex expressions involving commas", "[messages][capture]") {
CAPTURE(std::vector<int>{1, 2, 3}[0, 1, 2],
std::vector<int>{1, 2, 3}[(0, 1)],
std::vector<int>{1, 2, 3}[0]);
CAPTURE((helper_1436<int, int>{12, -12}),
(helper_1436<int, int>(-12, 12)));
CAPTURE( (1, 2), (2, 3) );
SUCCEED();
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#ifdef _MSC_VER
#pragma warning(pop)
#endif

View File

@@ -261,6 +261,46 @@ TEST_CASE( "vectors can be sized and resized", "[vector]" ) {
}
}
TEMPLATE_TEST_CASE( "TemplateTest: vectors can be sized and resized", "[vector][template]", int, float, std::string, (std::tuple<int,float>) ) {
std::vector<TestType> v( 5 );
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 5 );
SECTION( "resizing bigger changes size and capacity" ) {
v.resize( 10 );
REQUIRE( v.size() == 10 );
REQUIRE( v.capacity() >= 10 );
}
SECTION( "resizing smaller changes size but not capacity" ) {
v.resize( 0 );
REQUIRE( v.size() == 0 );
REQUIRE( v.capacity() >= 5 );
SECTION( "We can use the 'swap trick' to reset the capacity" ) {
std::vector<TestType> empty;
empty.swap( v );
REQUIRE( v.capacity() == 0 );
}
}
SECTION( "reserving bigger changes capacity but not size" ) {
v.reserve( 10 );
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 10 );
}
SECTION( "reserving smaller does not change size or capacity" ) {
v.reserve( 0 );
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 5 );
}
}
// https://github.com/philsquared/Catch/issues/166
TEST_CASE("A couple of nested sections followed by a failure", "[failing][.]") {
SECTION("Outer")

View File

@@ -18,7 +18,7 @@ if os.name == 'nt':
rootPath = os.path.join(catchPath, 'projects/SelfTest/Baselines')
langFilenameParser = re.compile(r'(.+\.[ch]pp)')
filelocParser = re.compile(r'''
.*/
(.+\.[ch]pp) # filename
@@ -91,12 +91,24 @@ def diffFiles(fileA, fileB):
return [line for line in diff if line[0] in ('+', '-')]
def filterLine(line, isCompact):
def normalizeFilepath(line):
if catchPath in line:
# make paths relative to Catch root
line = line.replace(catchPath + os.sep, '')
m = langFilenameParser.match(line)
if m:
filepath = m.group(0)
# go from \ in windows paths to /
line = line.replace('\\', '/')
filepath = filepath.replace('\\', '/')
# remove start of relative path
filepath = filepath.replace('../', '')
line = line[:m.start()] + filepath + line[m.end():]
return line
def filterLine(line, isCompact):
line = normalizeFilepath(line)
# strip source line numbers
m = filelocParser.match(line)
@@ -181,17 +193,17 @@ print(" " + cmdPath)
# ## Keep default reporters here ##
# Standard console reporter
approve("console.std", ["~[!nonportable]~[!benchmark]~[approvals]", "--order", "lex", "--rng-seed", "0"])
approve("console.std", ["~[!nonportable]~[!benchmark]~[approvals]", "--order", "lex", "--rng-seed", "1"])
# console reporter, include passes, warn about No Assertions
approve("console.sw", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "--order", "lex", "--rng-seed", "0"])
approve("console.sw", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "--order", "lex", "--rng-seed", "1"])
# console reporter, include passes, warn about No Assertions, limit failures to first 4
approve("console.swa4", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "-x", "4", "--order", "lex", "--rng-seed", "0"])
approve("console.swa4", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "-x", "4", "--order", "lex", "--rng-seed", "1"])
# junit reporter, include passes, warn about No Assertions
approve("junit.sw", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "-r", "junit", "--order", "lex", "--rng-seed", "0"])
approve("junit.sw", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "-r", "junit", "--order", "lex", "--rng-seed", "1"])
# xml reporter, include passes, warn about No Assertions
approve("xml.sw", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "-r", "xml", "--order", "lex", "--rng-seed", "0"])
approve("xml.sw", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "-r", "xml", "--order", "lex", "--rng-seed", "1"])
# compact reporter, include passes, warn about No Assertions
approve('compact.sw', ['~[!nonportable]~[!benchmark]~[approvals]', '-s', '-w', 'NoAssertions', '-r', 'compact', '--order', 'lex', "--rng-seed", "0"])
approve('compact.sw', ['~[!nonportable]~[!benchmark]~[approvals]', '-s', '-w', 'NoAssertions', '-r', 'compact', '--order', 'lex', "--rng-seed", "1"])
if overallResult != 0:
print("If these differences are expected, run approve.py to approve new baselines.")

View File

@@ -12,8 +12,6 @@ rootPath = os.path.join( catchPath, 'include/' )
versionPath = os.path.join( rootPath, "internal/catch_version.cpp" )
definePath = os.path.join(rootPath, 'catch.hpp')
readmePath = os.path.join( catchPath, "README.md" )
conanPath = os.path.join(catchPath, 'conanfile.py')
conanTestPath = os.path.join(catchPath, 'test_package', 'conanfile.py')
cmakePath = os.path.join(catchPath, 'CMakeLists.txt')
class Version:
@@ -98,35 +96,6 @@ def updateReadmeFile(version):
line = '[![Try online](https://img.shields.io/badge/try-online-blue.svg)]({0})'.format(wandboxLink)
f.write( line + "\n" )
def updateConanFile(version):
conanParser = re.compile( r' version = "\d+\.\d+\.\d+.*"')
f = open( conanPath, 'r' )
lines = []
for line in f:
m = conanParser.match( line )
if m:
lines.append( ' version = "{0}"'.format(format(version.getVersionString())) )
else:
lines.append( line.rstrip() )
f.close()
f = open( conanPath, 'w' )
for line in lines:
f.write( line + "\n" )
def updateConanTestFile(version):
conanParser = re.compile( r' requires = \"Catch\/\d+\.\d+\.\d+.*@%s\/%s\" % \(username, channel\)')
f = open( conanTestPath, 'r' )
lines = []
for line in f:
m = conanParser.match( line )
if m:
lines.append( ' requires = "Catch/{0}@%s/%s" % (username, channel)'.format(format(version.getVersionString())) )
else:
lines.append( line.rstrip() )
f.close()
f = open( conanTestPath, 'w' )
for line in lines:
f.write( line + "\n" )
def updateCmakeFile(version):
with open(cmakePath, 'r') as file:
@@ -173,6 +142,4 @@ def performUpdates(version):
shutil.copyfile(sourceFile, destFile)
updateReadmeFile(version)
updateConanFile(version)
updateConanTestFile(version)
updateCmakeFile(version)

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +0,0 @@
cmake_minimum_required(VERSION 3.0)
project(CatchTest CXX)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
add_executable(${CMAKE_PROJECT_NAME} MainTest.cpp)

View File

@@ -1,21 +0,0 @@
/*
* Created by Phil on 22/10/2010.
* Copyright 2010 Two Blue Cubes Ltd
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>
unsigned int Factorial( unsigned int number ) {
return number > 1 ? Factorial(number-1)*number : 1;
}
TEST_CASE( "Factorials are computed", "[factorial]" ) {
REQUIRE( Factorial(0) == 1 );
REQUIRE( Factorial(1) == 1 );
REQUIRE( Factorial(2) == 2 );
REQUIRE( Factorial(3) == 6 );
REQUIRE( Factorial(10) == 3628800 );
}

View File

@@ -1,21 +0,0 @@
#!/usr/bin/env python
from os import getenv
from os import path
from conans import ConanFile
from conans import CMake
class CatchConanTest(ConanFile):
generators = "cmake"
settings = "os", "compiler", "arch", "build_type"
username = getenv("CONAN_USERNAME", "philsquared")
channel = getenv("CONAN_CHANNEL", "testing")
requires = "Catch/2.4.1@%s/%s" % (username, channel)
def build(self):
cmake = CMake(self)
cmake.configure(build_dir="./")
cmake.build()
def test(self):
self.run(path.join("bin", "CatchTest"))

25
third_party/clara.hpp vendored
View File

@@ -5,7 +5,7 @@
//
// See https://github.com/philsquared/Clara for more details
// Clara v1.1.4
// Clara v1.1.5
#ifndef CLARA_HPP_INCLUDED
#define CLARA_HPP_INCLUDED
@@ -34,8 +34,8 @@
//
// A single-header library for wrapping and laying out basic text, by Phil Nash
//
// This work is licensed under the BSD 2-Clause license.
// See the accompanying LICENSE file, or the one at https://opensource.org/licenses/BSD-2-Clause
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// This project is hosted at https://github.com/philsquared/textflowcpp
@@ -142,6 +142,12 @@ namespace clara { namespace TextFlow {
}
public:
using difference_type = std::ptrdiff_t;
using value_type = std::string;
using pointer = value_type*;
using reference = value_type&;
using iterator_category = std::forward_iterator_tag;
explicit iterator( Column const& column ) : m_column( column ) {
assert( m_column.m_width > m_column.m_indent );
assert( m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent );
@@ -153,10 +159,7 @@ namespace clara { namespace TextFlow {
auto operator *() const -> std::string {
assert( m_stringIndex < m_column.m_strings.size() );
assert( m_pos <= m_end );
if( m_pos + m_column.m_width < m_end )
return addIndentAndSuffix(line().substr(m_pos, m_len));
else
return addIndentAndSuffix(line().substr(m_pos, m_end - m_pos));
return addIndentAndSuffix(line().substr(m_pos, m_len));
}
auto operator ++() -> iterator& {
@@ -266,6 +269,12 @@ namespace clara { namespace TextFlow {
}
public:
using difference_type = std::ptrdiff_t;
using value_type = std::string;
using pointer = value_type*;
using reference = value_type&;
using iterator_category = std::forward_iterator_tag;
explicit iterator( Columns const& columns )
: m_columns( columns.m_columns ),
m_activeIterators( m_columns.size() )
@@ -355,7 +364,7 @@ namespace clara { namespace TextFlow {
cols += other;
return cols;
}
}} // namespace clara::TextFlow
}}
#endif // CLARA_TEXTFLOW_HPP_INCLUDED