package junit.extensions;
import java.lang.reflect.InvocationTargetException;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import abbot.tester.swt.Robot;
/**
* Copied and changed from ForkedPDETestCase.
* <p/>
* Provides more proper Exception handling and tries to close everything cleanly
* when finished.<br/>
* For running PDE tests I encourage anyway to use ActivePDETestSuite in conjunction
* with PDETestFixture instead.
*
* @see junit.extensions.ForkedPDETestCase
* @author Richard Birenheide (D035816)
*/
/*
* To be discussed if this one could replace ForkedPDETestCase.
*/
public class ForkedPDETestCase2 extends TestCase{
protected InvocationTargetException ite = null;
protected IllegalAccessException iae = null;
protected boolean ranTest = false;
protected Display display;
protected Shell rootShell;
public ForkedPDETestCase2(){
super();
}
public ForkedPDETestCase2(String name){
super(name);
}
protected void runTest() throws Throwable {
IWorkbench iw = PlatformUI.getWorkbench();
IWorkbenchWindow iww = iw.getWorkbenchWindows()[0];
rootShell = iww.getShell();
display = rootShell.getDisplay();
// final ForkedPDETestCase2 thisTC = this;
// final Class testClass = getClass();
// final String name = getName();
ranTest = false;
Thread runTestThread = new Thread(){
public void run(){
assertNotNull(getName());
// Method runMethod= null;
// try {
// // use getMethod to get all public inherited
// // methods. getDeclaredMethods returns all
// // methods of this class but excludes the
// // inherited ones.
// runMethod= testClass.getMethod(name, null);
// } catch (NoSuchMethodException e) {
// fail("Method \""+name+"\" not found");
// }
// if (!Modifier.isPublic(runMethod.getModifiers())) {
// fail("Method \""+name+"\" should be public");
// }
try {
//runMethod.invoke(thisTC, new Class[0]);
ForkedPDETestCase2.super.runTest();
ranTest = true;
}
catch (InvocationTargetException e) {
e.fillInStackTrace();
ite = e;
}
catch (IllegalAccessException e) {
e.fillInStackTrace();
iae = e;
}
catch (Throwable t) {
ite = new InvocationTargetException(t);
}
finally {
Runnable closeChildren = new Runnable() {
public void run() {
if (!rootShell.isDisposed()) {
//Close all blocking dialogs. Necessary, otherwise the junit
//thread does not proceed.
Shell[] shells = rootShell.getShells();
for (int i = 0; i < shells.length; i++) {
if (!shells[i].isDisposed()) {
shells[i].close();
}
}
//This is in order to close cleanly any stuff (menues) which puts
//the UI thread in blocking mode.
//FIXME This is a crude workaround. Search for open menu items instead
//and close these.
Robot robot = new Robot();
for (int i = 0; i < 25; i++) {
robot.keyStroke(SWT.ESC);
}
}
}
};
display.syncExec(closeChildren);
}
}
};
runTestThread.setName(getName());
runTestThread.start();
int ctr = 0;
// run the UI loop until the test has completed or an exception has been thrown
while(!ranTest && !rootShell.isDisposed()){
// throw all caught exceptions inside the test thread
if(ite!=null)
//Since one wants a failure and not an error, if an assertion failed, extract that.
if (ite.getCause() instanceof AssertionFailedError) {
throw ite.getCause();
}
else {
throw ite;
}
if(iae!=null)
throw iae;
try {
if(!display.readAndDispatch())
display.sleep();
}
//if an assertion happened inside an #syncExec(Runnable) or #asyncExec(Runnable)
//this may lead to an SWTException thrown here. Therefore catch and rethrow
//applicable Exception.
catch (SWTException ex) {
if (ex.throwable instanceof AssertionFailedError) {
throw ex.throwable;
}
else {
throw ex;
}
}
if(ctr++%100000==0)
System.err.print(".");
}
}
}