diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/PathMacroManagerTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/PathMacroManagerTest.java index fe12d0b37a78..ab25313ba006 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/PathMacroManagerTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/PathMacroManagerTest.java @@ -18,19 +18,25 @@ package com.intellij.openapi.components.impl; import com.intellij.application.options.PathMacrosImpl; import com.intellij.application.options.ReplacePathToMacroMap; import com.intellij.mock.MockFileSystem; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.PathMacros; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.application.ex.ApplicationEx; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.ex.ProjectEx; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.vfs.VirtualFileSystem; import com.intellij.util.SystemProperties; import com.intellij.util.io.fs.FileSystem; import com.intellij.util.io.fs.IFileSystem; import org.hamcrest.Description; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jmock.Expectations; import org.jmock.Mockery; @@ -45,6 +51,8 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.picocontainer.PicoContainer; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import static org.hamcrest.core.Is.is; @@ -62,19 +70,21 @@ public class PathMacroManagerTest { private Module myModule; private ProjectEx myProject; private PathMacrosImpl myPathMacros; - private Mockery context = new JUnit4Mockery(); - { - context.setImposteriser(ClassImposteriser.INSTANCE); - } + private Mockery context; protected ApplicationEx myApplication; private IFileSystem myOldFileSystem; protected MockFileSystem myFileSystem; protected PicoContainer myAppPico; + protected Disposable myTestRunLifetime; @Before public final void setupApplication() throws Exception { + context = new JUnit4Mockery(); + context.setImposteriser(ClassImposteriser.INSTANCE); + myTestRunLifetime = Disposer.newDisposable(); myApplication = context.mock(ApplicationEx.class, "application"); + ApplicationManager.setApplication(myApplication, myTestRunLifetime); myAppPico = context.mock(PicoContainer.class); context.checking(new Expectations() { @@ -119,30 +129,71 @@ public class PathMacroManagerTest { FileSystem.FILE_SYSTEM = myOldFileSystem; } + @After + public final void disposeLifetime() { + Disposer.dispose(myTestRunLifetime); + } + + private VirtualFile setUpVirtualFiles(final @NotNull Expectations e, + final @NotNull String path, final @NotNull VirtualFile lowestChild, final @NotNull VirtualFileSystem virtualFileSystem) { + final ArrayList components = new ArrayList(Arrays.asList(path.split("/"))); + VirtualFile prevChild = lowestChild; + VirtualFile fileForPath = null; + for (int i = components.size() - 1; i >= 0; i--) { + final String curPath = "/" + StringUtil.join(components, "/"); + final String curPathWithSlash = curPath + "/"; + components.remove(components.size() - 1); + final VirtualFile mock = context.mock(VirtualFile.class, curPath.replace("/", "")); + if (fileForPath == null) + fileForPath = mock; + e.allowing(prevChild).getParent(); + e.will(Expectations.returnValue(mock)); + e.allowing(mock).getPath(); + e.will(Expectations.returnValue(curPath)); + + e.allowing(virtualFileSystem).findFileByPath(e.with(Expectations.equal(curPathWithSlash))); + e.will(Expectations.returnValue(mock)); + e.allowing(virtualFileSystem).findFileByPath(e.with(Expectations.equal(curPath))); + e.will(Expectations.returnValue(mock)); + prevChild = mock; + } + e.allowing(prevChild).getParent(); e.will(Expectations.returnValue(null)); + return fileForPath; + } + + private void setUpMocks(final String projectPath) { myModule = context.mock(Module.class); myPathMacros = context.mock(PathMacrosImpl.class); myProject = context.mock(ProjectEx.class); final VirtualFile projectFile = context.mock(VirtualFile.class, "projectFile"); - final VirtualFile projectParentFile = context.mock(VirtualFile.class, "projectParentFile"); + //final VirtualFile projectParentFile = context.mock(VirtualFile.class, "projectParentFile"); final VirtualFile moduleFile = context.mock(VirtualFile.class, "moduleFile"); final VirtualFile moduleParentFile = context.mock(VirtualFile.class, "moduleParentFile"); + final VirtualFileManager virtualFileManager = context.mock(VirtualFileManager.class, projectPath + "virtualFileManager"); + final VirtualFileSystem virtualFileSystem = context.mock(VirtualFileSystem.class, projectPath + "virtualFileSystem"); + context.checking(new Expectations() {{ allowing(myModule).isDisposed(); will(returnValue(false)); allowing(myProject).isDisposed(); will(returnValue(false)); allowing(projectFile).getPath(); will(returnValue(projectPath)); - allowing(projectFile).getParent(); will(returnValue(projectParentFile)); - allowing(projectParentFile).getPath(); will(returnValue(StringUtil.getPackageName(projectPath, '/'))); + final VirtualFile projectDir = setUpVirtualFiles(this, projectPath, projectFile, virtualFileSystem); + final String moduleFilePath = projectPath + "/module/module.iml"; allowing(moduleFile).getPath(); will(returnValue(moduleFilePath)); allowing(moduleFile).getParent(); will(returnValue(moduleParentFile)); - allowing(projectParentFile).getPath(); will(returnValue(StringUtil.getPackageName(moduleFilePath, '/'))); + allowing(moduleParentFile).getPath(); will(returnValue(projectPath + "/module")); + allowing(moduleParentFile).getParent(); will(returnValue(projectDir)); allowing(myApplication).getComponent(with(equal(PathMacros.class))); will(returnValue(myPathMacros)); + allowing(myApplication).getComponent(with(equal(VirtualFileManager.class))); will(returnValue(virtualFileManager)); + allowing(virtualFileManager).getFileSystem(with(equal("file"))); will(returnValue(virtualFileSystem)); + allowing(virtualFileSystem).findFileByPath(with(equal(projectPath + "/module"))); will(returnValue(moduleParentFile)); + allowing(myPathMacros).addMacroReplacements(with(any(ReplacePathToMacroMap.class))); allowing(myProject).getBaseDir(); will(returnValue(projectFile)); @@ -153,8 +204,6 @@ public class PathMacroManagerTest { @Test public void testRightMacrosOrder_RelativeValues_NoVariables() throws Exception { - assumeThat(SystemInfo.isWindows, is(false)); - setUpMocks("/tmp/foo"); final ReplacePathToMacroMap replacePathMap = new ModulePathMacroManager(myPathMacros, myModule).getReplacePathMap(); @@ -198,8 +247,6 @@ public class PathMacroManagerTest { @Test public void testPathsOutsideProject() throws Exception { - assumeThat(SystemInfo.isWindows, is(false)); - setUpMocks("/tmp/foo"); final ReplacePathToMacroMap replacePathMap = new ProjectPathMacroManager(myPathMacros, myProject).getReplacePathMap(); @@ -236,8 +283,6 @@ public class PathMacroManagerTest { @Test public void testProjectUnderUserHome() throws Exception { - assumeThat(SystemInfo.isWindows, is(false)); - setUpMocks(USER_HOME + "/IdeaProjects/foo"); final ReplacePathToMacroMap replacePathMap = new ModulePathMacroManager(myPathMacros, myModule).getReplacePathMap(); diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/BasePathMacroManager.java b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/BasePathMacroManager.java index b189459bb466..624eabc27fb9 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/BasePathMacroManager.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/BasePathMacroManager.java @@ -26,6 +26,8 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.StandardFileSystems; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.vfs.VirtualFileSystem; import com.intellij.util.containers.FactoryMap; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -42,7 +44,7 @@ public class BasePathMacroManager extends PathMacroManager { protected static void addFileHierarchyReplacements(ExpandMacroToPathMap result, String macroName, @Nullable String path) { if (path == null) return; - addFileHierarchyReplacements(result, StandardFileSystems.local().findFileByPath(path), "$" + macroName + "$"); + addFileHierarchyReplacements(result, getLocalFileSystem().findFileByPath(path), "$" + macroName + "$"); } private static void addFileHierarchyReplacements(ExpandMacroToPathMap result, @Nullable VirtualFile f, String macro) { @@ -63,7 +65,7 @@ public class BasePathMacroManager extends PathMacroManager { if (path == null) return; String macro = "$" + macroName + "$"; - VirtualFile dir = StandardFileSystems.local().findFileByPath(path); + VirtualFile dir = getLocalFileSystem().findFileByPath(path); boolean check = false; while (dir != null && dir.getParent() != null) { path = dir.getPath(); @@ -88,6 +90,11 @@ public class BasePathMacroManager extends PathMacroManager { } } + private static VirtualFileSystem getLocalFileSystem() { + // Use VFM directly because of mocks in tests. + return VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL); + } + private static void putIfAbsent(final ReplacePathToMacroMap result, @NonNls final String pathWithPrefix, @NonNls final String substitutionWithPrefix,