blob: aaa9eb2a33c1dcdd1188d176e482d3ada3b918a5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011 The University of York.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* Contributors:
* Antonio Garcia-Dominguez - initial API and implementation
******************************************************************************/
package org.eclipse.epsilon.eunit.dt.ui;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.epsilon.common.dt.extensions.ClassBasedExtension;
import org.eclipse.epsilon.common.dt.extensions.IllegalExtensionException;
import org.eclipse.epsilon.eol.exceptions.EolAssertionException;
import org.eclipse.epsilon.eol.exceptions.EolInternalException;
import org.eclipse.epsilon.eol.exceptions.EolRuntimeException;
import org.eclipse.epsilon.eol.execute.context.Frame;
import org.eclipse.epsilon.eol.execute.context.Variable;
import org.eclipse.epsilon.eunit.EUnitModule;
import org.eclipse.epsilon.eunit.EUnitTest;
import org.eclipse.epsilon.eunit.EUnitTestListener;
import org.eclipse.epsilon.eunit.EUnitTestResultType;
import org.eclipse.epsilon.eunit.dt.EUnitPlugin;
import org.eclipse.epsilon.eunit.dt.diff.IDifferenceViewer;
import org.eclipse.epsilon.eunit.dt.listener.ShowEUnitViewTestListener;
import org.eclipse.epsilon.internal.eunit.dt.diff.StringBasedDifferenceViewer;
import org.eclipse.epsilon.internal.eunit.dt.history.EUnitHistory;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ResourceLocator;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
/**
* View part for the EUnit test case runner.
*
* <p><b>Note:</b> this class implements the {@link EUnitTestListener} interface,
* but it is does <emph>not</emph> use the EUnit Ant extension point. That is the
* role of the {@link ShowEUnitViewTestListener}, which creates this view and sets
* it up. After setting it up, {@link ShowEUnitViewTestListener} delegates all
* notifications to this class.</p>
*
* @author Antonio Garc��a-Dom��nguez
* @version 1.0
*/
public class EUnitRunnerView extends ViewPart implements EUnitTestListener {
public EUnitRunnerView() {
EUnitPlugin.getDefault().setLastView(this);
}
private class CompareResultsAction extends Action {
private List<IDifferenceViewer> diffViewers = new ArrayList<>();
public CompareResultsAction() {
setText("Compare Results");
setToolTipText("Compares the expected result with the actual result");
setImageDescriptor(
EUnitPlugin.getImageDescriptor("icons/elcl16/compare.gif"));
setEnabled(false);
loadDiffViewers();
}
public void run() {
final EolAssertionException ex = getCurrentAssertionException();
if (ex == null) return;
IDifferenceViewer match = findMatchingViewer(ex);
if (match != null) {
match.compare(ex.getExpected(), ex.getActual(), ex.getDelta());
}
else {
// Normally this shouldn't be called, as the rest of the UI disables
// the "Compare" action when there are no matching difference viewers.
// However, we keep it as a safety measure.
MessageDialog.openError(getViewSite().getShell(), EUnitRunnerView.EUNIT_DIALOG_TITLE,
String.format("Could not find a difference viewer for expected=%s, actual=%s and delta=%s.",
ex.getExpected().getClass().getName(),
ex.getActual().getClass().getName(),
ex.getDelta() != null ? ex.getDelta().getClass().getName() : "null"));
}
}
private IDifferenceViewer findMatchingViewer(final EolAssertionException ex) {
for (IDifferenceViewer dv : diffViewers) {
if (dv.canCompare(ex.getExpected(), ex.getActual(), ex.getDelta())) {
return dv;
}
}
return null;
}
private void loadDiffViewers() {
try {
for (IDifferenceViewer dv :
ClassBasedExtension.getImplementations(
IDifferenceViewer.EXTENSION_POINT_ID,
IDifferenceViewer.class))
{
diffViewers.add(dv);
}
} catch (IllegalExtensionException e) {
EUnitPlugin.getDefault().logException(e);
}
// Fallback: use regular strings
diffViewers.add(new StringBasedDifferenceViewer());
}
/**
* If there's a test currently selected which failed due to an EolAssertionException for
* which differences can be visualized, returns the exception. Otherwise, returns <code>null</code>.
*/
public EolAssertionException getCurrentAssertionException() {
// Obtain the currently selected test
if (!(treeViewerTests.getSelection() instanceof IStructuredSelection)) {
return null;
}
IStructuredSelection sel = (IStructuredSelection)treeViewerTests.getSelection();
Object currentElement = sel.getFirstElement();
if (!(currentElement instanceof EUnitTest)) {
return null;
}
EUnitTest currentTest = (EUnitTest)currentElement;
// This action only works on test which have failed due to a violated assertion
final Throwable currentEx = unwrapInternalExceptionFrom(currentTest);
if (!(currentEx instanceof EolAssertionException)) {
return null;
}
EolAssertionException ex = (EolAssertionException)currentEx;
// We're only interested in the assertion exceptions which provide values and whose
// differences can be visualized
if (ex.getActual() != null && findMatchingViewer(ex) != null) {
return ex;
}
else {
return null;
}
}
private Throwable unwrapInternalExceptionFrom(EUnitTest currentTest) {
Throwable currentEx = currentTest.getException();
while (currentEx instanceof EolInternalException) {
// PointExecutor likes to wrap everything in EolInternalExceptions:
// remove all those wrapping exceptions
final EolInternalException iex = (EolInternalException)currentTest.getException();
currentEx = iex.getInternal();
}
return currentEx;
}
}
private static final String EUNIT_DIALOG_MSG_NOT_RUN_YET
= "EUnit has not been successfully launched yet: cannot rerun any suite!";
public static class RerunAllHandler extends AbstractHandler {
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
final EUnitRunnerView lastView = EUnitPlugin.getDefault().getLastView();
if (lastView != null) {
lastView.rerunCurrentLaunch(new ArrayList<EUnitTest>());
}
else {
MessageDialog.openError(Display.getDefault().getActiveShell(),
EUNIT_DIALOG_TITLE,
EUNIT_DIALOG_MSG_NOT_RUN_YET);
}
return null;
}
}
public static class RerunSameHandler extends AbstractHandler {
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
final EUnitRunnerView lastView = EUnitPlugin.getDefault().getLastView();
if (lastView != null) {
lastView.rerunCurrentLaunch(null);
}
else {
MessageDialog.openError(Display.getDefault().getActiveShell(),
EUNIT_DIALOG_TITLE,
EUNIT_DIALOG_MSG_NOT_RUN_YET);
}
return null;
}
}
public static class RerunOnlyFailedHandler extends AbstractHandler {
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
final EUnitHistory history = EUnitPlugin.getDefault().getHistory();
final ILaunch currentLaunch = history.getCurrentLaunch();
if (currentLaunch == null) {
MessageDialog.openError(Display.getDefault().getActiveShell(),
EUnitRunnerView.EUNIT_DIALOG_TITLE,
EUnitRunnerView.EUNIT_DIALOG_MSG_NOT_RUN_YET);
return null;
}
try {
final List<EUnitModule> modules = history
.getModules(currentLaunch);
final List<EUnitTest> tests = new ArrayList<>();
for (EUnitModule module : modules) {
final EUnitTest result = module.getSuiteRoot();
result.collectLeafTests(module.getSelectedOperations(),
EUnitTestResultType.ERROR, tests);
result.collectLeafTests(module.getSelectedOperations(),
EUnitTestResultType.FAILURE, tests);
}
// Note: we already checked that EUnit was run before through
// the EUnitHistory
EUnitPlugin.getDefault().getLastView()
.rerunCurrentLaunch(tests);
} catch (EolRuntimeException e) {
EUnitPlugin.getDefault().logException(e);
}
return null;
}
}
private final class JumpFromStackFrameAction extends OpenEOLEditorAction {
public void run() {
ISelection selection = treeViewerFailureTrace.getSelection();
Object obj = ((IStructuredSelection) selection).getFirstElement();
if (obj instanceof Variable) {
obj = failureTraceContentProvider.getContainingFrame((Variable)obj);
}
if (obj instanceof Frame) {
Frame frame = (Frame)obj;
if (frame.getCurrentStatement() != null) {
openInEOLEditor(frame.getCurrentStatement());
}
else if (frame.getEntryPoint() != null) {
openInEOLEditor(frame.getEntryPoint());
}
}
else if (obj instanceof EolAssertionException) {
actCompareResults.run();
}
}
}
private final class JumpFromTestAction extends OpenEOLEditorAction {
public void run() {
ISelection selection = treeViewerTests.getSelection();
Object obj = ((IStructuredSelection) selection).getFirstElement();
if (obj instanceof EUnitTest) {
EUnitTest test = (EUnitTest)obj;
if (test.getException() instanceof EolRuntimeException) {
EolRuntimeException eolEx = (EolRuntimeException)test.getException();
openInEOLEditor(eolEx.getAst());
}
else if (test.getOperation() != null) {
openInEOLEditor(test.getOperation());
}
}
}
}
private final class RerunSelectedTestCasesAction extends Action {
public RerunSelectedTestCasesAction() {
setText("Rerun These Tests");
setToolTipText("Tests the selected operations");
}
public void run() {
ISelection selection = treeViewerTests.getSelection();
if (selection instanceof IStructuredSelection) {
rerunCurrentLaunch(getSelectedTestCases(selection));
}
else {
MessageDialog.openError(
getViewSite().getShell(), EUNIT_DIALOG_TITLE, "No tests have been selected.");
}
}
private List<EUnitTest> getSelectedTestCases(ISelection selection) {
IStructuredSelection selectedTestCases = (IStructuredSelection)selection;
List<EUnitTest> testCases = new ArrayList<>();
for (Object o : selectedTestCases.toList()) {
if (o instanceof EUnitTest) {
testCases.add((EUnitTest)o);
}
}
return testCases;
}
}
private final class OnlyFailedTestsAction extends Action {
public OnlyFailedTestsAction() {
super("Show only failed tests", Action.AS_CHECK_BOX);
setToolTipText("Shows only the tests that have errors or failures");
setImageDescriptor(EUnitPlugin.getImageDescriptor("icons/obj16/failures.gif"));
}
public void run() {
showOnlyFailedTestsFilter.setEnabled(isChecked());
treeViewerTests.refresh();
}
}
private static final String EUNIT_DIALOG_TITLE = "EUnit";
/**
* The ID of the view as specified by the extension.
*/
public static final String ID = "org.eclipse.epsilon.eunit.runner.views.EUnitRunnerView";
private TreeViewer treeViewerTests;
private TreeViewer treeViewerFailureTrace;
private FailureTraceTreeLabelProvider failureTreeLabelProvider;
private FailureTraceTreeContentProvider failureTraceContentProvider;
private Label lblNErrors;
private Label lblNFailures;
private Label lblNRun;
private JUnitProgressBar barProgress;
private int nTotalTestCases;
private int nRunTestCases;
private int nErrors;
private int nFailures;
private Action actRerunSome;
private Action actJumpFromTest;
private Action actJumpFromStackFrame;
private Action actHistory;
private Action actOnlyFailedTests;
private CompareResultsAction actCompareResults;
private ShowOnlyFailedTestsViewerFilter showOnlyFailedTestsFilter;
private ToolBar toolbarFailureTrace;
/**
* This is a callback that will allow us to create the viewer and initialize
* it.
*/
public void createPartControl(Composite parent) {
final GridLayout gl_parent = new GridLayout(6, true);
gl_parent.marginHeight = 0;
gl_parent.marginWidth = 0;
gl_parent.horizontalSpacing = 0;
parent.setLayout(gl_parent);
Label lblRun = new Label(parent, SWT.NONE);
lblRun.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
lblRun.setText("Runs:");
lblNRun = new Label(parent, SWT.NONE);
GridData gd_lblNRun = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1);
gd_lblNRun.horizontalIndent = 10;
lblNRun.setLayoutData(gd_lblNRun);
lblNRun.setText("0/0");
lblNRun.setAlignment(SWT.LEFT);
Label lblFailures = new Label(parent, SWT.NONE);
lblFailures.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
lblFailures.setText("Failures:");
lblNFailures = new Label(parent, SWT.NONE);
GridData gd_lblNFailures = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
gd_lblNFailures.horizontalIndent = 10;
lblNFailures.setLayoutData(gd_lblNFailures);
lblNFailures.setText("0");
Label lblErrors = new Label(parent, SWT.NONE);
lblErrors.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
lblErrors.setText("Errors:");
lblNErrors = new Label(parent, SWT.NONE);
GridData gd_lblNErrors = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
gd_lblNErrors.horizontalIndent = 10;
lblNErrors.setLayoutData(gd_lblNErrors);
lblNErrors.setText("0");
barProgress = new JUnitProgressBar(parent);
barProgress.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 6, 1));
SashForm sashBetweenTestsAndFailures = new SashForm(parent, SWT.BORDER | SWT.SMOOTH | SWT.VERTICAL);
GridData gd_sashBetweenTestsAndFailures = new GridData(SWT.FILL, SWT.FILL, true, true, 6, 1);
gd_sashBetweenTestsAndFailures.widthHint = 593;
sashBetweenTestsAndFailures.setLayoutData(gd_sashBetweenTestsAndFailures);
treeViewerTests = new TreeViewer(sashBetweenTestsAndFailures, SWT.MULTI);
treeViewerTests.setContentProvider(new TestTreeContentProvider(getViewSite()));
Composite failureTraceComposite = new Composite(sashBetweenTestsAndFailures, SWT.NONE);
GridLayout gl_composite = new GridLayout(2, false);
gl_composite.marginTop = 0;
gl_composite.marginWidth = 0;
gl_composite.marginHeight = 0;
gl_composite.horizontalSpacing = 0;
failureTraceComposite.setLayout(gl_composite);
CLabel lblFailureTrace = new CLabel(failureTraceComposite, SWT.NONE);
lblFailureTrace.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
lblFailureTrace.setText("Failure Trace");
lblFailureTrace.setImage(
ResourceLocator.imageDescriptorFromBundle(EUnitPlugin.PLUGIN_ID, "icons/eview16/stackframe.gif")
.map(ImageDescriptor::createImage).orElse(null)
);
toolbarFailureTrace = new ToolBar(failureTraceComposite, SWT.FLAT);
toolbarFailureTrace.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
treeViewerFailureTrace = new TreeViewer(failureTraceComposite, SWT.SINGLE);
Tree treeFailureTrace = treeViewerFailureTrace.getTree();
treeFailureTrace.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
showOnlyFailedTestsFilter = new ShowOnlyFailedTestsViewerFilter();
failureTraceContentProvider = new FailureTraceTreeContentProvider(getViewSite());
failureTreeLabelProvider = new FailureTraceTreeLabelProvider();
treeViewerFailureTrace.setContentProvider(failureTraceContentProvider);
treeViewerFailureTrace.setLabelProvider(failureTreeLabelProvider);
treeViewerTests.setContentProvider(new TestTreeContentProvider(getViewSite()));
treeViewerTests.setLabelProvider(new TestTreeLabelProvider());
treeViewerTests.addFilter(new DiscardSkippedTestsViewerFilter());
treeViewerTests.addFilter(showOnlyFailedTestsFilter);
sashBetweenTestsAndFailures.setWeights(new int[] {1, 1});
// Create the help context id for the viewer's control
PlatformUI
.getWorkbench()
.getHelpSystem()
.setHelp(treeViewerTests.getControl(),
"org.eclipse.epsilon.eunit.runner.viewer");
makeActions();
hookContextMenuForTests();
hookContextMenuForStackFrames();
hookClickAction();
hookDoubleClickAction();
contributeToActionBars();
}
private void hookContextMenuForStackFrames() {
hookContextMenu("#FramePopupMenu", new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
EUnitRunnerView.this.fillContextMenuForStackFrames(manager);
}
}, treeViewerFailureTrace);
}
private void hookContextMenuForTests() {
hookContextMenu("#TestPopupMenu", new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
EUnitRunnerView.this.fillContextMenuForTests(manager);
}
}, treeViewerTests);
}
private void hookContextMenu(final String menuManagerName,
final IMenuListener menuListener, final Viewer component) {
MenuManager menuMgr = new MenuManager(menuManagerName);
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(menuListener);
Menu menu = menuMgr.createContextMenu(component.getControl());
component.getControl().setMenu(menu);
getSite().registerContextMenu(menuMgr, component);
}
private void contributeToActionBars() {
IActionBars bars = getViewSite().getActionBars();
fillLocalPullDown(bars.getMenuManager());
fillLocalToolBar(bars.getToolBarManager());
ToolBarManager manager = new ToolBarManager(toolbarFailureTrace);
manager.add(actCompareResults);
manager.add(new Separator());
manager.update(true);
}
private void fillLocalPullDown(IMenuManager manager) {
manager.add(actOnlyFailedTests);
manager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
}
private void fillContextMenuForTests(IMenuManager manager) {
manager.add(actRerunSome);
manager.add(actJumpFromTest);
}
private void fillContextMenuForStackFrames(IMenuManager manager) {
manager.add(actJumpFromStackFrame);
}
private void fillLocalToolBar(IToolBarManager manager) {
manager.add(actOnlyFailedTests);
manager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
manager.add(actHistory);
}
private void makeActions() {
actRerunSome = new RerunSelectedTestCasesAction();
actJumpFromTest = new JumpFromTestAction();
actJumpFromStackFrame = new JumpFromStackFrameAction();
actOnlyFailedTests = new OnlyFailedTestsAction();
actCompareResults = new CompareResultsAction();
final EUnitHistory history = EUnitPlugin.getDefault().getHistory();
actHistory = new HistoryDropDownAction(history, this);
}
private void hookClickAction() {
treeViewerTests.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
if (event.getSelection() instanceof IStructuredSelection) {
final IStructuredSelection sel = (IStructuredSelection)event.getSelection();
treeViewerFailureTrace.setInput(sel.getFirstElement());
final CompareResultsAction act = actCompareResults;
actCompareResults.setEnabled(act.getCurrentAssertionException() != null);
}
}
});
}
private void hookDoubleClickAction() {
treeViewerTests.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
actJumpFromTest.run();
}
});
treeViewerFailureTrace.addDoubleClickListener(new IDoubleClickListener(){
public void doubleClick(DoubleClickEvent event) {
actJumpFromStackFrame.run();
}
});
}
/**
* Passing the focus request to the viewer's control.
*/
public void setFocus() {
treeViewerTests.getControl().setFocus();
}
/**
* Changes the module which is currently displayed in this view.
* @param module EUnit module to be shown.
*/
public void setCurrentModules(final List<EUnitModule> modules) {
Display.getDefault().syncExec(new Runnable() {
public void run() {
try {
treeViewerTests.setInput(modules);
treeViewerTests.refresh();
failureTreeLabelProvider.setPrettyPrinterManager(
modules.get(0).getContext().getPrettyPrinterManager());
initializeTestCaseCounts(modules);
} catch (EolRuntimeException e) {
EUnitPlugin.getDefault().logException(e);
}
}
});
}
@Override
public void beforeCase(final EUnitModule module, EUnitTest test) {
if (test.isRootTest()) {
EUnitHistory history = EUnitPlugin.getDefault().getHistory();
List<EUnitModule> modules = history.getModules(history.getCurrentLaunch());
setCurrentModules(modules);
}
}
@Override
public void afterCase(final EUnitModule module, final EUnitTest test) {
Display.getDefault().syncExec(() -> {
treeViewerTests.update(test, null);
treeViewerTests.update(module, null);
if (test.isLeafTest()) {
if (test.getResult() != EUnitTestResultType.SKIPPED) {
++nRunTestCases;
}
switch (test.getResult()) {
case ERROR:
++nErrors;
break;
case FAILURE:
++nFailures;
break;
default:
break;
}
updateTestCaseCounts();
}
if (nErrors + nFailures > 0) {
treeViewerTests.expandAll();
}
});
}
private void initializeTestCaseCounts(List<EUnitModule> modules) throws EolRuntimeException {
nTotalTestCases = nErrors = nFailures = nRunTestCases = 0;
for (EUnitModule module : modules) {
final EUnitTest results = module.getSuiteRoot();
@SuppressWarnings("rawtypes")
final List selOps = module.getSelectedOperations();
final int allTests = results.countLeafTests(selOps);
final int withErrors = results.countLeafTests(selOps, EUnitTestResultType.ERROR);
final int withFailures = results.countLeafTests(selOps, EUnitTestResultType.FAILURE);
final int successfulTests = results.countLeafTests(selOps, EUnitTestResultType.SUCCESS);
nTotalTestCases += allTests;
nErrors += withErrors;
nFailures += withFailures;
nRunTestCases += withErrors + withFailures + successfulTests;
}
updateTestCaseCounts();
}
private void updateTestCaseCounts() {
lblNErrors.setText(Integer.toString(nErrors));
lblNFailures.setText(Integer.toString(nFailures));
lblNRun.setText(String.format("%d/%d", nRunTestCases, nTotalTestCases));
final boolean hasErrors = nErrors > 0 || nFailures > 0;
barProgress.reset(hasErrors, false, nRunTestCases, nTotalTestCases);
}
/**
* Reruns the last EUnit launch.
*
* @see #rerunLaunch(List, ILaunch)
*/
private void rerunCurrentLaunch(List<EUnitTest> tests) {
final EUnitHistory history = EUnitPlugin.getDefault().getHistory();
rerunLaunch(tests, history.getCurrentLaunch());
}
/**
* Reruns the EUnit launch in <code>lastLaunch</code>, using a working copy
* of its launch configuration. If <code>testCases</code> is null, the same
* operations as in the previous lunch will be run. Otherwise, if it is
* empty, all test cases will be run. If it is not empty, only the operations
* tested in the selected test cases will be run.
*/
private void rerunLaunch(List<EUnitTest> testCases, ILaunch launch) {
if (launch != null) {
ILaunchConfigurationWorkingCopy copy;
try {
copy = launch.getLaunchConfiguration().getWorkingCopy();
if (testCases != null) {
final Set<String> opNames = new HashSet<>();
collectOperationNamesFromSubtree(testCases, opNames);
EUnitPlugin.getDefault().setSelectedOperations(copy, new ArrayList<>(opNames));
}
copy.launch(launch.getLaunchMode(), null, true);
} catch (CoreException e) {
EUnitPlugin.getDefault().logException(e);
}
} else {
MessageDialog.openError(getViewSite().getShell(), EUNIT_DIALOG_TITLE,
EUNIT_DIALOG_MSG_NOT_RUN_YET);
}
}
private void collectOperationNamesFromSubtree(List<EUnitTest> tests, Collection<String> opNames) {
for (EUnitTest test : tests) {
// This tests, its ancestors and its descendants should be listed
for (EUnitTest curr = test; curr != null; curr = curr.getParent()) {
opNames.add(curr.getOperationName());
}
collectOperationNamesFromSubtree(test.getChildren(), opNames);
}
}
}