/*******************************************************************************
* Copyright Technophobia Ltd 2012
*
* This file is part of the Substeps Eclipse Plugin.
*
* The Substeps Eclipse Plugin is free software: you can redistribute it and/or modify
* it under the terms of the Eclipse Public License v1.0.
*
* The Substeps Eclipse Plugin is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Eclipse Public License for more details.
*
* You should have received a copy of the Eclipse Public License
* along with the Substeps Eclipse Plugin. If not, see <http://www.eclipse.org/legal/epl-v10.html>.
******************************************************************************/
package com.technophobia.substeps.junit.ui;
import java.io.File;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.ILaunchesListener2;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import com.technophobia.eclipse.launcher.config.SubstepsLaunchConfigurationConstants;
import com.technophobia.eclipse.transformer.Callback1;
import com.technophobia.substeps.FeatureRunnerPlugin;
import com.technophobia.substeps.model.RemoteTestRunnerClient;
import com.technophobia.substeps.model.SubstepsRunListener;
import com.technophobia.substeps.model.SubstepsSessionListener;
import com.technophobia.substeps.model.TestRunListenerAdapter;
import com.technophobia.substeps.model.serialize.SubstepsModelExporter;
import com.technophobia.substeps.model.structure.IncompleteParentItem;
import com.technophobia.substeps.model.structure.LinkedParentItemManager;
import com.technophobia.substeps.model.structure.PredicatedLinkedParentItemManager;
import com.technophobia.substeps.model.structure.Result;
import com.technophobia.substeps.model.structure.Status;
import com.technophobia.substeps.model.structure.SubstepsTestElement;
import com.technophobia.substeps.model.structure.SubstepsTestElementFactory;
import com.technophobia.substeps.model.structure.SubstepsTestLeafElement;
import com.technophobia.substeps.model.structure.SubstepsTestParentElement;
import com.technophobia.substeps.model.structure.SubstepsTestRootElement;
import com.technophobia.substeps.supplier.Supplier;
import com.technophobia.substeps.supplier.Transformer;
public class SubstepsRunSessionImpl implements SubstepsRunSession, TestRunStats {
/**
* The launch, or <code>null</code> iff this session was run externally.
*/
private final ILaunch launch;
private final String testRunName;
/**
* Java project, or <code>null</code>.
*/
private final IJavaProject project;
private final String testRunnerKind;
/**
* Test runner client or <code>null</code>.
*/
private RemoteTestRunnerClient testRunnerClient;
private final ListenerList sessionListeners;
/**
* The model root, or <code>null</code> if swapped to disk.
*/
private SubstepsTestRootElement testRoot;
/**
* The test run session's cached result, or <code>null</code> if
* <code>fTestRoot != null</code>.
*/
private Result testResult;
/**
* Map from testId to testElement.
*/
private HashMap<String, SubstepsTestElement> idToTest;
/**
* The Parent items for which additional children are expected.
*/
private final LinkedParentItemManager<IncompleteParentItem> incompleteParentItems;
/**
* Suite for unrooted test case elements, or <code>null</code>.
*/
private SubstepsTestParentElement unrootedSuite;
/**
* Number of tests started during this test run.
*/
volatile int startedCount;
/**
* Number of tests ignored during this test run.
*/
volatile int ignoredCount;
/**
* Number of errors during this test run.
*/
volatile int errorCount;
/**
* Number of failures during this test run.
*/
volatile int failureCount;
/**
* Total number of tests to run.
*/
volatile int totalCount;
/**
* <ul>
* <li>If > 0: Start time in millis</li>
* <li>If < 0: Unique identifier for imported test run</li>
* <li>If = 0: Session not started yet</li>
* </ul>
*/
volatile long startTime;
volatile boolean isRunning;
volatile boolean fIsStopped;
private final SubstepsTestElementFactory testElementFactory;
/**
* Creates a test run session.
*
* @param testRunName
* name of the test run
* @param project
* may be <code>null</code>
*/
public SubstepsRunSessionImpl(final String testRunName, final SubstepsTestElementFactory testElementFactory,
final IJavaProject project) {
// TODO: check assumptions about non-null fields
this.testElementFactory = testElementFactory;
this.launch = null;
this.project = project;
this.startTime = -System.currentTimeMillis();
Assert.isNotNull(testRunName);
this.testRunName = testRunName;
testRunnerKind = null;
testRoot = new SubstepsTestRootElement(this);
idToTest = new HashMap<String, SubstepsTestElement>();
this.incompleteParentItems = new PredicatedLinkedParentItemManager<IncompleteParentItem>(testRootSupplier(),
decrementRemainingChildItemsCallback(), checkRemainingChildItemsPredicate());
testRunnerClient = null;
sessionListeners = new ListenerList();
}
public SubstepsRunSessionImpl(final ILaunch launch, final SubstepsTestElementFactory testElementFactory,
final IJavaProject project, final int port) {
this.testElementFactory = testElementFactory;
Assert.isNotNull(launch);
this.launch = launch;
this.project = project;
final ILaunchConfiguration launchConfiguration = launch.getLaunchConfiguration();
if (launchConfiguration != null) {
testRunName = launchConfiguration.getName();
testRunnerKind = testRunnerKind(launchConfiguration);
} else {
testRunName = project.getElementName();
testRunnerKind = null;
}
testRoot = new SubstepsTestRootElement(this);
idToTest = new HashMap<String, SubstepsTestElement>();
this.incompleteParentItems = new PredicatedLinkedParentItemManager<IncompleteParentItem>(testRootSupplier(),
decrementRemainingChildItemsCallback(), checkRemainingChildItemsPredicate());
testRunnerClient = new RemoteTestRunnerClient();
testRunnerClient.startListening(new SubstepsRunListener[] { new TestSessionNotifier() }, port);
final ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
launchManager.addLaunchListener(new ILaunchesListener2() {
@Override
public void launchesTerminated(final ILaunch[] launches) {
if (Arrays.asList(launches).contains(launch)) {
if (testRunnerClient != null) {
testRunnerClient.stopWaiting();
}
launchManager.removeLaunchListener(this);
}
}
@Override
public void launchesRemoved(final ILaunch[] launches) {
if (Arrays.asList(launches).contains(launch)) {
if (testRunnerClient != null) {
testRunnerClient.stopWaiting();
}
launchManager.removeLaunchListener(this);
}
}
@Override
public void launchesChanged(final ILaunch[] launches) {
// No-op
}
@Override
public void launchesAdded(final ILaunch[] launches) {
// No-op
}
});
sessionListeners = new ListenerList();
addTestSessionListener(new TestRunListenerAdapter(this));
}
private String testRunnerKind(final ILaunchConfiguration launchConfiguration) {
try {
return launchConfiguration.getAttribute(SubstepsLaunchConfigurationConstants.ATTR_TEST_RUNNER_KIND,
(String) null);
} catch (final CoreException e) {
return null;
}
}
@Override
public void reset() {
startedCount = 0;
failureCount = 0;
errorCount = 0;
ignoredCount = 0;
totalCount = 0;
testRoot = new SubstepsTestRootElement(this);
testResult = null;
idToTest = new HashMap<String, SubstepsTestElement>();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jdt.junit.model.ITestElement#getTestResult(boolean)
*/
@Override
public Result getTestResult(final boolean includeChildren) {
if (testRoot != null) {
return testRoot.getTestResult(true);
}
return testResult;
}
@Override
public int getChildCount() {
return getTestRoot().getChildCount();
}
@Override
public SubstepsTestElement[] getChildren() {
return getTestRoot().getChildren();
}
@Override
public FailureTrace getFailureTrace() {
return null;
}
@Override
public SubstepsRunSession getSubstepsRunSession() {
return this;
}
@Override
public synchronized SubstepsTestRootElement getTestRoot() {
swapIn(); // TODO: TestRoot should stay (e.g. for
// getTestRoot().getStatus())
return testRoot;
}
/*
* @see org.eclipse.jdt.junit.model.ITestRunSession#getJavaProject()
*/
@Override
public IJavaProject getLaunchedProject() {
return project;
}
@Override
public String getTestRunnerKind() {
return testRunnerKind;
}
/**
* @return the launch, or <code>null</code> iff this session was run
* externally
*/
@Override
public ILaunch getLaunch() {
return launch;
}
@Override
public String getTestRunName() {
return testRunName;
}
@Override
public int getErrorCount() {
return errorCount;
}
@Override
public int getFailureCount() {
return failureCount;
}
@Override
public int getStartedCount() {
return startedCount;
}
@Override
public int getIgnoredCount() {
return ignoredCount;
}
@Override
public int getTotalCount() {
return totalCount;
}
@Override
public long getStartTime() {
return startTime;
}
@Override
public TestRunState getState() {
if (isRunning()) {
return TestRunState.IN_PROGRESS;
} else if (isStopped()) {
return TestRunState.STOPPED;
}
return TestRunState.COMPLETE;
}
@Override
public boolean hasErrorsOrFailures() {
return getFailureCount() > 0 || getErrorCount() > 0;
}
/**
* @return <code>true</code> iff the session has been stopped or terminated
*/
@Override
public boolean isStopped() {
return fIsStopped;
}
@Override
public synchronized void addTestSessionListener(final SubstepsSessionListener listener) {
swapIn();
sessionListeners.add(listener);
}
@Override
public void removeTestSessionListener(final SubstepsSessionListener listener) {
sessionListeners.remove(listener);
}
@Override
public synchronized void swapOut() {
if (testRoot == null)
return;
if (isRunning() || isStarting() || isKeptAlive())
return;
final Object[] listeners = sessionListeners.getListeners();
for (int i = 0; i < listeners.length; ++i) {
final SubstepsSessionListener registered = (SubstepsSessionListener) listeners[i];
if (!registered.acceptsSwapToDisk())
return;
}
try {
final File swapFile = getSwapFile();
SubstepsModelExporter.exportTestRunSession(this, swapFile);
testResult = testRoot.getTestResult(true);
testRoot = null;
testRunnerClient = null;
idToTest = new HashMap<String, SubstepsTestElement>();
incompleteParentItems.reset();
unrootedSuite = null;
} catch (final IllegalStateException e) {
FeatureRunnerPlugin.log(e);
} catch (final CoreException e) {
FeatureRunnerPlugin.log(e);
}
}
@Override
public boolean isStarting() {
return getStartTime() == 0 && launch != null && !launch.isTerminated();
}
@Override
public void removeSwapFile() {
final File swapFile = getSwapFile();
if (swapFile.exists())
swapFile.delete();
}
private File getSwapFile() throws IllegalStateException {
final File historyDir = FeatureRunnerPlugin.instance().getHistoryDirectory();
final String isoTime = new SimpleDateFormat("yyyyMMdd-HHmmss.SSS").format(new Date(getStartTime())); //$NON-NLS-1$
final String swapFileName = isoTime + ".xml"; //$NON-NLS-1$
return new File(historyDir, swapFileName);
}
public synchronized void swapIn() {
if (testRoot != null)
return;
// throw new UnsupportedOperationException("Import from disk not supported");
/*
* try { JUnitModel.importIntoTestRunSession(getSwapFile(), this); }
* catch (final IllegalStateException e) { JUnitCorePlugin.log(e);
* testRoot = new SubstepsTestRootElement(this); testResult = null; }
* catch (final CoreException e) { JUnitCorePlugin.log(e); testRoot =
* new SubstepsTestRootElement(this); testResult = null; }
*/
}
@Override
public void stopTestRun() {
if (isRunning() || !isKeptAlive())
fIsStopped = true;
if (testRunnerClient != null)
testRunnerClient.stopTest();
}
/**
* @return <code>true</code> iff the runtime VM of this test session is
* still alive
*/
@Override
public boolean isKeptAlive() {
if (testRunnerClient != null && launch != null && testRunnerClient.isRunning()
&& ILaunchManager.DEBUG_MODE.equals(launch.getLaunchMode())) {
final ILaunchConfiguration config = launch.getLaunchConfiguration();
try {
return config != null
&& config.getAttribute(SubstepsLaunchConfigurationConstants.ATTR_KEEPRUNNING, false);
} catch (final CoreException e) {
return false;
}
}
return false;
}
/**
* @return <code>true</code> iff this session has been started, but not
* ended nor stopped nor terminated
*/
@Override
public boolean isRunning() {
return isRunning;
}
/**
* Reruns the given test method.
*
* @param testId
* test id
* @param className
* test class name
* @param testName
* test method name
* @param launchMode
* launch mode, see {@link ILaunchManager}
* @param buildBeforeLaunch
* whether a build should be done before launch
* @return <code>false</code> iff the rerun could not be started
* @throws CoreException
* if the launch fails
*/
@Override
public boolean rerunTest(final String testId, final String className, final String testName,
final String launchMode, final boolean buildBeforeLaunch) throws CoreException {
if (isKeptAlive()) {
final Status status = ((SubstepsTestLeafElement) getTestElement(testId)).getStatus();
if (status == Status.ERROR) {
errorCount--;
} else if (status == Status.FAILURE) {
failureCount--;
}
testRunnerClient.rerunTest(testId, className, testName);
return true;
} else if (launch != null) {
// run the selected test using the previous launch configuration
final ILaunchConfiguration launchConfiguration = launch.getLaunchConfiguration();
if (launchConfiguration != null) {
String name = className;
if (testName != null)
name += "." + testName; //$NON-NLS-1$
final String configName = MessageFormat.format(
SubstepsFeatureMessages.SubstepsFeatureTestRunnerViewPart_configName, name);
final ILaunchConfigurationWorkingCopy tmp = launchConfiguration.copy(configName);
// fix for bug: 64838 junit view run single test does not use
// correct class [JUnit]
tmp.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, className);
// reset the container
tmp.setAttribute(SubstepsLaunchConfigurationConstants.ATTR_TEST_CONTAINER, ""); //$NON-NLS-1$
if (testName != null) {
tmp.setAttribute(SubstepsLaunchConfigurationConstants.ATTR_TEST_METHOD_NAME, testName);
// String args= "-rerun "+testId;
// tmp.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS,
// args);
}
tmp.launch(launchMode, null, buildBeforeLaunch);
return true;
}
}
return false;
}
@Override
public SubstepsTestElement getTestElement(final String id) {
return idToTest.get(id);
}
private SubstepsTestElement addTreeEntry(final String treeEntry) {
final SubstepsTestElement testElement = testElementFactory
.createForTestEntryString(treeEntry, parentSupplier());
if (!incompleteParentItems.isEmpty()) {
incompleteParentItems.processOutstandingChild();
}
if (testElement instanceof SubstepsTestParentElement) {
final SubstepsTestParentElement parentElement = (SubstepsTestParentElement) testElement;
if (parentElement.getChildCount() > 0)
incompleteParentItems.addNode(new IncompleteParentItem(parentElement, parentElement.getChildCount()));
}
idToTest.put(testElement.getId(), testElement);
return testElement;
// SubstepsTestElement testElement =
// testElementFactory.createForTestEntryString(treeEntry);
// if(testElement instanceof SubstepsTestParentElement){
// SubstepsTestParentElement parent = (SubstepsTestParentElement)
// testElement;
// if(parent.getchil)
// }
//
// if (incompleteTestSuites.isEmpty()) {
// return createTestElement(testRoot, id, testName, isSuite, testCount);
// } else {
// final int suiteIndex = incompleteTestSuites.size() - 1;
// final IncompleteTestSuite openSuite =
// incompleteTestSuites.get(suiteIndex);
// openSuite.outstandingChildren--;
// if (openSuite.outstandingChildren <= 0)
// incompleteTestSuites.remove(suiteIndex);
// return createTestElement(openSuite.testSuiteElement, id, testName,
// isSuite, testCount);
// }
}
/**
* An {@link SubstepsRunListener} that listens to events from the
* {@link RemoteTestRunnerClient} and translates them into high-level model
* events (broadcasted to {@link SubstepsSessionListener}s).
*/
private class TestSessionNotifier implements SubstepsRunListener {
@Override
public void testRunStarted(final int testCount) {
incompleteParentItems.reset();
startedCount = 0;
ignoredCount = 0;
failureCount = 0;
errorCount = 0;
totalCount = testCount;
startTime = System.currentTimeMillis();
isRunning = true;
final Object[] listeners = sessionListeners.getListeners();
for (int i = 0; i < listeners.length; ++i) {
((SubstepsSessionListener) listeners[i]).sessionStarted();
}
}
@Override
public void testRunEnded(final long elapsedTime) {
isRunning = false;
final Object[] listeners = sessionListeners.getListeners();
for (int i = 0; i < listeners.length; ++i) {
((SubstepsSessionListener) listeners[i]).sessionEnded(elapsedTime);
}
}
@Override
public void testRunStopped(final long elapsedTime) {
isRunning = false;
fIsStopped = true;
final Object[] listeners = sessionListeners.getListeners();
for (int i = 0; i < listeners.length; ++i) {
((SubstepsSessionListener) listeners[i]).sessionStopped(elapsedTime);
}
}
@Override
public void testRunTerminated() {
isRunning = false;
fIsStopped = true;
final Object[] listeners = sessionListeners.getListeners();
for (int i = 0; i < listeners.length; ++i) {
((SubstepsSessionListener) listeners[i]).sessionTerminated();
}
}
@Override
public void testTreeEntry(final String description) {
final SubstepsTestElement testElement = addTreeEntry(description);
final Object[] listeners = sessionListeners.getListeners();
for (int i = 0; i < listeners.length; ++i) {
((SubstepsSessionListener) listeners[i]).testAdded(testElement);
}
}
private SubstepsTestElement createUnrootedTestElement(final String testId, final String testName) {
final SubstepsTestParentElement unrooted = getUnrootedSuite();
final SubstepsTestElement testElement = testElementFactory.createTestElement(unrooted, testId, testName,
false, 1);
final Object[] listeners = sessionListeners.getListeners();
for (int i = 0; i < listeners.length; ++i) {
((SubstepsSessionListener) listeners[i]).testAdded(testElement);
}
return testElement;
}
private SubstepsTestParentElement getUnrootedSuite() {
if (unrootedSuite == null) {
unrootedSuite = (SubstepsTestParentElement) testElementFactory.createTestElement(testRoot,
"-2", SubstepsFeatureMessages.SubstepsRunSession_unrootedTests, true, 0); //$NON-NLS-1$
}
return unrootedSuite;
}
@Override
public void testStarted(final String testId, final String testName) {
if (startedCount == 0) {
final Object[] listeners = sessionListeners.getListeners();
for (int i = 0; i < listeners.length; ++i) {
((SubstepsSessionListener) listeners[i]).runningBegins();
}
}
SubstepsTestElement testElement = getTestElement(testId);
if (testElement == null) {
testElement = createUnrootedTestElement(testId, testName);
}
if (testElement instanceof SubstepsTestLeafElement) {
final SubstepsTestLeafElement testCaseElement = (SubstepsTestLeafElement) testElement;
setStatus(testCaseElement, Status.RUNNING);
startedCount++;
final Object[] listeners = sessionListeners.getListeners();
for (int i = 0; i < listeners.length; ++i) {
((SubstepsSessionListener) listeners[i]).testStarted(testCaseElement);
}
}
}
@Override
public void testEnded(final String testId, final String testName) {
SubstepsTestElement testElement = getTestElement(testId);
if (testElement == null) {
testElement = createUnrootedTestElement(testId, testName);
}
if (testElement instanceof SubstepsTestLeafElement) {
final SubstepsTestLeafElement testCaseElement = (SubstepsTestLeafElement) testElement;
if (testName.startsWith("@Ignore: ")) {
testCaseElement.setIgnored(true);
ignoredCount++;
}
if (testCaseElement.getStatus() == Status.RUNNING)
setStatus(testCaseElement, Status.OK);
final Object[] listeners = sessionListeners.getListeners();
for (int i = 0; i < listeners.length; ++i) {
((SubstepsSessionListener) listeners[i]).testEnded(testCaseElement);
}
}
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.jdt.internal.junit.model.ITestRunListener2#testFailed
* (int, java.lang.String, java.lang.String, java.lang.String,
* java.lang.String, java.lang.String)
*/
@Override
public void testFailed(final Status status, final String testId, final String testName, final String trace,
final String expected, final String actual) {
SubstepsTestElement testElement = getTestElement(testId);
if (testElement == null) {
testElement = createUnrootedTestElement(testId, testName);
}
registerTestFailureStatus(testElement, status, trace, expected, actual);
final Object[] listeners = sessionListeners.getListeners();
for (int i = 0; i < listeners.length; ++i) {
((SubstepsSessionListener) listeners[i]).testFailed(testElement, status, trace, expected, actual);
}
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.jdt.internal.junit.model.ITestRunListener2#testReran(
* java.lang.String, java.lang.String, java.lang.String, int,
* java.lang.String, java.lang.String, java.lang.String)
*/
@Override
public void testReran(final String testId, final String className, final String testName, final Status status,
final String trace, final String expectedResult, final String actualResult) {
SubstepsTestElement testElement = getTestElement(testId);
if (testElement == null) {
testElement = createUnrootedTestElement(testId, testName);
}
if (testElement instanceof SubstepsTestLeafElement) {
final SubstepsTestLeafElement testCaseElement = (SubstepsTestLeafElement) testElement;
registerTestFailureStatus(testElement, status, trace, expectedResult, actualResult);
final Object[] listeners = sessionListeners.getListeners();
for (int i = 0; i < listeners.length; ++i) {
// TODO: post old & new status?
((SubstepsSessionListener) listeners[i]).testReran(testCaseElement, status, trace, expectedResult,
actualResult);
}
}
}
@Override
public void sessionLaunched(final SubstepsRunSession substepsRunSession) {
// TODO Auto-generated method stub
}
@Override
public void sessionStarted(final SubstepsRunSession session) {
// TODO Auto-generated method stub
}
@Override
public void sessionFinished(final SubstepsRunSession session) {
// TODO Auto-generated method stub
}
@Override
public void testCaseStarted(final SubstepsTestLeafElement testCaseElement) {
// TODO Auto-generated method stub
}
@Override
public void testCaseFinished(final SubstepsTestLeafElement testCaseElement) {
// TODO Auto-generated method stub
}
}
@Override
public void registerTestFailureStatus(final SubstepsTestElement testElement, final Status status,
final String trace, final String expected, final String actual) {
testElement.setStatus(status, trace, expected, actual);
if (status.isError()) {
errorCount++;
} else if (status.isFailure()) {
failureCount++;
}
}
@Override
public void registerTestEnded(final SubstepsTestElement testElement, final boolean completed) {
if (testElement instanceof SubstepsTestLeafElement) {
totalCount++;
if (!completed) {
return;
}
startedCount++;
if (((SubstepsTestLeafElement) testElement).isIgnored()) {
ignoredCount++;
}
if (!testElement.getStatus().isErrorOrFailure())
setStatus(testElement, Status.OK);
}
}
private void setStatus(final SubstepsTestElement testElement, final Status status) {
testElement.setStatus(status);
}
@Override
public SubstepsTestElement[] getAllFailedTestElements() {
final ArrayList<SubstepsTestElement> failures = new ArrayList<SubstepsTestElement>();
addFailures(failures, getTestRoot());
return failures.toArray(new SubstepsTestElement[failures.size()]);
}
private void addFailures(final ArrayList<SubstepsTestElement> failures, final SubstepsTestElement testElement) {
final Result result = testElement.getTestResult(true);
if (result == Result.ERROR || result == Result.FAILURE) {
failures.add(testElement);
}
if (testElement instanceof SubstepsTestParentElement) {
final SubstepsTestParentElement testSuiteElement = (SubstepsTestParentElement) testElement;
final SubstepsTestElement[] children = testSuiteElement.getChildren();
for (int i = 0; i < children.length; i++) {
addFailures(failures, children[i]);
}
}
}
private Transformer<IncompleteParentItem, Boolean> checkRemainingChildItemsPredicate() {
return new Transformer<IncompleteParentItem, Boolean>() {
@Override
public Boolean from(final IncompleteParentItem from) {
return Boolean.valueOf(!from.hasOutstandingChildren());
}
};
}
private Callback1<IncompleteParentItem> decrementRemainingChildItemsCallback() {
return new Callback1<IncompleteParentItem>() {
@Override
public void callback(final IncompleteParentItem t) {
t.decrementOutstandingChildren();
}
};
}
private Supplier<IncompleteParentItem> testRootSupplier() {
return new Supplier<IncompleteParentItem>() {
@Override
public IncompleteParentItem get() {
return new IncompleteParentItem(testRoot, testRoot.getChildCount());
}
};
}
private Supplier<SubstepsTestParentElement> parentSupplier() {
return new Supplier<SubstepsTestParentElement>() {
@Override
public SubstepsTestParentElement get() {
return incompleteParentItems.get().getParentElement();
}
};
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jdt.junit.model.ITestElement#getElapsedTimeInSeconds()
*/
@Override
public double getElapsedTimeInSeconds() {
if (testRoot == null)
return Double.NaN;
return testRoot.getElapsedTimeInSeconds();
}
@Override
public String toString() {
return testRunName + " " + DateFormat.getDateTimeInstance().format(new Date(startTime)); //$NON-NLS-1$
}
}