/* * Copyright 2000-2016 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.openapi.roots; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.IoTestUtil; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.testFramework.PlatformTestCase; import com.intellij.testFramework.PsiTestUtil; import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.IOException; public class ProjectRootUtilSymlinkedFilesTest extends PlatformTestCase { private File myNonContentDir; private File myNonContentFile; private VirtualFile myNonContentVFile; private File myContentDir; private VirtualFile myContentVDir; private File myLibraryDir; private VirtualFile myLibraryVDir; @Override protected boolean shouldRunTest() { return super.shouldRunTest() && SystemInfo.areSymLinksSupported; } @Override public void setUp() throws Exception { super.setUp(); myNonContentDir = FileUtil.createTempDirectory("nonContent", null); myNonContentFile = new File(myNonContentDir, "foo.txt"); assertTrue(myNonContentFile.createNewFile()); myNonContentVFile = VfsUtil.findFileByIoFile(myNonContentFile, true); assertNotNull(myNonContentVFile); myContentDir = FileUtil.createTempDirectory("content", null); myContentVDir = VfsUtil.findFileByIoFile(myContentDir, true); assertNotNull(myContentVDir); PsiTestUtil.addContentRoot(getModule(), myContentVDir); myLibraryDir = FileUtil.createTempDirectory("library", null); myLibraryVDir = VfsUtil.findFileByIoFile(myLibraryDir, true); assertNotNull(myLibraryVDir); PsiTestUtil.addLibrary(getModule(), myLibraryVDir.getPath()); } public void testNoFilesInContent() throws Exception { assertEquals(myNonContentVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), myNonContentVFile)); } public void testLinkedDirInContent() throws Exception { doTestLinkedDirInProjectRoots(true); } public void testLinkedDirInLibrary() throws Exception { doTestLinkedDirInProjectRoots(false); } public void doTestLinkedDirInProjectRoots(boolean content) throws Exception { String linkedPath = (content ? myContentDir : myLibraryDir).getPath() + "/linked"; IoTestUtil.createSymLink(myNonContentDir.getPath(), linkedPath, true); VirtualFile linkedVFile = VfsUtil.findFileByIoFile(new File(linkedPath, myNonContentFile.getName()), true); assertEquals(linkedVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), myNonContentVFile)); } // not supported public void _testLinkedFileInSources() throws Exception { String linkedPath = myContentDir.getPath() + "/linked.txt"; IoTestUtil.createSymLink(myNonContentVFile.getPath(), linkedPath, true); VirtualFile linkedVFile = VfsUtil.findFileByIoFile(new File(linkedPath), true); assertEquals(linkedVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), myNonContentVFile)); } public void testFileWithTheSameNotButNotLinked() throws Exception { new WriteAction<Object>() { @Override protected void run(@NotNull Result<Object> result) throws Throwable { myContentVDir.createChildData(this, myNonContentFile.getName()); } }.execute(); assertEquals(myNonContentVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), myNonContentVFile)); } public void testWhenSeveralLinkedAlwaysReturnTheSameFile() throws Exception { String linkedPath1 = myContentDir.getPath() + "/linked1"; IoTestUtil.createSymLink(myNonContentDir.getPath(), linkedPath1, true); VirtualFile linkedVFile1 = VfsUtil.findFileByIoFile(new File(linkedPath1, myNonContentFile.getName()), true); assertNotNull(linkedVFile1); String linkedPath2 = myContentDir.getPath() + "/linked2"; IoTestUtil.createSymLink(myNonContentDir.getPath(), linkedPath2, true); VirtualFile linkedVFile2 = VfsUtil.findFileByIoFile(new File(linkedPath2, myNonContentFile.getName()), true); assertNotNull(linkedVFile2); VirtualFile found = ProjectRootUtil.findSymlinkedFileInContent(getProject(), myNonContentVFile); assertTrue(found.equals(linkedVFile1) || found.equals(linkedVFile2)); for(int i = 0; i < 10; i++) { assertEquals("try: " + i, found, ProjectRootUtil.findSymlinkedFileInContent(getProject(), myNonContentVFile)); } } public void testLinkedAndCanonicalUnderContent() throws Exception { doTestLinkedAndCanonicalUnderRoot(true); } public void testLinkedAndCanonicalUnderLibraryRoot() throws Exception { doTestLinkedAndCanonicalUnderRoot(false); } private void doTestLinkedAndCanonicalUnderRoot(boolean content) throws InterruptedException, IOException { String linkedPath = myContentDir.getPath() + "/linked"; IoTestUtil.createSymLink(myNonContentDir.getPath(), linkedPath, true); VirtualFile linkedVFile = VfsUtil.findFileByIoFile(new File(linkedPath, myNonContentFile.getName()), true); assertEquals(linkedVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), myNonContentVFile)); if(content) { PsiTestUtil.addContentRoot(getModule(), myNonContentVFile.getParent()); } else { PsiTestUtil.addLibrary(getModule(), myNonContentVFile.getParent().getPath()); } assertEquals(myNonContentVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), myNonContentVFile)); } public void testLinkedFileNotUnderTheContentRoot() throws Exception { File nonContentDir = FileUtil.createTempDirectory("nonContent2", null); String nonContentLinkedPath = nonContentDir + "/linked"; IoTestUtil.createSymLink(myNonContentDir.getPath(), nonContentLinkedPath, true); VirtualFile nonContentLinkedVFile = VfsUtil.findFileByIoFile(new File(nonContentLinkedPath, myNonContentFile.getName()), true); assertEquals(nonContentLinkedVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), nonContentLinkedVFile)); String contentLinkedPath = myContentDir + "/linked"; IoTestUtil.createSymLink(myNonContentDir.getPath(), contentLinkedPath, true); VirtualFile contentLinkedVFile = VfsUtil.findFileByIoFile(new File(contentLinkedPath, myNonContentFile.getName()), true); assertEquals(contentLinkedVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), myNonContentVFile)); assertEquals(contentLinkedVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), nonContentLinkedVFile)); assertEquals(contentLinkedVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), contentLinkedVFile)); } }