corelib/tests/optional.cc

287 lines
6.3 KiB
C++

#include <lw/lib/Types.hh>
#include <cppunit/extensions/HelperMacros.h>
using namespace lw;
class OptionalTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE( OptionalTest );
CPPUNIT_TEST( testDefaultCons );
CPPUNIT_TEST( testConstructCons );
CPPUNIT_TEST( testDestruct );
CPPUNIT_TEST( testCopyCons );
CPPUNIT_TEST( testCopyAss );
CPPUNIT_TEST( testMoveCons );
CPPUNIT_TEST( testMoveAss );
CPPUNIT_TEST( testSwapEE );
CPPUNIT_TEST( testSwapVV );
CPPUNIT_TEST( testSwapVE );
CPPUNIT_TEST( testValueCopyCons );
CPPUNIT_TEST( testValueCopyAss );
CPPUNIT_TEST( testValueMoveCons );
CPPUNIT_TEST( testValueMoveAss );
CPPUNIT_TEST( testSetNew );
CPPUNIT_TEST( testClear );
CPPUNIT_TEST( testCast );
CPPUNIT_TEST( testCastException );
CPPUNIT_TEST_SUITE_END( );
public:
void tearDown( ) override;
void testDefaultCons( );
void testConstructCons( );
void testDestruct( );
void testCopyCons( );
void testCopyAss( );
void testMoveCons( );
void testMoveAss( );
void testSwapEE( );
void testSwapVV( );
void testSwapVE( );
void testValueCopyCons( );
void testValueCopyAss( );
void testValueMoveCons( );
void testValueMoveAss( );
void testSetNew( );
void testClear( );
void testCast( );
void testCastException( );
};
CPPUNIT_TEST_SUITE_REGISTRATION( OptionalTest );
/*----------------------------------------------------------------------------*/
namespace {
int consCounter = 0;
int delCounter = 0;
int mvCounter = 0;
int cpCounter = 0;
struct T_Counter_
{
int value;
T_Counter_( ) noexcept : value( 0 ) { consCounter ++; }
explicit T_Counter_( int x ) noexcept : value( x ) { consCounter ++; }
T_Counter_( T_Counter_ const& o ) noexcept : value( o.value ) { cpCounter ++; }
T_Counter_( T_Counter_&& o ) noexcept : value( o.value ) { mvCounter ++; }
~T_Counter_( ) { delCounter ++; }
};
#define M_COUNTS_(C,D,CP,M) \
do { \
CPPUNIT_ASSERT_EQUAL( int( C ) , consCounter ); \
CPPUNIT_ASSERT_EQUAL( int( D ) , delCounter ); \
CPPUNIT_ASSERT_EQUAL( int( CP ) , cpCounter ); \
CPPUNIT_ASSERT_EQUAL( int( M ) , mvCounter ); \
} while ( 0 )
#define M_EMPTY_( O ) \
do { \
CPPUNIT_ASSERT( ! ( O ).present( ) ); \
CPPUNIT_ASSERT( ( O ).target( ) == nullptr ); \
} while ( 0 )
#define M_VALUE_( O , V ) \
do { \
CPPUNIT_ASSERT( ( O ).present( ) ); \
CPPUNIT_ASSERT( ( O ).target( ) != nullptr ); \
CPPUNIT_ASSERT_EQUAL( int( V ) , ( O ).target( )->value ); \
} while ( 0 )
} // namespace
void OptionalTest::tearDown( )
{
consCounter = delCounter = mvCounter = cpCounter = 0;
}
/*----------------------------------------------------------------------------*/
void OptionalTest::testDefaultCons( )
{
const T_Optional< T_Counter_ > o;
M_EMPTY_( o );
M_COUNTS_( 0 , 0 , 0 , 0 );
}
void OptionalTest::testConstructCons( )
{
const T_Optional< T_Counter_ > o{ Construct< T_Counter_ >( ) , 12 };
M_VALUE_( o , 12 );
M_COUNTS_( 1 , 0 , 0 , 0 );
}
void OptionalTest::testDestruct( )
{
{
T_Optional< T_Counter_ > o{ Construct< T_Counter_ >( ) };
}
M_COUNTS_( 1 , 1 , 0 , 0 );
}
/*----------------------------------------------------------------------------*/
void OptionalTest::testCopyCons( )
{
const T_Optional< T_Counter_ > s{ Construct< T_Counter_ >( ) , 12 };
const T_Optional< T_Counter_ > d( s );
M_COUNTS_( 1 , 0 , 1 , 0 );
M_VALUE_( s , 12 );
M_VALUE_( d , 12 );
}
void OptionalTest::testCopyAss( )
{
const T_Optional< T_Counter_ > s{ Construct< T_Counter_ >( ) , 12 };
const T_Optional< T_Counter_ > empty;
T_Optional< T_Counter_ > d;
d = s;
M_COUNTS_( 1 , 0 , 1 , 0 );
M_VALUE_( s , 12 );
M_VALUE_( d , 12 );
d = empty;
M_COUNTS_( 1 , 1 , 1 , 0 );
M_EMPTY_( d );
}
void OptionalTest::testMoveCons( )
{
T_Optional< T_Counter_ > s{ Construct< T_Counter_ >( ) , 12 };
const T_Optional< T_Counter_ > d( std::move( s ) );
M_COUNTS_( 1 , 1 , 0 , 1 );
M_VALUE_( d , 12 );
M_EMPTY_( s );
}
void OptionalTest::testMoveAss( )
{
T_Optional< T_Counter_ > s{ Construct< T_Counter_ >( ) , 12 };
T_Optional< T_Counter_ > empty;
T_Optional< T_Counter_ > d;
d = std::move( s );
M_COUNTS_( 1 , 1 , 0 , 1 );
M_EMPTY_( s );
M_VALUE_( d , 12 );
d = std::move( empty );
M_COUNTS_( 1 , 2 , 0 , 1 );
M_EMPTY_( d );
}
/*----------------------------------------------------------------------------*/
void OptionalTest::testSwapEE( )
{
T_Optional< T_Counter_ > o1 , o2;
swap( o1 , o2 );
M_COUNTS_( 0 , 0 , 0 , 0 );
M_EMPTY_( o1 );
M_EMPTY_( o2 );
}
void OptionalTest::testSwapVV( )
{
T_Optional< T_Counter_ > o1{ Construct< T_Counter_ >( ) , 1 } ,
o2{ Construct< T_Counter_ >( ) , 2 };
swap( o1 , o2 );
M_COUNTS_( 2 , 3 , 0 , 3 );
M_VALUE_( o1 , 2 );
M_VALUE_( o2 , 1 );
}
void OptionalTest::testSwapVE( )
{
T_Optional< T_Counter_ > o1{ Construct< T_Counter_ >( ) , 1 } , o2;
swap( o1 , o2 );
M_COUNTS_( 1 , 1 , 0 , 1 );
M_EMPTY_( o1 );
M_VALUE_( o2 , 1 );
}
/*----------------------------------------------------------------------------*/
void OptionalTest::testValueCopyCons( )
{
const T_Counter_ c( 12 );
T_Optional< T_Counter_ > o( c );
M_COUNTS_( 1 , 0 , 1 , 0 );
M_VALUE_( o , 12 );
}
void OptionalTest::testValueCopyAss( )
{
const T_Counter_ c( 12 );
T_Optional< T_Counter_ > o;
o = c;
M_COUNTS_( 1 , 0 , 1 , 0 );
M_VALUE_( o , 12 );
}
void OptionalTest::testValueMoveCons( )
{
T_Counter_ c( 12 );
T_Optional< T_Counter_ > o( std::move( c ) );
M_COUNTS_( 1 , 0 , 0 , 1 );
M_VALUE_( o , 12 );
}
void OptionalTest::testValueMoveAss( )
{
T_Counter_ c( 12 );
T_Optional< T_Counter_ > o;
o = std::move( c );
M_COUNTS_( 1 , 0 , 0 , 1 );
M_VALUE_( o , 12 );
}
/*----------------------------------------------------------------------------*/
void OptionalTest::testSetNew( )
{
T_Optional< T_Counter_ > s{ Construct< T_Counter_ >( ) , 12 };
s.setNew( 34 );
M_COUNTS_( 2 , 1 , 0 , 0 );
M_VALUE_( s , 34 );
}
void OptionalTest::testClear( )
{
T_Optional< T_Counter_ > s{ Construct< T_Counter_ >( ) , 12 };
s.clear( );
M_COUNTS_( 1 , 1 , 0 , 0 );
M_EMPTY_( s );
}
/*----------------------------------------------------------------------------*/
void OptionalTest::testCast( )
{
const T_Optional< T_Counter_ > s{ Construct< T_Counter_ >( ) , 12 };
T_Counter_ cnt( s );
CPPUNIT_ASSERT_EQUAL( 12 , cnt.value );
}
void OptionalTest::testCastException( )
{
const T_Optional< T_Counter_ > s;
try {
T_Counter_ cnt( s );
CPPUNIT_FAIL( "std::bad_cast not thrown" );
} catch ( std::bad_cast const& ) {
// OK
}
}