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 302-307
Link Here
|
302 |
testElement= (TestElement) selection.getFirstElement(); |
326 |
testElement= (TestElement) selection.getFirstElement(); |
303 |
} |
327 |
} |
304 |
fTestRunnerPart.handleTestSelected(testElement); |
328 |
fTestRunnerPart.handleTestSelected(testElement); |
|
|
329 |
// if LinkWithEditor is active, reveal the JavaEditor and select the java method |
330 |
// matching the selected test element, even if the JavaEditor is opened by not active. |
331 |
if(fTestRunnerPart.isLinkWithEditorActive() && testElement instanceof TestCaseElement) { |
332 |
handleTestSelected((TestCaseElement) testElement); |
333 |
} |
334 |
} |
335 |
|
336 |
/** |
337 |
* Reacts to a selection change in another {@link IWorkbenchPart}. If the given |
338 |
* {@link ISelection} matches an existing {@link TestCaseElement} in the viewer, this later will |
339 |
* be selected. |
340 |
* |
341 |
* @param part the part in which the selection changed. |
342 |
* @param selection the new selection |
343 |
* |
344 |
* @since 3.7 |
345 |
*/ |
346 |
public void selectionChanged(IWorkbenchPart part, ISelection selection) { |
347 |
if(fTestRunnerPart.isLinkWithEditorActive() && fTestRunnerPart.isLinkWithEditorActive() && part instanceof CompilationUnitEditor) { |
348 |
setSelection((CompilationUnitEditor)part); |
349 |
} |
305 |
} |
350 |
} |
306 |
|
351 |
|
307 |
public synchronized void setShowTime(boolean showTime) { |
352 |
public synchronized void setShowTime(boolean showTime) { |
Lines 568-573
Link Here
|
568 |
fTreeViewer.reveal(current); |
613 |
fTreeViewer.reveal(current); |
569 |
} |
614 |
} |
570 |
|
615 |
|
|
|
616 |
/** |
617 |
* Sets the current selection from the given {@link CompilationUnitEditor} and its selection. |
618 |
* @param editor the selected Java Element in the active Java Editor |
619 |
* |
620 |
*/ |
621 |
private void setSelection(final CompilationUnitEditor editor) { |
622 |
final ISelectionProvider selectionProvider = editor.getSelectionProvider(); |
623 |
final IJavaElement selectedJavaElement= getSelectedJavaElementInEditor(JavaUI.getEditorInputJavaElement(editor.getEditorInput()), selectionProvider.getSelection()); |
624 |
if(selectedJavaElement != null) { |
625 |
setSelection(selectedJavaElement); |
626 |
fJavaEditorSelectionListener = new JavaEditorSelectionListener((ICompilationUnit)selectedJavaElement.getAncestor(IJavaElement.COMPILATION_UNIT)); |
627 |
((IPostSelectionProvider)editor.getSelectionProvider()).addPostSelectionChangedListener(fJavaEditorSelectionListener); |
628 |
} |
629 |
} |
630 |
|
631 |
/** |
632 |
* Selects the the current selection from the given {@link IJavaElement} if it is an {@link IMethod} |
633 |
* @param activeJavaElement the selected Java Element in the active Java Editor |
634 |
* |
635 |
*/ |
636 |
private void setSelection(final IJavaElement activeJavaElement) { |
637 |
// select the method in the JUnit ViewPart |
638 |
// skip if history was cleared and 'Link with Editor' is still enabled. |
639 |
if(fTestRunSession != null && activeJavaElement != null && activeJavaElement.getElementType() == IJavaElement.METHOD) { |
640 |
final IMethod activeJavaMethod = (IMethod)activeJavaElement; |
641 |
final IType activeJavaType = (IType)activeJavaMethod.getAncestor(IJavaElement.TYPE); |
642 |
final String testClassName= activeJavaType.getFullyQualifiedName(); |
643 |
final String testMethodName= activeJavaMethod.getElementName(); |
644 |
final ITestCaseElement activeTestCaseElement = findTestCaseElement(fTestRunSession.getTestRoot(), testClassName, testMethodName); |
645 |
if(activeTestCaseElement != null) { |
646 |
final StructuredSelection selection= new StructuredSelection(activeTestCaseElement); |
647 |
if(!selection.equals(getActiveViewer().getSelection())) { |
648 |
fSelectionProvider.setSelection(selection, true); |
649 |
} |
650 |
} |
651 |
|
652 |
} |
653 |
} |
654 |
|
655 |
private ITestCaseElement findTestCaseElement(final ITestSuiteElement parentElement, final String testClassName, final String testMethodName) { |
656 |
for(ITestElement childElement : parentElement.getChildren()) { |
657 |
if(childElement instanceof ITestCaseElement) { |
658 |
ITestCaseElement testCaseElement = (ITestCaseElement)childElement; |
659 |
if (testCaseElement.getJavaType() != null && testCaseElement.getJavaType().getFullyQualifiedName().equals(testClassName) && testCaseElement.getJavaMethod() != null |
660 |
&& testCaseElement.getJavaMethod().getElementName().equals(testMethodName)) { |
661 |
return testCaseElement; |
662 |
} |
663 |
} else if(childElement instanceof ITestSuiteElement) { |
664 |
final ITestCaseElement localResult= findTestCaseElement((ITestSuiteElement)childElement, testClassName, testMethodName); |
665 |
if(localResult != null) { |
666 |
return localResult; |
667 |
} |
668 |
} |
669 |
} |
670 |
return null; |
671 |
|
672 |
} |
673 |
|
571 |
public void selectFirstFailure() { |
674 |
public void selectFirstFailure() { |
572 |
TestCaseElement firstFailure= getNextChildFailure(fTestRunSession.getTestRoot(), true); |
675 |
TestCaseElement firstFailure= getNextChildFailure(fTestRunSession.getTestRoot(), true); |
573 |
if (firstFailure != null) |
676 |
if (firstFailure != null) |
Lines 680-685
Link Here
|
680 |
public void expandFirstLevel() { |
783 |
public void expandFirstLevel() { |
681 |
fTreeViewer.expandToLevel(2); |
784 |
fTreeViewer.expandToLevel(2); |
682 |
} |
785 |
} |
|
|
786 |
|
787 |
/** |
788 |
* Links the selected test method with the Java Editor |
789 |
* @param page the currently active page |
790 |
* @param active boolean to indicate if the link with editor is enabled ({@code true}) or not ({@code false}) |
791 |
* |
792 |
* @since 3.7 |
793 |
*/ |
794 |
public void setLinkingActive(final IWorkbenchPage page, final boolean active) { |
795 |
if(page == null) { |
796 |
return; |
797 |
} |
798 |
if (active) { |
799 |
// add an IPartListener for future editor activations/opening/closing/etc. |
800 |
page.addPartListener(fLinkWithEditorPartListener); |
801 |
page.addPostSelectionListener(fLinkWithEditorSelectionListener); |
802 |
if(page.getActiveEditor() instanceof CompilationUnitEditor) { |
803 |
setSelection((CompilationUnitEditor)page.getActiveEditor()); |
804 |
} |
805 |
} else { |
806 |
// removes the IPartListener |
807 |
page.removePartListener(fLinkWithEditorPartListener); |
808 |
page.removePostSelectionListener(fLinkWithEditorSelectionListener); |
809 |
} |
810 |
} |
811 |
|
812 |
private final IPartListener2 fLinkWithEditorPartListener= new IPartListener2() { |
813 |
public void partVisible(IWorkbenchPartReference partRef) {} |
814 |
public void partBroughtToTop(IWorkbenchPartReference partRef) {} |
815 |
public void partHidden(IWorkbenchPartReference partRef) {} |
816 |
public void partOpened(IWorkbenchPartReference partRef) {} |
817 |
public void partInputChanged(IWorkbenchPartReference partRef) {} |
818 |
public void partClosed(IWorkbenchPartReference partRef) {} |
683 |
|
819 |
|
|
|
820 |
public void partActivated(IWorkbenchPartReference partRef) { |
821 |
if (partRef instanceof IEditorReference) { |
822 |
editorActivated(((IEditorReference) partRef).getEditor(true)); |
823 |
} |
824 |
} |
825 |
|
826 |
public void partDeactivated(IWorkbenchPartReference partRef) { |
827 |
if (partRef instanceof IEditorReference) { |
828 |
editorDeactivated(((IEditorReference) partRef).getEditor(true)); |
829 |
} |
830 |
} |
831 |
|
832 |
}; |
833 |
|
834 |
private ISelectionListener fLinkWithEditorSelectionListener = new ISelectionListener() { |
835 |
|
836 |
public void selectionChanged(IWorkbenchPart editor, ISelection selection) { |
837 |
if(editor instanceof CompilationUnitEditor && selection instanceof ITextSelection) { |
838 |
setSelection((CompilationUnitEditor)editor); |
839 |
} |
840 |
} |
841 |
|
842 |
}; |
843 |
|
844 |
private JavaEditorSelectionListener fJavaEditorSelectionListener; |
845 |
|
846 |
/** |
847 |
* Static Inner Java Editor selection listener |
848 |
* When the user moves to another |
849 |
* @since 3.7 |
850 |
*/ |
851 |
private class JavaEditorSelectionListener implements ISelectionChangedListener { |
852 |
|
853 |
private final ICompilationUnit compilationUnit; |
854 |
|
855 |
JavaEditorSelectionListener(final ICompilationUnit compilationUnit) { |
856 |
this.compilationUnit = compilationUnit; |
857 |
} |
858 |
|
859 |
public void selectionChanged(final SelectionChangedEvent event) { |
860 |
IJavaElement selectedJavaElement= getSelectedJavaElementInEditor(compilationUnit, event.getSelection()); |
861 |
setSelection(selectedJavaElement); |
862 |
} |
863 |
|
864 |
/** |
865 |
* Overriding java.lang.Object#hashCode() using the |
866 |
* {@link ICompilationUnit#getHandleIdentifier()} value to avoid duplicate listener |
867 |
* registrations in the {@link JavaEditor}'s {@link IPostSelectionProvider}. |
868 |
*/ |
869 |
@Override |
870 |
public int hashCode() { |
871 |
final int prime= 31; |
872 |
int result= 1; |
873 |
result= prime * result + ((compilationUnit == null) ? 0 : compilationUnit.getHandleIdentifier().hashCode()); |
874 |
return result; |
875 |
} |
876 |
|
877 |
/** |
878 |
* Overriding java.lang.Object#equals() using the |
879 |
* {@link ICompilationUnit#getHandleIdentifier()} value to avoid duplicate listener |
880 |
* registrations in the {@link JavaEditor}'s {@link IPostSelectionProvider}. |
881 |
*/ |
882 |
@Override |
883 |
public boolean equals(Object obj) { |
884 |
if (this == obj) { |
885 |
return true; |
886 |
} |
887 |
if (obj == null) { |
888 |
return false; |
889 |
} |
890 |
if (getClass() != obj.getClass()) { |
891 |
return false; |
892 |
} |
893 |
JavaEditorSelectionListener other= (JavaEditorSelectionListener)obj; |
894 |
if (compilationUnit == null) { |
895 |
if (other.compilationUnit != null) { |
896 |
return false; |
897 |
} |
898 |
} else if (!compilationUnit.getHandleIdentifier().equals(other.compilationUnit.getHandleIdentifier())) { |
899 |
return false; |
900 |
} |
901 |
return true; |
902 |
} |
903 |
} |
904 |
|
905 |
/** |
906 |
* An editor has been activated. Set the selection in this JUnit ViewPart |
907 |
* to match the editor's input, if linking is enabled. |
908 |
* @param editor the activated editor |
909 |
*/ |
910 |
private void editorActivated(IEditorPart editor) { |
911 |
if(!(editor instanceof CompilationUnitEditor)) { |
912 |
return; |
913 |
} |
914 |
CompilationUnitEditor javaEditor= (CompilationUnitEditor)editor; |
915 |
setSelection(javaEditor); |
916 |
} |
917 |
|
918 |
private IJavaElement getSelectedJavaElementInEditor(final IJavaElement javaElement, final ISelection selection) { |
919 |
if(javaElement instanceof ICompilationUnit && selection instanceof ITextSelection) { |
920 |
try { |
921 |
return ((ICompilationUnit)javaElement).getElementAt(((ITextSelection)selection).getOffset()); |
922 |
} catch(JavaModelException e) { |
923 |
JUnitPlugin.log(e); |
924 |
} |
925 |
} |
926 |
return null; |
927 |
} |
928 |
|
929 |
/** |
930 |
* An editor has been deactivated. |
931 |
* @param editor the activated editor |
932 |
*/ |
933 |
private void editorDeactivated(IEditorPart editor) { |
934 |
if(fJavaEditorSelectionListener != null & editor instanceof CompilationUnitEditor) { |
935 |
final IPostSelectionProvider selectionProvider = (IPostSelectionProvider)((CompilationUnitEditor)editor).getSelectionProvider(); |
936 |
selectionProvider.removePostSelectionChangedListener(fJavaEditorSelectionListener); |
937 |
} |
938 |
} |
939 |
|
940 |
private void handleTestSelected(final TestCaseElement testCaseElement) { |
941 |
try { |
942 |
final IType type= testCaseElement.getJavaType(); |
943 |
final IEditorPart editor= EditorUtility.isOpenInEditor(type); |
944 |
final IMethod selectedMethod= testCaseElement.getJavaMethod(); |
945 |
if(selectedMethod != null && editor != null && editor instanceof JavaEditor) { |
946 |
final JavaEditor javaEditor = (JavaEditor)editor; |
947 |
final ITextSelection javaEditorSelection= (ITextSelection)javaEditor.getSelectionProvider().getSelection(); |
948 |
final IJavaElement javaEditorSelectedElement= type.getCompilationUnit().getElementAt(javaEditorSelection.getOffset()); |
949 |
IEditorPart selectedMethodEditor = EditorUtility.isOpenInEditor(selectedMethod); |
950 |
// checks if the editor is already open or not |
951 |
if(selectedMethodEditor != null) { |
952 |
EditorUtility.openInEditor(selectedMethod, false); |
953 |
if(!selectedMethod.equals(javaEditorSelectedElement)) { |
954 |
EditorUtility.revealInEditor(selectedMethodEditor, selectedMethod); |
955 |
} |
956 |
} |
957 |
if(!selectedMethod.equals(javaEditorSelectedElement)) { |
958 |
JavaUI.revealInEditor(editor, (IJavaElement)selectedMethod); |
959 |
} |
960 |
} |
961 |
} catch(JavaModelException e) { |
962 |
JUnitPlugin.log(e); |
963 |
} catch(PartInitException e) { |
964 |
// ignore if no editor input can be found |
965 |
} |
966 |
} |
967 |
|
684 |
} |
968 |
} |
685 |
|
969 |
|