package org.fishwife.jrugged.clocks; import static org.easymock.EasyMock.*; import static org.junit.Assert.*; import org.fishwife.jrugged.interval.DiscreteInterval; import org.junit.Before; import org.junit.Test; public class TestTimer { private HardwareClock mockClock; private Timer impl; @Before public void setUp() { mockClock = createMock(HardwareClock.class); impl = new Timer(mockClock); } @Test public void createTimer() { new Timer(); } @Test public void provideAlternativeHardwareClock() { new Timer(mockClock); } @Test public void canSetTimer() { impl.set(40000L,3000L); } @Test(expected=IllegalStateException.class) public void cannotStartTimerThanHasNotBeenSet() { expect(mockClock.getGranularity()).andReturn(1000L).anyTimes(); replay(mockClock); impl.start(); verify(mockClock); } @Test public void canStartATimerThatHasBeenSet() { expect(mockClock.getGranularity()).andReturn(1000L).anyTimes(); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(3L,4L)).anyTimes(); replay(mockClock); impl.set(40000L,3000L); impl.start(); verify(mockClock); } @Test public void cannotSetATimerWithASmallerErrorThanClockGranularity() { expect(mockClock.getGranularity()).andReturn(1000L).anyTimes(); replay(mockClock); assertFalse(impl.set(1000L, 500L)); verify(mockClock); } @Test public void hasNotElapsedIfNotStarted() { expect(mockClock.getGranularity()).andReturn(1000L).anyTimes(); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(3L,4L)).anyTimes(); replay(mockClock); impl.set(1000L,1000L); assertFalse(impl.hasElapsed()); } @Test public void hasNotElapsedIfClockHasNotTicked() { expect(mockClock.getGranularity()).andReturn(1L).anyTimes(); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(4L,6L)).anyTimes(); replay(mockClock); impl.set(1000L,100L); impl.start(); assertFalse(impl.hasElapsed()); verify(mockClock); } @Test public void hasElapsedIfCurrentClockReadingIsWithinTargetRange() { expect(mockClock.getGranularity()).andReturn(1L).anyTimes(); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(4L,5L)); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(1010L,1015L)).anyTimes(); replay(mockClock); impl.set(1000L,100L); impl.start(); assertTrue(impl.hasElapsed()); verify(mockClock); } @Test public void hasNotElapsedIfCurrentClockReadingIsNotEntirelyWithinTargetRange() { expect(mockClock.getGranularity()).andReturn(1L).anyTimes(); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(4L,5L)); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(900L,1015L)).anyTimes(); replay(mockClock); impl.set(1000L,100L); impl.start(); assertFalse(impl.hasElapsed()); verify(mockClock); } @Test public void hasElapsedIfCurrentClockReadingPartiallyExceedsTargetRange() { expect(mockClock.getGranularity()).andReturn(1L).anyTimes(); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(4L,5L)); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(1015L,2000L)).anyTimes(); replay(mockClock); impl.set(1000L,100L); impl.start(); assertTrue(impl.hasElapsed()); verify(mockClock); } @Test public void hasElapsedIfCurrentClockReadingCompletelyExceedsTargetRange() { expect(mockClock.getGranularity()).andReturn(1L).anyTimes(); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(4L,5L)); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(2000L,2015L)).anyTimes(); replay(mockClock); impl.set(1000L,100L); impl.start(); assertTrue(impl.hasElapsed()); verify(mockClock); } @Test public void isNotLateIfCurrentClockReadingIsBeforeTargetRange() { expect(mockClock.getGranularity()).andReturn(1L).anyTimes(); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(4L,5L)); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(200L,205L)).anyTimes(); replay(mockClock); impl.set(1000L,100L); impl.start(); assertFalse(impl.isLate()); verify(mockClock); } @Test public void isNotLateIfCurrentClockReadingIsPartiallyBeforeTargetRange() { expect(mockClock.getGranularity()).andReturn(1L).anyTimes(); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(4L,5L)); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(200L,1006L)).anyTimes(); replay(mockClock); impl.set(1000L,100L); impl.start(); assertFalse(impl.isLate()); verify(mockClock); } @Test public void isNotLateIfCurrentClockReadingIsWithinTargetRange() { expect(mockClock.getGranularity()).andReturn(1L).anyTimes(); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(4L,5L)); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(1005L,1006L)).anyTimes(); replay(mockClock); impl.set(1000L,100L); impl.start(); assertFalse(impl.isLate()); verify(mockClock); } @Test public void isLateIfCurrentClockReadingIsPartiallyBeyondTargetRange() { expect(mockClock.getGranularity()).andReturn(1L).anyTimes(); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(4L,5L)); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(1005L,2006L)).anyTimes(); replay(mockClock); impl.set(1000L,100L); impl.start(); assertTrue(impl.isLate()); verify(mockClock); } @Test public void isLateIfCurrentClockReadingIsCompletelyBeyondTargetRange() { expect(mockClock.getGranularity()).andReturn(1L).anyTimes(); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(4L,5L)); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(2005L,2006L)).anyTimes(); replay(mockClock); impl.set(1000L,100L); impl.start(); assertTrue(impl.isLate()); verify(mockClock); } @Test public void isNotLateIfNotStarted() { expect(mockClock.getGranularity()).andReturn(1L).anyTimes(); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(4L,5L)).anyTimes(); replay(mockClock); impl.set(1000L,100L); assertFalse(impl.isLate()); verify(mockClock); } @Test public void timeRemainingTillElapsedIsDurationIfNotStarted() { expect(mockClock.getGranularity()).andReturn(1L).anyTimes(); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(4L,5L)).anyTimes(); replay(mockClock); impl.set(1000L,100L); assertEquals(new DiscreteInterval(900L,1100L), impl.getTimeRemaining()); verify(mockClock); } @Test(expected=IllegalStateException.class) public void cannotAskForRemainingTimeIfNotSet() { expect(mockClock.getGranularity()).andReturn(1L).anyTimes(); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(4L,5L)).anyTimes(); replay(mockClock); impl.getTimeRemaining(); } @Test public void hasFullTimeRemainingIfClockHasNotTicked() { expect(mockClock.getGranularity()).andReturn(1L).anyTimes(); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(4L,5L)).anyTimes(); replay(mockClock); impl.set(1000L,100L); impl.start(); assertEquals(new DiscreteInterval(899L,1101L), impl.getTimeRemaining()); verify(mockClock); } @Test public void canComputePartialTimeRemaining() { expect(mockClock.getGranularity()).andReturn(1L).anyTimes(); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(4L,5L)); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(504L,505L)).anyTimes(); replay(mockClock); impl.set(1000L,100L); impl.start(); assertEquals(new DiscreteInterval(399L,601L), impl.getTimeRemaining()); verify(mockClock); } @Test public void hasZeroTimeRemainingIfElapsed() { expect(mockClock.getGranularity()).andReturn(1L).anyTimes(); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(4L,5L)); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(1005L,1006L)).anyTimes(); replay(mockClock); impl.set(1000L,100L); impl.start(); assertEquals(new DiscreteInterval(0L,0L), impl.getTimeRemaining()); verify(mockClock); } @Test public void canSleepUntilClockElapses() { expect(mockClock.getGranularity()).andReturn(1L).anyTimes(); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(4L,5L)); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(504L,505L)); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(704L,705L)); expect(mockClock.getNanoTime()).andReturn(new DiscreteInterval(1005L,1006L)); replay(mockClock); impl.set(1000L,100L); impl.start(); impl.waitUntilElapsed(); verify(mockClock); } }