All tests files have .tests.cpp suffix. Also moved tests out of TestMain.cpp and moved up a level
This commit is contained in:
parent
e34754e433
commit
74d3dfd4cc
32 changed files with 3323 additions and 3322 deletions
448
projects/SelfTest/UsageTests/Tricky.tests.cpp
Normal file
448
projects/SelfTest/UsageTests/Tricky.tests.cpp
Normal file
|
@ -0,0 +1,448 @@
|
|||
/*
|
||||
* Created by Phil on 09/11/2010.
|
||||
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic ignored "-Wpadded"
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable : 4702) // Disable unreachable code warning for the last test
|
||||
// that is triggered when compiling as Win32|Release
|
||||
#endif
|
||||
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sstream>
|
||||
|
||||
namespace Catch {
|
||||
std::string toString( const std::pair<int, int>& value ) {
|
||||
std::ostringstream oss;
|
||||
oss << "std::pair( " << value.first << ", " << value.second << " )";
|
||||
return oss.str();
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
TEST_CASE
|
||||
(
|
||||
"Parsing a std::pair",
|
||||
"[Tricky][std::pair]"
|
||||
)
|
||||
{
|
||||
std::pair<int, int> aNicePair( 1, 2 );
|
||||
|
||||
REQUIRE( (std::pair<int, int>( 1, 2 )) == aNicePair );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
TEST_CASE
|
||||
(
|
||||
"Where there is more to the expression after the RHS",
|
||||
"[Tricky][failing][.]"
|
||||
)
|
||||
{
|
||||
// int a = 1, b = 2;
|
||||
// REQUIRE( a == 2 || b == 2 );
|
||||
WARN( "Uncomment the code in this test to check that it gives a sensible compiler error" );
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
TEST_CASE
|
||||
(
|
||||
"Where the LHS is not a simple value",
|
||||
"[Tricky][failing][.]"
|
||||
)
|
||||
{
|
||||
/*
|
||||
int a = 1;
|
||||
int b = 2;
|
||||
|
||||
// This only captures part of the expression, but issues a warning about the rest
|
||||
REQUIRE( a+1 == b-1 );
|
||||
*/
|
||||
WARN( "Uncomment the code in this test to check that it gives a sensible compiler error" );
|
||||
}
|
||||
|
||||
struct Opaque
|
||||
{
|
||||
int val;
|
||||
bool operator ==( const Opaque& o ) const
|
||||
{
|
||||
return val == o.val;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
TEST_CASE
|
||||
(
|
||||
"A failing expression with a non streamable type is still captured",
|
||||
"[Tricky][failing][.]"
|
||||
)
|
||||
{
|
||||
|
||||
Opaque o1, o2;
|
||||
o1.val = 7;
|
||||
o2.val = 8;
|
||||
|
||||
CHECK( &o1 == &o2 );
|
||||
CHECK( o1 == o2 );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
TEST_CASE
|
||||
(
|
||||
"string literals of different sizes can be compared",
|
||||
"[Tricky][failing][.]"
|
||||
)
|
||||
{
|
||||
REQUIRE( std::string( "first" ) == "second" );
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
TEST_CASE
|
||||
(
|
||||
"An expression with side-effects should only be evaluated once",
|
||||
"[Tricky]"
|
||||
)
|
||||
{
|
||||
int i = 7;
|
||||
|
||||
REQUIRE( i++ == 7 );
|
||||
REQUIRE( i++ == 8 );
|
||||
|
||||
}
|
||||
|
||||
namespace A {
|
||||
struct X
|
||||
{
|
||||
X() : a(4), b(2), c(7) {}
|
||||
X(int v) : a(v), b(2), c(7) {}
|
||||
int a;
|
||||
int b;
|
||||
int c;
|
||||
};
|
||||
}
|
||||
|
||||
namespace B {
|
||||
struct Y
|
||||
{
|
||||
Y() : a(4), b(2), c(7) {}
|
||||
Y(int v) : a(v), b(2), c(7) {}
|
||||
int a;
|
||||
int b;
|
||||
int c;
|
||||
};
|
||||
}
|
||||
|
||||
inline bool operator==(const A::X& lhs, const B::Y& rhs)
|
||||
{
|
||||
return (lhs.a == rhs.a);
|
||||
}
|
||||
|
||||
inline bool operator==(const B::Y& lhs, const A::X& rhs)
|
||||
{
|
||||
return (lhs.a == rhs.a);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/* This, currently, does not compile with LLVM
|
||||
TEST_CASE
|
||||
(
|
||||
"Operators at different namespace levels not hijacked by Koenig lookup"
|
||||
"[Tricky]"
|
||||
)
|
||||
{
|
||||
A::X x;
|
||||
B::Y y;
|
||||
REQUIRE( x == y );
|
||||
}
|
||||
*/
|
||||
|
||||
namespace ObjectWithConversions
|
||||
{
|
||||
struct Object
|
||||
{
|
||||
operator unsigned int() const {return 0xc0000000;}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
TEST_CASE
|
||||
(
|
||||
"Operators at different namespace levels not hijacked by Koenig lookup",
|
||||
"[Tricky][approvals]"
|
||||
)
|
||||
{
|
||||
Object o;
|
||||
REQUIRE(0xc0000000 == o );
|
||||
}
|
||||
}
|
||||
|
||||
namespace EnumBitFieldTests
|
||||
{
|
||||
enum Bits : uint32_t {
|
||||
bit0 = 0x0001,
|
||||
bit1 = 0x0002,
|
||||
bit2 = 0x0004,
|
||||
bit3 = 0x0008,
|
||||
bit1and2 = bit1 | bit2,
|
||||
bit30 = 0x40000000,
|
||||
bit31 = 0x80000000,
|
||||
bit30and31 = bit30 | bit31
|
||||
};
|
||||
|
||||
TEST_CASE( "Test enum bit values", "[Tricky]" )
|
||||
{
|
||||
REQUIRE( 0xc0000000 == bit30and31 );
|
||||
}
|
||||
}
|
||||
|
||||
struct Obj
|
||||
{
|
||||
Obj():prop(&p){}
|
||||
|
||||
int p;
|
||||
int* prop;
|
||||
};
|
||||
|
||||
TEST_CASE("boolean member", "[Tricky]")
|
||||
{
|
||||
Obj obj;
|
||||
REQUIRE( obj.prop != nullptr );
|
||||
}
|
||||
|
||||
// Tests for a problem submitted by Ralph McArdell
|
||||
//
|
||||
// The static bool value should not need to be defined outside the
|
||||
// struct it is declared in - but when evaluating it in a deduced
|
||||
// context it appears to require the extra definition.
|
||||
// The issue was fixed by adding bool overloads to bypass the
|
||||
// templates that were there to deduce it.
|
||||
template <bool B>
|
||||
struct is_true
|
||||
{
|
||||
static const bool value = B;
|
||||
};
|
||||
|
||||
TEST_CASE( "(unimplemented) static bools can be evaluated", "[Tricky]" )
|
||||
{
|
||||
SECTION("compare to true","")
|
||||
{
|
||||
REQUIRE( is_true<true>::value == true );
|
||||
REQUIRE( true == is_true<true>::value );
|
||||
}
|
||||
SECTION("compare to false","")
|
||||
{
|
||||
REQUIRE( is_true<false>::value == false );
|
||||
REQUIRE( false == is_true<false>::value );
|
||||
}
|
||||
|
||||
SECTION("negation", "")
|
||||
{
|
||||
REQUIRE( !is_true<false>::value );
|
||||
}
|
||||
|
||||
SECTION("double negation","")
|
||||
{
|
||||
REQUIRE( !!is_true<true>::value );
|
||||
}
|
||||
|
||||
SECTION("direct","")
|
||||
{
|
||||
REQUIRE( is_true<true>::value );
|
||||
REQUIRE_FALSE( is_true<false>::value );
|
||||
}
|
||||
}
|
||||
|
||||
// Uncomment these tests to produce an error at test registration time
|
||||
/*
|
||||
TEST_CASE( "Tests with the same name are not allowed", "[Tricky]" )
|
||||
{
|
||||
|
||||
}
|
||||
TEST_CASE( "Tests with the same name are not allowed", "[Tricky]" )
|
||||
{
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
struct Boolable
|
||||
{
|
||||
explicit Boolable( bool value ) : m_value( value ) {}
|
||||
|
||||
explicit operator bool() const {
|
||||
return m_value;
|
||||
}
|
||||
|
||||
bool m_value;
|
||||
};
|
||||
|
||||
TEST_CASE( "Objects that evaluated in boolean contexts can be checked", "[Tricky][SafeBool]" )
|
||||
{
|
||||
Boolable True( true );
|
||||
Boolable False( false );
|
||||
|
||||
CHECK( True );
|
||||
CHECK( !False );
|
||||
CHECK_FALSE( False );
|
||||
}
|
||||
|
||||
TEST_CASE( "Assertions then sections", "[Tricky]" )
|
||||
{
|
||||
// This was causing a failure due to the way the console reporter was handling
|
||||
// the current section
|
||||
|
||||
REQUIRE( Catch::alwaysTrue() );
|
||||
|
||||
SECTION( "A section" )
|
||||
{
|
||||
REQUIRE( Catch::alwaysTrue() );
|
||||
|
||||
SECTION( "Another section" )
|
||||
{
|
||||
REQUIRE( Catch::alwaysTrue() );
|
||||
}
|
||||
SECTION( "Another other section" )
|
||||
{
|
||||
REQUIRE( Catch::alwaysTrue() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Awkward
|
||||
{
|
||||
operator int() const { return 7; }
|
||||
};
|
||||
|
||||
TEST_CASE( "non streamable - with conv. op", "[Tricky]" )
|
||||
{
|
||||
Awkward awkward;
|
||||
std::string s = ::Catch::Detail::stringify( awkward );
|
||||
REQUIRE( s == "7" );
|
||||
}
|
||||
|
||||
inline void foo() {}
|
||||
|
||||
typedef void (*fooptr_t)();
|
||||
|
||||
TEST_CASE( "Comparing function pointers", "[Tricky][function pointer]" )
|
||||
{
|
||||
// This was giving a warning in VS2010
|
||||
// #179
|
||||
fooptr_t a = foo;
|
||||
|
||||
REQUIRE( a );
|
||||
REQUIRE( a == &foo );
|
||||
}
|
||||
|
||||
struct S
|
||||
{
|
||||
void f() {}
|
||||
};
|
||||
|
||||
|
||||
TEST_CASE( "Comparing member function pointers", "[Tricky][member function pointer][approvals]" )
|
||||
{
|
||||
typedef void (S::*MF)();
|
||||
MF m = &S::f;
|
||||
|
||||
CHECK( m == &S::f );
|
||||
}
|
||||
|
||||
class ClassName {};
|
||||
|
||||
TEST_CASE( "pointer to class", "[Tricky]" )
|
||||
{
|
||||
ClassName *p = 0;
|
||||
REQUIRE( p == 0 );
|
||||
}
|
||||
|
||||
#include <memory>
|
||||
|
||||
TEST_CASE( "null_ptr", "[Tricky]" )
|
||||
{
|
||||
std::unique_ptr<int> ptr;
|
||||
REQUIRE(ptr.get() == nullptr);
|
||||
}
|
||||
|
||||
TEST_CASE( "X/level/0/a", "[Tricky]" ) { SUCCEED(""); }
|
||||
TEST_CASE( "X/level/0/b", "[Tricky][fizz]" ){ SUCCEED(""); }
|
||||
TEST_CASE( "X/level/1/a", "[Tricky]" ) { SUCCEED(""); }
|
||||
TEST_CASE( "X/level/1/b", "[Tricky]" ) { SUCCEED(""); }
|
||||
|
||||
TEST_CASE( "has printf" ) {
|
||||
|
||||
// This can cause problems as, currently, stdout itself is not redirected - only the cout (and cerr) buffer
|
||||
printf( "loose text artifact\n" );
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct constructor_throws {
|
||||
[[noreturn]] constructor_throws() {
|
||||
throw 1;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("Commas in various macros are allowed") {
|
||||
REQUIRE_THROWS( std::vector<constructor_throws>{constructor_throws{}, constructor_throws{}} );
|
||||
CHECK_THROWS( std::vector<constructor_throws>{constructor_throws{}, constructor_throws{}} );
|
||||
REQUIRE_NOTHROW( std::vector<int>{1, 2, 3} == std::vector<int>{1, 2, 3} );
|
||||
CHECK_NOTHROW( std::vector<int>{1, 2, 3} == std::vector<int>{1, 2, 3} );
|
||||
|
||||
REQUIRE(std::vector<int>{1, 2} == std::vector<int>{1, 2});
|
||||
CHECK( std::vector<int>{1, 2} == std::vector<int>{1, 2} );
|
||||
REQUIRE_FALSE(std::vector<int>{1, 2} == std::vector<int>{1, 2, 3});
|
||||
CHECK_FALSE( std::vector<int>{1, 2} == std::vector<int>{1, 2, 3} );
|
||||
|
||||
CHECK_NOFAIL( std::vector<int>{1, 2} == std::vector<int>{1, 2} );
|
||||
CHECKED_IF( std::vector<int>{1, 2} == std::vector<int>{1, 2} ) {
|
||||
REQUIRE(true);
|
||||
} CHECKED_ELSE( std::vector<int>{1, 2} == std::vector<int>{1, 2} ) {
|
||||
CHECK(true);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE( "null deref", "[.][failing][!nonportable]" ) {
|
||||
CHECK( false );
|
||||
int *x = NULL;
|
||||
*x = 1;
|
||||
}
|
||||
|
||||
TEST_CASE( "non-copyable objects", "[.][failing]" ) {
|
||||
// Thanks to Agustin Bergé (@k-ballo on the cpplang Slack) for raising this
|
||||
std::type_info const& ti = typeid(int);
|
||||
CHECK( ti == typeid(int) );
|
||||
}
|
||||
|
||||
// #925
|
||||
using signal_t = void (*) (void*);
|
||||
|
||||
struct TestClass {
|
||||
signal_t testMethod_uponComplete_arg = nullptr;
|
||||
};
|
||||
|
||||
namespace utility {
|
||||
inline static void synchronizing_callback( void * ) { }
|
||||
}
|
||||
|
||||
TEST_CASE("#925: comparing function pointer to function address failed to compile", "[!nonportable]" ) {
|
||||
|
||||
TestClass test;
|
||||
REQUIRE(utility::synchronizing_callback != test.testMethod_uponComplete_arg);
|
||||
}
|
||||
|
||||
TEST_CASE( "Bitfields can be captured (#1027)" ) {
|
||||
struct Y {
|
||||
uint32_t v : 1;
|
||||
};
|
||||
Y y{ 0 };
|
||||
REQUIRE( y.v == 0 );
|
||||
REQUIRE( 0 == y.v );
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue