mirror of
https://github.com/catchorg/Catch2.git
synced 2024-12-22 19:33:29 +01:00
parent
24e6d5fa33
commit
0b1f1b1003
@ -140,6 +140,7 @@ set(INTERNAL_HEADERS
|
||||
${HEADER_DIR}/internal/catch_leak_detector.h
|
||||
${HEADER_DIR}/internal/catch_list.h
|
||||
${HEADER_DIR}/internal/catch_matchers.h
|
||||
${HEADER_DIR}/internal/catch_matchers_floating.h
|
||||
${HEADER_DIR}/internal/catch_matchers_string.h
|
||||
${HEADER_DIR}/internal/catch_matchers_vector.h
|
||||
${HEADER_DIR}/internal/catch_message.h
|
||||
@ -206,6 +207,7 @@ set(IMPL_SOURCES
|
||||
${HEADER_DIR}/internal/catch_list.cpp
|
||||
${HEADER_DIR}/internal/catch_leak_detector.cpp
|
||||
${HEADER_DIR}/internal/catch_matchers.cpp
|
||||
${HEADER_DIR}/internal/catch_matchers_floating.cpp
|
||||
${HEADER_DIR}/internal/catch_matchers_string.cpp
|
||||
${HEADER_DIR}/internal/catch_message.cpp
|
||||
${HEADER_DIR}/internal/catch_registry_hub.cpp
|
||||
|
@ -36,10 +36,19 @@ REQUIRE_THAT( str,
|
||||
```
|
||||
|
||||
## Built in matchers
|
||||
Currently Catch has some string matchers and some vector matchers. They are in the `Catch::Matchers` and `Catch` namespaces.
|
||||
Catch currently provides some matchers, they are in the `Catch::Matchers` and `Catch` namespaces.
|
||||
|
||||
### String matchers
|
||||
The string matchers are `StartsWith`, `EndsWith`, `Contains` and `Equals`. Each of them also takes an optional second argument, that decides case sensitivity (by-default, they are case sensitive).
|
||||
|
||||
### Vector matchers
|
||||
The vector matchers are `Contains`, `VectorContains` and `Equals`. `VectorContains` looks for a single element in the matched vector, `Contains` looks for a set (vector) of elements inside the matched vector.
|
||||
|
||||
### Floating point matchers
|
||||
The floating point matchers are `WithinULP` and `WithinAbs`. `WithinAbs` accepts floating point numbers that are within a certain margin of target. `WithinULP` performs an [ULP](https://en.wikipedia.org/wiki/Unit_in_the_last_place)-based comparison of two floating point numbers and accepts them if they are less than certain number of ULPs apart.
|
||||
|
||||
Do note that ULP-based checks only make sense when both compared numbers are of the same type and `WithinULP` will use type of its argument as the target type. This means that `WithinULP(1.f, 1)` will expect to compare `float`s, but `WithinULP(1., 1)` will expect to compare `double`s.
|
||||
|
||||
|
||||
## Custom matchers
|
||||
It's easy to provide your own matchers to extend Catch or just to work with your own types.
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "catch_capture.hpp"
|
||||
#include "catch_matchers.h"
|
||||
#include "catch_matchers_floating.h"
|
||||
#include "catch_matchers_string.h"
|
||||
#include "catch_matchers_vector.h"
|
||||
|
||||
|
144
include/internal/catch_matchers_floating.cpp
Normal file
144
include/internal/catch_matchers_floating.cpp
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Created by Martin on 07/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_matchers_floating.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace Catch {
|
||||
namespace Matchers {
|
||||
namespace Floating {
|
||||
enum class FloatingPointKind : uint8_t {
|
||||
Float,
|
||||
Double
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
union Float_t {
|
||||
Float_t(float num = 0.0f) : f(num) {}
|
||||
// Portable extraction of components.
|
||||
bool Negative() const { return i < 0; }
|
||||
int32_t RawMantissa() const { return i & ((1 << 23) - 1); }
|
||||
int32_t RawExponent() const { return (i >> 23) & 0xFF; }
|
||||
|
||||
int32_t i;
|
||||
float f;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct Converter;
|
||||
|
||||
template <>
|
||||
struct Converter<float> {
|
||||
static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
|
||||
Converter(float f) {
|
||||
std::memcpy(&i, &f, sizeof(f));
|
||||
}
|
||||
int32_t i;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<double> {
|
||||
static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
|
||||
Converter(double d) {
|
||||
std::memcpy(&i, &d, sizeof(d));
|
||||
}
|
||||
int64_t i;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
auto convert(T t) -> Converter<T> {
|
||||
return Converter<T>(t);
|
||||
}
|
||||
|
||||
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)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto lc = convert(lhs);
|
||||
auto rc = convert(rhs);
|
||||
|
||||
if ((lc.i < 0) != (rc.i < 0)) {
|
||||
// Potentially we can have +0 and -0
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
auto ulpDiff = abs(lc.i - rc.i);
|
||||
return ulpDiff <= maxUlpDiff;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace Catch {
|
||||
namespace Matchers {
|
||||
namespace Floating {
|
||||
WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
|
||||
:m_target{ target }, m_margin{ margin } {}
|
||||
|
||||
// Performs equivalent check of std::fabs(lhs - rhs) <= margin
|
||||
// But without the subtraction to allow for INFINITY in comparison
|
||||
bool WithinAbsMatcher::match(double const& matchee) const {
|
||||
return (matchee + m_margin >= m_target) && (m_target + m_margin >= m_margin);
|
||||
}
|
||||
|
||||
std::string WithinAbsMatcher::describe() const {
|
||||
return "is within " + std::to_string(m_margin) + " of " + std::to_string(m_target);
|
||||
}
|
||||
|
||||
|
||||
WithinUlpsMatcher::WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType)
|
||||
:m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
|
||||
if (m_ulps < 0) {
|
||||
throw std::domain_error("Expected ulp difference has to be >0");
|
||||
}
|
||||
}
|
||||
|
||||
bool WithinUlpsMatcher::match(double const& matchee) const {
|
||||
switch (m_type) {
|
||||
case FloatingPointKind::Float:
|
||||
return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);
|
||||
case FloatingPointKind::Double:
|
||||
return almostEqualUlps<double>(matchee, m_target, m_ulps);
|
||||
default:
|
||||
throw std::domain_error("Unknown FloatingPointKind value");
|
||||
}
|
||||
}
|
||||
|
||||
std::string WithinUlpsMatcher::describe() const {
|
||||
return "is within " + std::to_string(m_ulps) + " ULPs of " + std::to_string(m_target) + ((m_type == FloatingPointKind::Float)? "f" : "");
|
||||
}
|
||||
|
||||
}// namespace Floating
|
||||
|
||||
|
||||
|
||||
Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff) {
|
||||
return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
|
||||
}
|
||||
|
||||
Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff) {
|
||||
return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
|
||||
}
|
||||
|
||||
Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
|
||||
return Floating::WithinAbsMatcher(target, margin);
|
||||
}
|
||||
|
||||
} // namespace Matchers
|
||||
} // namespace Catch
|
||||
|
59
include/internal/catch_matchers_floating.h
Normal file
59
include/internal/catch_matchers_floating.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Created by Martin on 07/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_MATCHERS_FLOATING_H_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_MATCHERS_FLOATING_H_INCLUDED
|
||||
|
||||
#include "catch_matchers.h"
|
||||
|
||||
#include <type_traits>
|
||||
#include <cmath>
|
||||
|
||||
namespace Catch {
|
||||
namespace Matchers {
|
||||
|
||||
namespace Floating {
|
||||
|
||||
enum class FloatingPointKind : uint8_t;
|
||||
|
||||
struct WithinAbsMatcher : MatcherBase<double> {
|
||||
WithinAbsMatcher(double target, double margin);
|
||||
bool match(double const& matchee) const override;
|
||||
std::string describe() const override;
|
||||
private:
|
||||
double m_target;
|
||||
double m_margin;
|
||||
};
|
||||
|
||||
struct WithinUlpsMatcher : MatcherBase<double> {
|
||||
WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType);
|
||||
bool match(double const& matchee) const override;
|
||||
std::string describe() const override;
|
||||
private:
|
||||
double m_target;
|
||||
int m_ulps;
|
||||
FloatingPointKind m_type;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Floating
|
||||
|
||||
Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff);
|
||||
Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff);
|
||||
Floating::WithinAbsMatcher WithinAbs(double target, double margin);
|
||||
|
||||
// The following functions create the actual matcher objects.
|
||||
// This allows the types to be inferred
|
||||
|
||||
// StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
|
||||
// StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
|
||||
// StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
|
||||
// StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
|
||||
|
||||
} // namespace Matchers
|
||||
} // namespace Catch
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_MATCHERS_FLOATING_H_INCLUDED
|
@ -1003,6 +1003,6 @@ with expansion:
|
||||
"{?}" == "1"
|
||||
|
||||
===============================================================================
|
||||
test cases: 185 | 134 passed | 47 failed | 4 failed as expected
|
||||
assertions: 904 | 787 passed | 96 failed | 21 failed as expected
|
||||
test cases: 187 | 136 passed | 47 failed | 4 failed as expected
|
||||
assertions: 935 | 818 passed | 96 failed | 21 failed as expected
|
||||
|
||||
|
@ -1717,6 +1717,234 @@ PASSED:
|
||||
with expansion:
|
||||
3628800 (0x<hex digits>) == 3628800 (0x<hex digits>)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Floating point matchers: double
|
||||
Margin
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( 1., WithinAbs(1., 0) )
|
||||
with expansion:
|
||||
1.0 is within 0.000000 of 1.000000
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( 0., WithinAbs(1., 1) )
|
||||
with expansion:
|
||||
0.0 is within 1.000000 of 1.000000
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( 0., !WithinAbs(1., 0.99) )
|
||||
with expansion:
|
||||
0.0 not is within 0.990000 of 1.000000
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( 0., !WithinAbs(1., 0.99) )
|
||||
with expansion:
|
||||
0.0 not is within 0.990000 of 1.000000
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( NAN, !WithinAbs(NAN, 0) )
|
||||
with expansion:
|
||||
nanf not is within 0.000000 of nan
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Floating point matchers: double
|
||||
ULPs
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( 1., WithinULP(1., 0) )
|
||||
with expansion:
|
||||
1.0 is within 0 ULPs of 1.000000
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( std::nextafter(1., 2.), WithinULP(1., 1) )
|
||||
with expansion:
|
||||
1.0 is within 1 ULPs of 1.000000
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( std::nextafter(1., 0.), WithinULP(1., 1) )
|
||||
with expansion:
|
||||
1.0 is within 1 ULPs of 1.000000
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( std::nextafter(1., 2.), !WithinULP(1., 0) )
|
||||
with expansion:
|
||||
1.0 not is within 0 ULPs of 1.000000
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( 1., WithinULP(1., 0) )
|
||||
with expansion:
|
||||
1.0 is within 0 ULPs of 1.000000
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( -0., WithinULP(0., 0) )
|
||||
with expansion:
|
||||
-0.0 is within 0 ULPs of 0.000000
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( NAN, !WithinULP(NAN, 123) )
|
||||
with expansion:
|
||||
nanf not is within 123 ULPs of nanf
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Floating point matchers: double
|
||||
Composed
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( 1., WithinAbs(1., 0.5) || WithinULP(2., 1) )
|
||||
with expansion:
|
||||
1.0 ( is within 0.500000 of 1.000000 or is within 1 ULPs of 2.000000 )
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( 1., WithinAbs(2., 0.5) || WithinULP(1., 0) )
|
||||
with expansion:
|
||||
1.0 ( is within 0.500000 of 2.000000 or is within 0 ULPs of 1.000000 )
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123)) )
|
||||
with expansion:
|
||||
nanf not ( is within 100.000000 of nan or is within 123 ULPs of nanf )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Floating point matchers: float
|
||||
Margin
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( 1.f, WithinAbs(1.f, 0) )
|
||||
with expansion:
|
||||
1.0f is within 0.000000 of 1.000000
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( 0.f, WithinAbs(1.f, 1) )
|
||||
with expansion:
|
||||
0.0f is within 1.000000 of 1.000000
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( 0.f, !WithinAbs(1.f, 0.99f) )
|
||||
with expansion:
|
||||
0.0f not is within 0.990000 of 1.000000
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( 0.f, !WithinAbs(1.f, 0.99f) )
|
||||
with expansion:
|
||||
0.0f not is within 0.990000 of 1.000000
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( 0.f, WithinAbs(-0.f, 0) )
|
||||
with expansion:
|
||||
0.0f is within 0.000000 of -0.000000
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( NAN, !WithinAbs(NAN, 0) )
|
||||
with expansion:
|
||||
nanf not is within 0.000000 of nan
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Floating point matchers: float
|
||||
ULPs
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( 1.f, WithinULP(1.f, 0) )
|
||||
with expansion:
|
||||
1.0f is within 0 ULPs of 1.000000f
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( std::nextafter(1.f, 2.f), WithinULP(1.f, 1) )
|
||||
with expansion:
|
||||
1.0f is within 1 ULPs of 1.000000f
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( std::nextafter(1.f, 0.f), WithinULP(1.f, 1) )
|
||||
with expansion:
|
||||
1.0f is within 1 ULPs of 1.000000f
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( std::nextafter(1.f, 2.f), !WithinULP(1.f, 0) )
|
||||
with expansion:
|
||||
1.0f not is within 0 ULPs of 1.000000f
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( 1.f, WithinULP(1.f, 0) )
|
||||
with expansion:
|
||||
1.0f is within 0 ULPs of 1.000000f
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( -0.f, WithinULP(0.f, 0) )
|
||||
with expansion:
|
||||
-0.0f is within 0 ULPs of 0.000000f
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( NAN, !WithinULP(NAN, 123) )
|
||||
with expansion:
|
||||
nanf not is within 123 ULPs of nanf
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Floating point matchers: float
|
||||
Composed
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( 1.f, WithinAbs(1.f, 0.5) || WithinULP(1.f, 1) )
|
||||
with expansion:
|
||||
1.0f ( is within 0.500000 of 1.000000 or is within 1 ULPs of 1.000000f )
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( 1.f, WithinAbs(2.f, 0.5) || WithinULP(1.f, 0) )
|
||||
with expansion:
|
||||
1.0f ( is within 0.500000 of 2.000000 or is within 0 ULPs of 1.000000f )
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123)) )
|
||||
with expansion:
|
||||
nanf not ( is within 100.000000 of nan or is within 123 ULPs of nanf )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Greater-than inequalities with different epsilons
|
||||
-------------------------------------------------------------------------------
|
||||
@ -7632,6 +7860,6 @@ MiscTests.cpp:<line number>:
|
||||
PASSED:
|
||||
|
||||
===============================================================================
|
||||
test cases: 185 | 132 passed | 49 failed | 4 failed as expected
|
||||
assertions: 903 | 783 passed | 99 failed | 21 failed as expected
|
||||
test cases: 187 | 134 passed | 49 failed | 4 failed as expected
|
||||
assertions: 934 | 814 passed | 99 failed | 21 failed as expected
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuitesloose text artifact
|
||||
>
|
||||
<testsuite name="<exe-name>" errors="15" failures="85" tests="904" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||
<testsuite name="<exe-name>" errors="15" failures="85" tests="935" 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="#748 - captures with unexpected exceptions/outside assertions" time="{duration}">
|
||||
@ -263,6 +263,12 @@ MessageTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="<exe-name>.global" name="Factorials are computed" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Floating point matchers: double/Margin" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Floating point matchers: double/ULPs" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Floating point matchers: double/Composed" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Floating point matchers: float/Margin" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Floating point matchers: float/ULPs" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Floating point matchers: float/Composed" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Greater-than inequalities with different epsilons" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="INFO and WARN do not abort tests" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="INFO gets logged on failure" time="{duration}">
|
||||
|
@ -1945,6 +1945,278 @@
|
||||
</Expression>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Floating point matchers: double" tags="[floating-point][matchers]" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Section name="Margin" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
1., WithinAbs(1., 0)
|
||||
</Original>
|
||||
<Expanded>
|
||||
1.0 is within 0.000000 of 1.000000
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
0., WithinAbs(1., 1)
|
||||
</Original>
|
||||
<Expanded>
|
||||
0.0 is within 1.000000 of 1.000000
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
0., !WithinAbs(1., 0.99)
|
||||
</Original>
|
||||
<Expanded>
|
||||
0.0 not is within 0.990000 of 1.000000
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
0., !WithinAbs(1., 0.99)
|
||||
</Original>
|
||||
<Expanded>
|
||||
0.0 not is within 0.990000 of 1.000000
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
NAN, !WithinAbs(NAN, 0)
|
||||
</Original>
|
||||
<Expanded>
|
||||
nanf not is within 0.000000 of nan
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="5" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="ULPs" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
1., WithinULP(1., 0)
|
||||
</Original>
|
||||
<Expanded>
|
||||
1.0 is within 0 ULPs of 1.000000
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
std::nextafter(1., 2.), WithinULP(1., 1)
|
||||
</Original>
|
||||
<Expanded>
|
||||
1.0 is within 1 ULPs of 1.000000
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
std::nextafter(1., 0.), WithinULP(1., 1)
|
||||
</Original>
|
||||
<Expanded>
|
||||
1.0 is within 1 ULPs of 1.000000
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
std::nextafter(1., 2.), !WithinULP(1., 0)
|
||||
</Original>
|
||||
<Expanded>
|
||||
1.0 not is within 0 ULPs of 1.000000
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
1., WithinULP(1., 0)
|
||||
</Original>
|
||||
<Expanded>
|
||||
1.0 is within 0 ULPs of 1.000000
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
-0., WithinULP(0., 0)
|
||||
</Original>
|
||||
<Expanded>
|
||||
-0.0 is within 0 ULPs of 0.000000
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
NAN, !WithinULP(NAN, 123)
|
||||
</Original>
|
||||
<Expanded>
|
||||
nanf not is within 123 ULPs of nanf
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="7" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="Composed" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
1., WithinAbs(1., 0.5) || WithinULP(2., 1)
|
||||
</Original>
|
||||
<Expanded>
|
||||
1.0 ( is within 0.500000 of 1.000000 or is within 1 ULPs of 2.000000 )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
1., WithinAbs(2., 0.5) || WithinULP(1., 0)
|
||||
</Original>
|
||||
<Expanded>
|
||||
1.0 ( is within 0.500000 of 2.000000 or is within 0 ULPs of 1.000000 )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123))
|
||||
</Original>
|
||||
<Expanded>
|
||||
nanf not ( is within 100.000000 of nan or is within 123 ULPs of nanf )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="3" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Floating point matchers: float" tags="[floating-point][matchers]" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Section name="Margin" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
1.f, WithinAbs(1.f, 0)
|
||||
</Original>
|
||||
<Expanded>
|
||||
1.0f is within 0.000000 of 1.000000
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
0.f, WithinAbs(1.f, 1)
|
||||
</Original>
|
||||
<Expanded>
|
||||
0.0f is within 1.000000 of 1.000000
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
0.f, !WithinAbs(1.f, 0.99f)
|
||||
</Original>
|
||||
<Expanded>
|
||||
0.0f not is within 0.990000 of 1.000000
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
0.f, !WithinAbs(1.f, 0.99f)
|
||||
</Original>
|
||||
<Expanded>
|
||||
0.0f not is within 0.990000 of 1.000000
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
0.f, WithinAbs(-0.f, 0)
|
||||
</Original>
|
||||
<Expanded>
|
||||
0.0f is within 0.000000 of -0.000000
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
NAN, !WithinAbs(NAN, 0)
|
||||
</Original>
|
||||
<Expanded>
|
||||
nanf not is within 0.000000 of nan
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="6" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="ULPs" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
1.f, WithinULP(1.f, 0)
|
||||
</Original>
|
||||
<Expanded>
|
||||
1.0f is within 0 ULPs of 1.000000f
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
std::nextafter(1.f, 2.f), WithinULP(1.f, 1)
|
||||
</Original>
|
||||
<Expanded>
|
||||
1.0f is within 1 ULPs of 1.000000f
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
std::nextafter(1.f, 0.f), WithinULP(1.f, 1)
|
||||
</Original>
|
||||
<Expanded>
|
||||
1.0f is within 1 ULPs of 1.000000f
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
std::nextafter(1.f, 2.f), !WithinULP(1.f, 0)
|
||||
</Original>
|
||||
<Expanded>
|
||||
1.0f not is within 0 ULPs of 1.000000f
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
1.f, WithinULP(1.f, 0)
|
||||
</Original>
|
||||
<Expanded>
|
||||
1.0f is within 0 ULPs of 1.000000f
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
-0.f, WithinULP(0.f, 0)
|
||||
</Original>
|
||||
<Expanded>
|
||||
-0.0f is within 0 ULPs of 0.000000f
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
NAN, !WithinULP(NAN, 123)
|
||||
</Original>
|
||||
<Expanded>
|
||||
nanf not is within 123 ULPs of nanf
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="7" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="Composed" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
1.f, WithinAbs(1.f, 0.5) || WithinULP(1.f, 1)
|
||||
</Original>
|
||||
<Expanded>
|
||||
1.0f ( is within 0.500000 of 1.000000 or is within 1 ULPs of 1.000000f )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
1.f, WithinAbs(2.f, 0.5) || WithinULP(1.f, 0)
|
||||
</Original>
|
||||
<Expanded>
|
||||
1.0f ( is within 0.500000 of 2.000000 or is within 0 ULPs of 1.000000f )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123))
|
||||
</Original>
|
||||
<Expanded>
|
||||
nanf not ( is within 100.000000 of nan or is within 123 ULPs of nanf )
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="3" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Greater-than inequalities with different epsilons" tags="[Approx]" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ApproxTests.cpp" >
|
||||
<Original>
|
||||
@ -8446,7 +8718,7 @@ loose text artifact
|
||||
</Section>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<OverallResults successes="783" failures="100" expectedFailures="21"/>
|
||||
<OverallResults successes="814" failures="100" expectedFailures="21"/>
|
||||
</Group>
|
||||
<OverallResults successes="783" failures="99" expectedFailures="21"/>
|
||||
<OverallResults successes="814" failures="99" expectedFailures="21"/>
|
||||
</Catch>
|
||||
|
@ -226,6 +226,67 @@ TEST_CASE("Exception matchers that fail", "[matchers][exceptions][!throws][.fail
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Floating point matchers: float", "[matchers][floating-point]") {
|
||||
SECTION("Margin") {
|
||||
REQUIRE_THAT(1.f, WithinAbs(1.f, 0));
|
||||
REQUIRE_THAT(0.f, WithinAbs(1.f, 1));
|
||||
|
||||
REQUIRE_THAT(0.f, !WithinAbs(1.f, 0.99f));
|
||||
REQUIRE_THAT(0.f, !WithinAbs(1.f, 0.99f));
|
||||
|
||||
REQUIRE_THAT(0.f, WithinAbs(-0.f, 0));
|
||||
REQUIRE_THAT(NAN, !WithinAbs(NAN, 0));
|
||||
}
|
||||
SECTION("ULPs") {
|
||||
REQUIRE_THAT(1.f, WithinULP(1.f, 0));
|
||||
|
||||
REQUIRE_THAT(std::nextafter(1.f, 2.f), WithinULP(1.f, 1));
|
||||
REQUIRE_THAT(std::nextafter(1.f, 0.f), WithinULP(1.f, 1));
|
||||
REQUIRE_THAT(std::nextafter(1.f, 2.f), !WithinULP(1.f, 0));
|
||||
|
||||
REQUIRE_THAT(1.f, WithinULP(1.f, 0));
|
||||
REQUIRE_THAT(-0.f, WithinULP(0.f, 0));
|
||||
|
||||
REQUIRE_THAT(NAN, !WithinULP(NAN, 123));
|
||||
}
|
||||
SECTION("Composed") {
|
||||
REQUIRE_THAT(1.f, WithinAbs(1.f, 0.5) || WithinULP(1.f, 1));
|
||||
REQUIRE_THAT(1.f, WithinAbs(2.f, 0.5) || WithinULP(1.f, 0));
|
||||
|
||||
REQUIRE_THAT(NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123)));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Floating point matchers: double", "[matchers][floating-point]") {
|
||||
SECTION("Margin") {
|
||||
REQUIRE_THAT(1., WithinAbs(1., 0));
|
||||
REQUIRE_THAT(0., WithinAbs(1., 1));
|
||||
|
||||
REQUIRE_THAT(0., !WithinAbs(1., 0.99));
|
||||
REQUIRE_THAT(0., !WithinAbs(1., 0.99));
|
||||
|
||||
REQUIRE_THAT(NAN, !WithinAbs(NAN, 0));
|
||||
}
|
||||
SECTION("ULPs") {
|
||||
REQUIRE_THAT(1., WithinULP(1., 0));
|
||||
|
||||
REQUIRE_THAT(std::nextafter(1., 2.), WithinULP(1., 1));
|
||||
REQUIRE_THAT(std::nextafter(1., 0.), WithinULP(1., 1));
|
||||
REQUIRE_THAT(std::nextafter(1., 2.), !WithinULP(1., 0));
|
||||
|
||||
REQUIRE_THAT(1., WithinULP(1., 0));
|
||||
REQUIRE_THAT(-0., WithinULP(0., 0));
|
||||
|
||||
REQUIRE_THAT(NAN, !WithinULP(NAN, 123));
|
||||
}
|
||||
SECTION("Composed") {
|
||||
REQUIRE_THAT(1., WithinAbs(1., 0.5) || WithinULP(2., 1));
|
||||
REQUIRE_THAT(1., WithinAbs(2., 0.5) || WithinULP(1., 0));
|
||||
|
||||
REQUIRE_THAT(NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123)));
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CATCH_CONFIG_DISABLE_MATCHERS
|
||||
|
||||
#ifdef __clang__
|
||||
|
@ -52,6 +52,12 @@ infParser = re.compile(r'''
|
||||
|
|
||||
__builtin_huge_valf\(\) # OSX macro
|
||||
''', re.VERBOSE)
|
||||
nanParser = re.compile(r'''
|
||||
\(\(float\)\(\(\(float\)\(1e\+300\ \*\ 1e\+300\)\)\ \*\ 0\.0F\)\) # MSVC NAN macro
|
||||
|
|
||||
\(__builtin_nanf\ \(""\)\) # Linux (ubuntu) NAN macro
|
||||
''', re.VERBOSE)
|
||||
|
||||
|
||||
if len(sys.argv) == 2:
|
||||
cmdPath = sys.argv[1]
|
||||
@ -110,6 +116,7 @@ def filterLine(line):
|
||||
line = errnoParser.sub('errno', line)
|
||||
line = sinceEpochParser.sub('{since-epoch-report}', line)
|
||||
line = infParser.sub('INFINITY', line)
|
||||
line = nanParser.sub('NAN', line)
|
||||
return line
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user