/*
 * @(#)ObjectCacheUTest.java      0.9.0 17-APR-2001 - 14:40
 *
 * Copyright (C) 2001,,2003 2002 Matt Albrecht
 * groboclown@users.sourceforge.net
 * http://groboutils.sourceforge.net
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a
 *  copy of this software and associated documentation files (the "Software"),
 *  to deal in the Software without restriction, including without limitation
 *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *  and/or sell copies of the Software, and to permit persons to whom the 
 *  Software is furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in 
 *  all copies or substantial portions of the Software. 
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL 
 *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
 *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 *  DEALINGS IN THE SOFTWARE.
 */

package net.sourceforge.groboutils.util.datastruct.v1;

import net.sourceforge.groboutils.junit.v1.MultiThreadedTestRunner;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
 * 
 *
 * @author    Matt Albrecht <a href="mailto:groboclown@users.sourceforge.net">groboclown@users.sourceforge.net</a>
 * @since     April 17, 2001 (Alpha 0.9.0)
 * @version   $Date: 2003/02/10 22:52:44 $
 */
public class ObjectCacheUTest extends TestCase
{
    private static final Class THIS_CLASS = ObjectCacheUTest.class;
    
    public ObjectCacheUTest( String name )
    {
        super( name );
    }
    
    public static Test suite()
    {
        TestSuite suite = new TestSuite( THIS_CLASS );
        
        return suite;
    }
    
    public static void main( String[] args )
    {
        String[] name = { THIS_CLASS.getName() };
        
        // junit.textui.TestRunner.main( name );
        // junit.swingui.TestRunner.main( name );
        
        junit.textui.TestRunner.main( name );
    }
    
    protected void setUp() throws Exception
    {
        super.setUp();
        
        // set ourself up
    }
    
    
    protected void tearDown() throws Exception
    {
        // tear ourself down
        
        
        super.tearDown();
    }
    
    
    public class OCreator implements ObjectCache.ObjectCreator
    {
        private int count = 0;
        public synchronized Object createObject()
        {
            return "Object "+(++count);
        }
        
        public int getCreationCount()
        {
            return count;
        }
    }
    
    
    
    public void testInstantiate()
    {
        ObjectCache oc = new ObjectCache();
        assertEquals( "Size must be at default of UNLIMITED.",
            oc.UNLIMITED_SIZE, oc.getMaxSize() );
        assertEquals( "Underflows must be at zero.",
            0, oc.getUnderflows() );
        assertEquals( "Overflows must be at zero.",
            0, oc.getOverflows() );
        // this test only works because we didn't specify a creator
        // needs to be at end to avoid underflows
        assertTrue( "Cache should be empty after creation.", oc.get() == null );
            
        oc = new ObjectCache( 10 );
        assertEquals( "Size must be at specified size.",
            10, oc.getMaxSize() );
        assertEquals( "Underflows must be at zero.",
            0, oc.getUnderflows() );
        assertEquals( "Overflows must be at zero.",
            0, oc.getOverflows() );
        // this test only works because we didn't specify a creator
        // needs to be at end to avoid underflows
        assertTrue( "Cache should be empty after creation.", oc.get() == null );

        oc = new ObjectCache( Object.class );
        assertEquals( "Size must be at default of UNLIMITED.",
            oc.UNLIMITED_SIZE, oc.getMaxSize() );
        assertEquals( "Underflows must be at zero.",
            0, oc.getUnderflows() );
        assertEquals( "Overflows must be at zero.",
            0, oc.getOverflows() );
        
        oc = new ObjectCache( Object.class, 10 );
        assertEquals( "Size must be at specified size.",
            10, oc.getMaxSize() );
        assertEquals( "Underflows must be at zero.",
            0, oc.getUnderflows() );
        assertEquals( "Overflows must be at zero.",
            0, oc.getOverflows() );
        
        oc = new ObjectCache( new OCreator() );
        assertEquals( "Size must be at default of UNLIMITED.",
            oc.UNLIMITED_SIZE, oc.getMaxSize() );
        assertEquals( "Underflows must be at zero.",
            0, oc.getUnderflows() );
        assertEquals( "Overflows must be at zero.",
            0, oc.getOverflows() );
        
        oc = new ObjectCache( new OCreator(), 10 );
        assertEquals( "Size must be at specified size.",
            10, oc.getMaxSize() );
        assertEquals( "Underflows must be at zero.",
            0, oc.getUnderflows() );
        assertEquals( "Overflows must be at zero.",
            0, oc.getOverflows() );
    }
    
    
    public void testSimpleAdd() throws InterruptedException
    {
        ObjectCache oc = new ObjectCache();
        Object o1 = new Object();
        // this test only works because we didn't specify a creator
        assertTrue( "Cache should be empty after creation.", oc.get() == null );
        oc.putBack( o1 );
        Object o2 = oc.get();
        assertEquals( "What gets put in, needs to equal what gets put out.",
            o1, o2 );
        // this test only works because we didn't specify a creator
        assertTrue( "Cache should be empty after removing.", oc.get() == null );
    }
    
    public void testClassCreator()
    {
        ObjectCache oc = new ObjectCache( Object.class );
        Object o1 = oc.get();
        assertNotNull( "Cache should have created an entry.", o1 );
        assertEquals( "Cache should have created an Object.",
            Object.class, o1.getClass() );
    }
    
    public void testObjectCreator()
    {
        ObjectCache oc = new ObjectCache( new OCreator() );
        Object o1 = oc.get();
        assertNotNull( "Cache should have created an entry.", o1 );
        assertEquals( "Cache should have created a String.",
            String.class, o1.getClass() );
    }
    
    public void testFill()
    {
        OCreator creator = new OCreator();
        ObjectCache oc = new ObjectCache( creator, 5, true );
        assertEquals( "Cache did not fill itself.",
            5, creator.getCreationCount() );
        
        // empty the cache
        for (int i = 0; i < 5; i++)
        {
            Object o = oc.get();
            assertNotNull( "Cache with creator should never return null.",
                o );
        }
        
        // fill it up again
        oc.fillCache();
        assertEquals( "Cache did not fill itself.",
            10, creator.getCreationCount() );
    }
    
    public void testPutBack()
    {
        ObjectCache oc = new ObjectCache( 1 );
        Object o1 = new Object();
        Object o2 = new Object();
        oc.putBack( o1 );
        oc.putBack( o2 );
        assertEquals( "ObjectCache should have an overflow.",
            1, oc.getOverflows() );
        Object o3 = oc.get();
        assertEquals( "Cache should have returned 1st object.",
            o1, o3 );
        Object o4 = oc.get();
        assertEquals( "Cache should have returned null.",
            null, o4 );
    }
}
