/** * Copyright (c) 2014 - 2017 Frank Appel * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Frank Appel - initial API and implementation */ package com.codeaffine.eclipse.swt.util; import static com.codeaffine.test.util.lang.ThrowableCaptor.thrownBy; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import org.eclipse.swt.widgets.Shell; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import com.codeaffine.eclipse.swt.test.util.DisplayHelper; import com.codeaffine.eclipse.swt.test.util.SWTIgnoreConditions.CocoaPlatform; import com.codeaffine.eclipse.swt.util.ReadAndDispatch.ProblemHandler; import com.codeaffine.test.util.junit.ConditionalIgnoreRule; import com.codeaffine.test.util.junit.ConditionalIgnoreRule.ConditionalIgnore; public class ReadAndDispatchTest { private static final int DURATION = 10; private static final int SCHEDULE = 10; @Rule public final DisplayHelper displayHelper = new DisplayHelper(); @Rule public final ConditionalIgnoreRule conditionalIgnore = new ConditionalIgnoreRule(); private Shell shell; @Before public void setUp() { shell = openShell(); } @Test public void spinLoop() { ReadAndDispatch readAndDispatch = new ReadAndDispatch(); displayHelper.getDisplay().timerExec( SCHEDULE, () -> shell.dispose() ); readAndDispatch.spinLoop( shell ); assertThat( shell.isDisposed() ).isTrue(); } @Test public void spinLoopWithDuration() { ReadAndDispatch readAndDispatch = new ReadAndDispatch(); long start = System.currentTimeMillis(); readAndDispatch.spinLoop( shell, DURATION ); long actual = System.currentTimeMillis() - start; assertThat( actual ).isGreaterThanOrEqualTo( DURATION ); } @Test public void spinLoopWithProblem() { ReadAndDispatch readAndDispatch = new ReadAndDispatch(); RuntimeException expected = new RuntimeException(); displayHelper.getDisplay().timerExec( SCHEDULE, () -> { throw expected; } ); Throwable actual = thrownBy( () -> readAndDispatch.spinLoop( shell ) ); assertThat( actual ).isSameAs( expected ); } @Test public void spinLoopWithProblemHandler() { ProblemHandler problemHandler = mock( ProblemHandler.class ); RuntimeException expected = new RuntimeException(); ReadAndDispatch readAndDispatch = new ReadAndDispatch( problemHandler ); displayHelper.getDisplay().timerExec( SCHEDULE, () -> { throw expected; } ); readAndDispatch.spinLoop( shell, SCHEDULE * 2 ); verify( problemHandler ).handle( shell, expected ); } @Test @ConditionalIgnore(condition = CocoaPlatform.class) public void openErrorDialog() { Shell problemShell = displayHelper.createShell(); boolean[] wasOpened = new boolean[ 1 ]; displayHelper.getDisplay().timerExec( SCHEDULE, () -> captureOpenStateAndClose( problemShell, wasOpened ) ); ReadAndDispatch.openErrorDialog( problemShell, new RuntimeException() ); assertThat( wasOpened[ 0 ] ).isTrue(); assertThat( problemShell.isDisposed() ).isTrue(); } @Test( expected = IllegalArgumentException.class ) public void constructorWithNullAsProblemHandler() { new ReadAndDispatch( null ); } @Test( expected = IllegalArgumentException.class ) public void openErrorDialogWithNullAsShell() { ReadAndDispatch.openErrorDialog( null, new RuntimeException() ); } @Test( expected = IllegalArgumentException.class ) public void openErrorDialogWithNullAsProblem() { ReadAndDispatch.openErrorDialog( shell, null ); } private Shell openShell() { Shell result = displayHelper.createShell(); result.open(); return result; } private static void captureOpenStateAndClose( Shell problemShell, boolean[] problemShellOpened ) { captureDisposeState( problemShell, problemShellOpened ); problemShell.close(); } private static boolean captureDisposeState( Shell shell, boolean[] isOpen ) { return isOpen[ 0 ] = !shell.isDisposed(); } }