carbidecpp20devenv/plugins/org.eclipse.test.source_3.3.0.v20080507/src/org.junit4_4.3.1/junitsrc/org/junit/internal/runners/TestMethodRunner.java
changeset 0 20e4ed35fd3f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carbidecpp20devenv/plugins/org.eclipse.test.source_3.3.0.v20080507/src/org.junit4_4.3.1/junitsrc/org/junit/internal/runners/TestMethodRunner.java	Fri Apr 03 17:08:57 2009 +0100
@@ -0,0 +1,119 @@
+package org.junit.internal.runners;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.runner.Description;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunNotifier;
+
+public class TestMethodRunner extends BeforeAndAfterRunner {
+	private final Object fTest;
+	private final Method fMethod;
+	private final RunNotifier fNotifier;
+	private final TestIntrospector fTestIntrospector;
+	private final Description fDescription;
+
+	public TestMethodRunner(Object test, Method method, RunNotifier notifier, Description description) {
+		super(test.getClass(), Before.class, After.class, test);
+		fTest= test;
+		fMethod= method;
+		fNotifier= notifier;
+		fTestIntrospector= new TestIntrospector(test.getClass());
+		fDescription= description;
+	}
+
+	public void run() {
+		if (fTestIntrospector.isIgnored(fMethod)) {
+			fNotifier.fireTestIgnored(fDescription);
+			return;
+		}
+		fNotifier.fireTestStarted(fDescription);
+		try {
+			long timeout= fTestIntrospector.getTimeout(fMethod);
+			if (timeout > 0)
+				runWithTimeout(timeout);
+			else
+				runMethod();
+		} finally {
+			fNotifier.fireTestFinished(fDescription);
+		}
+	}
+
+	private void runWithTimeout(long timeout) {
+		ExecutorService service= Executors.newSingleThreadExecutor();
+		Callable<Object> callable= new Callable<Object>() {
+			public Object call() throws Exception {
+				runMethod();
+				return null;
+			}
+		};
+		Future<Object> result= service.submit(callable);
+		service.shutdown();
+		try {
+			boolean terminated= service.awaitTermination(timeout,
+					TimeUnit.MILLISECONDS);
+			if (!terminated)
+				service.shutdownNow();
+			result.get(0, TimeUnit.MILLISECONDS); // throws the exception if one occurred during the invocation
+		} catch (TimeoutException e) {
+			addFailure(new Exception(String.format("test timed out after %d milliseconds", timeout)));
+		} catch (Exception e) {
+			addFailure(e);
+		}		
+	}
+	
+	private void runMethod() {
+		runProtected();
+	}
+	
+	@Override
+	protected void runUnprotected() {
+		try {
+			executeMethodBody();
+			if (expectsException())
+				addFailure(new AssertionError("Expected exception: " + expectedException().getName()));
+		} catch (InvocationTargetException e) {
+			Throwable actual= e.getTargetException();
+			if (!expectsException())
+				addFailure(actual);
+			else if (isUnexpected(actual)) {
+				String message= "Unexpected exception, expected<" + expectedException().getName() + "> but was<"
+					+ actual.getClass().getName() + ">";
+				addFailure(new Exception(message, actual));
+			}
+		} catch (Throwable e) {
+			addFailure(e);
+		}
+	}
+
+	protected void executeMethodBody() throws IllegalAccessException, InvocationTargetException {
+		fMethod.invoke(fTest);
+	}
+
+	@Override
+	protected void addFailure(Throwable e) {
+		fNotifier.fireTestFailure(new Failure(fDescription, e));
+	}
+	
+	private boolean expectsException() {
+		return expectedException() != null;
+	}
+
+	private Class<? extends Throwable> expectedException() {
+		return fTestIntrospector.expectedException(fMethod);
+	}
+
+	private boolean isUnexpected(Throwable exception) {
+		return ! expectedException().isAssignableFrom(exception.getClass());
+	}
+}
+