287 lines
6.3 KiB
C++
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
|
|
}
|
|
}
|