package org.jactr.eclipse.test;
import static java.util.Arrays.asList;
import java.util.Collection;
import java.util.LinkedList;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
/**
* A rule to set up and tear down test cases for SWT widgets.
*
* Based on https://gist.github.com/fappel/9207164
*
*/
public class DisplayHelper implements TestRule {
private final Collection<Shell> capturedShells;
private boolean displayOwner;
private Display display;
public DisplayHelper() {
capturedShells = new LinkedList<>();
capturedShells.addAll( asList( captureShells() ) );
}
public Display getDisplay() {
if( display == null ) {
displayOwner = Display.getCurrent() == null;
display = Display.getDefault();
}
return display;
}
public Shell[] getNewShells() {
Collection<Shell> newShells = new LinkedList<>();
Shell[] shells = captureShells();
for( Shell shell : shells ) {
if( !capturedShells.contains( shell ) ) {
newShells.add( shell );
}
}
return newShells.toArray(new Shell[0]);
}
public Shell createShell() {
return createShell( SWT.NONE );
}
public Shell createShell( int style ) {
return new Shell( getDisplay(), style );
}
public void ensureDisplay() {
getDisplay();
}
public void flushPendingEvents() {
while( Display.getCurrent() != null
&& !Display.getCurrent().isDisposed()
&& Display.getCurrent().readAndDispatch() ) {}
}
public void dispose() {
flushPendingEvents();
disposeNewShells();
disposeDisplay();
}
public Statement apply( final Statement base, Description description ) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
try {
base.evaluate();
} finally {
dispose();
}
}
};
}
private void disposeNewShells() {
Shell[] newShells = getNewShells();
for( Shell shell : newShells ) {
shell.dispose();
}
}
private static Shell[] captureShells() {
Shell[] result = new Shell[ 0 ];
Display currentDisplay = Display.getCurrent();
if( currentDisplay != null ) {
result = currentDisplay.getShells();
}
return result;
}
private void disposeDisplay() {
if( display != null && displayOwner ) {
if( display.isDisposed() ) {
display.dispose();
}
display = null;
}
}
}