/*
 * @(#)ClassRecordUTest.java
 *
 * Copyright (C) 2003 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.codecoverage.v2.datastore;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import net.sourceforge.groboutils.autodoc.v1.AutoDoc;
import net.sourceforge.groboutils.codecoverage.v2.CCCreatorUtil;
import net.sourceforge.groboutils.codecoverage.v2.IAnalysisMetaData;
import net.sourceforge.groboutils.codecoverage.v2.IAnalysisModule;


/**
 * Tests the ClassRecord class.
 *
 * @author    Matt Albrecht <a href="mailto:groboclown@users.sourceforge.net">groboclown@users.sourceforge.net</a>
 * @version   $Date: 2004/04/15 05:48:28 $
 * @since     January 22, 2003
 */
public class ClassRecordUTest extends TestCase
{
    //-------------------------------------------------------------------------
    // Standard JUnit Class-specific declarations
    
    private static final Class THIS_CLASS = ClassRecordUTest.class;
    private static final AutoDoc DOC = new AutoDoc( THIS_CLASS );
    
    public ClassRecordUTest( String name )
    {
        super( name );
    }


    //-------------------------------------------------------------------------
    // Tests
    
    
    public void testConstructor1()
    {
        try
        {
            new ClassRecord( null, 0L, null, null, null );
        }
        catch (IllegalArgumentException ex)
        {
            // test exception
        }
    }
    
    
    public void testConstructor2()
    {
        try
        {
            new ClassRecord( "A", 0L, null, null, null );
        }
        catch (IllegalArgumentException ex)
        {
            // test exception
        }
    }
    
    
    public void testConstructor3()
    {
        try
        {
            new ClassRecord( null, 0L, null, new String[0], null );
        }
        catch (IllegalArgumentException ex)
        {
            // test exception
        }
    }
    
    
    public void testConstructor4()
    {
        try
        {
            new ClassRecord( null, 0L, null, null, createAnalysisModuleSet( 4 ) );
        }
        catch (IllegalArgumentException ex)
        {
            // test exception
        }
    }
    
    
    public void testConstructor5()
    {
        try
        {
            new ClassRecord( "A", 0L, null, null, createAnalysisModuleSet( 4 ) );
        }
        catch (IllegalArgumentException ex)
        {
            // test exception
        }
    }
    
    
    public void testConstructor6()
    {
        try
        {
            new ClassRecord( null, 0L, "a", new String[0],
                createAnalysisModuleSet( 4 ) );
        }
        catch (IllegalArgumentException ex)
        {
            // test exception
        }
    }
    
    
    public void testConstructor7()
    {
        try
        {
            new ClassRecord( "A", 0L, "a", new String[1],
                createAnalysisModuleSet( 4 ) );
        }
        catch (IllegalArgumentException ex)
        {
            // test exception
        }
    }
    
    
    public void testConstructor8()
    {
        new ClassRecord( "A", 0L, "a", new String[0],
            createAnalysisModuleSet( 4 ) );
    }
    
    
    public void testConstructor9()
    {
        new ClassRecord( "A", 0L, "a", new String[] { "m()V" },
            createAnalysisModuleSet( 4 ) );
    }
    
    
    public void testConstructor10()
    {
        try
        {
            new ClassRecord( "A", 0L, "a", new String[ Short.MAX_VALUE + 1 ],
                createAnalysisModuleSet( 4 ) );
            fail( "Did not throw IllegalStateException." );
        }
        catch (IllegalStateException ex)
        {
            assertTrue(
                "Did not raise exception for the correct reason.",
                ex.getMessage().toLowerCase().
                    indexOf( "too many methods" ) >= 0 );
        }
        
    }
    
    
    public void testGetClassName1()
    {
        ClassRecord cr = new ClassRecord( "A", 0L, "a", new String[] { "m()V" },
            createAnalysisModuleSet( 4 ) );
        assertEquals(
            "Did not return correct class name.",
            "A",
            cr.getClassName() );
    }
    
    
    public void testGetClassCRC1()
    {
        ClassRecord cr = new ClassRecord( "A", 100L, "a",
            new String[] { "m()V" }, createAnalysisModuleSet( 4 ) );
        assertEquals(
            "Did not return correct class crc.",
            100L,
            cr.getClassCRC() );
    }
    
    
    public void testGetClassSignature1()
    {
        ClassRecord cr = new ClassRecord( "A", -10L, "a",
            new String[] { "m()V" }, createAnalysisModuleSet( 4 ) );
        assertEquals(
            "Did not return correct class name.",
            "A--10",
            cr.getClassSignature() );
    }
    
    
    public void testGetAnalysisModuleSet1()
    {
        ClassRecord cr = new ClassRecord( "A", -10L, "a",
            new String[] { "m()V" }, createAnalysisModuleSet( 4 ) );
        AnalysisModuleSet ams = cr.getAnalysisModuleSet();
        assertEquals(
            "Did not return the correct number of modules.",
            4,
            ams.getAnalysisModuleCount() );
    }
    
    
    public void testGetMethods1()
    {
        ClassRecord cr = new ClassRecord( "A", -10L, "a",
            new String[0], createAnalysisModuleSet( 4 ) );
        String m[] = cr.getMethods();
        assertEquals(
            "Did not return correct method set.",
            0,
            m.length );
    }
    
    
    public void testGetMethods2()
    {
        ClassRecord cr = new ClassRecord( "A", -10L, "a", new String[] {
            "m1()V", "m2()V", "m3()V" },
            createAnalysisModuleSet( 4 ) );
        String m[] = cr.getMethods();
        assertEquals(
            "Did not return correct method set length.",
            3,
            m.length );
        assertEquals(
            "Did not return correct method [0], or resorted the list.",
            "m1()V",
            m[0] );
        assertEquals(
            "Did not return correct method [1], or resorted the list.",
            "m2()V",
            m[1] );
        assertEquals(
            "Did not return correct method [2], or resorted the list.",
            "m3()V",
            m[2] );
    }
    
    
    public void testGetMethodIndex1()
    {
        ClassRecord cr = new ClassRecord( "A", -10L, "a", new String[] {
            "m1()V", "m2()V", "m3()V" },
            createAnalysisModuleSet( 4 ) );
        try
        {
            cr.getMethodIndex( null );
            fail( "Did not throw IllegalArgumentException." );
        }
        catch (IllegalArgumentException ex)
        {
            // test exception
        }
    }
    
    
    public void testGetMethodIndex2()
    {
        ClassRecord cr = new ClassRecord( "A", -10L, "a", new String[] {
            "m1()V", "m2()V", "m3()V" },
            createAnalysisModuleSet( 4 ) );
        assertEquals(
            "Did not identify unknown method as not found.",
            (short)-1,
            cr.getMethodIndex( "m0()V" ) );
    }
    
    
    public void testGetMethodIndex3()
    {
        ClassRecord cr = new ClassRecord( "A", -10L, "a", new String[] {
            "m1()V", "m2()V", "m3()V" },
            createAnalysisModuleSet( 4 ) );
        assertEquals(
            "Did not keep the original order, or couldn't find the index [0].",
            (short)0,
            cr.getMethodIndex( "m1()V" ) );
        assertEquals(
            "Did not keep the original order, or couldn't find the index [1].",
            (short)1,
            cr.getMethodIndex( "m2()V" ) );
        assertEquals(
            "Did not keep the original order, or couldn't find the index [2].",
            (short)2,
            cr.getMethodIndex( "m3()V" ) );
    }
    
    
    public void testGetMethodCount1()
    {
        ClassRecord cr = new ClassRecord( "A", -10L, "a", new String[] {
            "m1()V", "m2()V", "m3()V" },
            createAnalysisModuleSet( 4 ) );
        assertEquals(
            "Did not return correct count.",
            3,
            cr.getMethodCount() );
    }
    
    
    public void testGetMethodCount2()
    {
        ClassRecord cr = new ClassRecord( "A", -10L, "a", new String[0],
            createAnalysisModuleSet( 4 ) );
        assertEquals(
            "Did not return correct count.",
            0,
            cr.getMethodCount() );
    }
    
    
    public void testGetMethodAt1()
    {
        ClassRecord cr = new ClassRecord( "A", -10L, "a", new String[0],
            createAnalysisModuleSet( 4 ) );
        try
        {
            cr.getMethodAt( (short)0 );
            fail( "Did not throw IllegalArgumentException." );
        }
        catch (IllegalArgumentException ex)
        {
            // test exception
        }
    }
    
    
    public void testGetMethodAt2a()
    {
        ClassRecord cr = new ClassRecord( "A", -10L, "a", new String[] {
            "m1()V", "m2()V", "m3()V" },
            createAnalysisModuleSet( 4 ) );
        try
        {
            cr.getMethodAt( (short)3 );
            fail( "Did not throw IllegalArgumentException." );
        }
        catch (IllegalArgumentException ex)
        {
            // test exception
        }
    }
    
    
    public void testGetMethodAt2b()
    {
        ClassRecord cr = new ClassRecord( "A", -10L, "a", new String[] {
            "m1()V", "m2()V", "m3()V" },
            createAnalysisModuleSet( 4 ) );
        try
        {
            cr.getMethodAt( (short)-1 );
            fail( "Did not throw IllegalArgumentException." );
        }
        catch (IllegalArgumentException ex)
        {
            // test exception
        }
    }
    
    
    public void testGetMethodAt2c()
    {
        ClassRecord cr = new ClassRecord( "A", -10L, "a", new String[] {
            "m1()V", "m2()V", "m3()V" },
            createAnalysisModuleSet( 4 ) );
        try
        {
            cr.getMethodAt( (short)4 );
            fail( "Did not throw IllegalArgumentException." );
        }
        catch (IllegalArgumentException ex)
        {
            // test exception
        }
    }
    
    
    public void testGetMethodAt3()
    {
        ClassRecord cr = new ClassRecord( "A", -10L, "a", new String[] {
            "m1()V", "m2()V", "m3()V" },
            createAnalysisModuleSet( 4 ) );
        assertEquals(
            "Did not return correct method name [0].",
            "m1()V",
            cr.getMethodAt( (short)0 ) );
        assertEquals(
            "Did not return correct method name [1].",
            "m2()V",
            cr.getMethodAt( (short)1 ) );
        assertEquals(
            "Did not return correct method name [2].",
            "m3()V",
            cr.getMethodAt( (short)2 ) );
    }
    
    
    public void testAddMark1()
    {
        ClassRecord cr = new ClassRecord( "A", -10L, "a", new String[] {
            "m1()V", "m2()V", "m3()V" },
            createAnalysisModuleSet( 4 ) );
        try
        {
            cr.addMark( null );
        }
        catch (IllegalArgumentException ex)
        {
            // test exception
        }
    }
    
    
    public void testMarks1a()
    {
        AnalysisModuleSet ams = createAnalysisModuleSet( 4 );
        ClassRecord cr = new ClassRecord( "A", -10L, "a", new String[] {
            "m1()V", "m2()V", "m3()V" }, ams );
        String moduleN = ams.getAnalysisModuleAt( (short)0 ).getMeasureName();
        cr.addMark( createMarkRecord( 0, moduleN, "m0()V", 1 ) );
        MarkRecord mr[] = cr.getMarksForAnalysisModule( moduleN );
        assertEquals(
            "Mark record length is wrong.",
            1,
            mr.length );
        try
        {
            mr[0].getMethodIndex();
            fail( "Did not throw IllegalStateException." );
        }
        catch (IllegalStateException ex)
        {
            // test exception
        }
    }
    
    
    public void testMarks1b()
    {
        AnalysisModuleSet ams = createAnalysisModuleSet( 4 );
        ClassRecord cr = new ClassRecord( "A", -10L, "a", new String[] {
            "m1()V", "m2()V", "m3()V" }, ams );
        IAnalysisModule am = ams.getAnalysisModuleAt( (short)0 );
        String moduleN = am.getMeasureName();
        cr.addMark( createMarkRecord( 0, moduleN, "m0()V", 1 ) );
        MarkRecord mr[] = cr.getMarksForAnalysisModule( am );
        assertEquals(
            "Mark record length is wrong.",
            1,
            mr.length );
        try
        {
            mr[0].getMethodIndex();
            fail( "Did not throw IllegalStateException." );
        }
        catch (IllegalStateException ex)
        {
            // test exception
        }
    }
    
    
    public void testMarks2a()
    {
        AnalysisModuleSet ams = createAnalysisModuleSet( 4 );
        ClassRecord cr = new ClassRecord( "A", -10L, "a", new String[] {
            "m1()V", "m2()V", "m3()V" }, ams );
        String moduleN1 = ams.getAnalysisModuleAt( (short)0 ).getMeasureName();
        String moduleN2 = ams.getAnalysisModuleAt( (short)1 ).getMeasureName();
        cr.addMark( createMarkRecord( 0, moduleN1, "m1()V", 1 ) );
        cr.addMark( createMarkRecord( 0, moduleN2, "m1()V", 2 ) );
        MarkRecord mr[] = cr.getMarksForAnalysisModule( moduleN1 );
        assertEquals(
            "Mark record length is wrong.",
            1,
            mr.length );
        assertEquals(
            "Wrong method index.",
            (short)0,
            mr[0].getMethodIndex() );
        assertEquals(
            "Wrong mark index.",
            (short)1,
            mr[0].getMarkIndex() );
        
        mr = cr.getMarksForAnalysisModule( moduleN2 );
        assertEquals(
            "Mark record length is wrong.",
            1,
            mr.length );
        assertEquals(
            "Wrong method index.",
            (short)0,
            mr[0].getMethodIndex() );
        assertEquals(
            "Wrong mark index.",
            (short)2,
            mr[0].getMarkIndex() );
    }
    
    
    public void testMarks2b()
    {
        AnalysisModuleSet ams = createAnalysisModuleSet( 4 );
        ClassRecord cr = new ClassRecord( "A", -10L, "a", new String[] {
            "m1()V", "m2()V", "m3()V" }, ams );
        IAnalysisModule am1 = ams.getAnalysisModuleAt( (short)0 );
        IAnalysisModule am2 = ams.getAnalysisModuleAt( (short)1 );
        String moduleN1 = am1.getMeasureName();
        String moduleN2 = am2.getMeasureName();
        cr.addMark( createMarkRecord( 0, moduleN1, "m1()V", 1 ) );
        cr.addMark( createMarkRecord( 0, moduleN2, "m1()V", 2 ) );
        MarkRecord mr[] = cr.getMarksForAnalysisModule( am1 );
        assertEquals(
            "Mark record length is wrong.",
            1,
            mr.length );
        assertEquals(
            "Wrong method index.",
            (short)0,
            mr[0].getMethodIndex() );
        assertEquals(
            "Wrong mark index.",
            (short)1,
            mr[0].getMarkIndex() );
        
        mr = cr.getMarksForAnalysisModule( am2 );
        assertEquals(
            "Mark record length is wrong.",
            1,
            mr.length );
        assertEquals(
            "Wrong method index.",
            (short)0,
            mr[0].getMethodIndex() );
        assertEquals(
            "Wrong mark index.",
            (short)2,
            mr[0].getMarkIndex() );
    }
    
    
    public void testMarks3a()
    {
        AnalysisModuleSet ams = createAnalysisModuleSet( 4 );
        ClassRecord cr = new ClassRecord( "A", -10L, "a", new String[] {
            "m1()V", "m2()V", "m3()V" }, ams );
        String moduleN = ams.getAnalysisModuleAt( (short)0 ).getMeasureName();
        cr.addMark( createMarkRecord( 0, moduleN, "m1()V", 1 ) );
        cr.addMark( createMarkRecord( 1, moduleN, "m1()V", 1 ) );
        MarkRecord mr[] = cr.getMarksForAnalysisModule( moduleN );
        assertEquals(
            "Mark record length is wrong.",
            1,
            mr.length );
    }
    
    
    public void testMarks3b()
    {
        AnalysisModuleSet ams = createAnalysisModuleSet( 4 );
        ClassRecord cr = new ClassRecord( "A", -10L, "a", new String[] {
            "m1()V", "m2()V", "m3()V" }, ams );
        IAnalysisModule am = ams.getAnalysisModuleAt( (short)0 );
        String moduleN = am.getMeasureName();
        cr.addMark( createMarkRecord( 0, moduleN, "m1()V", 1 ) );
        cr.addMark( createMarkRecord( 1, moduleN, "m1()V", 1 ) );
        MarkRecord mr[] = cr.getMarksForAnalysisModule( am );
        assertEquals(
            "Mark record length is wrong.",
            1,
            mr.length );
    }
    
    
    public void testMarks4()
    {
        AnalysisModuleSet ams = createAnalysisModuleSet( 4 );
        ClassRecord cr = new ClassRecord( "A", -10L, "a", new String[] {
            "m1()V", "m2()V", "m3()V" }, ams );
        IAnalysisModule am = ams.getAnalysisModuleAt( (short)0 );
        String moduleN = am.getMeasureName();
        cr.addMark( createMarkRecord( 0, moduleN, "m1()V", 1 ) );
        MarkRecord mr1[] = cr.getMarksForAnalysisModule( moduleN );
        MarkRecord mr2[] = cr.getMarksForAnalysisModule( am );
        assertSame(
            "Marks are wrong.",
            mr1[0],
            mr2[0] );
    }
    
    
    //-------------------------------------------------------------------------
    // Helpers
    
    
    
    protected IAnalysisMetaData createAnalysisMetaData( int weight )
    {
        return CCCreatorUtil.createIAnalysisMetaData( "a", "b", (byte)weight );
    }
    
    
    protected AnalysisModuleSet createAnalysisModuleSet( int count )
    {
        return CCCreatorUtil.createAnalysisModuleSet( count );
    }
    
    
    protected MarkRecord createMarkRecord( int metaDataWeight, String am,
            String methSig, int markId )
    {
        return new MarkRecord( createAnalysisMetaData( metaDataWeight ),
            am, methSig, (short)markId, 1 );
    }
    
    
    //-------------------------------------------------------------------------
    // Standard JUnit declarations
    
    
    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 );
    }
    
    
    /**
     * 
     * @exception Exception thrown under any exceptional condition.
     */
    protected void setUp() throws Exception
    {
        super.setUp();

       
        // set ourself up
    }
    
    
    /**
     * 
     * @exception Exception thrown under any exceptional condition.
     */
    protected void tearDown() throws Exception
    {
        // tear ourself down
        
        
        super.tearDown();
    }
}

