/* * 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 com.intellij.testFramework.fixtures.impl; import com.intellij.ide.IdeView; import com.intellij.ide.startup.impl.StartupManagerImpl; import com.intellij.idea.ApplicationStarter; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ex.ProjectManagerEx; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.encoding.EncodingManager; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageManagerImpl; import com.intellij.testFramework.EditorListenerTracker; import com.intellij.testFramework.LightPlatformTestCase; import com.intellij.testFramework.PlatformTestCase; import com.intellij.testFramework.ThreadTracker; import com.intellij.testFramework.builders.ModuleFixtureBuilder; import com.intellij.testFramework.fixtures.HeavyIdeaTestFixture; import com.intellij.util.PathUtil; import com.intellij.util.ui.UIUtil; import gnu.trove.THashSet; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.PrintStream; import java.util.HashSet; import java.util.Set; /** * @author mike */ class HeavyIdeaTestFixtureImpl extends BaseFixture implements HeavyIdeaTestFixture { @NonNls private static final String PROJECT_FILE_PREFIX = "temp"; private Project myProject; private final Set<File> myFilesToDelete = new HashSet<File>(); private ApplicationStarter myApplication; private final Set<ModuleFixtureBuilder> myModuleFixtureBuilders = new THashSet<ModuleFixtureBuilder>(); private EditorListenerTracker myEditorListenerTracker; private ThreadTracker myThreadTracker; private final String myName; public HeavyIdeaTestFixtureImpl(@NotNull String name) { myName = name; } protected void addModuleFixtureBuilder(ModuleFixtureBuilder builder) { myModuleFixtureBuilders.add(builder); } @Override public void setUp() throws Exception { super.setUp(); initApplication(); setUpProject(); EncodingManager.getInstance(); // adds listeners myEditorListenerTracker = new EditorListenerTracker(); myThreadTracker = new ThreadTracker(); InjectedLanguageManagerImpl.pushInjectors(getProject()); } @Override public void tearDown() throws Exception { Project project = getProject(); LightPlatformTestCase.doTearDown(project, myApplication, false); for (ModuleFixtureBuilder moduleFixtureBuilder : myModuleFixtureBuilders) { moduleFixtureBuilder.getFixture().tearDown(); } UIUtil.invokeAndWaitIfNeeded(new Runnable() { @Override public void run() { ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { Disposer.dispose(myProject); myProject = null; } }); } }); for (final File fileToDelete : myFilesToDelete) { boolean deleted = FileUtil.delete(fileToDelete); assert deleted : "Can't delete " + fileToDelete; } super.tearDown(); myEditorListenerTracker.checkListenersLeak(); myThreadTracker.checkLeak(); LightPlatformTestCase.checkEditorsReleased(); InjectedLanguageManagerImpl.checkInjectorsAreDisposed(project); } private void setUpProject() throws Exception { new WriteCommandAction.Simple(null) { @Override protected void run() throws Throwable { File projectDir = FileUtil.createTempDirectory(myName + "_", "project"); FileUtil.delete(projectDir); myFilesToDelete.add(projectDir); LocalFileSystem.getInstance().refreshAndFindFileByIoFile(projectDir); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); new Throwable(projectDir.getPath()).printStackTrace(new PrintStream(buffer)); myProject = PlatformTestCase.createProject(projectDir, buffer.toString()); for (ModuleFixtureBuilder moduleFixtureBuilder : myModuleFixtureBuilders) { moduleFixtureBuilder.getFixture().setUp(); } StartupManagerImpl sm = (StartupManagerImpl)StartupManager.getInstance(myProject); sm.runStartupActivities(); sm.startCacheUpdate(); sm.runPostStartupActivities(); ProjectManagerEx.getInstanceEx().openTestProject(myProject); LightPlatformTestCase.clearUncommittedDocuments(myProject); } }.execute().throwException(); } private void initApplication() throws Exception { myApplication = ApplicationStarter.getInstance(); //myApplication.setDataProvider(new MyDataProvider()); } @Override public Project getProject() { assert myProject != null : "setUp() should be called first"; return myProject; } @Override public Module getModule() { Module[] modules = ModuleManager.getInstance(getProject()).getModules(); return modules.length == 0 ? null : modules[0]; } private class MyDataProvider implements DataProvider { @Override @Nullable public Object getData(@NonNls String dataId) { if (CommonDataKeys.PROJECT.is(dataId)) { return myProject; } else if (PlatformDataKeys.EDITOR.is(dataId) || OpenFileDescriptor.NAVIGATE_IN_EDITOR.is(dataId)) { if (myProject == null) return null; return FileEditorManager.getInstance(myProject).getSelectedTextEditor(); } else { Editor editor = (Editor)getData(PlatformDataKeys.EDITOR.getName()); if (editor != null) { FileEditorManagerEx manager = FileEditorManagerEx.getInstanceEx(myProject); return manager.getData(dataId, editor, editor.getCaretModel().getCurrentCaret()); } else if (LangDataKeys.IDE_VIEW.is(dataId)) { VirtualFile[] contentRoots = ProjectRootManager.getInstance(myProject).getContentRoots(); final PsiDirectory psiDirectory = PsiManager.getInstance(myProject).findDirectory(contentRoots[0]); if (contentRoots.length > 0) { return new IdeView() { @Override public void selectElement(PsiElement element) { } @Override public PsiDirectory[] getDirectories() { return new PsiDirectory[] {psiDirectory}; } @Override public PsiDirectory getOrChooseDirectory() { return psiDirectory; } }; } } return null; } } } @Override public PsiFile addFileToProject(@NonNls String rootPath, @NonNls final String relativePath, @NonNls final String fileText) throws IOException { final VirtualFile dir = VfsUtil.createDirectories(rootPath + "/" + PathUtil.getParentPath(relativePath)); final VirtualFile[] virtualFile = new VirtualFile[1]; new WriteCommandAction.Simple(getProject()) { @Override protected void run() throws Throwable { virtualFile[0] = dir.createChildData(this, StringUtil.getShortName(relativePath, '/')); VfsUtil.saveText(virtualFile[0], fileText); } }.execute(); return ApplicationManager.getApplication().runReadAction(new Computable<PsiFile>() { public PsiFile compute() { return PsiManager.getInstance(getProject()).findFile(virtualFile[0]); } }); } }