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 241975 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]
New Patch after review, with support for Parameterized Tests
BZ372588---JUnit-Add-Link-with-Editor-to-JUnit-view.patch (text/plain), 75.65 KB, created by
Xavier Coulon
on 2014-04-14 11:36:00 EDT
(
hide
)
Description:
New Patch after review, with support for Parameterized Tests
Filename:
MIME Type:
Creator:
Xavier Coulon
Created:
2014-04-14 11:36:00 EDT
Size:
75.65 KB
patch
obsolete
>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..d042112 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> >+ * - 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.model; >@@ -15,9 +17,24 @@ > 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; > >@@ -27,7 +44,25 @@ > } > > /** >+ * @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; >+ } >+ >+ /** > * {@inheritDoc} >+ * > * @see org.eclipse.jdt.junit.model.ITestCaseElement#getTestMethodName() > * @see org.eclipse.jdt.internal.junit.runner.MessageIds#TEST_IDENTIFIER_MESSAGE_FORMAT > * @see org.eclipse.jdt.internal.junit.runner.MessageIds#IGNORED_TEST_PREFIX >@@ -35,16 +70,52 @@ > public String getTestMethodName() { > String testName= getTestName(); > int index= testName.lastIndexOf('('); >- if (index > 0) >+ if (index > 0) { > return testName.substring(0, index); >+ } >+ index= testName.indexOf('('); >+ if (index > 0) { >+ return testName.substring(0, index); >+ } > index= testName.indexOf('@'); >- if (index > 0) >+ 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. >+ */ >+ 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; >+ } >+ >+ /** > * {@inheritDoc} >+ * > * @see org.eclipse.jdt.junit.model.ITestCaseElement#getTestClassName() > */ > public String getTestClassName() { >@@ -61,7 +132,7 @@ > else > return super.getTestResult(includeChildren); > } >- >+ > public void setIgnored(boolean ignored) { > fIgnored= ignored; > } >@@ -73,4 +144,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..41fdf60 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,24 @@ > return extractClassName(getTestName()); > } > >+ /** >+ * @return the Java {@link IType} associated with this {@link TestElement}. >+ */ >+ 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..c7580eb 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 >@@ -17,8 +17,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 +161,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/src/org/eclipse/jdt/internal/junit/ui/TestRunnerViewPart.java b/org.eclipse.jdt.junit/src/org/eclipse/jdt/internal/junit/ui/TestRunnerViewPart.java >index ccf104e..5e08fa7 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 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2013 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 >@@ -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; > > /** >@@ -159,27 +163,32 @@ > public static final String NAME= "org.eclipse.jdt.junit.ResultView"; //$NON-NLS-1$ > > private static final String RERUN_LAST_COMMAND= "org.eclipse.jdt.junit.junitShortcut.rerunLast"; //$NON-NLS-1$ >+ > private static final String RERUN_FAILED_FIRST_COMMAND= "org.eclipse.jdt.junit.junitShortcut.rerunFailedFirst"; //$NON-NLS-1$ > > static final int REFRESH_INTERVAL= 200; > > static final int LAYOUT_FLAT= 0; >+ > static final int LAYOUT_HIERARCHICAL= 1; > > /** > * Whether the output scrolls and reveals tests as they are executed. > */ >- protected boolean fAutoScroll = true; >+ protected boolean fAutoScroll= true; >+ > /** > * The current orientation; either <code>VIEW_ORIENTATION_HORIZONTAL</code> > * <code>VIEW_ORIENTATION_VERTICAL</code>, or <code>VIEW_ORIENTATION_AUTOMATIC</code>. > */ > private int fOrientation= VIEW_ORIENTATION_AUTOMATIC; >+ > /** > * The current orientation; either <code>VIEW_ORIENTATION_HORIZONTAL</code> > * <code>VIEW_ORIENTATION_VERTICAL</code>. > */ > private int fCurrentOrientation; >+ > /** > * The current layout mode (LAYOUT_FLAT or LAYOUT_HIERARCHICAL). > */ >@@ -188,16 +197,23 @@ > // private boolean fTestIsRunning= false; > > protected JUnitProgressBar fProgressBar; >+ > protected ProgressImages fProgressImages; >+ > protected Image fViewImage; >+ > protected CounterPanel fCounterPanel; >+ > protected boolean fShowOnErrorOnly= false; >+ > protected Clipboard fClipboard; >+ > protected volatile String fInfoMessage; > > private FailureTrace fFailureTrace; > > private TestViewer fTestViewer; >+ > /** > * Is the UI disposed? > */ >@@ -207,73 +223,120 @@ > * Actions > */ > private Action fNextAction; >+ > private Action fPreviousAction; > > private StopAction fStopAction; >+ >+ >+ /** >+ * Helper to open and activate editors. >+ * >+ * @since 3.7 >+ */ >+ private LinkWithEditorAction fLinkWithEditorAction; >+ > private JUnitCopyAction fCopyAction; >+ > private Action fPasteAction; > > private Action fRerunLastTestAction; >+ > private IHandlerActivation fRerunLastActivation; >+ > private Action fRerunFailedFirstAction; >+ > private IHandlerActivation fRerunFailedFirstActivation; > > private Action fFailuresOnlyFilterAction; >+ > private ScrollLockAction fScrollLockAction; >+ > private ToggleOrientationAction[] fToggleOrientationActions; >+ > private ShowTestHierarchyAction fShowTestHierarchyAction; >+ > private ShowTimeAction fShowTimeAction; >+ > private ActivateOnErrorAction fActivateOnErrorAction; >+ > private IMenuListener fViewMenuListener; > > private TestRunSession fTestRunSession; >+ > private TestSessionListener fTestSessionListener; > > private RunnerViewHistory fViewHistory; >+ > private TestRunSessionListener fTestRunSessionListener; > > final Image fStackViewIcon; >+ > final Image fTestRunOKIcon; >+ > final Image fTestRunFailIcon; >+ > final Image fTestRunOKDirtyIcon; >+ > final Image fTestRunFailDirtyIcon; > > final Image fTestIcon; >+ > final Image fTestOkIcon; >+ > final Image fTestErrorIcon; >+ > final Image fTestFailIcon; >+ > final Image fTestAssumptionFailureIcon; >+ > final Image fTestRunningIcon; >+ > final Image fTestIgnoredIcon; > > final ImageDescriptor fSuiteIconDescriptor= JUnitPlugin.getImageDescriptor("obj16/tsuite.gif"); //$NON-NLS-1$ >+ > final ImageDescriptor fSuiteOkIconDescriptor= JUnitPlugin.getImageDescriptor("obj16/tsuiteok.gif"); //$NON-NLS-1$ >+ > final ImageDescriptor fSuiteErrorIconDescriptor= JUnitPlugin.getImageDescriptor("obj16/tsuiteerror.gif"); //$NON-NLS-1$ >+ > final ImageDescriptor fSuiteFailIconDescriptor= JUnitPlugin.getImageDescriptor("obj16/tsuitefail.gif"); //$NON-NLS-1$ >+ > final ImageDescriptor fSuiteRunningIconDescriptor= JUnitPlugin.getImageDescriptor("obj16/tsuiterun.gif"); //$NON-NLS-1$ > > final Image fSuiteIcon; >+ > final Image fSuiteOkIcon; >+ > final Image fSuiteErrorIcon; >+ > final Image fSuiteFailIcon; >+ > final Image fSuiteRunningIcon; > > final List<Image> fImagesToDispose; > > // Persistence tags. > static final String TAG_PAGE= "page"; //$NON-NLS-1$ >+ > static final String TAG_RATIO= "ratio"; //$NON-NLS-1$ >+ > static final String TAG_TRACEFILTER= "tracefilter"; //$NON-NLS-1$ >+ > static final String TAG_ORIENTATION= "orientation"; //$NON-NLS-1$ >+ > static final String TAG_SCROLL= "scroll"; //$NON-NLS-1$ >+ > /** > * @since 3.2 > */ > static final String TAG_LAYOUT= "layout"; //$NON-NLS-1$ >+ > /** > * @since 3.2 > */ > static final String TAG_FAILURES_ONLY= "failuresOnly"; //$NON-NLS-1$ >+ > /** > * @since 3.4 > */ >@@ -288,15 +351,18 @@ > * @since 3.6 > */ > static final String PREF_LAST_URL= "lastImportURL"; //$NON-NLS-1$ >- >+ > //orientations > static final int VIEW_ORIENTATION_VERTICAL= 0; >+ > static final int VIEW_ORIENTATION_HORIZONTAL= 1; >+ > static final int VIEW_ORIENTATION_AUTOMATIC= 2; > > private IMemento fMemento; > > Image fOriginalViewImage; >+ > IElementChangedListener fDirtyListener; > > >@@ -304,6 +370,7 @@ > private SashForm fSashForm; > > private Composite fCounterComposite; >+ > private Composite fParent; > > /** >@@ -312,20 +379,33 @@ > private UpdateUIJob fUpdateJob; > > /** >- * A Job that runs as long as a test run is running. >- * It is used to show busyness for running jobs in the view (title in italics). >+ * A Job that runs as long as a test run is running. It is used to show busyness for running >+ * jobs in the view (title in italics). > */ > private JUnitIsRunningJob fJUnitIsRunningJob; >+ > private ILock fJUnitIsRunningLock; >- public static final Object FAMILY_JUNIT_RUN = new Object(); >+ >+ public static final Object FAMILY_JUNIT_RUN= new Object(); > > private IPartListener2 fPartListener= new IPartListener2() { >- public void partActivated(IWorkbenchPartReference ref) { } >- public void partBroughtToTop(IWorkbenchPartReference ref) { } >- public void partInputChanged(IWorkbenchPartReference ref) { } >- public void partClosed(IWorkbenchPartReference ref) { } >- public void partDeactivated(IWorkbenchPartReference ref) { } >- public void partOpened(IWorkbenchPartReference ref) { } >+ public void partActivated(IWorkbenchPartReference ref) { >+ } >+ >+ public void partBroughtToTop(IWorkbenchPartReference ref) { >+ } >+ >+ public void partInputChanged(IWorkbenchPartReference ref) { >+ } >+ >+ public void partClosed(IWorkbenchPartReference ref) { >+ } >+ >+ public void partDeactivated(IWorkbenchPartReference ref) { >+ } >+ >+ public void partOpened(IWorkbenchPartReference ref) { >+ } > > public void partVisible(IWorkbenchPartReference ref) { > if (getSite().getId().equals(ref.getId())) { >@@ -410,7 +490,7 @@ > > @Override > public ImageDescriptor getImageDescriptor(Object element) { >- TestRunSession session= (TestRunSession) element; >+ TestRunSession session= (TestRunSession)element; > if (session.isStopped()) > return fSuiteIconDescriptor; > >@@ -481,7 +561,7 @@ > if (lastPath != null) { > importDialog.setFilterPath(lastPath); > } >- importDialog.setFilterExtensions(new String[] {"*.xml", "*.*"}); //$NON-NLS-1$ //$NON-NLS-2$ >+ importDialog.setFilterExtensions(new String[] { "*.xml", "*.*" }); //$NON-NLS-1$ //$NON-NLS-2$ > String path= importDialog.open(); > if (path == null) > return; >@@ -497,23 +577,24 @@ > } > } > } >- >+ > private static class JUnitPasteAction extends Action { > private final Shell fShell; >+ > private Clipboard fClipboard; >- >+ > public JUnitPasteAction(Shell shell, Clipboard clipboard) { > super(JUnitMessages.TestRunnerViewPart_JUnitPasteAction_label); > Assert.isNotNull(clipboard); > fShell= shell; > fClipboard= clipboard; > } >- >+ > @Override > public void run() { >- String urlData= (String) fClipboard.getContents(URLTransfer.getInstance()); >+ String urlData= (String)fClipboard.getContents(URLTransfer.getInstance()); > if (urlData == null) { >- urlData= (String) fClipboard.getContents(TextTransfer.getInstance()); >+ urlData= (String)fClipboard.getContents(TextTransfer.getInstance()); > } > if (urlData != null && urlData.length() > 0) { > if (isValidUrl(urlData)) { >@@ -524,7 +605,7 @@ > MessageDialog.openInformation(fShell, > JUnitMessages.TestRunnerViewPart_JUnitPasteAction_cannotpaste_title, > JUnitMessages.TestRunnerViewPart_JUnitPasteAction_cannotpaste_message >- ); >+ ); > } > > private boolean isValidUrl(String urlData) { >@@ -537,7 +618,7 @@ > return true; > } > } >- >+ > private static class ImportTestRunSessionFromURLAction extends Action { > private static class URLValidator implements IInputValidator { > public String isValid(String newText) { >@@ -554,24 +635,24 @@ > } > > private static final String DIALOG_SETTINGS= "ImportTestRunSessionFromURLAction"; //$NON-NLS-1$ >- >+ > private final Shell fShell; >- >+ > public ImportTestRunSessionFromURLAction(Shell shell) { > super(JUnitMessages.TestRunnerViewPart_ImportTestRunSessionFromURLAction_import_from_url); > fShell= shell; > } >- >+ > @Override > public void run() { > String title= JUnitMessages.TestRunnerViewPart_ImportTestRunSessionAction_title; > String message= JUnitMessages.TestRunnerViewPart_ImportTestRunSessionFromURLAction_url; >- >+ > final IDialogSettings dialogSettings= JUnitPlugin.getDefault().getDialogSettings(); > String url= dialogSettings.get(PREF_LAST_URL); >- >+ > IInputValidator validator= new URLValidator(); >- >+ > InputDialog inputDialog= new InputDialog(fShell, title, message, url, validator) { > @Override > protected Control createDialogArea(Composite parent) { >@@ -583,6 +664,7 @@ > } > return dialogArea2; > } >+ > @Override > protected IDialogSettings getDialogBoundsSettings() { > IDialogSettings settings= dialogSettings.getSection(DIALOG_SETTINGS); >@@ -592,12 +674,13 @@ > settings.put("DIALOG_HEIGHT", Dialog.DIALOG_DEFAULT_BOUNDS); //$NON-NLS-1$ > return settings; > } >+ > @Override > protected boolean isResizable() { > return true; > } > }; >- >+ > int res= inputDialog.open(); > if (res == IDialogConstants.OK_ID) { > url= inputDialog.getValue(); >@@ -609,6 +692,7 @@ > > private static class ExportTestRunSessionAction extends Action { > private final TestRunSession fTestRunSession; >+ > private final Shell fShell; > > public ExportTestRunSessionAction(Shell shell, TestRunSession testRunSession) { >@@ -627,7 +711,7 @@ > exportDialog.setFilterPath(lastPath); > } > exportDialog.setFileName(getFileName()); >- exportDialog.setFilterExtensions(new String[] {"*.xml", "*.*"}); //$NON-NLS-1$ //$NON-NLS-2$ >+ exportDialog.setFilterExtensions(new String[] { "*.xml", "*.*" }); //$NON-NLS-1$ //$NON-NLS-2$ > String path= exportDialog.open(); > if (path == null) > return; >@@ -664,13 +748,13 @@ > String testRunLabel= BasicElementLabels.getJavaElementName(testRunSession.getTestRunName()); > String msg; > if (testRunSession.getLaunch() != null) { >- msg= Messages.format(JUnitMessages.TestRunnerViewPart_Launching, new Object[]{ testRunLabel }); >+ msg= Messages.format(JUnitMessages.TestRunnerViewPart_Launching, new Object[] { testRunLabel }); > } else { > msg= testRunLabel; > } > registerInfoMessage(msg); > } >- >+ > TestRunSession deactivatedSession= setActiveTestRunSession(testRunSession); > if (deactivatedSession != null) > deactivatedSession.swapOut(); >@@ -678,13 +762,14 @@ > } > }); > } >+ > public void sessionRemoved(final TestRunSession testRunSession) { > getDisplay().asyncExec(new Runnable() { > public void run() { > if (testRunSession.equals(fTestRunSession)) { > List<TestRunSession> testRunSessions= JUnitCorePlugin.getModel().getTestRunSessions(); > TestRunSession deactivatedSession; >- if (! testRunSessions.isEmpty()) { >+ if (!testRunSessions.isEmpty()) { > deactivatedSession= setActiveTestRunSession(testRunSessions.get(0)); > } else { > deactivatedSession= setActiveTestRunSession(null); >@@ -698,7 +783,7 @@ > } > > private class TestSessionListener implements ITestSessionListener { >- public void sessionStarted(){ >+ public void sessionStarted() { > fTestViewer.registerViewersRefresh(); > fShowOnErrorOnly= getShowOnErrorOnly(); > >@@ -708,12 +793,12 @@ > fRerunLastTestAction.setEnabled(true); > } > >- public void sessionEnded(long elapsedTime){ >+ public void sessionEnded(long elapsedTime) { > deregisterTestSessionListener(false); >- >+ > fTestViewer.registerAutoScrollTarget(null); > >- String[] keys= {elapsedTimeAsString(elapsedTime)}; >+ String[] keys= { elapsedTimeAsString(elapsedTime) }; > String msg= Messages.format(JUnitMessages.TestRunnerViewPart_message_finish, keys); > registerInfoMessage(msg); > >@@ -732,6 +817,8 @@ > JavaCore.addElementChangedListener(fDirtyListener); > } > warnOfContentChange(); >+ fLinkWithEditorAction.setEnabled(fTestRunSession != null); >+ setLinkingWithEditorActive(fTestRunSession != null); > } > }); > stopUpdateJobs(); >@@ -739,7 +826,7 @@ > > public void sessionStopped(final long elapsedTime) { > deregisterTestSessionListener(false); >- >+ > fTestViewer.registerAutoScrollTarget(null); > > registerInfoMessage(JUnitMessages.TestRunnerViewPart_message_stopped); >@@ -748,7 +835,7 @@ > > public void sessionTerminated() { > deregisterTestSessionListener(true); >- >+ > fTestViewer.registerAutoScrollTarget(null); > > registerInfoMessage(JUnitMessages.TestRunnerViewPart_message_terminated); >@@ -776,21 +863,21 @@ > } > fTestViewer.registerViewerUpdate(testElement); > >- // show the view on the first error only >- if (fShowOnErrorOnly && (getErrorsPlusFailures() == 1)) >- postShowTestResultsView(); >+ // show the view on the first error only >+ if (fShowOnErrorOnly && (getErrorsPlusFailures() == 1)) >+ postShowTestResultsView(); > >- //TODO: >- // [Bug 35590] JUnit window doesn't report errors from junit.extensions.TestSetup [JUnit] >- // when a failure occurs in test setup then no test is running >- // to update the views we artificially signal the end of a test run >+ //TODO: >+ // [Bug 35590] JUnit window doesn't report errors from junit.extensions.TestSetup [JUnit] >+ // when a failure occurs in test setup then no test is running >+ // to update the views we artificially signal the end of a test run > // if (!fTestIsRunning) { > // fTestIsRunning= false; > // testEnded(testCaseElement); > // } > } > >- public void testEnded(TestCaseElement testCaseElement){ >+ public void testEnded(TestCaseElement testCaseElement) { > fTestViewer.registerViewerUpdate(testCaseElement); > } > >@@ -816,6 +903,7 @@ > super(name); > setSystem(true); > } >+ > @Override > public IStatus runInUIThread(IProgressMonitor monitor) { > if (!isDisposed()) { >@@ -828,6 +916,7 @@ > public void stop() { > fRunning= false; > } >+ > @Override > public boolean shouldSchedule() { > return fRunning; >@@ -839,12 +928,14 @@ > super(name); > setSystem(true); > } >+ > @Override > public IStatus run(IProgressMonitor monitor) { > // wait until the test run terminates > fJUnitIsRunningLock.acquire(); > return Status.OK_STATUS; > } >+ > @Override > public boolean belongsTo(Object family) { > return family == TestRunnerViewPart.FAMILY_JUNIT_RUN; >@@ -858,7 +949,7 @@ > boolean enabled= false; > List<TestRunSession> testRunSessions= JUnitCorePlugin.getModel().getTestRunSessions(); > for (TestRunSession testRunSession : testRunSessions) { >- if (! testRunSession.isRunning() && ! testRunSession.isStarting()) { >+ if (!testRunSession.isRunning() && !testRunSession.isStarting()) { > enabled= true; > break; > } >@@ -877,7 +968,7 @@ > List<TestRunSession> testRunSessions= JUnitCorePlugin.getModel().getTestRunSessions(); > for (Iterator<TestRunSession> iter= testRunSessions.iterator(); iter.hasNext();) { > TestRunSession testRunSession= iter.next(); >- if (! testRunSession.isRunning() && ! testRunSession.isStarting()) { >+ if (!testRunSession.isRunning() && !testRunSession.isStarting()) { > iter.remove(); > } > } >@@ -899,6 +990,55 @@ > } > } > >+ /** >+ * 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 { > public RerunLastAction() { > setText(JUnitMessages.TestRunnerViewPart_rerunaction_label); >@@ -909,7 +1049,7 @@ > } > > @Override >- public void run(){ >+ public void run() { > rerunTestRun(); > } > } >@@ -924,7 +1064,7 @@ > } > > @Override >- public void run(){ >+ public void run() { > rerunTestFailedFirst(); > } > } >@@ -975,7 +1115,7 @@ > int type= delta.getElement().getElementType(); > > switch (type) { >- // Consider containers for class files. >+ // Consider containers for class files. > case IJavaElement.JAVA_MODEL: > case IJavaElement.JAVA_PROJECT: > case IJavaElement.PACKAGE_FRAGMENT_ROOT: >@@ -1059,9 +1199,11 @@ > //setImageDescriptor(JUnitPlugin.getImageDescriptor("obj16/failures.gif")); //$NON-NLS-1$ > update(); > } >+ > public void update() { > setChecked(getShowOnErrorOnly()); > } >+ > @Override > public void run() { > boolean checked= isChecked(); >@@ -1085,7 +1227,7 @@ > fTestFailIcon= createManagedImage("obj16/testfail.gif"); //$NON-NLS-1$ > fTestRunningIcon= createManagedImage("obj16/testrun.gif"); //$NON-NLS-1$ > fTestIgnoredIcon= createManagedImage("obj16/testignored.gif"); //$NON-NLS-1$ >- fTestAssumptionFailureIcon = createManagedImage("obj16/testassumptionfailed.gif"); //$NON-NLS-1$ >+ fTestAssumptionFailureIcon= createManagedImage("obj16/testassumptionfailed.gif"); //$NON-NLS-1$ > > fSuiteIcon= createManagedImage(fSuiteIconDescriptor); > fSuiteOkIcon= createManagedImage(fSuiteOkIconDescriptor); >@@ -1120,7 +1262,7 @@ > private IWorkbenchSiteProgressService getProgressService() { > Object siteService= getSite().getAdapter(IWorkbenchSiteProgressService.class); > if (siteService != null) >- return (IWorkbenchSiteProgressService) siteService; >+ return (IWorkbenchSiteProgressService)siteService; > return null; > } > >@@ -1158,7 +1300,7 @@ > // } > Integer ratio= memento.getInteger(TAG_RATIO); > if (ratio != null) >- fSashForm.setWeights(new int[] { ratio.intValue(), 1000 - ratio.intValue()} ); >+ fSashForm.setWeights(new int[] { ratio.intValue(), 1000 - ratio.intValue() }); > Integer orientation= memento.getInteger(TAG_ORIENTATION); > if (orientation != null) > fOrientation= orientation.intValue(); >@@ -1200,6 +1342,36 @@ > } > } > >+ /** >+ * 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.7 >+ */ >+ 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() { > postSyncProcessChanges(); > >@@ -1237,7 +1409,7 @@ > doShowInfoMessage(); > refreshCounters(); > >- if (! fPartIsVisible) >+ if (!fPartIsVisible) > updateViewTitleProgress(); > else { > updateViewIcon(); >@@ -1298,31 +1470,31 @@ > } > ILaunch launch= fTestRunSession.getLaunch(); > if (launch != null && launch.getLaunchConfiguration() != null) { >- ILaunchConfiguration launchConfiguration= launch.getLaunchConfiguration(); >- if (launchConfiguration != null) { >- try { >- String oldName= launchConfiguration.getName(); >- String oldFailuresFilename= launchConfiguration.getAttribute(JUnitLaunchConfigurationConstants.ATTR_FAILURES_NAMES, (String) null); >- String configName; >- if (oldFailuresFilename != null) { >- configName= oldName; >- } else { >- configName= Messages.format(JUnitMessages.TestRunnerViewPart_rerunFailedFirstLaunchConfigName, oldName); >- } >- ILaunchConfigurationWorkingCopy tmp= launchConfiguration.copy(configName); >- tmp.setAttribute(JUnitLaunchConfigurationConstants.ATTR_FAILURES_NAMES, createFailureNamesFile()); >- relaunch(tmp, launch.getLaunchMode()); >- return; >- } catch (CoreException e) { >- ErrorDialog.openError(getSite().getShell(), >- JUnitMessages.TestRunnerViewPart_error_cannotrerun, e.getMessage(), e.getStatus() >- ); >+ ILaunchConfiguration launchConfiguration= launch.getLaunchConfiguration(); >+ if (launchConfiguration != null) { >+ try { >+ String oldName= launchConfiguration.getName(); >+ String oldFailuresFilename= launchConfiguration.getAttribute(JUnitLaunchConfigurationConstants.ATTR_FAILURES_NAMES, (String)null); >+ String configName; >+ if (oldFailuresFilename != null) { >+ configName= oldName; >+ } else { >+ configName= Messages.format(JUnitMessages.TestRunnerViewPart_rerunFailedFirstLaunchConfigName, oldName); > } >+ ILaunchConfigurationWorkingCopy tmp= launchConfiguration.copy(configName); >+ tmp.setAttribute(JUnitLaunchConfigurationConstants.ATTR_FAILURES_NAMES, createFailureNamesFile()); >+ relaunch(tmp, launch.getLaunchMode()); >+ return; >+ } catch (CoreException e) { >+ ErrorDialog.openError(getSite().getShell(), >+ JUnitMessages.TestRunnerViewPart_error_cannotrerun, e.getMessage(), e.getStatus() >+ ); > } >- MessageDialog.openInformation(getSite().getShell(), >+ } >+ MessageDialog.openInformation(getSite().getShell(), > JUnitMessages.TestRunnerViewPart_cannotrerun_title, > JUnitMessages.TestRunnerViewPart_cannotrerurn_message >- ); >+ ); > } > } > >@@ -1354,7 +1526,7 @@ > } > > public void setAutoScroll(boolean scroll) { >- fAutoScroll = scroll; >+ fAutoScroll= scroll; > } > > public boolean isAutoScroll() { >@@ -1385,7 +1557,7 @@ > } > > private String elapsedTimeAsString(long runTime) { >- return NumberFormat.getInstance().format((double)runTime/1000); >+ return NumberFormat.getInstance().format((double)runTime / 1000); > } > > private void handleStopped() { >@@ -1493,7 +1665,7 @@ > } > if (!fTestRunSession.isStarting() && !fShowOnErrorOnly) > showTestResultsView(); >- >+ > setTitleToolTip(); > > clearStatus(); >@@ -1507,11 +1679,19 @@ > startUpdateJobs(); > > fStopAction.setEnabled(true); >+ fLinkWithEditorAction.setEnabled(true); > >- } else /* old or fresh session: don't want jobs at this stage */ { >+ } 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(); > } > } >@@ -1527,16 +1707,16 @@ > > private void updateRerunFailedFirstAction() { > boolean state= hasErrorsOrFailures() && fTestRunSession.getLaunch() != null; >- fRerunFailedFirstAction.setEnabled(state); >- } >+ fRerunFailedFirstAction.setEnabled(state); >+ } > >- /** >- * @return the display name of the current test run sessions kind, or <code>null</code> >- */ >- public String getTestKindDisplayName() { >- ITestKind kind= fTestRunSession.getTestRunnerKind(); >+ /** >+ * @return the display name of the current test run sessions kind, or <code>null</code> >+ */ >+ public String getTestKindDisplayName() { >+ ITestKind kind= fTestRunSession.getTestRunnerKind(); > if (!kind.isNull()) { >- return kind.getDisplayName(); >+ return kind.getDisplayName(); > } > return null; > } >@@ -1546,18 +1726,18 @@ > > String testRunLabel= BasicElementLabels.getJavaElementName(fTestRunSession.getTestRunName()); > if (testKindDisplayStr != null) >- setTitleToolTip(MessageFormat.format(JUnitMessages.TestRunnerViewPart_titleToolTip, new Object[] {testRunLabel, testKindDisplayStr})); >+ setTitleToolTip(MessageFormat.format(JUnitMessages.TestRunnerViewPart_titleToolTip, new Object[] { testRunLabel, testKindDisplayStr })); > else > setTitleToolTip(testRunLabel); > } > > @Override >- public synchronized void dispose(){ >+ public synchronized void dispose() { > fIsDisposed= true; > if (fTestRunSessionListener != null) > JUnitCorePlugin.getModel().removeTestRunSessionListener(fTestRunSessionListener); > >- IHandlerService handlerService= (IHandlerService) getSite().getWorkbenchWindow().getService(IHandlerService.class); >+ IHandlerService handlerService= (IHandlerService)getSite().getWorkbenchWindow().getService(IHandlerService.class); > handlerService.deactivateHandler(fRerunLastActivation); > handlerService.deactivateHandler(fRerunFailedFirstActivation); > setActiveTestRunSession(null); >@@ -1579,6 +1759,7 @@ > if (fFailureTrace != null) { > fFailureTrace.dispose(); > } >+ getSite().getPage().removePostSelectionListener(fTestViewer); > } > > private void disposeImages() { >@@ -1593,7 +1774,7 @@ > } > > private void refreshCounters() { >- // TODO: Inefficient. Either >+ // TODO: Inefficient. Either > // - keep a boolean fHasTestRun and update only on changes, or > // - improve components to only redraw on changes (once!). > >@@ -1612,7 +1793,7 @@ > totalCount= fTestRunSession.getTotalCount(); > errorCount= fTestRunSession.getErrorCount(); > failureCount= fTestRunSession.getFailureCount(); >- assumptionFailureCount = fTestRunSession.getAssumptionFailureCount(); >+ assumptionFailureCount= fTestRunSession.getAssumptionFailureCount(); > hasErrorsOrFailures= errorCount + failureCount > 0; > stopped= fTestRunSession.isStopped(); > } else { >@@ -1621,7 +1802,7 @@ > totalCount= 0; > errorCount= 0; > failureCount= 0; >- assumptionFailureCount = 0; >+ assumptionFailureCount= 0; > hasErrorsOrFailures= false; > stopped= false; > } >@@ -1634,7 +1815,7 @@ > int ticksDone; > if (startedCount == 0) > ticksDone= 0; >- else if (startedCount == totalCount && ! fTestRunSession.isRunning()) >+ else if (startedCount == totalCount && !fTestRunSession.isRunning()) > ticksDone= totalCount; > else > ticksDone= startedCount - 1; >@@ -1660,7 +1841,7 @@ > if (page != null) { > try { // show the result view > testRunner= (TestRunnerViewPart)page.findView(TestRunnerViewPart.NAME); >- if(testRunner == null) { >+ if (testRunner == null) { > IWorkbenchPart activePart= page.getActivePart(); > testRunner= (TestRunnerViewPart)page.showView(TestRunnerViewPart.NAME, null, IWorkbenchPage.VIEW_VISIBLE); > //restore focus >@@ -1696,6 +1877,7 @@ > protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) { > return new Point(1, 1); // (0, 0) does not work with super-intelligent ViewForm > } >+ > @Override > protected void layout(Composite composite, boolean flushCache) { > } >@@ -1715,7 +1897,7 @@ > fFailureTrace= new FailureTrace(bottom, fClipboard, this, failureToolBar); > bottom.setContent(fFailureTrace.getComposite()); > >- fSashForm.setWeights(new int[]{50, 50}); >+ fSashForm.setWeights(new int[] { 50, 50 }); > return fSashForm; > } > >@@ -1750,15 +1932,15 @@ > sashForm.setLayoutData(new GridData(GridData.FILL_BOTH)); > > IActionBars actionBars= getViewSite().getActionBars(); >- >- fCopyAction = new JUnitCopyAction(fFailureTrace, fClipboard); >+ >+ fCopyAction= new JUnitCopyAction(fFailureTrace, fClipboard); > fCopyAction.setActionDefinitionId(ActionFactory.COPY.getCommandId()); > actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), fCopyAction); >- >+ > fPasteAction= new JUnitPasteAction(parent.getShell(), fClipboard); > fPasteAction.setActionDefinitionId(ActionFactory.PASTE.getCommandId()); > actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), fPasteAction); >- >+ > initPageSwitcher(); > addDropAdapter(parent); > >@@ -1777,7 +1959,7 @@ > > fTestRunSessionListener= new TestRunSessionListener(); > JUnitCorePlugin.getModel().addTestRunSessionListener(fTestRunSessionListener); >- >+ > // always show youngest test run in view. simulate "sessionAdded" event to do that > List<TestRunSession> testRunSessions= JUnitCorePlugin.getModel().getTestRunSessions(); > if (!testRunSessions.isEmpty()) { >@@ -1786,31 +1968,34 @@ > } > > private void addDropAdapter(Composite parent) { >- DropTarget dropTarget = new DropTarget(parent, DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK | DND.DROP_DEFAULT); >+ DropTarget dropTarget= new DropTarget(parent, DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK | DND.DROP_DEFAULT); > dropTarget.setTransfer(new Transfer[] { TextTransfer.getInstance() }); > class DropAdapter extends DropTargetAdapter { >- @Override >+ @Override > public void dragEnter(DropTargetEvent event) { >- event.detail = DND.DROP_COPY; >- event.feedback = DND.FEEDBACK_NONE; >- } >- @Override >+ event.detail= DND.DROP_COPY; >+ event.feedback= DND.FEEDBACK_NONE; >+ } >+ >+ @Override > public void dragOver(DropTargetEvent event) { >- event.detail = DND.DROP_COPY; >- event.feedback = DND.FEEDBACK_NONE; >- } >- @Override >+ event.detail= DND.DROP_COPY; >+ event.feedback= DND.FEEDBACK_NONE; >+ } >+ >+ @Override > public void dragOperationChanged(DropTargetEvent event) { >- event.detail = DND.DROP_COPY; >- event.feedback = DND.FEEDBACK_NONE; >- } >- @Override >+ event.detail= DND.DROP_COPY; >+ event.feedback= DND.FEEDBACK_NONE; >+ } >+ >+ @Override > public void drop(final DropTargetEvent event) { >- if (TextTransfer.getInstance().isSupportedType(event.currentDataType)) { >- String url= (String) event.data; >+ if (TextTransfer.getInstance().isSupportedType(event.currentDataType)) { >+ String url= (String)event.data; > importTestRunSession(url); >- } >- } >+ } >+ } > } > dropTarget.addDropListener(new DropAdapter()); > } >@@ -1825,7 +2010,7 @@ > > @Override > public String getName(Object page) { >- return fViewHistory.getText((TestRunSession) page); >+ return fViewHistory.getText((TestRunSession)page); > } > > @Override >@@ -1835,7 +2020,7 @@ > > @Override > public void activatePage(Object page) { >- fViewHistory.setActiveEntry((TestRunSession) page); >+ fViewHistory.setActiveEntry((TestRunSession)page); > } > > @Override >@@ -1849,6 +2034,7 @@ > parent.addControlListener(new ControlListener() { > public void controlMoved(ControlEvent e) { > } >+ > public void controlResized(ControlEvent e) { > computeOrientation(); > } >@@ -1874,7 +2060,7 @@ > private void configureToolBar() { > IActionBars actionBars= getViewSite().getActionBars(); > IToolBarManager toolBar= actionBars.getToolBarManager(); >- IMenuManager viewMenu = actionBars.getMenuManager(); >+ IMenuManager viewMenu= actionBars.getMenuManager(); > > fNextAction= new ShowNextFailureAction(this); > fNextAction.setEnabled(false); >@@ -1887,26 +2073,31 @@ > fStopAction= new StopAction(); > fStopAction.setEnabled(false); > >+ fLinkWithEditorAction= new LinkWithEditorAction(); >+ fLinkWithEditorAction.setEnabled(false); >+ > fRerunLastTestAction= new RerunLastAction(); >- IHandlerService handlerService= (IHandlerService) getSite().getWorkbenchWindow().getService(IHandlerService.class); >- IHandler handler = new AbstractHandler() { >+ IHandlerService handlerService= (IHandlerService)getSite().getWorkbenchWindow().getService(IHandlerService.class); >+ IHandler handler= new AbstractHandler() { > public Object execute(ExecutionEvent event) throws ExecutionException { > fRerunLastTestAction.run(); > return null; > } >+ > @Override > public boolean isEnabled() { > return fRerunLastTestAction.isEnabled(); > } > }; >- fRerunLastActivation= handlerService.activateHandler(RERUN_LAST_COMMAND, handler); >+ fRerunLastActivation= handlerService.activateHandler(RERUN_LAST_COMMAND, handler); > > fRerunFailedFirstAction= new RerunLastFailedFirstAction(); >- handler = new AbstractHandler() { >+ handler= new AbstractHandler() { > public Object execute(ExecutionEvent event) throws ExecutionException { > fRerunFailedFirstAction.run(); > return null; > } >+ > @Override > public boolean isEnabled() { > return fRerunFailedFirstAction.isEnabled(); >@@ -1919,11 +2110,11 @@ > fScrollLockAction= new ScrollLockAction(this); > fScrollLockAction.setChecked(!fAutoScroll); > >- fToggleOrientationActions = >- new ToggleOrientationAction[] { >- new ToggleOrientationAction(VIEW_ORIENTATION_VERTICAL), >- new ToggleOrientationAction(VIEW_ORIENTATION_HORIZONTAL), >- new ToggleOrientationAction(VIEW_ORIENTATION_AUTOMATIC)}; >+ fToggleOrientationActions= >+ new ToggleOrientationAction[] { >+ new ToggleOrientationAction(VIEW_ORIENTATION_VERTICAL), >+ new ToggleOrientationAction(VIEW_ORIENTATION_HORIZONTAL), >+ new ToggleOrientationAction(VIEW_ORIENTATION_AUTOMATIC) }; > > fShowTestHierarchyAction= new ShowTestHierarchyAction(); > fShowTimeAction= new ShowTimeAction(); >@@ -1937,14 +2128,15 @@ > toolBar.add(fRerunFailedFirstAction); > toolBar.add(fStopAction); > toolBar.add(fViewHistory.createHistoryDropDownAction()); >- >+ toolBar.add(new Separator()); >+ toolBar.add(fLinkWithEditorAction); > > viewMenu.add(fShowTestHierarchyAction); > viewMenu.add(fShowTimeAction); > viewMenu.add(new Separator()); > > MenuManager layoutSubMenu= new MenuManager(JUnitMessages.TestRunnerViewPart_layout_menu); >- for (int i = 0; i < fToggleOrientationActions.length; ++i) { >+ for (int i= 0; i < fToggleOrientationActions.length; ++i) { > layoutSubMenu.add(fToggleOrientationActions[i]); > } > viewMenu.add(layoutSubMenu); >@@ -1983,7 +2175,7 @@ > IEditorPart activeEditorPart= (IEditorPart)activePart; > IEditorActionBarContributor contributor= activeEditorPart.getEditorSite().getActionBarContributor(); > if (contributor instanceof EditorActionBarContributor) >- return ((EditorActionBarContributor) contributor).getActionBars().getStatusLineManager(); >+ return ((EditorActionBarContributor)contributor).getActionBars().getStatusLineManager(); > } > // no active part > return getViewSite().getActionBars().getStatusLineManager(); >@@ -1995,10 +2187,10 @@ > composite.setLayout(layout); > setCounterColumns(layout); > >- fCounterPanel = new CounterPanel(composite); >+ fCounterPanel= new CounterPanel(composite); > fCounterPanel.setLayoutData( >- new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL)); >- fProgressBar = new JUnitProgressBar(composite); >+ new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL)); >+ fProgressBar= new JUnitProgressBar(composite); > fProgressBar.setLayoutData( > new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL)); > return composite; >@@ -2070,7 +2262,7 @@ > public void rerunTest(String testId, String className, String testName, String launchMode) { > if (lastLaunchIsKeptAlive()) { > fTestRunSession.rerunTest(testId, className, testName); >- TestCaseElement testCaseElement= (TestCaseElement) fTestRunSession.getTestElement(testId); >+ TestCaseElement testCaseElement= (TestCaseElement)fTestRunSession.getTestElement(testId); > testCaseElement.setStatus(TestElement.Status.RUNNING, null, null, null); > fTestViewer.registerViewerUpdate(testCaseElement); > postSyncProcessChanges(); >@@ -2086,9 +2278,9 @@ > try { > String name= className; > if (testName != null) >- name+= "."+testName; //$NON-NLS-1$ >+ name+= "." + testName; //$NON-NLS-1$ > String configName= Messages.format(JUnitMessages.TestRunnerViewPart_configName, name); >- ILaunchConfigurationWorkingCopy tmp = launchConfiguration.copy(configName); >+ ILaunchConfigurationWorkingCopy tmp= launchConfiguration.copy(configName); > // fix for bug: 64838 junit view run single test does not use correct class [JUnit] > tmp.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, className); > // reset the container >@@ -2098,12 +2290,12 @@ > } > relaunch(tmp, launchMode); > return; >- } catch (CoreException e) { >- ErrorDialog.openError(getSite().getShell(), >- JUnitMessages.TestRunnerViewPart_error_cannotrerun, e.getMessage(), e.getStatus() >+ } catch (CoreException e) { >+ ErrorDialog.openError(getSite().getShell(), >+ JUnitMessages.TestRunnerViewPart_error_cannotrerun, e.getMessage(), e.getStatus() > ); >- return; >- } >+ return; >+ } > } > } > } >@@ -2134,12 +2326,12 @@ > private void setOrientation(int orientation) { > if ((fSashForm == null) || fSashForm.isDisposed()) > return; >- boolean horizontal = orientation == VIEW_ORIENTATION_HORIZONTAL; >+ boolean horizontal= orientation == VIEW_ORIENTATION_HORIZONTAL; > fSashForm.setOrientation(horizontal ? SWT.HORIZONTAL : SWT.VERTICAL); >- for (int i = 0; i < fToggleOrientationActions.length; ++i) >+ for (int i= 0; i < fToggleOrientationActions.length; ++i) > fToggleOrientationActions[i].setChecked(fOrientation == fToggleOrientationActions[i].getOrientation()); >- fCurrentOrientation = orientation; >- GridLayout layout= (GridLayout) fCounterComposite.getLayout(); >+ fCurrentOrientation= orientation; >+ GridLayout layout= (GridLayout)fCounterComposite.getLayout(); > setCounterColumns(layout); > fParent.layout(); > } >@@ -2165,7 +2357,7 @@ > } catch (InterruptedException e) { > // cancelled > } catch (InvocationTargetException e) { >- CoreException ce= (CoreException) e.getCause(); >+ CoreException ce= (CoreException)e.getCause(); > StatusManager.getManager().handle(ce.getStatus(), StatusManager.SHOW | StatusManager.LOG); > } > } >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 3ab858c..6eda70a 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; >@@ -40,8 +43,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; >@@ -50,12 +55,21 @@ > 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.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; > >@@ -66,11 +80,16 @@ > import org.eclipse.jdt.internal.junit.model.TestRunSession; > import org.eclipse.jdt.internal.junit.model.TestSuiteElement; > >+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(); >@@ -87,7 +106,7 @@ > private final class FailuresOnlyFilter extends ViewerFilter { > @Override > public boolean select(Viewer viewer, Object parentElement, Object element) { >- return select(((TestElement) element)); >+ return select(((TestElement)element)); > } > > public boolean select(TestElement testElement) { >@@ -95,19 +114,22 @@ > if (status.isErrorOrFailure()) > return true; > else >- return ! fTestRunSession.isRunning() && status == Status.RUNNING; // rerunning >+ return !fTestRunSession.isRunning() && status == Status.RUNNING; // rerunning > } > } > > private static class ReverseList<E> extends AbstractList<E> { > private final List<E> fList; >+ > public ReverseList(List<E> list) { > fList= list; > } >+ > @Override > public E get(int index) { > return fList.get(fList.size() - index - 1); > } >+ > @Override > public int size() { > return fList.size(); >@@ -121,7 +143,7 @@ > } > > @Override >- public void run(){ >+ public void run() { > fTreeViewer.expandAll(); > } > } >@@ -129,29 +151,43 @@ > private final FailuresOnlyFilter fFailuresOnlyFilter= new FailuresOnlyFilter(); > > private final TestRunnerViewPart fTestRunnerPart; >+ > private final Clipboard fClipboard; > > private PageBook fViewerbook; >+ > private TreeViewer fTreeViewer; >+ > private TestSessionTreeContentProvider fTreeContentProvider; >+ > private TestSessionLabelProvider fTreeLabelProvider; >+ > private TableViewer fTableViewer; >+ > private TestSessionTableContentProvider fTableContentProvider; >+ > private TestSessionLabelProvider fTableLabelProvider; >+ > private SelectionProviderMediator fSelectionProvider; > > private int fLayoutMode; >+ > private boolean fTreeHasFilter; >+ > private boolean fTableHasFilter; > > private TestRunSession fTestRunSession; > > private boolean fTreeNeedsRefresh; >+ > private boolean fTableNeedsRefresh; >+ > private HashSet<TestElement> fNeedUpdate; >+ > private TestCaseElement fAutoScrollTarget; > > private LinkedList<TestSuiteElement> fAutoClose; >+ > private HashSet<TestSuiteElement> fAutoExpand; > > >@@ -191,8 +227,8 @@ > fTreeViewer.getTree().addSelectionListener(testOpenListener); > fTableViewer.getTable().addSelectionListener(testOpenListener); > >+ // register the selection provider to broadcast selection to other views > fTestRunnerPart.getSite().setSelectionProvider(fSelectionProvider); >- > fViewerbook.showPage(fTreeViewer.getTree()); > } > >@@ -212,9 +248,9 @@ > > > void handleMenuAboutToShow(IMenuManager manager) { >- IStructuredSelection selection= (IStructuredSelection) fSelectionProvider.getSelection(); >- if (! selection.isEmpty()) { >- TestElement testElement= (TestElement) selection.getFirstElement(); >+ IStructuredSelection selection= (IStructuredSelection)fSelectionProvider.getSelection(); >+ if (!selection.isEmpty()) { >+ TestElement testElement= (TestElement)selection.getFirstElement(); > > String testLabel= testElement.getTestName(); > String className= testElement.getClassName(); >@@ -226,7 +262,7 @@ > manager.add(new RerunAction(JUnitMessages.RerunAction_label_debug, fTestRunnerPart, testElement.getId(), className, null, ILaunchManager.DEBUG_MODE)); > } > } else { >- TestCaseElement testCaseElement= (TestCaseElement) testElement; >+ TestCaseElement testCaseElement= (TestCaseElement)testElement; > String testMethodName= testCaseElement.getTestMethodName(); > manager.add(new OpenTestAction(fTestRunnerPart, testCaseElement)); > manager.add(new Separator()); >@@ -277,11 +313,11 @@ > } > > void handleDefaultSelected() { >- IStructuredSelection selection= (IStructuredSelection) fSelectionProvider.getSelection(); >+ IStructuredSelection selection= (IStructuredSelection)fSelectionProvider.getSelection(); > if (selection.size() != 1) > return; > >- TestElement testElement= (TestElement) selection.getFirstElement(); >+ TestElement testElement= (TestElement)selection.getFirstElement(); > > OpenTestAction action; > if (testElement instanceof TestSuiteElement) { >@@ -306,12 +342,17 @@ > } > > private void handleSelected() { >- IStructuredSelection selection= (IStructuredSelection) fSelectionProvider.getSelection(); >+ IStructuredSelection selection= (IStructuredSelection)fSelectionProvider.getSelection(); > TestElement testElement= null; > if (selection.size() == 1) { >- testElement= (TestElement) selection.getFirstElement(); >+ 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) { >@@ -339,7 +380,7 @@ > IStructuredSelection selection= null; > boolean switchLayout= layoutMode != fLayoutMode; > if (switchLayout) { >- selection= (IStructuredSelection) fSelectionProvider.getSelection(); >+ selection= (IStructuredSelection)fSelectionProvider.getSelection(); > if (layoutMode == TestRunnerViewPart.LAYOUT_HIERARCHICAL) { > if (fTreeNeedsRefresh) { > clearUpdateAndExpansion(); >@@ -356,7 +397,7 @@ > //avoid realizing all TableItems, especially in flat mode! > StructuredViewer viewer= getActiveViewer(); > if (failuresOnly) { >- if (! getActiveViewerHasFilter()) { >+ if (!getActiveViewerHasFilter()) { > setActiveViewerNeedsRefresh(true); > setActiveViewerHasFilter(true); > viewer.setInput(null); >@@ -448,15 +489,15 @@ > toUpdate= fNeedUpdate.toArray(); > fNeedUpdate.clear(); > } >- if (! fTreeNeedsRefresh && toUpdate.length > 0) { >+ if (!fTreeNeedsRefresh && toUpdate.length > 0) { > if (fTreeHasFilter) > for (Object element : toUpdate) >- updateElementInTree((TestElement) element); >+ updateElementInTree((TestElement)element); > else { > HashSet<Object> toUpdateWithParents= new HashSet<Object>(); > toUpdateWithParents.addAll(Arrays.asList(toUpdate)); > for (Object element : toUpdate) { >- TestElement parent= ((TestElement) element).getParent(); >+ TestElement parent= ((TestElement)element).getParent(); > while (parent != null) { > toUpdateWithParents.add(parent); > parent= parent.getParent(); >@@ -465,10 +506,10 @@ > fTreeViewer.update(toUpdateWithParents.toArray(), null); > } > } >- if (! fTableNeedsRefresh && toUpdate.length > 0) { >+ if (!fTableNeedsRefresh && toUpdate.length > 0) { > if (fTableHasFilter) > for (Object element : toUpdate) >- updateElementInTable((TestElement) element); >+ updateElementInTable((TestElement)element); > else > fTableViewer.update(toUpdate, null); > } >@@ -485,9 +526,9 @@ > if (fTreeViewer.testFindItem(current) != null) > fTreeViewer.remove(current); > current= current.getParent(); >- } while (! (current instanceof TestRoot) && ! isShown(current)); >+ } while (!(current instanceof TestRoot) && !isShown(current)); > >- while (current != null && ! (current instanceof TestRoot)) { >+ while (current != null && !(current instanceof TestRoot)) { > fTreeViewer.update(current, null); > current= current.getParent(); > } >@@ -514,12 +555,12 @@ > TestElement previous= getNextFailure(element, false); > int insertionIndex= -1; > if (previous != null) { >- TableItem item= (TableItem) fTableViewer.testFindItem(previous); >+ TableItem item= (TableItem)fTableViewer.testFindItem(previous); > if (item != null) > insertionIndex= fTableViewer.getTable().indexOf(item); > } > fTableViewer.insert(element, insertionIndex); >- } else { >+ } else { > fTableViewer.update(element, null); > } > } else { >@@ -532,7 +573,7 @@ > } > > private void autoScrollInUI() { >- if (! fTestRunnerPart.isAutoScroll()) { >+ if (!fTestRunnerPart.isAutoScroll()) { > clearAutoExpand(); > fAutoClose.clear(); > return; >@@ -554,8 +595,8 @@ > TestCaseElement current= fAutoScrollTarget; > fAutoScrollTarget= null; > >- TestSuiteElement parent= current == null ? null : (TestSuiteElement) fTreeContentProvider.getParent(current); >- if (fAutoClose.isEmpty() || ! fAutoClose.getLast().equals(parent)) { >+ TestSuiteElement parent= current == null ? null : (TestSuiteElement)fTreeContentProvider.getParent(current); >+ if (fAutoClose.isEmpty() || !fAutoClose.getLast().equals(parent)) { > // we're in a new branch, so let's close old OK branches: > for (ListIterator<TestSuiteElement> iter= fAutoClose.listIterator(fAutoClose.size()); iter.hasPrevious();) { > TestSuiteElement previousAutoOpened= iter.previous(); >@@ -569,13 +610,149 @@ > } > } > >- while (parent != null && ! fTestRunSession.getTestRoot().equals(parent) && fTreeViewer.getExpandedState(parent) == false) { >+ while (parent != null && !fTestRunSession.getTestRoot().equals(parent) && fTreeViewer.getExpandedState(parent) == false) { > fAutoClose.add(parent); // add to auto-opened elements -> close later if STATUS_OK >- parent= (TestSuiteElement) fTreeContentProvider.getParent(parent); >+ parent= (TestSuiteElement)fTreeContentProvider.getParent(parent); > } > } > if (current != null) > 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.7 >+ */ >+ public void setSelection(final IEditorPart editor) { >+ final IJavaElement selectedJavaElement= getSelectedJavaElementInEditor(editor); >+ setSelection(editor, 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 part the {@link IWorkbenchPart} in which the selection changed. Nothing happens if the >+ * given part if the {@link TestRunnerViewPart} associated with this >+ * {@link TestViewer}. >+ * @param activeJavaElement the selected Java Element (or null) in the active >+ * {@link IWorkbenchPart} >+ * >+ */ >+ private void setSelection(final IWorkbenchPart part, final IJavaElement activeJavaElement) { >+ if (part != fTestRunnerPart) { >+ 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() { >@@ -585,8 +762,8 @@ > } > > public void selectFailure(boolean showNext) { >- IStructuredSelection selection= (IStructuredSelection) getActiveViewer().getSelection(); >- TestElement selected= (TestElement) selection.getFirstElement(); >+ IStructuredSelection selection= (IStructuredSelection)getActiveViewer().getSelection(); >+ TestElement selected= (TestElement)selection.getFirstElement(); > TestElement next; > > if (selected == null) { >@@ -601,7 +778,7 @@ > > private TestElement getNextFailure(TestElement selected, boolean showNext) { > if (selected instanceof TestSuiteElement) { >- TestElement nextChild= getNextChildFailure((TestSuiteElement) selected, showNext); >+ TestElement nextChild= getNextChildFailure((TestSuiteElement)selected, showNext); > if (nextChild != null) > return nextChild; > } >@@ -614,17 +791,17 @@ > return null; > > List<ITestElement> siblings= Arrays.asList(parent.getChildren()); >- if (! showNext) >+ if (!showNext) > siblings= new ReverseList<ITestElement>(siblings); > > int nextIndex= siblings.indexOf(current) + 1; > for (int i= nextIndex; i < siblings.size(); i++) { >- TestElement sibling= (TestElement) siblings.get(i); >+ TestElement sibling= (TestElement)siblings.get(i); > if (sibling.getStatus().isErrorOrFailure()) { > if (sibling instanceof TestCaseElement) { >- return (TestCaseElement) sibling; >+ return (TestCaseElement)sibling; > } else { >- return getNextChildFailure((TestSuiteElement) sibling, showNext); >+ return getNextChildFailure((TestSuiteElement)sibling, showNext); > } > } > } >@@ -633,15 +810,15 @@ > > private TestCaseElement getNextChildFailure(TestSuiteElement root, boolean showNext) { > List<ITestElement> children= Arrays.asList(root.getChildren()); >- if (! showNext) >+ if (!showNext) > children= new ReverseList<ITestElement>(children); > for (int i= 0; i < children.size(); i++) { >- TestElement child= (TestElement) children.get(i); >+ TestElement child= (TestElement)children.get(i); > if (child.getStatus().isErrorOrFailure()) { > if (child instanceof TestCaseElement) { >- return (TestCaseElement) child; >+ return (TestCaseElement)child; > } else { >- return getNextChildFailure((TestSuiteElement) child, showNext); >+ return getNextChildFailure((TestSuiteElement)child, showNext); > } > } > } >@@ -682,7 +859,7 @@ > } > > public synchronized void registerFailedForAutoScroll(TestElement testElement) { >- TestSuiteElement parent= (TestSuiteElement) fTreeContentProvider.getParent(testElement); >+ TestSuiteElement parent= (TestSuiteElement)fTreeContentProvider.getParent(testElement); > if (parent != null) > fAutoExpand.add(parent); > } >@@ -691,5 +868,88 @@ > fTreeViewer.expandToLevel(2); > } > >-} >+ public void selectionChanged(IWorkbenchPart part, ISelection selection) { >+ if (selection instanceof ITextSelection && part instanceof IEditorPart) { >+ setSelection((IEditorPart)part); >+ } >+ } > >+ /** >+ * @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); >+ } >+}
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