corelib/tests/key-value-table.cc

414 lines
12 KiB
C++

#include <ebcl/HashTables.hh>
#include <cppunit/extensions/HelperMacros.h>
using namespace ebcl;
class KeyValueTableTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE( KeyValueTableTest );
CPPUNIT_TEST( testEmpty );
CPPUNIT_TEST( testAdd );
CPPUNIT_TEST( testAddDuplicate );
CPPUNIT_TEST( testUpdate );
CPPUNIT_TEST( testUpdateMissing );
CPPUNIT_TEST( testSetNew );
CPPUNIT_TEST( testSetExisting );
CPPUNIT_TEST( testRemove );
CPPUNIT_TEST( testRemoveMissing );
CPPUNIT_TEST( testContains );
CPPUNIT_TEST( testContainsMissing );
CPPUNIT_TEST( testIndexOf );
CPPUNIT_TEST( testIndexOfMissing );
CPPUNIT_TEST( testGet );
CPPUNIT_TEST( testGetMissing );
CPPUNIT_TEST( testClear );
CPPUNIT_TEST( testFree );
CPPUNIT_TEST( testCopyCons );
CPPUNIT_TEST( testCopyAss );
CPPUNIT_TEST( testMoveCons );
CPPUNIT_TEST( testMoveAss );
CPPUNIT_TEST( testSwap );
CPPUNIT_TEST_SUITE_END( );
static constexpr uint32_t C_SIZE_ = 16;
public:
void testEmpty( );
void testAdd( );
void testAddDuplicate( );
void testUpdate( );
void testUpdateMissing( );
void testSetNew( );
void testSetExisting( );
void testRemove( );
void testRemoveMissing( );
void testContains( );
void testContainsMissing( );
void testIndexOf( );
void testIndexOfMissing( );
void testGet( );
void testGetMissing( );
void testCopyCons( );
void testCopyAss( );
void testMoveCons( );
void testMoveAss( );
void testClear( );
void testFree( );
void testSwap( );
};
CPPUNIT_TEST_SUITE_REGISTRATION( KeyValueTableTest );
/*----------------------------------------------------------------------------*/
void KeyValueTableTest::testEmpty( )
{
T_KeyValueTable< uint32_t , uint32_t > table;
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , table.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , table.keys( ).size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , table.values( ).size( ) );
}
/*----------------------------------------------------------------------------*/
void KeyValueTableTest::testAdd( )
{
T_KeyValueTable< uint32_t , uint32_t > table;
bool ok( table.add( 123u , 456u ) );
CPPUNIT_ASSERT( ok );
CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , table.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , table.keys( ).size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , table.values( ).size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 123 ) , table.keys( )[ 0 ] );
CPPUNIT_ASSERT_EQUAL( uint32_t( 456 ) , table.values( )[ 0 ] );
}
void KeyValueTableTest::testAddDuplicate( )
{
T_KeyValueTable< uint32_t , uint32_t > table;
table.add( 123u , 456u );
bool ok( table.add( 123u , 789u ) );
CPPUNIT_ASSERT( !ok );
CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , table.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , table.keys( ).size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , table.values( ).size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 123 ) , table.keys( )[ 0 ] );
CPPUNIT_ASSERT_EQUAL( uint32_t( 456 ) , table.values( )[ 0 ] );
}
void KeyValueTableTest::testUpdate( )
{
T_KeyValueTable< uint32_t , uint32_t > table;
table.add( 123u , 456u );
bool ok( table.update( 123u , 789u ) );
CPPUNIT_ASSERT( ok );
CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , table.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , table.keys( ).size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , table.values( ).size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 123 ) , table.keys( )[ 0 ] );
CPPUNIT_ASSERT_EQUAL( uint32_t( 789 ) , table.values( )[ 0 ] );
}
void KeyValueTableTest::testUpdateMissing( )
{
T_KeyValueTable< uint32_t , uint32_t > table;
bool ok( table.update( 123u , 789u ) );
CPPUNIT_ASSERT( !ok );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , table.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , table.keys( ).size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , table.values( ).size( ) );
}
void KeyValueTableTest::testSetNew( )
{
T_KeyValueTable< uint32_t , uint32_t > table;
table.set( 123u , 456u );
CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , table.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , table.keys( ).size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , table.values( ).size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 123 ) , table.keys( )[ 0 ] );
CPPUNIT_ASSERT_EQUAL( uint32_t( 456 ) , table.values( )[ 0 ] );
}
void KeyValueTableTest::testSetExisting( )
{
T_KeyValueTable< uint32_t , uint32_t > table;
table.add( 123u , 456u );
table.set( 123u , 789u );
CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , table.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , table.keys( ).size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , table.values( ).size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 123 ) , table.keys( )[ 0 ] );
CPPUNIT_ASSERT_EQUAL( uint32_t( 789 ) , table.values( )[ 0 ] );
}
/*----------------------------------------------------------------------------*/
void KeyValueTableTest::testRemove( )
{
T_KeyValueTable< uint32_t , uint32_t > table;
table.set( 123u , 456u );
table.set( 456u , 789u );
bool ok( table.remove( 456 ) );
CPPUNIT_ASSERT( ok );
CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , table.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , table.keys( ).size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , table.values( ).size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 123 ) , table.keys( )[ 0 ] );
CPPUNIT_ASSERT_EQUAL( uint32_t( 456 ) , table.values( )[ 0 ] );
}
void KeyValueTableTest::testRemoveMissing( )
{
T_KeyValueTable< uint32_t , uint32_t > table;
table.set( 123u , 456u );
bool ok( table.remove( 456 ) );
CPPUNIT_ASSERT( !ok );
CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , table.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , table.keys( ).size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , table.values( ).size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 123 ) , table.keys( )[ 0 ] );
CPPUNIT_ASSERT_EQUAL( uint32_t( 456 ) , table.values( )[ 0 ] );
}
/*----------------------------------------------------------------------------*/
void KeyValueTableTest::testContains( )
{
T_KeyValueTable< uint32_t , uint32_t > table;
table.set( 123u , 456u );
CPPUNIT_ASSERT( table.contains( 123 ) );
}
void KeyValueTableTest::testContainsMissing( )
{
T_KeyValueTable< uint32_t , uint32_t > table;
table.set( 123u , 456u );
CPPUNIT_ASSERT( !table.contains( 456 ) );
}
void KeyValueTableTest::testIndexOf( )
{
T_KeyValueTable< uint32_t , uint32_t > table;
for ( uint32_t i = 0 ; i < 124 ; i += 2 ) {
table.set( i , i * 2 );
}
for ( uint32_t i = 1 ; i < 124 ; i += 2 ) {
table.set( i , i * 2 );
}
const uint32_t index( table.indexOf( 57 ) );
CPPUNIT_ASSERT( index != T_HashIndex::INVALID_INDEX );
CPPUNIT_ASSERT( index < table.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 114 ) , table[ index ] );
CPPUNIT_ASSERT_EQUAL( uint32_t( 114 ) , table.values( )[ index ] );
CPPUNIT_ASSERT_EQUAL( uint32_t( 57 ) , table.keys( )[ index ] );
}
void KeyValueTableTest::testIndexOfMissing( )
{
T_KeyValueTable< uint32_t , uint32_t > table;
const uint32_t index( table.indexOf( 57 ) );
CPPUNIT_ASSERT( index == T_HashIndex::INVALID_INDEX );
}
void KeyValueTableTest::testGet( )
{
T_KeyValueTable< uint32_t , uint32_t > table;
for ( uint32_t i = 0 ; i < 124 ; i += 2 ) {
table.set( i , i * 2 );
}
for ( uint32_t i = 1 ; i < 124 ; i += 2 ) {
table.set( i , i * 2 );
}
const uint32_t* index( table.get( 57 ) );
CPPUNIT_ASSERT( index != nullptr );
CPPUNIT_ASSERT_EQUAL( uint32_t( 114 ) , *index );
}
void KeyValueTableTest::testGetMissing( )
{
T_KeyValueTable< uint32_t , uint32_t > table;
const uint32_t* index( table.get( 57 ) );
CPPUNIT_ASSERT( index == nullptr );
}
/*----------------------------------------------------------------------------*/
void KeyValueTableTest::testCopyCons( )
{
T_KeyValueTable< uint32_t , uint32_t > table;
for ( uint32_t i = 0 ; i < 124 ; i += 2 ) {
table.set( i , i * 2 );
}
for ( uint32_t i = 1 ; i < 124 ; i += 2 ) {
table.set( i , i * 2 );
}
const auto sz( table.size( ) );
T_KeyValueTable< uint32_t , uint32_t > copy( table );
CPPUNIT_ASSERT_EQUAL( sz , table.size( ) );
CPPUNIT_ASSERT_EQUAL( sz , copy.size( ) );
auto const& k( table.keys( ) );
for ( uint32_t i = 0 ; i < sz ; i ++ ) {
CPPUNIT_ASSERT( copy.contains( k[ i ] ) );
const uint32_t oValue( table.values( )[ i ] );
uint32_t const* const cPtr( copy.get( k[ i ] ) );
CPPUNIT_ASSERT( cPtr != nullptr );
CPPUNIT_ASSERT_EQUAL( oValue , *cPtr );
}
}
void KeyValueTableTest::testCopyAss( )
{
T_KeyValueTable< uint32_t , uint32_t > table;
for ( uint32_t i = 0 ; i < 124 ; i += 2 ) {
table.set( i , i * 2 );
}
for ( uint32_t i = 1 ; i < 124 ; i += 2 ) {
table.set( i , i * 2 );
}
const auto sz( table.size( ) );
T_KeyValueTable< uint32_t , uint32_t > copy;
copy = table;
CPPUNIT_ASSERT_EQUAL( sz , table.size( ) );
CPPUNIT_ASSERT_EQUAL( sz , copy.size( ) );
auto const& k( table.keys( ) );
for ( uint32_t i = 0 ; i < sz ; i ++ ) {
CPPUNIT_ASSERT( copy.contains( k[ i ] ) );
const uint32_t oValue( table.values( )[ i ] );
uint32_t const* const cPtr( copy.get( k[ i ] ) );
CPPUNIT_ASSERT( cPtr != nullptr );
CPPUNIT_ASSERT_EQUAL( oValue , *cPtr );
}
}
/*----------------------------------------------------------------------------*/
void KeyValueTableTest::testMoveCons( )
{
T_KeyValueTable< uint32_t , uint32_t > table;
for ( uint32_t i = 0 ; i < 124 ; i += 2 ) {
table.set( i , i * 2 );
}
for ( uint32_t i = 1 ; i < 124 ; i += 2 ) {
table.set( i , i * 2 );
}
const auto sz( table.size( ) );
T_Array< uint32_t > k( table.keys( ) );
T_KeyValueTable< uint32_t , uint32_t > copy( std::move( table ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , table.size( ) );
CPPUNIT_ASSERT_EQUAL( sz , copy.size( ) );
for ( uint32_t i = 0 ; i < sz ; i ++ ) {
CPPUNIT_ASSERT( copy.contains( k[ i ] ) );
CPPUNIT_ASSERT( !table.contains( k[ i ] ) );
uint32_t const* const cPtr( copy.get( k[ i ] ) );
CPPUNIT_ASSERT( cPtr != nullptr );
CPPUNIT_ASSERT_EQUAL( k[ i ] * 2 , *cPtr );
}
}
void KeyValueTableTest::testMoveAss( )
{
T_KeyValueTable< uint32_t , uint32_t > table;
for ( uint32_t i = 0 ; i < 124 ; i += 2 ) {
table.set( i , i * 2 );
}
for ( uint32_t i = 1 ; i < 124 ; i += 2 ) {
table.set( i , i * 2 );
}
const auto sz( table.size( ) );
T_Array< uint32_t > k( table.keys( ) );
T_KeyValueTable< uint32_t , uint32_t > copy;
copy = std::move( table );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , table.size( ) );
CPPUNIT_ASSERT_EQUAL( sz , copy.size( ) );
for ( uint32_t i = 0 ; i < sz ; i ++ ) {
CPPUNIT_ASSERT( copy.contains( k[ i ] ) );
CPPUNIT_ASSERT( !table.contains( k[ i ] ) );
uint32_t const* const cPtr( copy.get( k[ i ] ) );
CPPUNIT_ASSERT( cPtr != nullptr );
CPPUNIT_ASSERT_EQUAL( k[ i ] * 2 , *cPtr );
}
}
/*----------------------------------------------------------------------------*/
void KeyValueTableTest::testClear( )
{
T_KeyValueTable< uint32_t , uint32_t > table;
for ( uint32_t i = 0 ; i < 124 ; i += 2 ) {
table.set( i , i * 2 );
}
for ( uint32_t i = 1 ; i < 124 ; i += 2 ) {
table.set( i , i * 2 );
}
table.clear( );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , table.size( ) );
}
void KeyValueTableTest::testFree( )
{
T_KeyValueTable< uint32_t , uint32_t > table;
for ( uint32_t i = 0 ; i < 124 ; i += 2 ) {
table.set( i , i * 2 );
}
for ( uint32_t i = 1 ; i < 124 ; i += 2 ) {
table.set( i , i * 2 );
}
table.free( );
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , table.size( ) );
}
/*----------------------------------------------------------------------------*/
void KeyValueTableTest::testSwap( )
{
T_KeyValueTable< uint32_t , uint32_t > table;
T_KeyValueTable< uint32_t , uint32_t > table2;
for ( uint32_t i = 0 ; i < 12 ; i ++ ) {
table.set( i , i * 2 );
table2.set( 20 + i , i );
}
table.set( 123u , 456u );
swap( table , table2 );
CPPUNIT_ASSERT_EQUAL( uint32_t( 12 ) , table.size( ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 13 ) , table2.size( ) );
for ( uint32_t i = 0 ; i < 12 ; i ++ ) {
CPPUNIT_ASSERT( !table.contains( i ) );
CPPUNIT_ASSERT( table.contains( 20 + i ) );
CPPUNIT_ASSERT_EQUAL( i , *( table.get( 20 + i ) ) );
CPPUNIT_ASSERT( !table2.contains( 20 + i ) );
CPPUNIT_ASSERT( table2.contains( i ) );
CPPUNIT_ASSERT_EQUAL( i * 2 , *( table2.get( i ) ) );
}
CPPUNIT_ASSERT( table2.contains( 123 ) );
CPPUNIT_ASSERT_EQUAL( uint32_t( 456 ) , *( table2.get( 123 ) ) );
}