| package org.jetbrains.android; |
| |
| import com.android.SdkConstants; |
| import com.intellij.codeInsight.daemon.LineMarkerInfo; |
| import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl; |
| import com.intellij.ide.actions.GotoRelatedSymbolAction; |
| import com.intellij.navigation.GotoRelatedItem; |
| import com.intellij.openapi.actionSystem.Presentation; |
| import com.intellij.openapi.vfs.VirtualFile; |
| import com.intellij.psi.PsiClass; |
| import com.intellij.psi.PsiElement; |
| import com.intellij.psi.PsiFile; |
| import com.intellij.psi.xml.XmlAttributeValue; |
| import com.intellij.testFramework.TestActionEvent; |
| import com.intellij.util.containers.HashSet; |
| |
| import java.util.*; |
| |
| /** |
| * @author Eugene.Kudelevsky |
| */ |
| @SuppressWarnings("ConstantConditions") |
| public class AndroidGotoRelatedTest extends AndroidTestCase { |
| private static final String BASE_PATH = "/gotoRelated/"; |
| |
| public AndroidGotoRelatedTest() { |
| super(false); |
| } |
| |
| @Override |
| public void setUp() throws Exception { |
| super.setUp(); |
| myFixture.copyFileToProject("R.java", "gen/p1/p2/R.java"); |
| } |
| |
| public void testActivityToLayout() throws Exception { |
| createManifest(); |
| final VirtualFile layout = myFixture.copyFileToProject(BASE_PATH + "layout1.xml", "res/layout/layout.xml"); |
| final VirtualFile layout1 = myFixture.copyFileToProject(BASE_PATH + "layout1.xml", "res/layout/layout1.xml"); |
| final VirtualFile layout2 = myFixture.copyFileToProject(BASE_PATH + "layout1.xml", "res/layout/layout2.xml"); |
| final VirtualFile layoutLand = myFixture.copyFileToProject(BASE_PATH + "layout1.xml", "res/layout-land/layout.xml"); |
| final VirtualFile activityFile = myFixture.copyFileToProject(BASE_PATH + "Activity1.java", "src/p1/p2/MyActivity.java"); |
| final List<VirtualFile> expectedTargetFiles = Arrays.asList(layout, layout1, layout2, layoutLand); |
| doTestGotoRelatedFile(activityFile, expectedTargetFiles, PsiFile.class); |
| doCheckLineMarkers(expectedTargetFiles, PsiFile.class); |
| } |
| |
| public void testActivityToLayoutAndManifest() throws Exception { |
| final VirtualFile layout = myFixture.copyFileToProject(BASE_PATH + "layout1.xml", "res/layout/layout.xml"); |
| final VirtualFile manifestFile = |
| myFixture.copyFileToProject(BASE_PATH + "Manifest.xml", SdkConstants.FN_ANDROID_MANIFEST_XML); |
| final VirtualFile activityFile = myFixture.copyFileToProject(BASE_PATH + "Activity1.java", "src/p1/p2/MyActivity.java"); |
| |
| AndroidGotoRelatedProvider.ourAddDeclarationToManifest = true; |
| final List<GotoRelatedItem> items; |
| try { |
| items = doGotoRelatedFile(activityFile); |
| } |
| finally { |
| AndroidGotoRelatedProvider.ourAddDeclarationToManifest = false; |
| } |
| assertEquals(2, items.size()); |
| XmlAttributeValue manifestDeclarationTarget = null; |
| PsiFile psiFileTarget = null; |
| |
| for (GotoRelatedItem item : items) { |
| final PsiElement element = item.getElement(); |
| |
| if (element instanceof PsiFile) { |
| psiFileTarget = (PsiFile)element; |
| } |
| else if (element instanceof XmlAttributeValue) { |
| manifestDeclarationTarget = (XmlAttributeValue)element; |
| } |
| else { |
| fail("Unexpected element: " + element); |
| } |
| } |
| assertEquals(layout, psiFileTarget.getVirtualFile()); |
| assertEquals(manifestFile, manifestDeclarationTarget.getContainingFile().getVirtualFile()); |
| } |
| |
| public void testActivityToAndManifest() throws Exception { |
| final VirtualFile manifestFile = |
| myFixture.copyFileToProject(BASE_PATH + "Manifest.xml", SdkConstants.FN_ANDROID_MANIFEST_XML); |
| final VirtualFile activityFile = myFixture.copyFileToProject(BASE_PATH + "Activity1.java", "src/p1/p2/MyActivity.java"); |
| |
| AndroidGotoRelatedProvider.ourAddDeclarationToManifest = true; |
| final List<GotoRelatedItem> items; |
| try { |
| items = doGotoRelatedFile(activityFile); |
| } |
| finally { |
| AndroidGotoRelatedProvider.ourAddDeclarationToManifest = false; |
| } |
| assertEquals(1, items.size()); |
| final GotoRelatedItem item = items.get(0); |
| final PsiElement element = item.getElement(); |
| assertInstanceOf(element, XmlAttributeValue.class); |
| assertEquals(manifestFile, element.getContainingFile().getVirtualFile()); |
| } |
| |
| public void testSimpleClassToLayout() throws Exception { |
| createManifest(); |
| myFixture.copyFileToProject(BASE_PATH + "layout1.xml", "res/layout/layout.xml"); |
| final VirtualFile file = myFixture.copyFileToProject(BASE_PATH + "Class1.java", "src/p1/p2/Class1.java"); |
| doTestGotoRelatedFile(file, Collections.<VirtualFile>emptyList(), PsiFile.class); |
| final List<LineMarkerInfo> markerInfos = doGetRelatedLineMarkers(); |
| assertEmpty(markerInfos); |
| } |
| |
| public void testFragmentToLayout() throws Exception { |
| createManifest(); |
| final VirtualFile layout = myFixture.copyFileToProject(BASE_PATH + "layout1.xml", "res/layout/layout.xml"); |
| final VirtualFile layoutLand = myFixture.copyFileToProject(BASE_PATH + "layout1.xml", "res/layout-land/layout.xml"); |
| final VirtualFile fragmentFile = myFixture.copyFileToProject(BASE_PATH + "Fragment1.java", "src/p1/p2/MyFragment.java"); |
| final List<VirtualFile> expectedTargetFiles = Arrays.asList(layout, layoutLand); |
| doTestGotoRelatedFile(fragmentFile, expectedTargetFiles, PsiFile.class); |
| doCheckLineMarkers(expectedTargetFiles, PsiFile.class); |
| } |
| |
| public void testLayoutToContext() throws Exception { |
| createManifest(); |
| final VirtualFile layout = myFixture.copyFileToProject(BASE_PATH + "layout1.xml", "res/layout/layout.xml"); |
| myFixture.copyFileToProject(BASE_PATH + "layout1.xml", "res/layout/layout1.xml"); |
| myFixture.copyFileToProject(BASE_PATH + "layout1.xml", "res/layout/layout2.xml"); |
| myFixture.copyFileToProject(BASE_PATH + "layout1.xml", "res/layout-land/layout.xml"); |
| final VirtualFile activityFile = myFixture.copyFileToProject(BASE_PATH + "Activity1.java", "src/p1/p2/MyActivity.java"); |
| myFixture.copyFileToProject(BASE_PATH + "Class1.java", "src/p1/p2/Class1.java"); |
| myFixture.copyFileToProject(BASE_PATH + "Activity2.java", "src/p1/p2/Activity2.java"); |
| final VirtualFile fragmentFile = myFixture.copyFileToProject(BASE_PATH + "Fragment1.java", "src/p1/p2/MyFragment.java"); |
| myFixture.copyFileToProject(BASE_PATH + "Fragment2.java", "src/p1/p2/Fragment2.java"); |
| final List<VirtualFile> expectedTargetFiles = Arrays.asList(activityFile, fragmentFile); |
| doTestGotoRelatedFile(layout, expectedTargetFiles, PsiClass.class); |
| doCheckLineMarkers(expectedTargetFiles, PsiClass.class); |
| } |
| |
| public void testNestedActivity() throws Exception { |
| createManifest(); |
| final VirtualFile layout = myFixture.copyFileToProject(BASE_PATH + "layout1.xml", "res/layout/layout.xml"); |
| myFixture.copyFileToProject(BASE_PATH + "layout1.xml", "res/layout/layout1.xml"); |
| myFixture.copyFileToProject(BASE_PATH + "layout1.xml", "res/layout/layout2.xml"); |
| final VirtualFile layoutLand = myFixture.copyFileToProject(BASE_PATH + "layout1.xml", "res/layout-land/layout.xml"); |
| final VirtualFile activityFile = myFixture.copyFileToProject(BASE_PATH + "Activity3.java", "src/p1/p2/MyActivity.java"); |
| doTestGotoRelatedFile(activityFile, Arrays.asList(layout, layoutLand), PsiFile.class); |
| } |
| |
| public void testSpecifiedWithAttribute() throws Exception { |
| createManifest(); |
| final VirtualFile layout = myFixture.copyFileToProject(BASE_PATH + "layout2.xml", "res/layout/layout.xml"); |
| final VirtualFile activityFile = myFixture.copyFileToProject(BASE_PATH + "Activity4.java", "src/p1/p2/MyActivity.java"); |
| doTestGotoRelatedFile(layout, Collections.singletonList(activityFile), PsiClass.class); |
| } |
| |
| private void doTestGotoRelatedFile(VirtualFile file, List<VirtualFile> expectedTargetFiles, Class<?> targetElementClass) { |
| final List<GotoRelatedItem> items = doGotoRelatedFile(file); |
| doCheckItems(expectedTargetFiles, items, targetElementClass); |
| } |
| |
| private List<GotoRelatedItem> doGotoRelatedFile(VirtualFile file) { |
| myFixture.configureFromExistingVirtualFile(file); |
| |
| final GotoRelatedSymbolAction action = new GotoRelatedSymbolAction(); |
| final TestActionEvent e = new TestActionEvent(action); |
| action.beforeActionPerformedUpdate(e); |
| final Presentation presentation = e.getPresentation(); |
| assertTrue(presentation.isEnabled() && presentation.isVisible()); |
| return GotoRelatedSymbolAction.getItems(myFixture.getFile(), myFixture.getEditor(), null); |
| } |
| |
| private void doCheckLineMarkers(List<VirtualFile> expectedTargetFiles, Class<?> targetElementClass) { |
| final List<LineMarkerInfo> relatedMarkers = doGetRelatedLineMarkers(); |
| assertEquals(relatedMarkers.toString(), 1, relatedMarkers.size()); |
| final LineMarkerInfo marker = relatedMarkers.get(0); |
| doCheckItems(expectedTargetFiles, ((AndroidLineMarkerProvider.MyNavigationHandler)marker. |
| getNavigationHandler()).doComputeItems(), targetElementClass); |
| } |
| |
| private List<LineMarkerInfo> doGetRelatedLineMarkers() { |
| myFixture.doHighlighting(); |
| |
| final List<LineMarkerInfo> markers = DaemonCodeAnalyzerImpl.getLineMarkers( |
| myFixture.getEditor().getDocument(), myFixture.getProject()); |
| final List<LineMarkerInfo> relatedMarkers = new ArrayList<LineMarkerInfo>(); |
| |
| for (LineMarkerInfo marker : markers) { |
| if (marker.getNavigationHandler() instanceof AndroidLineMarkerProvider.MyNavigationHandler) { |
| relatedMarkers.add(marker); |
| } |
| } |
| return relatedMarkers; |
| } |
| |
| private static void doCheckItems(List<VirtualFile> expectedTargetFiles, List<GotoRelatedItem> items, Class<?> targetElementClass) { |
| final Set<VirtualFile> targetFiles = new HashSet<VirtualFile>(); |
| |
| for (GotoRelatedItem item : items) { |
| final PsiElement element = item.getElement(); |
| assertInstanceOf(element, targetElementClass); |
| final VirtualFile targetFile = element.getContainingFile().getVirtualFile(); |
| assertNotNull(targetFile); |
| targetFiles.add(targetFile); |
| } |
| assertEquals(new HashSet<VirtualFile>(expectedTargetFiles), targetFiles); |
| } |
| } |