/* * Copyright 2010 The Rabbit Eclipse Plug-in Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package rabbit.tracking.internal; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.sameInstance; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Shell; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.lang.reflect.Field; import java.util.Observable; import java.util.Observer; import java.util.concurrent.ScheduledThreadPoolExecutor; /** * @see IdleDetector */ public class IdleDetectorTest { /** * Helper observer for testing. */ private static class ObserverTester implements Observer { private int activeCount = 0; private int inactiveCount = 0; @Override public synchronized void update(Observable o, Object arg) { IdleDetector detect = (IdleDetector) o; if (detect.isUserActive()) { activeCount++; } else { inactiveCount++; } } } private Display display; private Shell shell; @After public void after() { shell.dispose(); display.dispose(); } @Before public void before() { display = new Display(); shell = new Shell(display); } @Test public void shouldBeAbleToDetectThatTheUserHasReturnedToActiveByPressingAKey() throws Exception { long idleInterval = 50; long runDelay = 10; IdleDetector d = create(display, idleInterval, runDelay); d.setRunning(true); Thread.sleep((idleInterval + runDelay) * 2); assertThat(d.isUserActive(), is(false)); shell.notifyListeners(SWT.KeyDown, new Event()); assertThat(d.isUserActive(), is(true)); } @Test public void observersShouldBeNotifiedWhenTheUserReturnsToActiveByPressingAKey() throws Exception { long idleInterval = 100; long runDelay = 10; IdleDetector d = new IdleDetector(display, idleInterval, runDelay); ObserverTester ob = new ObserverTester(); d.addObserver(ob); d.setRunning(true); Thread.sleep(idleInterval + (runDelay * 2)); Thread.sleep(idleInterval + (runDelay * 2)); assertFalse(d.isUserActive()); shell.notifyListeners(SWT.KeyDown, new Event()); shell.notifyListeners(SWT.KeyDown, new Event()); assertEquals(1, ob.inactiveCount); assertEquals(1, ob.activeCount); } @Test public void shouldBeAbleToDetectThatTheUserHasReturnedToActiveByClickingTheMouse() throws Exception { long idleInterval = 500; long runDelay = 10; IdleDetector d = new IdleDetector(display, idleInterval, runDelay); d.setRunning(true); Thread.sleep(idleInterval + (runDelay * 2)); assertFalse(d.isUserActive()); shell.notifyListeners(SWT.MouseDown, new Event()); assertTrue(d.isUserActive()); } @Test public void observersShouldBeNotifiedWhenTheUserReturnsToActiveByClickingTheMouse() throws Exception { long idleInterval = 500; long runDelay = 10; IdleDetector d = new IdleDetector(display, idleInterval, runDelay); ObserverTester ob = new ObserverTester(); d.addObserver(ob); d.setRunning(true); Thread.sleep(idleInterval + (runDelay * 2)); Thread.sleep(idleInterval + (runDelay * 2)); assertFalse(d.isUserActive()); shell.notifyListeners(SWT.MouseDown, new Event()); shell.notifyListeners(SWT.MouseDown, new Event()); shell.notifyListeners(SWT.MouseDown, new Event()); assertEquals(1, ob.inactiveCount); assertEquals(1, ob.activeCount); } @Test public void observersShouldNotBeNotifiedWhenTheUserIsActive() throws Exception { long idleInterval = 50; long runDelay = 10; IdleDetector d = new IdleDetector(display, idleInterval, runDelay); ObserverTester ob = new ObserverTester(); d.addObserver(ob); d.setRunning(true); Thread.sleep(idleInterval / 2); assertTrue(d.isUserActive()); shell.notifyListeners(SWT.MouseDown, new Event()); Thread.sleep(idleInterval / 2); assertTrue(d.isUserActive()); shell.notifyListeners(SWT.MouseDown, new Event()); Thread.sleep(idleInterval / 2); assertTrue(d.isUserActive()); shell.notifyListeners(SWT.MouseDown, new Event()); assertEquals(0, ob.inactiveCount); assertEquals(0, ob.activeCount); } @Test(expected = NullPointerException.class) public void shouldThrowNullPointerExceptionIfConstructedWithoutADisplay() { new IdleDetector(null, 10, 10); } @Test(expected = IllegalArgumentException.class) public void shouldThrowIllegalArgumentExceptionIfConstructedWithANegativeDelay() { new IdleDetector(display, 10, -1); } @Test(expected = IllegalArgumentException.class) public void shouldThrowIllegalArgumentExceptionIfConstructedWithANegativeInterval() { new IdleDetector(display, -1, 10); } @Test public void shouldDoNothingAfterTheDisplayHasBeenDisposed() { IdleDetector d = new IdleDetector(display, 10, 10); display.dispose(); try { d.setRunning(true); d.setRunning(false); } catch (Exception e) { fail(); } } @Test public void shouldReturnTheDisplay() { Display actualDisplay = create(display, 1, 1).getDisplay(); assertThat(actualDisplay, sameInstance(display)); } @Test public void shouldReturnTheIdleInterval() { long expected = 1936l; long actual = create(display, expected, 1).getIdleInterval(); assertThat(actual, is(expected)); } @Test public void shouldReturnTheDelay() { long expectedDelay = 1231; long actualDelay = create(display, 101010, expectedDelay).getRunDelay(); assertThat(actualDelay, is(expectedDelay)); } @Test public void shouldNotBeRunningWhenFirstConstructed() { assertThat(create(display, 10, 10).isRunning(), is(false)); } private IdleDetector create(Display display, long idleTime, long delay) { return new IdleDetector(display, idleTime, delay); } @Test public void theUserShouldBeActiveWhenTheIdleDetectorIsFirstConstructed() { assertTrue(new IdleDetector(display, 10, 10).isUserActive()); } @Test public void shouldNotNotifyAnyObserversIfNotEnabled() throws Exception { // IdleDetector is not running, so no observers should be notified long idleInterval = 500; long runDelay = 10; IdleDetector d = new IdleDetector(display, idleInterval, runDelay); ObserverTester ob = new ObserverTester(); d.addObserver(ob); d.setRunning(false); Thread.sleep(idleInterval + (runDelay * 2)); Thread.sleep(idleInterval + (runDelay * 2)); shell.notifyListeners(SWT.KeyDown, new Event()); shell.notifyListeners(SWT.MouseDown, new Event()); assertEquals(0, ob.inactiveCount); assertEquals(0, ob.activeCount); } @Test public void testSetRunning() { IdleDetector d = new IdleDetector(display, 100, 100); assertFalse(d.isRunning()); try { d.setRunning(false); d.setRunning(false); } catch (Exception e) { fail(); } try { d.setRunning(true); d.setRunning(true); } catch (Exception e) { fail(); } d.setRunning(true); assertTrue(d.isRunning()); try { assertFalse(getTimer(d).isShutdown()); } catch (Exception e) { fail(); } d.setRunning(false); assertFalse(d.isRunning()); try { assertTrue(getTimer(d).isShutdown()); } catch (Exception e) { fail(); } } private ScheduledThreadPoolExecutor getTimer(IdleDetector d) throws Exception { Field field = d.getClass().getDeclaredField("timer"); field.setAccessible(true); return (ScheduledThreadPoolExecutor) field.get(d); } }