// for a JUnit 4.4 test case, 
//    you generally import the following:

import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;

/**
 * a JUnit test class for class GameDie,
 *     developed during the CS 458 Week 9 Lab
 *     trying to use a TDD (test-driven
 *     development) approach
 *     *   first, write a test
 *     *   then, write just enough code
 *         to pass that test
 * (yes, this is a bit more extreme than
 *  test-first, writing your tests for
 *  a module and then writing the module)
 * 
 * @author Sharon Tuttle
 * @version 2016-10-19
 */

public class GameDieTest
{
    // create one or more instances
    //    of the class under test
    //    as private data fields of the
    //    testing class
    
    private GameDie die6;
    private GameDie die20;
    
    // the @Before annotation is used for
    //   a method usually named setUp;
    // *   there is only ONE of these methods
    //     per JUnit test class
    // *   this method is run once before
    //     EACH unit test method
    
    /**
     * This @Before method is run before
     *     every @Test method
     */
    
    @Before
    public void setUp() throws Exception
    {
        die6 = new GameDie(6);
        die20 = new GameDie(20);
    } 
    
    /**
     * test method for getTop
     */
    
    @Test
    public void testGetTop()
    {
        assertEquals("new die6's top should be 1",
                     1, die6.getTop());
        
        assertEquals("new die20's top should be 1",
                     1, die20.getTop());
        
        // after a roll, the die's top should
        //    change to the value of the latest
        //    roll
        
        int testDie6Roll = die6.roll();
        int testDie20Roll = die20.roll();
        
        assertEquals("roll value should be new top",
                     testDie6Roll, die6.getTop());
        
        assertEquals("roll value should be new top",
                     testDie20Roll, die20.getTop());
        
    }
    
    /**
     * test method for getNumSides
     */
    
    @Test
    public void testGetNumSides()
    {
        assertEquals("this die6's number of sides " +
                     "should be 6", 6, 
                     die6.getNumSides());
        
        assertEquals("this die20's number of sides " +
                     "should be 20", 20, 
                     die20.getNumSides());
    }
    
    /**
     * test method for roll
     */
    
    @Test
    public void testRoll()
    {
        int testRollDie6Result;
        int testRollDie20Result;
        
        for (int i=0; i<1000000; i++)
        {
            testRollDie6Result = die6.roll();
            testRollDie20Result = die20.roll();
            
            assertTrue("die6 roll must be between " +
                       "1-6 inclusive", 
                       (testRollDie6Result >= 1) &&
                       (testRollDie6Result <= 
                            die6.getNumSides()));
            
            assertTrue("die20 roll must be between " +
                       "1-20 inclusive", 
                       (testRollDie20Result >= 1) &&
                       (testRollDie20Result <= 
                            die20.getNumSides()));
        }
    }
    
    /**
     * test method for getNumRolls
     */
    
    @Test
    public void testGetNumRolls()
    {
        // before any rolls, number of rolls
        //    had BETTER be 0!
        
        assertEquals("newly created die6 should " +
                     "have been rolled 0 times",
                     0, die6.getNumRolls());
        
        assertEquals("newly created die20 should " +
                     "have been rolled 0 times",
                     0, die20.getNumRolls());
        
        // if I roll a die, are the number
        //   of rolls counted correctly?
        
        for (int i=0; i<500; i++)
        {
            die6.roll();
            die20.roll();
        }
        die20.roll();
        
        assertEquals("500-times-rolled die6 should " +
                     "have been rolled 500 times",
                     500, die6.getNumRolls());
        
        assertEquals("501-times-rolled die20 should " +
                     "have been rolled 501 times",
                     501, die20.getNumRolls());
    }
    
}