package cal;

import junit.framework.TestCase;

/** Testing for TimeOfDay.
 * @author Gary T. Leavens
 * @version $Revision: 1.2 $
 */
public class TimeOfDayTest extends TestCase {

    /**
     * Constructor for TimeOfDayTest.
     * @param name
     */
    public TimeOfDayTest(String name) {
        super(name);
    }

    /**
     * Run the tests in the text user interface.
     */
    public static void main(String[] args) {
        junit.textui.TestRunner.run(TimeOfDayTest.class);
    }

    /** test data */
    private TimeOfDay[] receivers;

    /** Initialize the test data.
     * @see TestCase#setUp()
     */
    protected void setUp() throws Exception {
        super.setUp();
        if (receivers == null) {
            receivers =
                new TimeOfDay[] {
                    new TimeOfDay(0, 0),
                    new TimeOfDay(12, 0),
                    new TimeOfDay(11, 59),
                    new TimeOfDay(23, 59),
                    new TimeOfDay(6, 30),
                    new TimeOfDay(13, 13),
                    };
        }
    }

    /**
     * Test for the method toString()
     */
    public void testToString0() {
        assertEquals("00:00", receivers[0].toString());
    }

    /**
     * Test for the method toString()
     */
    public void testToString1() {
        assertEquals("12:00", receivers[1].toString());
    }

    /**
     * Test for the method toString()
     */
    public void testToString2() {
        assertEquals("11:59", receivers[2].toString());
    }

    /**
     * Test for the method toString()
     */
    public void testToString3() {
        assertEquals("23:59", receivers[3].toString());
    }

    /**
     * Test for the method toString()
     */
    public void testToString4() {
        assertEquals("06:30", receivers[4].toString());
    }

    /**
     * Test for the method toString()
     */
    public void testToString5() {
        assertEquals("13:13", receivers[5].toString());
    }

    /**
     * Test for the method ampmString.
     */
    public void testAmpmString0() {
        assertEquals("12:00AM", receivers[0].ampmString());
    }

    /**
     * Test for the method ampmString.
     */
    public void testAmpmString1() {
        assertEquals("12:00PM", receivers[1].ampmString());
    }

    /**
     * Test for the method ampmString.
     */
    public void testAmpmString2() {
        assertEquals("11:59AM", receivers[2].ampmString());
    }

    /**
     * Test for the method ampmString.
     */
    public void testAmpmString3() {
        assertEquals("11:59PM", receivers[3].ampmString());
    }
    /**
     * Test for the method ampmString.
     */
    public void testAmpmString4() {
        assertEquals("06:30AM", receivers[4].ampmString());
    }
    /**
     * Test for the method ampmString.
     */
    public void testAmpmString5() {
        assertEquals("01:13PM", receivers[5].ampmString());
    }

    /**
     * Test for the method hashCode.
     */
    public void testHashCode() {
        for (int i = 0; i < receivers.length; i++) {
            // make sure hashCode just runs ok,
            // can't say anything about the result
            receivers.hashCode();
        }
        assertEquals(new TimeOfDay(10,1).hashCode(),
                     TimeOfDay.am(10,1).hashCode());
    }

    /**
     * Test for the constructor TimeOfDay,
     * along with getHour, getMinutes, and minutesPastMidnight.
     */
    public void testTimeOfDay() {
        for (int h = 0; h < 24; h++) {
            for (int m = 0; m < 60; m += 5) {
                TimeOfDay t = new TimeOfDay(h, m);
                assertEquals(h, t.getHour());
                assertEquals(m, t.getMinutes());
                assertEquals(h * 60 + m, t.minutesPastMidnight());
            }
        }
    }

    /**
     * Test for the static method am.
     */
    public void testAm() {
        for (int h = 0; h < 12; h++) {
            for (int m = 0; m < 60; m += 5) {
                TimeOfDay t = TimeOfDay.am(h, m);
                assertEquals(h, t.getHour());
                assertEquals(m, t.getMinutes());
            }
        }
    }

    /**
     * Test for the static method pm.
     */
    public void testPm() {
        for (int h = 0; h < 12; h++) {
            for (int m = 0; m < 60; m += 5) {
                TimeOfDay t = TimeOfDay.pm(h, m);
                assertEquals(h + 12, t.getHour());
                assertEquals(m, t.getMinutes());
            }
        }
    }

    /**
     * Test for the method addMinutes.
     */
    public void testaddMinutes0() {
        for (int m = 0; m < 24 * 60; m = (m == 0 ? m + 1 : m * 2)) {
            for (int i = 0; i < receivers.length; i++) {
                int min = receivers[i].getMinutes();
                int hr = receivers[i].getHour();
                TimeOfDay t = receivers[i].addMinutes(m);
                assertEquals((hr + (min + m) / 60) % 24, t.getHour());
                assertEquals((min + m) % 60, t.getMinutes());
            }
        }
    }

    /**
     * Test for the method isAM.
     */
    public void testIsAM() {
        for (int i = 0; i < receivers.length; i++) {
            assertEquals(receivers[i].getHour() < 12, receivers[i].isAM());
        }
    }

    /**
     * Test for the method isPM.
     */
    public void testIsPM() {
        for (int i = 0; i < receivers.length; i++) {
            assertEquals(receivers[i].getHour() >= 12, receivers[i].isPM());
        }
    }

    /**
     * Test for the method minutesFrom.
     */
    public void testMinutesFrom() {
        for (int i = 0; i < receivers.length; i++) {
            for (int j = 0; j < receivers.length; j++) {
                if (receivers[j].compareTo(receivers[i]) <= 0) {
                    assertEquals(
                        receivers[i].minutesPastMidnight()
                            - receivers[j].minutesPastMidnight(),
                        receivers[i].minutesFrom(receivers[j]));
                }
            }
        }
    }

    /**
     * Test for the method equals.
     */
    public void testEquals() {
        for (int i = 0; i < receivers.length; i++) {
            assertFalse(receivers[i].equals(null));
            assertFalse(receivers[i].equals(new Integer(12)));
            for (int j = 0; j < receivers.length; j++) {
                assertEquals(i == j, receivers[i].equals(receivers[j]));
            }
        }
    }

    /**
     * Test for the compareTo methods.
     */
    public void testCompareTo() {
        for (int i = 0; i < receivers.length; i++) {

            boolean caughtException = false;
            try {
                receivers[i].compareTo((Object) null);
            } catch (ClassCastException e) {
                caughtException = true;
            }
            assertTrue(caughtException);

            caughtException = false;
            try {
                receivers[i].compareTo(new Integer(12));
            } catch (ClassCastException e) {
                caughtException = true;
            }
            assertTrue(caughtException);

            assertEquals(0, receivers[i].compareTo((Object) receivers[i]));
            assertEquals(0, receivers[i].compareTo(receivers[i]));

            for (int j = i + 1; j < receivers.length; j++) {
                assertEquals(
                    receivers[i].minutesPastMidnight()
                        < receivers[j].minutesPastMidnight()
                        ? -1
                        : +1,
                    receivers[i].compareTo((Object) receivers[j]));
                assertEquals(
                    receivers[i].minutesPastMidnight()
                        < receivers[j].minutesPastMidnight()
                        ? -1
                        : +1,
                    receivers[i].compareTo(receivers[j]));
            }
        }
    }
}
