From aed9f7750b030511935c153d667a94e9391676e9 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 24 Dec 2014 12:42:52 +0100 Subject: [PATCH] vfs: consistency checks on file operations --- .../testFramework/ResolveTestCase.java | 61 +++-- .../psi/impl/file/PsiDirectoryImpl.java | 2 +- .../vfs/impl/local/LocalFileSystemBase.java | 250 ++++++++++++------ .../src/messages/VfsBundle.properties | 25 +- .../vfs/local/LocalFileSystemTest.java | 43 ++- .../intellij/testFramework/VfsTestUtil.java | 10 +- .../vcs/AbstractVcsTestCase.java | 2 +- .../com/intellij/openapi/vcs/VcsTestUtil.java | 2 +- .../git4idea/tests/GitChangeProviderTest.java | 4 +- 9 files changed, 284 insertions(+), 115 deletions(-) diff --git a/java/testFramework/src/com/intellij/testFramework/ResolveTestCase.java b/java/testFramework/src/com/intellij/testFramework/ResolveTestCase.java index e2cebe40700a..865a6f76ed30 100644 --- a/java/testFramework/src/com/intellij/testFramework/ResolveTestCase.java +++ b/java/testFramework/src/com/intellij/testFramework/ResolveTestCase.java @@ -1,6 +1,5 @@ - /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -17,49 +16,75 @@ package com.intellij.testFramework; import com.intellij.openapi.application.ex.PathManagerEx; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiManager; import com.intellij.psi.PsiReference; -import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; public abstract class ResolveTestCase extends PsiTestCase { - @NonNls protected static final String MARKER = ""; + protected static final String MARKER = ""; - protected PsiReference configureByFile(@NonNls String filePath) throws Exception{ + private Document myDocument; + + @Override + protected void tearDown() throws Exception { + if (myDocument != null) { + FileDocumentManager.getInstance().reloadFromDisk(myDocument); + } + + super.tearDown(); + } + + protected PsiReference configureByFile(@NotNull String filePath) throws Exception { return configureByFile(filePath, null); } - - protected PsiReference configureByFile(@TestDataFile @NonNls String filePath, @Nullable VirtualFile parentDir) throws Exception{ + + protected PsiReference configureByFile(@TestDataFile @NotNull String filePath, @Nullable VirtualFile parentDir) throws Exception { final String fullPath = getTestDataPath() + filePath; final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/')); assertNotNull("file " + filePath + " not found", vFile); - String fileText = StringUtil.convertLineSeparators(VfsUtil.loadText(vFile)); - - final String fileName = vFile.getName(); - - return configureByFileText(fileText, fileName, parentDir); + String fileText = StringUtil.convertLineSeparators(VfsUtilCore.loadText(vFile)); + return configureByFileText(fileText, vFile.getName(), parentDir); } protected PsiReference configureByFileText(String fileText, String fileName) throws Exception { return configureByFileText(fileText, fileName, null); } - - protected PsiReference configureByFileText(String fileText, String fileName, @Nullable final VirtualFile parentDir) throws Exception { + + protected PsiReference configureByFileText(String fileText, String fileName, @Nullable VirtualFile parentDir) throws Exception { int offset = fileText.indexOf(MARKER); assertTrue(offset >= 0); fileText = fileText.substring(0, offset) + fileText.substring(offset + MARKER.length()); - myFile = parentDir == null? createFile(myModule, fileName, fileText) : createFile(myModule, parentDir, fileName, fileText); + if (parentDir == null) { + myFile = createFile(myModule, fileName, fileText); + } + else { + VirtualFile existing = parentDir.findChild(fileName); + if (existing != null) { + myDocument = FileDocumentManager.getInstance().getDocument(existing); + assertNotNull(myDocument); + myDocument.setText(fileText); + myFile = PsiManager.getInstance(getProject()).findFile(existing); + assertNotNull(myFile); + assertEquals(fileText, myFile.getText()); + } + else { + myFile = createFile(myModule, parentDir, fileName, fileText); + } + } + PsiReference ref = myFile.findReferenceAt(offset); - assertNotNull(ref); - return ref; } diff --git a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java index e0ed0dd9182e..8bdd768c91f1 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java @@ -150,7 +150,7 @@ public class PsiDirectoryImpl extends PsiElementBase implements PsiDirectory, Qu CheckUtil.checkWritable(this); VirtualFile parentFile = myFile.getParent(); if (parentFile == null) { - throw new IncorrectOperationException(VfsBundle.message("cannot.rename.root.directory")); + throw new IncorrectOperationException(VfsBundle.message("cannot.rename.root.directory", myFile.getPath())); } VirtualFile child = parentFile.findChild(name); if (child != null && !child.equals(myFile)) { diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java index 9ed819cdd1aa..51ded3f9e4cb 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java @@ -32,7 +32,6 @@ import com.intellij.openapi.vfs.newvfs.RefreshQueue; import com.intellij.openapi.vfs.newvfs.VfsImplUtil; import com.intellij.openapi.vfs.newvfs.impl.FakeVirtualFile; import com.intellij.util.ArrayUtil; -import com.intellij.util.PathUtil; import com.intellij.util.Processor; import com.intellij.util.ThrowableConsumer; import com.intellij.util.containers.ContainerUtil; @@ -341,19 +340,12 @@ public abstract class LocalFileSystemBase extends LocalFileSystem { return false; } - private void auxNotifyCompleted(@NotNull ThrowableConsumer consumer) { - for (LocalFileOperationsHandler handler : myHandlers) { - handler.afterDone(consumer); - } - } - - @Nullable - private File auxCopy(@NotNull VirtualFile file, @NotNull VirtualFile toDir, @NotNull String copyName) throws IOException { + private boolean auxCopy(@NotNull VirtualFile file, @NotNull VirtualFile toDir, @NotNull String copyName) throws IOException { for (LocalFileOperationsHandler handler : myHandlers) { final File copy = handler.copy(file, toDir, copyName); - if (copy != null) return copy; + if (copy != null) return true; } - return null; + return false; } private boolean auxRename(@NotNull VirtualFile file, @NotNull String newName) throws IOException { @@ -377,53 +369,97 @@ public abstract class LocalFileSystemBase extends LocalFileSystem { return false; } - private static void delete(@NotNull File physicalFile) throws IOException { - if (!FileUtil.delete(physicalFile)) { - throw new IOException(VfsBundle.message("file.delete.error", physicalFile.getPath())); + private void auxNotifyCompleted(@NotNull ThrowableConsumer consumer) { + for (LocalFileOperationsHandler handler : myHandlers) { + handler.afterDone(consumer); } } @Override @NotNull - public VirtualFile createChildDirectory(final Object requestor, @NotNull final VirtualFile parent, @NotNull final String dir) throws IOException { - final File ioDir = new File(convertToIOFile(parent), dir); - final boolean succeed = auxCreateDirectory(parent, dir) || ioDir.mkdirs(); + public VirtualFile createChildDirectory(Object requestor, @NotNull final VirtualFile parent, @NotNull final String dir) throws IOException { + if (!VirtualFile.isValidName(dir)) { + throw new IOException(VfsBundle.message("directory.invalid.name.error", dir)); + } + + if (!parent.exists() || !parent.isDirectory()) { + throw new IOException(VfsBundle.message("vfs.target.not.directory.error", parent.getPath())); + } + if (parent.findChild(dir) != null) { + throw new IOException(VfsBundle.message("vfs.target.already.exists.error", parent.getPath() + "/" + dir)); + } + + File ioParent = convertToIOFile(parent); + if (!ioParent.isDirectory()) { + throw new IOException(VfsBundle.message("target.not.directory.error", ioParent.getPath())); + } + + if (!auxCreateDirectory(parent, dir)) { + File ioDir = new File(ioParent, dir); + if (!(ioDir.mkdirs() || ioDir.isDirectory())) { + throw new IOException(VfsBundle.message("new.directory.failed.error", ioDir.getPath())); + } + } + auxNotifyCompleted(new ThrowableConsumer() { @Override public void consume(LocalFileOperationsHandler handler) throws IOException { handler.createDirectory(parent, dir); } }); - if (!succeed) { - throw new IOException("Failed to create directory: " + ioDir.getPath()); - } return new FakeVirtualFile(parent, dir); } @NotNull @Override - public VirtualFile createChildFile(final Object requestor, @NotNull final VirtualFile parent, @NotNull final String file) throws IOException { - final File ioFile = new File(convertToIOFile(parent), file); - final boolean succeed = auxCreateFile(parent, file) || FileUtil.createIfDoesntExist(ioFile); + public VirtualFile createChildFile(Object requestor, @NotNull final VirtualFile parent, @NotNull final String file) throws IOException { + if (!VirtualFile.isValidName(file)) { + throw new IOException(VfsBundle.message("file.invalid.name.error", file)); + } + + if (!parent.exists() || !parent.isDirectory()) { + throw new IOException(VfsBundle.message("vfs.target.not.directory.error", parent.getPath())); + } + if (parent.findChild(file) != null) { + throw new IOException(VfsBundle.message("vfs.target.already.exists.error", parent.getPath() + "/" + file)); + } + + File ioParent = convertToIOFile(parent); + if (!ioParent.isDirectory()) { + throw new IOException(VfsBundle.message("target.not.directory.error", ioParent.getPath())); + } + + if (!auxCreateFile(parent, file)) { + File ioFile = new File(ioParent, file); + if (!FileUtil.createIfDoesntExist(ioFile)) { + throw new IOException(VfsBundle.message("new.file.failed.error", ioFile.getPath())); + } + } + auxNotifyCompleted(new ThrowableConsumer() { @Override public void consume(LocalFileOperationsHandler handler) throws IOException { handler.createFile(parent, file); } }); - if (!succeed) { - throw new IOException("Failed to create child file at " + ioFile.getPath()); - } return new FakeVirtualFile(parent, file); } @Override - public void deleteFile(final Object requestor, @NotNull final VirtualFile file) throws IOException { - if (!auxDelete(file)) { - delete(convertToIOFile(file)); + public void deleteFile(Object requestor, @NotNull final VirtualFile file) throws IOException { + if (file.getParent() == null) { + throw new IOException(VfsBundle.message("cannot.delete.root.directory", file.getPath())); } + + if (!auxDelete(file)) { + File ioFile = convertToIOFile(file); + if (!FileUtil.delete(ioFile)) { + throw new IOException(VfsBundle.message("delete.failed.error", ioFile.getPath())); + } + } + auxNotifyCompleted(new ThrowableConsumer() { @Override public void consume(LocalFileOperationsHandler handler) throws IOException { @@ -484,17 +520,41 @@ public abstract class LocalFileSystemBase extends LocalFileSystem { } @Override - public void moveFile(final Object requestor, @NotNull final VirtualFile file, @NotNull final VirtualFile newParent) throws IOException { + public void moveFile(Object requestor, @NotNull final VirtualFile file, @NotNull final VirtualFile newParent) throws IOException { + String name = file.getName(); + + if (!file.exists()) { + throw new IOException(VfsBundle.message("vfs.file.not.exist.error", file.getPath())); + } + if (file.getParent() == null) { + throw new IOException(VfsBundle.message("cannot.rename.root.directory", file.getPath())); + } + if (!newParent.exists() || !newParent.isDirectory()) { + throw new IOException(VfsBundle.message("vfs.target.not.directory.error", newParent.getPath())); + } + if (newParent.findChild(name) != null) { + throw new IOException(VfsBundle.message("vfs.target.already.exists.error", newParent.getPath() + "/" + name)); + } + + File ioFile = convertToIOFile(file); + if (!ioFile.exists()) { + throw new FileNotFoundException(VfsBundle.message("file.not.exist.error", ioFile.getPath())); + } + File ioParent = convertToIOFile(newParent); + if (!ioParent.isDirectory()) { + throw new IOException(VfsBundle.message("target.not.directory.error", ioParent.getPath())); + } + File ioTarget = new File(ioParent, name); + if (ioTarget.exists()) { + throw new IOException(VfsBundle.message("target.already.exists.error", ioTarget.getPath())); + } + if (!auxMove(file, newParent)) { - final File ioFrom = convertToIOFile(file); - final File ioParent = convertToIOFile(newParent); - if (!ioParent.isDirectory()) { - throw new IOException("Target '" + ioParent + "' is not a directory"); - } - if (!ioFrom.renameTo(new File(ioParent, file.getName()))) { - throw new IOException("Move failed: '" + file.getPath() + "' to '" + newParent.getPath() +"'"); + if (!ioFile.renameTo(ioTarget)) { + throw new IOException(VfsBundle.message("move.failed.error", ioFile.getPath(), ioParent.getPath())); } } + auxNotifyCompleted(new ThrowableConsumer() { @Override public void consume(LocalFileOperationsHandler handler) throws IOException { @@ -504,24 +564,39 @@ public abstract class LocalFileSystemBase extends LocalFileSystem { } @Override - public void renameFile(final Object requestor, @NotNull final VirtualFile file, @NotNull final String newName) throws IOException { - if (!file.exists()) { - throw new IOException("File to move does not exist: " + file.getPath()); + public void renameFile(Object requestor, @NotNull final VirtualFile file, @NotNull final String newName) throws IOException { + if (!VirtualFile.isValidName(newName)) { + throw new IOException(VfsBundle.message("file.invalid.name.error", newName)); } - final VirtualFile parent = file.getParent(); - assert parent != null; + boolean sameName = !isCaseSensitive() && newName.equalsIgnoreCase(file.getName()); + + if (!file.exists()) { + throw new IOException(VfsBundle.message("vfs.file.not.exist.error", file.getPath())); + } + VirtualFile parent = file.getParent(); + if (parent == null) { + throw new IOException(VfsBundle.message("cannot.rename.root.directory", file.getPath())); + } + if (!sameName && parent.findChild(newName) != null) { + throw new IOException(VfsBundle.message("vfs.target.already.exists.error", parent.getPath() + "/" + newName)); + } + + File ioFile = convertToIOFile(file); + if (!ioFile.exists()) { + throw new FileNotFoundException(VfsBundle.message("file.not.exist.error", ioFile.getPath())); + } + File ioTarget = new File(convertToIOFile(parent), newName); + if (!sameName && ioTarget.exists()) { + throw new IOException(VfsBundle.message("target.already.exists.error", ioTarget.getPath())); + } if (!auxRename(file, newName)) { - final File target = new File(convertToIOFile(parent), newName); - if (!convertToIOFile(file).renameTo(target)) { - if (target.exists()) { - throw new IOException("Destination already exists: " + parent.getPath() + "/" + newName); - } else { - throw new IOException("Unable to rename " + file.getPath()); - } + if (!ioFile.renameTo(ioTarget)) { + throw new IOException(VfsBundle.message("rename.failed.error", ioFile.getPath(), newName)); } } + auxNotifyCompleted(new ThrowableConsumer() { @Override public void consume(LocalFileOperationsHandler handler) throws IOException { @@ -532,49 +607,62 @@ public abstract class LocalFileSystemBase extends LocalFileSystem { @NotNull @Override - public VirtualFile copyFile(final Object requestor, - @NotNull final VirtualFile vFile, + public VirtualFile copyFile(Object requestor, + @NotNull final VirtualFile file, @NotNull final VirtualFile newParent, @NotNull final String copyName) throws IOException { - if (!PathUtil.isValidFileName(copyName)) { - throw new IOException("Invalid file name: " + copyName); + if (!VirtualFile.isValidName(copyName)) { + throw new IOException(VfsBundle.message("file.invalid.name.error", copyName)); } - FileAttributes attributes = getAttributes(vFile); - if (attributes == null || attributes.isSpecial()) { - throw new FileNotFoundException("Not a file: " + vFile); + if (!file.exists()) { + throw new IOException(VfsBundle.message("vfs.file.not.exist.error", file.getPath())); + } + if (!newParent.exists() || !newParent.isDirectory()) { + throw new IOException(VfsBundle.message("vfs.target.not.directory.error", newParent.getPath())); + } + if (newParent.findChild(copyName) != null) { + throw new IOException(VfsBundle.message("vfs.target.already.exists.error", newParent.getPath() + "/" + copyName)); } - File physicalFile = convertToIOFile(vFile); - File physicalCopy = auxCopy(vFile, newParent, copyName); + FileAttributes attributes = getAttributes(file); + if (attributes == null) { + throw new FileNotFoundException(VfsBundle.message("file.not.exist.error", file.getPath())); + } + if (attributes.isSpecial()) { + throw new FileNotFoundException("Not a file: " + file); + } + File ioParent = convertToIOFile(newParent); + if (!ioParent.isDirectory()) { + throw new IOException(VfsBundle.message("target.not.directory.error", ioParent.getPath())); + } + File ioTarget = new File(ioParent, copyName); + if (ioTarget.exists()) { + throw new IOException(VfsBundle.message("target.already.exists.error", ioTarget.getPath())); + } - try { - if (physicalCopy == null) { - File newPhysicalParent = convertToIOFile(newParent); - physicalCopy = new File(newPhysicalParent, copyName); - - try { - if (attributes.isDirectory()) { - FileUtil.copyDir(physicalFile, physicalCopy); - } - else { - FileUtil.copy(physicalFile, physicalCopy); - } + if (!auxCopy(file, newParent, copyName)) { + try { + File ioFile = convertToIOFile(file); + if (attributes.isDirectory()) { + FileUtil.copyDir(ioFile, ioTarget); } - catch (IOException e) { - FileUtil.delete(physicalCopy); - throw e; + else { + FileUtil.copy(ioFile, ioTarget); } } + catch (IOException e) { + FileUtil.delete(ioTarget); + throw e; + } } - finally { - auxNotifyCompleted(new ThrowableConsumer() { - @Override - public void consume(LocalFileOperationsHandler handler) throws IOException { - handler.copy(vFile, newParent, copyName); - } - }); - } + + auxNotifyCompleted(new ThrowableConsumer() { + @Override + public void consume(LocalFileOperationsHandler handler) throws IOException { + handler.copy(file, newParent, copyName); + } + }); return new FakeVirtualFile(newParent, copyName); } diff --git a/platform/platform-resources-en/src/messages/VfsBundle.properties b/platform/platform-resources-en/src/messages/VfsBundle.properties index f9c5c0c0a581..293cc3026d97 100644 --- a/platform/platform-resources-en/src/messages/VfsBundle.properties +++ b/platform/platform-resources-en/src/messages/VfsBundle.properties @@ -15,15 +15,28 @@ cannot.create.local.file=Cannot create local file: {0} download.progress.connecting=Connecting to ''{0}''... download.progress.downloading=Downloading ''{0}''... -file.invalid.name.error=Invalid file name: \"{0}\" -directory.invalid.name.error=Invalid directory name: \"{0}\" +vfs.file.not.exist.error=''{0}'' does not exist in VFS +vfs.target.already.exists.error=''{0}'' already exists in VFS +vfs.target.not.directory.error=''{0}'' is not a directory in VFS +file.not.exist.error=''{0}'' does not exist +target.already.exists.error=''{0}'' already exists +target.not.directory.error=''{0}'' is not a directory +file.invalid.name.error=Invalid file name: ''{0}'' +directory.invalid.name.error=Invalid directory name: ''{0}'' + +rename.failed.error=Cannot rename ''{0}'' to ''{1}'' +move.failed.error=Cannot move ''{0}'' to ''{1}'' +delete.failed.error=Cannot delete ''{0}'' +new.file.failed.error=Cannot create file ''{0}'' +new.directory.failed.error=Cannot create directory ''{0}'' + directory.create.wrong.parent.error=Not a directory. Cannot create new directory in. file.create.wrong.parent.error=Not a directory. Cannot create new file in. file.already.exists.error=Cannot create file ''{0}''. File already exists. dir.already.exists.error=Cannot create directory ''{0}''. Directory already exists. invalid.directory.create.files=Invalid directory. Cannot create files. -file.delete.error=Cannot delete file {0}. -file.move.error=Can not move file to {0} -file.copy.error=Can not copy file to {0} +file.move.error=Cannot move file to {0} +file.copy.error=Cannot copy file to {0} file.copy.target.must.be.directory=Cannot copy, target must be directory. -cannot.rename.root.directory=Cannot rename root directory. \ No newline at end of file +cannot.rename.root.directory=Cannot rename root directory ''{0}'' +cannot.delete.root.directory=Cannot delete root directory ''{0}'' diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java index 82bda836bf89..c75f101e5357 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java @@ -17,6 +17,8 @@ package com.intellij.openapi.vfs.local; import com.intellij.ide.GeneralSettings; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.Result; +import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileAttributes; import com.intellij.openapi.util.io.FileUtil; @@ -452,7 +454,7 @@ public class LocalFileSystemTest extends PlatformLangTestCase { assertEquals(newName, sourceFile.getName()); topDir.getChildren(); - newName = newName.toLowerCase(); + newName = newName.toLowerCase(Locale.ENGLISH); FileUtil.rename(file, intermediate); FileUtil.rename(intermediate, new File(top, newName)); topDir.refresh(false, true); @@ -582,4 +584,43 @@ public class LocalFileSystemTest extends PlatformLangTestCase { RefreshWorker.setCancellingCondition(null); } } + + public void testInvalidFileName() { + new WriteAction() { + @Override + protected void run(@NotNull Result result) throws Throwable { + VirtualFile tempDir = myFS.refreshAndFindFileByIoFile(createTempDirectory()); + assertNotNull(tempDir); + try { + tempDir.createChildData(this, "a/b"); + fail("invalid file name should have been rejected"); + } + catch (IOException e) { + assertEquals(VfsBundle.message("file.invalid.name.error", "a/b"), e.getMessage()); + } + } + }.execute(); + } + + public void testDuplicateViaRename() { + new WriteAction() { + @Override + protected void run(@NotNull Result result) throws Throwable { + VirtualFile tempDir = myFS.refreshAndFindFileByIoFile(createTempDirectory()); + assertNotNull(tempDir); + + VirtualFile file1 = tempDir.createChildData(this, "a.txt"); + FileUtil.delete(VfsUtilCore.virtualToIoFile(file1)); + + VirtualFile file2 = tempDir.createChildData(this, "b.txt"); + try { + file2.rename(this, "a.txt"); + fail("duplicate file name should have been rejected"); + } + catch (IOException e) { + assertEquals(VfsBundle.message("vfs.target.already.exists.error", file1.getPath()), e.getMessage()); + } + } + }.execute(); + } } diff --git a/platform/testFramework/src/com/intellij/testFramework/VfsTestUtil.java b/platform/testFramework/src/com/intellij/testFramework/VfsTestUtil.java index 279e640d4a2d..ccc7c0a46787 100644 --- a/platform/testFramework/src/com/intellij/testFramework/VfsTestUtil.java +++ b/platform/testFramework/src/com/intellij/testFramework/VfsTestUtil.java @@ -67,16 +67,18 @@ public class VfsTestUtil { } parent = child; } - final VirtualFile file; + + VirtualFile file; parent.getChildren();//need this to ensure that fileCreated event is fired if (dir) { file = parent.createChildDirectory(VfsTestUtil.class, PathUtil.getFileName(relativePath)); } else { - file = parent.createChildData(VfsTestUtil.class, PathUtil.getFileName(relativePath)); - if (!text.isEmpty()) { - VfsUtil.saveText(file, text); + file = parent.findFileByRelativePath(relativePath); + if (file == null) { + file = parent.createChildData(VfsTestUtil.class, PathUtil.getFileName(relativePath)); } + VfsUtil.saveText(file, text); } return file; } diff --git a/platform/testFramework/testSrc/com/intellij/testFramework/vcs/AbstractVcsTestCase.java b/platform/testFramework/testSrc/com/intellij/testFramework/vcs/AbstractVcsTestCase.java index bc20186244dd..6643acfd3803 100644 --- a/platform/testFramework/testSrc/com/intellij/testFramework/vcs/AbstractVcsTestCase.java +++ b/platform/testFramework/testSrc/com/intellij/testFramework/vcs/AbstractVcsTestCase.java @@ -132,7 +132,7 @@ public abstract class AbstractVcsTestCase { } public VirtualFile createDirInCommand(final VirtualFile parent, final String name) { - return VcsTestUtil.createDir(myProject, parent, name); + return VcsTestUtil.findOrCreateDir(myProject, parent, name); } protected void clearDirInCommand(final VirtualFile dir, final Processor filter) { diff --git a/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/VcsTestUtil.java b/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/VcsTestUtil.java index c7da2ad49a04..a31a76e73fa6 100644 --- a/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/VcsTestUtil.java +++ b/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/VcsTestUtil.java @@ -60,7 +60,7 @@ public class VcsTestUtil { * @param name Name of the directory. * @return reference to the created or already existing directory. */ - public static VirtualFile createDir(@NotNull final Project project, @NotNull final VirtualFile parent, @NotNull final String name) { + public static VirtualFile findOrCreateDir(@NotNull final Project project, @NotNull final VirtualFile parent, @NotNull final String name) { return new WriteCommandAction(project) { @Override protected void run(@NotNull Result result) throws Throwable { diff --git a/plugins/git4idea/tests/git4idea/tests/GitChangeProviderTest.java b/plugins/git4idea/tests/git4idea/tests/GitChangeProviderTest.java index 39eacd86883a..e5259354ba7f 100644 --- a/plugins/git4idea/tests/git4idea/tests/GitChangeProviderTest.java +++ b/plugins/git4idea/tests/git4idea/tests/GitChangeProviderTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -222,7 +222,7 @@ public abstract class GitChangeProviderTest extends GitSingleRepoTest { private VirtualFile create(VirtualFile parent, String name, boolean dir) { final VirtualFile file = dir ? - VcsTestUtil.createDir(myProject, parent, name) : + VcsTestUtil.findOrCreateDir(myProject, parent, name) : createFile(myProject, parent, name, "content" + Math.random()); dirty(file); return file;