Lines 9-16
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> - https://bugs.eclipse.org/bugs/show_bug.cgi?id=102512 - [JUnit] test method name cut off before ( |
12 |
* Xavier Coulon <xcoulon@redhat.com> |
13 |
|
13 |
* - https://bugs.eclipse.org/bugs/show_bug.cgi?id=102512 - [JUnit] test method name cut off before ( |
|
|
14 |
* - https://bugs.eclipse.org/bugs/show_bug.cgi?id=372588 - [JUnit] Add "Link with Editor" to JUnit view |
14 |
*******************************************************************************/ |
15 |
*******************************************************************************/ |
15 |
|
16 |
|
16 |
package org.eclipse.jdt.internal.junit.ui; |
17 |
package org.eclipse.jdt.internal.junit.ui; |
Lines 23-29
Link Here
|
23 |
import java.util.List; |
24 |
import java.util.List; |
24 |
import java.util.ListIterator; |
25 |
import java.util.ListIterator; |
25 |
|
26 |
|
|
|
27 |
import org.eclipse.jdt.junit.model.ITestCaseElement; |
26 |
import org.eclipse.jdt.junit.model.ITestElement; |
28 |
import org.eclipse.jdt.junit.model.ITestElement; |
|
|
29 |
import org.eclipse.jdt.junit.model.ITestSuiteElement; |
27 |
|
30 |
|
28 |
import org.eclipse.swt.SWT; |
31 |
import org.eclipse.swt.SWT; |
29 |
import org.eclipse.swt.dnd.Clipboard; |
32 |
import org.eclipse.swt.dnd.Clipboard; |
Lines 40-47
Link Here
|
40 |
import org.eclipse.jface.action.MenuManager; |
43 |
import org.eclipse.jface.action.MenuManager; |
41 |
import org.eclipse.jface.action.Separator; |
44 |
import org.eclipse.jface.action.Separator; |
42 |
import org.eclipse.jface.viewers.AbstractTreeViewer; |
45 |
import org.eclipse.jface.viewers.AbstractTreeViewer; |
|
|
46 |
import org.eclipse.jface.viewers.ISelection; |
43 |
import org.eclipse.jface.viewers.ISelectionChangedListener; |
47 |
import org.eclipse.jface.viewers.ISelectionChangedListener; |
44 |
import org.eclipse.jface.viewers.IStructuredSelection; |
48 |
import org.eclipse.jface.viewers.IStructuredSelection; |
|
|
49 |
import org.eclipse.jface.viewers.ITreeSelection; |
45 |
import org.eclipse.jface.viewers.SelectionChangedEvent; |
50 |
import org.eclipse.jface.viewers.SelectionChangedEvent; |
46 |
import org.eclipse.jface.viewers.StructuredSelection; |
51 |
import org.eclipse.jface.viewers.StructuredSelection; |
47 |
import org.eclipse.jface.viewers.StructuredViewer; |
52 |
import org.eclipse.jface.viewers.StructuredViewer; |
Lines 50-61
Link Here
|
50 |
import org.eclipse.jface.viewers.Viewer; |
55 |
import org.eclipse.jface.viewers.Viewer; |
51 |
import org.eclipse.jface.viewers.ViewerFilter; |
56 |
import org.eclipse.jface.viewers.ViewerFilter; |
52 |
|
57 |
|
|
|
58 |
import org.eclipse.jface.text.ITextSelection; |
59 |
|
60 |
import org.eclipse.ui.IEditorPart; |
61 |
import org.eclipse.ui.ISelectionListener; |
53 |
import org.eclipse.ui.IWorkbenchActionConstants; |
62 |
import org.eclipse.ui.IWorkbenchActionConstants; |
|
|
63 |
import org.eclipse.ui.IWorkbenchPart; |
64 |
import org.eclipse.ui.PartInitException; |
54 |
import org.eclipse.ui.part.PageBook; |
65 |
import org.eclipse.ui.part.PageBook; |
55 |
|
66 |
|
56 |
import org.eclipse.debug.core.ILaunchManager; |
67 |
import org.eclipse.debug.core.ILaunchManager; |
57 |
|
68 |
|
|
|
69 |
import org.eclipse.jdt.core.ICompilationUnit; |
70 |
import org.eclipse.jdt.core.IJavaElement; |
58 |
import org.eclipse.jdt.core.IJavaProject; |
71 |
import org.eclipse.jdt.core.IJavaProject; |
|
|
72 |
import org.eclipse.jdt.core.IMethod; |
59 |
import org.eclipse.jdt.core.IType; |
73 |
import org.eclipse.jdt.core.IType; |
60 |
import org.eclipse.jdt.core.JavaModelException; |
74 |
import org.eclipse.jdt.core.JavaModelException; |
61 |
|
75 |
|
Lines 66-76
Link Here
|
66 |
import org.eclipse.jdt.internal.junit.model.TestRunSession; |
80 |
import org.eclipse.jdt.internal.junit.model.TestRunSession; |
67 |
import org.eclipse.jdt.internal.junit.model.TestSuiteElement; |
81 |
import org.eclipse.jdt.internal.junit.model.TestSuiteElement; |
68 |
|
82 |
|
|
|
83 |
import org.eclipse.jdt.ui.JavaUI; |
84 |
|
85 |
import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor; |
86 |
import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility; |
87 |
import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; |
69 |
import org.eclipse.jdt.internal.ui.viewsupport.ColoringLabelProvider; |
88 |
import org.eclipse.jdt.internal.ui.viewsupport.ColoringLabelProvider; |
70 |
import org.eclipse.jdt.internal.ui.viewsupport.SelectionProviderMediator; |
89 |
import org.eclipse.jdt.internal.ui.viewsupport.SelectionProviderMediator; |
71 |
|
90 |
|
72 |
|
91 |
|
73 |
public class TestViewer { |
92 |
public class TestViewer implements ISelectionListener { |
74 |
private final class TestSelectionListener implements ISelectionChangedListener { |
93 |
private final class TestSelectionListener implements ISelectionChangedListener { |
75 |
public void selectionChanged(SelectionChangedEvent event) { |
94 |
public void selectionChanged(SelectionChangedEvent event) { |
76 |
handleSelected(); |
95 |
handleSelected(); |
Lines 312-317
Link Here
|
312 |
testElement= (TestElement) selection.getFirstElement(); |
331 |
testElement= (TestElement) selection.getFirstElement(); |
313 |
} |
332 |
} |
314 |
fTestRunnerPart.handleTestSelected(testElement); |
333 |
fTestRunnerPart.handleTestSelected(testElement); |
|
|
334 |
// if LinkWithEditor is active, reveal the JavaEditor and select the java type or method |
335 |
// matching the selected test element, even if the JavaEditor is opened by not active. |
336 |
if (fTestRunnerPart.isLinkWithEditorActive()) { |
337 |
handleTestElementSelected(testElement); |
338 |
} |
315 |
} |
339 |
} |
316 |
|
340 |
|
317 |
public synchronized void setShowTime(boolean showTime) { |
341 |
public synchronized void setShowTime(boolean showTime) { |
Lines 578-583
Link Here
|
578 |
fTreeViewer.reveal(current); |
602 |
fTreeViewer.reveal(current); |
579 |
} |
603 |
} |
580 |
|
604 |
|
|
|
605 |
/** |
606 |
* Sets the current selection from the given {@link IEditorPart} (if it is a |
607 |
* {@link CompilationUnitEditor}) and its selection. |
608 |
* |
609 |
* @param editor the selected Java Element in the active Compilation Unit Editor |
610 |
* |
611 |
* @since 3.7 |
612 |
*/ |
613 |
public void setSelection(final IEditorPart editor) { |
614 |
final IJavaElement selectedJavaElement= getSelectedJavaElementInEditor(editor); |
615 |
setSelection(selectedJavaElement); |
616 |
} |
617 |
|
618 |
/** |
619 |
* Sets the current selection from the given {@link IJavaElement} if it matches an |
620 |
* {@link ITestCaseElement} and updates the LinkWithEditorAction image in the associated |
621 |
* {@link TestRunnerViewPart}. |
622 |
* |
623 |
* @param activeJavaElement the selected Java Element (or null) in the active |
624 |
* {@link IWorkbenchPart} |
625 |
* |
626 |
*/ |
627 |
private void setSelection(final IJavaElement activeJavaElement) { |
628 |
final ITestElement activeTestCaseElement= findTestElement(activeJavaElement); |
629 |
if (activeTestCaseElement != null) { |
630 |
// selection is in-sync |
631 |
fTestRunnerPart.setLinkingWithEditorInSync(true); |
632 |
// 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) |
633 |
final Object currentSelection= getCurrentViewerSelection(); |
634 |
if ((currentSelection instanceof TestCaseElement && ((TestCaseElement)currentSelection).getJavaMethod() != null && !((TestCaseElement)currentSelection).getJavaMethod().equals( |
635 |
activeJavaElement)) |
636 |
|| (currentSelection instanceof TestSuiteElement && ((TestSuiteElement)currentSelection).getJavaType() != null && !((TestSuiteElement)currentSelection).getJavaType().equals( |
637 |
activeJavaElement))) { |
638 |
final IStructuredSelection selection= new StructuredSelection(activeTestCaseElement); |
639 |
fSelectionProvider.setSelection(selection, true); |
640 |
} |
641 |
} |
642 |
else { |
643 |
// selection is out-of-sync: show a different icon on the button. |
644 |
fTestRunnerPart.setLinkingWithEditorInSync(false); |
645 |
} |
646 |
} |
647 |
|
648 |
/** |
649 |
* @return the current selection in the JUnit Viewer (provided by the underlying selection |
650 |
* provider), or {@code null} if the kind of selection is not an {@link ITreeSelection} |
651 |
* nor an {@link IStructuredSelection}. |
652 |
*/ |
653 |
private Object getCurrentViewerSelection() { |
654 |
final ISelection currentSelection= fSelectionProvider.getSelection(); |
655 |
if (currentSelection instanceof ITreeSelection) { |
656 |
return ((ITreeSelection)currentSelection).getFirstElement(); |
657 |
} else if (currentSelection instanceof IStructuredSelection) { |
658 |
return ((IStructuredSelection)currentSelection).getFirstElement(); |
659 |
} |
660 |
return null; |
661 |
} |
662 |
|
663 |
/** |
664 |
* Finds the {@link ITestElement} from the given {@link IJavaElement} |
665 |
* |
666 |
* @param javaElement the java element associated with the {@link ITestElement} to find. |
667 |
* @return the {@link ITestElement} or null if it could not be found. |
668 |
*/ |
669 |
private ITestElement findTestElement(final IJavaElement javaElement) { |
670 |
if (fTestRunSession == null || javaElement == null) { |
671 |
return null; |
672 |
} |
673 |
switch (javaElement.getElementType()) { |
674 |
case IJavaElement.METHOD: |
675 |
final IMethod javaMethod= (IMethod)javaElement; |
676 |
final IType javaType= (IType)javaMethod.getAncestor(IJavaElement.TYPE); |
677 |
final String testClassName= javaType.getFullyQualifiedName(); |
678 |
final String testMethodName= javaMethod.getElementName(); |
679 |
return findTestCaseElement(fTestRunSession.getTestRoot(), testClassName, testMethodName); |
680 |
case IJavaElement.TYPE: |
681 |
return findTestSuiteElement(fTestRunSession.getTestRoot(), ((IType)javaElement).getFullyQualifiedName()); |
682 |
default: |
683 |
return null; |
684 |
} |
685 |
} |
686 |
|
687 |
/** |
688 |
* Finds the {@link ITestCaseElement} with the given test class name and test method name in the |
689 |
* given {@link ITestSuiteElement} |
690 |
* |
691 |
* @param parentElement the parent Test Suite |
692 |
* @param testClassName the name of the test class |
693 |
* @param testMethodName the name of the test method |
694 |
* |
695 |
* @return the {@link ITestCaseElement} or null if it could not be found. |
696 |
*/ |
697 |
private ITestCaseElement findTestCaseElement(final ITestSuiteElement parentElement, final String testClassName, final String testMethodName) { |
698 |
for (ITestElement childElement : parentElement.getChildren()) { |
699 |
if (childElement instanceof ITestCaseElement) { |
700 |
final TestCaseElement testCaseElement= (TestCaseElement)childElement; |
701 |
if (testCaseElement.getJavaType() != null && testCaseElement.getJavaType().getFullyQualifiedName().equals(testClassName) && testCaseElement.getJavaMethod() != null |
702 |
&& testCaseElement.getJavaMethod() != null && testCaseElement.getJavaMethod().getElementName().equals(testMethodName)) { |
703 |
return testCaseElement; |
704 |
} |
705 |
} else if (childElement instanceof ITestSuiteElement) { |
706 |
final ITestCaseElement localResult= findTestCaseElement((ITestSuiteElement)childElement, testClassName, testMethodName); |
707 |
if (localResult != null) { |
708 |
return localResult; |
709 |
} |
710 |
} |
711 |
} |
712 |
return null; |
713 |
} |
714 |
|
715 |
/** |
716 |
* Finds the {@link ITestSuiteElement} with the given test class name in the given |
717 |
* {@link ITestSuiteElement} |
718 |
* |
719 |
* @param parentElement the parent Test Suite |
720 |
* @param testClassName the name of the test class |
721 |
* |
722 |
* @return the {@link ITestSuiteElement} or null if it could not be found. |
723 |
*/ |
724 |
private ITestSuiteElement findTestSuiteElement(final ITestSuiteElement parentElement, final String testClassName) { |
725 |
for (ITestElement childElement : parentElement.getChildren()) { |
726 |
if (childElement instanceof ITestSuiteElement) { |
727 |
final ITestSuiteElement childTestSuite= (ITestSuiteElement)childElement; |
728 |
if (childTestSuite.getSuiteTypeName().equals(testClassName)) { |
729 |
return childTestSuite; |
730 |
} |
731 |
} |
732 |
} |
733 |
return null; |
734 |
} |
735 |
|
581 |
public void selectFirstFailure() { |
736 |
public void selectFirstFailure() { |
582 |
TestCaseElement firstFailure= getNextChildFailure(fTestRunSession.getTestRoot(), true); |
737 |
TestCaseElement firstFailure= getNextChildFailure(fTestRunSession.getTestRoot(), true); |
583 |
if (firstFailure != null) |
738 |
if (firstFailure != null) |
Lines 691-695
Link Here
|
691 |
fTreeViewer.expandToLevel(2); |
846 |
fTreeViewer.expandToLevel(2); |
692 |
} |
847 |
} |
693 |
|
848 |
|
694 |
} |
849 |
/** |
|
|
850 |
* Reacts to a selection change in the active {@link IWorkbenchPart} (or when another part |
851 |
* received the focus). |
852 |
* |
853 |
* @param part the {@link IWorkbenchPart} in which the selection change occurred |
854 |
* @param selection the selection in the given part |
855 |
*/ |
856 |
public void selectionChanged(IWorkbenchPart part, ISelection selection) { |
857 |
if (part instanceof IEditorPart) { |
858 |
setSelection((IEditorPart)part); |
859 |
} else if (part instanceof TestRunnerViewPart) { |
860 |
fTestRunnerPart.setLinkingWithEditorInSync(true); |
861 |
} |
862 |
} |
695 |
|
863 |
|
|
|
864 |
/** |
865 |
* @return the selected {@link IJavaElement} in the current editor if it is a {@link CompilationUnitEditor}, null otherwise. |
866 |
* @param editor the editor |
867 |
*/ |
868 |
private IJavaElement getSelectedJavaElementInEditor(final IEditorPart editor) { |
869 |
if (editor instanceof CompilationUnitEditor) { |
870 |
final CompilationUnitEditor compilationUnitEditor = (CompilationUnitEditor)editor; |
871 |
try { |
872 |
final IJavaElement inputJavaElement= JavaUI.getEditorInputJavaElement(editor.getEditorInput()); |
873 |
final ITextSelection selection= (ITextSelection)compilationUnitEditor.getSelectionProvider().getSelection(); |
874 |
final ICompilationUnit compilationUnit= (ICompilationUnit)inputJavaElement.getAncestor(IJavaElement.COMPILATION_UNIT); |
875 |
return compilationUnit.getElementAt(selection.getOffset()); |
876 |
} catch (JavaModelException e) { |
877 |
JUnitPlugin.log(e); |
878 |
} |
879 |
} |
880 |
return null; |
881 |
} |
882 |
|
883 |
/** |
884 |
* Handles the case when a {@link TestCaseElement} has been selected: open the associated code |
885 |
* in the Java Editor |
886 |
* |
887 |
* @param testElement the new selected {@link TestCaseElement} |
888 |
*/ |
889 |
private void handleTestElementSelected(final ITestElement testElement) { |
890 |
if (testElement instanceof TestCaseElement) { |
891 |
final IMethod selectedMethod= ((TestCaseElement)testElement).getJavaMethod(); |
892 |
handleJavaElementSelected(selectedMethod); |
893 |
} else if (testElement instanceof TestSuiteElement) { |
894 |
final IJavaElement selectedElement= ((TestSuiteElement)testElement).getJavaElement(); |
895 |
handleJavaElementSelected(selectedElement); |
896 |
} |
897 |
} |
898 |
|
899 |
/** |
900 |
* Reveals the given {@link IJavaElement} in its associated Editor if this later is already |
901 |
* open, and sets the "Link with Editor" button state accordingly. |
902 |
* |
903 |
* @param selectedJavaElement the selected {@link IJavaElement} in the {@link TestViewer} that |
904 |
* should be revealed in its Java Editor. |
905 |
*/ |
906 |
private void handleJavaElementSelected(final IJavaElement selectedJavaElement) { |
907 |
try { |
908 |
final IEditorPart editor= EditorUtility.isOpenInEditor(selectedJavaElement); |
909 |
if (selectedJavaElement != null && editor != null && editor instanceof JavaEditor) { |
910 |
final JavaEditor javaEditor= (JavaEditor)editor; |
911 |
final ITextSelection javaEditorSelection= (ITextSelection)javaEditor.getSelectionProvider().getSelection(); |
912 |
final IEditorPart selectedMethodEditor= EditorUtility.isOpenInEditor(selectedJavaElement); |
913 |
// checks if the editor is already open or not |
914 |
if (selectedMethodEditor != null) { |
915 |
// Retrieve the current active editor |
916 |
final IEditorPart activeEditor= fTestRunnerPart.getSite().getPage().getActiveEditor(); |
917 |
// open the required editor if it is not the active one |
918 |
if (!selectedMethodEditor.equals(activeEditor)) { |
919 |
EditorUtility.openInEditor(selectedJavaElement, false); |
920 |
} |
921 |
// retrieve the current java element (unless the associated compilation unit cannot be retrieved) |
922 |
final ICompilationUnit compilationUnit= (ICompilationUnit)selectedJavaElement.getAncestor(IJavaElement.COMPILATION_UNIT); |
923 |
if (compilationUnit != null) { |
924 |
final IJavaElement javaEditorSelectedElement= compilationUnit.getElementAt(javaEditorSelection.getOffset()); |
925 |
// force to reveal the selected element in case where the editor was not active |
926 |
if (!selectedMethodEditor.equals(activeEditor) || !selectedJavaElement.equals(javaEditorSelectedElement)) { |
927 |
EditorUtility.revealInEditor(selectedMethodEditor, selectedJavaElement); |
928 |
} |
929 |
fTestRunnerPart.setLinkingWithEditorInSync(true); |
930 |
return; |
931 |
} |
932 |
} |
933 |
} |
934 |
} catch (JavaModelException e) { |
935 |
JUnitPlugin.log(e); |
936 |
} catch (PartInitException e) { |
937 |
// occurs if the editor could not be opened or the input element is not valid Status code |
938 |
JUnitPlugin.log(e); |
939 |
} |
940 |
fTestRunnerPart.setLinkingWithEditorInSync(false); |
941 |
} |
942 |
|
943 |
} |