blob: e14e9acdba4024489ef74b13c90860a779afca90 [file] [log] [blame]
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);
}
}