|
From: <caw...@us...> - 2006-12-15 15:39:50
|
Revision: 1711
http://svn.sourceforge.net/rubyeclipse/?rev=1711&view=rev
Author: cawilliams
Date: 2006-12-15 07:39:49 -0800 (Fri, 15 Dec 2006)
Log Message:
-----------
Added Paths:
-----------
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/CompareResultsAction.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/CopyTraceAction.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/CounterPanel.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/FailureTab.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/FailureTrace.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/ITestRunListener2.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/ITestRunListener3.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenEditorAtLineAction.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenLocationAction.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenSymbolAction.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/RemoteTestRunnerClient.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/RerunAction.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/ScrollLockAction.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TabFolderLayout.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestHierarchyTab.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestRunInfo.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestRunTab.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestUnitMessages.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestUnitMessages.properties
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestUnitProgressBar.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestUnitView.java
trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/TestunitPlugin.java
Added: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/CompareResultsAction.java
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/CompareResultsAction.java (rev 0)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/CompareResultsAction.java 2006-12-15 15:39:49 UTC (rev 1711)
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.rubypeople.rdt.internal.testunit.ui;
+
+import org.eclipse.jface.action.Action;
+
+/**
+ * Action to enable/disable stack trace filtering.
+ */
+public class CompareResultsAction extends Action {
+
+
+ public CompareResultsAction(FailureTrace view) {
+ super(TestUnitMessages.getString("CompareResultsAction.label")); //$NON-NLS-1$
+ setDescription(TestUnitMessages.getString("CompareResultsAction.description")); //$NON-NLS-1$
+ setToolTipText(TestUnitMessages.getString("CompareResultsAction.tooltip")); //$NON-NLS-1$
+
+ setDisabledImageDescriptor(TestunitPlugin.getImageDescriptor("dlcl16/compare.gif")); //$NON-NLS-1$
+ setHoverImageDescriptor(TestunitPlugin.getImageDescriptor("elcl16/compare.gif")); //$NON-NLS-1$
+ setImageDescriptor(TestunitPlugin.getImageDescriptor("elcl16/compare.gif")); //$NON-NLS-1$
+ }
+
+ /*
+ * @see Action#actionPerformed
+ */
+ public void run() {
+ // TODO Allow comparison of results
+// CompareResultDialog dialog = new CompareResultDialog(fView.getShell(), fView.getFailedTest());
+// dialog.create();
+// dialog.open();
+ }
+}
\ No newline at end of file
Added: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/CopyTraceAction.java
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/CopyTraceAction.java (rev 0)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/CopyTraceAction.java 2006-12-15 15:39:49 UTC (rev 1711)
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.rubypeople.rdt.internal.testunit.ui;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import org.eclipse.swt.SWTError;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.util.Assert;
+
+/**
+ * Copies a test failure stack trace to the clipboard.
+ */
+public class CopyTraceAction extends Action {
+ private FailureTrace fView;
+
+ private final Clipboard fClipboard;
+
+ /**
+ * Constructor for CopyTraceAction.
+ */
+ public CopyTraceAction(FailureTrace view, Clipboard clipboard) {
+ super(TestUnitMessages.getString("CopyTrace.action.label")); //$NON-NLS-1$
+ Assert.isNotNull(clipboard);
+ // TODO Show help!
+ //WorkbenchHelp.setHelp(this, ITestUnitHelpContextIds.COPYTRACE_ACTION);
+ fView= view;
+ fClipboard= clipboard;
+ }
+
+ /*
+ * @see IAction#run()
+ */
+ public void run() {
+ String trace= fView.getTrace();
+ if (trace == null)
+ trace= ""; //$NON-NLS-1$
+
+ TextTransfer plainTextTransfer = TextTransfer.getInstance();
+ try{
+ fClipboard.setContents(
+ new String[]{ convertLineTerminators(trace) },
+ new Transfer[]{ plainTextTransfer });
+ } catch (SWTError e){
+ if (e.code != DND.ERROR_CANNOT_SET_CLIPBOARD)
+ throw e;
+ if (MessageDialog.openQuestion(fView.getComposite().getShell(), TestUnitMessages.getString("CopyTraceAction.problem"), TestUnitMessages.getString("CopyTraceAction.clipboard_busy"))) //$NON-NLS-1$ //$NON-NLS-2$
+ run();
+ }
+ }
+
+ private String convertLineTerminators(String in) {
+ StringWriter stringWriter= new StringWriter();
+ PrintWriter printWriter= new PrintWriter(stringWriter);
+ StringReader stringReader= new StringReader(in);
+ BufferedReader bufferedReader= new BufferedReader(stringReader);
+ String line;
+ try {
+ while ((line= bufferedReader.readLine()) != null) {
+ printWriter.println(line);
+ }
+ } catch (IOException e) {
+ return in; // return the trace unfiltered
+ }
+ return stringWriter.toString();
+ }
+}
Added: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/CounterPanel.java
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/CounterPanel.java (rev 0)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/CounterPanel.java 2006-12-15 15:39:49 UTC (rev 1711)
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.rubypeople.rdt.internal.testunit.ui;
+
+
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * A panel with counters for the number of Runs, Errors and Failures.
+ */
+public class CounterPanel extends Composite {
+ protected Text fNumberOfErrors;
+ protected Text fNumberOfFailures;
+ protected Text fNumberOfRuns;
+ protected int fTotal;
+
+ private final Image fErrorIcon= TestUnitView.createImage("ovr16/error_ovr.gif"); //$NON-NLS-1$
+ private final Image fFailureIcon= TestUnitView.createImage("ovr16/failed_ovr.gif"); //$NON-NLS-1$
+
+ public CounterPanel(Composite parent) {
+ super(parent, SWT.WRAP);
+ GridLayout gridLayout= new GridLayout();
+ gridLayout.numColumns= 9;
+ gridLayout.makeColumnsEqualWidth= false;
+ gridLayout.marginWidth= 0;
+ setLayout(gridLayout);
+
+ fNumberOfRuns= createLabel(TestUnitMessages.getString("CounterPanel.label.runs"), null, " 0/0 "); //$NON-NLS-1$ //$NON-NLS-2$
+ fNumberOfErrors= createLabel(TestUnitMessages.getString("CounterPanel.label.errors"), fErrorIcon, " 0 "); //$NON-NLS-1$ //$NON-NLS-2$
+ fNumberOfFailures= createLabel(TestUnitMessages.getString("CounterPanel.label.failures"), fFailureIcon, " 0 "); //$NON-NLS-1$ //$NON-NLS-2$
+
+ addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ disposeIcons();
+ }
+ });
+ }
+
+ private void disposeIcons() {
+ fErrorIcon.dispose();
+ fFailureIcon.dispose();
+ }
+
+ private Text createLabel(String name, Image image, String init) {
+ Label label= new Label(this, SWT.NONE);
+ if (image != null) {
+ image.setBackground(label.getBackground());
+ label.setImage(image);
+ }
+ label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+
+ label= new Label(this, SWT.NONE);
+ label.setText(name);
+ label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+ label.setFont(JFaceResources.getBannerFont());
+
+ Text value= new Text(this, SWT.READ_ONLY);
+ value.setText(init);
+ // bug: 39661 Junit test counters do not repaint correctly [JUnit]
+ value.setBackground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
+ value.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING));
+ return value;
+ }
+
+ public void reset() {
+ setErrorValue(0);
+ setFailureValue(0);
+ setRunValue(0);
+ fTotal= 0;
+ }
+
+ public void setTotal(int value) {
+ fTotal= value;
+ }
+
+ public int getTotal(){
+ return fTotal;
+ }
+
+ public void setRunValue(int value) {
+ String runString= TestUnitMessages.getFormattedString("CounterPanel.runcount", new String[] { Integer.toString(value), Integer.toString(fTotal) }); //$NON-NLS-1$
+ fNumberOfRuns.setText(runString);
+
+ fNumberOfRuns.redraw();
+ redraw();
+ }
+
+ public void setErrorValue(int value) {
+ fNumberOfErrors.setText(Integer.toString(value));
+ redraw();
+ }
+
+ public void setFailureValue(int value) {
+ fNumberOfFailures.setText(Integer.toString(value));
+ redraw();
+ }
+}
Added: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/FailureTab.java
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/FailureTab.java (rev 0)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/FailureTab.java 2006-12-15 15:39:49 UTC (rev 1711)
@@ -0,0 +1,348 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.rubypeople.rdt.internal.testunit.ui;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CTabFolder;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+import org.rubypeople.rdt.core.RubyCore;
+import org.rubypeople.rdt.internal.core.symbols.ISymbolFinder;
+import org.rubypeople.rdt.testunit.ITestRunListener;
+
+/**
+ * A tab presenting the failed tests in a table.
+ */
+public class FailureTab extends TestRunTab implements IMenuListener {
+
+ private Table fTable;
+ private TestUnitView fRunnerViewPart;
+ private boolean fMoveSelection = false;
+
+ private final Image fErrorIcon = TestUnitView.createImage("obj16/testerr.gif"); //$NON-NLS-1$
+ private final Image fFailureIcon = TestUnitView.createImage("obj16/testfail.gif"); //$NON-NLS-1$
+ private final Image fFailureTabIcon = TestUnitView.createImage("obj16/failures.gif"); //$NON-NLS-1$
+
+ public FailureTab() {}
+
+ public void createTabControl(CTabFolder tabFolder, Clipboard clipboard, TestUnitView runner) {
+ fRunnerViewPart = runner;
+
+ CTabItem failureTab = new CTabItem(tabFolder, SWT.NONE);
+ failureTab.setText(getName());
+ failureTab.setImage(fFailureTabIcon);
+
+ Composite composite = new Composite(tabFolder, SWT.NONE);
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.marginHeight = 0;
+ gridLayout.marginWidth = 0;
+ composite.setLayout(gridLayout);
+
+ GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
+ composite.setLayoutData(gridData);
+
+ fTable = new Table(composite, SWT.NONE);
+ gridLayout = new GridLayout();
+ gridLayout.marginHeight = 0;
+ gridLayout.marginWidth = 0;
+ fTable.setLayout(gridLayout);
+
+ gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
+ fTable.setLayoutData(gridData);
+
+ failureTab.setControl(composite);
+ failureTab.setToolTipText(TestUnitMessages.getString("FailureRunView.tab.tooltip")); //$NON-NLS-1$
+
+ initMenu();
+ addListeners();
+ }
+
+ private void disposeIcons() {
+ fErrorIcon.dispose();
+ fFailureIcon.dispose();
+ fFailureTabIcon.dispose();
+ }
+
+ private void initMenu() {
+ MenuManager menuMgr = new MenuManager();
+ menuMgr.setRemoveAllWhenShown(true);
+ menuMgr.addMenuListener(this);
+ Menu menu = menuMgr.createContextMenu(fTable);
+ fTable.setMenu(menu);
+ }
+
+ public String getName() {
+ return TestUnitMessages.getString("FailureRunView.tab.title"); //$NON-NLS-1$
+ }
+
+ public String getSelectedTestId() {
+ int index = fTable.getSelectionIndex();
+ if (index == -1) return null;
+ return getTestInfo(fTable.getItem(index)).getTestId();
+ }
+
+ public String getAllFailedTestNames() {
+ StringBuffer trace = new StringBuffer();
+ String lineDelim = System.getProperty("line.separator", "\n"); //$NON-NLS-1$//$NON-NLS-2$
+ for (int i = 0; i < fTable.getItemCount(); i++) {
+ TestRunInfo testInfo = getTestInfo(fTable.getItem(i));
+ trace.append(testInfo.getTestName()).append(lineDelim);
+ String failureTrace = testInfo.getTrace();
+ if (failureTrace != null) {
+ StringReader stringReader = new StringReader(failureTrace);
+ BufferedReader bufferedReader = new BufferedReader(stringReader);
+ String line;
+ try {
+ while ((line = bufferedReader.readLine()) != null)
+ trace.append(line + lineDelim);
+ } catch (IOException e) {
+ trace.append(lineDelim);
+ }
+ }
+ }
+ return trace.toString();
+ }
+
+ private String getClassName() {
+ TableItem item = getSelectedItem();
+ TestRunInfo info = getTestInfo(item);
+ return info.getClassName();
+ }
+
+ private String getMethodName() {
+ TableItem item = getSelectedItem();
+ TestRunInfo info = getTestInfo(item);
+ return info.getTestMethodName();
+ }
+
+ public void menuAboutToShow(IMenuManager manager) {
+ if (fTable.getSelectionCount() > 0) {
+ String className = getClassName();
+ String methodName = getMethodName();
+ if (className != null) {
+ System.err.println("MethodName: " + methodName);
+ manager.add(OpenSymbolAction.forMethod(className, methodName, getSymbolFinder(), getShell()));
+ manager.add(new Separator());
+ manager.add(new RerunAction(fRunnerViewPart, getSelectedTestId(),
+ className, methodName, ILaunchManager.RUN_MODE));
+ manager.add(new RerunAction(fRunnerViewPart, getSelectedTestId(),
+ className, methodName, ILaunchManager.DEBUG_MODE));
+ manager.add(new Separator());
+ // TODO Add back the actions!
+ //manager.add(new CopyFailureListAction(fRunnerViewPart,
+ // FailureTab.this, fClipboard));
+ }
+ }
+ }
+
+ private ISymbolFinder getSymbolFinder() {
+ return RubyCore.getPlugin().getSymbolFinder();
+ }
+
+ private TableItem getSelectedItem() {
+ int index = fTable.getSelectionIndex();
+ if (index == -1) return null;
+ return fTable.getItem(index);
+ }
+
+ public void setSelectedTest(String testId) {
+ TableItem[] items = fTable.getItems();
+ for (int i = 0; i < items.length; i++) {
+ TableItem tableItem = items[i];
+ TestRunInfo info = getTestInfo(tableItem);
+ if (info.getTestId().equals(testId)) {
+ fTable.setSelection(new TableItem[] { tableItem});
+ fTable.showItem(tableItem);
+ return;
+ }
+ }
+ }
+
+ private TestRunInfo getTestInfo(TableItem item) {
+ return (TestRunInfo) item.getData();
+ }
+
+ public void setFocus() {
+ fTable.setFocus();
+ }
+
+ public void endTest(String testId) {
+ TestRunInfo testInfo = fRunnerViewPart.getTestInfo(testId);
+ if (testInfo == null || testInfo.getStatus() == ITestRunListener.STATUS_OK) return;
+
+ TableItem tableItem = new TableItem(fTable, SWT.NONE);
+ updateTableItem(testInfo, tableItem);
+ fTable.showItem(tableItem);
+ }
+
+ private void updateTableItem(TestRunInfo testInfo, TableItem tableItem) {
+ String label = TestUnitMessages.getFormattedString("FailureRunView.labelfmt", new String[] { testInfo.getTestMethodName(), testInfo.getClassName()}); //$NON-NLS-1$
+ tableItem.setText(label);
+ if (testInfo.getStatus() == ITestRunListener.STATUS_FAILURE)
+ tableItem.setImage(fFailureIcon);
+ else
+ tableItem.setImage(fErrorIcon);
+ tableItem.setData(testInfo);
+ }
+
+ private TableItem findItem(String testId) {
+ TableItem[] items = fTable.getItems();
+ for (int i = 0; i < items.length; i++) {
+ TestRunInfo info = getTestInfo(items[i]);
+ if (info.getTestId().equals(testId)) return items[i];
+ }
+ return null;
+ }
+
+ public void activate() {
+ fMoveSelection = false;
+ testSelected();
+ }
+
+ public void aboutToStart() {
+ fMoveSelection = false;
+ fTable.removeAll();
+ }
+
+ private void testSelected() {
+ fRunnerViewPart.handleTestSelected(getSelectedTestId());
+ }
+
+ private void addListeners() {
+ fTable.addSelectionListener(new SelectionListener() {
+
+ public void widgetSelected(SelectionEvent e) {
+ activate();
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ activate();
+ }
+ });
+
+ fTable.addDisposeListener(new DisposeListener() {
+
+ public void widgetDisposed(DisposeEvent e) {
+ disposeIcons();
+ }
+ });
+
+ fTable.addMouseListener(new MouseAdapter() {
+
+ public void mouseDoubleClick(MouseEvent e) {
+ handleDoubleClick(e);
+ }
+
+ public void mouseDown(MouseEvent e) {
+ activate();
+ }
+
+ public void mouseUp(MouseEvent e) {
+ activate();
+ }
+ });
+ }
+
+ void handleDoubleClick(MouseEvent e) {
+ if (fTable.getSelectionCount() > 0)
+ OpenSymbolAction.forMethod(getClassName(), getMethodName(), getSymbolFinder(), getShell()).run();
+ }
+
+ private Shell getShell() {
+ return fTable.getShell();
+ }
+
+ /*
+ * @see ITestRunView#testStatusChanged(TestRunInfo)
+ */
+ public void testStatusChanged(TestRunInfo info) {
+ TableItem item = findItem(info.getTestId());
+ if (item != null) {
+ if (info.getStatus() == ITestRunListener.STATUS_OK) {
+ item.dispose();
+ return;
+ }
+ updateTableItem(info, item);
+ }
+ if (item == null && info.getStatus() != ITestRunListener.STATUS_OK) {
+ item = new TableItem(fTable, SWT.NONE);
+ updateTableItem(info, item);
+ }
+ if (item != null) fTable.showItem(item);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jdt.internal.junit.ui.ITestRunView#selectNext()
+ */
+ public void selectNext() {
+ if (fTable.getItemCount() == 0) return;
+
+ int index = fTable.getSelectionIndex();
+ if (index == -1) index = 0;
+
+ if (fMoveSelection)
+ index = Math.min(fTable.getItemCount() - 1, index + 1);
+ else
+ fMoveSelection = true;
+
+ selectTest(index);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jdt.internal.junit.ui.ITestRunView#selectPrevious()
+ */
+ public void selectPrevious() {
+ if (fTable.getItemCount() == 0) return;
+
+ int index = fTable.getSelectionIndex();
+ if (index == -1) index = fTable.getItemCount() - 1;
+
+ if (fMoveSelection)
+ index = Math.max(0, index - 1);
+ else
+ fMoveSelection = true;
+
+ selectTest(index);
+ }
+
+ private void selectTest(int index) {
+ TableItem item = fTable.getItem(index);
+ TestRunInfo info = getTestInfo(item);
+ fRunnerViewPart.showTest(info);
+ }
+}
\ No newline at end of file
Added: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/FailureTrace.java
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/FailureTrace.java (rev 0)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/FailureTrace.java 2006-12-15 15:39:49 UTC (rev 1711)
@@ -0,0 +1,262 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Sebastian Davids: sd...@gm... bug 37333, 26653
+ *******************************************************************************/
+package org.rubypeople.rdt.internal.testunit.ui;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.ToolBarManager;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.util.IOpenEventListener;
+import org.eclipse.jface.util.OpenStrategy;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.ToolBar;
+import org.rubypeople.rdt.internal.ui.util.StackTraceLine;
+
+/**
+ * A pane that shows a stack trace of a failed test.
+ */
+public class FailureTrace implements IMenuListener {
+ private final Image fStackIcon= TestUnitView.createImage("obj16/stkfrm_obj.gif"); //$NON-NLS-1$
+ private final Image fExceptionIcon= TestUnitView.createImage("obj16/exc_catch.gif"); //$NON-NLS-1$
+
+ private Table fTable;
+ private String fInputTrace;
+ private final Clipboard fClipboard;
+ private TestRunInfo fFailure;
+ private CompareResultsAction fCompareAction;
+
+
+ public FailureTrace(Composite parent, Clipboard clipboard, TestUnitView testRunner, ToolBar toolBar) {
+ Assert.isNotNull(clipboard);
+
+ // fill the failure trace viewer toolbar
+ ToolBarManager failureToolBarmanager= new ToolBarManager(toolBar);
+ // TODO Add the EnableStackFilterAction back
+ //failureToolBarmanager.add(new EnableStackFilterAction(this));
+ fCompareAction = new CompareResultsAction(this);
+ fCompareAction.setEnabled(false);
+ failureToolBarmanager.add(fCompareAction);
+ failureToolBarmanager.update(true);
+
+ fTable= new Table(parent, SWT.SINGLE | SWT.V_SCROLL | SWT.H_SCROLL);
+ fClipboard= clipboard;
+
+ OpenStrategy handler = new OpenStrategy(fTable);
+ handler.addOpenListener(new IOpenEventListener() {
+ public void handleOpen(SelectionEvent e) {
+ if (fTable.getSelectionIndex() == 0 && fFailure.isComparisonFailure()) {
+ (new CompareResultsAction(FailureTrace.this)).run();
+ }
+ if (fTable.getSelection().length != 0) {
+ Action a = createOpenEditorAction(getSelectedText());
+ if (a != null)
+ a.run();
+ }
+ }
+ });
+
+ initMenu();
+ fTable.addSelectionListener(new SelectionListener() {
+
+ public void widgetSelected(SelectionEvent e) {}
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ new StackTraceLine(getSelectedText()).openEditor();
+ }
+ });
+
+ parent.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ disposeIcons();
+ }
+ });
+ }
+
+ private void initMenu() {
+ MenuManager menuMgr= new MenuManager();
+ menuMgr.setRemoveAllWhenShown(true);
+ menuMgr.addMenuListener(this);
+ Menu menu= menuMgr.createContextMenu(fTable);
+ fTable.setMenu(menu);
+ }
+
+ public void menuAboutToShow(IMenuManager manager) {
+ if (fTable.getSelectionCount() > 0) {
+ Action a= createOpenEditorAction(getSelectedText());
+ if (a != null)
+ manager.add(a);
+ manager.add(new CopyTraceAction(FailureTrace.this, fClipboard));
+ }
+ // fix for bug 68058
+ if (fFailure != null && fFailure.isComparisonFailure())
+ manager.add(new CompareResultsAction(FailureTrace.this));
+ }
+
+ public String getTrace() {
+ return fInputTrace;
+ }
+
+ private String getSelectedText() {
+ return fTable.getSelection()[0].getText();
+ }
+
+ private Action createOpenEditorAction(String traceLine) {
+ return new OpenEditorAction(new StackTraceLine(traceLine));
+ }
+
+ private void disposeIcons(){
+ if (fExceptionIcon != null && !fExceptionIcon.isDisposed())
+ fExceptionIcon.dispose();
+ if (fStackIcon != null && !fStackIcon.isDisposed())
+ fStackIcon.dispose();
+ }
+
+ /**
+ * Returns the composite used to present the trace
+ */
+ public Composite getComposite(){
+ return fTable;
+ }
+
+ /**
+ * Refresh the table from the the trace.
+ */
+ public void refresh() {
+ updateTable(fInputTrace);
+ }
+
+ /**
+ * Shows a TestFailure
+ * @param failure the failed test
+ */
+ public void showFailure(TestRunInfo failure) {
+ fFailure= failure;
+ String trace= ""; //$NON-NLS-1$
+ updateEnablement(failure);
+ if (failure != null)
+ trace= failure.getTrace();
+ if (fInputTrace == trace)
+ return;
+ fInputTrace= trace;
+ updateTable(trace);
+ }
+
+ public void updateEnablement(TestRunInfo failure) {
+ fCompareAction.setEnabled(failure != null && failure.isComparisonFailure());
+ }
+
+ private void updateTable(String trace) {
+ if(trace == null || trace.trim().equals("")) { //$NON-NLS-1$
+ clear();
+ return;
+ }
+ trace= trace.trim();
+ fTable.setRedraw(false);
+ fTable.removeAll();
+ fillTable(filterStack(trace));
+ fTable.setRedraw(true);
+ }
+
+ private void fillTable(String trace) {
+ StringReader stringReader= new StringReader(trace);
+ BufferedReader bufferedReader= new BufferedReader(stringReader);
+ String line;
+
+ try {
+ // first line contains the thrown exception
+ line= bufferedReader.readLine();
+ if (line == null)
+ return;
+
+ TableItem tableItem= new TableItem(fTable, SWT.NONE);
+ String itemLabel= line.replace('\t', ' ');
+ tableItem.setText(itemLabel);
+ tableItem.setImage(fExceptionIcon);
+
+ // the stack frames of the trace
+ while ((line= bufferedReader.readLine()) != null) {
+ itemLabel= line.replace('\t', ' ');
+ tableItem= new TableItem(fTable, SWT.NONE);
+ // heuristic for detecting a stack frame - works for JDK
+ if ((itemLabel.indexOf(" at ") >= 0)) { //$NON-NLS-1$
+ tableItem.setImage(fStackIcon);
+ }
+ tableItem.setText(itemLabel);
+ }
+ } catch (IOException e) {
+ TableItem tableItem= new TableItem(fTable, SWT.NONE);
+ tableItem.setText(trace);
+ }
+ }
+
+ /**
+ * Shows other information than a stack trace.
+ * @param text the informational message to be shown
+ */
+ public void setInformation(String text) {
+ clear();
+ TableItem tableItem= new TableItem(fTable, SWT.NONE);
+ tableItem.setText(text);
+ }
+
+ /**
+ * Clears the non-stack trace info
+ */
+ public void clear() {
+ fTable.removeAll();
+ fInputTrace= null;
+ }
+
+ private String filterStack(String stackTrace) {
+ return stackTrace;
+ // TODO Filter the stack trace
+ }
+
+
+ public TestRunInfo getFailedTest() {
+ return fFailure;
+ }
+
+ public Shell getShell() {
+ return fTable.getShell();
+ }
+
+ private class OpenEditorAction extends Action {
+ private final StackTraceLine trace;
+
+ public OpenEditorAction(StackTraceLine trace) {
+ super(TestUnitMessages.getString("OpenEditor.action.label"));
+ this.trace = trace;
+ }
+
+ public void run() {
+ trace.openEditor();
+ }
+ }
+}
Added: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/ITestRunListener2.java
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/ITestRunListener2.java (rev 0)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/ITestRunListener2.java 2006-12-15 15:39:49 UTC (rev 1711)
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.rubypeople.rdt.internal.testunit.ui;
+
+import org.rubypeople.rdt.testunit.ITestRunListener;
+
+/**
+ * Extends ITestRunListener with a call back to trace the test contents
+ */
+public interface ITestRunListener2 extends ITestRunListener {
+
+ /**
+ * Information about a member of the test suite that is about to be run. The
+ * format of the string is:
+ *
+ * <pre>
+ *
+ * "testId","testName","isSuite","testcount"
+ *
+ * testId: a unique id for the test
+ * testName: the name of the test
+ * isSuite: true or false depending on whether the test is a suite
+ * testCount: an integer indicating the number of tests
+ *
+ * Example: "324968,testPass(junit.tests.MyTest),false,1"
+ *
+ * </pre>
+ *
+ * @param description
+ * a string describing a tree entry
+ */
+ public void testTreeEntry(String description);
+}
\ No newline at end of file
Added: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/ITestRunListener3.java
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/ITestRunListener3.java (rev 0)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/ITestRunListener3.java 2006-12-15 15:39:49 UTC (rev 1711)
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.rubypeople.rdt.internal.testunit.ui;
+
+
+/**
+ * Extends ITestRunListener2 with a call back to trace the test contents
+ */
+public interface ITestRunListener3 extends ITestRunListener2 {
+
+ public void testFailed(int status, String testId, String testName, String trace, String expected, String actual);
+
+ public void testReran(String testId, String className, String testName, int statusCode, String trace, String expectedResult, String actualResult);
+}
Added: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenEditorAtLineAction.java
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenEditorAtLineAction.java (rev 0)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenEditorAtLineAction.java 2006-12-15 15:39:49 UTC (rev 1711)
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Sebastian Davids: sd...@gm... bug 37333 Failure Trace cannot
+ * navigate to non-public class in CU throwing Exception
+
+ *******************************************************************************/
+package org.rubypeople.rdt.internal.testunit.ui;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.model.ISourceLocator;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.rubypeople.rdt.core.IRubyElement;
+import org.rubypeople.rdt.core.IRubyProject;
+import org.rubypeople.rdt.internal.debug.ui.RubySourceLocator;
+
+/**
+ * Open a test in the Ruby editor and reveal a given line
+ */
+public class OpenEditorAtLineAction extends Action {
+
+ private int fLineNumber;
+ private String fileName;
+ private TestUnitView fTestRunner;
+
+ /**
+ * Constructor for OpenEditorAtLineAction.
+ */
+ public OpenEditorAtLineAction(TestUnitView testRunner, String fileName, int line) {
+ super(TestUnitMessages.getString("OpenEditorAction.action.label"));
+ // TODO Uncomment and fix!
+ // WorkbenchHelp.setHelp(this,
+ // IJUnitHelpContextIds.OPENEDITORATLINE_ACTION);
+ fLineNumber = line;
+ fTestRunner = testRunner;
+ this.fileName = fileName;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.rubypeople.rdt.internal.testunit.ui.OpenEditorAction#run()
+ */
+ public void run() {
+ try {
+ IEditorInput input = getInput();
+ if (input == null) {
+ if (TestunitPlugin.getDefault().isDebugging()) {
+ System.out
+ .println("Could not create editor input for stack trace: " + fileName);
+ }
+ // wrongly detected stack trace
+ return;
+ }
+ IEditorPart editorPart = getEditorPart(input);
+ setEditorToLine(editorPart, input);
+ } catch (CoreException e) {
+ TestunitPlugin.log(new Status(IStatus.ERROR, TestunitPlugin.PLUGIN_ID, 0,
+ "Could not open editor or set line in editor." + fileName, e));
+ }
+ }
+
+ /**
+ * @param input
+ * @return
+ * @throws PartInitException
+ */
+ private IEditorPart getEditorPart(IEditorInput input) throws PartInitException {
+ ISourceLocator sourceLocator = getSourceLocator();
+ if (!(sourceLocator instanceof RubySourceLocator)) { return null; }
+ RubySourceLocator rubySourceLocator = (RubySourceLocator) sourceLocator;
+
+ Object sourceElement = rubySourceLocator.getSourceElement(fileName);
+ return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().openEditor(
+ input, rubySourceLocator.getEditorId(input, sourceElement));
+ }
+
+ private void setEditorToLine(IEditorPart pEditorPart, IEditorInput pInput) throws CoreException {
+ if (!(pEditorPart instanceof ITextEditor)) { return; }
+ // documents start at 0
+ if (fLineNumber > 0) {
+ fLineNumber--;
+ }
+ if (fLineNumber == 0) { return; }
+ ITextEditor textEditor = (ITextEditor) pEditorPart;
+ IDocumentProvider provider = textEditor.getDocumentProvider();
+ provider.connect(pInput);
+ IDocument document = provider.getDocument(pInput);
+ try {
+ IRegion line = document.getLineInformation(fLineNumber);
+ textEditor.selectAndReveal(line.getOffset(), line.getLength());
+ } catch (BadLocationException e) {
+ if (TestunitPlugin.getDefault().isDebugging()) {
+ System.out.println("Could not set editor to line: " + fLineNumber);
+ }
+ }
+ provider.disconnect(pInput);
+ }
+
+ protected void reveal(ITextEditor textEditor) {
+ if (fLineNumber >= 0) {
+ try {
+ IDocument document = textEditor.getDocumentProvider().getDocument(
+ textEditor.getEditorInput());
+ textEditor.selectAndReveal(document.getLineOffset(fLineNumber - 1), document
+ .getLineLength(fLineNumber - 1));
+ } catch (BadLocationException x) {
+ // marker refers to invalid text position -> do nothing
+ }
+ }
+ }
+
+ protected IRubyElement findElement(IRubyProject project, String className) throws CoreException {
+ return project.findType(className);
+ }
+
+ public boolean isEnabled() {
+ return getInput() != null;
+ }
+
+ /**
+ * @return
+ */
+ private IEditorInput getInput() {
+ ISourceLocator sourceLocator = getSourceLocator();
+ if (!(sourceLocator instanceof RubySourceLocator)) { return null; }
+ RubySourceLocator rubySourceLocator = (RubySourceLocator) sourceLocator;
+
+ Object sourceElement = rubySourceLocator.getSourceElement(fileName);
+ IEditorInput input = rubySourceLocator.getEditorInput(sourceElement);
+ return input;
+ }
+
+ /**
+ * @return
+ */
+ private ISourceLocator getSourceLocator() {
+ ILaunch launch = fTestRunner.getLastLaunch();
+ if (launch == null) { return null; }
+ return launch.getSourceLocator();
+ }
+
+ protected Shell getShell() {
+ return fTestRunner.getSite().getShell();
+ }
+
+ protected IRubyProject getLaunchedProject() {
+ return fTestRunner.getLaunchedProject();
+ }
+
+}
Added: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenLocationAction.java
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenLocationAction.java (rev 0)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenLocationAction.java 2006-12-15 15:39:49 UTC (rev 1711)
@@ -0,0 +1,23 @@
+package org.rubypeople.rdt.internal.testunit.ui;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.rubypeople.rdt.internal.core.symbols.Location;
+import org.rubypeople.rdt.internal.ui.util.PositionBasedEditorOpener;
+
+
+public class OpenLocationAction extends Action implements IAction {
+
+ private final Location location;
+
+ public OpenLocationAction(Location location) {
+ super(location.getFilename());
+ this.location = location;
+ }
+
+ public void run() {
+ new PositionBasedEditorOpener(location.getFilename(), location.getPosition()).open();
+ }
+
+
+}
Added: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenSymbolAction.java
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenSymbolAction.java (rev 0)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/OpenSymbolAction.java 2006-12-15 15:39:49 UTC (rev 1711)
@@ -0,0 +1,99 @@
+package org.rubypeople.rdt.internal.testunit.ui;
+
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Shell;
+import org.rubypeople.rdt.internal.core.symbols.ClassSymbol;
+import org.rubypeople.rdt.internal.core.symbols.ISymbolFinder;
+import org.rubypeople.rdt.internal.core.symbols.Location;
+import org.rubypeople.rdt.internal.core.symbols.MethodSymbol;
+import org.rubypeople.rdt.internal.core.symbols.Symbol;
+import org.rubypeople.rdt.internal.ui.RubyPluginImages;
+import org.rubypeople.rdt.internal.ui.dialogs.ElementListSelectionDialog;
+import org.rubypeople.rdt.internal.ui.util.PositionBasedEditorOpener;
+
+public class OpenSymbolAction extends Action implements IAction {
+
+ private final Symbol symbol;
+ private final ISymbolFinder finder;
+ private final Shell shell;
+ private String dialogTitle;
+
+ public static IAction forClass(String className, ISymbolFinder finder, Shell shell) {
+ return new OpenSymbolAction(new ClassSymbol(className), finder, shell, "Open Class");
+ }
+
+ public static IAction forMethod(String className, String testMethod,
+ ISymbolFinder finder, Shell shell) {
+ return new OpenSymbolAction(new MethodSymbol(className, testMethod), finder, shell, "Open Method");
+ }
+
+ public OpenSymbolAction(Symbol symbol, ISymbolFinder finder, Shell shell, String title) {
+ super(TestUnitMessages.getString("OpenEditor.action.label"));
+ this.shell = shell;
+ this.symbol = symbol;
+ this.finder = finder;
+ this.dialogTitle = title;
+ }
+
+
+ public void run() {
+ Set locations = finder.find(symbol);
+ if (locations.size() == 0)
+ return;
+
+ Location location;
+ if (locations.size() == 1) {
+ location = (Location) locations.iterator().next();
+ } else {
+ ElementListSelectionDialog selectionDialog
+ = new ElementListSelectionDialog(shell, new LocationLabel());
+ selectionDialog.setElements(locations.toArray());
+ selectionDialog.setMessage("Select a location");
+ selectionDialog.setTitle(dialogTitle);
+ selectionDialog.open();
+ if (selectionDialog.getReturnCode() == SWT.CANCEL)
+ return;
+ location= (Location) selectionDialog.getResult()[0];
+ }
+ PositionBasedEditorOpener editorOpener
+ = new PositionBasedEditorOpener(location.getFilename(),
+ location.getPosition());
+ editorOpener.open();
+ }
+
+
+ private final class LocationLabel implements ILabelProvider {
+ public Image getImage(Object element) {
+ return RubyPluginImages.get(RubyPluginImages.IMG_CTOOLS_RUBY_PAGE);
+ }
+
+ public String getText(Object element) {
+ Location location = (Location) element;
+ IFile sourceFile = location.getSourceFile();
+ return sourceFile.getName() + ":" + location.getPosition().getStartLine() + " - " + sourceFile.getFullPath().removeLastSegments(1);
+ }
+
+ public void addListener(ILabelProviderListener listener) {
+ }
+
+ public void dispose() {
+ }
+
+ public boolean isLabelProperty(Object element, String property) {
+ return false;
+ }
+
+ public void removeListener(ILabelProviderListener listener) {
+ }
+ }
+
+
+}
Added: trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/RemoteTestRunnerClient.java
===================================================================
--- trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/RemoteTestRunnerClient.java (rev 0)
+++ trunk/org.rubypeople.rdt.testunit/src/org/rubypeople/rdt/internal/testunit/ui/RemoteTestRunnerClient.java 2006-12-15 15:39:49 UTC (rev 1711)
@@ -0,0 +1,534 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Julien Ruaux: jr...@oc...
+ * Vincent Massol: vm...@oc...
+ ******************************************************************************/
+package org.rubypeople.rdt.internal.testunit.ui;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.SafeRunner;
+import org.rubypeople.rdt.internal.testunit.runner.MessageIds;
+import org.rubypeople.rdt.testunit.ITestRunListener;
+
+/**
+ * The client side of the RemoteTestRunner. Handles the marshaling of the
+ * different messages.
+ */
+public class RemoteTestRunnerClient {
+
+ public abstract class ListenerSafeRunnable implements ISafeRunnable {
+
+ public void handleException(Throwable exception) {
+ TestunitPlugin.log(exception);
+ }
+ }
+
+ /**
+ * A simple state machine to process requests from the RemoteTestRunner
+ */
+ abstract class ProcessingState {
+
+ abstract ProcessingState readMessage(String message);
+ }
+
+ class DefaultProcessingState extends ProcessingState {
+
+ ProcessingState readMessage(String message) {
+ if (message.startsWith(MessageIds.TRACE_START)) {
+ fFailedTrace = ""; //$NON-NLS-1$
+ return fTraceState;
+ }
+ if (message.startsWith(MessageIds.EXPECTED_START)) {
+ fExpectedResult = null;
+ return fExpectedState;
+ }
+ if (message.startsWith(MessageIds.ACTUAL_START)) {
+ fActualResult = null;
+ return fActualState;
+ }
+ if (message.startsWith(MessageIds.RTRACE_START)) {
+ fFailedRerunTrace = ""; //$NON-NLS-1$
+ return fRerunState;
+ }
+ String arg = message.substring(MessageIds.MSG_HEADER_LENGTH);
+ if (message.startsWith(MessageIds.TEST_RUN_START)) {
+ // version < 2 format: count
+ // version >= 2 format: count+" "+version
+ int count = 0;
+ int v = arg.indexOf(' ');
+ if (v == -1) {
+ fVersion = "v1"; //$NON-NLS-1$
+ count = Integer.parseInt(arg);
+ } else {
+ fVersion = arg.substring(v + 1);
+ String sc = arg.substring(0, v);
+ count = Integer.parseInt(sc);
+ }
+ notifyTestRunStarted(count);
+ return this;
+ }
+ if (message.startsWith(MessageIds.TEST_START)) {
+ notifyTestStarted(arg);
+ return this;
+ }
+ if (message.startsWith(MessageIds.TEST_END)) {
+ notifyTestEnded(arg);
+ return this;
+ }
+ if (message.startsWith(MessageIds.TEST_ERROR)) {
+ extractFailure(arg, ITestRunListener.STATUS_ERROR);
+ return this;
+ }
+ if (message.startsWith(MessageIds.TEST_FAILED)) {
+ extractFailure(arg, ITestRunListener.STATUS_FAILURE);
+ return this;
+ }
+ if (message.startsWith(MessageIds.TEST_RUN_END)) {
+ long elapsedTime = Long.parseLong(arg);
+ testRunEnded(elapsedTime);
+ return this;
+ }
+ if (message.startsWith(MessageIds.TEST_STOPPED)) {
+ long elapsedTime = Long.parseLong(arg);
+ notifyTestRunStopped(elapsedTime);
+ shutDown();
+ return this;
+ }
+ if (message.startsWith(MessageIds.TEST_TREE)) {
+ notifyTestTreeEntry(arg);
+ return this;
+ }
+ if (message.startsWith(MessageIds.TEST_RERAN)) {
+ if (hasTestId())
+ scanReranMessage(arg);
+ else
+ scanOldReranMessage(arg);
+ return this;
+ }
+ return this;
+ }
+ }
+
+ class TraceProcessingState extends ProcessingState {
+
+ ProcessingState readMessage(String message) {
+ if (message.startsWith(MessageIds.TRACE_END)) {
+ notifyTestFailed();
+ fFailedTrace = ""; //$NON-NLS-1$
+ fExpectedResult = null;
+ fActualResult = null;
+ return fDefaultState;
+ }
+ fFailedTrace += message + '\n';
+ return this;
+ }
+ }
+
+ class ExpectedProcessingState extends ProcessingState {
+
+ ProcessingState readMessage(String message) {
+ if (message.startsWith(MessageIds.EXPECTED_END)) return fDefaultState;
+ if (fExpectedResult == null)
+ fExpectedResult = message + '\n';
+ else
+ fExpectedResult += message + '\n';
+ return this;
+ }
+ }
+
+ class ActualProcessingState extends ProcessingState {
+
+ ProcessingState readMessage(String message) {
+ if (message.startsWith(MessageIds.ACTUAL_END)) return fDefaultState;
+ if (fActualResult == null)
+ fActualResult = message + '\n';
+ else
+ fActualResult += message + '\n';
+ return this;
+ }
+ }
+
+ class RerunTraceProcessingState extends ProcessingState {
+
+ ProcessingState readMessage(String message) {
+ if (message.startsWith(MessageIds.RTRACE_END)) return fDefaultState;
+ fFailedRerunTrace += message + '\n';
+ return this;
+ }
+ }
+
+ ProcessingState fDefaultState = new DefaultProcessingState();
+ ProcessingState fTraceState = new TraceProcessingState();
+ ProcessingState fExpectedState = new ExpectedProcessingState();
+ ProcessingState fActualState = new ActualProcessingState();
+ ProcessingState fRerunState = new RerunTraceProcessingState();
+ ProcessingState fCurrentState = fDefaultState;
+
+ /**
+ * An array of listeners that are informed about test events.
+ */
+ private ITestRunListener[] fListeners;
+
+ /**
+ * The server socket
+ */
+ private ServerSocket fServerSocket;
+ private Socket fSocket;
+ private int fPort = -1;
+ private PrintWriter fWriter;
+ private BufferedReader fBufferedReader;
+ /**
+ * The protocol version
+ */
+ private String fVersion;
+ /**
+ * The failed test that is currently reported from the RemoteTestRunner
+ */
+ private String fFailedTest;
+ /**
+ * The Id of the failed test
+ */
+ private String fFailedTestId;
+ /**
+ * The failed trace that is currently reported from the RemoteTestRunner
+ */
+ private String fFailedTrace;
+ /**
+ * The expected test result
+ */
+ private String fExpectedResult;
+ /**
+ * The actual test result
+ */
+ private String fActualResult;
+ /**
+ * The failed trace of a reran test
+ */
+ private String fFailedRerunTrace;
+ /**
+ * The kind of failure of the test that is currently reported as failed
+ */
+ private int fFailureKind;
+
+ private boolean fDebug = false;
+
+ /**
+ * Reads the message stream from the RemoteTestRunner
+ */
+ private class ServerConnection extends Thread {
+
+ int fServerPort;
+
+ public ServerConnection(int port) {
+ super("ServerConnection"); //$NON-NLS-1$
+ fServerPort = port;
+ }
+
+ public void run() {
+ try {
+ if (fDebug) System.out.println("Creating server socket " + fServerPort); //$NON-NLS-1$
+ fServerSocket = new ServerSocket(fServerPort);
+ fSocket = fServerSocket.accept();
+ try {
+ fBufferedReader = new BufferedReader(new InputStreamReader(fSocket.getInputStream(), "UTF-8")); //$NON-NLS-1$
+ } catch (UnsupportedEncodingException e) {
+ fBufferedReader = new BufferedReader(new InputStreamReader(fSocket.getInputStream()));
+ }
+ try {
+ fWriter = new PrintWriter(new OutputStreamWriter(fSocket.getOutputStream(), "UTF-8"), true); //$NON-NLS-1$
+ } catch (UnsupportedEncodingException e1) {
+ fWriter = new PrintWriter(new OutputStreamWriter(fSocket.getOutputStream()), true);
+ }
+ String message;
+ while (fBufferedReader != null && (message = readMessage(fBufferedReader)) != null)
+ receiveMessage(message);
+ } catch (SocketException e) {
+ notifyTestRunTerminated();
+ } catch (IOException e) {
+ System.out.println(e);
+ // fall through
+ }
+ shutDown();
+ }
+ }
+
+ /**
+ * Start listening to a test run. Start a server connection that the
+ * RemoteTestRunner can connect to.
+ */
+ public synchronized void startListening(ITestRunListener[] listeners, int port) {
+ fListeners = listeners;
+ fPort = port;
+ ServerConnection connection = new ServerConnection(port);
+ connection.start();
+ }
+
+ /**
+ * Requests to stop the remote test run.
+ */
+ public synchronized void stopTest() {
+ if (isRunning()) {
+ fWriter.println(MessageIds.TEST_STOP);
+ fWriter.flush();
+ }
+ }
+
+ private synchronized void shutDown() {
+ if (fDebug) System.out.println("shutdown " + fPort); //$NON-NLS-1$
+
+ if (fWriter != null) {
+ fWriter.close();
+ fWriter = null;
+ }
+ try {
+ if (fBufferedReader != null) {
+ fBufferedReader.close();
+ fBufferedReader = null;
+ }
+ } catch (IOException e) {}
+ try {
+ if (fSocket != null) {
+ fSocket.close();
+ fSocket = null;
+ }
+ } catch (IOException e) {}
+ try {
+ if (fServerSocket != null) {
+ fServerSocket.close();
+ fServerSocket = null;
+ }
+ } catch (IOException e) {}
+ }
+
+ public boolean isRunning() {
+ return fSocket != null;
+ }
+
+ private String readMessage(BufferedReader in) throws IOException {
+ return in.readLine();
+ }
+
+ private void receiveMessage(String message) {
+ fCurrentState = fCurrentState.readMessage(message);
+ }
+
+ private void scanOldReranMessage(String arg) {
+ // OLD V1 format
+ // format: className" "testName" "status
+ // status: FAILURE, ERROR, OK
+ int c = arg.indexOf(" "); //$NON-NLS-1$
+ int t = arg.indexOf(" ", c + 1); //$NON-NLS-1$
+ String className = arg.substring(0, c);
+ String testName = arg.substring(c + 1, t);
+ String status = arg.substring(t + 1);
+ int statusCode = ITestRunListener.STATUS_OK;
+ if (status.equals("FAILURE")) //$NON-NLS-1$
+ statusCode = ITestRunListener.STATUS_FAILURE;
+ else if (status.equals("ERROR")) //$NON-NLS-1$
+ statusCode = ITestRunListener.STATUS_ERROR;
+
+ String trace = ""; //$NON-NLS-1$
+ if (statusCode != ITestRunListener.STATUS_OK) trace = fFailedRerunTrace;
+ // assumption a rerun trace was sent before
+ notifyTestReran(className + testName, className, testName, statusCode, trace);
+ }
+
+ private void scanReranMessage(String arg) {
+ // format: testId" "className" "testName" "status
+ // status: FAILURE, ERROR, OK
+ int i = arg.indexOf(' ');
+ int c = arg.indexOf(' ', i + 1); //$NON-NLS-1$
+ int t = arg.indexOf(' ', c + 1); //$NON-NLS-1$
+ String testId = arg.substring(0, i);
+ String className = arg.substring(i + 1, c);
+ String testName = arg.substring(c + 1, t);
+ String status = arg.substring(t + 1);
+ int statusCode = ITestRunListener.STATUS_OK;
+ if (status.equals("FAILURE")) //$NON-NLS-1$
+ statusCode = ITestRunListener.STATUS_FAILURE;
+ else if (status.equals("ERROR")) //$NON-NLS-1$
+ statusCode = ITestRunListener.STATUS_ERROR;
+
+ String trace = ""; //$NON-NLS-1$
+ if (statusCode != ITestRunListener.STATUS_OK) trace = fFailedRerunTrace;
+ // assumption a rerun trace was sent before
+ notifyTestReran(testId, className, testName, statusCode, trace);
+ }
+
+ private void extractFailure(String arg, int status) {
+ String s[] = extractTestId(arg);
+ fFailedTestId = s[0];
+ fFailedTest = s[1];
+ fFailureKind = status;
+ }
+
+ /**
+ * Returns an array with two elements. The first one is the testId, the
+ * second one the testName.
+ */
+ String[] extractTestId(String arg) {
+ String[] result = new String[2];
+ if (!hasTestId()) {
+ result[0] = arg; // use the test name as the test Id
+ result[1] = arg;
+ return result;
+ }
+ int i = arg.indexOf(',');
+ result[0] = arg.substring(0, i);
+ result[1] = arg.substring(i + 1, arg.length());
+ return result;
+ }
+
+ private boolean hasTestId() {
+ if (fVersion == null) // TODO fix me
+ return true;
+ return fVersion.equals("v2"); //$NON-NLS-1$
+ }
+
+ private void notifyTestReran(final String testId, final String className, final String testName, final int statusCode, final String trace) {
+ for (int i = 0; i < fListeners.length; i++) {
+ final ITestRunListener listener = fListeners[i];
+ SafeRunner.run(new ListenerSafeRunnable() {
+
+ public void run() {
+ if (listener instance...
[truncated message content] |