/** \file
 *
 *  Contains the test cases for the FastMap class
 *
 *  Copyright (c) 2007,2008,2009 MBARI
 *  MBARI Proprietary Information.  All Rights Reserved
 */

#ifndef _FASTMAP_TEST_H_
#define _FASTMAP_TEST_H_

#include "utils/FastMap.h"
#include "utils/Str.h"

#include <cxxtest/TestSuite.h>
#include <stdlib.h>

/**
 * %Units tests for class FastMap
 *
 * \ingroup utils
 */
class FastMap_Test : public CxxTest::TestSuite
{
public:

    /// FastMap Test - heap-allocated storage
    void testPutGetAndSizeNoDuplicates( void )
    {
        FastMap<const Str, const Str*> map;

        Str key1( "Key1" );
        Str key2( "Key2" );
        Str key3( "Key3" );
        Str key4( "Key4" );
        Str key5( "Key5" );

        const Str entry1( "Entry1" );
        const Str entry2( "Entry2" );
        const Str entry3( "Entry3" );
        const Str entry4( "Entry4" );
        const Str entry4a( "Entry4a" );

        TS_ASSERT_EQUALS( map.size(), 0U );

        map.put( key2, &entry2 );
        TS_ASSERT_EQUALS( map.size(), 1U );

        map.put( key4, &entry4 );
        TS_ASSERT_EQUALS( map.size(), 2U );

        map.put( key1, &entry1 );
        TS_ASSERT_EQUALS( map.size(), 3U );

        map.put( key3, &entry3 );
        TS_ASSERT_EQUALS( map.size(), 4U );

        // Repeat entry of key 4
        map.put( key4, &entry4a );
        TS_ASSERT_EQUALS( map.size(), 4U );

        TS_ASSERT_EQUALS( *map.get( key1 ), entry1 );
        TS_ASSERT_EQUALS( *map.get( key2 ), entry2 );
        TS_ASSERT_EQUALS( *map.get( key3 ), entry3 );
        TS_ASSERT_EQUALS( *map.get( key4 ), entry4 );
        TS_ASSERT_EQUALS( map.get( key5 ), ( void* )0 );

    }

    /// FastMap Test - dynamically-allocated storage
    void testPutGetAndSizeNoDuplicatesDynamic( void )
    {
        FastMap<const Str, const Str*> map2;

        Str key21( "Key21" );
        Str key22( "Key22" );
        Str key23( "Key23" );
        Str key24( "Key24" );
        Str key25( "Key25" );

        map2.put( key22, new Str( "Entry2.2" ) );
        map2.put( key24, new Str( "Entry2.4" ) );
        map2.put( key21, new Str( "Entry2.1" ) );
        map2.put( key23, new Str( "Entry2.3" ) );
        Str* str = new Str( "Entry2.4a" );
        if( !map2.put( key24, str ) )
        {
            delete str;
        }

        TS_ASSERT_SAME_DATA( map2.get( key21 )->cStr(), "Entry2.1", 9 );
        TS_ASSERT_SAME_DATA( map2.get( key22 )->cStr(), "Entry2.2", 9 );
        TS_ASSERT_SAME_DATA( map2.get( key23 )->cStr(), "Entry2.3", 9 );
        TS_ASSERT_SAME_DATA( map2.get( key24 )->cStr(), "Entry2.4", 9 );
        TS_ASSERT_EQUALS( map2.get( key25 ), ( void* )0 );

        while( map2.size() > 0 )
        {
            delete map2.popIndexed( 0 );
        }

    }

    /// FastMap Test - heap-allocated storage
    void testPutGetRandomDumpDuplicates( void )
    {
        int n = 40000;
        FlexArray<Str*> keys( true, n / 2 );
        FastMap<Str, int*> map( false, n / 2 );
        for( int i = 1; i < n; ++i )
        {
            Str* str = new Str( ( int )( random() % ( n / 2 ) ) );
            if( !map.put( *str, &n ) )
            {
                delete str;
            }
            else
            {
                keys.push( str );
            }
        }

        for( unsigned int i = 0; i < keys.size(); ++i )
        {
            Str* key = keys.get( i );
            TS_ASSERT_EQUALS( map.get( *key ), &n );
        }
    }
};

#endif // _FASTMAP_TEST_H
