Lines 9-14
Link Here
|
9 |
* IBM Corporation - initial API and implementation |
9 |
* IBM Corporation - initial API and implementation |
10 |
* Brock Janiczak (brockj@tpg.com.au) |
10 |
* Brock Janiczak (brockj@tpg.com.au) |
11 |
* - https://bugs.eclipse.org/bugs/show_bug.cgi?id=102236: [JUnit] display execution time next to each test |
11 |
* - https://bugs.eclipse.org/bugs/show_bug.cgi?id=102236: [JUnit] display execution time next to each test |
|
|
12 |
* Xavier Coulon <xcoulon@redhat.com> - [JUnit] Add "Link with Editor" to JUnit view - https://bugs.eclipse.org/bugs/show_bug.cgi?id=372588 |
12 |
*******************************************************************************/ |
13 |
*******************************************************************************/ |
13 |
|
14 |
|
14 |
package org.eclipse.jdt.internal.junit.ui; |
15 |
package org.eclipse.jdt.internal.junit.ui; |
Lines 21-27
Link Here
|
21 |
import java.util.List; |
22 |
import java.util.List; |
22 |
import java.util.ListIterator; |
23 |
import java.util.ListIterator; |
23 |
|
24 |
|
|
|
25 |
import org.eclipse.jdt.junit.model.ITestCaseElement; |
24 |
import org.eclipse.jdt.junit.model.ITestElement; |
26 |
import org.eclipse.jdt.junit.model.ITestElement; |
|
|
27 |
import org.eclipse.jdt.junit.model.ITestSuiteElement; |
25 |
|
28 |
|
26 |
import org.eclipse.swt.SWT; |
29 |
import org.eclipse.swt.SWT; |
27 |
import org.eclipse.swt.dnd.Clipboard; |
30 |
import org.eclipse.swt.dnd.Clipboard; |
Lines 38-44
Link Here
|
38 |
import org.eclipse.jface.action.MenuManager; |
41 |
import org.eclipse.jface.action.MenuManager; |
39 |
import org.eclipse.jface.action.Separator; |
42 |
import org.eclipse.jface.action.Separator; |
40 |
import org.eclipse.jface.viewers.AbstractTreeViewer; |
43 |
import org.eclipse.jface.viewers.AbstractTreeViewer; |
|
|
44 |
import org.eclipse.jface.viewers.IPostSelectionProvider; |
45 |
import org.eclipse.jface.viewers.ISelection; |
41 |
import org.eclipse.jface.viewers.ISelectionChangedListener; |
46 |
import org.eclipse.jface.viewers.ISelectionChangedListener; |
|
|
47 |
import org.eclipse.jface.viewers.ISelectionProvider; |
42 |
import org.eclipse.jface.viewers.IStructuredSelection; |
48 |
import org.eclipse.jface.viewers.IStructuredSelection; |
43 |
import org.eclipse.jface.viewers.SelectionChangedEvent; |
49 |
import org.eclipse.jface.viewers.SelectionChangedEvent; |
44 |
import org.eclipse.jface.viewers.StructuredSelection; |
50 |
import org.eclipse.jface.viewers.StructuredSelection; |
Lines 48-59
Link Here
|
48 |
import org.eclipse.jface.viewers.Viewer; |
54 |
import org.eclipse.jface.viewers.Viewer; |
49 |
import org.eclipse.jface.viewers.ViewerFilter; |
55 |
import org.eclipse.jface.viewers.ViewerFilter; |
50 |
|
56 |
|
|
|
57 |
import org.eclipse.jface.text.ITextSelection; |
58 |
|
59 |
import org.eclipse.ui.IEditorPart; |
60 |
import org.eclipse.ui.IEditorReference; |
61 |
import org.eclipse.ui.IPartListener2; |
62 |
import org.eclipse.ui.ISelectionListener; |
51 |
import org.eclipse.ui.IWorkbenchActionConstants; |
63 |
import org.eclipse.ui.IWorkbenchActionConstants; |
|
|
64 |
import org.eclipse.ui.IWorkbenchPage; |
65 |
import org.eclipse.ui.IWorkbenchPart; |
66 |
import org.eclipse.ui.IWorkbenchPartReference; |
67 |
import org.eclipse.ui.PartInitException; |
52 |
import org.eclipse.ui.part.PageBook; |
68 |
import org.eclipse.ui.part.PageBook; |
53 |
|
69 |
|
54 |
import org.eclipse.debug.core.ILaunchManager; |
70 |
import org.eclipse.debug.core.ILaunchManager; |
55 |
|
71 |
|
|
|
72 |
import org.eclipse.jdt.core.ICompilationUnit; |
73 |
import org.eclipse.jdt.core.IJavaElement; |
56 |
import org.eclipse.jdt.core.IJavaProject; |
74 |
import org.eclipse.jdt.core.IJavaProject; |
|
|
75 |
import org.eclipse.jdt.core.IMethod; |
57 |
import org.eclipse.jdt.core.IType; |
76 |
import org.eclipse.jdt.core.IType; |
58 |
import org.eclipse.jdt.core.JavaModelException; |
77 |
import org.eclipse.jdt.core.JavaModelException; |
59 |
|
78 |
|
Lines 64-69
Link Here
|
64 |
import org.eclipse.jdt.internal.junit.model.TestRunSession; |
83 |
import org.eclipse.jdt.internal.junit.model.TestRunSession; |
65 |
import org.eclipse.jdt.internal.junit.model.TestSuiteElement; |
84 |
import org.eclipse.jdt.internal.junit.model.TestSuiteElement; |
66 |
|
85 |
|
|
|
86 |
import org.eclipse.jdt.ui.JavaUI; |
87 |
|
88 |
import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor; |
89 |
import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility; |
90 |
import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; |
67 |
import org.eclipse.jdt.internal.ui.viewsupport.ColoringLabelProvider; |
91 |
import org.eclipse.jdt.internal.ui.viewsupport.ColoringLabelProvider; |
68 |
import org.eclipse.jdt.internal.ui.viewsupport.SelectionProviderMediator; |
92 |
import org.eclipse.jdt.internal.ui.viewsupport.SelectionProviderMediator; |
69 |
|
93 |
|
Lines 164-169
Link Here
|
164 |
registerViewersRefresh(); |
188 |
registerViewersRefresh(); |
165 |
|
189 |
|
166 |
initContextMenu(); |
190 |
initContextMenu(); |
|
|
191 |
|
192 |
// re-activate the "Link with editor" from start if it was enabled in the previous |
193 |
// instance of the workbench. |
194 |
if(runner.isLinkWithEditorActive()) { |
195 |
setLinkingActive(runner.getSite().getPage(), true); |
196 |
} |
197 |
|
167 |
} |
198 |
} |
168 |
|
199 |
|
169 |
private void createTestViewers(Composite parent) { |
200 |
private void createTestViewers(Composite parent) { |
Lines 302-307
Link Here
|
302 |
testElement= (TestElement) selection.getFirstElement(); |
333 |
testElement= (TestElement) selection.getFirstElement(); |
303 |
} |
334 |
} |
304 |
fTestRunnerPart.handleTestSelected(testElement); |
335 |
fTestRunnerPart.handleTestSelected(testElement); |
|
|
336 |
// if LinkWithEditor is active, reveal the JavaEditor and select the java method |
337 |
// matching the selected test element, even if the JavaEditor is opened by not active. |
338 |
if(fTestRunnerPart.isLinkWithEditorActive() && testElement instanceof TestCaseElement) { |
339 |
handleTestSelected((TestCaseElement) testElement); |
340 |
} |
341 |
} |
342 |
|
343 |
/** |
344 |
* Reacts to a selection change in another {@link IWorkbenchPart}. If the given |
345 |
* {@link ISelection} matches an existing {@link TestCaseElement} in the viewer, this later will |
346 |
* be selected. |
347 |
* |
348 |
* @param part the part in which the selection changed. |
349 |
* @param selection the new selection |
350 |
* |
351 |
* @since 3.7 |
352 |
*/ |
353 |
public void selectionChanged(IWorkbenchPart part, ISelection selection) { |
354 |
if(fTestRunnerPart.isLinkWithEditorActive() && fTestRunnerPart.isLinkWithEditorActive() && part instanceof CompilationUnitEditor) { |
355 |
setSelection((CompilationUnitEditor)part); |
356 |
} |
305 |
} |
357 |
} |
306 |
|
358 |
|
307 |
public synchronized void setShowTime(boolean showTime) { |
359 |
public synchronized void setShowTime(boolean showTime) { |
Lines 568-573
Link Here
|
568 |
fTreeViewer.reveal(current); |
620 |
fTreeViewer.reveal(current); |
569 |
} |
621 |
} |
570 |
|
622 |
|
|
|
623 |
/** |
624 |
* Sets the current selection from the given {@link CompilationUnitEditor} and its selection. |
625 |
* @param editor the selected Java Element in the active Java Editor |
626 |
* |
627 |
*/ |
628 |
private void setSelection(final CompilationUnitEditor editor) { |
629 |
final ISelectionProvider selectionProvider = editor.getSelectionProvider(); |
630 |
final IJavaElement selectedJavaElement= getSelectedJavaElementInEditor(JavaUI.getEditorInputJavaElement(editor.getEditorInput()), selectionProvider.getSelection()); |
631 |
if(selectedJavaElement != null) { |
632 |
setSelection(selectedJavaElement); |
633 |
fJavaEditorSelectionListener = new JavaEditorSelectionListener((ICompilationUnit)selectedJavaElement.getAncestor(IJavaElement.COMPILATION_UNIT)); |
634 |
((IPostSelectionProvider)editor.getSelectionProvider()).addPostSelectionChangedListener(fJavaEditorSelectionListener); |
635 |
} |
636 |
} |
637 |
|
638 |
/** |
639 |
* Selects the the current selection from the given {@link IJavaElement} if it is an {@link IMethod} |
640 |
* @param activeJavaElement the selected Java Element in the active Java Editor |
641 |
* |
642 |
*/ |
643 |
private void setSelection(final IJavaElement activeJavaElement) { |
644 |
// select the method in the JUnit ViewPart |
645 |
// skip if history was cleared and 'Link with Editor' is still enabled. |
646 |
if(fTestRunSession != null && activeJavaElement != null && activeJavaElement.getElementType() == IJavaElement.METHOD) { |
647 |
final IMethod activeJavaMethod = (IMethod)activeJavaElement; |
648 |
final IType activeJavaType = (IType)activeJavaMethod.getAncestor(IJavaElement.TYPE); |
649 |
final String testClassName= activeJavaType.getFullyQualifiedName(); |
650 |
final String testMethodName= activeJavaMethod.getElementName(); |
651 |
final ITestCaseElement activeTestCaseElement = findTestCaseElement(fTestRunSession.getTestRoot(), testClassName, testMethodName); |
652 |
if(activeTestCaseElement != null) { |
653 |
final StructuredSelection selection= new StructuredSelection(activeTestCaseElement); |
654 |
if(!selection.equals(getActiveViewer().getSelection())) { |
655 |
fSelectionProvider.setSelection(selection, true); |
656 |
} |
657 |
} |
658 |
|
659 |
} |
660 |
} |
661 |
|
662 |
private ITestCaseElement findTestCaseElement(final ITestSuiteElement parentElement, final String testClassName, final String testMethodName) { |
663 |
for(ITestElement childElement : parentElement.getChildren()) { |
664 |
if(childElement instanceof ITestCaseElement) { |
665 |
ITestCaseElement testCaseElement = (ITestCaseElement)childElement; |
666 |
if (testCaseElement.getJavaType() != null && testCaseElement.getJavaType().getFullyQualifiedName().equals(testClassName) && testCaseElement.getJavaMethod() != null |
667 |
&& testCaseElement.getJavaMethod().getElementName().equals(testMethodName)) { |
668 |
return testCaseElement; |
669 |
} |
670 |
} else if(childElement instanceof ITestSuiteElement) { |
671 |
final ITestCaseElement localResult= findTestCaseElement((ITestSuiteElement)childElement, testClassName, testMethodName); |
672 |
if(localResult != null) { |
673 |
return localResult; |
674 |
} |
675 |
} |
676 |
} |
677 |
return null; |
678 |
|
679 |
} |
680 |
|
571 |
public void selectFirstFailure() { |
681 |
public void selectFirstFailure() { |
572 |
TestCaseElement firstFailure= getNextChildFailure(fTestRunSession.getTestRoot(), true); |
682 |
TestCaseElement firstFailure= getNextChildFailure(fTestRunSession.getTestRoot(), true); |
573 |
if (firstFailure != null) |
683 |
if (firstFailure != null) |
Lines 680-685
Link Here
|
680 |
public void expandFirstLevel() { |
790 |
public void expandFirstLevel() { |
681 |
fTreeViewer.expandToLevel(2); |
791 |
fTreeViewer.expandToLevel(2); |
682 |
} |
792 |
} |
|
|
793 |
|
794 |
/** |
795 |
* Links the selected test method with the Java Editor |
796 |
* @param page the currently active page |
797 |
* @param active boolean to indicate if the link with editor is enabled ({@code true}) or not ({@code false}) |
798 |
* |
799 |
* @since 3.7 |
800 |
*/ |
801 |
public void setLinkingActive(final IWorkbenchPage page, final boolean active) { |
802 |
if(page == null) { |
803 |
return; |
804 |
} |
805 |
if (active) { |
806 |
// add an IPartListener for future editor activations/opening/closing/etc. |
807 |
page.addPartListener(fLinkWithEditorPartListener); |
808 |
page.addPostSelectionListener(fLinkWithEditorSelectionListener); |
809 |
if(page.getActiveEditor() instanceof CompilationUnitEditor) { |
810 |
setSelection((CompilationUnitEditor)page.getActiveEditor()); |
811 |
} |
812 |
} else { |
813 |
// removes the IPartListener |
814 |
page.removePartListener(fLinkWithEditorPartListener); |
815 |
page.removePostSelectionListener(fLinkWithEditorSelectionListener); |
816 |
} |
817 |
} |
818 |
|
819 |
private final IPartListener2 fLinkWithEditorPartListener= new IPartListener2() { |
820 |
public void partVisible(IWorkbenchPartReference partRef) {} |
821 |
public void partBroughtToTop(IWorkbenchPartReference partRef) {} |
822 |
public void partHidden(IWorkbenchPartReference partRef) {} |
823 |
public void partOpened(IWorkbenchPartReference partRef) {} |
824 |
public void partInputChanged(IWorkbenchPartReference partRef) {} |
825 |
public void partClosed(IWorkbenchPartReference partRef) {} |
683 |
|
826 |
|
|
|
827 |
public void partActivated(IWorkbenchPartReference partRef) { |
828 |
if (partRef instanceof IEditorReference) { |
829 |
editorActivated(((IEditorReference) partRef).getEditor(true)); |
830 |
} |
831 |
} |
832 |
|
833 |
public void partDeactivated(IWorkbenchPartReference partRef) { |
834 |
if (partRef instanceof IEditorReference) { |
835 |
editorDeactivated(((IEditorReference) partRef).getEditor(true)); |
836 |
} |
837 |
} |
838 |
|
839 |
}; |
840 |
|
841 |
private ISelectionListener fLinkWithEditorSelectionListener = new ISelectionListener() { |
842 |
|
843 |
public void selectionChanged(IWorkbenchPart editor, ISelection selection) { |
844 |
if(editor instanceof CompilationUnitEditor && selection instanceof ITextSelection) { |
845 |
setSelection((CompilationUnitEditor)editor); |
846 |
} |
847 |
} |
848 |
|
849 |
}; |
850 |
|
851 |
private JavaEditorSelectionListener fJavaEditorSelectionListener; |
852 |
|
853 |
/** |
854 |
* Static Inner Java Editor selection listener |
855 |
* When the user moves to another |
856 |
* @since 3.7 |
857 |
*/ |
858 |
private class JavaEditorSelectionListener implements ISelectionChangedListener { |
859 |
|
860 |
private final ICompilationUnit compilationUnit; |
861 |
|
862 |
JavaEditorSelectionListener(final ICompilationUnit compilationUnit) { |
863 |
this.compilationUnit = compilationUnit; |
864 |
} |
865 |
|
866 |
public void selectionChanged(final SelectionChangedEvent event) { |
867 |
IJavaElement selectedJavaElement= getSelectedJavaElementInEditor(compilationUnit, event.getSelection()); |
868 |
setSelection(selectedJavaElement); |
869 |
} |
870 |
|
871 |
/** |
872 |
* Overriding java.lang.Object#hashCode() using the |
873 |
* {@link ICompilationUnit#getHandleIdentifier()} value to avoid duplicate listener |
874 |
* registrations in the {@link JavaEditor}'s {@link IPostSelectionProvider}. |
875 |
*/ |
876 |
@Override |
877 |
public int hashCode() { |
878 |
final int prime= 31; |
879 |
int result= 1; |
880 |
result= prime * result + ((compilationUnit == null) ? 0 : compilationUnit.getHandleIdentifier().hashCode()); |
881 |
return result; |
882 |
} |
883 |
|
884 |
/** |
885 |
* Overriding java.lang.Object#equals() using the |
886 |
* {@link ICompilationUnit#getHandleIdentifier()} value to avoid duplicate listener |
887 |
* registrations in the {@link JavaEditor}'s {@link IPostSelectionProvider}. |
888 |
*/ |
889 |
@Override |
890 |
public boolean equals(Object obj) { |
891 |
if (this == obj) { |
892 |
return true; |
893 |
} |
894 |
if (obj == null) { |
895 |
return false; |
896 |
} |
897 |
if (getClass() != obj.getClass()) { |
898 |
return false; |
899 |
} |
900 |
JavaEditorSelectionListener other= (JavaEditorSelectionListener)obj; |
901 |
if (compilationUnit == null) { |
902 |
if (other.compilationUnit != null) { |
903 |
return false; |
904 |
} |
905 |
} else if (!compilationUnit.getHandleIdentifier().equals(other.compilationUnit.getHandleIdentifier())) { |
906 |
return false; |
907 |
} |
908 |
return true; |
909 |
} |
910 |
} |
911 |
|
912 |
/** |
913 |
* An editor has been activated. Set the selection in this JUnit ViewPart |
914 |
* to match the editor's input, if linking is enabled. |
915 |
* @param editor the activated editor |
916 |
*/ |
917 |
private void editorActivated(IEditorPart editor) { |
918 |
if(!(editor instanceof CompilationUnitEditor)) { |
919 |
return; |
920 |
} |
921 |
CompilationUnitEditor javaEditor= (CompilationUnitEditor)editor; |
922 |
setSelection(javaEditor); |
923 |
} |
924 |
|
925 |
private IJavaElement getSelectedJavaElementInEditor(final IJavaElement javaElement, final ISelection selection) { |
926 |
if(javaElement instanceof ICompilationUnit && selection instanceof ITextSelection) { |
927 |
try { |
928 |
return ((ICompilationUnit)javaElement).getElementAt(((ITextSelection)selection).getOffset()); |
929 |
} catch(JavaModelException e) { |
930 |
JUnitPlugin.log(e); |
931 |
} |
932 |
} |
933 |
return null; |
934 |
} |
935 |
|
936 |
/** |
937 |
* An editor has been deactivated. |
938 |
* @param editor the activated editor |
939 |
*/ |
940 |
private void editorDeactivated(IEditorPart editor) { |
941 |
if(fJavaEditorSelectionListener != null & editor instanceof CompilationUnitEditor) { |
942 |
final IPostSelectionProvider selectionProvider = (IPostSelectionProvider)((CompilationUnitEditor)editor).getSelectionProvider(); |
943 |
selectionProvider.removePostSelectionChangedListener(fJavaEditorSelectionListener); |
944 |
} |
945 |
} |
946 |
|
947 |
private void handleTestSelected(final TestCaseElement testCaseElement) { |
948 |
try { |
949 |
final IType type= testCaseElement.getJavaType(); |
950 |
final IEditorPart editor= EditorUtility.isOpenInEditor(type); |
951 |
final IMethod selectedMethod= testCaseElement.getJavaMethod(); |
952 |
if(selectedMethod != null && editor != null && editor instanceof JavaEditor) { |
953 |
final JavaEditor javaEditor = (JavaEditor)editor; |
954 |
final ITextSelection javaEditorSelection= (ITextSelection)javaEditor.getSelectionProvider().getSelection(); |
955 |
final IJavaElement javaEditorSelectedElement= type.getCompilationUnit().getElementAt(javaEditorSelection.getOffset()); |
956 |
IEditorPart selectedMethodEditor = EditorUtility.isOpenInEditor(selectedMethod); |
957 |
// checks if the editor is already open or not |
958 |
if(selectedMethodEditor != null) { |
959 |
EditorUtility.openInEditor(selectedMethod, false); |
960 |
if(!selectedMethod.equals(javaEditorSelectedElement)) { |
961 |
EditorUtility.revealInEditor(selectedMethodEditor, selectedMethod); |
962 |
} |
963 |
} |
964 |
if(!selectedMethod.equals(javaEditorSelectedElement)) { |
965 |
JavaUI.revealInEditor(editor, (IJavaElement)selectedMethod); |
966 |
} |
967 |
} |
968 |
} catch(JavaModelException e) { |
969 |
JUnitPlugin.log(e); |
970 |
} catch(PartInitException e) { |
971 |
// ignore if no editor input can be found |
972 |
} |
973 |
} |
974 |
|
684 |
} |
975 |
} |
685 |
|
976 |
|