blob: 90937182d5677236ce899dadc26e70b65f94d1a3 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2015 Christian Pontesegger and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Christian Pontesegger - initial API and implementation
*******************************************************************************/
package org.eclipse.ease.modules.unittest.ui.views;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.ease.debugging.IScriptDebugFrame;
import org.eclipse.ease.modules.platform.UIModule;
import org.eclipse.ease.modules.unittest.ITestListener;
import org.eclipse.ease.modules.unittest.components.Test;
import org.eclipse.ease.modules.unittest.components.TestComposite;
import org.eclipse.ease.modules.unittest.components.TestFile;
import org.eclipse.ease.modules.unittest.components.TestResult;
import org.eclipse.ease.modules.unittest.components.TestStatus;
import org.eclipse.ease.modules.unittest.components.TestSuite;
import org.eclipse.ease.modules.unittest.components.TestSuiteModel;
import org.eclipse.ease.modules.unittest.ui.Activator;
import org.eclipse.ease.modules.unittest.ui.sourceprovider.TestSuiteSource;
import org.eclipse.ease.ui.console.ScriptConsole;
import org.eclipse.ease.ui.tools.DecoratedLabelProvider;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.layout.TreeColumnLayout;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.window.ToolTip;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
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.ProgressBar;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleListener;
import org.eclipse.ui.handlers.CollapseAllHandler;
import org.eclipse.ui.handlers.ExpandAllHandler;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.ui.texteditor.ITextEditor;
public class UnitTestView extends ViewPart implements ITestListener, IConsoleListener {
public static final String VIEW_ID = "org.eclipse.ease.views.unittest";
public static final String TEST_STATUS_PROPERTY = "test status";
private static class Statistics {
private final Map<Object, Integer> mCounters = new HashMap<>();
public synchronized void updateCounter(final Object identifier, final int value) {
if (mCounters.containsKey(identifier))
mCounters.put(identifier, mCounters.get(identifier) + value);
else
mCounters.put(identifier, value);
}
public void reset() {
mCounters.clear();
}
public synchronized int getCounter(final Object identifier) {
if (mCounters.containsKey(identifier))
return mCounters.get(identifier);
return 0;
}
}
private static final String XML_CURRENT_SUITE = "currentSuite";
private static final Object STATISTICS_TESTFILES_FINISHED = "testFiles";
private static final Object STATISTICS_TEST_ERROR = "test errors";
private static final Object STATISTICS_TEST_FAILURE = "test failures";
private static final Object STATISTICS_TEST_VALID = "valid tests";
private static final Object STATISTICS_TESTFILE_COUNT = "testFile count";
private static final Object STATISTICS_TEST_FINISHED = "test count";
private ProgressBar fProgressBar;
private TreeViewer fFileTreeViewer;
private TreeViewer fTestTreeViewer;
private SashForm sashForm;
private int[] fSashWeights = new int[] { 70, 30 };
private IMemento mMemento;
private CollapseAllHandler mCollapseAllHandler;
private ExpandAllHandler mExpandAllHandler;
private Label lblTimeLeftText;
private LocalResourceManager fResourceManager;
private final UpdateUI fUIUpdater = new UpdateUI();
private final Statistics fStatistics = new Statistics();
private Label lblErrorCount;
private Label lblFailureCount;
private SuiteRuntimeInformation fRuntimeInformation = null;
private Label lblTimeLeft;
private ScriptConsole fConsole = null;
public UnitTestView() {
}
@Override
public void init(final IViewSite site, final IMemento memento) throws PartInitException {
mMemento = memento;
super.init(site, memento);
}
@Override
public void createPartControl(final Composite parent) {
parent.setLayout(new GridLayout(1, false));
final Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(new GridLayout(8, false));
composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
fResourceManager = new LocalResourceManager(JFaceResources.getResources(), composite);
final Label lblErrorIcon = new Label(composite, SWT.NONE);
final GridData gdLblErrorIcon = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
gdLblErrorIcon.horizontalIndent = 50;
lblErrorIcon.setLayoutData(gdLblErrorIcon);
lblErrorIcon.setImage(fResourceManager.createImage(Activator.getImageDescriptor(Activator.ICON_ERROR)));
final Label lblErrors = new Label(composite, SWT.NONE);
lblErrors.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
lblErrors.setAlignment(SWT.CENTER);
lblErrors.setText("Errors:");
lblErrorCount = new Label(composite, SWT.NONE);
final GridData gd_lblErrorCount = new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1);
gd_lblErrorCount.horizontalIndent = 20;
lblErrorCount.setLayoutData(gd_lblErrorCount);
final Label lblFailureIcon = new Label(composite, SWT.NONE);
final GridData gdLblFailureIcon = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
gdLblFailureIcon.horizontalIndent = 50;
lblFailureIcon.setLayoutData(gdLblFailureIcon);
lblFailureIcon.setImage(fResourceManager.createImage(Activator.getImageDescriptor(Activator.ICON_FAILURE)));
final Label lblFailures = new Label(composite, SWT.NONE);
lblFailures.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
lblFailures.setAlignment(SWT.CENTER);
lblFailures.setText("Failures:");
lblFailureCount = new Label(composite, SWT.NONE);
final GridData gdLblFailureCount = new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1);
gdLblFailureCount.horizontalIndent = 20;
lblFailureCount.setLayoutData(gdLblFailureCount);
lblTimeLeftText = new Label(composite, SWT.NONE);
final GridData gdLabel = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
gdLabel.horizontalIndent = 50;
lblTimeLeftText.setLayoutData(gdLabel);
lblTimeLeftText.setText("Time left: ");
lblTimeLeftText.setVisible(false);
lblTimeLeft = new Label(composite, SWT.NONE);
final GridData gdLblTimeLeft = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
gdLblTimeLeft.horizontalIndent = 20;
lblTimeLeft.setLayoutData(gdLblTimeLeft);
lblTimeLeft.setVisible(false);
fProgressBar = new ProgressBar(parent, SWT.NONE);
fProgressBar.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
sashForm = new SashForm(parent, SWT.NONE);
sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
sashForm.setOrientation(SWT.VERTICAL);
fFileTreeViewer = new TreeViewer(sashForm, SWT.BORDER | SWT.MULTI);
fFileTreeViewer.setContentProvider(new TestSuiteContentProvider());
fFileTreeViewer.setComparator(new ViewerComparator() {
@Override
public final int category(final Object element) {
if (element instanceof TestFile)
return 1;
return 0;
}
});
// use a decorated label provider
final LabelProvider provider = new TestSuiteLabelProvider(fResourceManager);
fFileTreeViewer.setLabelProvider(new DecoratedLabelProvider(provider));
fFileTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
@Override
public void doubleClick(final DoubleClickEvent event) {
try {
final Object element = ((IStructuredSelection) event.getSelection()).getFirstElement();
if (element instanceof TestFile) {
final Object file = ((TestFile) element).getFile();
if (file instanceof IFile)
UIModule.showEditor((IFile) ((TestFile) element).getFile());
} else if (element instanceof TestSuite)
UIModule.showEditor(((TestSuite) element).getModel().getFile());
} catch (final Throwable e) {
// TODO handle this exception (but for now, at least know it happened)
throw new RuntimeException(e);
}
}
});
fFileTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(final SelectionChangedEvent event) {
final ITreeSelection selection = (ITreeSelection) event.getSelection();
final Object element = selection.getFirstElement();
if (element instanceof TestComposite) {
// test set selected
fTestTreeViewer.setInput(element);
if (sashForm.getWeights()[1] == 0)
sashForm.setWeights(fSashWeights);
fTestTreeViewer.refresh();
} else {
// test container selected, or no selection at all
fTestTreeViewer.setInput(null);
if (sashForm.getWeights()[1] != 0)
fSashWeights = sashForm.getWeights();
sashForm.setWeights(new int[] { 100, 0 });
}
}
});
// create tree viewer for tests
fTestTreeViewer = createTestArea(sashForm);
sashForm.setWeights(new int[] { 1, 1 });
// add context menu support
final MenuManager menuManager = new MenuManager();
final Menu menu = menuManager.createContextMenu(fFileTreeViewer.getTree());
fFileTreeViewer.getTree().setMenu(menu);
getSite().registerContextMenu(menuManager, fFileTreeViewer);
final MenuManager menuManager2 = new MenuManager();
final Menu menu2 = menuManager2.createContextMenu(fFileTreeViewer.getTree());
fTestTreeViewer.getTree().setMenu(menu2);
getSite().registerContextMenu(menuManager2, fTestTreeViewer);
// add collapseAll/expandAll handlers
final IHandlerService handlerService = getSite().getService(IHandlerService.class);
mCollapseAllHandler = new CollapseAllHandler(fFileTreeViewer);
handlerService.activateHandler(CollapseAllHandler.COMMAND_ID, mCollapseAllHandler);
mExpandAllHandler = new ExpandAllHandler(fFileTreeViewer);
handlerService.activateHandler(ExpandAllHandler.COMMAND_ID, mExpandAllHandler);
// menuManager.setRemoveAllWhenShown(true);
// load last suite
if (mMemento != null) {
final IMemento currentSuiteNode = mMemento.getChild(XML_CURRENT_SUITE);
if (currentSuiteNode != null) {
final Path path = new Path(currentSuiteNode.getTextData());
final IFile suiteFile = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
try {
loadSuite(new TestSuite(new TestSuiteModel(suiteFile)));
} catch (final Exception e) {
// loading failed, ignore
}
}
}
// register for console events
ConsolePlugin.getDefault().getConsoleManager().addConsoleListener(UnitTestView.this);
final MultiSelectionProvider selectionProvider = new MultiSelectionProvider();
selectionProvider.addSelectionProvider(fFileTreeViewer);
selectionProvider.addSelectionProvider(fTestTreeViewer);
getSite().setSelectionProvider(selectionProvider);
}
private TreeViewer createTestArea(final Composite parent) {
final Composite composite = new Composite(parent, SWT.NONE);
final TreeColumnLayout layout = new TreeColumnLayout();
composite.setLayout(layout);
final TreeViewer viewer = new TreeViewer(composite, SWT.BORDER | SWT.FULL_SELECTION);
viewer.addDoubleClickListener(new IDoubleClickListener() {
@Override
public void doubleClick(final DoubleClickEvent event) {
final Object element = ((IStructuredSelection) event.getSelection()).getFirstElement();
if (element instanceof Test) {
List<IScriptDebugFrame> trace;
final List<TestResult> messages = ((Test) element).getMessages();
if ((messages != null) && (!messages.isEmpty()))
trace = messages.get(0).getStackTrace();
else
trace = ((Test) element).getTestLocation();
if (trace != null) {
// open trace location
for (final IScriptDebugFrame traceElement : trace) {
final Object file = traceElement.getScript().getFile();
if (file instanceof IFile) {
if (((IFile) file).exists()) {
try {
final int line = Math.max(traceElement.getLineNumber(), 1);
final ITextEditor textEditor = (ITextEditor) UIModule.showEditor((IFile) file);
final IDocument document = textEditor.getDocumentProvider().getDocument(textEditor.getEditorInput());
try {
textEditor.selectAndReveal(document.getLineOffset(line - 1), document.getLineLength(line - 1));
} catch (final BadLocationException e) {
// TODO implement
throw new RuntimeException(e);
}
} catch (final Throwable e) {
// TODO handle this exception (but for now, at least know it happened)
throw new RuntimeException(e);
}
break;
}
}
}
} else {
// we do not have a trace, open test set
final Object input = viewer.getInput();
if (input instanceof TestFile) {
try {
final Object file = ((TestFile) input).getFile();
if (file instanceof IFile)
UIModule.showEditor((IFile) ((TestFile) input).getFile());
} catch (final Throwable e) {
// TODO handle this exception (but for now, at least know it happened)
throw new RuntimeException(e);
}
}
}
}
}
});
viewer.getTree().setHeaderVisible(true);
viewer.getTree().setLinesVisible(true);
viewer.setContentProvider(new TestFileContentProvider());
final TreeViewerColumn testColumn = new TreeViewerColumn(viewer, SWT.NONE);
testColumn.getColumn().setWidth(100);
testColumn.getColumn().setText("Test");
layout.setColumnData(testColumn.getColumn(), new ColumnWeightData(30, 50, true));
testColumn.setLabelProvider(new ColumnLabelProvider() {
@Override
public String getText(final Object element) {
if (element instanceof Test)
return ((Test) element).getTitle();
if (element instanceof Entry<?, ?>)
// metadata
return ((Entry<?, ?>) element).getKey().toString();
return "";
}
@Override
public Image getImage(final Object element) {
if (element instanceof Entry<?, ?>)
// metadata
return fResourceManager.createImage(Activator.getImageDescriptor(Activator.ICON_METADATA));
TestStatus status = null;
if (element instanceof Test)
status = ((Test) element).getStatus();
else if (element instanceof TestResult)
status = ((TestResult) element).getStatus();
if (status != null) {
switch (status) {
case PASS:
return fResourceManager.createImage(Activator.getImageDescriptor(Activator.ICON_PASS));
case ERROR:
return fResourceManager.createImage(Activator.getImageDescriptor(Activator.ICON_ERROR));
case FAILURE:
return fResourceManager.createImage(Activator.getImageDescriptor(Activator.ICON_FAILURE));
case RUNNING:
return fResourceManager.createImage(Activator.getImageDescriptor(Activator.ICON_RUNNING));
default:
return super.getImage(element);
}
}
return super.getImage(element);
}
@Override
public String getToolTipText(final Object element) {
if (element instanceof Test) {
if ((((Test) element).getDescription() != null) && (!((Test) element).getDescription().isEmpty()))
return ((Test) element).getDescription();
}
return super.getToolTipText(element);
}
});
final TreeViewerColumn messageColumn = new TreeViewerColumn(viewer, SWT.NONE);
messageColumn.getColumn().setWidth(100);
messageColumn.getColumn().setText("Message");
layout.setColumnData(messageColumn.getColumn(), new ColumnWeightData(70, 50, true));
messageColumn.setLabelProvider(new ColumnLabelProvider() {
@Override
public String getText(final Object element) {
if (element instanceof Test) {
final TestResult message = ((Test) element).getSeverestMessage();
if (message != null)
return message.getDescription();
return ((Test) element).getDescription();
}
if (element instanceof Entry<?, ?>)
// metadata
return ((Entry<?, ?>) element).getValue().toString();
return super.getText(element);
}
});
ColumnViewerToolTipSupport.enableFor(viewer, ToolTip.NO_RECREATE);
return viewer;
}
@Override
public void setFocus() {
// nothing to do
}
public TreeViewer getFileTreeViewer() {
return fFileTreeViewer;
}
private class UpdateUI extends UIJob {
private final List<Object> fElements = new ArrayList<>();
public UpdateUI() {
super("Update Script Unit View");
}
public void addElement(final Object element) {
synchronized (fElements) {
if (fElements.isEmpty()) {
// we might have added the same element again, so we cannot check for size() == 1 afterwards
fElements.add(element);
schedule(300);
} else
fElements.add(element);
}
}
@Override
public IStatus runInUIThread(final IProgressMonitor monitor) {
// create a local copy of elements so we can continue tests without waiting for the UI updater
ArrayList<Object> localElements;
synchronized (fElements) {
localElements = new ArrayList<>(fElements);
fElements.clear();
}
// update tree elements
for (final Object element : localElements) {
TestComposite affectedComposite = null;
if (element instanceof Test)
affectedComposite = ((Test) element).getParent();
else if (element instanceof TestComposite)
affectedComposite = (TestComposite) element;
while (affectedComposite != null) {
// update tree element and all its parents (no folders)
fFileTreeViewer.update(affectedComposite, new String[] { TEST_STATUS_PROPERTY });
affectedComposite = affectedComposite.getParent();
}
}
// update table
if (fTestTreeViewer.getInput() != null) {
// update only if tableviewer is visible at all
for (final Object element : localElements) {
if (element instanceof Test) {
final TestComposite testComposite = ((Test) element).getParent();
if (fTestTreeViewer.getInput().equals(testComposite)) {
fTestTreeViewer.refresh();
// TODO scroll to last element
// one refresh is enough for the whole table, so bail out
break;
}
}
}
}
// update statistics
if (!fProgressBar.isDisposed()) {
lblErrorCount.setText(Integer.toString(fStatistics.getCounter(STATISTICS_TEST_ERROR)));
lblFailureCount.setText(Integer.toString(fStatistics.getCounter(STATISTICS_TEST_FAILURE)));
lblFailureCount.getParent().layout();
fProgressBar.setSelection(fStatistics.getCounter(STATISTICS_TESTFILES_FINISHED));
lblTimeLeft.setText(getEstimatedTime());
if ((fStatistics.getCounter(STATISTICS_TEST_ERROR) > 0) || (fStatistics.getCounter(STATISTICS_TEST_FAILURE) > 0))
fProgressBar.setForeground(fResourceManager.createColor(new RGB(0xaa, 0, 0)));
else if (fStatistics.getCounter(STATISTICS_TESTFILES_FINISHED) == fStatistics.getCounter(STATISTICS_TESTFILE_COUNT)) {
if ((fStatistics.getCounter(STATISTICS_TEST_ERROR) == 0) && (fStatistics.getCounter(STATISTICS_TEST_FAILURE) == 0))
fProgressBar.setForeground(fResourceManager.createColor(new RGB(0, 0xaa, 0)));
}
}
synchronized (fElements) {
if (!fElements.isEmpty())
schedule(1000);
}
return Status.OK_STATUS;
}
private String getEstimatedTime() {
if (getCurrentSuite().getStatus() != TestStatus.RUNNING) {
lblTimeLeft.setVisible(false);
lblTimeLeftText.setVisible(false);
return "";
}
if (fRuntimeInformation != null) {
final long time = fRuntimeInformation.getEstimatedTestTime();
if (time < 0)
return "calculating...";
if (time < 60000)
return new SimpleDateFormat("ss 'seconds'").format(time);
if (time < 3600000)
return new SimpleDateFormat("mm:ss").format(time);
return new SimpleDateFormat("hh:mm:ss").format(time);
}
return "unknown";
}
}
@Override
public void notify(final Object testObject, final TestStatus status) {
if ((testObject instanceof TestSuite) && (status == TestStatus.RUNNING)) {
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
try {
loadSuite((TestSuite) testObject);
} catch (final Exception e) {
// TODO handle this exception (but for now, at least know it happened)
throw new RuntimeException(e);
}
fStatistics.reset();
fStatistics.updateCounter(STATISTICS_TESTFILE_COUNT, ((TestSuite) testObject).getActiveTestCount());
// initialize progress bar
fProgressBar.setMaximum(fStatistics.getCounter(STATISTICS_TESTFILE_COUNT));
fProgressBar.setSelection(0);
fProgressBar.setForeground(null);
// create console
if (fConsole == null)
fConsole = ScriptConsole.create(testObject.toString(), null);
// clear & attach to suite
fConsole.clearConsole();
fConsole.activate();
((TestSuite) testObject).setOutputStream(fConsole.getOutputStream());
((TestSuite) testObject).setErrorStream(fConsole.getErrorStream());
((TestSuite) testObject).setErrorStream(fConsole.getInputStream());
// update estimated runtime
lblTimeLeft.setVisible(true);
lblTimeLeftText.setVisible(true);
}
});
} else {
// update statistics
if ((status != TestStatus.RUNNING) && (status != TestStatus.NOT_RUN)) {
// test finished
if (testObject instanceof Test) {
// do not track when this is a temporary tests in test count
if (!((Test) testObject).isTransient())
fStatistics.updateCounter(STATISTICS_TEST_FINISHED, 1);
// do not track when this is a temporary test that passed
if ((!((Test) testObject).isTransient()) || (!((Test) testObject).getMessages().isEmpty())) {
switch (status) {
case FAILURE:
fStatistics.updateCounter(STATISTICS_TEST_FAILURE, 1);
break;
case ERROR:
fStatistics.updateCounter(STATISTICS_TEST_ERROR, 1);
break;
case PASS:
// do not track when global test file scope is valid
fStatistics.updateCounter(STATISTICS_TEST_VALID, 1);
break;
default:
// nothing to do
break;
}
}
} else if (testObject instanceof TestFile) {
fStatistics.updateCounter(STATISTICS_TESTFILES_FINISHED, 1);
}
}
}
fUIUpdater.addElement(testObject);
}
public StructuredViewer getTableViewer() {
return fTestTreeViewer;
}
@Override
public void saveState(final IMemento memento) {
final TestSuite suite = getCurrentSuite();
if (suite != null) {
final IFile file = suite.getModel().getFile();
if ((file != null) && (file.exists())) {
// we finally detected the current test suite
memento.createChild(XML_CURRENT_SUITE).putTextData(file.getFullPath().toString());
}
}
super.saveState(memento);
}
public TestSuite getCurrentSuite() {
final Object input = fFileTreeViewer.getInput();
if (input instanceof Object[]) {
if (((Object[]) input).length > 0) {
final Object suite = ((Object[]) input)[0];
if (suite instanceof TestSuite)
return (TestSuite) suite;
}
}
return null;
}
/**
* Loads a suite file and populates the treeview. Needs to be called from UIThread.
*
* @param suite
* testSuite
* @return
* @throws IOException
* cannot read from suite file
* @throws CoreException
* invalid data within suite file
*/
public void loadSuite(final TestSuite suite) throws IOException, CoreException {
// save current suite
final TestSuite currentSuite = getCurrentSuite();
if (!suite.equals(currentSuite)) {
if (currentSuite != null) {
Activator.getDefault().addRecentFile(currentSuite.getModel().getFile());
// save timing information
if (fRuntimeInformation != null)
fRuntimeInformation.save();
// clear data to minimize memory footprint in eclipse caches
currentSuite.reset();
}
fFileTreeViewer.setInput(new Object[] { suite });
fRuntimeInformation = new SuiteRuntimeInformation(suite);
// update source provider
final TestSuiteSource instance = TestSuiteSource.getActiveInstance();
if (instance != null)
instance.setActiveSuite(suite);
suite.addTestListener(this);
// refresh console
if (fConsole != null) {
fConsole.terminate();
fConsole = null;
}
}
fFileTreeViewer.refresh();
fFileTreeViewer.expandAll();
}
@Override
public void dispose() {
// unregister from console events
ConsolePlugin.getDefault().getConsoleManager().removeConsoleListener(this);
// dispose handlers
mCollapseAllHandler.dispose();
mExpandAllHandler.dispose();
// save current suite
final TestSuite currentSuite = getCurrentSuite();
if (currentSuite != null)
Activator.getDefault().addRecentFile(currentSuite.getModel().getFile());
// save timing information
if (fRuntimeInformation != null)
fRuntimeInformation.save();
// allow for garbage collection as eclipse does not clean up views correctly on clode
fRuntimeInformation = null;
final TestSuiteSource instance = TestSuiteSource.getActiveInstance();
if (instance != null)
instance.setActiveSuite(null);
fFileTreeViewer.setInput(new Object[0]);
// clear data to minimize memory footprint in eclipse caches
if (currentSuite != null)
currentSuite.reset();
super.dispose();
}
@Override
public void consolesAdded(final IConsole[] consoles) {
// nothing to do
}
@Override
public void consolesRemoved(final IConsole[] consoles) {
for (final IConsole console : consoles) {
if (console.equals(fConsole))
fConsole = null;
}
}
}