Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 248908 Details for
Bug 372588
[JUnit] Add "Link with Editor" to JUnit view
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Update patch with updated @since tag and file headers
BZ372588---JUnit-Add-Link-with-Editor-to-JUnit-20141125b.patch (text/plain), 30.78 KB, created by
Xavier Coulon
on 2014-11-25 06:04:48 EST
(
hide
)
Description:
Update patch with updated @since tag and file headers
Filename:
MIME Type:
Creator:
Xavier Coulon
Created:
2014-11-25 06:04:48 EST
Size:
30.78 KB
patch
obsolete
>diff --git a/org.eclipse.jdt.junit.core/.gitignore b/org.eclipse.jdt.junit.core/.gitignore >new file mode 100644 >index 0000000..ae3c172 >--- /dev/null >+++ b/org.eclipse.jdt.junit.core/.gitignore >@@ -0,0 +1 @@ >+/bin/ >diff --git a/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/model/TestCaseElement.java b/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/model/TestCaseElement.java >index c4e1dee..a44e440 100644 >--- a/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/model/TestCaseElement.java >+++ b/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/model/TestCaseElement.java >@@ -7,7 +7,9 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Xavier Coulon <xcoulon@redhat.com> - https://bugs.eclipse.org/bugs/show_bug.cgi?id=102512 - [JUnit] test method name cut off before ( >+ * Xavier Coulon <xcoulon@redhat.com> >+ * - [JUnit] test method name cut off before '(' - https://bugs.eclipse.org/bugs/show_bug.cgi?id=102512 >+ * - [JUnit] Add "Link with Editor" to JUnit view - https://bugs.eclipse.org/bugs/show_bug.cgi?id=372588 > *******************************************************************************/ > > package org.eclipse.jdt.internal.junit.model; >@@ -15,15 +17,47 @@ > import org.eclipse.jdt.junit.model.ITestCaseElement; > > import org.eclipse.core.runtime.Assert; >+import org.eclipse.core.runtime.IAdaptable; > >+import org.eclipse.jdt.core.IJavaElement; >+import org.eclipse.jdt.core.IMethod; >+import org.eclipse.jdt.core.IType; >+import org.eclipse.jdt.core.JavaModelException; > >-public class TestCaseElement extends TestElement implements ITestCaseElement { >+import org.eclipse.jdt.internal.junit.JUnitCorePlugin; >+ >+/** >+ * >+ * @since 3.7 implements {@link IAdaptable} >+ */ >+public class TestCaseElement extends TestElement implements ITestCaseElement, IAdaptable { >+ >+ private IMethod fJavaMethod= null; >+ >+ private boolean fJavaMethodResolved= false; > > private boolean fIgnored; > > public TestCaseElement(TestSuiteElement parent, String id, String testName) { > super(parent, id, testName); > Assert.isNotNull(parent); >+ } >+ >+ /** >+ * @return the name of the Java Method associated with this {@link TestCaseElement}, ie, it >+ * returns the valid java identifier part of the name (in particular, it removes the >+ * brackets suffix for Parameterized JUnit tests). >+ * >+ * >+ */ >+ private String getJavaTestMethodName() { >+ String testMethodName= getTestMethodName(); >+ for (int i= 0; i < testMethodName.length(); i++) { >+ if (!Character.isJavaIdentifierPart(testMethodName.charAt(i))) { >+ return testMethodName.substring(0, i); >+ } >+ } >+ return testMethodName; > } > > /** >@@ -41,6 +75,36 @@ > if (index > 0) > return testName.substring(0, index); > return testName; >+ } >+ >+ /** >+ * Finds and returns the {@link IMethod} associated with this {@link TestCaseElement}. >+ * >+ * @return the corresponding Java method element or null if not found. >+ * @since 3.7 >+ */ >+ public IMethod getJavaMethod() { >+ if (!fJavaMethodResolved) { >+ try { >+ final IType type= getJavaType(); >+ if (type != null) { >+ final IMethod[] methods= type.getMethods(); >+ String testMethodName= getJavaTestMethodName(); >+ for (int i= 0; i < methods.length; i++) { >+ if (methods[i].getElementName().equals(testMethodName)) { >+ fJavaMethod= methods[i]; >+ return methods[i]; >+ } >+ } >+ } >+ return null; >+ } catch (JavaModelException e) { >+ JUnitCorePlugin.log(e); >+ } finally { >+ fJavaMethodResolved= true; >+ } >+ } >+ return fJavaMethod; > } > > /** >@@ -73,4 +137,19 @@ > public String toString() { > return "TestCase: " + getTestClassName() + "." + getTestMethodName() + " : " + super.toString(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ > } >+ >+ /** >+ * Provides support for converting this {@link TestCaseElement} into an {@link IMethod} when the >+ * given adapter class is {@link IJavaElement}. >+ * >+ * @param adapter the class in which this {@link TestCaseElement} should be adapted. >+ * @return an object in the request type, or null if it could not be adapted. >+ * @since 3.7 >+ */ >+ public Object getAdapter(Class adapter) { >+ if (adapter != null && adapter.equals(IJavaElement.class)) { >+ return getJavaMethod(); >+ } >+ return null; >+ } > } >diff --git a/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/model/TestElement.java b/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/model/TestElement.java >index 0987059..a754db1 100644 >--- a/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/model/TestElement.java >+++ b/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/model/TestElement.java >@@ -20,6 +20,11 @@ > > import org.eclipse.core.runtime.Assert; > >+import org.eclipse.jdt.core.IType; >+import org.eclipse.jdt.core.JavaModelException; >+ >+import org.eclipse.jdt.internal.junit.JUnitCorePlugin; >+ > > public abstract class TestElement implements ITestElement { > public final static class Status { >@@ -175,6 +180,10 @@ > > private boolean fAssumptionFailed; > >+ private IType fJavaType= null; >+ >+ private boolean fJavaTypeResolved= false; >+ > /** > * Running time in seconds. Contents depend on the current {@link #getProgressState()}: > * <ul> >@@ -324,6 +333,25 @@ > return extractClassName(getTestName()); > } > >+ /** >+ * @return the Java {@link IType} associated with this {@link TestElement}. >+ * @since 3.7 >+ */ >+ public IType getJavaType() { >+ if (!fJavaTypeResolved) { >+ try { >+ fJavaType= getTestRunSession().getLaunchedProject().findType(getClassName()); >+ } catch (JavaModelException e) { >+ JUnitCorePlugin.log(e); >+ } finally { >+ fJavaTypeResolved= true; >+ } >+ } >+ return fJavaType; >+ } >+ >+ >+ > private static String extractClassName(String testNameString) { > testNameString= extractRawClassName(testNameString); > testNameString= testNameString.replace('$', '.'); // see bug 178503 >diff --git a/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/model/TestSuiteElement.java b/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/model/TestSuiteElement.java >index df8c4a5..33d89d7 100644 >--- a/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/model/TestSuiteElement.java >+++ b/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/model/TestSuiteElement.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * Copyright (c) 2000, 2014 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Xavier Coulon <xcoulon@redhat.com> - [JUnit] Add "Link with Editor" to JUnit view - https://bugs.eclipse.org/bugs/show_bug.cgi?id=372588 > *******************************************************************************/ > > package org.eclipse.jdt.internal.junit.model; >@@ -17,8 +18,18 @@ > import org.eclipse.jdt.junit.model.ITestElement; > import org.eclipse.jdt.junit.model.ITestSuiteElement; > >+import org.eclipse.core.runtime.IAdaptable; > >-public class TestSuiteElement extends TestElement implements ITestSuiteElement { >+import org.eclipse.jdt.core.IJavaElement; >+import org.eclipse.jdt.core.IMethod; >+import org.eclipse.jdt.core.IType; >+ >+ >+public class TestSuiteElement extends TestElement implements ITestSuiteElement, IAdaptable { >+ >+ private IJavaElement fJavaElement= null; >+ >+ private boolean fJavaElementResolved= false; > > private List/*<TestElement>*/ fChildren; > private Status fChildrenStatus; >@@ -151,4 +162,60 @@ > return "TestSuite: " + getSuiteTypeName() + " : " + super.toString() + " (" + fChildren.size() + ")"; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ > } > >+ /** >+ * Provides support for converting this {@link TestSuiteElement} into an {@link IType} (or an >+ * {@link IMethod} when this {@link TestSuiteElement} matches a JUnit Parameterized Test) when >+ * the given adapter class is {@link IJavaElement}. >+ * >+ * @param adapter the class in which this {@link TestSuiteElement} should be adapted. >+ * @return an object in the request type, or null if it could not be adapted. >+ * @since 3.7 >+ */ >+ public Object getAdapter(Class adapter) { >+ if (adapter != null && adapter.equals(IJavaElement.class)) { >+ return getJavaElement(); >+ } >+ return null; >+ } >+ >+ /** >+ * Returns the closest {@link IJavaElement} for the given {@link TestSuiteElement}, including >+ * with a work-around for Parameterized tests by looking at the child elements: if there's only >+ * one, return its Java {@link IMethod}. Otherwise, return the {@link IType} >+ * >+ * @return the {@link IJavaElement} found for this {@link TestSuiteElement}. >+ * >+ * @see TestElement#getJavaType() >+ */ >+ public IJavaElement getJavaElement() { >+ if (!fJavaElementResolved) { >+ // whatever happens, let's consider that the Java Type has been resolved, to make sure we don't come back here again for this TestSuitElement. >+ fJavaElementResolved= true; >+ fJavaElement= super.getJavaType(); >+ if (fJavaElement == null) { >+ if (getChildren().length == 1 && getChildren()[0] instanceof TestCaseElement) { >+ fJavaElement= ((TestCaseElement)getChildren()[0]).getJavaMethod(); >+ } >+ } >+ } >+ return fJavaElement; >+ } >+ >+ /** >+ * Returns the {@link IType} associated with the given {@link TestSuiteElement}, or uses the >+ * work-around in {@link TestSuiteElement#getJavaElement()} to retrieve the {@link IType} >+ * associated with the single child {@link TestCaseElement} if this {@link TestSuiteElement} >+ * matches a Parameterized JUnit Test. >+ * >+ * @see TestElement#getJavaType() >+ */ >+ public IType getJavaType() { >+ final IType javaType= super.getJavaType(); >+ if (javaType != null) { >+ return javaType; >+ } else if (getJavaElement() != null) { >+ return (IType)fJavaElement.getAncestor(IJavaElement.TYPE); >+ } >+ return null; >+ } > } >diff --git a/org.eclipse.jdt.junit/.gitignore b/org.eclipse.jdt.junit/.gitignore >new file mode 100644 >index 0000000..ae3c172 >--- /dev/null >+++ b/org.eclipse.jdt.junit/.gitignore >@@ -0,0 +1 @@ >+/bin/ >diff --git a/org.eclipse.jdt.junit/src/org/eclipse/jdt/internal/junit/ui/TestRunnerViewPart.java b/org.eclipse.jdt.junit/src/org/eclipse/jdt/internal/junit/ui/TestRunnerViewPart.java >index 41fe5cc..e261128 100644 >--- a/org.eclipse.jdt.junit/src/org/eclipse/jdt/internal/junit/ui/TestRunnerViewPart.java >+++ b/org.eclipse.jdt.junit/src/org/eclipse/jdt/internal/junit/ui/TestRunnerViewPart.java >@@ -16,6 +16,7 @@ > * Andrew Eisenberg <andrew@eisenberg.as> - [JUnit] Rerun failed first does not work with JUnit4 - https://bugs.eclipse.org/bugs/show_bug.cgi?id=140392 > * Thirumala Reddy Mutchukota <thirumala@google.com> - [JUnit] Avoid rerun test launch on UI thread - https://bugs.eclipse.org/bugs/show_bug.cgi?id=411841 > * 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 >+ * Xavier Coulon <xcoulon@redhat.com> - [JUnit] Add "Link with Editor" to JUnit view - https://bugs.eclipse.org/bugs/show_bug.cgi?id=372588 > *******************************************************************************/ > package org.eclipse.jdt.internal.junit.ui; > >@@ -96,6 +97,7 @@ > import org.eclipse.jface.dialogs.MessageDialog; > import org.eclipse.jface.operation.IRunnableWithProgress; > import org.eclipse.jface.resource.ImageDescriptor; >+import org.eclipse.jface.viewers.ISelection; > > import org.eclipse.ui.IActionBars; > import org.eclipse.ui.IEditorActionBarContributor; >@@ -149,6 +151,8 @@ > > import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; > >+import org.eclipse.jdt.internal.ui.JavaPluginImages; >+import org.eclipse.jdt.internal.ui.actions.AbstractToggleLinkingAction; > import org.eclipse.jdt.internal.ui.viewsupport.ViewHistory; > > /** >@@ -210,6 +214,15 @@ > private Action fPreviousAction; > > private StopAction fStopAction; >+ >+ >+ /** >+ * Helper to open and activate editors. >+ * >+ * @since 3.7 >+ */ >+ private LinkWithEditorAction fLinkWithEditorAction; >+ > private JUnitCopyAction fCopyAction; > private Action fPasteAction; > >@@ -732,6 +745,8 @@ > JavaCore.addElementChangedListener(fDirtyListener); > } > warnOfContentChange(); >+ fLinkWithEditorAction.setEnabled(fTestRunSession != null); >+ setLinkingWithEditorActive(fTestRunSession != null); > } > }); > stopUpdateJobs(); >@@ -897,6 +912,55 @@ > stopTest(); > setEnabled(false); > } >+ } >+ >+ /** >+ * This action toggles whether this {@link TestRunnerViewPart} links its selection to the active >+ * editor. >+ * >+ */ >+ private class LinkWithEditorAction extends AbstractToggleLinkingAction { >+ >+ /** Image to use when the sync is on.*/ >+ private static final String SYNCED_GIF= "synced.gif"; //$NON-NLS-1$ >+ >+ /** Image to use when the sync is broken.*/ >+ private static final String SYNC_BROKEN_GIF= "sync_broken.gif"; //$NON-NLS-1$ >+ >+ private String fIconName = SYNC_BROKEN_GIF; >+ >+ LinkWithEditorAction() { >+ // enable by default >+ setChecked(true); >+ } >+ >+ @Override >+ public void run() { >+ setLinkingWithEditorActive(isChecked()); >+ } >+ >+ /** >+ * Updates the Link image with a "normal link" image if parameter is true, or a >+ * "broken link" image otherwise >+ * >+ * @param isInSync the state of synchronization >+ */ >+ public void updateLinkImage(boolean isInSync) { >+ String iconName= isInSync ? SYNCED_GIF : SYNC_BROKEN_GIF; >+ if (!iconName.equals(fIconName)) { >+ JavaPluginImages.setLocalImageDescriptors(fLinkWithEditorAction, iconName); >+ fIconName= iconName; >+ } >+ } >+ >+ } >+ >+ /** >+ * @return {@code true} if the {@link LinkWithEditorAction} is checked, false otherwise. >+ * @since 3.7 >+ */ >+ public boolean isLinkWithEditorActive() { >+ return fLinkWithEditorAction.isChecked(); > } > > private class RerunLastAction extends Action { >@@ -1198,6 +1262,36 @@ > } > fTestRunSession.stopTestRun(); > } >+ } >+ >+ /** >+ * Activate the 'Link with Editor' in the current {@link IWorkbenchPage}. (The >+ * {@link TestViewer} will respond to {@link ISelection} changes.) >+ * >+ * @param active boolean to indicate if the link with editor is active ({@code true}) or not ( >+ * {@code false}) >+ * >+ * @since 3.8 >+ */ >+ public void setLinkingWithEditorActive(final boolean active) { >+ if (active) { >+ getSite().getPage().addPostSelectionListener(fTestViewer); >+ fTestViewer.setSelection(getSite().getPage().getActiveEditor()); >+ } else { >+ getSite().getPage().removePostSelectionListener(fTestViewer); >+ } >+ } >+ >+ /** >+ * Updates the Link image with a "normal link" image if parameter is true, or a "broken link" >+ * image otherwise >+ * >+ * @param isInSync the state of synchronization >+ * >+ * @since 3.7 >+ */ >+ public void setLinkingWithEditorInSync(final boolean isInSync) { >+ fLinkWithEditorAction.updateLinkImage(isInSync); > } > > private void startUpdateJobs() { >@@ -1507,11 +1601,19 @@ > startUpdateJobs(); > > fStopAction.setEnabled(true); >+ fLinkWithEditorAction.setEnabled(true); > > } else /* old or fresh session: don't want jobs at this stage */ { > stopUpdateJobs(); > > fStopAction.setEnabled(fTestRunSession.isKeptAlive()); >+ fLinkWithEditorAction.setEnabled(fTestRunSession != null); >+ // if "Link with Editor" is active, register the listener >+ if (isLinkWithEditorActive()) { >+ getSite().getPage().addPostSelectionListener(fTestViewer); >+ fTestViewer.setSelection(getSite().getPage().getActiveEditor()); >+ } >+ > fTestViewer.expandFirstLevel(); > } > } >@@ -1579,6 +1681,7 @@ > if (fFailureTrace != null) { > fFailureTrace.dispose(); > } >+ getSite().getPage().removePostSelectionListener(fTestViewer); > } > > private void disposeImages() { >@@ -1887,6 +1990,9 @@ > fStopAction= new StopAction(); > fStopAction.setEnabled(false); > >+ fLinkWithEditorAction= new LinkWithEditorAction(); >+ fLinkWithEditorAction.setEnabled(false); >+ > fRerunLastTestAction= new RerunLastAction(); > IHandlerService handlerService= getSite().getWorkbenchWindow().getService(IHandlerService.class); > IHandler handler = new AbstractHandler() { >@@ -1937,6 +2043,8 @@ > toolBar.add(fRerunFailedFirstAction); > toolBar.add(fStopAction); > toolBar.add(fViewHistory.createHistoryDropDownAction()); >+ toolBar.add(new Separator()); >+ toolBar.add(fLinkWithEditorAction); > > > viewMenu.add(fShowTestHierarchyAction); >diff --git a/org.eclipse.jdt.junit/src/org/eclipse/jdt/internal/junit/ui/TestViewer.java b/org.eclipse.jdt.junit/src/org/eclipse/jdt/internal/junit/ui/TestViewer.java >index 8ff5d29..51402f8 100644 >--- a/org.eclipse.jdt.junit/src/org/eclipse/jdt/internal/junit/ui/TestViewer.java >+++ b/org.eclipse.jdt.junit/src/org/eclipse/jdt/internal/junit/ui/TestViewer.java >@@ -9,8 +9,9 @@ > * IBM Corporation - initial API and implementation > * Brock Janiczak (brockj@tpg.com.au) > * - https://bugs.eclipse.org/bugs/show_bug.cgi?id=102236: [JUnit] display execution time next to each test >- * Xavier Coulon <xcoulon@redhat.com> - https://bugs.eclipse.org/bugs/show_bug.cgi?id=102512 - [JUnit] test method name cut off before ( >- >+ * Xavier Coulon <xcoulon@redhat.com> >+ * - https://bugs.eclipse.org/bugs/show_bug.cgi?id=102512 - [JUnit] test method name cut off before ( >+ * - https://bugs.eclipse.org/bugs/show_bug.cgi?id=372588 - [JUnit] Add "Link with Editor" to JUnit view > *******************************************************************************/ > > package org.eclipse.jdt.internal.junit.ui; >@@ -23,7 +24,9 @@ > import java.util.List; > import java.util.ListIterator; > >+import org.eclipse.jdt.junit.model.ITestCaseElement; > import org.eclipse.jdt.junit.model.ITestElement; >+import org.eclipse.jdt.junit.model.ITestSuiteElement; > > import org.eclipse.swt.SWT; > import org.eclipse.swt.dnd.Clipboard; >@@ -42,8 +45,10 @@ > import org.eclipse.jface.action.MenuManager; > import org.eclipse.jface.action.Separator; > import org.eclipse.jface.viewers.AbstractTreeViewer; >+import org.eclipse.jface.viewers.ISelection; > import org.eclipse.jface.viewers.ISelectionChangedListener; > import org.eclipse.jface.viewers.IStructuredSelection; >+import org.eclipse.jface.viewers.ITreeSelection; > import org.eclipse.jface.viewers.SelectionChangedEvent; > import org.eclipse.jface.viewers.StructuredSelection; > import org.eclipse.jface.viewers.StructuredViewer; >@@ -52,13 +57,22 @@ > import org.eclipse.jface.viewers.Viewer; > import org.eclipse.jface.viewers.ViewerFilter; > >+import org.eclipse.jface.text.ITextSelection; >+ >+import org.eclipse.ui.IEditorPart; >+import org.eclipse.ui.ISelectionListener; > import org.eclipse.ui.IWorkbenchActionConstants; >+import org.eclipse.ui.IWorkbenchPart; >+import org.eclipse.ui.PartInitException; > import org.eclipse.ui.part.PageBook; > > import org.eclipse.debug.core.ILaunchConfiguration; > import org.eclipse.debug.core.ILaunchManager; > >+import org.eclipse.jdt.core.ICompilationUnit; >+import org.eclipse.jdt.core.IJavaElement; > import org.eclipse.jdt.core.IJavaProject; >+import org.eclipse.jdt.core.IMethod; > import org.eclipse.jdt.core.IType; > import org.eclipse.jdt.core.JavaModelException; > >@@ -72,11 +86,16 @@ > > import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; > >+import org.eclipse.jdt.ui.JavaUI; >+ >+import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor; >+import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility; >+import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; > import org.eclipse.jdt.internal.ui.viewsupport.ColoringLabelProvider; > import org.eclipse.jdt.internal.ui.viewsupport.SelectionProviderMediator; > > >-public class TestViewer { >+public class TestViewer implements ISelectionListener { > private final class TestSelectionListener implements ISelectionChangedListener { > public void selectionChanged(SelectionChangedEvent event) { > handleSelected(); >@@ -343,6 +362,11 @@ > testElement= (TestElement) selection.getFirstElement(); > } > fTestRunnerPart.handleTestSelected(testElement); >+ // if LinkWithEditor is active, reveal the JavaEditor and select the java type or method >+ // matching the selected test element, even if the JavaEditor is opened by not active. >+ if (fTestRunnerPart.isLinkWithEditorActive()) { >+ handleTestElementSelected(testElement); >+ } > } > > public synchronized void setShowTime(boolean showTime) { >@@ -609,6 +633,137 @@ > fTreeViewer.reveal(current); > } > >+ /** >+ * Sets the current selection from the given {@link IEditorPart} (if it is a >+ * {@link CompilationUnitEditor}) and its selection. >+ * >+ * @param editor the selected Java Element in the active Compilation Unit Editor >+ * >+ * @since 3.8 >+ */ >+ public void setSelection(final IEditorPart editor) { >+ final IJavaElement selectedJavaElement= getSelectedJavaElementInEditor(editor); >+ setSelection(selectedJavaElement); >+ } >+ >+ /** >+ * Sets the current selection from the given {@link IJavaElement} if it matches an >+ * {@link ITestCaseElement} and updates the LinkWithEditorAction image in the associated >+ * {@link TestRunnerViewPart}. >+ * >+ * @param activeJavaElement the selected Java Element (or null) in the active >+ * {@link IWorkbenchPart} >+ * >+ */ >+ private void setSelection(final IJavaElement activeJavaElement) { >+ final ITestElement activeTestCaseElement= findTestElement(activeJavaElement); >+ if (activeTestCaseElement != null) { >+ // selection is in-sync >+ fTestRunnerPart.setLinkingWithEditorInSync(true); >+ // update the current selection in the viewer if it does not match with the java element selected in the given part (if it's not the parent TestViewerPart) >+ final Object currentSelection= getCurrentViewerSelection(); >+ if ((currentSelection instanceof TestCaseElement && ((TestCaseElement)currentSelection).getJavaMethod() != null && !((TestCaseElement)currentSelection).getJavaMethod().equals( >+ activeJavaElement)) >+ || (currentSelection instanceof TestSuiteElement && ((TestSuiteElement)currentSelection).getJavaType() != null && !((TestSuiteElement)currentSelection).getJavaType().equals( >+ activeJavaElement))) { >+ final IStructuredSelection selection= new StructuredSelection(activeTestCaseElement); >+ fSelectionProvider.setSelection(selection, true); >+ } >+ } >+ else { >+ // selection is out-of-sync: show a different icon on the button. >+ fTestRunnerPart.setLinkingWithEditorInSync(false); >+ } >+ } >+ >+ /** >+ * @return the current selection in the JUnit Viewer (provided by the underlying selection >+ * provider), or {@code null} if the kind of selection is not an {@link ITreeSelection} >+ * nor an {@link IStructuredSelection}. >+ */ >+ private Object getCurrentViewerSelection() { >+ final ISelection currentSelection= fSelectionProvider.getSelection(); >+ if (currentSelection instanceof ITreeSelection) { >+ return ((ITreeSelection)currentSelection).getFirstElement(); >+ } else if (currentSelection instanceof IStructuredSelection) { >+ return ((IStructuredSelection)currentSelection).getFirstElement(); >+ } >+ return null; >+ } >+ >+ /** >+ * Finds the {@link ITestElement} from the given {@link IJavaElement} >+ * >+ * @param javaElement the java element associated with the {@link ITestElement} to find. >+ * @return the {@link ITestElement} or null if it could not be found. >+ */ >+ private ITestElement findTestElement(final IJavaElement javaElement) { >+ if (fTestRunSession == null || javaElement == null) { >+ return null; >+ } >+ switch (javaElement.getElementType()) { >+ case IJavaElement.METHOD: >+ final IMethod javaMethod= (IMethod)javaElement; >+ final IType javaType= (IType)javaMethod.getAncestor(IJavaElement.TYPE); >+ final String testClassName= javaType.getFullyQualifiedName(); >+ final String testMethodName= javaMethod.getElementName(); >+ return findTestCaseElement(fTestRunSession.getTestRoot(), testClassName, testMethodName); >+ case IJavaElement.TYPE: >+ return findTestSuiteElement(fTestRunSession.getTestRoot(), ((IType)javaElement).getFullyQualifiedName()); >+ default: >+ return null; >+ } >+ } >+ >+ /** >+ * Finds the {@link ITestCaseElement} with the given test class name and test method name in the >+ * given {@link ITestSuiteElement} >+ * >+ * @param parentElement the parent Test Suite >+ * @param testClassName the name of the test class >+ * @param testMethodName the name of the test method >+ * >+ * @return the {@link ITestCaseElement} or null if it could not be found. >+ */ >+ private ITestCaseElement findTestCaseElement(final ITestSuiteElement parentElement, final String testClassName, final String testMethodName) { >+ for (ITestElement childElement : parentElement.getChildren()) { >+ if (childElement instanceof ITestCaseElement) { >+ final TestCaseElement testCaseElement= (TestCaseElement)childElement; >+ if (testCaseElement.getJavaType() != null && testCaseElement.getJavaType().getFullyQualifiedName().equals(testClassName) && testCaseElement.getJavaMethod() != null >+ && testCaseElement.getJavaMethod() != null && testCaseElement.getJavaMethod().getElementName().equals(testMethodName)) { >+ return testCaseElement; >+ } >+ } else if (childElement instanceof ITestSuiteElement) { >+ final ITestCaseElement localResult= findTestCaseElement((ITestSuiteElement)childElement, testClassName, testMethodName); >+ if (localResult != null) { >+ return localResult; >+ } >+ } >+ } >+ return null; >+ } >+ >+ /** >+ * Finds the {@link ITestSuiteElement} with the given test class name in the given >+ * {@link ITestSuiteElement} >+ * >+ * @param parentElement the parent Test Suite >+ * @param testClassName the name of the test class >+ * >+ * @return the {@link ITestSuiteElement} or null if it could not be found. >+ */ >+ private ITestSuiteElement findTestSuiteElement(final ITestSuiteElement parentElement, final String testClassName) { >+ for (ITestElement childElement : parentElement.getChildren()) { >+ if (childElement instanceof ITestSuiteElement) { >+ final ITestSuiteElement childTestSuite= (ITestSuiteElement)childElement; >+ if (childTestSuite.getSuiteTypeName().equals(testClassName)) { >+ return childTestSuite; >+ } >+ } >+ } >+ return null; >+ } >+ > public void selectFirstFailure() { > TestCaseElement firstFailure= getNextChildFailure(fTestRunSession.getTestRoot(), true); > if (firstFailure != null) >@@ -722,5 +877,99 @@ > fTreeViewer.expandToLevel(2); > } > >-} >+ /** >+ * Reacts to a selection change in the active {@link IWorkbenchPart} (or when another part >+ * received the focus). >+ * >+ * @param part the {@link IWorkbenchPart} in which the selection change occurred >+ * @param selection the selection in the given part >+ * @since 3.8 >+ */ >+ public void selectionChanged(IWorkbenchPart part, ISelection selection) { >+ if (part instanceof IEditorPart) { >+ setSelection((IEditorPart)part); >+ } else if (part instanceof TestRunnerViewPart) { >+ fTestRunnerPart.setLinkingWithEditorInSync(true); >+ } >+ } > >+ /** >+ * @return the selected {@link IJavaElement} in the current editor if it is a {@link CompilationUnitEditor}, null otherwise. >+ * @param editor the editor >+ */ >+ private IJavaElement getSelectedJavaElementInEditor(final IEditorPart editor) { >+ if (editor instanceof CompilationUnitEditor) { >+ final CompilationUnitEditor compilationUnitEditor = (CompilationUnitEditor)editor; >+ try { >+ final IJavaElement inputJavaElement= JavaUI.getEditorInputJavaElement(editor.getEditorInput()); >+ final ITextSelection selection= (ITextSelection)compilationUnitEditor.getSelectionProvider().getSelection(); >+ final ICompilationUnit compilationUnit= (ICompilationUnit)inputJavaElement.getAncestor(IJavaElement.COMPILATION_UNIT); >+ return compilationUnit.getElementAt(selection.getOffset()); >+ } catch (JavaModelException e) { >+ JUnitPlugin.log(e); >+ } >+ } >+ return null; >+ } >+ >+ /** >+ * Handles the case when a {@link TestCaseElement} has been selected: open the associated code >+ * in the Java Editor >+ * >+ * @param testElement the new selected {@link TestCaseElement} >+ */ >+ private void handleTestElementSelected(final ITestElement testElement) { >+ if (testElement instanceof TestCaseElement) { >+ final IMethod selectedMethod= ((TestCaseElement)testElement).getJavaMethod(); >+ handleJavaElementSelected(selectedMethod); >+ } else if (testElement instanceof TestSuiteElement) { >+ final IJavaElement selectedElement= ((TestSuiteElement)testElement).getJavaElement(); >+ handleJavaElementSelected(selectedElement); >+ } >+ } >+ >+ /** >+ * Reveals the given {@link IJavaElement} in its associated Editor if this later is already >+ * open, and sets the "Link with Editor" button state accordingly. >+ * >+ * @param selectedJavaElement the selected {@link IJavaElement} in the {@link TestViewer} that >+ * should be revealed in its Java Editor. >+ */ >+ private void handleJavaElementSelected(final IJavaElement selectedJavaElement) { >+ try { >+ final IEditorPart editor= EditorUtility.isOpenInEditor(selectedJavaElement); >+ if (selectedJavaElement != null && editor != null && editor instanceof JavaEditor) { >+ final JavaEditor javaEditor= (JavaEditor)editor; >+ final ITextSelection javaEditorSelection= (ITextSelection)javaEditor.getSelectionProvider().getSelection(); >+ final IEditorPart selectedMethodEditor= EditorUtility.isOpenInEditor(selectedJavaElement); >+ // checks if the editor is already open or not >+ if (selectedMethodEditor != null) { >+ // Retrieve the current active editor >+ final IEditorPart activeEditor= fTestRunnerPart.getSite().getPage().getActiveEditor(); >+ // open the required editor if it is not the active one >+ if (!selectedMethodEditor.equals(activeEditor)) { >+ EditorUtility.openInEditor(selectedJavaElement, false); >+ } >+ // retrieve the current java element (unless the associated compilation unit cannot be retrieved) >+ final ICompilationUnit compilationUnit= (ICompilationUnit)selectedJavaElement.getAncestor(IJavaElement.COMPILATION_UNIT); >+ if (compilationUnit != null) { >+ final IJavaElement javaEditorSelectedElement= compilationUnit.getElementAt(javaEditorSelection.getOffset()); >+ // force to reveal the selected element in case where the editor was not active >+ if (!selectedMethodEditor.equals(activeEditor) || !selectedJavaElement.equals(javaEditorSelectedElement)) { >+ EditorUtility.revealInEditor(selectedMethodEditor, selectedJavaElement); >+ } >+ fTestRunnerPart.setLinkingWithEditorInSync(true); >+ return; >+ } >+ } >+ } >+ } catch (JavaModelException e) { >+ JUnitPlugin.log(e); >+ } catch (PartInitException e) { >+ // occurs if the editor could not be opened or the input element is not valid Status code >+ JUnitPlugin.log(e); >+ } >+ fTestRunnerPart.setLinkingWithEditorInSync(false); >+ } >+ >+} >diff --git a/org.eclipse.jdt.ui/.gitignore b/org.eclipse.jdt.ui/.gitignore >index c614df2..77a61af 100644 >--- a/org.eclipse.jdt.ui/.gitignore >+++ b/org.eclipse.jdt.ui/.gitignore >@@ -1 +1,2 @@ > /bin-jar-in-jar-loader/ >+/bin/
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 372588
:
235306
|
239512
|
239779
|
239813
|
240197
|
240412
|
241975
|
242004
|
248907
|
248908
|
248945
|
249171
|
251221
|
251985
|
252025