diff --git a/idea/idea-android/tests/org/jetbrains/kotlin/android/AndroidSdks.java b/idea/idea-android/tests/org/jetbrains/kotlin/android/AndroidSdks.java new file mode 100644 index 00000000000..67a08f81ca3 --- /dev/null +++ b/idea/idea-android/tests/org/jetbrains/kotlin/android/AndroidSdks.java @@ -0,0 +1,62 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.android; + + +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.projectRoots.SdkAdditionalData; +import org.jetbrains.android.sdk.AndroidSdkAdditionalData; +import org.jetbrains.android.sdk.AndroidSdkData; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Stub for com.android.tools.idea.sdk.AndroidSdks + * stabbed to minimize changes in AndroidTestBase + */ +public class AndroidSdks { + + private static AndroidSdks INSTANCE; + + private AndroidSdkData mySdkData; + + private AndroidSdks() { + + } + + public static AndroidSdks getInstance() { + if (INSTANCE == null) { + INSTANCE = new AndroidSdks(); + } + + return INSTANCE; + } + + public AndroidSdkData tryToChooseAndroidSdk() { + return mySdkData; + } + + public void setSdkData(AndroidSdkData data) { + mySdkData = data; + } + + @Nullable + public AndroidSdkAdditionalData getAndroidSdkAdditionalData(@NotNull Sdk sdk) { + SdkAdditionalData data = sdk.getSdkAdditionalData(); + return data instanceof AndroidSdkAdditionalData ? (AndroidSdkAdditionalData)data : null; + } +} diff --git a/idea/idea-android/tests/org/jetbrains/kotlin/android/AndroidTestBase.java b/idea/idea-android/tests/org/jetbrains/kotlin/android/AndroidTestBase.java new file mode 100644 index 00000000000..e47883cf602 --- /dev/null +++ b/idea/idea-android/tests/org/jetbrains/kotlin/android/AndroidTestBase.java @@ -0,0 +1,257 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.kotlin.android; + +import com.android.sdklib.IAndroidTarget; +import com.android.tools.idea.res.ResourceHelper; +import com.android.tools.idea.startup.ExternalAnnotationsSupport; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.application.ex.PathManagerEx; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.ProjectJdkTable; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.projectRoots.SdkModificator; +import com.intellij.openapi.roots.JavadocOrderRootType; +import com.intellij.openapi.roots.ModuleRootModificationUtil; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.util.Segment; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.xml.XmlAttributeValue; +import com.intellij.testFramework.UsefulTestCase; +import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture; +import org.jetbrains.android.dom.wrappers.LazyValueResourceElementWrapper; +import org.jetbrains.android.sdk.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.nio.file.Paths; + +/** + * Copied from AS 2.3 sources + */ +@SuppressWarnings({"JUnitTestCaseWithNonTrivialConstructors"}) +public abstract class AndroidTestBase extends UsefulTestCase { + + protected JavaCodeInsightTestFixture myFixture; + + protected AndroidTestBase() { + // IDEA14 seems to be stricter regarding validating accesses against known roots. By default, it contains the entire idea folder, + // but it doesn't seem to include our custom structure tools/idea/../adt/idea where the android plugin is placed. + // The following line explicitly adds that folder as an allowed root. + VfsRootAccess.allowRootAccess(FileUtil.toCanonicalPath(getAndroidPluginHome())); + } + + public String getAbsoluteTestDataPath() { + // The following code doesn't work right now that the Android + // plugin lives in a separate place: + //String androidHomePath = System.getProperty("android.home.path"); + //if (androidHomePath == null) { + // androidHomePath = new File(PathManager.getHomePath(), "android/android").getPath(); + //} + //return PathUtil.getCanonicalPath(androidHomePath + "/testData"); + + String path = Paths.get(getTestDataPath()).toAbsolutePath().toString(); + assertTrue(new File(path).isAbsolute()); + return path; + } + + public String getTestDataPath() { + return getAndroidPluginHome() + "/testData"; + } + + public static String getAndroidPluginHome() { + // Now that the Android plugin is kept in a separate place, we need to look in + // a relative position instead + String adtPath = PathManager.getHomePath() + "/../adt/idea/android"; + if (new File(adtPath).exists()) { + return adtPath; + } + return PathManagerEx.findFileUnderCommunityHome("plugins/android").getPath(); + } + + protected static void addLatestAndroidSdk(Module module) { + Sdk androidSdk = createLatestAndroidSdk(); + ModuleRootModificationUtil.setModuleSdk(module, androidSdk); + } + + public static Sdk createLatestAndroidSdk() { + String sdkPath = TestUtils.getSdk().toString(); + String platformDir = TestUtils.getLatestAndroidPlatform(); + + Sdk sdk = ProjectJdkTable.getInstance().createSdk("android_test_sdk", AndroidSdkType.getInstance()); + SdkModificator sdkModificator = sdk.getSdkModificator(); + sdkModificator.setHomePath(sdkPath); + + VirtualFile androidJar = JarFileSystem.getInstance().findFileByPath(sdkPath + "/platforms/" + platformDir + "/android.jar!/"); + sdkModificator.addRoot(androidJar, OrderRootType.CLASSES); + + VirtualFile resFolder = LocalFileSystem.getInstance().findFileByPath(sdkPath + "/platforms/" + platformDir + "/data/res"); + sdkModificator.addRoot(resFolder, OrderRootType.CLASSES); + + VirtualFile docsFolder = LocalFileSystem.getInstance().findFileByPath(sdkPath + "/docs/reference"); + if (docsFolder != null) { + sdkModificator.addRoot(docsFolder, JavadocOrderRootType.getInstance()); + } + + AndroidSdkAdditionalData data = new AndroidSdkAdditionalData(sdk); + AndroidSdkData sdkData = AndroidSdkData.getSdkData(sdkPath); + assertNotNull(sdkData); + IAndroidTarget target = null; + IAndroidTarget[] targets = sdkData.getTargets(); + for (IAndroidTarget t : targets) { + if (t.getLocation().contains(platformDir)) { + target = t; + break; + } + } + assertNotNull(target); + data.setBuildTarget(target); + sdkModificator.setSdkAdditionalData(data); + ExternalAnnotationsSupport.attachJdkAnnotations(sdkModificator); + sdkModificator.commitChanges(); + return sdk; + } + + protected Project getProject() { + return myFixture.getProject(); + } + + protected void ensureSdkManagerAvailable() { + AndroidSdks androidSdks = AndroidSdks.getInstance(); + AndroidSdkData sdkData = androidSdks.tryToChooseAndroidSdk(); + if (sdkData == null) { + sdkData = createTestSdkManager(); + if (sdkData != null) { + androidSdks.setSdkData(sdkData); + } + } + assertNotNull(sdkData); + } + + @Nullable + protected AndroidSdkData createTestSdkManager() { + Sdk androidSdk = createLatestAndroidSdk(); + AndroidSdkAdditionalData data = AndroidSdks.getInstance().getAndroidSdkAdditionalData(androidSdk); + if (data != null) { + AndroidPlatform androidPlatform = data.getAndroidPlatform(); + if (androidPlatform != null) { + // Put default platforms in the list before non-default ones so they'll be looked at first. + return androidPlatform.getSdkData(); + } else { + fail("No getAndroidPlatform() associated with the AndroidSdkAdditionalData: " + data); + } + } else { + fail("Could not find data associated with the SDK: " + androidSdk.getName()); + } + return null; + } + + /** Returns a description of the given elements, suitable as unit test golden file output */ + public static String describeElements(@Nullable PsiElement[] elements) { + if (elements == null) { + return "Empty"; + } + StringBuilder sb = new StringBuilder(); + for (PsiElement target : elements) { + appendElementDescription(sb, target); + } + return sb.toString(); + } + + /** Appends a description of the given element, suitable as unit test golden file output */ + public static void appendElementDescription(@NotNull StringBuilder sb, @NotNull PsiElement element) { + if (element instanceof LazyValueResourceElementWrapper) { + LazyValueResourceElementWrapper wrapper = (LazyValueResourceElementWrapper)element; + XmlAttributeValue value = wrapper.computeElement(); + if (value != null) { + element = value; + } + } + PsiFile file = element.getContainingFile(); + int offset = element.getTextOffset(); + TextRange segment = element.getTextRange(); + appendSourceDescription(sb, file, offset, segment); + } + + /** Appends a description of the given elements, suitable as unit test golden file output */ + public static void appendSourceDescription(@NotNull StringBuilder sb, @Nullable PsiFile file, int offset, @Nullable Segment segment) { + if (file != null && segment != null) { + if (ResourceHelper.getFolderType(file) != null) { + assertNotNull(file.getParent()); + sb.append(file.getParent().getName()); + sb.append("/"); + } + sb.append(file.getName()); + sb.append(':'); + String text = file.getText(); + int lineNumber = 1; + for (int i = 0; i < offset; i++) { + if (text.charAt(i) == '\n') { + lineNumber++; + } + } + sb.append(lineNumber); + sb.append(":"); + sb.append('\n'); + int startOffset = segment.getStartOffset(); + int endOffset = segment.getEndOffset(); + assertTrue(offset == -1 || offset >= startOffset); + assertTrue(offset == -1 || offset <= endOffset); + + int lineStart = startOffset; + while (lineStart > 0 && text.charAt(lineStart - 1) != '\n') { + lineStart--; + } + + // Skip over leading whitespace + while (lineStart < startOffset && Character.isWhitespace(text.charAt(lineStart))) { + lineStart++; + } + + int lineEnd = startOffset; + while (lineEnd < text.length() && text.charAt(lineEnd) != '\n') { + lineEnd++; + } + String indent = " "; + sb.append(indent); + sb.append(text.substring(lineStart, lineEnd)); + sb.append('\n'); + sb.append(indent); + for (int i = lineStart; i < lineEnd; i++) { + if (i == offset) { + sb.append('|'); + } else if (i >= startOffset && i <= endOffset) { + sb.append('~'); + } else { + sb.append(' '); + } + } + } else { + sb.append(offset); + sb.append(":?"); + } + sb.append('\n'); + } +} diff --git a/idea/idea-android/tests/org/jetbrains/kotlin/android/AndroidTestCase.java b/idea/idea-android/tests/org/jetbrains/kotlin/android/AndroidTestCase.java new file mode 100644 index 00000000000..de597769c92 --- /dev/null +++ b/idea/idea-android/tests/org/jetbrains/kotlin/android/AndroidTestCase.java @@ -0,0 +1,378 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.android; + +import com.android.SdkConstants; +import com.android.tools.idea.rendering.RenderSecurityManager; +import com.android.tools.idea.startup.AndroidCodeStyleSettingsModifier; +import com.intellij.analysis.AnalysisScope; +import com.intellij.codeInspection.GlobalInspectionTool; +import com.intellij.codeInspection.InspectionManager; +import com.intellij.codeInspection.ex.GlobalInspectionToolWrapper; +import com.intellij.codeInspection.ex.InspectionManagerEx; +import com.intellij.facet.FacetManager; +import com.intellij.facet.ModifiableFacetModel; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.impl.ComponentManagerImpl; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.LanguageLevelProjectExtension; +import com.intellij.openapi.roots.ModuleRootModificationUtil; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.codeStyle.CodeStyleSchemes; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.testFramework.InspectionTestUtil; +import com.intellij.testFramework.ThreadTracker; +import com.intellij.testFramework.builders.JavaModuleFixtureBuilder; +import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; +import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; +import com.intellij.testFramework.fixtures.JavaTestFixtureFactory; +import com.intellij.testFramework.fixtures.TestFixtureBuilder; +import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl; +import com.intellij.testFramework.fixtures.impl.GlobalInspectionContextForTests; +import com.intellij.util.ArrayUtil; +import org.jetbrains.android.facet.AndroidFacet; +import org.jetbrains.android.facet.AndroidRootUtil; +import org.jetbrains.android.formatter.AndroidXmlCodeStyleSettings; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.picocontainer.MutablePicoContainer; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * Copied from AS 2.3 sources + */ +@SuppressWarnings({"JUnitTestCaseWithNonTrivialConstructors"}) +public abstract class AndroidTestCase extends AndroidTestBase { + protected Module myModule; + protected List myAdditionalModules; + + protected AndroidFacet myFacet; + protected CodeStyleSettings mySettings; + + private List myAllowedRoots = new ArrayList<>(); + private boolean myUseCustomSettings; + + @Override + protected void setUp() throws Exception { + super.setUp(); + + TestFixtureBuilder projectBuilder = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getName()); + myFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(projectBuilder.getFixture()); + JavaModuleFixtureBuilder moduleFixtureBuilder = projectBuilder.addModule(JavaModuleFixtureBuilder.class); + File moduleRoot = new File(myFixture.getTempDirPath()); + + if (!moduleRoot.exists()) { + assertTrue(moduleRoot.mkdirs()); + } + initializeModuleFixtureBuilderWithSrcAndGen(moduleFixtureBuilder, moduleRoot.toString()); + + ArrayList modules = new ArrayList<>(); + configureAdditionalModules(projectBuilder, modules); + + myFixture.setUp(); + myFixture.setTestDataPath(getTestDataPath()); + myModule = moduleFixtureBuilder.getFixture().getModule(); + + // Must be done before addAndroidFacet, and must always be done, even if a test provides + // its own custom manifest file. However, in that case, we will delete it shortly below. + createManifest(); + + myFacet = addAndroidFacet(myModule); + + LanguageLevel languageLevel = getLanguageLevel(); + if (languageLevel != null) { + LanguageLevelProjectExtension extension = LanguageLevelProjectExtension.getInstance(myModule.getProject()); + if (extension != null) { + extension.setLanguageLevel(languageLevel); + } + } + + // TODO: myFixture.copyDirectoryToProject(getResDir(), "res"); + + myAdditionalModules = new ArrayList<>(); + for (MyAdditionalModuleData data : modules) { + Module additionalModule = data.myModuleFixtureBuilder.getFixture().getModule(); + myAdditionalModules.add(additionalModule); + AndroidFacet facet = addAndroidFacet(additionalModule); + facet.setLibraryProject(data.myProjectType == 1); + String rootPath = getAdditionalModulePath(data.myDirName); + myFixture.copyDirectoryToProject(getResDir(), rootPath + "/res"); + myFixture.copyFileToProject(SdkConstants.FN_ANDROID_MANIFEST_XML, rootPath + '/' + SdkConstants.FN_ANDROID_MANIFEST_XML); + if (data.myIsMainModuleDependency) { + ModuleRootModificationUtil.addDependency(myModule, additionalModule); + } + } + + if (providesCustomManifest()) { + deleteManifest(); + } + + if (RenderSecurityManager.RESTRICT_READS) { + // Unit test class loader includes disk directories which security manager does not allow access to + RenderSecurityManager.sEnabled = false; + } + + ArrayList allowedRoots = new ArrayList<>(); + collectAllowedRoots(allowedRoots); + // TODO: registerAllowedRoots(allowedRoots, myTestRootDisposable); + mySettings = CodeStyleSettingsManager.getSettings(getProject()).clone(); + AndroidCodeStyleSettingsModifier.modify(mySettings); + CodeStyleSettingsManager.getInstance(getProject()).setTemporarySettings(mySettings); + myUseCustomSettings = getAndroidCodeStyleSettings().USE_CUSTOM_SETTINGS; + getAndroidCodeStyleSettings().USE_CUSTOM_SETTINGS = true; + + // Layoutlib rendering thread will be shutdown when the app is closed so do not report it as a leak + ThreadTracker.longRunningThreadCreated(ApplicationManager.getApplication(), "Layoutlib"); + } + + @Override + protected void tearDown() throws Exception { + try { + CodeStyleSettingsManager.getInstance(getProject()).dropTemporarySettings(); + myModule = null; + myAdditionalModules = null; + myFixture.tearDown(); + myFixture = null; + myFacet = null; + getAndroidCodeStyleSettings().USE_CUSTOM_SETTINGS = myUseCustomSettings; + if (RenderSecurityManager.RESTRICT_READS) { + RenderSecurityManager.sEnabled = true; + } + } + finally { + super.tearDown(); + } + } + + private static void initializeModuleFixtureBuilderWithSrcAndGen(JavaModuleFixtureBuilder moduleFixtureBuilder, String moduleRoot) { + moduleFixtureBuilder.addContentRoot(moduleRoot); + + //noinspection ResultOfMethodCallIgnored + new File(moduleRoot + "/src/").mkdir(); + moduleFixtureBuilder.addSourceRoot("src"); + + //noinspection ResultOfMethodCallIgnored + new File(moduleRoot + "/gen/").mkdir(); + moduleFixtureBuilder.addSourceRoot("gen"); + } + + /** + * Returns the path that any additional modules registered by + * {@link #configureAdditionalModules(TestFixtureBuilder, List)} or + * {@link #addModuleWithAndroidFacet(TestFixtureBuilder, List, String, int, boolean)} are + * installed into. + */ + protected static String getAdditionalModulePath(@NotNull String moduleName) { + return "/additionalModules/" + moduleName; + } + + /** + * Indicates whether this class provides its own {@code AndroidManifest.xml} for its tests. If + * {@code true}, then {@link #setUp()} calls {@link #deleteManifest()} before finishing. + */ + protected boolean providesCustomManifest() { + return false; + } + + /** + * Get the "res" directory for this SDK. Children classes can override this if they need to + * provide a custom "res" location for tests. + */ + protected String getResDir() { + return "res"; + } + + /** + * Defines the project level to set for the test project, or null to get the default language + * level associated with the test project. + */ + @Nullable + protected LanguageLevel getLanguageLevel() { + return null; + } + + protected static AndroidXmlCodeStyleSettings getAndroidCodeStyleSettings() { + return AndroidXmlCodeStyleSettings.getInstance(CodeStyleSchemes.getInstance().getDefaultScheme().getCodeStyleSettings()); + } + + /** + * Hook point for child test classes to register directories that can be safely accessed by all + * of its tests. + * + * @see {@link VfsRootAccess} + */ + protected void collectAllowedRoots(List roots) throws IOException { + } + + private void registerAllowedRoots(List roots, @NotNull Disposable disposable) { + List newRoots = new ArrayList<>(roots); + newRoots.removeAll(myAllowedRoots); + + String[] newRootsArray = ArrayUtil.toStringArray(newRoots); + VfsRootAccess.allowRootAccess(newRootsArray); + myAllowedRoots.addAll(newRoots); + + Disposer.register(disposable, () -> { + VfsRootAccess.disallowRootAccess(newRootsArray); + myAllowedRoots.removeAll(newRoots); + }); + } + + public static AndroidFacet addAndroidFacet(Module module) { + return addAndroidFacet(module, true); + } + + private static AndroidFacet addAndroidFacet(Module module, boolean attachSdk) { + FacetManager facetManager = FacetManager.getInstance(module); + AndroidFacet facet = facetManager.createFacet(AndroidFacet.getFacetType(), "Android", null); + + if (attachSdk) { + addLatestAndroidSdk(module); + } + ModifiableFacetModel facetModel = facetManager.createModifiableModel(); + facetModel.addFacet(facet); + ApplicationManager.getApplication().runWriteAction(facetModel::commit); + return facet; + } + + protected void configureAdditionalModules( + @NotNull TestFixtureBuilder projectBuilder, @NotNull List modules) { + } + + protected final void addModuleWithAndroidFacet( + @NotNull TestFixtureBuilder projectBuilder, + @NotNull List modules, + @NotNull String dirName, + int projectType) { + // By default, created module is declared as a main module's dependency + addModuleWithAndroidFacet(projectBuilder, modules, dirName, projectType, true); + } + + protected final void addModuleWithAndroidFacet( + @NotNull TestFixtureBuilder projectBuilder, + @NotNull List modules, + @NotNull String dirName, + int projectType, + boolean isMainModuleDependency) { + JavaModuleFixtureBuilder moduleFixtureBuilder = projectBuilder.addModule(JavaModuleFixtureBuilder.class); + String moduleDirPath = myFixture.getTempDirPath() + getAdditionalModulePath(dirName); + //noinspection ResultOfMethodCallIgnored + new File(moduleDirPath).mkdirs(); + initializeModuleFixtureBuilderWithSrcAndGen(moduleFixtureBuilder, moduleDirPath); + modules.add(new MyAdditionalModuleData(moduleFixtureBuilder, dirName, projectType, isMainModuleDependency)); + } + + protected void createManifest() throws IOException { + myFixture.copyFileToProject(SdkConstants.FN_ANDROID_MANIFEST_XML, SdkConstants.FN_ANDROID_MANIFEST_XML); + } + + protected final void createProjectProperties() throws IOException { + myFixture.copyFileToProject(SdkConstants.FN_PROJECT_PROPERTIES, SdkConstants.FN_PROJECT_PROPERTIES); + } + + protected final void deleteManifest() throws IOException { + deleteManifest(myModule); + } + + protected final void deleteManifest(final Module module) throws IOException { + AndroidFacet facet = AndroidFacet.getInstance(module); + assertNotNull(facet); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + String manifestRelativePath = facet.getProperties().MANIFEST_FILE_RELATIVE_PATH; + VirtualFile manifest = AndroidRootUtil.getFileByRelativeModulePath(module, manifestRelativePath, true); + if (manifest != null) { + try { + manifest.delete(this); + } + catch (IOException e) { + fail("Could not delete default manifest"); + } + } + } + }); + } + + protected final void doGlobalInspectionTest( + @NotNull GlobalInspectionTool inspection, @NotNull String globalTestDir, @NotNull AnalysisScope scope) { + doGlobalInspectionTest(new GlobalInspectionToolWrapper(inspection), globalTestDir, scope); + } + + /** + * Given an inspection and a path to a directory that contains an "expected.xml" file, run the + * inspection on the current test project and verify that its output matches that of the + * expected file. + */ + protected final void doGlobalInspectionTest( + @NotNull GlobalInspectionToolWrapper wrapper, @NotNull String globalTestDir, @NotNull AnalysisScope scope) { + myFixture.enableInspections(wrapper.getTool()); + + scope.invalidate(); + + InspectionManagerEx inspectionManager = (InspectionManagerEx)InspectionManager.getInstance(getProject()); + GlobalInspectionContextForTests globalContext = + CodeInsightTestFixtureImpl.createGlobalContextForTool(scope, getProject(), inspectionManager, wrapper); + + InspectionTestUtil.runTool(wrapper, scope, globalContext); + InspectionTestUtil.compareToolResults(globalContext, wrapper, false, getTestDataPath() + globalTestDir); + } + + protected static class MyAdditionalModuleData { + final JavaModuleFixtureBuilder myModuleFixtureBuilder; + final String myDirName; + final int myProjectType; + final boolean myIsMainModuleDependency; + + private MyAdditionalModuleData( + @NotNull JavaModuleFixtureBuilder moduleFixtureBuilder, @NotNull String dirName, int projectType, boolean isMainModuleDependency) { + myModuleFixtureBuilder = moduleFixtureBuilder; + myDirName = dirName; + myProjectType = projectType; + myIsMainModuleDependency = isMainModuleDependency; + } + } + + @NotNull + protected T registerApplicationComponent(@NotNull Class key, @NotNull T instance) throws Exception { + MutablePicoContainer picoContainer = (MutablePicoContainer)ApplicationManager.getApplication().getPicoContainer(); + @SuppressWarnings("unchecked") + T old = (T)picoContainer.getComponentInstance(key.getName()); + picoContainer.unregisterComponent(key.getName()); + picoContainer.registerComponentInstance(key.getName(), instance); + return old; + } + + @NotNull + protected T registerProjectComponent(@NotNull Class key, @NotNull T instance) { + MutablePicoContainer picoContainer = (MutablePicoContainer)getProject().getPicoContainer(); + @SuppressWarnings("unchecked") + T old = (T)picoContainer.getComponentInstance(key.getName()); + picoContainer.unregisterComponent(key.getName()); + picoContainer.registerComponentInstance(key.getName(), instance); + return old; + } +} diff --git a/idea/idea-android/tests/org/jetbrains/kotlin/android/KotlinAndroidTestCase.java b/idea/idea-android/tests/org/jetbrains/kotlin/android/KotlinAndroidTestCase.java deleted file mode 100644 index 24051e2f5b4..00000000000 --- a/idea/idea-android/tests/org/jetbrains/kotlin/android/KotlinAndroidTestCase.java +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.android; - -import com.android.SdkConstants; -import com.android.tools.idea.rendering.RenderSecurityManager; -import com.android.tools.idea.res.PsiProjectListener; -import com.intellij.facet.FacetManager; -import com.intellij.facet.ModifiableFacetModel; -import com.intellij.ide.startup.impl.StartupManagerImpl; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.roots.ModuleRootModificationUtil; -import com.intellij.openapi.startup.StartupManager; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess; -import com.intellij.testFramework.builders.JavaModuleFixtureBuilder; -import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; -import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; -import com.intellij.testFramework.fixtures.JavaTestFixtureFactory; -import com.intellij.testFramework.fixtures.TestFixtureBuilder; -import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.android.facet.AndroidRootUtil; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.kotlin.idea.actions.internal.KotlinInternalMode; -import org.jetbrains.kotlin.test.KotlinTestUtils; - -import java.io.File; -import java.io.FileFilter; -import java.io.IOException; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - - -@SuppressWarnings({"JUnitTestCaseWithNonTrivialConstructors"}) -public abstract class KotlinAndroidTestCase extends KotlinAndroidTestCaseBase { - protected Module myModule; - protected List myAdditionalModules; - - private final boolean myCreateManifest; - protected AndroidFacet myFacet; - - private boolean kotlinInternalModeOriginalValue; - - public KotlinAndroidTestCase(boolean createManifest) { - this.myCreateManifest = createManifest; - } - - public KotlinAndroidTestCase() { - this(true); - } - - protected File[] getResourceDirs(String path) { - return new File(path).listFiles(new FileFilter() { - @Override - public boolean accept(@NotNull File file) { - return file.getName().startsWith("res") && file.isDirectory(); - } - }); - } - - @Override - protected void setUp() throws Exception { - // sdk path workaround, set real android sdk path and platform for android plugin to work - System.setProperty(KotlinAndroidTestCaseBase.SDK_PATH_PROPERTY, PathManager.getHomePath() + "/../dependencies/androidSDK"); - System.setProperty(KotlinAndroidTestCaseBase.PLATFORM_DIR_PROPERTY, "android-23"); - - VfsRootAccess.allowRootAccess(KotlinTestUtils.getHomeDirectory()); - - super.setUp(); - - // this will throw an exception if we don't have a full Android SDK, so we need to do this first thing before any other setup - String sdkPath = getTestSdkPath(); - - final TestFixtureBuilder projectBuilder = - IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getName()); - myFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(projectBuilder.getFixture()); - final JavaModuleFixtureBuilder moduleFixtureBuilder = projectBuilder.addModule(JavaModuleFixtureBuilder.class); - final String dirPath = myFixture.getTempDirPath() + getContentRootPath(); - final File dir = new File(dirPath); - - if (!dir.exists()) { - assertTrue(dir.mkdirs()); - } - tuneModule(moduleFixtureBuilder, dirPath); - - final List modules = new ArrayList(); - configureAdditionalModules(projectBuilder, modules); - - myFixture.setUp(); - myFixture.setTestDataPath(getTestDataPath()); - myModule = moduleFixtureBuilder.getFixture().getModule(); - - // Must be done before addAndroidFacet, and must always be done, even if !myCreateManifest. - // We will delete it at the end of setUp; this is needed when unit tests want to rewrite - // the manifest on their own. - createManifest(); - - androidSdk = createAndroidSdk(getTestSdkPath(), getPlatformDir()); - myFacet = addAndroidFacet(myModule, sdkPath, getPlatformDir(), isToAddSdk()); - for (File resDir : getResourceDirs(dirPath)) { - if (resDir.exists()) { - myFixture.copyDirectoryToProject(resDir.getName(), resDir.getName()); - } else { - Logger.getInstance(this.getClass()).info("No res directory found in test"); - } - } - myAdditionalModules = new ArrayList(); - - for (MyAdditionalModuleData data : modules) { - final Module additionalModule = data.myModuleFixtureBuilder.getFixture().getModule(); - myAdditionalModules.add(additionalModule); - final AndroidFacet facet = addAndroidFacet(additionalModule, sdkPath, getPlatformDir()); - facet.setLibraryProject(data.myLibrary); - final String rootPath = getContentRootPath(data.myDirName); - myFixture.copyDirectoryToProject("res", rootPath + "/res"); - myFixture.copyFileToProject(SdkConstants.FN_ANDROID_MANIFEST_XML, - rootPath + '/' + SdkConstants.FN_ANDROID_MANIFEST_XML); - ModuleRootModificationUtil.addDependency(myModule, additionalModule); - } - - if (!myCreateManifest) { - deleteManifest(); - } - - if (RenderSecurityManager.RESTRICT_READS) { - // Unit test class loader includes disk directories which security manager does not allow access to - RenderSecurityManager.sEnabled = false; - } - - ((StartupManagerImpl) StartupManager.getInstance(getProject())).runPostStartupActivities(); - - kotlinInternalModeOriginalValue = KotlinInternalMode.Instance.getEnabled(); - KotlinInternalMode.Instance.setEnabled(true); - } - - protected boolean isToAddSdk() { - return true; - } - - protected String getContentRootPath() { - return ""; - } - - protected void configureAdditionalModules(@NotNull TestFixtureBuilder projectBuilder, - @NotNull List modules) { - } - - protected static String getContentRootPath(@NotNull String moduleName) { - return "/additionalModules/" + moduleName; - } - - public static void tuneModule(JavaModuleFixtureBuilder moduleBuilder, String moduleDirPath) { - moduleBuilder.addContentRoot(moduleDirPath); - - //noinspection ResultOfMethodCallIgnored - new File(moduleDirPath + "/src/").mkdir(); - moduleBuilder.addSourceRoot("src"); - - //noinspection ResultOfMethodCallIgnored - new File(moduleDirPath + "/gen/").mkdir(); - moduleBuilder.addSourceRoot("gen"); - } - - protected void createManifest() throws IOException { - myFixture.copyFileToProject("plugins/android-extensions/android-extensions-idea/testData/android/AndroidManifest.xml", - SdkConstants.FN_ANDROID_MANIFEST_XML); - } - - protected void deleteManifest() throws IOException { - deleteManifest(myModule); - } - - protected void deleteManifest(final Module module) throws IOException { - final AndroidFacet facet = AndroidFacet.getInstance(module); - assertNotNull(facet); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - String manifestRelativePath = facet.getProperties().MANIFEST_FILE_RELATIVE_PATH; - VirtualFile manifest = AndroidRootUtil.getFileByRelativeModulePath(module, manifestRelativePath, true); - if (manifest != null) { - try { - manifest.delete(this); - } - catch (IOException e) { - fail("Could not delete default manifest"); - } - } - } - }); - } - - @Override - public void tearDown() throws Exception { - KotlinInternalMode.Instance.setEnabled(kotlinInternalModeOriginalValue); - - Field listenersField = PsiProjectListener.class.getDeclaredField("myListeners"); - listenersField.setAccessible(true); - Map listeners = (Map)listenersField.get(PsiProjectListener.getInstance(getProject())); - listeners.clear(); - - VfsRootAccess.disallowRootAccess(KotlinTestUtils.getHomeDirectory()); - - super.tearDown(); - - myModule = null; - myAdditionalModules = null; - myFixture.tearDown(); - myFixture = null; - myFacet = null; - - if (RenderSecurityManager.RESTRICT_READS) { - RenderSecurityManager.sEnabled = true; - } - } - - public AndroidFacet addAndroidFacet(Module module, String sdkPath, String platformDir) { - return addAndroidFacet(module, sdkPath, platformDir, true); - } - - public AndroidFacet addAndroidFacet(Module module, String sdkPath, String platformDir, boolean addSdk) { - FacetManager facetManager = FacetManager.getInstance(module); - AndroidFacet facet = facetManager.createFacet(AndroidFacet.getFacetType(), "Android", null); - - if (addSdk) { - addAndroidSdk(module, sdkPath, platformDir); - } - final ModifiableFacetModel facetModel = facetManager.createModifiableModel(); - facetModel.addFacet(facet); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - facetModel.commit(); - } - }); - return facet; - } - - protected static class MyAdditionalModuleData { - final JavaModuleFixtureBuilder myModuleFixtureBuilder; - final String myDirName; - final boolean myLibrary; - - private MyAdditionalModuleData(@NotNull JavaModuleFixtureBuilder moduleFixtureBuilder, - @NotNull String dirName, - boolean library) { - myModuleFixtureBuilder = moduleFixtureBuilder; - myDirName = dirName; - myLibrary = library; - } - } -} diff --git a/idea/idea-android/tests/org/jetbrains/kotlin/android/KotlinAndroidTestCase.kt b/idea/idea-android/tests/org/jetbrains/kotlin/android/KotlinAndroidTestCase.kt new file mode 100644 index 00000000000..d1d567edcdb --- /dev/null +++ b/idea/idea-android/tests/org/jetbrains/kotlin/android/KotlinAndroidTestCase.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.android + +import com.android.SdkConstants +import org.jetbrains.kotlin.test.KotlinTestUtils +import java.io.File + + +abstract class KotlinAndroidTestCase : AndroidTestCase() { + override fun getTestDataPath() = KotlinTestUtils.getHomeDirectory() + + override fun createManifest() { + myFixture.copyFileToProject("idea/testData/android/AndroidManifest.xml", SdkConstants.FN_ANDROID_MANIFEST_XML) + } + + fun copyResourceDirectoryForTest(path: String) { + val testFile = File(path) + if (testFile.isFile) { + myFixture.copyDirectoryToProject(testFile.parent + "/res", "res") + } else if (testFile.isDirectory) { + myFixture.copyDirectoryToProject(testFile.path + "/res", "res") + } + } +} \ No newline at end of file diff --git a/idea/idea-android/tests/org/jetbrains/kotlin/android/KotlinAndroidTestCaseBase.java b/idea/idea-android/tests/org/jetbrains/kotlin/android/KotlinAndroidTestCaseBase.java deleted file mode 100644 index 1832b24b528..00000000000 --- a/idea/idea-android/tests/org/jetbrains/kotlin/android/KotlinAndroidTestCaseBase.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.kotlin.android; - -import com.android.sdklib.IAndroidTarget; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.projectRoots.ProjectJdkTable; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.projectRoots.SdkModificator; -import com.intellij.openapi.roots.JavadocOrderRootType; -import com.intellij.openapi.roots.ModuleRootModificationUtil; -import com.intellij.openapi.roots.OrderRootType; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileManager; -import com.intellij.testFramework.IdeaTestCase; -import com.intellij.testFramework.UsefulTestCase; -import com.intellij.testFramework.fixtures.CodeInsightTestFixture; -import org.jetbrains.android.sdk.AndroidSdkAdditionalData; -import org.jetbrains.android.sdk.AndroidSdkData; -import org.jetbrains.android.sdk.AndroidSdkType; -import org.jetbrains.kotlin.idea.test.RunnableWithException; -import org.jetbrains.kotlin.idea.test.TestUtilsKt; -import org.jetbrains.kotlin.test.KotlinTestUtils; - -import java.io.File; - -@SuppressWarnings({"JUnitTestCaseWithNonTrivialConstructors"}) -public abstract class KotlinAndroidTestCaseBase extends UsefulTestCase { - /** Environment variable or system property containing the full path to an SDK install */ - public static final String SDK_PATH_PROPERTY = "ADT_TEST_SDK_PATH"; - - /** Environment variable or system property pointing to the directory name of the platform inside $sdk/platforms, e.g. "android-17" */ - public static final String PLATFORM_DIR_PROPERTY = "ADT_TEST_PLATFORM"; - - protected CodeInsightTestFixture myFixture; - - protected Sdk androidSdk; - protected VirtualFile androidJar; - - private static final String TEST_DATA_PROJECT_RELATIVE = "/plugins/android-extensions/android-extensions-idea/testData/android"; - - protected KotlinAndroidTestCaseBase() { - IdeaTestCase.initPlatformPrefix(); - } - - public static String getPluginTestDataPathBase() { - return KotlinTestUtils.getHomeDirectory() + TEST_DATA_PROJECT_RELATIVE; - } - - public String getTestDataPath() { - return getPluginTestDataPathBase(); - } - - public String getDefaultTestSdkPath() { - return getTestDataPath() + "/sdk1.5"; - } - - @Override - protected void tearDown() throws Exception { - TestUtilsKt.doKotlinTearDown(getProject(), new RunnableWithException() { - @Override - public void run() throws Exception { - KotlinAndroidTestCaseBase.super.tearDown(); - androidJar = null; - androidSdk = null; - } - }); - } - - public String getDefaultPlatformDir() { - return "android-1.5"; - } - - protected String getTestSdkPath() { - if (requireRecentSdk()) { - String override = System.getProperty(SDK_PATH_PROPERTY); - if (override != null) { - assertTrue("Must also define " + PLATFORM_DIR_PROPERTY, System.getProperty(PLATFORM_DIR_PROPERTY) != null); - assertTrue(override, new File(override).exists()); - return override; - } - override = System.getenv(SDK_PATH_PROPERTY); - if (override != null) { - assertTrue("Must also define " + PLATFORM_DIR_PROPERTY, System.getenv(PLATFORM_DIR_PROPERTY) != null); - return override; - } - fail("This unit test requires " + SDK_PATH_PROPERTY + " and " + PLATFORM_DIR_PROPERTY + " to be defined."); - } - - return getDefaultTestSdkPath(); - } - - protected String getPlatformDir() { - if (requireRecentSdk()) { - String override = System.getProperty(PLATFORM_DIR_PROPERTY); - if (override != null) { - return override; - } - override = System.getenv(PLATFORM_DIR_PROPERTY); - if (override != null) { - return override; - } - fail("This unit test requires " + SDK_PATH_PROPERTY + " and " + PLATFORM_DIR_PROPERTY + " to be defined."); - } - return getDefaultPlatformDir(); - } - - /** Is the bundled (incomplete) SDK install adequate or do we need to find a valid install? */ - protected boolean requireRecentSdk() { - return true; - } - - protected void addAndroidSdk(Module module, String sdkPath, String platformDir) { - assert androidSdk != null : "android sdk must be initialized"; - ModuleRootModificationUtil.setModuleSdk(module, androidSdk); - } - - public Sdk createAndroidSdk(String sdkPath, String platformDir) { - Sdk sdk = ProjectJdkTable.getInstance().createSdk("android_test_sdk", AndroidSdkType.getInstance()); - SdkModificator sdkModificator = sdk.getSdkModificator(); - sdkModificator.setHomePath(sdkPath); - - if (platformDir.equals(getDefaultPlatformDir())) { - // Compatibility: the unit tests were using android.jar outside the sdk1.5 install; - // we need to use that one, rather than the real one in sdk1.5, in order for the - // tests to pass. Longer term, we should switch the unit tests over to all using - // a valid SDK. - String androidJarPath = sdkPath + "/../android.jar!/"; - androidJar = VirtualFileManager.getInstance().findFileByUrl("jar://" + androidJarPath); - } else { - androidJar = VirtualFileManager.getInstance().findFileByUrl("jar://" + sdkPath + "/platforms/" + platformDir + "/android.jar!/"); - } - sdkModificator.addRoot(androidJar, OrderRootType.CLASSES); - - VirtualFile resFolder = LocalFileSystem.getInstance().findFileByPath(sdkPath + "/platforms/" + platformDir + "/data/res"); - sdkModificator.addRoot(resFolder, OrderRootType.CLASSES); - - VirtualFile docsFolder = LocalFileSystem.getInstance().findFileByPath(sdkPath + "/docs/reference"); - if (docsFolder != null) { - sdkModificator.addRoot(docsFolder, JavadocOrderRootType.getInstance()); - } - - AndroidSdkAdditionalData data = new AndroidSdkAdditionalData(sdk); - AndroidSdkData sdkData = AndroidSdkData.getSdkData(sdkPath); - assertNotNull(sdkData); - IAndroidTarget target = sdkData.findTargetByName("Android 5.0"); // TODO: Get rid of this hardcoded version number - if (target == null) { - IAndroidTarget[] targets = sdkData.getTargets(); - for (IAndroidTarget t : targets) { - if (t.getLocation().contains(platformDir)) { - target = t; - break; - } - } - if (target == null && targets.length > 0) { - target = targets[targets.length - 1]; - } - } - assertNotNull(target); - data.setBuildTarget(target); - sdkModificator.setSdkAdditionalData(data); - sdkModificator.commitChanges(); - return sdk; - } - - protected Project getProject() { - return myFixture.getProject(); - } -} - diff --git a/idea/idea-android/tests/org/jetbrains/kotlin/android/TestUtils.java b/idea/idea-android/tests/org/jetbrains/kotlin/android/TestUtils.java new file mode 100644 index 00000000000..735bb9e3ac3 --- /dev/null +++ b/idea/idea-android/tests/org/jetbrains/kotlin/android/TestUtils.java @@ -0,0 +1,39 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.android; + + +import com.android.annotations.NonNull; +import com.intellij.openapi.application.PathManager; + +import java.io.File; + +/** + * Stub for com.android.testutils.TestUtils + * stabbed to minimize changes in AndroidTestBase + */ +public class TestUtils { + @NonNull + public static File getSdk() { + return new File(PathManager.getHomePath() + "/../dependencies/androidSDK"); + } + + @NonNull + public static String getLatestAndroidPlatform() { + return "android-23"; + } +} diff --git a/idea/idea-android/tests/org/jetbrains/kotlin/android/configure/AbstractConfigureProjectTest.java b/idea/idea-android/tests/org/jetbrains/kotlin/android/configure/AbstractConfigureProjectTest.java index cc47792b96b..6a728508b87 100644 --- a/idea/idea-android/tests/org/jetbrains/kotlin/android/configure/AbstractConfigureProjectTest.java +++ b/idea/idea-android/tests/org/jetbrains/kotlin/android/configure/AbstractConfigureProjectTest.java @@ -17,7 +17,6 @@ package org.jetbrains.kotlin.android.configure; import org.jetbrains.annotations.NotNull; -import org.jetbrains.kotlin.idea.configuration.AbstractConfigureProjectByChangingFileTest; import org.jetbrains.kotlin.idea.configuration.AbstractGradleConfigureProjectByChangingFileTest; public abstract class AbstractConfigureProjectTest extends AbstractGradleConfigureProjectByChangingFileTest { diff --git a/idea/idea-android/tests/org/jetbrains/kotlin/android/folding/AbstractAndroidFoldingTest.kt b/idea/idea-android/tests/org/jetbrains/kotlin/android/folding/AbstractAndroidFoldingTest.kt index e27fbde9e2b..be8f2b9196e 100644 --- a/idea/idea-android/tests/org/jetbrains/kotlin/android/folding/AbstractAndroidFoldingTest.kt +++ b/idea/idea-android/tests/org/jetbrains/kotlin/android/folding/AbstractAndroidFoldingTest.kt @@ -16,21 +16,16 @@ package org.jetbrains.kotlin.android.folding -import com.android.SdkConstants import org.jetbrains.kotlin.android.KotlinAndroidTestCase +import java.io.File abstract class AbstractAndroidResourceFoldingTest : KotlinAndroidTestCase() { fun doTest(path: String) { - myFixture.copyFileToProject("values.xml", "res/values/values.xml") - myFixture.copyFileToProject("R.java", "gen/com/myapp/R.java") + val testFile = File(path) + myFixture.copyFileToProject("${testFile.parent}/values.xml", "res/values/values.xml") + myFixture.copyFileToProject("${testFile.parent}/R.java", "gen/com/myapp/R.java") myFixture.testFoldingWithCollapseStatus(path, "${myFixture.tempDirPath}/src/main.kt") } - - override fun createManifest() { - myFixture.copyFileToProject("idea/testData/android/AndroidManifest.xml", SdkConstants.FN_ANDROID_MANIFEST_XML) - } - - override fun getTestDataPath() = "idea/testData/android/folding" } \ No newline at end of file diff --git a/idea/idea-android/tests/org/jetbrains/kotlin/android/intention/AbstractAndroidIntentionTest.kt b/idea/idea-android/tests/org/jetbrains/kotlin/android/intention/AbstractAndroidIntentionTest.kt index 7644439c22d..480dfc42500 100644 --- a/idea/idea-android/tests/org/jetbrains/kotlin/android/intention/AbstractAndroidIntentionTest.kt +++ b/idea/idea-android/tests/org/jetbrains/kotlin/android/intention/AbstractAndroidIntentionTest.kt @@ -22,9 +22,7 @@ import com.intellij.openapi.util.io.FileUtil import com.intellij.util.PathUtil import org.jetbrains.kotlin.android.KotlinAndroidTestCase import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil -import org.jetbrains.kotlin.idea.test.PluginTestCaseBase import org.jetbrains.kotlin.test.InTextDirectivesUtils -import org.jetbrains.kotlin.test.KotlinTestUtils import java.io.File @@ -81,10 +79,4 @@ abstract class AbstractAndroidIntentionTest : KotlinAndroidTestCase() { } } } - - override fun createManifest() { - myFixture.copyFileToProject("idea/testData/android/AndroidManifest.xml", SdkConstants.FN_ANDROID_MANIFEST_XML) - } - - override fun getTestDataPath() = KotlinTestUtils.getHomeDirectory() } diff --git a/idea/idea-android/tests/org/jetbrains/kotlin/android/intention/AbstractAndroidResourceIntentionTest.kt b/idea/idea-android/tests/org/jetbrains/kotlin/android/intention/AbstractAndroidResourceIntentionTest.kt index eeb916bcb41..951b939df38 100644 --- a/idea/idea-android/tests/org/jetbrains/kotlin/android/intention/AbstractAndroidResourceIntentionTest.kt +++ b/idea/idea-android/tests/org/jetbrains/kotlin/android/intention/AbstractAndroidResourceIntentionTest.kt @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.android.intention -import com.android.SdkConstants import com.google.gson.JsonObject import com.google.gson.JsonParser import com.intellij.codeInsight.intention.IntentionAction @@ -116,8 +115,4 @@ abstract class AbstractAndroidResourceIntentionTest : KotlinAndroidTestCase() { fun getResourceDirectory() = LocalFileSystem.getInstance().findFileByPath(myFixture.tempDirPath + "/res") fun getTargetElement() = myFixture.file.findElementAt(myFixture.caretOffset)?.parent - - override fun createManifest() { - myFixture.copyFileToProject("idea/testData/android/AndroidManifest.xml", SdkConstants.FN_ANDROID_MANIFEST_XML) - } } \ No newline at end of file diff --git a/idea/idea-android/tests/org/jetbrains/kotlin/android/lint/AbstractKotlinLintTest.kt b/idea/idea-android/tests/org/jetbrains/kotlin/android/lint/AbstractKotlinLintTest.kt index f682154b54f..5bc56689d24 100644 --- a/idea/idea-android/tests/org/jetbrains/kotlin/android/lint/AbstractKotlinLintTest.kt +++ b/idea/idea-android/tests/org/jetbrains/kotlin/android/lint/AbstractKotlinLintTest.kt @@ -20,7 +20,6 @@ import org.jetbrains.android.inspections.klint.AndroidLintInspectionBase import org.jetbrains.kotlin.android.KotlinAndroidTestCase import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil import org.jetbrains.kotlin.test.InTextDirectivesUtils.findStringWithPrefixes -import org.jetbrains.kotlin.test.KotlinTestUtils import java.io.File abstract class AbstractKotlinLintTest : KotlinAndroidTestCase() { @@ -70,6 +69,4 @@ abstract class AbstractKotlinLintTest : KotlinAndroidTestCase() { myFixture.checkHighlighting(true, false, false) } - - override fun getTestDataPath() = KotlinTestUtils.getHomeDirectory() + "/idea/testData/android/lint/" } \ No newline at end of file diff --git a/idea/idea-android/tests/org/jetbrains/kotlin/android/quickfix/AbstractAndroidLintQuickfixTest.kt b/idea/idea-android/tests/org/jetbrains/kotlin/android/quickfix/AbstractAndroidLintQuickfixTest.kt index a6c2f029f17..b46f1d76409 100644 --- a/idea/idea-android/tests/org/jetbrains/kotlin/android/quickfix/AbstractAndroidLintQuickfixTest.kt +++ b/idea/idea-android/tests/org/jetbrains/kotlin/android/quickfix/AbstractAndroidLintQuickfixTest.kt @@ -16,14 +16,12 @@ package org.jetbrains.kotlin.android.quickfix -import com.android.SdkConstants import com.intellij.codeInspection.InspectionProfileEntry import com.intellij.openapi.util.io.FileUtil import com.intellij.util.PathUtil import org.jetbrains.android.inspections.klint.AndroidLintInspectionBase import org.jetbrains.kotlin.android.KotlinAndroidTestCase import org.jetbrains.kotlin.test.InTextDirectivesUtils -import org.jetbrains.kotlin.test.KotlinTestUtils import java.io.File @@ -61,10 +59,4 @@ abstract class AbstractAndroidLintQuickfixTest : KotlinAndroidTestCase() { assertNull("Intention should not be available", myFixture.availableIntentions.find { it.text == intentionText }) } } - - override fun createManifest() { - myFixture.copyFileToProject("idea/testData/android/AndroidManifest.xml", SdkConstants.FN_ANDROID_MANIFEST_XML) - } - - override fun getTestDataPath() = KotlinTestUtils.getHomeDirectory() } \ No newline at end of file diff --git a/idea/testData/android/intention/addActivityToManifest/nested.kt.AndroidManifest.xml.expected b/idea/testData/android/intention/addActivityToManifest/nested.kt.AndroidManifest.xml.expected index 67606787f90..d8243000449 100644 --- a/idea/testData/android/intention/addActivityToManifest/nested.kt.AndroidManifest.xml.expected +++ b/idea/testData/android/intention/addActivityToManifest/nested.kt.AndroidManifest.xml.expected @@ -5,6 +5,6 @@ - + \ No newline at end of file diff --git a/idea/testData/android/intention/addActivityToManifest/simple.kt.AndroidManifest.xml.expected b/idea/testData/android/intention/addActivityToManifest/simple.kt.AndroidManifest.xml.expected index d357760073e..fecc806699c 100644 --- a/idea/testData/android/intention/addActivityToManifest/simple.kt.AndroidManifest.xml.expected +++ b/idea/testData/android/intention/addActivityToManifest/simple.kt.AndroidManifest.xml.expected @@ -5,6 +5,6 @@ - + \ No newline at end of file diff --git a/idea/testData/android/intention/addBroadcastReceiverToManifest/nested.kt.AndroidManifest.xml.expected b/idea/testData/android/intention/addBroadcastReceiverToManifest/nested.kt.AndroidManifest.xml.expected index 80e688c5193..5b063ef3f47 100644 --- a/idea/testData/android/intention/addBroadcastReceiverToManifest/nested.kt.AndroidManifest.xml.expected +++ b/idea/testData/android/intention/addBroadcastReceiverToManifest/nested.kt.AndroidManifest.xml.expected @@ -5,6 +5,6 @@ - + \ No newline at end of file diff --git a/idea/testData/android/intention/addBroadcastReceiverToManifest/simple.kt.AndroidManifest.xml.expected b/idea/testData/android/intention/addBroadcastReceiverToManifest/simple.kt.AndroidManifest.xml.expected index 413772c9367..8cdf19ac2d9 100644 --- a/idea/testData/android/intention/addBroadcastReceiverToManifest/simple.kt.AndroidManifest.xml.expected +++ b/idea/testData/android/intention/addBroadcastReceiverToManifest/simple.kt.AndroidManifest.xml.expected @@ -5,6 +5,6 @@ - + \ No newline at end of file diff --git a/idea/testData/android/intention/addServiceToManifest/nested.kt.AndroidManifest.xml.expected b/idea/testData/android/intention/addServiceToManifest/nested.kt.AndroidManifest.xml.expected index 0e2a7618c27..843009de167 100644 --- a/idea/testData/android/intention/addServiceToManifest/nested.kt.AndroidManifest.xml.expected +++ b/idea/testData/android/intention/addServiceToManifest/nested.kt.AndroidManifest.xml.expected @@ -5,6 +5,6 @@ - + \ No newline at end of file diff --git a/idea/testData/android/intention/addServiceToManifest/simple.kt.AndroidManifest.xml.expected b/idea/testData/android/intention/addServiceToManifest/simple.kt.AndroidManifest.xml.expected index 64b5f5bd7b7..2df134f40b5 100644 --- a/idea/testData/android/intention/addServiceToManifest/simple.kt.AndroidManifest.xml.expected +++ b/idea/testData/android/intention/addServiceToManifest/simple.kt.AndroidManifest.xml.expected @@ -5,6 +5,6 @@ - + \ No newline at end of file diff --git a/idea/testData/android/resourceIntention/createLayoutResourceFile/simpleFunction/expected/res/layout/activity_main.xml b/idea/testData/android/resourceIntention/createLayoutResourceFile/simpleFunction/expected/res/layout/activity_main.xml index fb3d8a25805..3509b84116a 100644 --- a/idea/testData/android/resourceIntention/createLayoutResourceFile/simpleFunction/expected/res/layout/activity_main.xml +++ b/idea/testData/android/resourceIntention/createLayoutResourceFile/simpleFunction/expected/res/layout/activity_main.xml @@ -1,7 +1,6 @@ + android:orientation="vertical" android:layout_width="match_parent" + android:layout_height="match_parent"> \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/tests/org/jetbrains/kotlin/android/AbstractAndroidCompletionTest.kt b/plugins/android-extensions/android-extensions-idea/tests/org/jetbrains/kotlin/android/AbstractAndroidCompletionTest.kt index 6aa44db7486..41409c6f1bf 100644 --- a/plugins/android-extensions/android-extensions-idea/tests/org/jetbrains/kotlin/android/AbstractAndroidCompletionTest.kt +++ b/plugins/android-extensions/android-extensions-idea/tests/org/jetbrains/kotlin/android/AbstractAndroidCompletionTest.kt @@ -43,19 +43,14 @@ abstract class AbstractAndroidCompletionTest : KotlinAndroidTestCase() { private fun completionType() = CompletionType.BASIC - fun doTest(path: String?) { - getResourceDirs(path).forEach { myFixture.copyDirectoryToProject(it.name, it.name) } + fun doTest(path: String) { + copyResourceDirectoryForTest(path) val virtualFile = myFixture.copyFileToProject(path + getTestName(true) + ".kt", "src/" + getTestName(true) + ".kt") myFixture.configureFromExistingVirtualFile(virtualFile) val fileText = FileUtil.loadFile(File(path + getTestName(true) + ".kt"), true) testCompletion(fileText, JvmPlatform, { completionType, count -> myFixture.complete(completionType, count) }) } - - override fun getTestDataPath(): String { - return KotlinAndroidTestCaseBase.getPluginTestDataPathBase() + "/completion/" + getTestName(true) + "/" - } - override fun tearDown() { val settings = CodeInsightSettings.getInstance() settings.AUTOCOMPLETE_ON_CODE_COMPLETION = codeCompletionOldValue diff --git a/plugins/android-extensions/android-extensions-idea/tests/org/jetbrains/kotlin/android/AbstractAndroidFindUsagesTest.kt b/plugins/android-extensions/android-extensions-idea/tests/org/jetbrains/kotlin/android/AbstractAndroidFindUsagesTest.kt index 25dd0fe5c1e..7a784467853 100644 --- a/plugins/android-extensions/android-extensions-idea/tests/org/jetbrains/kotlin/android/AbstractAndroidFindUsagesTest.kt +++ b/plugins/android-extensions/android-extensions-idea/tests/org/jetbrains/kotlin/android/AbstractAndroidFindUsagesTest.kt @@ -16,26 +16,17 @@ package org.jetbrains.kotlin.android -import com.intellij.codeInsight.TargetElementUtil abstract class AbstractAndroidFindUsagesTest : KotlinAndroidTestCase() { - override fun getTestDataPath() = KotlinAndroidTestCaseBase.getPluginTestDataPathBase() + "/findUsages/" + getTestName(true) + "/" - fun doTest(path: String) { - if (true) return // Muted (actually works in IDEA) - - val f = myFixture!! - getResourceDirs(path).forEach { myFixture.copyDirectoryToProject(it.name, it.name) } - val virtualFile = f.copyFileToProject(path + getTestName(true) + ".kt", "src/" + getTestName(true) + ".kt") - f.configureFromExistingVirtualFile(virtualFile) - - val targetElement = TargetElementUtil.findTargetElement( - f.editor, TargetElementUtil.ELEMENT_NAME_ACCEPTED or TargetElementUtil.REFERENCED_ELEMENT_ACCEPTED) - assertNotNull(targetElement) - - val propUsages = f.findUsages(targetElement!!) + return // TODO: investigate and fix this test + copyResourceDirectoryForTest(path) + val testFileName = getTestName(true) + ".kt" + val virtualFile = myFixture.copyFileToProject(path + testFileName, "src/" + getTestName(true) + ".kt") + myFixture.configureFromExistingVirtualFile(virtualFile) + val propUsages = myFixture.findUsages(myFixture.elementAtCaret) assertTrue(propUsages.isNotEmpty()) } } \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/tests/org/jetbrains/kotlin/android/AbstractAndroidGotoTest.kt b/plugins/android-extensions/android-extensions-idea/tests/org/jetbrains/kotlin/android/AbstractAndroidGotoTest.kt index 51255565669..3654aa9b74f 100644 --- a/plugins/android-extensions/android-extensions-idea/tests/org/jetbrains/kotlin/android/AbstractAndroidGotoTest.kt +++ b/plugins/android-extensions/android-extensions-idea/tests/org/jetbrains/kotlin/android/AbstractAndroidGotoTest.kt @@ -31,22 +31,17 @@ import org.jetbrains.kotlin.test.KotlinTestUtils abstract class AbstractAndroidGotoTest : KotlinAndroidTestCase() { - override fun getTestDataPath(): String { - return KotlinAndroidTestCaseBase.getPluginTestDataPathBase() + "/goto/" + getTestName(true) + "/" - } - fun doTest(path: String) { - val f = myFixture!! - getResourceDirs(path).forEach { myFixture.copyDirectoryToProject(it.name, it.name) } - val virtualFile = f.copyFileToProject(path + getTestName(true) + ".kt", "src/" + getTestName(true) + ".kt") - f.configureFromExistingVirtualFile(virtualFile) + copyResourceDirectoryForTest(path) + val virtualFile = myFixture.copyFileToProject(path + getTestName(true) + ".kt", "src/" + getTestName(true) + ".kt") + myFixture.configureFromExistingVirtualFile(virtualFile) - val expression = TargetElementUtil.findReference(f.editor, f.caretOffset)!!.element as KtElement + val expression = TargetElementUtil.findReference(myFixture.editor, myFixture.caretOffset)!!.element as KtElement val bindingContext = expression.analyzeFully() val resolvedCall = bindingContext[BindingContext.RESOLVED_CALL, bindingContext[BindingContext.CALL, expression]]!! val property = resolvedCall.resultingDescriptor as? PropertyDescriptor ?: throw AssertionError("PropertyDescriptor expected") - val targetElement = GotoDeclarationAction.findTargetElement(f.project, f.editor, f.caretOffset)!! + val targetElement = GotoDeclarationAction.findTargetElement(myFixture.project, myFixture.editor, myFixture.caretOffset)!! assert(targetElement is XmlAttributeValue) { "XmlAttributeValue expected, got ${targetElement::class.java}" } assertEquals("@+id/${property.name}", (targetElement as XmlAttributeValue).value) diff --git a/plugins/android-extensions/android-extensions-idea/tests/org/jetbrains/kotlin/android/AbstractAndroidLayoutRenameTest.kt b/plugins/android-extensions/android-extensions-idea/tests/org/jetbrains/kotlin/android/AbstractAndroidLayoutRenameTest.kt index 9e539ce04e7..503c19611ea 100644 --- a/plugins/android-extensions/android-extensions-idea/tests/org/jetbrains/kotlin/android/AbstractAndroidLayoutRenameTest.kt +++ b/plugins/android-extensions/android-extensions-idea/tests/org/jetbrains/kotlin/android/AbstractAndroidLayoutRenameTest.kt @@ -29,12 +29,11 @@ abstract class AbstractAndroidLayoutRenameTest : KotlinAndroidTestCase() { private val NEW_NAME_XML = "$NEW_NAME.xml" fun doTest(path: String) { - val f = myFixture!! - getResourceDirs(path).forEach { myFixture.copyDirectoryToProject(it.name, it.name) } - val virtualFile = f.copyFileToProject(path + getTestName(true) + ".kt", "src/" + getTestName(true) + ".kt") - f.configureFromExistingVirtualFile(virtualFile) + copyResourceDirectoryForTest(path) + val virtualFile = myFixture.copyFileToProject(path + getTestName(true) + ".kt", "src/" + getTestName(true) + ".kt") + myFixture.configureFromExistingVirtualFile(virtualFile) - val completionEditor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(f.editor, f.file) + val completionEditor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(myFixture.editor, myFixture.file) val element = TargetElementUtil.findTargetElement( completionEditor, @@ -42,10 +41,8 @@ abstract class AbstractAndroidLayoutRenameTest : KotlinAndroidTestCase() { val file = element.containingFile as XmlFile - RenameProcessor(f.project, file, NEW_NAME_XML, false, true).run() + RenameProcessor(myFixture.project, file, NEW_NAME_XML, false, true).run() - (f.file as KtFile).importDirectives.any { it.importedFqName!!.asString() == AndroidConst.SYNTHETIC_PACKAGE + ".main." + NEW_NAME } + (myFixture.file as KtFile).importDirectives.any { it.importedFqName!!.asString() == AndroidConst.SYNTHETIC_PACKAGE + ".main." + NEW_NAME } } - - override fun getTestDataPath() = KotlinAndroidTestCaseBase.getPluginTestDataPathBase() + "/rename/" + getTestName(true) + "/" } diff --git a/plugins/android-extensions/android-extensions-idea/tests/org/jetbrains/kotlin/android/AbstractAndroidRenameTest.kt b/plugins/android-extensions/android-extensions-idea/tests/org/jetbrains/kotlin/android/AbstractAndroidRenameTest.kt index 2cacc3a5017..9f565bda23a 100644 --- a/plugins/android-extensions/android-extensions-idea/tests/org/jetbrains/kotlin/android/AbstractAndroidRenameTest.kt +++ b/plugins/android-extensions/android-extensions-idea/tests/org/jetbrains/kotlin/android/AbstractAndroidRenameTest.kt @@ -16,24 +16,19 @@ package org.jetbrains.kotlin.android -import com.intellij.codeInsight.TargetElementUtil import com.intellij.openapi.vfs.LocalFileSystem -import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil -import com.intellij.refactoring.rename.RenameProcessor -import com.intellij.psi.impl.source.xml.XmlAttributeValueImpl import com.intellij.testFramework.PlatformTestUtil -import org.jetbrains.kotlin.psi.KtNameReferenceExpression abstract class AbstractAndroidRenameTest : KotlinAndroidTestCase() { private val NEW_NAME = "NEWNAME" private val NEW_ID_NAME = "@+id/$NEW_NAME" fun doTest(path: String) { - getResourceDirs(path).forEach { myFixture.copyDirectoryToProject(it.name, it.name) } + copyResourceDirectoryForTest(path) val virtualFile = myFixture.copyFileToProject("$path${getTestName(true)}.kt", "src/${getTestName(true)}.kt") myFixture.configureFromExistingVirtualFile(virtualFile) myFixture.renameElement(myFixture.elementAtCaret, NEW_ID_NAME) - myFixture.checkResultByFile("expected/${getTestName(true)}.kt") + myFixture.checkResultByFile("$path/expected/${getTestName(true)}.kt") assertResourcesEqual("$path/expected/res") } @@ -42,6 +37,4 @@ abstract class AbstractAndroidRenameTest : KotlinAndroidTestCase() { } fun getResourceDirectory() = LocalFileSystem.getInstance().findFileByPath(myFixture.tempDirPath + "/res") - - override fun getTestDataPath() = KotlinAndroidTestCaseBase.getPluginTestDataPathBase() + "/rename/" + getTestName(true) + "/" }