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 42-49
Link Here
|
42 |
import org.eclipse.jface.action.MenuManager; |
45 |
import org.eclipse.jface.action.MenuManager; |
43 |
import org.eclipse.jface.action.Separator; |
46 |
import org.eclipse.jface.action.Separator; |
44 |
import org.eclipse.jface.viewers.AbstractTreeViewer; |
47 |
import org.eclipse.jface.viewers.AbstractTreeViewer; |
|
|
48 |
import org.eclipse.jface.viewers.ISelection; |
45 |
import org.eclipse.jface.viewers.ISelectionChangedListener; |
49 |
import org.eclipse.jface.viewers.ISelectionChangedListener; |
46 |
import org.eclipse.jface.viewers.IStructuredSelection; |
50 |
import org.eclipse.jface.viewers.IStructuredSelection; |
|
|
51 |
import org.eclipse.jface.viewers.ITreeSelection; |
47 |
import org.eclipse.jface.viewers.SelectionChangedEvent; |
52 |
import org.eclipse.jface.viewers.SelectionChangedEvent; |
48 |
import org.eclipse.jface.viewers.StructuredSelection; |
53 |
import org.eclipse.jface.viewers.StructuredSelection; |
49 |
import org.eclipse.jface.viewers.StructuredViewer; |
54 |
import org.eclipse.jface.viewers.StructuredViewer; |
Lines 52-64
Link Here
|
52 |
import org.eclipse.jface.viewers.Viewer; |
57 |
import org.eclipse.jface.viewers.Viewer; |
53 |
import org.eclipse.jface.viewers.ViewerFilter; |
58 |
import org.eclipse.jface.viewers.ViewerFilter; |
54 |
|
59 |
|
|
|
60 |
import org.eclipse.jface.text.ITextSelection; |
61 |
|
62 |
import org.eclipse.ui.IEditorPart; |
63 |
import org.eclipse.ui.ISelectionListener; |
55 |
import org.eclipse.ui.IWorkbenchActionConstants; |
64 |
import org.eclipse.ui.IWorkbenchActionConstants; |
|
|
65 |
import org.eclipse.ui.IWorkbenchPart; |
66 |
import org.eclipse.ui.PartInitException; |
56 |
import org.eclipse.ui.part.PageBook; |
67 |
import org.eclipse.ui.part.PageBook; |
57 |
|
68 |
|
58 |
import org.eclipse.debug.core.ILaunchConfiguration; |
69 |
import org.eclipse.debug.core.ILaunchConfiguration; |
59 |
import org.eclipse.debug.core.ILaunchManager; |
70 |
import org.eclipse.debug.core.ILaunchManager; |
60 |
|
71 |
|
|
|
72 |
import org.eclipse.jdt.core.ICompilationUnit; |
73 |
import org.eclipse.jdt.core.IJavaElement; |
61 |
import org.eclipse.jdt.core.IJavaProject; |
74 |
import org.eclipse.jdt.core.IJavaProject; |
|
|
75 |
import org.eclipse.jdt.core.IMethod; |
62 |
import org.eclipse.jdt.core.IType; |
76 |
import org.eclipse.jdt.core.IType; |
63 |
import org.eclipse.jdt.core.JavaModelException; |
77 |
import org.eclipse.jdt.core.JavaModelException; |
64 |
|
78 |
|
Lines 72-82
Link Here
|
72 |
|
86 |
|
73 |
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; |
87 |
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; |
74 |
|
88 |
|
|
|
89 |
import org.eclipse.jdt.ui.JavaUI; |
90 |
|
91 |
import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor; |
92 |
import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility; |
93 |
import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; |
75 |
import org.eclipse.jdt.internal.ui.viewsupport.ColoringLabelProvider; |
94 |
import org.eclipse.jdt.internal.ui.viewsupport.ColoringLabelProvider; |
76 |
import org.eclipse.jdt.internal.ui.viewsupport.SelectionProviderMediator; |
95 |
import org.eclipse.jdt.internal.ui.viewsupport.SelectionProviderMediator; |
77 |
|
96 |
|
78 |
|
97 |
|
79 |
public class TestViewer { |
98 |
public class TestViewer implements ISelectionListener { |
80 |
private final class TestSelectionListener implements ISelectionChangedListener { |
99 |
private final class TestSelectionListener implements ISelectionChangedListener { |
81 |
public void selectionChanged(SelectionChangedEvent event) { |
100 |
public void selectionChanged(SelectionChangedEvent event) { |
82 |
handleSelected(); |
101 |
handleSelected(); |
Lines 343-348
Link Here
|
343 |
testElement= (TestElement) selection.getFirstElement(); |
362 |
testElement= (TestElement) selection.getFirstElement(); |
344 |
} |
363 |
} |
345 |
fTestRunnerPart.handleTestSelected(testElement); |
364 |
fTestRunnerPart.handleTestSelected(testElement); |
|
|
365 |
// if LinkWithEditor is active, reveal the JavaEditor and select the java type or method |
366 |
// matching the selected test element, even if the JavaEditor is opened by not active. |
367 |
if (fTestRunnerPart.isLinkWithEditorActive()) { |
368 |
handleTestElementSelected(testElement); |
369 |
} |
346 |
} |
370 |
} |
347 |
|
371 |
|
348 |
public synchronized void setShowTime(boolean showTime) { |
372 |
public synchronized void setShowTime(boolean showTime) { |
Lines 609-614
Link Here
|
609 |
fTreeViewer.reveal(current); |
633 |
fTreeViewer.reveal(current); |
610 |
} |
634 |
} |
611 |
|
635 |
|
|
|
636 |
/** |
637 |
* Sets the current selection from the given {@link IEditorPart} (if it is a |
638 |
* {@link CompilationUnitEditor}) and its selection. |
639 |
* |
640 |
* @param editor the selected Java Element in the active Compilation Unit Editor |
641 |
* |
642 |
* @since 3.7 |
643 |
*/ |
644 |
public void setSelection(final IEditorPart editor) { |
645 |
final IJavaElement selectedJavaElement= getSelectedJavaElementInEditor(editor); |
646 |
setSelection(selectedJavaElement); |
647 |
} |
648 |
|
649 |
/** |
650 |
* Sets the current selection from the given {@link IJavaElement} if it matches an |
651 |
* {@link ITestCaseElement} and updates the LinkWithEditorAction image in the associated |
652 |
* {@link TestRunnerViewPart}. |
653 |
* |
654 |
* @param activeJavaElement the selected Java Element (or null) in the active |
655 |
* {@link IWorkbenchPart} |
656 |
* |
657 |
*/ |
658 |
private void setSelection(final IJavaElement activeJavaElement) { |
659 |
final ITestElement activeTestCaseElement= findTestElement(activeJavaElement); |
660 |
if (activeTestCaseElement != null) { |
661 |
// selection is in-sync |
662 |
fTestRunnerPart.setLinkingWithEditorInSync(true); |
663 |
// 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) |
664 |
final Object currentSelection= getCurrentViewerSelection(); |
665 |
if ((currentSelection instanceof TestCaseElement && ((TestCaseElement)currentSelection).getJavaMethod() != null && !((TestCaseElement)currentSelection).getJavaMethod().equals( |
666 |
activeJavaElement)) |
667 |
|| (currentSelection instanceof TestSuiteElement && ((TestSuiteElement)currentSelection).getJavaType() != null && !((TestSuiteElement)currentSelection).getJavaType().equals( |
668 |
activeJavaElement))) { |
669 |
final IStructuredSelection selection= new StructuredSelection(activeTestCaseElement); |
670 |
fSelectionProvider.setSelection(selection, true); |
671 |
} |
672 |
} |
673 |
else { |
674 |
// selection is out-of-sync: show a different icon on the button. |
675 |
fTestRunnerPart.setLinkingWithEditorInSync(false); |
676 |
} |
677 |
} |
678 |
|
679 |
/** |
680 |
* @return the current selection in the JUnit Viewer (provided by the underlying selection |
681 |
* provider), or {@code null} if the kind of selection is not an {@link ITreeSelection} |
682 |
* nor an {@link IStructuredSelection}. |
683 |
*/ |
684 |
private Object getCurrentViewerSelection() { |
685 |
final ISelection currentSelection= fSelectionProvider.getSelection(); |
686 |
if (currentSelection instanceof ITreeSelection) { |
687 |
return ((ITreeSelection)currentSelection).getFirstElement(); |
688 |
} else if (currentSelection instanceof IStructuredSelection) { |
689 |
return ((IStructuredSelection)currentSelection).getFirstElement(); |
690 |
} |
691 |
return null; |
692 |
} |
693 |
|
694 |
/** |
695 |
* Finds the {@link ITestElement} from the given {@link IJavaElement} |
696 |
* |
697 |
* @param javaElement the java element associated with the {@link ITestElement} to find. |
698 |
* @return the {@link ITestElement} or null if it could not be found. |
699 |
*/ |
700 |
private ITestElement findTestElement(final IJavaElement javaElement) { |
701 |
if (fTestRunSession == null || javaElement == null) { |
702 |
return null; |
703 |
} |
704 |
switch (javaElement.getElementType()) { |
705 |
case IJavaElement.METHOD: |
706 |
final IMethod javaMethod= (IMethod)javaElement; |
707 |
final IType javaType= (IType)javaMethod.getAncestor(IJavaElement.TYPE); |
708 |
final String testClassName= javaType.getFullyQualifiedName(); |
709 |
final String testMethodName= javaMethod.getElementName(); |
710 |
return findTestCaseElement(fTestRunSession.getTestRoot(), testClassName, testMethodName); |
711 |
case IJavaElement.TYPE: |
712 |
return findTestSuiteElement(fTestRunSession.getTestRoot(), ((IType)javaElement).getFullyQualifiedName()); |
713 |
default: |
714 |
return null; |
715 |
} |
716 |
} |
717 |
|
718 |
/** |
719 |
* Finds the {@link ITestCaseElement} with the given test class name and test method name in the |
720 |
* given {@link ITestSuiteElement} |
721 |
* |
722 |
* @param parentElement the parent Test Suite |
723 |
* @param testClassName the name of the test class |
724 |
* @param testMethodName the name of the test method |
725 |
* |
726 |
* @return the {@link ITestCaseElement} or null if it could not be found. |
727 |
*/ |
728 |
private ITestCaseElement findTestCaseElement(final ITestSuiteElement parentElement, final String testClassName, final String testMethodName) { |
729 |
for (ITestElement childElement : parentElement.getChildren()) { |
730 |
if (childElement instanceof ITestCaseElement) { |
731 |
final TestCaseElement testCaseElement= (TestCaseElement)childElement; |
732 |
if (testCaseElement.getJavaType() != null && testCaseElement.getJavaType().getFullyQualifiedName().equals(testClassName) && testCaseElement.getJavaMethod() != null |
733 |
&& testCaseElement.getJavaMethod() != null && testCaseElement.getJavaMethod().getElementName().equals(testMethodName)) { |
734 |
return testCaseElement; |
735 |
} |
736 |
} else if (childElement instanceof ITestSuiteElement) { |
737 |
final ITestCaseElement localResult= findTestCaseElement((ITestSuiteElement)childElement, testClassName, testMethodName); |
738 |
if (localResult != null) { |
739 |
return localResult; |
740 |
} |
741 |
} |
742 |
} |
743 |
return null; |
744 |
} |
745 |
|
746 |
/** |
747 |
* Finds the {@link ITestSuiteElement} with the given test class name in the given |
748 |
* {@link ITestSuiteElement} |
749 |
* |
750 |
* @param parentElement the parent Test Suite |
751 |
* @param testClassName the name of the test class |
752 |
* |
753 |
* @return the {@link ITestSuiteElement} or null if it could not be found. |
754 |
*/ |
755 |
private ITestSuiteElement findTestSuiteElement(final ITestSuiteElement parentElement, final String testClassName) { |
756 |
for (ITestElement childElement : parentElement.getChildren()) { |
757 |
if (childElement instanceof ITestSuiteElement) { |
758 |
final ITestSuiteElement childTestSuite= (ITestSuiteElement)childElement; |
759 |
if (childTestSuite.getSuiteTypeName().equals(testClassName)) { |
760 |
return childTestSuite; |
761 |
} |
762 |
} |
763 |
} |
764 |
return null; |
765 |
} |
766 |
|
612 |
public void selectFirstFailure() { |
767 |
public void selectFirstFailure() { |
613 |
TestCaseElement firstFailure= getNextChildFailure(fTestRunSession.getTestRoot(), true); |
768 |
TestCaseElement firstFailure= getNextChildFailure(fTestRunSession.getTestRoot(), true); |
614 |
if (firstFailure != null) |
769 |
if (firstFailure != null) |
Lines 722-726
Link Here
|
722 |
fTreeViewer.expandToLevel(2); |
877 |
fTreeViewer.expandToLevel(2); |
723 |
} |
878 |
} |
724 |
|
879 |
|
725 |
} |
880 |
/** |
|
|
881 |
* Reacts to a selection change in the active {@link IWorkbenchPart} (or when another part |
882 |
* received the focus). |
883 |
* |
884 |
* @param part the {@link IWorkbenchPart} in which the selection change occurred |
885 |
* @param selection the selection in the given part |
886 |
* @since 3.7 |
887 |
*/ |
888 |
public void selectionChanged(IWorkbenchPart part, ISelection selection) { |
889 |
if (part instanceof IEditorPart) { |
890 |
setSelection((IEditorPart)part); |
891 |
} else if (part instanceof TestRunnerViewPart) { |
892 |
fTestRunnerPart.setLinkingWithEditorInSync(true); |
893 |
} |
894 |
} |
726 |
|
895 |
|
|
|
896 |
/** |
897 |
* @return the selected {@link IJavaElement} in the current editor if it is a {@link CompilationUnitEditor}, null otherwise. |
898 |
* @param editor the editor |
899 |
*/ |
900 |
private IJavaElement getSelectedJavaElementInEditor(final IEditorPart editor) { |
901 |
if (editor instanceof CompilationUnitEditor) { |
902 |
final CompilationUnitEditor compilationUnitEditor = (CompilationUnitEditor)editor; |
903 |
try { |
904 |
final IJavaElement inputJavaElement= JavaUI.getEditorInputJavaElement(editor.getEditorInput()); |
905 |
final ITextSelection selection= (ITextSelection)compilationUnitEditor.getSelectionProvider().getSelection(); |
906 |
final ICompilationUnit compilationUnit= (ICompilationUnit)inputJavaElement.getAncestor(IJavaElement.COMPILATION_UNIT); |
907 |
return compilationUnit.getElementAt(selection.getOffset()); |
908 |
} catch (JavaModelException e) { |
909 |
JUnitPlugin.log(e); |
910 |
} |
911 |
} |
912 |
return null; |
913 |
} |
914 |
|
915 |
/** |
916 |
* Handles the case when a {@link TestCaseElement} has been selected: open the associated code |
917 |
* in the Java Editor |
918 |
* |
919 |
* @param testElement the new selected {@link TestCaseElement} |
920 |
*/ |
921 |
private void handleTestElementSelected(final ITestElement testElement) { |
922 |
if (testElement instanceof TestCaseElement) { |
923 |
final IMethod selectedMethod= ((TestCaseElement)testElement).getJavaMethod(); |
924 |
handleJavaElementSelected(selectedMethod); |
925 |
} else if (testElement instanceof TestSuiteElement) { |
926 |
final IJavaElement selectedElement= ((TestSuiteElement)testElement).getJavaElement(); |
927 |
handleJavaElementSelected(selectedElement); |
928 |
} |
929 |
} |
930 |
|
931 |
/** |
932 |
* Reveals the given {@link IJavaElement} in its associated Editor if this later is already |
933 |
* open, and sets the "Link with Editor" button state accordingly. |
934 |
* |
935 |
* @param selectedJavaElement the selected {@link IJavaElement} in the {@link TestViewer} that |
936 |
* should be revealed in its Java Editor. |
937 |
*/ |
938 |
private void handleJavaElementSelected(final IJavaElement selectedJavaElement) { |
939 |
try { |
940 |
final IEditorPart editor= EditorUtility.isOpenInEditor(selectedJavaElement); |
941 |
if (selectedJavaElement != null && editor != null && editor instanceof JavaEditor) { |
942 |
final JavaEditor javaEditor= (JavaEditor)editor; |
943 |
final ITextSelection javaEditorSelection= (ITextSelection)javaEditor.getSelectionProvider().getSelection(); |
944 |
final IEditorPart selectedMethodEditor= EditorUtility.isOpenInEditor(selectedJavaElement); |
945 |
// checks if the editor is already open or not |
946 |
if (selectedMethodEditor != null) { |
947 |
// Retrieve the current active editor |
948 |
final IEditorPart activeEditor= fTestRunnerPart.getSite().getPage().getActiveEditor(); |
949 |
// open the required editor if it is not the active one |
950 |
if (!selectedMethodEditor.equals(activeEditor)) { |
951 |
EditorUtility.openInEditor(selectedJavaElement, false); |
952 |
} |
953 |
// retrieve the current java element (unless the associated compilation unit cannot be retrieved) |
954 |
final ICompilationUnit compilationUnit= (ICompilationUnit)selectedJavaElement.getAncestor(IJavaElement.COMPILATION_UNIT); |
955 |
if (compilationUnit != null) { |
956 |
final IJavaElement javaEditorSelectedElement= compilationUnit.getElementAt(javaEditorSelection.getOffset()); |
957 |
// force to reveal the selected element in case where the editor was not active |
958 |
if (!selectedMethodEditor.equals(activeEditor) || !selectedJavaElement.equals(javaEditorSelectedElement)) { |
959 |
EditorUtility.revealInEditor(selectedMethodEditor, selectedJavaElement); |
960 |
} |
961 |
fTestRunnerPart.setLinkingWithEditorInSync(true); |
962 |
return; |
963 |
} |
964 |
} |
965 |
} |
966 |
} catch (JavaModelException e) { |
967 |
JUnitPlugin.log(e); |
968 |
} catch (PartInitException e) { |
969 |
// occurs if the editor could not be opened or the input element is not valid Status code |
970 |
JUnitPlugin.log(e); |
971 |
} |
972 |
fTestRunnerPart.setLinkingWithEditorInSync(false); |
973 |
} |
974 |
|
975 |
} |