View | Details | Raw Unified | Return to bug 372588 | Differences between
and this patch

Collapse All | Expand All

(-)a/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/model/TestCaseElement.java (-1 / +126 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Xavier Coulon <xcoulon@redhat.com> -  [JUnit] Add "Link with Editor" to JUnit view - https://bugs.eclipse.org/bugs/show_bug.cgi?id=372588
10
 *******************************************************************************/
11
 *******************************************************************************/
11
12
12
package org.eclipse.jdt.internal.junit.model;
13
package org.eclipse.jdt.internal.junit.model;
Lines 14-23 Link Here
14
import org.eclipse.jdt.junit.model.ITestCaseElement;
15
import org.eclipse.jdt.junit.model.ITestCaseElement;
15
16
16
import org.eclipse.core.runtime.Assert;
17
import org.eclipse.core.runtime.Assert;
18
import org.eclipse.core.runtime.IAdaptable;
17
19
20
import org.eclipse.jdt.core.IJavaElement;
21
import org.eclipse.jdt.core.IJavaProject;
22
import org.eclipse.jdt.core.IMethod;
23
import org.eclipse.jdt.core.IType;
24
import org.eclipse.jdt.core.JavaModelException;
18
25
19
public class TestCaseElement extends TestElement implements ITestCaseElement {
26
import org.eclipse.jdt.internal.junit.JUnitCorePlugin;
20
27
28
/**
29
 * 
30
 * @since 3.7 implements {@link IAdaptable}
31
 */
32
public class TestCaseElement extends TestElement implements ITestCaseElement, IAdaptable {
33
34
	private IType fJavaType = null;
35
36
	private IMethod fJavaMethod = null;
37
	
21
	private boolean fIgnored;
38
	private boolean fIgnored;
22
39
23
	public TestCaseElement(TestSuiteElement parent, String id, String testName) {
40
	public TestCaseElement(TestSuiteElement parent, String id, String testName) {
Lines 41-46 Link Here
41
			return testName.substring(0, index);
58
			return testName.substring(0, index);
42
		return testName;
59
		return testName;
43
	}
60
	}
61
	
62
	/**
63
	 * {@inheritDoc}
64
	 * @see org.eclipse.jdt.junit.model.ITestCaseElement#getJavaMethod()
65
	 */
66
	public IMethod getJavaMethod() {
67
		if(fJavaMethod == null) {
68
			try {
69
				String testMethodName= getTestMethodName();
70
				// parameterized tests show an index that should be removed from the name
71
				final int index= testMethodName.indexOf('[');
72
				if (index != -1) {
73
					fJavaMethod= findJavaMethod(testMethodName.substring(0, index));
74
				} else {
75
					fJavaMethod= findJavaMethod(testMethodName);
76
				}
77
			} catch (JavaModelException e) {
78
				JUnitCorePlugin.log(e);
79
			}
80
		}
81
		return fJavaMethod;
82
	}
83
	
84
	/**
85
	 * Finds and returns the {@link IMethod} associated with this {@link TestCaseElement}.
86
	 * 
87
	 * @param methodName the name of the method to find 
88
	 * @return the corresponding Java method element or null if not found.
89
	 * @throws JavaModelException if the inspection of one of the java elements in the given editor failed.
90
	 */
91
	private IMethod findJavaMethod(final String methodName) throws JavaModelException {
92
		final IType type= getJavaType();
93
		if(type != null) {
94
			final IMethod[] methods= type.getMethods();
95
			for (int i = 0; i < methods.length; i++) {
96
				if (methods[i].getElementName().equals(methodName)) {
97
					return methods[i];
98
				}
99
			}
100
		}
101
		return null;
102
	}
44
103
45
	/**
104
	/**
46
	 * {@inheritDoc}
105
	 * {@inheritDoc}
Lines 48-53 Link Here
48
	 */
107
	 */
49
	public String getTestClassName() {
108
	public String getTestClassName() {
50
		return getClassName();
109
		return getClassName();
110
	}
111
112
	/**
113
	 * @return the Java {@link IType} associated with this {@link TestCaseElement}.
114
	 * {@inheritDoc}
115
	 * @see org.eclipse.jdt.junit.model.ITestCaseElement#getJavaType()
116
	 */
117
	public IType getJavaType() {
118
		if(fJavaType == null) {
119
			try {
120
				String[] items= getTestClassName().split("\\."); //$NON-NLS-1$
121
				StringBuffer buffer= new StringBuffer();
122
				boolean primaryTypeFound= false;
123
				for (int i= 0; i < items.length; i++) {
124
					buffer.append(items[i]);
125
					boolean firstChar= Character.isUpperCase(items[i].charAt(0));
126
					if (firstChar && !primaryTypeFound) {
127
						primaryTypeFound= true;
128
					}
129
					if (i < items.length - 1) {
130
						if (primaryTypeFound) {
131
							buffer.append('$');
132
						} else {
133
							buffer.append('.');
134
						}
135
					}
136
				}
137
				fJavaType= getTestRunSession().getLaunchedProject().findType(buffer.toString());
138
			} catch (JavaModelException e) {
139
				JUnitCorePlugin.log(e);
140
			}
141
		}
142
		return fJavaType;
51
	}
143
	}
52
144
53
	/*
145
	/*
Lines 72-75 Link Here
72
	public String toString() {
164
	public String toString() {
73
		return "TestCase: " + getTestClassName() + "." + getTestMethodName() + " : " + super.toString(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
165
		return "TestCase: " + getTestClassName() + "." + getTestMethodName() + " : " + super.toString(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
74
	}
166
	}
167
168
	/**
169
	 * Provides support for converting this {@link TestCaseElement} into an {@link IJavaElement}.
170
	 * @param adapter the class in which this {@link TestCaseElement} should be adapted.
171
	 * @return an object in the request type, or null if it could not be adapted.
172
	 * @since 3.7
173
	 */
174
	public Object getAdapter(Class adapter) {
175
		if(adapter != null && adapter.equals(IJavaElement.class)) {
176
			if(fJavaMethod == null) {
177
				try {
178
					final IJavaProject launchedProject= getTestRunSession().getLaunchedProject();
179
					final IType type= launchedProject.findType(this.getTestClassName());
180
					if(type != null && type.exists()) {
181
						final IMethod[] methods= type.getMethods();
182
						if(methods != null) {
183
							for(int i = 0; i < methods.length; i++) {
184
								if(methods[i].getElementName().equals(this.getJavaMethod())) {
185
									fJavaMethod = methods[i];
186
									break;
187
								}
188
							}
189
						}
190
					}
191
192
				} catch (JavaModelException e) {
193
					JUnitCorePlugin.log(e);
194
				}
195
			}
196
			return fJavaMethod;
197
		}
198
		return null;
199
	}
75
}
200
}
(-)a/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/junit/model/ITestCaseElement.java (+20 lines)
Lines 7-14 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Xavier Coulon <xcoulon@redhat.com> -  [JUnit] Add "Link with Editor" to JUnit view - https://bugs.eclipse.org/bugs/show_bug.cgi?id=372588
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.junit.model;
12
package org.eclipse.jdt.junit.model;
13
14
import org.eclipse.jdt.core.IMethod;
15
import org.eclipse.jdt.core.IType;
12
16
13
/**
17
/**
14
 * Represents a test case element.
18
 * Represents a test case element.
Lines 31-40 Link Here
31
	public String getTestMethodName();
35
	public String getTestMethodName();
32
36
33
	/**
37
	/**
38
	 * Returns the Java method.
39
	 *
40
	 * @return returns the Java method.
41
	 * @since 3.7
42
	 */
43
	public IMethod getJavaMethod();
44
	
45
	/**
34
	 * Returns the qualified type name of the class the test is contained in.
46
	 * Returns the qualified type name of the class the test is contained in.
35
	 *
47
	 *
36
	 * @return the qualified type name of the class the test is contained in.
48
	 * @return the qualified type name of the class the test is contained in.
37
	 */
49
	 */
38
	public String getTestClassName();
50
	public String getTestClassName();
39
51
52
	/**
53
	 * Returns Java type the test is contained in.
54
	 *
55
	 * @return Java type the test is contained in.
56
	 * @since 3.7
57
	 */
58
	public IType getJavaType();
59
	
40
}
60
}
(-)a/org.eclipse.jdt.junit/src/org/eclipse/jdt/internal/junit/ui/TestRunnerViewPart.java (-1 / +63 lines)
Lines 16-21 Link Here
16
 *     Andrew Eisenberg <andrew@eisenberg.as> - [JUnit] Rerun failed first does not work with JUnit4 - https://bugs.eclipse.org/bugs/show_bug.cgi?id=140392
16
 *     Andrew Eisenberg <andrew@eisenberg.as> - [JUnit] Rerun failed first does not work with JUnit4 - https://bugs.eclipse.org/bugs/show_bug.cgi?id=140392
17
 *     Thirumala Reddy Mutchukota <thirumala@google.com> - [JUnit] Avoid rerun test launch on UI thread - https://bugs.eclipse.org/bugs/show_bug.cgi?id=411841
17
 *     Thirumala Reddy Mutchukota <thirumala@google.com> - [JUnit] Avoid rerun test launch on UI thread - https://bugs.eclipse.org/bugs/show_bug.cgi?id=411841
18
 *     Andrew Eisenberg <andrew@eisenberg.as> - [JUnit] Add a monospace font option for the junit results view - https://bugs.eclipse.org/bugs/show_bug.cgi?id=411794
18
 *     Andrew Eisenberg <andrew@eisenberg.as> - [JUnit] Add a monospace font option for the junit results view - https://bugs.eclipse.org/bugs/show_bug.cgi?id=411794
19
 *     Xavier Coulon <xcoulon@redhat.com> -  [JUnit] Add "Link with Editor" to JUnit view - https://bugs.eclipse.org/bugs/show_bug.cgi?id=372588
19
 *******************************************************************************/
20
 *******************************************************************************/
20
package org.eclipse.jdt.internal.junit.ui;
21
package org.eclipse.jdt.internal.junit.ui;
21
22
Lines 96-101 Link Here
96
import org.eclipse.jface.dialogs.MessageDialog;
97
import org.eclipse.jface.dialogs.MessageDialog;
97
import org.eclipse.jface.operation.IRunnableWithProgress;
98
import org.eclipse.jface.operation.IRunnableWithProgress;
98
import org.eclipse.jface.resource.ImageDescriptor;
99
import org.eclipse.jface.resource.ImageDescriptor;
100
import org.eclipse.jface.viewers.ISelection;
99
101
100
import org.eclipse.ui.IActionBars;
102
import org.eclipse.ui.IActionBars;
101
import org.eclipse.ui.IEditorActionBarContributor;
103
import org.eclipse.ui.IEditorActionBarContributor;
Lines 149-154 Link Here
149
151
150
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
152
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
151
153
154
import org.eclipse.jdt.ui.PreferenceConstants;
155
156
import org.eclipse.jdt.internal.ui.actions.AbstractToggleLinkingAction;
152
import org.eclipse.jdt.internal.ui.viewsupport.ViewHistory;
157
import org.eclipse.jdt.internal.ui.viewsupport.ViewHistory;
153
158
154
/**
159
/**
Lines 210-215 Link Here
210
	private Action fPreviousAction;
215
	private Action fPreviousAction;
211
216
212
	private StopAction fStopAction;
217
	private StopAction fStopAction;
218
219
	
220
	/**
221
	 * Helper to open and activate editors.
222
	 * @since 3.7
223
	 */
224
	private LinkWithEditorAction fLinkWithEditorAction;
225
213
	private JUnitCopyAction fCopyAction;
226
	private JUnitCopyAction fCopyAction;
214
	private Action fPasteAction;
227
	private Action fPasteAction;
215
228
Lines 705-710 Link Here
705
			startUpdateJobs();
718
			startUpdateJobs();
706
719
707
			fStopAction.setEnabled(true);
720
			fStopAction.setEnabled(true);
721
			fLinkWithEditorAction.setEnabled(true);
708
			fRerunLastTestAction.setEnabled(true);
722
			fRerunLastTestAction.setEnabled(true);
709
		}
723
		}
710
724
Lines 722-727 Link Here
722
					if (isDisposed())
736
					if (isDisposed())
723
						return;
737
						return;
724
					fStopAction.setEnabled(lastLaunchIsKeptAlive());
738
					fStopAction.setEnabled(lastLaunchIsKeptAlive());
739
					fLinkWithEditorAction.setEnabled(fTestRunSession != null);
725
					updateRerunFailedFirstAction();
740
					updateRerunFailedFirstAction();
726
					processChangesInUI();
741
					processChangesInUI();
727
					if (hasErrorsOrFailures()) {
742
					if (hasErrorsOrFailures()) {
Lines 897-902 Link Here
897
			stopTest();
912
			stopTest();
898
			setEnabled(false);
913
			setEnabled(false);
899
		}
914
		}
915
	}
916
917
	/**
918
	 * This action toggles whether this {@link TestRunnerViewPart} links
919
	 * its selection to the active editor.
920
	 *
921
	 */
922
	private class LinkWithEditorAction extends AbstractToggleLinkingAction {
923
		
924
		LinkWithEditorAction() {
925
			boolean isLinkingEnabled= PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.LINK_BROWSING_JUNIT_TESTS_TO_EDITOR);
926
			setChecked(isLinkingEnabled);
927
		}
928
		
929
		@Override
930
		public void run() {
931
			PreferenceConstants.getPreferenceStore().setValue(PreferenceConstants.LINK_BROWSING_JUNIT_TESTS_TO_EDITOR, isChecked());
932
			setLinkingActive(isChecked());
933
		}
934
	}
935
	
936
	/**
937
	 * @return {@code true} if the {@link LinkWithEditorAction} is checked, false otherwise.
938
	 * @since 3.7
939
	 */
940
	public boolean isLinkWithEditorActive() {
941
		return fLinkWithEditorAction.isChecked();
900
	}
942
	}
901
943
902
	private class RerunLastAction extends Action {
944
	private class RerunLastAction extends Action {
Lines 1200-1205 Link Here
1200
		}
1242
		}
1201
	}
1243
	}
1202
1244
1245
	/**
1246
	 * Activate the 'Link with Editor' in the current {@link IWorkbenchPage}. 
1247
	 * (The {@link TestViewer} will respond to {@link ISelection} changes.) 
1248
	 * 
1249
	 * @param active boolean to indicate if the link with editor is active ({@code true}) or not ({@code false})
1250
	 * 
1251
	 * @since 3.7
1252
	 */
1253
	public void setLinkingActive(boolean active) {
1254
		fTestViewer.setLinkingActive(getSite().getPage(), active);
1255
	}
1256
	
1203
	private void startUpdateJobs() {
1257
	private void startUpdateJobs() {
1204
		postSyncProcessChanges();
1258
		postSyncProcessChanges();
1205
1259
Lines 1507-1517 Link Here
1507
				startUpdateJobs();
1561
				startUpdateJobs();
1508
1562
1509
				fStopAction.setEnabled(true);
1563
				fStopAction.setEnabled(true);
1564
				fLinkWithEditorAction.setEnabled(true);
1510
1565
1511
			} else /* old or fresh session: don't want jobs at this stage */ {
1566
			} else /* old or fresh session: don't want jobs at this stage */ {
1512
				stopUpdateJobs();
1567
				stopUpdateJobs();
1513
1568
1514
				fStopAction.setEnabled(fTestRunSession.isKeptAlive());
1569
				fStopAction.setEnabled(fTestRunSession.isKeptAlive());
1570
				fLinkWithEditorAction.setEnabled(fTestRunSession != null);
1515
				fTestViewer.expandFirstLevel();
1571
				fTestViewer.expandFirstLevel();
1516
			}
1572
			}
1517
		}
1573
		}
Lines 1579-1584 Link Here
1579
		if (fFailureTrace != null) {
1635
		if (fFailureTrace != null) {
1580
			fFailureTrace.dispose();
1636
			fFailureTrace.dispose();
1581
		}
1637
		}
1638
		//getSite().getPage().removeSelectionListener(fTestViewer);
1582
	}
1639
	}
1583
1640
1584
	private void disposeImages() {
1641
	private void disposeImages() {
Lines 1783-1788 Link Here
1783
		if (!testRunSessions.isEmpty()) {
1840
		if (!testRunSessions.isEmpty()) {
1784
			fTestRunSessionListener.sessionAdded(testRunSessions.get(0));
1841
			fTestRunSessionListener.sessionAdded(testRunSessions.get(0));
1785
		}
1842
		}
1843
		
1786
	}
1844
	}
1787
1845
1788
	private void addDropAdapter(Composite parent) {
1846
	private void addDropAdapter(Composite parent) {
Lines 1887-1892 Link Here
1887
		fStopAction= new StopAction();
1945
		fStopAction= new StopAction();
1888
		fStopAction.setEnabled(false);
1946
		fStopAction.setEnabled(false);
1889
1947
1948
		fLinkWithEditorAction= new LinkWithEditorAction();
1949
		fLinkWithEditorAction.setEnabled(false);
1950
		
1890
		fRerunLastTestAction= new RerunLastAction();
1951
		fRerunLastTestAction= new RerunLastAction();
1891
		IHandlerService handlerService= (IHandlerService) getSite().getWorkbenchWindow().getService(IHandlerService.class);
1952
		IHandlerService handlerService= (IHandlerService) getSite().getWorkbenchWindow().getService(IHandlerService.class);
1892
		IHandler handler = new AbstractHandler() {
1953
		IHandler handler = new AbstractHandler() {
Lines 1937-1943 Link Here
1937
		toolBar.add(fRerunFailedFirstAction);
1998
		toolBar.add(fRerunFailedFirstAction);
1938
		toolBar.add(fStopAction);
1999
		toolBar.add(fStopAction);
1939
		toolBar.add(fViewHistory.createHistoryDropDownAction());
2000
		toolBar.add(fViewHistory.createHistoryDropDownAction());
1940
2001
		toolBar.add(new Separator());
2002
		toolBar.add(fLinkWithEditorAction);
1941
2003
1942
		viewMenu.add(fShowTestHierarchyAction);
2004
		viewMenu.add(fShowTestHierarchyAction);
1943
		viewMenu.add(fShowTimeAction);
2005
		viewMenu.add(fShowTimeAction);
(-)a/org.eclipse.jdt.junit/src/org/eclipse/jdt/internal/junit/ui/TestViewer.java (+291 lines)
Lines 9-14 Link Here
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Brock Janiczak (brockj@tpg.com.au)
10
 *     Brock Janiczak (brockj@tpg.com.au)
11
 *         - https://bugs.eclipse.org/bugs/show_bug.cgi?id=102236: [JUnit] display execution time next to each test
11
 *         - https://bugs.eclipse.org/bugs/show_bug.cgi?id=102236: [JUnit] display execution time next to each test
12
 *     Xavier Coulon <xcoulon@redhat.com> -  [JUnit] Add "Link with Editor" to JUnit view - https://bugs.eclipse.org/bugs/show_bug.cgi?id=372588
12
 *******************************************************************************/
13
 *******************************************************************************/
13
14
14
package org.eclipse.jdt.internal.junit.ui;
15
package org.eclipse.jdt.internal.junit.ui;
Lines 21-27 Link Here
21
import java.util.List;
22
import java.util.List;
22
import java.util.ListIterator;
23
import java.util.ListIterator;
23
24
25
import org.eclipse.jdt.junit.model.ITestCaseElement;
24
import org.eclipse.jdt.junit.model.ITestElement;
26
import org.eclipse.jdt.junit.model.ITestElement;
27
import org.eclipse.jdt.junit.model.ITestSuiteElement;
25
28
26
import org.eclipse.swt.SWT;
29
import org.eclipse.swt.SWT;
27
import org.eclipse.swt.dnd.Clipboard;
30
import org.eclipse.swt.dnd.Clipboard;
Lines 38-44 Link Here
38
import org.eclipse.jface.action.MenuManager;
41
import org.eclipse.jface.action.MenuManager;
39
import org.eclipse.jface.action.Separator;
42
import org.eclipse.jface.action.Separator;
40
import org.eclipse.jface.viewers.AbstractTreeViewer;
43
import org.eclipse.jface.viewers.AbstractTreeViewer;
44
import org.eclipse.jface.viewers.IPostSelectionProvider;
45
import org.eclipse.jface.viewers.ISelection;
41
import org.eclipse.jface.viewers.ISelectionChangedListener;
46
import org.eclipse.jface.viewers.ISelectionChangedListener;
47
import org.eclipse.jface.viewers.ISelectionProvider;
42
import org.eclipse.jface.viewers.IStructuredSelection;
48
import org.eclipse.jface.viewers.IStructuredSelection;
43
import org.eclipse.jface.viewers.SelectionChangedEvent;
49
import org.eclipse.jface.viewers.SelectionChangedEvent;
44
import org.eclipse.jface.viewers.StructuredSelection;
50
import org.eclipse.jface.viewers.StructuredSelection;
Lines 48-59 Link Here
48
import org.eclipse.jface.viewers.Viewer;
54
import org.eclipse.jface.viewers.Viewer;
49
import org.eclipse.jface.viewers.ViewerFilter;
55
import org.eclipse.jface.viewers.ViewerFilter;
50
56
57
import org.eclipse.jface.text.ITextSelection;
58
59
import org.eclipse.ui.IEditorPart;
60
import org.eclipse.ui.IEditorReference;
61
import org.eclipse.ui.IPartListener2;
62
import org.eclipse.ui.ISelectionListener;
51
import org.eclipse.ui.IWorkbenchActionConstants;
63
import org.eclipse.ui.IWorkbenchActionConstants;
64
import org.eclipse.ui.IWorkbenchPage;
65
import org.eclipse.ui.IWorkbenchPart;
66
import org.eclipse.ui.IWorkbenchPartReference;
67
import org.eclipse.ui.PartInitException;
52
import org.eclipse.ui.part.PageBook;
68
import org.eclipse.ui.part.PageBook;
53
69
54
import org.eclipse.debug.core.ILaunchManager;
70
import org.eclipse.debug.core.ILaunchManager;
55
71
72
import org.eclipse.jdt.core.ICompilationUnit;
73
import org.eclipse.jdt.core.IJavaElement;
56
import org.eclipse.jdt.core.IJavaProject;
74
import org.eclipse.jdt.core.IJavaProject;
75
import org.eclipse.jdt.core.IMethod;
57
import org.eclipse.jdt.core.IType;
76
import org.eclipse.jdt.core.IType;
58
import org.eclipse.jdt.core.JavaModelException;
77
import org.eclipse.jdt.core.JavaModelException;
59
78
Lines 64-69 Link Here
64
import org.eclipse.jdt.internal.junit.model.TestRunSession;
83
import org.eclipse.jdt.internal.junit.model.TestRunSession;
65
import org.eclipse.jdt.internal.junit.model.TestSuiteElement;
84
import org.eclipse.jdt.internal.junit.model.TestSuiteElement;
66
85
86
import org.eclipse.jdt.ui.JavaUI;
87
88
import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor;
89
import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
90
import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
67
import org.eclipse.jdt.internal.ui.viewsupport.ColoringLabelProvider;
91
import org.eclipse.jdt.internal.ui.viewsupport.ColoringLabelProvider;
68
import org.eclipse.jdt.internal.ui.viewsupport.SelectionProviderMediator;
92
import org.eclipse.jdt.internal.ui.viewsupport.SelectionProviderMediator;
69
93
Lines 164-169 Link Here
164
		registerViewersRefresh();
188
		registerViewersRefresh();
165
189
166
		initContextMenu();
190
		initContextMenu();
191
		
192
		// re-activate the "Link with editor" from start if it was enabled in the previous
193
		// instance of the workbench.
194
		if(runner.isLinkWithEditorActive()) {
195
			setLinkingActive(runner.getSite().getPage(), true);
196
		}
197
167
	}
198
	}
168
199
169
	private void createTestViewers(Composite parent) {
200
	private void createTestViewers(Composite parent) {
Lines 302-307 Link Here
302
			testElement= (TestElement) selection.getFirstElement();
333
			testElement= (TestElement) selection.getFirstElement();
303
		}
334
		}
304
		fTestRunnerPart.handleTestSelected(testElement);
335
		fTestRunnerPart.handleTestSelected(testElement);
336
		// if LinkWithEditor is active, reveal the JavaEditor and select the java method 
337
		// matching the selected test element, even if the JavaEditor is opened by not active.
338
		if(fTestRunnerPart.isLinkWithEditorActive() && testElement instanceof TestCaseElement) {
339
			handleTestSelected((TestCaseElement) testElement);
340
		}
341
	}
342
	
343
	/**
344
	 * Reacts to a selection change in another {@link IWorkbenchPart}. If the given
345
	 * {@link ISelection} matches an existing {@link TestCaseElement} in the viewer, this later will
346
	 * be selected.
347
	 * 
348
	 * @param part the part in which the selection changed.
349
	 * @param selection the new selection
350
	 * 
351
	 * @since 3.7
352
	 */
353
	public void selectionChanged(IWorkbenchPart part, ISelection selection) {
354
		if(fTestRunnerPart.isLinkWithEditorActive() && fTestRunnerPart.isLinkWithEditorActive() && part instanceof CompilationUnitEditor) {
355
			setSelection((CompilationUnitEditor)part);
356
		}
305
	}
357
	}
306
358
307
	public synchronized void setShowTime(boolean showTime) {
359
	public synchronized void setShowTime(boolean showTime) {
Lines 568-573 Link Here
568
			fTreeViewer.reveal(current);
620
			fTreeViewer.reveal(current);
569
	}
621
	}
570
622
623
	/**
624
	 * Sets the current selection from the given {@link CompilationUnitEditor} and its selection.
625
	 * @param editor the selected Java Element in the active Java Editor
626
	 * 
627
	 */
628
	private void setSelection(final CompilationUnitEditor editor) {
629
		final ISelectionProvider selectionProvider = editor.getSelectionProvider();
630
		final IJavaElement selectedJavaElement= getSelectedJavaElementInEditor(JavaUI.getEditorInputJavaElement(editor.getEditorInput()), selectionProvider.getSelection());
631
		if(selectedJavaElement != null) {
632
			setSelection(selectedJavaElement);
633
			fJavaEditorSelectionListener = new JavaEditorSelectionListener((ICompilationUnit)selectedJavaElement.getAncestor(IJavaElement.COMPILATION_UNIT));
634
			((IPostSelectionProvider)editor.getSelectionProvider()).addPostSelectionChangedListener(fJavaEditorSelectionListener);
635
		}
636
	}
637
638
	/**
639
	 * Selects the  the current selection from the given {@link IJavaElement} if it is an {@link IMethod}
640
	 * @param activeJavaElement the selected Java Element in the active Java Editor
641
	 * 
642
	 */
643
	private void setSelection(final IJavaElement activeJavaElement) {
644
		// select the method in the JUnit ViewPart
645
		// skip if history was cleared and 'Link with Editor' is still enabled.
646
		if(fTestRunSession != null && activeJavaElement != null && activeJavaElement.getElementType() == IJavaElement.METHOD) {
647
			final IMethod activeJavaMethod = (IMethod)activeJavaElement;
648
			final IType activeJavaType = (IType)activeJavaMethod.getAncestor(IJavaElement.TYPE);
649
			final String testClassName= activeJavaType.getFullyQualifiedName();
650
			final String testMethodName= activeJavaMethod.getElementName();
651
			final ITestCaseElement activeTestCaseElement = findTestCaseElement(fTestRunSession.getTestRoot(), testClassName, testMethodName);
652
			if(activeTestCaseElement != null) {
653
				final StructuredSelection selection= new StructuredSelection(activeTestCaseElement);
654
				if(!selection.equals(getActiveViewer().getSelection())) {
655
					fSelectionProvider.setSelection(selection, true);
656
				}
657
			}
658
			
659
		}		
660
	}
661
	
662
	private ITestCaseElement findTestCaseElement(final ITestSuiteElement parentElement, final String testClassName, final String testMethodName) {
663
		for(ITestElement childElement : parentElement.getChildren()) {
664
			if(childElement instanceof ITestCaseElement) {
665
				ITestCaseElement testCaseElement = (ITestCaseElement)childElement;
666
				if (testCaseElement.getJavaType() != null && testCaseElement.getJavaType().getFullyQualifiedName().equals(testClassName) && testCaseElement.getJavaMethod() != null
667
						&& testCaseElement.getJavaMethod().getElementName().equals(testMethodName)) {
668
					return testCaseElement;
669
				}
670
			} else if(childElement instanceof ITestSuiteElement) {
671
				final ITestCaseElement localResult= findTestCaseElement((ITestSuiteElement)childElement, testClassName, testMethodName);
672
				if(localResult != null) {
673
					return localResult;
674
				}
675
			}
676
		}
677
		return null;
678
679
	}
680
	
571
	public void selectFirstFailure() {
681
	public void selectFirstFailure() {
572
		TestCaseElement firstFailure= getNextChildFailure(fTestRunSession.getTestRoot(), true);
682
		TestCaseElement firstFailure= getNextChildFailure(fTestRunSession.getTestRoot(), true);
573
		if (firstFailure != null)
683
		if (firstFailure != null)
Lines 680-685 Link Here
680
	public void expandFirstLevel() {
790
	public void expandFirstLevel() {
681
		fTreeViewer.expandToLevel(2);
791
		fTreeViewer.expandToLevel(2);
682
	}
792
	}
793
	
794
	/**
795
	 * Links the selected test method with the Java Editor
796
	 * @param page the currently active page
797
	 * @param active boolean to indicate if the link with editor is enabled ({@code true}) or not ({@code false})
798
	 * 
799
	 * @since 3.7
800
	 */
801
	public void setLinkingActive(final IWorkbenchPage page, final boolean active) {
802
		if(page == null) {
803
			return;
804
		}
805
		if (active) {
806
			// add an IPartListener for future editor activations/opening/closing/etc.
807
			page.addPartListener(fLinkWithEditorPartListener);
808
			page.addPostSelectionListener(fLinkWithEditorSelectionListener);
809
			if(page.getActiveEditor() instanceof CompilationUnitEditor) {
810
				setSelection((CompilationUnitEditor)page.getActiveEditor());
811
			}
812
		} else {
813
			// removes the IPartListener
814
			page.removePartListener(fLinkWithEditorPartListener);
815
			page.removePostSelectionListener(fLinkWithEditorSelectionListener);
816
		}
817
	}
818
	
819
	private final IPartListener2 fLinkWithEditorPartListener= new IPartListener2() {
820
		public void partVisible(IWorkbenchPartReference partRef) {}
821
		public void partBroughtToTop(IWorkbenchPartReference partRef) {}
822
		public void partHidden(IWorkbenchPartReference partRef) {}
823
		public void partOpened(IWorkbenchPartReference partRef) {}
824
		public void partInputChanged(IWorkbenchPartReference partRef) {}
825
		public void partClosed(IWorkbenchPartReference partRef) {}
683
826
827
		public void partActivated(IWorkbenchPartReference partRef) {
828
			if (partRef instanceof IEditorReference) {
829
				editorActivated(((IEditorReference) partRef).getEditor(true));
830
			}
831
		}
832
		
833
		public void partDeactivated(IWorkbenchPartReference partRef) {
834
			if (partRef instanceof IEditorReference) {
835
				editorDeactivated(((IEditorReference) partRef).getEditor(true));
836
			}
837
		}
838
839
	};
840
	
841
	private ISelectionListener fLinkWithEditorSelectionListener = new ISelectionListener() {
842
		
843
		public void selectionChanged(IWorkbenchPart editor, ISelection selection) {
844
			if(editor instanceof CompilationUnitEditor && selection instanceof ITextSelection) {
845
				setSelection((CompilationUnitEditor)editor);
846
			}
847
		}
848
849
	};
850
	
851
	private JavaEditorSelectionListener fJavaEditorSelectionListener;
852
853
	/**
854
	 * Static Inner Java Editor selection listener
855
	 * When the user moves to another 
856
	 * @since 3.7
857
	 */
858
	private class JavaEditorSelectionListener implements ISelectionChangedListener {
859
		
860
		private final ICompilationUnit compilationUnit;
861
862
		JavaEditorSelectionListener(final ICompilationUnit compilationUnit) {
863
			this.compilationUnit = compilationUnit;
864
		}
865
		
866
		public void selectionChanged(final SelectionChangedEvent event) {
867
			IJavaElement selectedJavaElement= getSelectedJavaElementInEditor(compilationUnit, event.getSelection());
868
			setSelection(selectedJavaElement);
869
		}
870
		
871
		/**
872
		 * Overriding java.lang.Object#hashCode() using the
873
		 * {@link ICompilationUnit#getHandleIdentifier()} value to avoid duplicate listener
874
		 * registrations in the {@link JavaEditor}'s {@link IPostSelectionProvider}.
875
		 */
876
		@Override
877
		public int hashCode() {
878
			final int prime= 31;
879
			int result= 1;
880
			result= prime * result + ((compilationUnit == null) ? 0 : compilationUnit.getHandleIdentifier().hashCode());
881
			return result;
882
		}
883
884
		/**
885
		 * Overriding java.lang.Object#equals() using the
886
		 * {@link ICompilationUnit#getHandleIdentifier()} value to avoid duplicate listener
887
		 * registrations in the {@link JavaEditor}'s {@link IPostSelectionProvider}.
888
		 */
889
		@Override
890
		public boolean equals(Object obj) {
891
			if (this == obj) {
892
				return true;
893
			}
894
			if (obj == null) {
895
				return false;
896
			}
897
			if (getClass() != obj.getClass()) {
898
				return false;
899
			}
900
			JavaEditorSelectionListener other= (JavaEditorSelectionListener)obj;
901
			if (compilationUnit == null) {
902
				if (other.compilationUnit != null) {
903
					return false;
904
				}
905
			} else if (!compilationUnit.getHandleIdentifier().equals(other.compilationUnit.getHandleIdentifier())) {
906
				return false;
907
			}
908
			return true;
909
		}
910
	}
911
	
912
	/**
913
	 * An editor has been activated.  Set the selection in this JUnit ViewPart
914
	 * to match the editor's input, if linking is enabled.
915
	 * @param editor the activated editor
916
	 */
917
	private void editorActivated(IEditorPart editor) {
918
		if(!(editor instanceof CompilationUnitEditor)) {
919
			return;
920
		}
921
		CompilationUnitEditor javaEditor= (CompilationUnitEditor)editor;
922
		setSelection(javaEditor);
923
	}
924
925
	private IJavaElement getSelectedJavaElementInEditor(final IJavaElement javaElement, final ISelection selection) {
926
		if(javaElement instanceof ICompilationUnit && selection instanceof ITextSelection) {
927
			try {
928
				return ((ICompilationUnit)javaElement).getElementAt(((ITextSelection)selection).getOffset());
929
			} catch(JavaModelException e) {
930
				JUnitPlugin.log(e);
931
			}
932
		}
933
		return null;
934
	}
935
	
936
	/**
937
	 * An editor has been deactivated. 
938
	 * @param editor the activated editor
939
	 */
940
	private void editorDeactivated(IEditorPart editor) {
941
		if(fJavaEditorSelectionListener != null & editor instanceof CompilationUnitEditor) {
942
			final IPostSelectionProvider selectionProvider = (IPostSelectionProvider)((CompilationUnitEditor)editor).getSelectionProvider();
943
			selectionProvider.removePostSelectionChangedListener(fJavaEditorSelectionListener);
944
		}
945
	}
946
947
	private void handleTestSelected(final TestCaseElement testCaseElement) {
948
		try {
949
			final IType type= testCaseElement.getJavaType();
950
			final IEditorPart editor= EditorUtility.isOpenInEditor(type);
951
			final IMethod selectedMethod= testCaseElement.getJavaMethod();
952
			if(selectedMethod != null && editor != null && editor instanceof JavaEditor) {
953
				final JavaEditor javaEditor = (JavaEditor)editor;
954
				final ITextSelection javaEditorSelection= (ITextSelection)javaEditor.getSelectionProvider().getSelection();
955
				final IJavaElement javaEditorSelectedElement= type.getCompilationUnit().getElementAt(javaEditorSelection.getOffset());
956
				IEditorPart selectedMethodEditor = EditorUtility.isOpenInEditor(selectedMethod);
957
				// checks if the editor is already open or not
958
				if(selectedMethodEditor != null) {
959
					EditorUtility.openInEditor(selectedMethod, false);
960
					if(!selectedMethod.equals(javaEditorSelectedElement)) {
961
						EditorUtility.revealInEditor(selectedMethodEditor, selectedMethod);
962
					}
963
				}
964
				if(!selectedMethod.equals(javaEditorSelectedElement)) {
965
					JavaUI.revealInEditor(editor, (IJavaElement)selectedMethod);
966
				}
967
			}
968
		} catch(JavaModelException e) {
969
			JUnitPlugin.log(e);
970
		} catch(PartInitException e) {
971
			// ignore if no editor input can be found
972
		}		
973
	}
974
	
684
}
975
}
685
976
(-)a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/PreferenceConstants.java (+10 lines)
Lines 460-465 Link Here
460
	 */
460
	 */
461
	public static final String LINK_BROWSING_PACKAGES_TO_EDITOR= "org.eclipse.jdt.ui.browsing.packagestoeditor"; //$NON-NLS-1$
461
	public static final String LINK_BROWSING_PACKAGES_TO_EDITOR= "org.eclipse.jdt.ui.browsing.packagestoeditor"; //$NON-NLS-1$
462
462
463
	/**
464
	 * A named preference that controls whether the JUnit view's selection is
465
	 * linked to the active editor.
466
	 * <p>
467
	 * Value is of type <code>Boolean</code>.
468
	 * </p>
469
	 * @since 3.9
470
	 */
471
	public static final String LINK_BROWSING_JUNIT_TESTS_TO_EDITOR= "org.eclipse.jdt.ui.browsing.junitteststoeditor"; //$NON-NLS-1$
472
463
473
464
474
465
	/**
475
	/**

Return to bug 372588