| package org.jetbrains.android.dom; |
| |
| import com.android.SdkConstants; |
| import com.intellij.codeInsight.completion.CompletionType; |
| import com.intellij.codeInsight.navigation.actions.GotoDeclarationAction; |
| import com.intellij.openapi.application.ApplicationManager; |
| import com.intellij.openapi.command.WriteCommandAction; |
| import com.intellij.openapi.module.Module; |
| import com.intellij.openapi.roots.ModuleRootModificationUtil; |
| import com.intellij.openapi.vfs.VirtualFile; |
| import com.intellij.psi.PsiElement; |
| import com.intellij.psi.PsiFile; |
| import com.intellij.testFramework.IdeaTestCase; |
| import com.intellij.testFramework.UsefulTestCase; |
| import com.intellij.testFramework.builders.JavaModuleFixtureBuilder; |
| import com.intellij.testFramework.fixtures.*; |
| import com.intellij.usageView.UsageInfo; |
| import org.jetbrains.android.AndroidFindUsagesTest; |
| import org.jetbrains.android.AndroidTestCase; |
| import org.jetbrains.android.facet.AndroidFacet; |
| import org.jetbrains.android.inspections.AndroidDomInspection; |
| import org.jetbrains.annotations.NonNls; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.List; |
| |
| import static org.jetbrains.android.AndroidTestCase.getDefaultPlatformDir; |
| import static org.jetbrains.android.AndroidTestCase.getDefaultTestSdkPath; |
| |
| /** |
| * @author Eugene.Kudelevsky |
| */ |
| @SuppressWarnings("ResultOfMethodCallIgnored") |
| public class AndroidLibraryProjectTest extends UsefulTestCase { |
| @NonNls private static final String BASE_PATH = "libModule/"; |
| |
| private Module myAppModule; |
| private AndroidFacet myAppFacet; |
| |
| private Module myLibModule; |
| private Module myLibGenModule; |
| private AndroidFacet myLibFacet; |
| |
| protected JavaCodeInsightTestFixture myFixture; |
| |
| @SuppressWarnings("JUnitTestCaseWithNonTrivialConstructors") |
| public AndroidLibraryProjectTest() { |
| IdeaTestCase.initPlatformPrefix(); |
| } |
| |
| @Override |
| public void setUp() throws Exception { |
| super.setUp(); |
| final TestFixtureBuilder<IdeaProjectTestFixture> projectBuilder = |
| IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getName()); |
| myFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(projectBuilder.getFixture()); |
| myFixture.enableInspections(AndroidDomInspection.class); |
| |
| final JavaModuleFixtureBuilder appModuleBuilder = projectBuilder.addModule(JavaModuleFixtureBuilder.class); |
| String appModuleDir = myFixture.getTempDirPath() + "/app"; |
| new File(appModuleDir).mkdir(); |
| AndroidTestCase.tuneModule(appModuleBuilder, appModuleDir); |
| |
| final JavaModuleFixtureBuilder libModuleBuilder = projectBuilder.addModule(JavaModuleFixtureBuilder.class); |
| String libModuleDir = myFixture.getTempDirPath() + "/lib"; |
| new File(libModuleDir).mkdir(); |
| |
| libModuleBuilder.addContentRoot(libModuleDir); |
| new File(libModuleDir + "/src/").mkdir(); |
| libModuleBuilder.addSourceRoot("src"); |
| |
| final JavaModuleFixtureBuilder libGenModuleBuilder = projectBuilder.addModule(JavaModuleFixtureBuilder.class); |
| String libGenModule = myFixture.getTempDirPath() + "/lib/gen"; |
| new File(libGenModule).mkdir(); |
| libGenModuleBuilder.addSourceContentRoot(libGenModule); |
| |
| myFixture.setUp(); |
| myFixture.setTestDataPath(AndroidTestCase.getAbsoluteTestDataPath()); |
| |
| myAppModule = appModuleBuilder.getFixture().getModule(); |
| myLibModule = libModuleBuilder.getFixture().getModule(); |
| myLibGenModule = libGenModuleBuilder.getFixture().getModule(); |
| |
| // Manifest must exist before facet is added |
| final VirtualFile manifest = |
| myFixture.copyFileToProject(SdkConstants.FN_ANDROID_MANIFEST_XML, SdkConstants.FN_ANDROID_MANIFEST_XML); |
| final VirtualFile manifest2 = |
| myFixture.copyFileToProject(SdkConstants.FN_ANDROID_MANIFEST_XML, "app/" + SdkConstants.FN_ANDROID_MANIFEST_XML); |
| final VirtualFile manifest3 = |
| myFixture.copyFileToProject(BASE_PATH + "LibAndroidManifest.xml", "lib/" + SdkConstants.FN_ANDROID_MANIFEST_XML); |
| |
| myAppFacet = AndroidTestCase.addAndroidFacet(myAppModule, getDefaultTestSdkPath(), getDefaultPlatformDir()); |
| myLibFacet = AndroidTestCase.addAndroidFacet(myLibModule, getDefaultTestSdkPath(), getDefaultPlatformDir()); |
| myLibFacet.setLibraryProject(true); |
| |
| ModuleRootModificationUtil.addDependency(myAppModule, myLibModule); |
| ModuleRootModificationUtil.addDependency(myLibModule, myLibGenModule); |
| |
| // Manifest files will be recreated using createInitialStructure or other custom code in each test case |
| |
| WriteCommandAction.runWriteCommandAction(null, new Runnable() { |
| @Override |
| public void run() { |
| try { |
| manifest.delete(this); |
| manifest2.delete(this); |
| manifest3.delete(this); |
| } |
| catch (IOException e) { |
| fail("Could not delete default manifest"); |
| } |
| } |
| }); |
| } |
| |
| private void createInitialStructure() { |
| myFixture.copyFileToProject(SdkConstants.FN_ANDROID_MANIFEST_XML, "app/" + SdkConstants.FN_ANDROID_MANIFEST_XML); |
| myFixture.copyFileToProject(BASE_PATH + "LibAndroidManifest.xml", "lib/" + SdkConstants.FN_ANDROID_MANIFEST_XML); |
| |
| myFixture.copyDirectoryToProject("res", "app/res"); |
| myFixture.copyDirectoryToProject(BASE_PATH + "res", "lib/res"); |
| } |
| |
| @Override |
| protected void tearDown() throws Exception { |
| myAppModule = null; |
| myLibModule = null; |
| myLibGenModule = null; |
| |
| myAppFacet = null; |
| myLibFacet = null; |
| |
| myFixture.tearDown(); |
| myFixture = null; |
| |
| super.tearDown(); |
| } |
| |
| public void testHighlighting() { |
| createInitialStructure(); |
| String to = "app/res/layout/" + getTestName(true) + ".xml"; |
| VirtualFile file = myFixture.copyFileToProject(BASE_PATH + getTestName(true) + ".xml", to); |
| myFixture.configureFromExistingVirtualFile(file); |
| myFixture.doHighlighting(); |
| myFixture.checkHighlighting(true, false, true); |
| } |
| |
| public void testHighlighting1() { |
| createInitialStructure(); |
| String to = "app/res/layout/" + getTestName(true) + ".xml"; |
| VirtualFile file = myFixture.copyFileToProject(BASE_PATH + getTestName(true) + ".xml", to); |
| myFixture.configureFromExistingVirtualFile(file); |
| myFixture.doHighlighting(); |
| myFixture.checkHighlighting(true, false, true); |
| } |
| |
| public void testHighlighting2() { |
| myFixture.copyFileToProject(BASE_PATH + "LibAndroidManifest.xml", "lib/" + SdkConstants.FN_ANDROID_MANIFEST_XML); |
| final VirtualFile manifestFile = |
| myFixture.copyFileToProject(BASE_PATH + getTestName(true) + ".xml", "app/" + SdkConstants.FN_ANDROID_MANIFEST_XML); |
| myFixture.copyDirectoryToProject(BASE_PATH + "res", "lib/res"); |
| myFixture.configureFromExistingVirtualFile(manifestFile); |
| myFixture.doHighlighting(); |
| myFixture.checkHighlighting(true, false, true); |
| } |
| |
| public void testJavaHighlighting() { |
| createInitialStructure(); |
| myFixture.copyFileToProject(BASE_PATH + "LibR.java", "lib/src/p1/p2/lib/R.java"); |
| String to = "lib/src/p1/p2/lib" + getTestName(true) + ".java"; |
| VirtualFile file = myFixture.copyFileToProject(BASE_PATH + getTestName(false) + ".java", to); |
| myFixture.configureFromExistingVirtualFile(file); |
| myFixture.doHighlighting(); |
| myFixture.checkHighlighting(true, true, true); |
| } |
| |
| private void doRename(final VirtualFile file, final String newName) { |
| ApplicationManager.getApplication().runWriteAction(new Runnable() { |
| @Override |
| public void run() { |
| try { |
| file.rename(myFixture.getProject(), newName); |
| } |
| catch (IOException e) { |
| new RuntimeException(e); |
| } |
| } |
| }); |
| } |
| |
| public void testCompletion() { |
| createInitialStructure(); |
| doTestCompletion(); |
| } |
| |
| public void testCompletion1() { |
| createInitialStructure(); |
| doTestCompletion(); |
| } |
| |
| public void testCustomAttrCompletion() { |
| createInitialStructure(); |
| myFixture.copyFileToProject(BASE_PATH + "LibView.java", "lib/src/p1/p2/lib/LibView.java"); |
| myFixture.copyFileToProject(BASE_PATH + "lib_attrs.xml", "lib/res/values/lib_attrs.xml"); |
| doTestCompletion(); |
| } |
| |
| private void doTestCompletion() { |
| String to = "app/res/layout/" + getTestName(true) + ".xml"; |
| VirtualFile file = myFixture.copyFileToProject(BASE_PATH + getTestName(true) + ".xml", to); |
| myFixture.configureFromExistingVirtualFile(file); |
| myFixture.complete(CompletionType.BASIC); |
| myFixture.checkResultByFile(BASE_PATH + getTestName(true) + "_after.xml"); |
| } |
| |
| public void testJavaNavigation() throws Exception { |
| createInitialStructure(); |
| myFixture.copyFileToProject("R.java", "app/src/p1/p2/R.java"); |
| VirtualFile file = myFixture.copyFileToProject(BASE_PATH + getTestName(false) + ".java", "/app/src/p1/p2/Java.java"); |
| myFixture.configureFromExistingVirtualFile(file); |
| |
| PsiElement[] targets = |
| GotoDeclarationAction.findAllTargetElements(myFixture.getProject(), myFixture.getEditor(), myFixture.getCaretOffset()); |
| assertNotNull(targets); |
| assertEquals(1, targets.length); |
| PsiElement targetElement = targets[0]; |
| assertInstanceOf(targetElement, PsiFile.class); |
| assertEquals("main.xml", ((PsiFile)targetElement).getName()); |
| } |
| |
| public void testFileResourceFindUsages() throws Throwable { |
| doFindUsagesTest("xml", "lib/res/layout/"); |
| } |
| |
| public void testFileResourceFindUsages1() throws Throwable { |
| doFindUsagesTest("xml", "app/res/layout/"); |
| } |
| |
| public void testFileResourceFindUsagesFromJava() throws Throwable { |
| doFindUsagesTest("java", "app/src/p1/p2/"); |
| } |
| |
| public void testFileResourceFindUsagesFromJava1() throws Throwable { |
| boolean temp = myLibFacet.isLibraryProject(); |
| try { |
| myLibFacet.setLibraryProject(true); |
| doFindUsagesTest("java", "app/src/p1/p2/lib/"); |
| } |
| finally { |
| myLibFacet.setLibraryProject(temp); |
| } |
| } |
| |
| public void testFileResourceFindUsagesFromJava2() throws Throwable { |
| doFindUsagesTest("java", "lib/src/p1/p2/lib/"); |
| } |
| |
| public void testValueResourceFindUsages() throws Throwable { |
| doFindUsagesTest("xml", "lib/res/layout/"); |
| } |
| |
| public void testValueResourceFindUsages1() throws Throwable { |
| doFindUsagesTest("xml", "app/res/layout/"); |
| } |
| |
| private void doFindUsagesTest(String extension, String dir) throws Throwable { |
| createInitialStructure(); |
| myFixture.copyFileToProject(BASE_PATH + "FindUsagesClass.java", "app/src/p1/p2/Class.java"); |
| myFixture.copyFileToProject(BASE_PATH + "FindUsagesClass1.java", "app/src/p1/p2/lib/Class.java"); |
| myFixture.copyFileToProject(BASE_PATH + "FindUsagesClass1.java", "lib/src/p1/p2/lib/Class.java"); |
| myFixture.copyFileToProject(BASE_PATH + "FindUsagesStyles.xml", "app/res/values/styles.xml"); |
| myFixture.copyFileToProject(BASE_PATH + "picture1.png", "lib/res/drawable/picture1.png"); |
| myFixture.copyFileToProject("R.java", "app/src/p1/p2/R.java"); |
| myFixture.copyFileToProject(BASE_PATH + "LibR.java", "lib/src/p1/p2/lib/R.java"); |
| Collection<UsageInfo> references = findCodeUsages(getTestName(false) + "." + extension, dir); |
| assertEquals(buildFileList(references), 5, references.size()); |
| } |
| |
| private List<UsageInfo> findCodeUsages(String path, String dir) throws Throwable { |
| String newFilePath = dir + path; |
| VirtualFile file = myFixture.copyFileToProject(BASE_PATH + path, newFilePath); |
| Collection<UsageInfo> usages = AndroidFindUsagesTest.findUsages(file, myFixture); |
| List<UsageInfo> result = new ArrayList<UsageInfo>(); |
| for (UsageInfo usage : usages) { |
| if (!usage.isNonCodeUsage) { |
| result.add(usage); |
| } |
| } |
| return result; |
| } |
| |
| private static String buildFileList(Collection<UsageInfo> infos) { |
| final StringBuilder result = new StringBuilder(); |
| |
| for (UsageInfo info : infos) { |
| final PsiFile file = info.getFile(); |
| final VirtualFile vFile = file != null ? file.getVirtualFile() : null; |
| final String path = vFile != null ? vFile.getPath() : "null"; |
| result.append(path).append('\n'); |
| } |
| return result.toString(); |
| } |
| } |