mirror of https://github.com/catchorg/Catch2.git
Reorganised (some) usage tests so they can be included multiple times
This commit is contained in:
parent
516dbc83bc
commit
61e838edf2
|
@ -10,13 +10,32 @@
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace { namespace ApproxTests {
|
||||||
|
|
||||||
|
#ifndef APPROX_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
|
||||||
|
#define APPROX_TEST_HELPERS_INCLUDED
|
||||||
|
|
||||||
|
inline double divide( double a, double b ) {
|
||||||
|
return a/b;
|
||||||
|
}
|
||||||
|
|
||||||
|
class StrongDoubleTypedef {
|
||||||
|
double d_ = 0.0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit StrongDoubleTypedef(double d) : d_(d) {}
|
||||||
|
explicit operator double() const { return d_; }
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::ostream& operator<<( std::ostream& os, StrongDoubleTypedef td ) {
|
||||||
|
return os << "StrongDoubleTypedef(" << static_cast<double>(td) << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
TEST_CASE
|
TEST_CASE( "Some simple comparisons between doubles", "[Approx]" ) {
|
||||||
(
|
|
||||||
"Some simple comparisons between doubles",
|
|
||||||
"[Approx]"
|
|
||||||
)
|
|
||||||
{
|
|
||||||
double d = 1.23;
|
double d = 1.23;
|
||||||
|
|
||||||
REQUIRE( d == Approx( 1.23 ) );
|
REQUIRE( d == Approx( 1.23 ) );
|
||||||
|
@ -31,12 +50,7 @@ TEST_CASE
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
TEST_CASE
|
TEST_CASE( "Approximate comparisons with different epsilons", "[Approx]" ) {
|
||||||
(
|
|
||||||
"Approximate comparisons with different epsilons",
|
|
||||||
"[Approx]"
|
|
||||||
)
|
|
||||||
{
|
|
||||||
double d = 1.23;
|
double d = 1.23;
|
||||||
|
|
||||||
REQUIRE( d != Approx( 1.231 ) );
|
REQUIRE( d != Approx( 1.231 ) );
|
||||||
|
@ -44,12 +58,7 @@ TEST_CASE
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
TEST_CASE
|
TEST_CASE( "Less-than inequalities with different epsilons", "[Approx]" ) {
|
||||||
(
|
|
||||||
"Less-than inequalities with different epsilons",
|
|
||||||
"[Approx]"
|
|
||||||
)
|
|
||||||
{
|
|
||||||
double d = 1.23;
|
double d = 1.23;
|
||||||
|
|
||||||
REQUIRE( d <= Approx( 1.24 ) );
|
REQUIRE( d <= Approx( 1.24 ) );
|
||||||
|
@ -59,12 +68,7 @@ TEST_CASE
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
TEST_CASE
|
TEST_CASE( "Greater-than inequalities with different epsilons", "[Approx]" ) {
|
||||||
(
|
|
||||||
"Greater-than inequalities with different epsilons",
|
|
||||||
"[Approx]"
|
|
||||||
)
|
|
||||||
{
|
|
||||||
double d = 1.23;
|
double d = 1.23;
|
||||||
|
|
||||||
REQUIRE( d >= Approx( 1.22 ) );
|
REQUIRE( d >= Approx( 1.22 ) );
|
||||||
|
@ -74,34 +78,19 @@ TEST_CASE
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
TEST_CASE
|
TEST_CASE( "Approximate comparisons with floats", "[Approx]" ) {
|
||||||
(
|
|
||||||
"Approximate comparisons with floats",
|
|
||||||
"[Approx]"
|
|
||||||
)
|
|
||||||
{
|
|
||||||
REQUIRE( 1.23f == Approx( 1.23f ) );
|
REQUIRE( 1.23f == Approx( 1.23f ) );
|
||||||
REQUIRE( 0.0f == Approx( 0.0f ) );
|
REQUIRE( 0.0f == Approx( 0.0f ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
TEST_CASE
|
TEST_CASE( "Approximate comparisons with ints", "[Approx]" ) {
|
||||||
(
|
|
||||||
"Approximate comparisons with ints",
|
|
||||||
"[Approx]"
|
|
||||||
)
|
|
||||||
{
|
|
||||||
REQUIRE( 1 == Approx( 1 ) );
|
REQUIRE( 1 == Approx( 1 ) );
|
||||||
REQUIRE( 0 == Approx( 0 ) );
|
REQUIRE( 0 == Approx( 0 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
TEST_CASE
|
TEST_CASE( "Approximate comparisons with mixed numeric types", "[Approx]" ) {
|
||||||
(
|
|
||||||
"Approximate comparisons with mixed numeric types",
|
|
||||||
"[Approx]"
|
|
||||||
)
|
|
||||||
{
|
|
||||||
const double dZero = 0;
|
const double dZero = 0;
|
||||||
const double dSmall = 0.00001;
|
const double dSmall = 0.00001;
|
||||||
const double dMedium = 1.234;
|
const double dMedium = 1.234;
|
||||||
|
@ -114,12 +103,7 @@ TEST_CASE
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
TEST_CASE
|
TEST_CASE( "Use a custom approx", "[Approx][custom]" ) {
|
||||||
(
|
|
||||||
"Use a custom approx",
|
|
||||||
"[Approx][custom]"
|
|
||||||
)
|
|
||||||
{
|
|
||||||
double d = 1.23;
|
double d = 1.23;
|
||||||
|
|
||||||
Approx approx = Approx::custom().epsilon( 0.01 );
|
Approx approx = Approx::custom().epsilon( 0.01 );
|
||||||
|
@ -135,12 +119,7 @@ TEST_CASE
|
||||||
REQUIRE( approx( d ) != 1.25 );
|
REQUIRE( approx( d ) != 1.25 );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline double divide( double a, double b ) {
|
TEST_CASE( "Approximate PI", "[Approx][PI]" ) {
|
||||||
return a/b;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE( "Approximate PI", "[Approx][PI]" )
|
|
||||||
{
|
|
||||||
REQUIRE( divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 ) );
|
REQUIRE( divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 ) );
|
||||||
REQUIRE( divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 ) );
|
REQUIRE( divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 ) );
|
||||||
}
|
}
|
||||||
|
@ -194,19 +173,6 @@ TEST_CASE("Assorted miscellaneous tests", "[Approx]") {
|
||||||
REQUIRE_FALSE(NAN == Approx(NAN));
|
REQUIRE_FALSE(NAN == Approx(NAN));
|
||||||
}
|
}
|
||||||
|
|
||||||
class StrongDoubleTypedef
|
|
||||||
{
|
|
||||||
double d_ = 0.0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit StrongDoubleTypedef(double d) : d_(d) {}
|
|
||||||
explicit operator double() const { return d_; }
|
|
||||||
};
|
|
||||||
|
|
||||||
inline std::ostream& operator<<( std::ostream& os, StrongDoubleTypedef td ) {
|
|
||||||
return os << "StrongDoubleTypedef(" << static_cast<double>(td) << ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE( "Comparison with explicitly convertible types", "[Approx]" )
|
TEST_CASE( "Comparison with explicitly convertible types", "[Approx]" )
|
||||||
{
|
{
|
||||||
StrongDoubleTypedef td(10.0);
|
StrongDoubleTypedef td(10.0);
|
||||||
|
@ -228,3 +194,5 @@ TEST_CASE( "Comparison with explicitly convertible types", "[Approx]" )
|
||||||
REQUIRE(Approx(11.0) >= td);
|
REQUIRE(Approx(11.0) >= td);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}} // namespace ApproxTests
|
||||||
|
|
|
@ -8,96 +8,100 @@
|
||||||
|
|
||||||
#include "catch.hpp"
|
#include "catch.hpp"
|
||||||
|
|
||||||
inline bool itDoesThis(){ return true; }
|
namespace { namespace BDDTests {
|
||||||
inline bool itDoesThat(){ return true; }
|
|
||||||
|
|
||||||
SCENARIO( "Do that thing with the thing", "[Tags]" ) {
|
#ifndef BDD_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
|
||||||
GIVEN( "This stuff exists" ) {
|
#define BDD_TEST_HELPERS_INCLUDED
|
||||||
// make stuff exist
|
|
||||||
WHEN( "I do this" ) {
|
inline bool itDoesThis() { return true; }
|
||||||
// do this
|
|
||||||
THEN( "it should do this")
|
inline bool itDoesThat() { return true; }
|
||||||
{
|
|
||||||
REQUIRE( itDoesThis() );
|
namespace {
|
||||||
AND_THEN( "do that")
|
|
||||||
REQUIRE( itDoesThat() );
|
// a trivial fixture example to support SCENARIO_METHOD tests
|
||||||
|
struct Fixture {
|
||||||
|
Fixture()
|
||||||
|
: d_counter(0) {
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
int counter() {
|
||||||
|
return d_counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int d_counter;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
#endif
|
||||||
|
|
||||||
SCENARIO( "Vector resizing affects size and capacity", "[vector][bdd][size][capacity]" ) {
|
SCENARIO("Do that thing with the thing", "[Tags]") {
|
||||||
GIVEN( "an empty vector" ) {
|
GIVEN("This stuff exists") {
|
||||||
std::vector<int> v;
|
// make stuff exist
|
||||||
REQUIRE( v.size() == 0 );
|
WHEN("I do this") {
|
||||||
|
// do this
|
||||||
WHEN( "it is made larger" ) {
|
THEN("it should do this") {
|
||||||
v.resize( 10 );
|
REQUIRE(itDoesThis());
|
||||||
THEN( "the size and capacity go up" ) {
|
AND_THEN("do that")REQUIRE(itDoesThat());
|
||||||
REQUIRE( v.size() == 10 );
|
|
||||||
REQUIRE( v.capacity() >= 10 );
|
|
||||||
|
|
||||||
AND_WHEN( "it is made smaller again" ) {
|
|
||||||
v.resize( 5 );
|
|
||||||
THEN( "the size goes down but the capacity stays the same" ) {
|
|
||||||
REQUIRE( v.size() == 5 );
|
|
||||||
REQUIRE( v.capacity() >= 10 );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
WHEN( "we reserve more space" ) {
|
SCENARIO("Vector resizing affects size and capacity", "[vector][bdd][size][capacity]") {
|
||||||
v.reserve( 10 );
|
GIVEN("an empty vector") {
|
||||||
THEN( "The capacity is increased but the size remains the same" ) {
|
std::vector<int> v;
|
||||||
REQUIRE( v.capacity() >= 10 );
|
REQUIRE(v.size() == 0);
|
||||||
REQUIRE( v.size() == 0 );
|
|
||||||
|
WHEN("it is made larger") {
|
||||||
|
v.resize(10);
|
||||||
|
THEN("the size and capacity go up") {
|
||||||
|
REQUIRE(v.size() == 10);
|
||||||
|
REQUIRE(v.capacity() >= 10);
|
||||||
|
|
||||||
|
AND_WHEN("it is made smaller again") {
|
||||||
|
v.resize(5);
|
||||||
|
THEN("the size goes down but the capacity stays the same") {
|
||||||
|
REQUIRE(v.size() == 5);
|
||||||
|
REQUIRE(v.capacity() >= 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WHEN("we reserve more space") {
|
||||||
|
v.reserve(10);
|
||||||
|
THEN("The capacity is increased but the size remains the same") {
|
||||||
|
REQUIRE(v.capacity() >= 10);
|
||||||
|
REQUIRE(v.size() == 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
SCENARIO( "This is a really long scenario name to see how the list command deals with wrapping",
|
SCENARIO("This is a really long scenario name to see how the list command deals with wrapping",
|
||||||
"[very long tags][lots][long][tags][verbose]"
|
"[very long tags][lots][long][tags][verbose]"
|
||||||
"[one very long tag name that should cause line wrapping writing out using the list command]"
|
"[one very long tag name that should cause line wrapping writing out using the list command]"
|
||||||
"[anotherReallyLongTagNameButThisOneHasNoObviousWrapPointsSoShouldSplitWithinAWordUsingADashCharacter]" ) {
|
"[anotherReallyLongTagNameButThisOneHasNoObviousWrapPointsSoShouldSplitWithinAWordUsingADashCharacter]") {
|
||||||
GIVEN( "A section name that is so long that it cannot fit in a single console width" )
|
GIVEN("A section name that is so long that it cannot fit in a single console width")WHEN(
|
||||||
WHEN( "The test headers are printed as part of the normal running of the scenario" )
|
"The test headers are printed as part of the normal running of the scenario")THEN(
|
||||||
THEN( "The, deliberately very long and overly verbose (you see what I did there?) section names must wrap, along with an indent" )
|
"The, deliberately very long and overly verbose (you see what I did there?) section names must wrap, along with an indent")SUCCEED(
|
||||||
SUCCEED("boo!");
|
"boo!");
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
// a trivial fixture example to support SCENARIO_METHOD tests
|
|
||||||
struct Fixture
|
|
||||||
{
|
|
||||||
Fixture()
|
|
||||||
: d_counter(0)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int counter()
|
SCENARIO_METHOD(Fixture,
|
||||||
{
|
"BDD tests requiring Fixtures to provide commonly-accessed data or methods",
|
||||||
return d_counter++;
|
"[bdd][fixtures]") {
|
||||||
}
|
const int before(counter());
|
||||||
|
GIVEN("No operations precede me") {
|
||||||
int d_counter;
|
REQUIRE(before == 0);
|
||||||
};
|
WHEN("We get the count") {
|
||||||
|
const int after(counter());
|
||||||
}
|
THEN("Subsequently values are higher") {
|
||||||
|
REQUIRE(after > before);
|
||||||
SCENARIO_METHOD(Fixture,
|
}
|
||||||
"BDD tests requiring Fixtures to provide commonly-accessed data or methods",
|
|
||||||
"[bdd][fixtures]") {
|
|
||||||
const int before(counter());
|
|
||||||
GIVEN("No operations precede me") {
|
|
||||||
REQUIRE(before == 0);
|
|
||||||
WHEN("We get the count") {
|
|
||||||
const int after(counter());
|
|
||||||
THEN("Subsequently values are higher") {
|
|
||||||
REQUIRE(after > before);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}} // namespace BDDtests
|
||||||
|
|
|
@ -8,32 +8,29 @@
|
||||||
|
|
||||||
#include "catch.hpp"
|
#include "catch.hpp"
|
||||||
|
|
||||||
namespace
|
namespace{ namespace ClassTests {
|
||||||
|
|
||||||
|
#ifndef CLASS_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
|
||||||
|
#define CLASS_TEST_HELPERS_INCLUDED
|
||||||
|
|
||||||
|
class TestClass
|
||||||
{
|
{
|
||||||
class TestClass
|
std::string s;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TestClass()
|
||||||
|
: s( "hello" )
|
||||||
|
{}
|
||||||
|
|
||||||
|
void succeedingCase()
|
||||||
{
|
{
|
||||||
std::string s;
|
REQUIRE( s == "hello" );
|
||||||
|
}
|
||||||
public:
|
void failingCase()
|
||||||
TestClass()
|
{
|
||||||
: s( "hello" )
|
REQUIRE( s == "world" );
|
||||||
{}
|
}
|
||||||
|
};
|
||||||
void succeedingCase()
|
|
||||||
{
|
|
||||||
REQUIRE( s == "hello" );
|
|
||||||
}
|
|
||||||
void failingCase()
|
|
||||||
{
|
|
||||||
REQUIRE( s == "world" );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
METHOD_AS_TEST_CASE( TestClass::succeedingCase, "A METHOD_AS_TEST_CASE based test run that succeeds", "[class]" )
|
|
||||||
METHOD_AS_TEST_CASE( TestClass::failingCase, "A METHOD_AS_TEST_CASE based test run that fails", "[.][class][failing]" )
|
|
||||||
|
|
||||||
|
|
||||||
struct Fixture
|
struct Fixture
|
||||||
{
|
{
|
||||||
|
@ -42,6 +39,13 @@ struct Fixture
|
||||||
int m_a;
|
int m_a;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
METHOD_AS_TEST_CASE( TestClass::succeedingCase, "A METHOD_AS_TEST_CASE based test run that succeeds", "[class]" )
|
||||||
|
METHOD_AS_TEST_CASE( TestClass::failingCase, "A METHOD_AS_TEST_CASE based test run that fails", "[.][class][failing]" )
|
||||||
|
|
||||||
TEST_CASE_METHOD( Fixture, "A TEST_CASE_METHOD based test run that succeeds", "[class]" )
|
TEST_CASE_METHOD( Fixture, "A TEST_CASE_METHOD based test run that succeeds", "[class]" )
|
||||||
{
|
{
|
||||||
REQUIRE( m_a == 1 );
|
REQUIRE( m_a == 1 );
|
||||||
|
@ -55,3 +59,5 @@ namespace Inner
|
||||||
REQUIRE( m_a == 2 );
|
REQUIRE( m_a == 2 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}} // namespace ClassTests
|
||||||
|
|
|
@ -7,51 +7,53 @@
|
||||||
|
|
||||||
#include "catch.hpp"
|
#include "catch.hpp"
|
||||||
|
|
||||||
|
namespace { namespace CompilationTests {
|
||||||
|
|
||||||
|
#ifndef COMPILATION_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
|
||||||
|
#define COMPILATION_TEST_HELPERS_INCLUDED
|
||||||
|
|
||||||
// This is a minimal example for an issue we have found in 1.7.0
|
// This is a minimal example for an issue we have found in 1.7.0
|
||||||
struct foo {
|
struct foo {
|
||||||
int i;
|
int i;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
bool operator==(const T& val, foo f){
|
bool operator==(const T &val, foo f) {
|
||||||
return val == f.i;
|
return val == f.i;
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("#809") {
|
|
||||||
foo f; f.i = 42;
|
|
||||||
REQUIRE(42 == f);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
|
||||||
// Changes to REQUIRE_THROWS_AS made it stop working in a template in
|
|
||||||
// an unfixable way (as long as C++03 compatibility is being kept).
|
|
||||||
// To prevent these from happening in the future, this needs to compile
|
|
||||||
|
|
||||||
void throws_int(bool b) {
|
|
||||||
if (b) {
|
|
||||||
throw 1;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
struct Y {
|
||||||
bool templated_tests(T t) {
|
uint32_t v : 1;
|
||||||
int a = 3;
|
};
|
||||||
REQUIRE(a == t);
|
|
||||||
CHECK(a == t);
|
void throws_int(bool b) {
|
||||||
REQUIRE_THROWS(throws_int(true));
|
if (b) {
|
||||||
CHECK_THROWS_AS(throws_int(true), int);
|
throw 1;
|
||||||
REQUIRE_NOTHROW(throws_int(false));
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool templated_tests(T t) {
|
||||||
|
int a = 3;
|
||||||
|
REQUIRE(a == t);
|
||||||
|
CHECK(a == t);
|
||||||
|
REQUIRE_THROWS(throws_int(true));
|
||||||
|
CHECK_THROWS_AS(throws_int(true), int);
|
||||||
|
REQUIRE_NOTHROW(throws_int(false));
|
||||||
#ifndef CATCH_CONFIG_DISABLE_MATCHERS
|
#ifndef CATCH_CONFIG_DISABLE_MATCHERS
|
||||||
REQUIRE_THAT("aaa", Catch::EndsWith("aaa"));
|
REQUIRE_THAT("aaa", Catch::EndsWith("aaa"));
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("#833") {
|
struct A {
|
||||||
REQUIRE(templated_tests<int>(3));
|
};
|
||||||
}
|
|
||||||
|
std::ostream &operator<<(std::ostream &o, const A &) { return o << 0; }
|
||||||
|
|
||||||
|
struct B : private A {
|
||||||
|
bool operator==(int) const { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
|
@ -63,35 +65,48 @@ TEST_CASE("#833") {
|
||||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Test containing example where original stream insertable check breaks compilation
|
B f();
|
||||||
namespace {
|
|
||||||
struct A {};
|
|
||||||
std::ostream& operator<< (std::ostream &o, const A &) { return o << 0; }
|
|
||||||
|
|
||||||
struct B : private A {
|
std::ostream g();
|
||||||
bool operator== (int) const { return true; }
|
|
||||||
};
|
|
||||||
|
|
||||||
B f ();
|
|
||||||
std::ostream g ();
|
|
||||||
}
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TEST_CASE( "#872" ) {
|
#endif
|
||||||
A dummy;
|
|
||||||
CAPTURE( dummy );
|
|
||||||
B x;
|
|
||||||
REQUIRE (x == 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Y {
|
TEST_CASE("#809") {
|
||||||
uint32_t v : 1;
|
foo f;
|
||||||
};
|
f.i = 42;
|
||||||
|
REQUIRE(42 == f);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE( "#1027" ) {
|
|
||||||
Y y{ 0 };
|
// ------------------------------------------------------------------
|
||||||
REQUIRE(y.v == 0);
|
// Changes to REQUIRE_THROWS_AS made it stop working in a template in
|
||||||
REQUIRE(0 == y.v);
|
// an unfixable way (as long as C++03 compatibility is being kept).
|
||||||
}
|
// To prevent these from happening in the future, this needs to compile
|
||||||
|
|
||||||
|
TEST_CASE("#833") {
|
||||||
|
REQUIRE(templated_tests<int>(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Test containing example where original stream insertable check breaks compilation
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("#872") {
|
||||||
|
A dummy;
|
||||||
|
CAPTURE(dummy);
|
||||||
|
B x;
|
||||||
|
REQUIRE (x == 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("#1027") {
|
||||||
|
Y y{0};
|
||||||
|
REQUIRE(y.v == 0);
|
||||||
|
REQUIRE(0 == y.v);
|
||||||
|
}
|
||||||
|
|
||||||
|
}} // namespace CompilationTests
|
||||||
|
|
|
@ -17,6 +17,11 @@
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace { namespace ConditionTests {
|
||||||
|
|
||||||
|
#ifndef CONDITION_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
|
||||||
|
#define CONDITION_TEST_HELPERS_INCLUDED
|
||||||
|
|
||||||
struct TestData {
|
struct TestData {
|
||||||
int int_seven = 7;
|
int int_seven = 7;
|
||||||
std::string str_hello = "hello";
|
std::string str_hello = "hello";
|
||||||
|
@ -24,7 +29,6 @@ struct TestData {
|
||||||
double double_pi = 3.1415926535;
|
double double_pi = 3.1415926535;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct TestDef {
|
struct TestDef {
|
||||||
TestDef& operator + ( const std::string& ) {
|
TestDef& operator + ( const std::string& ) {
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -34,13 +38,17 @@ struct TestDef {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline const char* returnsConstNull(){ return nullptr; }
|
||||||
|
inline char* returnsNull(){ return nullptr; }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// The "failing" tests all use the CHECK macro, which continues if the specific test fails.
|
// The "failing" tests all use the CHECK macro, which continues if the specific test fails.
|
||||||
// This allows us to see all results, even if an earlier check fails
|
// This allows us to see all results, even if an earlier check fails
|
||||||
|
|
||||||
// Equality tests
|
// Equality tests
|
||||||
TEST_CASE( "Equality checks that should succeed" )
|
TEST_CASE( "Equality checks that should succeed" )
|
||||||
{
|
{
|
||||||
|
|
||||||
TestDef td;
|
TestDef td;
|
||||||
td + "hello" + "hello";
|
td + "hello" + "hello";
|
||||||
|
|
||||||
|
@ -256,9 +264,6 @@ TEST_CASE( "Comparisons between ints where one side is computed" )
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline const char* returnsConstNull(){ return nullptr; }
|
|
||||||
inline char* returnsNull(){ return nullptr; }
|
|
||||||
|
|
||||||
TEST_CASE( "Pointers can be compared to null" )
|
TEST_CASE( "Pointers can be compared to null" )
|
||||||
{
|
{
|
||||||
TestData* p = nullptr;
|
TestData* p = nullptr;
|
||||||
|
@ -323,3 +328,4 @@ TEST_CASE( "'Not' checks that should fail", "[.][failing]" )
|
||||||
CHECK_FALSE( 1 == 1 );
|
CHECK_FALSE( 1 == 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}} // namespace ConditionTests
|
||||||
|
|
|
@ -19,70 +19,97 @@
|
||||||
#pragma clang diagnostic ignored "-Wweak-vtables"
|
#pragma clang diagnostic ignored "-Wweak-vtables"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace
|
namespace { namespace ExceptionTests {
|
||||||
{
|
|
||||||
inline int thisThrows()
|
|
||||||
{
|
|
||||||
if( Catch::alwaysTrue() )
|
|
||||||
throw std::domain_error( "expected exception" );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int thisDoesntThrow()
|
#ifndef EXCEPTION_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
|
||||||
{
|
#define EXCEPTION_TEST_HELPERS_INCLUDED
|
||||||
return 0;
|
|
||||||
}
|
inline int thisThrows() {
|
||||||
|
if( Catch::alwaysTrue() )
|
||||||
|
throw std::domain_error( "expected exception" );
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "When checked exceptions are thrown they can be expected or unexpected", "[!throws]" )
|
int thisDoesntThrow() {
|
||||||
{
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CustomException {
|
||||||
|
public:
|
||||||
|
CustomException( const std::string& msg )
|
||||||
|
: m_msg( msg )
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::string getMessage() const {
|
||||||
|
return m_msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CustomStdException : public std::exception {
|
||||||
|
public:
|
||||||
|
CustomStdException( const std::string& msg )
|
||||||
|
: m_msg( msg )
|
||||||
|
{}
|
||||||
|
~CustomStdException() noexcept {}
|
||||||
|
|
||||||
|
std::string getMessage() const {
|
||||||
|
return m_msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void throwCustom() {
|
||||||
|
if( Catch::alwaysTrue() )
|
||||||
|
throw CustomException( "custom exception - not std" );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TEST_CASE( "When checked exceptions are thrown they can be expected or unexpected", "[!throws]" ) {
|
||||||
REQUIRE_THROWS_AS( thisThrows(), std::domain_error );
|
REQUIRE_THROWS_AS( thisThrows(), std::domain_error );
|
||||||
REQUIRE_NOTHROW( thisDoesntThrow() );
|
REQUIRE_NOTHROW( thisDoesntThrow() );
|
||||||
REQUIRE_THROWS( thisThrows() );
|
REQUIRE_THROWS( thisThrows() );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Expected exceptions that don't throw or unexpected exceptions fail the test", "[.][failing][!throws]" )
|
TEST_CASE( "Expected exceptions that don't throw or unexpected exceptions fail the test", "[.][failing][!throws]" ) {
|
||||||
{
|
|
||||||
CHECK_THROWS_AS( thisThrows(), std::string );
|
CHECK_THROWS_AS( thisThrows(), std::string );
|
||||||
CHECK_THROWS_AS( thisDoesntThrow(), std::domain_error );
|
CHECK_THROWS_AS( thisDoesntThrow(), std::domain_error );
|
||||||
CHECK_NOTHROW( thisThrows() );
|
CHECK_NOTHROW( thisThrows() );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "When unchecked exceptions are thrown directly they are always failures", "[.][failing][!throws]" )
|
TEST_CASE( "When unchecked exceptions are thrown directly they are always failures", "[.][failing][!throws]" ) {
|
||||||
{
|
|
||||||
if( Catch::alwaysTrue() )
|
if( Catch::alwaysTrue() )
|
||||||
throw std::domain_error( "unexpected exception" );
|
throw std::domain_error( "unexpected exception" );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "An unchecked exception reports the line of the last assertion", "[.][failing][!throws]" )
|
TEST_CASE( "An unchecked exception reports the line of the last assertion", "[.][failing][!throws]" ) {
|
||||||
{
|
|
||||||
CHECK( 1 == 1 );
|
CHECK( 1 == 1 );
|
||||||
if( Catch::alwaysTrue() )
|
if( Catch::alwaysTrue() )
|
||||||
throw std::domain_error( "unexpected exception" );
|
throw std::domain_error( "unexpected exception" );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "When unchecked exceptions are thrown from sections they are always failures", "[.][failing][!throws]" )
|
TEST_CASE( "When unchecked exceptions are thrown from sections they are always failures", "[.][failing][!throws]" ) {
|
||||||
{
|
SECTION( "section name" ) {
|
||||||
SECTION( "section name" )
|
|
||||||
{
|
|
||||||
if( Catch::alwaysTrue() )
|
if( Catch::alwaysTrue() )
|
||||||
throw std::domain_error( "unexpected exception" );
|
throw std::domain_error( "unexpected exception" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "When unchecked exceptions are thrown from functions they are always failures", "[.][failing][!throws]" )
|
TEST_CASE( "When unchecked exceptions are thrown from functions they are always failures", "[.][failing][!throws]" ) {
|
||||||
{
|
|
||||||
CHECK( thisThrows() == 0 );
|
CHECK( thisThrows() == 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "When unchecked exceptions are thrown during a REQUIRE the test should abort fail", "[.][failing][!throws]" )
|
TEST_CASE( "When unchecked exceptions are thrown during a REQUIRE the test should abort fail", "[.][failing][!throws]" ) {
|
||||||
{
|
|
||||||
REQUIRE( thisThrows() == 0 );
|
REQUIRE( thisThrows() == 0 );
|
||||||
FAIL( "This should never happen" );
|
FAIL( "This should never happen" );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "When unchecked exceptions are thrown during a CHECK the test should continue", "[.][failing][!throws]" )
|
TEST_CASE( "When unchecked exceptions are thrown during a CHECK the test should continue", "[.][failing][!throws]" ) {
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
CHECK(thisThrows() == 0);
|
CHECK(thisThrows() == 0);
|
||||||
}
|
}
|
||||||
|
@ -91,96 +118,45 @@ TEST_CASE( "When unchecked exceptions are thrown during a CHECK the test should
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "When unchecked exceptions are thrown, but caught, they do not affect the test", "[!throws]" )
|
TEST_CASE( "When unchecked exceptions are thrown, but caught, they do not affect the test", "[!throws]" ) {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
throw std::domain_error( "unexpected exception" );
|
throw std::domain_error( "unexpected exception" );
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...) {}
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class CustomException
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CustomException( const std::string& msg )
|
|
||||||
: m_msg( msg )
|
|
||||||
{}
|
|
||||||
|
|
||||||
std::string getMessage() const
|
CATCH_TRANSLATE_EXCEPTION( CustomException& ex ) {
|
||||||
{
|
|
||||||
return m_msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string m_msg;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CustomStdException : public std::exception
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CustomStdException( const std::string& msg )
|
|
||||||
: m_msg( msg )
|
|
||||||
{}
|
|
||||||
~CustomStdException() noexcept {}
|
|
||||||
|
|
||||||
std::string getMessage() const
|
|
||||||
{
|
|
||||||
return m_msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string m_msg;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
CATCH_TRANSLATE_EXCEPTION( CustomException& ex )
|
|
||||||
{
|
|
||||||
return ex.getMessage();
|
return ex.getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_TRANSLATE_EXCEPTION( CustomStdException& ex )
|
CATCH_TRANSLATE_EXCEPTION( CustomStdException& ex ) {
|
||||||
{
|
|
||||||
return ex.getMessage();
|
return ex.getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_TRANSLATE_EXCEPTION( double& ex )
|
CATCH_TRANSLATE_EXCEPTION( double& ex ) {
|
||||||
{
|
|
||||||
return Catch::Detail::stringify( ex );
|
return Catch::Detail::stringify( ex );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Non-std exceptions can be translated", "[.][failing][!throws]" )
|
TEST_CASE("Non-std exceptions can be translated", "[.][failing][!throws]" ) {
|
||||||
{
|
|
||||||
if( Catch::alwaysTrue() )
|
if( Catch::alwaysTrue() )
|
||||||
throw CustomException( "custom exception" );
|
throw CustomException( "custom exception" );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Custom std-exceptions can be custom translated", "[.][failing][!throws]" )
|
TEST_CASE("Custom std-exceptions can be custom translated", "[.][failing][!throws]" ) {
|
||||||
{
|
|
||||||
if( Catch::alwaysTrue() )
|
if( Catch::alwaysTrue() )
|
||||||
throw CustomException( "custom std exception" );
|
throw CustomException( "custom std exception" );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void throwCustom() {
|
TEST_CASE( "Custom exceptions can be translated when testing for nothrow", "[.][failing][!throws]" ) {
|
||||||
if( Catch::alwaysTrue() )
|
|
||||||
throw CustomException( "custom exception - not std" );
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE( "Custom exceptions can be translated when testing for nothrow", "[.][failing][!throws]" )
|
|
||||||
{
|
|
||||||
REQUIRE_NOTHROW( throwCustom() );
|
REQUIRE_NOTHROW( throwCustom() );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Custom exceptions can be translated when testing for throwing as something else", "[.][failing][!throws]" )
|
TEST_CASE( "Custom exceptions can be translated when testing for throwing as something else", "[.][failing][!throws]" ) {
|
||||||
{
|
|
||||||
REQUIRE_THROWS_AS( throwCustom(), std::exception );
|
REQUIRE_THROWS_AS( throwCustom(), std::exception );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE( "Unexpected exceptions can be translated", "[.][failing][!throws]" ) {
|
||||||
TEST_CASE( "Unexpected exceptions can be translated", "[.][failing][!throws]" )
|
|
||||||
{
|
|
||||||
if( Catch::alwaysTrue() )
|
if( Catch::alwaysTrue() )
|
||||||
throw double( 3.14 );
|
throw double( 3.14 );
|
||||||
}
|
}
|
||||||
|
@ -224,6 +200,8 @@ TEST_CASE( "#748 - captures with unexpected exceptions", "[.][failing][!throws][
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}} // namespace ExceptionTests
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,193 +16,21 @@
|
||||||
#pragma clang diagnostic ignored "-Wpadded"
|
#pragma clang diagnostic ignored "-Wpadded"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace { namespace MatchersTests {
|
||||||
|
|
||||||
#ifndef CATCH_CONFIG_DISABLE_MATCHERS
|
#ifndef CATCH_CONFIG_DISABLE_MATCHERS
|
||||||
|
|
||||||
inline const char* testStringForMatching()
|
#ifndef MATCHERS_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
|
||||||
{
|
#define MATCHERS_TEST_HELPERS_INCLUDED
|
||||||
return "this string contains 'abc' as a substring";
|
|
||||||
}
|
|
||||||
inline const char* testStringForMatching2()
|
|
||||||
{
|
|
||||||
return "some completely different text that contains one common word";
|
|
||||||
}
|
|
||||||
|
|
||||||
using namespace Catch::Matchers;
|
inline const char *testStringForMatching() {
|
||||||
|
return "this string contains 'abc' as a substring";
|
||||||
TEST_CASE("String matchers", "[matchers]" ) {
|
|
||||||
REQUIRE_THAT( testStringForMatching(), Contains( "string" ) );
|
|
||||||
REQUIRE_THAT( testStringForMatching(), Contains( "string", Catch::CaseSensitive::No ));
|
|
||||||
CHECK_THAT( testStringForMatching(), Contains( "abc" ) );
|
|
||||||
CHECK_THAT( testStringForMatching(), Contains( "aBC", Catch::CaseSensitive::No ));
|
|
||||||
|
|
||||||
CHECK_THAT( testStringForMatching(), StartsWith( "this" ) );
|
|
||||||
CHECK_THAT( testStringForMatching(), StartsWith( "THIS", Catch::CaseSensitive::No ));
|
|
||||||
CHECK_THAT( testStringForMatching(), EndsWith( "substring" ) );
|
|
||||||
CHECK_THAT( testStringForMatching(), EndsWith(" SuBsTrInG", Catch::CaseSensitive::No ));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Contains string matcher", "[.][failing][matchers]") {
|
|
||||||
CHECK_THAT( testStringForMatching(), Contains( "not there", Catch::CaseSensitive::No ) );
|
|
||||||
CHECK_THAT( testStringForMatching(), Contains( "STRING" ));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("StartsWith string matcher", "[.][failing][matchers]") {
|
|
||||||
CHECK_THAT( testStringForMatching(), StartsWith( "This String" ));
|
|
||||||
CHECK_THAT( testStringForMatching(), StartsWith( "string", Catch::CaseSensitive::No ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("EndsWith string matcher", "[.][failing][matchers]") {
|
|
||||||
CHECK_THAT( testStringForMatching(), EndsWith( "Substring" ));
|
|
||||||
CHECK_THAT( testStringForMatching(), EndsWith( "this", Catch::CaseSensitive::No ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Equals string matcher", "[.][failing][matchers]") {
|
|
||||||
CHECK_THAT( testStringForMatching(), Equals( "this string contains 'ABC' as a substring" ) );
|
|
||||||
CHECK_THAT( testStringForMatching(), Equals( "something else", Catch::CaseSensitive::No ));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Equals", "[matchers]") {
|
|
||||||
CHECK_THAT( testStringForMatching(), Equals( "this string contains 'abc' as a substring" ));
|
|
||||||
CHECK_THAT( testStringForMatching(), Equals( "this string contains 'ABC' as a substring", Catch::CaseSensitive::No ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// <regex> does not work in libstdc++ 4.8, so we have to enable these tests only when they
|
|
||||||
// are expected to pass and cannot have them in baselines
|
|
||||||
TEST_CASE("Regex string matcher -- libstdc++-4.8 workaround", "[matchers][approvals]") {
|
|
||||||
|
|
||||||
// This is fiiiine
|
|
||||||
// Taken from an answer at
|
|
||||||
// https://stackoverflow.com/questions/12530406/is-gcc-4-8-or-earlier-buggy-about-regular-expressions
|
|
||||||
#if (!defined(__GNUC__)) || \
|
|
||||||
(__cplusplus >= 201103L && \
|
|
||||||
(!defined(__GLIBCXX__) || (__cplusplus >= 201402L) || \
|
|
||||||
(defined(_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT) || \
|
|
||||||
defined(_GLIBCXX_REGEX_STATE_LIMIT) || \
|
|
||||||
(defined(_GLIBCXX_RELEASE) && \
|
|
||||||
_GLIBCXX_RELEASE > 4))))
|
|
||||||
|
|
||||||
REQUIRE_THAT(testStringForMatching(), Matches("this string contains 'abc' as a substring"));
|
|
||||||
REQUIRE_THAT(testStringForMatching(), Matches("this string CONTAINS 'abc' as a substring", Catch::CaseSensitive::No));
|
|
||||||
REQUIRE_THAT(testStringForMatching(), Matches("^this string contains 'abc' as a substring$"));
|
|
||||||
REQUIRE_THAT(testStringForMatching(), Matches("^.* 'abc' .*$"));
|
|
||||||
REQUIRE_THAT(testStringForMatching(), Matches("^.* 'ABC' .*$", Catch::CaseSensitive::No));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
REQUIRE_THAT(testStringForMatching2(), !Matches("this string contains 'abc' as a substring"));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Regex string matcher", "[matchers][.failing]") {
|
|
||||||
CHECK_THAT( testStringForMatching(), Matches("this STRING contains 'abc' as a substring"));
|
|
||||||
CHECK_THAT( testStringForMatching(), Matches("contains 'abc' as a substring"));
|
|
||||||
CHECK_THAT( testStringForMatching(), Matches("this string contains 'abc' as a"));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Matchers can be (AllOf) composed with the && operator", "[matchers][operators][operator&&]")
|
|
||||||
{
|
|
||||||
CHECK_THAT( testStringForMatching(),
|
|
||||||
Contains( "string" ) &&
|
|
||||||
Contains( "abc" ) &&
|
|
||||||
Contains( "substring" ) &&
|
|
||||||
Contains( "contains" ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Matchers can be (AnyOf) composed with the || operator", "[matchers][operators][operator||]")
|
|
||||||
{
|
|
||||||
CHECK_THAT( testStringForMatching(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) );
|
|
||||||
CHECK_THAT( testStringForMatching2(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Matchers can be composed with both && and ||", "[matchers][operators][operator||][operator&&]")
|
|
||||||
{
|
|
||||||
CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "substring" ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Matchers can be composed with both && and || - failing", "[matchers][operators][operator||][operator&&][.failing]")
|
|
||||||
{
|
|
||||||
CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "random" ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Matchers can be negated (Not) with the ! operator", "[matchers][operators][not]")
|
|
||||||
{
|
|
||||||
CHECK_THAT( testStringForMatching(), !Contains( "different" ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Matchers can be negated (Not) with the ! operator - failing", "[matchers][operators][not][.failing]")
|
|
||||||
{
|
|
||||||
CHECK_THAT( testStringForMatching(), !Contains( "substring" ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE( "Vector matchers", "[matchers][vector]" ) {
|
|
||||||
std::vector<int> v;
|
|
||||||
v.push_back( 1 );
|
|
||||||
v.push_back( 2 );
|
|
||||||
v.push_back( 3 );
|
|
||||||
|
|
||||||
std::vector<int> v2;
|
|
||||||
v2.push_back( 1 );
|
|
||||||
v2.push_back( 2 );
|
|
||||||
|
|
||||||
std::vector<int> empty;
|
|
||||||
|
|
||||||
SECTION( "Contains (element)" ) {
|
|
||||||
CHECK_THAT( v, VectorContains( 1 ) );
|
|
||||||
CHECK_THAT( v, VectorContains( 2 ) );
|
|
||||||
}
|
|
||||||
SECTION( "Contains (vector)" ) {
|
|
||||||
CHECK_THAT( v, Contains( v2 ) );
|
|
||||||
v2.push_back( 3 ); // now exactly matches
|
|
||||||
CHECK_THAT( v, Contains( v2 ) );
|
|
||||||
|
|
||||||
CHECK_THAT( v, Contains( empty) );
|
|
||||||
CHECK_THAT( empty, Contains( empty) );
|
|
||||||
}
|
|
||||||
SECTION( "Contains (element), composed" ) {
|
|
||||||
CHECK_THAT( v, VectorContains( 1 ) && VectorContains( 2 ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION( "Equals" ) {
|
inline const char *testStringForMatching2() {
|
||||||
|
return "some completely different text that contains one common word";
|
||||||
// Same vector
|
|
||||||
CHECK_THAT( v, Equals( v ) );
|
|
||||||
|
|
||||||
CHECK_THAT( empty, Equals( empty ) );
|
|
||||||
|
|
||||||
// Different vector with same elements
|
|
||||||
v2.push_back( 3 );
|
|
||||||
CHECK_THAT( v, Equals( v2 ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE( "Vector matchers that fail", "[matchers][vector][.][failing]" ) {
|
|
||||||
std::vector<int> v;
|
|
||||||
v.push_back( 1 );
|
|
||||||
v.push_back( 2 );
|
|
||||||
v.push_back( 3 );
|
|
||||||
|
|
||||||
std::vector<int> v2;
|
|
||||||
v2.push_back( 1 );
|
|
||||||
v2.push_back( 2 );
|
|
||||||
|
|
||||||
std::vector<int> empty;
|
|
||||||
|
|
||||||
SECTION( "Contains (element)" ) {
|
|
||||||
CHECK_THAT( v, VectorContains( -1 ) );
|
|
||||||
CHECK_THAT( empty, VectorContains( 1 ) );
|
|
||||||
}
|
|
||||||
SECTION( "Contains (vector)" ) {
|
|
||||||
CHECK_THAT( empty, Contains( v) );
|
|
||||||
v2.push_back( 4 );
|
|
||||||
CHECK_THAT( v, Contains( v2 ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION( "Equals" ) {
|
|
||||||
|
|
||||||
CHECK_THAT( v, Equals( v2 ) );
|
|
||||||
CHECK_THAT( v2, Equals( v ) );
|
|
||||||
CHECK_THAT( empty, Equals( v ) );
|
|
||||||
CHECK_THAT( v, Equals( empty ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(disable:4702) // Unreachable code -- MSVC 19 (VS 2015) sees right through the indirection
|
#pragma warning(disable:4702) // Unreachable code -- MSVC 19 (VS 2015) sees right through the indirection
|
||||||
|
@ -210,119 +38,299 @@ TEST_CASE( "Vector matchers that fail", "[matchers][vector][.][failing]" ) {
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
|
||||||
struct SpecialException : std::exception {
|
struct SpecialException : std::exception {
|
||||||
SpecialException(int i_):i(i_) {}
|
SpecialException(int i_) : i(i_) {}
|
||||||
int i;
|
|
||||||
};
|
|
||||||
|
|
||||||
void doesNotThrow() {}
|
int i;
|
||||||
|
};
|
||||||
|
|
||||||
[[noreturn]]
|
void doesNotThrow() {}
|
||||||
void throws(int i) {
|
|
||||||
throw SpecialException{ i };
|
|
||||||
}
|
|
||||||
|
|
||||||
[[noreturn]]
|
[[noreturn]]
|
||||||
void throwsAsInt(int i) {
|
void throws(int i) {
|
||||||
throw i;
|
throw SpecialException{i};
|
||||||
}
|
|
||||||
|
|
||||||
class ExceptionMatcher : public Catch::MatcherBase<SpecialException> {
|
|
||||||
int m_expected;
|
|
||||||
public:
|
|
||||||
ExceptionMatcher(int i):m_expected(i) {}
|
|
||||||
bool match(SpecialException const& se) const override {
|
|
||||||
return se.i == m_expected;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string describe() const override {
|
[[noreturn]]
|
||||||
std::ostringstream ss;
|
void throwsAsInt(int i) {
|
||||||
ss << "special exception has value of " << m_expected;
|
throw i;
|
||||||
return ss.str();
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
class ExceptionMatcher : public Catch::MatcherBase<SpecialException> {
|
||||||
|
int m_expected;
|
||||||
|
public:
|
||||||
|
ExceptionMatcher(int i) : m_expected(i) {}
|
||||||
|
|
||||||
TEST_CASE( "Exception matchers that succeed", "[matchers][exceptions][!throws]" ) {
|
bool match(SpecialException const &se) const override {
|
||||||
CHECK_THROWS_MATCHES(throws(1), SpecialException, ExceptionMatcher{ 1 });
|
return se.i == m_expected;
|
||||||
REQUIRE_THROWS_MATCHES(throws(2), SpecialException, ExceptionMatcher{ 2 });
|
}
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Exception matchers that fail", "[matchers][exceptions][!throws][.failing]") {
|
std::string describe() const override {
|
||||||
SECTION("No exception") {
|
std::ostringstream ss;
|
||||||
CHECK_THROWS_MATCHES(doesNotThrow(), SpecialException, ExceptionMatcher{ 1 });
|
ss << "special exception has value of " << m_expected;
|
||||||
REQUIRE_THROWS_MATCHES(doesNotThrow(), SpecialException, ExceptionMatcher{ 1 });
|
return ss.str();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using namespace Catch::Matchers;
|
||||||
|
|
||||||
|
TEST_CASE("String matchers", "[matchers]") {
|
||||||
|
REQUIRE_THAT(testStringForMatching(), Contains("string"));
|
||||||
|
REQUIRE_THAT(testStringForMatching(), Contains("string", Catch::CaseSensitive::No));
|
||||||
|
CHECK_THAT(testStringForMatching(), Contains("abc"));
|
||||||
|
CHECK_THAT(testStringForMatching(), Contains("aBC", Catch::CaseSensitive::No));
|
||||||
|
|
||||||
|
CHECK_THAT(testStringForMatching(), StartsWith("this"));
|
||||||
|
CHECK_THAT(testStringForMatching(), StartsWith("THIS", Catch::CaseSensitive::No));
|
||||||
|
CHECK_THAT(testStringForMatching(), EndsWith("substring"));
|
||||||
|
CHECK_THAT(testStringForMatching(), EndsWith(" SuBsTrInG", Catch::CaseSensitive::No));
|
||||||
}
|
}
|
||||||
SECTION("Type mismatch") {
|
|
||||||
CHECK_THROWS_MATCHES(throwsAsInt(1), SpecialException, ExceptionMatcher{ 1 });
|
TEST_CASE("Contains string matcher", "[.][failing][matchers]") {
|
||||||
REQUIRE_THROWS_MATCHES(throwsAsInt(1), SpecialException, ExceptionMatcher{ 1 });
|
CHECK_THAT(testStringForMatching(), Contains("not there", Catch::CaseSensitive::No));
|
||||||
|
CHECK_THAT(testStringForMatching(), Contains("STRING"));
|
||||||
}
|
}
|
||||||
SECTION("Contents are wrong") {
|
|
||||||
CHECK_THROWS_MATCHES(throws(3), SpecialException, ExceptionMatcher{ 1 });
|
TEST_CASE("StartsWith string matcher", "[.][failing][matchers]") {
|
||||||
REQUIRE_THROWS_MATCHES(throws(4), SpecialException, ExceptionMatcher{ 1 });
|
CHECK_THAT(testStringForMatching(), StartsWith("This String"));
|
||||||
|
CHECK_THAT(testStringForMatching(), StartsWith("string", Catch::CaseSensitive::No));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Floating point matchers: float", "[matchers][floating-point]") {
|
TEST_CASE("EndsWith string matcher", "[.][failing][matchers]") {
|
||||||
SECTION("Margin") {
|
CHECK_THAT(testStringForMatching(), EndsWith("Substring"));
|
||||||
REQUIRE_THAT(1.f, WithinAbs(1.f, 0));
|
CHECK_THAT(testStringForMatching(), EndsWith("this", Catch::CaseSensitive::No));
|
||||||
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));
|
TEST_CASE("Equals string matcher", "[.][failing][matchers]") {
|
||||||
REQUIRE_THAT(std::nextafter(1.f, 0.f), WithinULP(1.f, 1));
|
CHECK_THAT(testStringForMatching(), Equals("this string contains 'ABC' as a substring"));
|
||||||
REQUIRE_THAT(std::nextafter(1.f, 2.f), !WithinULP(1.f, 0));
|
CHECK_THAT(testStringForMatching(), Equals("something else", Catch::CaseSensitive::No));
|
||||||
|
|
||||||
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("Equals", "[matchers]") {
|
||||||
|
CHECK_THAT(testStringForMatching(), Equals("this string contains 'abc' as a substring"));
|
||||||
|
CHECK_THAT(testStringForMatching(),
|
||||||
|
Equals("this string contains 'ABC' as a substring", Catch::CaseSensitive::No));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Floating point matchers: double", "[matchers][floating-point]") {
|
// <regex> does not work in libstdc++ 4.8, so we have to enable these tests only when they
|
||||||
SECTION("Margin") {
|
// are expected to pass and cannot have them in baselines
|
||||||
REQUIRE_THAT(1., WithinAbs(1., 0));
|
TEST_CASE("Regex string matcher -- libstdc++-4.8 workaround", "[matchers][approvals]") {
|
||||||
REQUIRE_THAT(0., WithinAbs(1., 1));
|
|
||||||
|
|
||||||
REQUIRE_THAT(0., !WithinAbs(1., 0.99));
|
// This is fiiiine
|
||||||
REQUIRE_THAT(0., !WithinAbs(1., 0.99));
|
// Taken from an answer at
|
||||||
|
// https://stackoverflow.com/questions/12530406/is-gcc-4-8-or-earlier-buggy-about-regular-expressions
|
||||||
|
#if (!defined(__GNUC__)) || \
|
||||||
|
(__cplusplus >= 201103L && \
|
||||||
|
(!defined(__GLIBCXX__) || (__cplusplus >= 201402L) || \
|
||||||
|
(defined(_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT) || \
|
||||||
|
defined(_GLIBCXX_REGEX_STATE_LIMIT) || \
|
||||||
|
(defined(_GLIBCXX_RELEASE) && \
|
||||||
|
_GLIBCXX_RELEASE > 4))))
|
||||||
|
|
||||||
REQUIRE_THAT(NAN, !WithinAbs(NAN, 0));
|
REQUIRE_THAT(testStringForMatching(), Matches("this string contains 'abc' as a substring"));
|
||||||
}
|
REQUIRE_THAT(testStringForMatching(),
|
||||||
SECTION("ULPs") {
|
Matches("this string CONTAINS 'abc' as a substring", Catch::CaseSensitive::No));
|
||||||
REQUIRE_THAT(1., WithinULP(1., 0));
|
REQUIRE_THAT(testStringForMatching(), Matches("^this string contains 'abc' as a substring$"));
|
||||||
|
REQUIRE_THAT(testStringForMatching(), Matches("^.* 'abc' .*$"));
|
||||||
|
REQUIRE_THAT(testStringForMatching(), Matches("^.* 'ABC' .*$", Catch::CaseSensitive::No));
|
||||||
|
#endif
|
||||||
|
|
||||||
REQUIRE_THAT(std::nextafter(1., 2.), WithinULP(1., 1));
|
REQUIRE_THAT(testStringForMatching2(), !Matches("this string contains 'abc' as a substring"));
|
||||||
REQUIRE_THAT(std::nextafter(1., 0.), WithinULP(1., 1));
|
}
|
||||||
REQUIRE_THAT(std::nextafter(1., 2.), !WithinULP(1., 0));
|
|
||||||
|
|
||||||
REQUIRE_THAT(1., WithinULP(1., 0));
|
TEST_CASE("Regex string matcher", "[matchers][.failing]") {
|
||||||
REQUIRE_THAT(-0., WithinULP(0., 0));
|
CHECK_THAT(testStringForMatching(), Matches("this STRING contains 'abc' as a substring"));
|
||||||
|
CHECK_THAT(testStringForMatching(), Matches("contains 'abc' as a substring"));
|
||||||
|
CHECK_THAT(testStringForMatching(), Matches("this string contains 'abc' as a"));
|
||||||
|
}
|
||||||
|
|
||||||
REQUIRE_THAT(NAN, !WithinULP(NAN, 123));
|
TEST_CASE("Matchers can be (AllOf) composed with the && operator", "[matchers][operators][operator&&]") {
|
||||||
}
|
CHECK_THAT(testStringForMatching(),
|
||||||
SECTION("Composed") {
|
Contains("string") &&
|
||||||
REQUIRE_THAT(1., WithinAbs(1., 0.5) || WithinULP(2., 1));
|
Contains("abc") &&
|
||||||
REQUIRE_THAT(1., WithinAbs(2., 0.5) || WithinULP(1., 0));
|
Contains("substring") &&
|
||||||
|
Contains("contains"));
|
||||||
|
}
|
||||||
|
|
||||||
REQUIRE_THAT(NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123)));
|
TEST_CASE("Matchers can be (AnyOf) composed with the || operator", "[matchers][operators][operator||]") {
|
||||||
}
|
CHECK_THAT(testStringForMatching(), Contains("string") || Contains("different") || Contains("random"));
|
||||||
}
|
CHECK_THAT(testStringForMatching2(), Contains("string") || Contains("different") || Contains("random"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Matchers can be composed with both && and ||", "[matchers][operators][operator||][operator&&]") {
|
||||||
|
CHECK_THAT(testStringForMatching(), (Contains("string") || Contains("different")) && Contains("substring"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Matchers can be composed with both && and || - failing",
|
||||||
|
"[matchers][operators][operator||][operator&&][.failing]") {
|
||||||
|
CHECK_THAT(testStringForMatching(), (Contains("string") || Contains("different")) && Contains("random"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Matchers can be negated (Not) with the ! operator", "[matchers][operators][not]") {
|
||||||
|
CHECK_THAT(testStringForMatching(), !Contains("different"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Matchers can be negated (Not) with the ! operator - failing",
|
||||||
|
"[matchers][operators][not][.failing]") {
|
||||||
|
CHECK_THAT(testStringForMatching(), !Contains("substring"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Vector matchers", "[matchers][vector]") {
|
||||||
|
std::vector<int> v;
|
||||||
|
v.push_back(1);
|
||||||
|
v.push_back(2);
|
||||||
|
v.push_back(3);
|
||||||
|
|
||||||
|
std::vector<int> v2;
|
||||||
|
v2.push_back(1);
|
||||||
|
v2.push_back(2);
|
||||||
|
|
||||||
|
std::vector<int> empty;
|
||||||
|
|
||||||
|
SECTION("Contains (element)") {
|
||||||
|
CHECK_THAT(v, VectorContains(1));
|
||||||
|
CHECK_THAT(v, VectorContains(2));
|
||||||
|
}
|
||||||
|
SECTION("Contains (vector)") {
|
||||||
|
CHECK_THAT(v, Contains(v2));
|
||||||
|
v2.push_back(3); // now exactly matches
|
||||||
|
CHECK_THAT(v, Contains(v2));
|
||||||
|
|
||||||
|
CHECK_THAT(v, Contains(empty));
|
||||||
|
CHECK_THAT(empty, Contains(empty));
|
||||||
|
}
|
||||||
|
SECTION("Contains (element), composed") {
|
||||||
|
CHECK_THAT(v, VectorContains(1) && VectorContains(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Equals") {
|
||||||
|
|
||||||
|
// Same vector
|
||||||
|
CHECK_THAT(v, Equals(v));
|
||||||
|
|
||||||
|
CHECK_THAT(empty, Equals(empty));
|
||||||
|
|
||||||
|
// Different vector with same elements
|
||||||
|
v2.push_back(3);
|
||||||
|
CHECK_THAT(v, Equals(v2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Vector matchers that fail", "[matchers][vector][.][failing]") {
|
||||||
|
std::vector<int> v;
|
||||||
|
v.push_back(1);
|
||||||
|
v.push_back(2);
|
||||||
|
v.push_back(3);
|
||||||
|
|
||||||
|
std::vector<int> v2;
|
||||||
|
v2.push_back(1);
|
||||||
|
v2.push_back(2);
|
||||||
|
|
||||||
|
std::vector<int> empty;
|
||||||
|
|
||||||
|
SECTION("Contains (element)") {
|
||||||
|
CHECK_THAT(v, VectorContains(-1));
|
||||||
|
CHECK_THAT(empty, VectorContains(1));
|
||||||
|
}
|
||||||
|
SECTION("Contains (vector)") {
|
||||||
|
CHECK_THAT(empty, Contains(v));
|
||||||
|
v2.push_back(4);
|
||||||
|
CHECK_THAT(v, Contains(v2));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Equals") {
|
||||||
|
|
||||||
|
CHECK_THAT(v, Equals(v2));
|
||||||
|
CHECK_THAT(v2, Equals(v));
|
||||||
|
CHECK_THAT(empty, Equals(v));
|
||||||
|
CHECK_THAT(v, Equals(empty));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Exception matchers that succeed", "[matchers][exceptions][!throws]") {
|
||||||
|
CHECK_THROWS_MATCHES(throws(1), SpecialException, ExceptionMatcher{1});
|
||||||
|
REQUIRE_THROWS_MATCHES(throws(2), SpecialException, ExceptionMatcher{2});
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Exception matchers that fail", "[matchers][exceptions][!throws][.failing]") {
|
||||||
|
SECTION("No exception") {
|
||||||
|
CHECK_THROWS_MATCHES(doesNotThrow(), SpecialException, ExceptionMatcher{1});
|
||||||
|
REQUIRE_THROWS_MATCHES(doesNotThrow(), SpecialException, ExceptionMatcher{1});
|
||||||
|
}
|
||||||
|
SECTION("Type mismatch") {
|
||||||
|
CHECK_THROWS_MATCHES(throwsAsInt(1), SpecialException, ExceptionMatcher{1});
|
||||||
|
REQUIRE_THROWS_MATCHES(throwsAsInt(1), SpecialException, ExceptionMatcher{1});
|
||||||
|
}
|
||||||
|
SECTION("Contents are wrong") {
|
||||||
|
CHECK_THROWS_MATCHES(throws(3), SpecialException, ExceptionMatcher{1});
|
||||||
|
REQUIRE_THROWS_MATCHES(throws(4), SpecialException, ExceptionMatcher{1});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} } // namespace MatchersTests
|
||||||
|
|
||||||
#endif // CATCH_CONFIG_DISABLE_MATCHERS
|
#endif // CATCH_CONFIG_DISABLE_MATCHERS
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,48 @@
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace { namespace MiscTests {
|
||||||
|
|
||||||
|
#ifndef MISC_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
|
||||||
|
#define MISC_TEST_HELPERS_INCLUDED
|
||||||
|
|
||||||
|
inline const char* makeString( bool makeNull ) {
|
||||||
|
return makeNull ? nullptr : "valid string";
|
||||||
|
}
|
||||||
|
inline bool testCheckedIf( bool flag ) {
|
||||||
|
CHECKED_IF( flag )
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inline bool testCheckedElse( bool flag ) {
|
||||||
|
CHECKED_ELSE( flag )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned int Factorial( unsigned int number ) {
|
||||||
|
return number > 1 ? Factorial(number-1)*number : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int f() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void manuallyRegisteredTestFunction() {
|
||||||
|
SUCCEED( "was called" );
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AutoTestReg {
|
||||||
|
AutoTestReg() {
|
||||||
|
REGISTER_TEST_CASE( manuallyRegisteredTestFunction, "ManuallyRegistered" );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static AutoTestReg autoTestReg;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
TEST_CASE( "random SECTION tests", "[.][sections][failing]" ) {
|
TEST_CASE( "random SECTION tests", "[.][sections][failing]" ) {
|
||||||
int a = 1;
|
int a = 1;
|
||||||
int b = 2;
|
int b = 2;
|
||||||
|
@ -108,23 +150,11 @@ TEST_CASE( "Sends stuff to stdout and stderr", "[.]" ) {
|
||||||
std::cerr << "A string sent directly to stderr" << std::endl;
|
std::cerr << "A string sent directly to stderr" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const char* makeString( bool makeNull ) {
|
|
||||||
return makeNull ? nullptr : "valid string";
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE( "null strings" ) {
|
TEST_CASE( "null strings" ) {
|
||||||
REQUIRE( makeString( false ) != static_cast<char*>(nullptr));
|
REQUIRE( makeString( false ) != static_cast<char*>(nullptr));
|
||||||
REQUIRE( makeString( true ) == static_cast<char*>(nullptr));
|
REQUIRE( makeString( true ) == static_cast<char*>(nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool testCheckedIf( bool flag ) {
|
|
||||||
CHECKED_IF( flag )
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE( "checkedIf" ) {
|
TEST_CASE( "checkedIf" ) {
|
||||||
REQUIRE( testCheckedIf( true ) );
|
REQUIRE( testCheckedIf( true ) );
|
||||||
}
|
}
|
||||||
|
@ -133,13 +163,6 @@ TEST_CASE( "checkedIf, failing", "[failing][.]" ) {
|
||||||
REQUIRE( testCheckedIf( false ) );
|
REQUIRE( testCheckedIf( false ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool testCheckedElse( bool flag ) {
|
|
||||||
CHECKED_ELSE( flag )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE( "checkedElse" ) {
|
TEST_CASE( "checkedElse" ) {
|
||||||
REQUIRE( testCheckedElse( true ) );
|
REQUIRE( testCheckedElse( true ) );
|
||||||
}
|
}
|
||||||
|
@ -171,9 +194,6 @@ TEST_CASE( "atomic if", "[failing][0]") {
|
||||||
REQUIRE(x == 0);
|
REQUIRE(x == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned int Factorial( unsigned int number ) {
|
|
||||||
return number > 1 ? Factorial(number-1)*number : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE( "Factorials are computed", "[factorial]" ) {
|
TEST_CASE( "Factorials are computed", "[factorial]" ) {
|
||||||
REQUIRE( Factorial(0) == 1 );
|
REQUIRE( Factorial(0) == 1 );
|
||||||
|
@ -312,11 +332,6 @@ TEST_CASE( "# A test name that starts with a #" ) {
|
||||||
SUCCEED( "yay" );
|
SUCCEED( "yay" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int f() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE( "#835 -- errno should not be touched by Catch", "[.][failing][!shouldfail]" ) {
|
TEST_CASE( "#835 -- errno should not be touched by Catch", "[.][failing][!shouldfail]" ) {
|
||||||
errno = 1;
|
errno = 1;
|
||||||
CHECK(f() == 0);
|
CHECK(f() == 0);
|
||||||
|
@ -331,12 +346,4 @@ TEST_CASE( "#961 -- Dynamically created sections should all be reported", "[.]"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void manuallyRegisteredTestFunction() {
|
}} // namespace MiscTests
|
||||||
SUCCEED( "was called" );
|
|
||||||
}
|
|
||||||
struct AutoTestReg {
|
|
||||||
AutoTestReg() {
|
|
||||||
REGISTER_TEST_CASE( manuallyRegisteredTestFunction, "ManuallyRegistered" );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
static AutoTestReg autoTestReg;
|
|
||||||
|
|
Loading…
Reference in New Issue