test for VfsUtil.findRelativeFile(uri, base)
[idea/community.git] / platform / platform-tests / testSrc / com / intellij / openapi / vfs / VfsUtilTest.java
1 /*
2  * Copyright 2000-2015 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.openapi.vfs;
17
18 import com.intellij.openapi.application.ApplicationManager;
19 import com.intellij.openapi.application.Result;
20 import com.intellij.openapi.application.WriteAction;
21 import com.intellij.openapi.application.ex.PathManagerEx;
22 import com.intellij.openapi.util.SystemInfo;
23 import com.intellij.openapi.util.io.FileUtil;
24 import com.intellij.openapi.util.io.IoTestUtil;
25 import com.intellij.openapi.vfs.newvfs.ManagingFS;
26 import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
27 import com.intellij.testFramework.PlatformTestCase;
28 import com.intellij.testFramework.UsefulTestCase;
29 import com.intellij.testFramework.vcs.DirectoryData;
30 import com.intellij.util.ThrowableRunnable;
31 import com.intellij.util.TimeoutUtil;
32 import com.intellij.util.concurrency.Semaphore;
33 import org.jetbrains.annotations.NotNull;
34
35 import java.io.File;
36 import java.io.IOException;
37 import java.net.URI;
38 import java.net.URL;
39 import java.nio.charset.Charset;
40 import java.util.Collections;
41 import java.util.List;
42
43 public class VfsUtilTest extends PlatformTestCase {
44   @Override
45   protected boolean isRunInEdt() {
46     return false;
47   }
48
49   @Override
50   protected boolean isRunInWriteAction() {
51     return false;
52   }
53
54   @Override
55   protected void setUp() throws Exception {
56     invokeAndWaitIfNeeded(new ThrowableRunnable<Exception>() {
57       @Override
58       public void run() throws Exception {
59         VfsUtilTest.super.setUp();
60       }
61     });
62   }
63
64   @Override
65   protected void tearDown() throws Exception {
66     invokeAndWaitIfNeeded(new ThrowableRunnable<Exception>() {
67       @Override
68       public void run() throws Exception {
69         VfsUtilTest.super.tearDown();
70       }
71     });
72   }
73
74   public void testFixIdeaUrl() {
75     assertEquals("file:/C:/Temp/README.txt", VfsUtilCore.fixIDEAUrl("file://C:/Temp/README.txt"));
76     assertEquals("file:/C:/Temp/README.txt", VfsUtilCore.fixIDEAUrl("file:///C:/Temp/README.txt"));
77     assertEquals("file:/tmp/foo.bar", VfsUtilCore.fixIDEAUrl("file:///tmp/foo.bar"));
78   }
79
80   public void testFindFileByUrl() throws Exception {
81     File file1 = new File(PathManagerEx.getTestDataPath());
82     file1 = new File(file1, "vfs");
83     file1 = new File(file1, "findFileByUrl");
84     VirtualFile file0 = VfsUtil.findFileByURL(file1.toURI().toURL());
85     assertNotNull(file0);
86     assertTrue(file0.isDirectory());
87     List<VirtualFile> list = VfsUtil.getChildren(file0, new VirtualFileFilter() {
88       @Override
89       public boolean accept(VirtualFile file) {
90         return !file.getName().endsWith(".new");
91       }
92     });
93     assertEquals(2, list.size());     // "CVS" dir ignored
94
95     File file2 = new File(file1, "test.zip");
96     URL url2 = file2.toURI().toURL();
97
98     url2 = new URL("jar", "", url2.toExternalForm() + "!/");
99     file0 = VfsUtil.findFileByURL(url2);
100     assertNotNull(file0);
101     assertTrue(file0.isDirectory());
102
103     url2 = new URL(url2, "com/intellij/installer");
104     file0 = VfsUtil.findFileByURL(url2);
105     assertNotNull(file0);
106     assertTrue(file0.isDirectory());
107
108     File file3 = new File(file1, "1.txt");
109     file0 = VfsUtil.findFileByURL(file3.toURI().toURL());
110     String content = VfsUtilCore.loadText(file0);
111     assertNotNull(file0);
112     assertFalse(file0.isDirectory());
113     assertEquals("test text", content);
114   }
115
116   public void testFindRelativeFile() throws Exception {
117     final VirtualFile root = VirtualFileManager.getInstance().findFileByUrl("temp:///");
118     assertNotNull(root);
119     VirtualFile file = VfsUtilCore.findRelativeFile(root.getUrl(), null);
120     assertEquals(root, file);
121
122     File ioTestDataDir = new File(PathManagerEx.getTestDataPath());
123     VirtualFile testDataDir = LocalFileSystem.getInstance().findFileByIoFile(ioTestDataDir);
124     assertNotNull(testDataDir);
125     assertEquals(testDataDir, VfsUtilCore.findRelativeFile(VfsUtilCore.convertFromUrl(ioTestDataDir.toURI().toURL()), null));
126     assertEquals(testDataDir, VfsUtilCore.findRelativeFile(ioTestDataDir.getAbsolutePath(), null));
127
128     File ioVfsDir = new File(ioTestDataDir, "vfs");
129     VirtualFile vfsDir = LocalFileSystem.getInstance().findFileByIoFile(ioVfsDir);
130     assertNotNull(vfsDir);
131     assertEquals(vfsDir, VfsUtilCore.findRelativeFile(ioVfsDir.getAbsolutePath(), null));
132     assertEquals(vfsDir, VfsUtilCore.findRelativeFile("vfs", testDataDir));
133   }
134
135   public void testRelativePath() throws Exception {
136     final File root = new File(PathManagerEx.getTestDataPath());
137     final File testRoot = new File(new File(root, "vfs"), "relativePath");
138     VirtualFile vTestRoot = LocalFileSystem.getInstance().findFileByIoFile(testRoot);
139     assertNotNull(vTestRoot);
140     assertTrue(vTestRoot.isDirectory());
141
142     final File subDir = new File(testRoot, "subDir");
143     final VirtualFile vSubDir = LocalFileSystem.getInstance().findFileByIoFile(subDir);
144     assertNotNull(vSubDir);
145
146     final File subSubDir = new File(subDir, "subSubDir");
147     final VirtualFile vSubSubDir = LocalFileSystem.getInstance().findFileByIoFile(subSubDir);
148     assertNotNull(vSubSubDir);
149
150     assertEquals("subDir", VfsUtilCore.getRelativePath(vSubDir, vTestRoot, '/'));
151     assertEquals("subDir/subSubDir", VfsUtilCore.getRelativePath(vSubSubDir, vTestRoot, '/'));
152     assertEquals("", VfsUtilCore.getRelativePath(vTestRoot, vTestRoot, '/'));
153   }
154
155   public void testVisitRecursively() throws Exception {
156     final DirectoryData data = new DirectoryData(myProject.getBaseDir());
157     try {
158       data.clear();
159       data.create();
160
161       final File subDir = new File(data.getBase().getPath(), "DL0N1");
162       final VirtualFile vSubDir = LocalFileSystem.getInstance().findFileByIoFile(subDir);
163       assertNotNull(vSubDir);
164
165       VfsUtilCore.visitChildrenRecursively(data.getBase(), new VirtualFileVisitor() {
166         @Override
167         public boolean visitFile(@NotNull VirtualFile file) {
168           assertTrue(!VfsUtilCore.isAncestor(vSubDir, file, true));
169           return !vSubDir.equals(file);
170         }
171       });
172     }
173     finally {
174       data.clear();
175     }
176   }
177
178   public void testFindChildWithTrailingSpace() throws IOException {
179     File tempDir = createTempDirectory();
180     VirtualFile vDir = LocalFileSystem.getInstance().findFileByIoFile(tempDir);
181     assertNotNull(vDir);
182     assertTrue(vDir.isDirectory());
183
184     VirtualFile child = vDir.findChild(" ");
185     assertNull(child);
186
187     UsefulTestCase.assertEmpty(vDir.getChildren());
188   }
189
190   public void testDirAttributeRefreshes() throws IOException {
191     File tempDir = createTempDirectory();
192     VirtualFile vDir = refreshAndFindFile(tempDir);
193     assertNotNull(vDir);
194     assertTrue(vDir.isDirectory());
195
196     File file = FileUtil.createTempFile(tempDir, "xxx", "yyy", true);
197     assertNotNull(file);
198     VirtualFile vFile = refreshAndFindFile(file);
199     assertNotNull(vFile);
200     assertFalse(vFile.isDirectory());
201
202     boolean deleted = file.delete();
203     assertTrue(deleted);
204     boolean created = file.mkdir();
205     assertTrue(created);
206     assertTrue(file.exists());
207
208     VirtualFile vFile2 = refreshAndFindFile(file);
209     assertNotNull(vFile2);
210     assertTrue(vFile2.isDirectory());
211   }
212
213   public void testPresentableUrlSurvivesDeletion() throws IOException {
214     final VirtualFile file = createTempFile("txt", null, "content", Charset.defaultCharset());
215     String url = file.getPresentableUrl();
216     assertNotNull(url);
217     new WriteAction() {
218       @Override
219       protected void run(@NotNull Result result) throws Throwable {
220         file.delete(this);
221       }
222     }.execute();
223     assertEquals(url, file.getPresentableUrl());
224   }
225
226   public void testToUri() {
227     if (!SystemInfo.isWindows) {
228       assertEquals("file:///asd", VfsUtil.toUri(new File("/asd")).toASCIIString());
229       assertEquals("file:///asd%20/sd", VfsUtil.toUri(new File("/asd /sd")).toASCIIString());
230     }
231
232     URI uri = VfsUtil.toUri("file:///asd");
233     assertNotNull(uri);
234     assertEquals("file", uri.getScheme());
235     assertEquals("/asd", uri.getPath());
236
237     uri = VfsUtil.toUri("file:///asd/ ads/ad#test");
238     assertNotNull(uri);
239     assertEquals("file", uri.getScheme());
240     assertEquals("/asd/ ads/ad", uri.getPath());
241     assertEquals("test", uri.getFragment());
242
243     uri = VfsUtil.toUri("file:///asd/ ads/ad#");
244     assertNotNull(uri);
245     assertEquals("file:///asd/%20ads/ad#", uri.toString());
246
247     uri = VfsUtil.toUri("mailto:someone@example.com");
248     assertNotNull(uri);
249     assertEquals("someone@example.com", uri.getSchemeSpecificPart());
250
251     if (SystemInfo.isWindows) {
252       uri = VfsUtil.toUri("file://C:/p");
253       assertNotNull(uri);
254       assertEquals("file", uri.getScheme());
255       assertEquals("/C:/p", uri.getPath());
256     }
257
258     uri = VfsUtil.toUri("file:///Users/S pace");
259     assertNotNull(uri);
260     assertEquals("file", uri.getScheme());
261     assertEquals("/Users/S pace", uri.getPath());
262     assertEquals("/Users/S%20pace", uri.getRawPath());
263     assertEquals("file:///Users/S%20pace", uri.toString());
264
265     uri = VfsUtil.toUri("http://developer.android.com/guide/developing/tools/avd.html");
266     assertNotNull(uri);
267     assertEquals("http", uri.getScheme());
268     assertEquals("/guide/developing/tools/avd.html", uri.getRawPath());
269     assertEquals("http://developer.android.com/guide/developing/tools/avd.html", uri.toString());
270
271     uri = VfsUtil.toUri("http://developer.android.com/guide/developing/tools/avd.html?f=23r2ewd");
272     assertNotNull(uri);
273     assertEquals("http", uri.getScheme());
274     assertEquals("/guide/developing/tools/avd.html", uri.getRawPath());
275     assertEquals("http://developer.android.com/guide/developing/tools/avd.html?f=23r2ewd", uri.toString());
276     assertEquals("f=23r2ewd", uri.getQuery());
277   }
278
279   public void testIsAncestor() {
280     assertTrue(VfsUtilCore.isEqualOrAncestor("file:///my/dir", "file:///my/dir"));
281     assertTrue(VfsUtilCore.isEqualOrAncestor("file:///my/dir", "file:///my/dir/file.txt"));
282     assertTrue(VfsUtilCore.isEqualOrAncestor("file:///my/dir/", "file:///my/dir/file.txt"));
283     assertFalse(VfsUtilCore.isEqualOrAncestor("file:///my/dir2", "file:///my/dir/file.txt"));
284     assertFalse(VfsUtilCore.isEqualOrAncestor("file:///my/dir", "file:///my/dir2"));
285     assertFalse(VfsUtilCore.isEqualOrAncestor("file:///my/dir/", "file:///my/dir2"));
286   }
287
288   public void testFindRootWithDenormalizedPath() throws IOException {
289     File tempJar = IoTestUtil.createTestJar();
290     VirtualFile jar = refreshAndFindFile(tempJar);
291     assertNotNull(jar);
292
293     JarFileSystem fs = JarFileSystem.getInstance();
294     NewVirtualFile root1 = ManagingFS.getInstance().findRoot(jar.getPath() + "!/", fs);
295     NewVirtualFile root2 = ManagingFS.getInstance().findRoot(jar.getParent().getPath() + "//" + jar.getName() + "!/", fs);
296     assertNotNull(root1);
297     assertSame(root1, root2);
298   }
299
300   public void testNotCanonicallyNamedChild() throws IOException {
301     File tempDir = createTempDirectory();
302     assertTrue(new File(tempDir, "libFiles").createNewFile());
303     assertTrue(new File(tempDir, "CssInvalidElement").createNewFile());
304     assertTrue(new File(tempDir, "extFiles").createNewFile());
305
306     VirtualFile vDir = refreshAndFindFile(tempDir);
307     assertNotNull(vDir);
308     assertTrue(vDir.isDirectory());
309
310     assertNotNull(vDir.findChild("libFiles"));
311     assertNotNull(vDir.findChild("CssInvalidElement"));
312
313     assertNotNull(vDir.findChild("extFiles"));
314     assertNotNull(vDir.findChild("/extFiles/"));
315     assertNotNull(vDir.findChild("extFiles/"));
316     assertNotNull(vDir.findChild("/extFiles"));
317     assertNotNull(vDir.findChild("//extFiles"));
318     assertNotNull(vDir.findChild("extFiles///"));
319
320     assertNull(vDir.findChild("/xxx/extFiles/"));
321     assertNull(vDir.findChild("xxx/extFiles/"));
322     assertNull(vDir.findChild("/xxx/extFiles"));
323     assertNull(vDir.findChild("xxx/extFiles"));
324     assertNull(vDir.findChild("xxx//extFiles"));
325   }
326
327   public void testRenameDuringFullRefresh() throws IOException { doRenameAndRefreshTest(true); }
328   public void testRenameDuringPartialRefresh() throws IOException { doRenameAndRefreshTest(false); }
329
330   private void doRenameAndRefreshTest(boolean full) throws IOException {
331     assertFalse(ApplicationManager.getApplication().isDispatchThread());
332
333     File tempDir = createTempDirectory();
334     assertTrue(new File(tempDir, "child").createNewFile());
335
336     VirtualFile parent = refreshAndFindFile(tempDir);
337     assertNotNull(parent);
338     if (full) {
339       assertEquals(1, parent.getChildren().length);
340     }
341     final VirtualFile child = parent.findChild("child");
342     assertNotNull(child);
343
344     List<VirtualFile> files = Collections.singletonList(parent);
345
346     final Semaphore semaphore = new Semaphore();
347     for (int i = 0; i < 1000; i++) {
348       semaphore.down();
349       VfsUtil.markDirty(true, false, parent);
350       LocalFileSystem.getInstance().refreshFiles(files, true, true, new Runnable() {
351         @Override
352         public void run() {
353           semaphore.up();
354         }
355       });
356
357       assertTrue(child.isValid());
358       final String newName = "name" + i;
359       new WriteAction() {
360         @Override
361         protected void run(@NotNull Result result) throws Throwable {
362           child.rename(this, newName);
363         }
364       }.execute();
365       assertTrue(child.isValid());
366
367       TimeoutUtil.sleep(1);  // needed to prevent frequent event detector from triggering
368     }
369
370     assertTrue(semaphore.waitFor(60000));
371   }
372 }