Files
openide/java/java-tests/testSrc/com/intellij/openapi/command/undo/GlobalUndoTest.java
Andrei.Kuznetsov 89605ab0a7 IJPL-578 wait for indexes to be ready in tests after VFS refresh
GitOrigin-RevId: 8d0b450d68eefaa96d6d882ecfe18af32579fd3f
2024-02-29 22:09:25 +00:00

1541 lines
50 KiB
Java

// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.command.undo;
import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.codeInsight.actions.ReformatCodeProcessor;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.QuickFixFactory;
import com.intellij.configurationStore.StoreUtil;
import com.intellij.mock.Mock;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.UndoConfirmationPolicy;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.fileEditor.impl.CurrentEditorProvider;
import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.TestDialog;
import com.intellij.openapi.ui.TestDialogManager;
import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.refactoring.rename.RenameProcessor;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.testFramework.VfsTestUtil;
import kotlin.text.Charsets;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.lang.ref.Reference;
import java.util.Collections;
public class GlobalUndoTest extends UndoTestCase implements TestDialog {
private TestDialog myOldTestDialogValue;
private PsiClass myClass;
private VirtualFile myDir;
private static final String myDirName = "dir1";
private VirtualFile myDir1;
private VirtualFile myDir2;
private VirtualFile myDirToMove;
private VirtualFile myDirToRename;
private static final String DIR_TO_RENAME_NAME = "dirToRename.txt";
private static final String NEW_NAME = "NewName";
private boolean myConfirmationWasRequested;
private static final String DIR_NAME = "dir.txt";
private PsiJavaFile myContainingFile;
@Override
protected void setUp() throws Exception {
super.setUp();
myOldTestDialogValue = TestDialogManager.setTestDialog(this);
}
@Override
protected void tearDown() throws Exception {
try {
TestDialogManager.setTestDialog(myOldTestDialogValue);
myContainingFile = null;
myClass = null;
}
catch (Throwable e) {
addSuppressedException(e);
}
finally {
super.tearDown();
}
}
@Override
public int show(@NotNull String message) {
myConfirmationWasRequested = true;
return 0;
}
public void testCreateClassIsUndoableAction() {
createClass("Class");
globalUndo();
}
public void testUndoDeleteClass() {
String className = "TestClass";
createClass(className);
String contentBefore = getDocumentText(findFile(className, myRoot));
deleteClass();
for (int i = 0; i < 2; i++) {
globalUndo();
assertFileExists(className, contentBefore);
globalUndo();
assertFileDoesNotExist(className, myRoot);
globalRedo();
assertFileExists(className, contentBefore);
globalRedo();
assertFileDoesNotExist(className, myRoot);
}
}
public void testUndoCreateClassTwice() {
createClass("TestClass1");
createClass("TestClass2");
Editor editor = openEditor("TestClass2.java");
undo(editor);
globalUndo();
StoreUtil.saveDocumentsAndProjectsAndApp(false);
checkAllFilesDeleted();
}
public void testUndoFileCopy() throws Exception {
VirtualFile file = createFile("a.txt", "").getVirtualFile();
VirtualFile dir = file.getParent();
VirtualFile copy = WriteCommandAction.writeCommandAction(myProject).compute(() -> file.copy(this, dir, "b.txt"));
globalUndo();
assertTrue(file.isValid());
assertFalse(copy.isValid());
}
public void testUndoRenameClass() {
String firstClassName = "Class1";
String secondClassName = "Class223467234678234678236478263478";
createClass(firstClassName);
renameClassTo(secondClassName);
assertFileExists(myRoot, secondClassName);
assertFileDoesNotExist(firstClassName, myRoot);
for (int i = 0; i < 2; i++) {
globalUndo();
assertFileExists(myRoot, firstClassName);
assertFileDoesNotExist(secondClassName, myRoot);
globalRedo();
assertFileExists(myRoot, secondClassName);
assertFileDoesNotExist(firstClassName, myRoot);
}
}
public void testUndoRenameWithCaseChangeClass() {
final VirtualFile f = createChildData(myRoot, "Foo.txt");
executeCommand(() -> rename(f, "FOO.txt"));
assertEquals("FOO.txt", f.getName());
for (int i = 0; i < 2; i++) {
globalUndo();
assertEquals("Foo.txt", f.getName());
globalRedo();
assertEquals("FOO.txt", f.getName());
}
}
private void renameClassTo(final String newClassName) {
executeCommand("Rename Class", () -> new RenameProcessor(myProject, myClass, newClassName, true, true).run());
}
public void testUndoAfterEmptyReformat() {
createClass("foo");
final PsiFile file = myContainingFile;
final Editor editor = openEditor("foo.java");
new ReformatCodeProcessor(myProject, file, null, false).run();
undo(editor);
assertFileDoesNotExist("foo", myRoot);
}
public void testUndoMoveFile() {
VirtualFile dir1 = createChildDirectory(myRoot, myDirName);
VirtualFile dir2 = createChildDirectory(myRoot, "dir2");
String className = "Class1";
createClass(className, dir1);
assertFileExists(dir1, className);
assertFileDoesNotExist(className, dir2);
moveClassTo(dir2);
assertFileExists(dir2, className);
assertFileDoesNotExist(className, dir1);
globalUndo();
assertFileExists(dir1, className);
assertFileDoesNotExist(className, dir2);
globalRedo();
assertFileExists(dir2, className);
assertFileDoesNotExist(className, dir1);
}
public void testRedoCreateAndMove() {
final VirtualFile dir = createChildDirectory(myRoot, "dir");
final VirtualFile[] f = new VirtualFile[1];
executeCommand(() -> {
f[0] = createChildData(myRoot, "foo.txt");
setDocumentText(f[0], "foo");
});
executeCommand(() -> {
move(f[0], dir);
setDocumentText(f[0], "foobar");
});
globalUndo();
globalUndo();
assertNull(myRoot.findChild("foo.txt"));
globalRedo();
f[0] = myRoot.findChild("foo.txt");
assertNotNull(f[0]);
assertEquals("foo", getDocumentText(f[0]));
globalRedo();
assertEquals(dir, f[0].getParent());
assertEquals("foobar", getDocumentText(f[0]));
}
public void testRestoringUndoStackForDocumentWhenItIsRecreatedWithSameName() {
final VirtualFile[] f = new VirtualFile[1];
executeCommand(() -> {
f[0] = createChildData(myRoot, "foo.txt");
setDocumentText(f[0], "foo");
});
executeCommand(() -> setDocumentText(f[0], "foofoo"));
undo(getEditor(f[0]));
undo(getEditor(f[0]));
assertNull(myRoot.findChild("foo.txt"));
globalRedo();
f[0] = myRoot.findChild("foo.txt");
assertNotNull(f[0]);
assertEquals("foo", getDocumentText(f[0]));
redo(getEditor(f[0]));
assertEquals("foofoo", getDocumentText(f[0]));
}
public void testDoNotConfuseRecreatedFilesWithDeleted() {
final VirtualFile[] f = new VirtualFile[1];
executeCommand(() -> {
f[0] = createChildData(myRoot, "foo.txt");
setDocumentText(f[0], "foo");
});
executeCommand(() -> setDocumentText(f[0], "foofoo"));
executeCommand(() -> delete(f[0]));
executeCommand(() -> f[0] = createChildData(myRoot, "foo.txt"));
assertGlobalRedoNotAvailable();
assertRedoNotAvailable(getEditor(f[0]));
undo(getEditor(f[0])); // should undo creation, not editing of previous document
assertNull(myRoot.findChild("foo.txt"));
globalUndo();
f[0] = myRoot.findChild("foo.txt");
assertNotNull(f[0]);
assertEquals("foofoo", getDocumentText(f[0]));
undo(getEditor(f[0]));
assertEquals("foo", getDocumentText(f[0]));
}
public void testDeletionOfNoneJavaFiles() {
VirtualFile f = createChildData(myRoot, "f.xxx");
deleteInCommand(f);
assertGlobalUndoIsAvailable();
globalUndo();
assertNotNull(myRoot.findChild("f.xxx"));
}
public void testUndoDeleteDir() {
createDirectory(myDirName);
checkDirExists();
deleteDirectory();
checkDirDoesNotExist();
globalUndo();
checkDirExists();
globalRedo();
checkDirDoesNotExist();
}
public void testUndoRenameDirectoryWithFile() {
final VirtualFile[] dir = new VirtualFile[1];
final VirtualFile[] file = new VirtualFile[1];
executeCommand(() -> {
dir[0] = createChildDirectory(myRoot, "dir");
file[0] = createChildData(dir[0], "file.txt");
});
setDocumentText(file[0], "document");
executeCommand(() -> {
rename(dir[0], "dir2");
setDocumentText(file[0], "document2");
});
for (int i = 0; i < 2; i++) {
globalUndo();
assertNull(myRoot.findChild("dir2"));
dir[0] = myRoot.findChild("dir");
assertNotNull(dir);
file[0] = dir[0].findChild("file.txt");
assertNotNull(file[0]);
assertEquals("document", getDocumentText(file[0]));
globalRedo();
assertNull(myRoot.findChild("dir"));
dir[0] = myRoot.findChild("dir2");
assertNotNull(dir);
file[0] = dir[0].findChild("file.txt");
assertNotNull(file[0]);
assertEquals("document2", getDocumentText(file[0]));
}
}
public void testUndoDeleteDirectoryWithFile() {
final VirtualFile[] dir = new VirtualFile[1];
final VirtualFile[] file = new VirtualFile[1];
executeCommand(() -> {
dir[0] = createChildDirectory(myRoot, "dir");
file[0] = createChildData(dir[0], "file.txt");
});
setDocumentText(file[0], "document");
executeCommand(() -> {
delete(file[0]);
delete(dir[0]);
});
for (int i = 0; i < 2; i++) {
globalUndo();
dir[0] = myRoot.findChild("dir");
assertNotNull(dir);
file[0] = dir[0].findChild("file.txt");
assertNotNull(file[0]);
assertEquals("document", getDocumentText(file[0]));
globalRedo();
assertNull(myRoot.findChild("dir"));
}
}
public void testUndoDeleteDirectoryWithFileWithDisabledUndoMustNotRecreateFiles() {
final VirtualFile[] dir = new VirtualFile[1];
final VirtualFile[] file = new VirtualFile[1];
executeCommand(() -> {
dir[0] = createChildDirectory(myRoot, "dir");
file[0] = createChildData(dir[0], "file.txt");
});
setDocumentText(file[0], "document");
executeCommand(() -> {
UndoUtil.disableUndoFor(file[0]);
delete(file[0]);
delete(dir[0]);
});
for (int i = 0; i < 2; i++) {
globalUndo();
dir[0] = myRoot.findChild("dir");
assertNotNull(dir);
file[0] = dir[0].findChild("file.txt");
assertNull(file[0]);
globalRedo();
assertNull(myRoot.findChild("dir"));
}
}
public void testUndoDirectoryMovingToExistingDirectory() throws IOException {
createTestProjectStructureAndMoveDirectory();
File ioDir = createDirOnTheDirToMovePlaceWithTheSameName();
checkSuccessfulMoveUndo(ioDir);
}
public void testUndoDirectoryMovingToExistingFile() throws IOException {
createTestProjectStructureAndMoveDirectory();
File ioDir = createFileOnTheDirToMovePlaceWithTheSameName();
checkSuccessfulMoveUndo(ioDir);
}
private void createTestProjectStructureAndMoveDirectory() throws IOException {
WriteCommandAction.writeCommandAction(getProject()).run(() -> {
createDirectory("parent");
myDir1 = myDir.createChildDirectory(this, "dir1");
myDir2 = myDir.createChildDirectory(this, "dir2");
myDirToMove = myDir1.createChildDirectory(this, DIR_NAME);
myDirToMove.createChildData(this, "file.txt");
});
CommandProcessor.getInstance().executeCommand(myProject, () -> move(myDirToMove, myDir2), "Moving", null);
}
private File createFileOnTheDirToMovePlaceWithTheSameName() throws IOException {
File ioDir = new File(VfsUtilCore.virtualToIoFile(myDir1), DIR_NAME);
ioDir.createNewFile();
refreshFileSystem();
return ioDir;
}
private File createDirOnTheDirToMovePlaceWithTheSameName() {
File ioDir = new File(VfsUtilCore.virtualToIoFile(myDir1), DIR_NAME);
ioDir.mkdir();
refreshFileSystem();
return ioDir;
}
private void checkSuccessfulMoveUndo(File ioDir) {
globalUndo();
assertTrue(new File(ioDir, "file.txt").exists());
assertNull(myDir2.findChild(DIR_NAME));
}
public void testUndoDirectoryRenamingToExistingDirectory() {
createTestProjectStructureAndRenameDirectory();
File ioDir = createDirOnTheDirToRenamePlaceWithTheSameName();
checkSuccessfulRenameUndo(ioDir);
}
public void testUndoDirectoryRenamingToExistingFile() throws IOException {
createTestProjectStructureAndRenameDirectory();
File ioDir = createFileOnTheDirToRenamePlaceWithTheSameName();
checkSuccessfulRenameUndo(ioDir);
}
// ignored because some problems with weak references in filedocumentmanager
public void testCanUndoDocumentAfterExternalChange() throws Exception {
final VirtualFile f = createChildData(myRoot, "f.txt");
executeCommand(() -> setDocumentText(f, "doc"));
Document doc = FileDocumentManager.getInstance().getDocument(f); // prevent weak refs from being collected
FileDocumentManager.getInstance().saveAllDocuments(); // prevent 'file has been changed dialog'
File ioFile = new File(f.getPath());
FileUtil.writeToFile(ioFile, "external".getBytes(Charsets.UTF_8));
ioFile.setLastModified(f.getTimeStamp() + 2000);
LocalFileSystem.getInstance().refresh(false);
assertEquals("external", getDocumentText(f));
Editor editor = getEditor(f);
assertGlobalUndoNotAvailable();
assertUndoIsAvailable(editor);
undo(editor);
assertEquals("doc", getDocumentText(f));
undo(editor);
assertEquals("", getDocumentText(f));
redo(editor);
assertEquals("doc", getDocumentText(f));
redo(editor);
assertEquals("external", getDocumentText(f));
Reference.reachabilityFence(doc);
}
public void testCanUndoAfterFileWasDeletedAndWhenCreatedExternally() throws IOException {
VirtualFile f = createChildData(myRoot, "f.txt");
final VirtualFile finalF = f;
executeCommand(() -> setDocumentText(finalF, "doc"));
executeCommand(() -> delete(finalF));
File ioFile = new File(f.getPath());
FileUtil.writeToFile(ioFile, "external".getBytes(Charsets.UTF_8));
LocalFileSystem.getInstance().refresh(false);
f = myRoot.findChild("f.txt");
assertNotNull(f);
assertEquals("external", getDocumentText(f));
Editor editor = getEditor(f);
assertGlobalUndoIsAvailable();
assertUndoIsAvailable(editor);
undo(editor);
assertEquals("doc", getDocumentText(f));
undo(editor);
assertEquals("", getDocumentText(f));
redo(editor);
assertEquals("doc", getDocumentText(f));
// todo
//redo(editor);
//assertEquals("external", getDocumentText(f));
}
public void testDoNotRecordDocumentChangesWhenFileChangedExternallyAndNoChangesRecordedYet() throws IOException {
VirtualFile f = createChildData(myRoot, "f.txt");
Document d = FileDocumentManager.getInstance().getDocument(f); // make sure the document is cached.
File ioFile = new File(f.getPath());
FileUtil.writeToFile(ioFile, "external".getBytes(Charsets.UTF_8));
ioFile.setLastModified(f.getTimeStamp() + 2000);
LocalFileSystem.getInstance().refresh(false);
assertEquals("external", getDocumentText(f));
assertGlobalUndoNotAvailable();
assertUndoNotAvailable(getEditor(f));
Reference.reachabilityFence(d);
}
public void testGlobalUndoIsAvailableWhenFileChangedExternallyWithForceFlag() {
String fileName = "f.txt";
String projectFileName = "proj.txt";
VirtualFile f = createChildData(myRoot, projectFileName);
executeCommand(() -> {
createChildData(myRoot, fileName);
// Rider case, modify externally and refresh some file in a command
File ioFile = new File(f.getPath());
FileUtil.writeToFile(ioFile, "content".getBytes(Charsets.UTF_8));
ioFile.setLastModified(f.getTimeStamp() + 2000);
UndoUtil.setForceUndoFlag(f, true);
f.refresh(false, true);
});
assertGlobalUndoIsAvailable();
assertNotNull(myRoot.findChild(fileName));
globalUndo();
assertNull(myRoot.findChild(fileName));
}
public void testRecordDocumentChangesWhenFileChangedExternallyAndAlreadyHasChanges() throws IOException {
final VirtualFile f = createChildData(myRoot, "f.txt");
executeCommand(() -> setDocumentText(f, "doc"));
assertGlobalUndoNotAvailable();
assertUndoIsAvailable(getEditor(f));
undo(getEditor(f)); // clear undo stack, but preserve the change in redo stack
File ioFile = new File(f.getPath());
FileUtil.writeToFile(ioFile, "external".getBytes(Charsets.UTF_8));
ioFile.setLastModified(f.getTimeStamp() + 2000);
LocalFileSystem.getInstance().refresh(false);
assertEquals("external", getDocumentText(f));
assertGlobalUndoNotAvailable();
assertUndoIsAvailable(getEditor(f));
}
private Pair<Editor, Editor> prepareTestUndoFallback(){
createClass("Bar");
createClass("Foo");
Editor barEditor = openEditor("Bar.java");
// 1: extends Foo
WriteAction.runAndWait(() -> executeCommand(() -> barEditor.getDocument().insertString(17, "extends Foo")));
// 2: change local stack in second file
WriteAction.runAndWait(() -> executeCommand(() -> barEditor.getDocument().insertString(30, "public void Test(){}")));
// 3: rename Foo class
renameClassTo("FooRenamed");
Editor fooEditor = openEditor("FooRenamed.java");
// 4: change local stack in FooRenamed.java
WriteAction.runAndWait(() -> executeCommand(() -> fooEditor.getDocument().insertString(25, "public void Test(){}")));
return new Pair<>(barEditor, fooEditor);
}
public void testUndoFallbackToLocalStack() {
Registry.get("ide.undo.fallback").setValue(true, getTestRootDisposable());
Pair<Editor, Editor> pair = prepareTestUndoFallback();
var barEditor = pair.first;
var fooEditor = pair.second;
undo(barEditor);
assertFalse("Bar.java doesn't remove rename from Foo.java", barEditor.getDocument().getText().contains("FooRenamed"));
assertTrue("Foo.java doesn't contains last rename result", fooEditor.getDocument().getText().contains("FooRenamed"));
}
public void testUndoFallbackToLocalStackAndRedo() {
Registry.get("ide.undo.fallback").setValue(true, getTestRootDisposable());
Pair<Editor, Editor> pair = prepareTestUndoFallback();
var barEditor = pair.first;
var fooEditor = pair.second;
undo(barEditor);
// call redo to gather splitted command together
redo(barEditor);
assertTrue(barEditor.getDocument().getText().contains("FooRenamed"));
// 7: undo rename Foo -> FooRenamed to check that changes also applied to Bar.java
undo(fooEditor);
undo(fooEditor);
assertFalse("FooRenamed rename undo doesn't applied to Bar.java", barEditor.getDocument().getText().contains("FooRenamed"));
}
public void testUndoRedoNotAvailableAfterFileWasDeletedExternally() {
final VirtualFile f1 = createChildData(myRoot, "f1.txt");
final VirtualFile f2 = createChildData(myRoot, "f2.txt");
executeCommand(() -> {
rename(f1, "ff1.txt");
setDocumentText(f1, "ff1");
});
executeCommand(() -> {
rename(f2, "ff2.txt");
setDocumentText(f2, "ff2");
});
// <---- test point
executeCommand(() -> {
rename(f2, "fff2.txt");
setDocumentText(f2, "fff2");
});
executeCommand(() -> {
rename(f1, "fff1.txt");
setDocumentText(f1, "fff1");
});
globalUndo();
assertGlobalUndoIsAvailable();
assertGlobalRedoIsAvailable();
globalUndo();
assertGlobalUndoIsAvailable();
assertGlobalRedoIsAvailable();
delete(f1); // commands for f1 should be invalidated here
assertGlobalUndoIsAvailable();
assertGlobalRedoIsAvailable();
globalRedo();
assertGlobalUndoIsAvailable();
assertGlobalRedoNotAvailable();
globalUndo();
globalUndo(); // back to the 'test point'
assertGlobalUndoNotAvailable();
assertGlobalRedoIsAvailable();
}
public void testCanUndoDocumentsAfterSave() {
FileDocumentManager dm = FileDocumentManager.getInstance();
EditorFactory ef = EditorFactory.getInstance();
VirtualFile f = createChildData(myRoot, "f.java");
Document d = dm.getDocument(f);
Editor e = ef.createEditor(d);
assertEquals("", d.getText());
typeInText(e, "12345");
assertEquals("12345", d.getText());
dm.saveDocument(d);
undo(e);
ef.releaseEditor(e);
assertEquals("", d.getText());
}
public void testClearingRedoStackClearsGlobalCommandsCorrectly() {
final VirtualFile[] f1 = new VirtualFile[1];
final VirtualFile[] f2 = new VirtualFile[1];
final VirtualFile[] f3 = new VirtualFile[1];
executeCommand(() -> {
f1[0] = createChildData(myRoot, "f1.java");
f2[0] = createChildData(myRoot, "f2.java");
f3[0] = createChildData(myRoot, "f3.java");
});
for (VirtualFile each : FileEditorManager.getInstance(myProject).getOpenFiles()) {
FileEditorManager.getInstance(myProject).closeFile(each);
}
executeCommand(() -> {
setDocumentText(f1[0], "f1");
setDocumentText(f2[0], "f2");
});
executeCommand(() -> setDocumentText(f3[0], "f3"));
undo(getEditor(f3[0]));
undo(null);
assertEquals("", getDocumentText(f1[0]));
assertEquals("", getDocumentText(f3[0]));
assertRedoIsAvailable(null);
assertRedoIsAvailable(getEditor(f1[0]));
assertRedoIsAvailable(getEditor(f2[0]));
assertRedoIsAvailable(getEditor(f3[0]));
for (VirtualFile each : FileEditorManager.getInstance(myProject).getOpenFiles()) {
FileEditorManager.getInstance(myProject).closeFile(each);
}
executeCommand(() -> setDocumentText(f1[0], "ff1"));
assertRedoNotAvailable(null);
assertRedoNotAvailable(getEditor(f1[0]));
assertRedoNotAvailable(getEditor(f2[0]));
assertRedoIsAvailable(getEditor(f3[0]));
}
public void testRegisteringOpenDocumentWhenAnotherFileIsAffected() {
final VirtualFile[] f1 = new VirtualFile[1];
final VirtualFile[] f2 = new VirtualFile[1];
final VirtualFile[] f3 = new VirtualFile[1];
f1[0] = createChildData(myRoot, "f1.java");
f2[0] = createChildData(myRoot, "f2.java");
f3[0] = createChildData(myRoot, "f3.java");
executeCommand(() -> setDocumentText(f1[0], "f1"));
assertUndoNotAvailable(null);
assertUndoIsAvailable(getEditor(f1[0]));
assertUndoNotAvailable(getEditor(f2[0]));
assertUndoNotAvailable(getEditor(f3[0]));
myEditor = openEditor(f2[0]);
executeCommand(() -> setDocumentText(f1[0], "f1"));
assertUndoIsAvailable(null);
assertUndoIsAvailable(getEditor(f1[0]));
assertUndoIsAvailable(getEditor(f2[0]));
assertUndoNotAvailable(getEditor(f3[0]));
}
public void testRegisteringOpenDocumentForReadOnlyFileDoesNotBreakUndoChain() throws Exception {
final VirtualFile f1 = createChildData(myRoot, "f1.java");
final VirtualFile f2 = createChildData(myRoot, "f2.java");
final VirtualFile f3 = createChildData(myRoot, "f3.java");
WriteAction.runAndWait(() -> f2.setWritable(false));
executeCommand(() -> setDocumentText(f1, "initial"));
assertUndoNotAvailable(null);
assertUndoIsAvailable(getEditor(f1));
assertUndoNotAvailable(getEditor(f2));
assertUndoNotAvailable(getEditor(f3));
myEditor = openEditor(f2);
executeCommand(() -> setDocumentText(f1, "new content"));
assertUndoIsAvailable(null);
assertUndoIsAvailable(getEditor(f1));
assertUndoIsAvailable(getEditor(f2));
assertUndoNotAvailable(getEditor(f3));
undo(getEditor(f2));
assertEquals("initial", getDocumentText(f1));
}
public void testDoNotRegisterOpenDocumentWhenAnotherFileReloaded() throws Exception {
final VirtualFile f1 = createChildData(myRoot, "f1.java");
final VirtualFile f2 = createChildData(myRoot, "f2.java");
executeCommand(() -> setDocumentText(f1, "f1"));
executeCommand(() -> {
setDocumentText(f2, "f2");
FileDocumentManager.getInstance().saveDocument(getDocument(f2));
});
assertUndoNotAvailable(null);
assertUndoIsAvailable(getEditor(f1));
assertUndoIsAvailable(getEditor(f2));
myEditor = openEditor(f1);
File file = new File(f2.getPath());
FileUtil.writeToFile(file, "reloaded");
file.setLastModified(file.lastModified() + 10000);
LocalFileSystem.getInstance().refreshIoFiles(Collections.singletonList(file));
assertUndoNotAvailable(null);
assertUndoIsAvailable(getEditor(f1));
assertUndoIsAvailable(getEditor(f2));
// undo open document first
undo(getEditor(f1));
assertEquals("", getDocumentText(f1));
undo(getEditor(f2));
assertEquals("f2", getDocumentText(f2));
}
public void testClearingRedoStackClearsGlobalCommandsCorrectlyIntersectingStacks() {
final VirtualFile[] f1 = new VirtualFile[1];
final VirtualFile[] f2 = new VirtualFile[1];
final VirtualFile[] f3 = new VirtualFile[1];
final VirtualFile[] f4 = new VirtualFile[1];
executeCommand(() -> {
f1[0] = createChildData(myRoot, "f1.java");
f2[0] = createChildData(myRoot, "f2.java");
f3[0] = createChildData(myRoot, "f3.java");
f4[0] = createChildData(myRoot, "f4.java");
});
executeCommand(() -> {
setDocumentText(f1[0], "f1");
setDocumentText(f2[0], "f2");
});
executeCommand(() -> {
setDocumentText(f3[0], "f3");
setDocumentText(f4[0], "f4");
});
undo(null);
undo(null);
assertEquals("", getDocumentText(f1[0]));
assertEquals("", getDocumentText(f3[0]));
assertRedoIsAvailable(null);
assertRedoIsAvailable(getEditor(f1[0]));
assertRedoIsAvailable(getEditor(f2[0]));
assertRedoIsAvailable(getEditor(f3[0]));
assertRedoIsAvailable(getEditor(f4[0]));
executeCommand(() -> setDocumentText(f1[0], "ff1"));
assertRedoNotAvailable(null);
assertRedoNotAvailable(getEditor(f1[0]));
assertRedoNotAvailable(getEditor(f2[0]));
assertRedoNotAvailable(getEditor(f3[0]));
assertRedoNotAvailable(getEditor(f4[0]));
}
public void testClearingRedoStackClearsStackNotTooMuch() {
final VirtualFile[] f1 = new VirtualFile[1];
final VirtualFile[] f2 = new VirtualFile[1];
executeCommand(() -> {
f1[0] = createChildData(myRoot, "f1.java");
f2[0] = createChildData(myRoot, "f2.java");
});
executeCommand(() -> setDocumentText(f1[0], "f1"));
executeCommand(() -> {
setDocumentText(f1[0], "ff1");
setDocumentText(f2[0], "ff2");
});
undo(getEditor(f1[0]));
undo(getEditor(f1[0]));
assertEquals("", getDocumentText(f1[0]));
assertEquals("", getDocumentText(f2[0]));
assertRedoIsAvailable(null);
assertRedoIsAvailable(getEditor(f1[0]));
assertRedoIsAvailable(getEditor(f2[0]));
executeCommand(() -> setDocumentText(f2[0], "fff2"));
assertRedoNotAvailable(null);
assertRedoIsAvailable(getEditor(f1[0]));
assertRedoNotAvailable(getEditor(f2[0]));
redo(getEditor(f1[0]));
assertEquals("f1", getDocumentText(f1[0]));
}
public void testAddingAffectedDocumentOrFile() {
final VirtualFile f1 = createChildData(myRoot, "f1.java");
final VirtualFile f2 = createChildData(myRoot, "f2.java");
final VirtualFile f3 = createChildData(myRoot, "f3.java");
assertUndoNotAvailable(getEditor(f1));
assertUndoNotAvailable(getEditor(f2));
assertUndoNotAvailable(getEditor(f3));
CommandProcessor.getInstance().executeCommand(myProject, () -> {
setDocumentText(f1, "foo");
CommandProcessor.getInstance().addAffectedDocuments(myProject, FileDocumentManager.getInstance().getDocument(f2));
CommandProcessor.getInstance().addAffectedFiles(myProject, f3);
}, null, null);
assertUndoIsAvailable(getEditor(f1));
assertUndoIsAvailable(getEditor(f2));
assertUndoIsAvailable(getEditor(f3));
myManager.flushCurrentCommandMerger();
assertUndoIsAvailable(getEditor(f1));
assertUndoIsAvailable(getEditor(f2));
assertUndoIsAvailable(getEditor(f3));
}
public void testAddingAffectedDocumentWhenNoOtherChangesDoesntChangeUndoRedoStacks() {
final VirtualFile f1 = createChildData(myRoot, "f1.java");
final VirtualFile f2 = createChildData(myRoot, "f2.java");
final VirtualFile f3 = createChildData(myRoot, "f3.java");
assertUndoNotAvailable(getEditor(f1));
assertUndoNotAvailable(getEditor(f2));
assertUndoNotAvailable(getEditor(f3));
CommandProcessor.getInstance().executeCommand(myProject, () -> {
CommandProcessor.getInstance().addAffectedDocuments(myProject, FileDocumentManager.getInstance().getDocument(f2));
CommandProcessor.getInstance().addAffectedFiles(myProject, f3);
}, null, null);
assertUndoNotAvailable(getEditor(f1));
assertUndoNotAvailable(getEditor(f2));
assertUndoNotAvailable(getEditor(f3));
myManager.flushCurrentCommandMerger();
assertUndoNotAvailable(getEditor(f1));
assertUndoNotAvailable(getEditor(f2));
assertUndoNotAvailable(getEditor(f3));
}
public void testFixRIDER10340() {
createClass("TestClass1");
Editor editor = openEditor("TestClass1.java");
WriteAction.runAndWait(() -> executeCommand(() -> editor.getDocument().insertString(27, "public class Aaa {}")));
PsiDocumentManager instance = PsiDocumentManager.getInstance(myProject);
instance.commitAllDocuments();
PsiFile file = instance.getPsiFile(editor.getDocument());
PsiClass aaaClass = (PsiClass)file.getViewProvider().findElementAt(41).getParent();
IntentionAction fix = QuickFixFactory.getInstance().createMoveClassToSeparateFileFix(aaaClass);
WriteAction.runAndWait(() -> executeCommand(() -> fix.invoke(myProject, editor, file)));
instance.commitAllDocuments();
VirtualFile aaaFile = file.getVirtualFile().getParent().findChild("Aaa.java");
deleteInCommand(aaaFile);
undo(editor);
undo(editor);
assertEquals("public class TestClass1 {\n}public class Aaa {}\n", editor.getDocument().getText());
}
public void testPerformance() {
WriteCommandAction.runWriteCommandAction(getProject(), new Runnable() {
@Override
public void run() {
try {
VirtualFile dir1 = myRoot.createChildDirectory(this, "dir1");
VirtualFile dir2 = myRoot.createChildDirectory(this, "dir2");
dir1.createChildData(this, "f.java");
dir1.move(this, dir2);
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
});
PlatformTestUtil.assertTiming("", 2000, 1, () -> {
redoUndo();
redoUndo();
redoUndo();
});
}
private void redoUndo() {
globalUndo();
globalRedo();
}
public void testRedoIsNotAvailableAfterFileChanges() {
final VirtualFile f = createChildData(myRoot, "f.java");
renameInCommand(f, "ff.java");
globalUndo();
assertGlobalRedoIsAvailable();
renameInCommand(f, "fff.java");
assertGlobalRedoNotAvailable();
}
public void testUndoRedoFileWithChangedDocument() throws Exception {
VirtualFile file = getTempDir().createVirtualDir();
assertNotNull(file);
final String[] path = new String[1];
executeCommand(() -> {
PsiFile f = createFile(myModule, file, "foo.txt", "initial");
Document doc = PsiDocumentManager.getInstance(myProject).getDocument(f);
setDocumentText(doc, "document");
path[0] = f.getVirtualFile().getPath();
});
globalUndo();
globalRedo();
VirtualFile f = LocalFileSystem.getInstance().findFileByPath(path[0]);
assertNotNull(f);
assertEquals("initial", VfsUtilCore.loadText(f));
Document doc = FileDocumentManager.getInstance().getDocument(f);
assertEquals("document", doc.getText());
}
public void testUndoRedoFileWithChangedDocumentWithSeveralAffectedFiles() throws Exception {
final String[] path = new String[2];
executeCommand(() -> {
VirtualFile f = createChildData(myRoot, "foo1.txt");
setBinaryContent(f, "initial1".getBytes(Charsets.UTF_8));
Document doc = FileDocumentManager.getInstance().getDocument(f);
setDocumentText(doc, "document1");
path[0] = f.getPath();
f = createChildData(myRoot, "foo2.txt");
setBinaryContent(f, "initial2".getBytes(Charsets.UTF_8));
doc = FileDocumentManager.getInstance().getDocument(f);
setDocumentText(doc, "document2");
path[1] = f.getPath();
});
globalUndo();
globalRedo();
VirtualFile f = LocalFileSystem.getInstance().findFileByPath(path[0]);
assertNotNull(f);
assertEquals("initial1", VfsUtilCore.loadText(f));
Document doc = FileDocumentManager.getInstance().getDocument(f);
assertEquals("document1", doc.getText());
f = LocalFileSystem.getInstance().findFileByPath(path[1]);
assertNotNull(f);
assertEquals("initial2", VfsUtilCore.loadText(f));
doc = FileDocumentManager.getInstance().getDocument(f);
assertEquals("document2", doc.getText());
}
private static void setDocumentText(final Document doc, final String document2) {
ApplicationManager.getApplication().runWriteAction(() -> doc.setText(document2));
}
public void testUndoRedoFileMoveAndDeleteWithChangedDocument() throws Exception {
final VirtualFile[] dir = new VirtualFile[1];
final VirtualFile[] f = new VirtualFile[1];
executeCommand(() -> {
dir[0] = createChildDirectory(myRoot, "dir");
f[0] = createChildData(myRoot, "foo.txt");
setBinaryContent(f[0], "initial".getBytes(Charsets.UTF_8));
setDocumentText(f[0], "document");
});
executeCommand(() -> {
move(f[0], dir[0]);
setDocumentText(f[0], "moved");
});
executeCommand(() -> delete(dir[0]));
globalUndo();
f[0] = LocalFileSystem.getInstance().findFileByPath(f[0].getPath());
dir[0] = LocalFileSystem.getInstance().findFileByPath(dir[0].getPath());
assertNotNull(f[0]);
assertNotNull(dir[0]);
assertEquals(dir[0], f[0].getParent());
assertEquals("moved", VfsUtilCore.loadText(f[0]));
Document doc = FileDocumentManager.getInstance().getDocument(f[0]);
assertEquals("moved", doc.getText());
globalUndo();
assertEquals(myRoot, f[0].getParent());
assertEquals("moved", VfsUtilCore.loadText(f[0]));
doc = FileDocumentManager.getInstance().getDocument(f[0]);
assertEquals("document", doc.getText());
globalUndo();
globalRedo();
f[0] = LocalFileSystem.getInstance().findFileByPath(f[0].getPath());
dir[0] = LocalFileSystem.getInstance().findFileByPath(dir[0].getPath());
assertEquals(myRoot, f[0].getParent());
assertEquals("initial", VfsUtilCore.loadText(f[0]));
doc = FileDocumentManager.getInstance().getDocument(f[0]);
assertEquals("document", doc.getText());
globalRedo();
assertEquals(dir[0], f[0].getParent());
assertEquals("initial", VfsUtilCore.loadText(f[0]));
doc = FileDocumentManager.getInstance().getDocument(f[0]);
assertEquals("moved", doc.getText());
}
private void renameInCommand(final VirtualFile f, final String name) {
executeCommand(() -> rename(f, name));
}
private void checkSuccessfulRenameUndo(File ioDir) {
try {
globalUndo();
}
catch (Exception ex) {
fail("Unexpected exception: " + ex.getLocalizedMessage());
}
assertTrue(new File(ioDir, "file.txt").exists());
assertNull(myDir.findChild(NEW_NAME));
}
private File createDirOnTheDirToRenamePlaceWithTheSameName() {
File result = new File(VfsUtilCore.virtualToIoFile(myDirToRename.getParent()), DIR_TO_RENAME_NAME);
result.mkdir();
refreshFileSystem();
return result;
}
private File createFileOnTheDirToRenamePlaceWithTheSameName() throws IOException {
File result = new File(VfsUtilCore.virtualToIoFile(myDirToRename.getParent()), DIR_TO_RENAME_NAME);
result.createNewFile();
refreshFileSystem();
return result;
}
private void createTestProjectStructureAndRenameDirectory() {
createDirectory("parent");
myDirToRename = createChildDirectory(myDir, DIR_TO_RENAME_NAME);
createChildData(myDirToRename, "file.txt");
CommandProcessor.getInstance().executeCommand(myProject, () -> rename(myDirToRename, NEW_NAME), "Renaming", null);
}
private static void refreshFileSystem() {
VfsTestUtil.syncRefresh();
}
private void deleteInCommand(final VirtualFile f) {
executeCommand("Delete file", () -> delete(f));
}
private void checkDirDoesNotExist() {
assertNull(myRoot.findChild(myDirName));
}
private void checkDirExists() {
VirtualFile file = myRoot.findChild(myDirName);
assertNotNull(file);
assertTrue(file.isValid());
}
private void createDirectory(final String name) {
executeCommand("Create Directory", () -> myDir = createChildDirectory(myRoot, name));
}
private void deleteDirectory() {
Command command = () -> delete(myDir);
executeCommand("Delete Directory", command);
}
private void moveClassTo(final VirtualFile dirTo) {
Command command = () -> {
VirtualFile file = myClass.getContainingFile().getVirtualFile();
move(file, dirTo);
};
executeCommand("Move class to a new dir", command);
}
public void testSCR5784() throws Exception {
myFile = createFile("Test.java", "abcd efgh ijk");
myEditor = createEditor(myFile.getVirtualFile());
myManager.setOverriddenEditorProvider(new CurrentEditorProvider() {
@Override
public @Nullable FileEditor getCurrentEditor(@Nullable Project project) {
return TextEditorProvider.getInstance().getTextEditor(myEditor);
}
});
final SelectionModel selectionModel = myEditor.getSelectionModel();
final CaretModel caretModel = myEditor.getCaretModel();
final Document document = myEditor.getDocument();
selectionModel.setSelection(0, 4);
caretModel.moveToOffset(4);
String text0 = document.getText();
int caret0 = caretModel.getOffset();
int selStart0 = selectionModel.getSelectionStart();
int selEnd0 = selectionModel.getSelectionEnd();
CommandProcessor.getInstance().executeCommand(myProject, () -> ApplicationManager.getApplication().runWriteAction(() -> {
selectionModel.removeSelection();
document.insertString(document.getTextLength(), "abcd");
selectionModel.setSelection(document.getTextLength() - "abcd".length(), document.getTextLength());
}), "Command 1", "DndGroup");
CommandProcessor.getInstance()
.executeCommand(myProject, () -> ApplicationManager.getApplication().runWriteAction(() -> document.deleteString(0, "abcd".length())),
"Command 2", "DndGroup");
CommandProcessor.getInstance().executeCommand(myProject, EmptyRunnable.getInstance(), "Command 3", null);
String text1 = document.getText();
int caret1 = caretModel.getOffset();
int selStart1 = selectionModel.getSelectionStart();
int selEnd1 = selectionModel.getSelectionEnd();
CommandProcessor.getInstance().executeCommand(myProject, () -> ApplicationManager.getApplication().runWriteAction(() -> {
selectionModel.removeSelection();
document.insertString(4, "abcd");
selectionModel.setSelection(4, 4 + "abcd".length());
}), "Command 4", "DndGroup");
CommandProcessor.getInstance().executeCommand(myProject, () -> ApplicationManager.getApplication()
.runWriteAction(() -> document.deleteString(document.getTextLength() - "abcd".length(), document.getTextLength())), "Command 5",
"DndGroup");
undo(myEditor);
assertEquals(text1, document.getText());
assertEquals(caret1, caretModel.getOffset());
assertEquals(selStart1, selectionModel.getSelectionStart());
assertEquals(selEnd1, selectionModel.getSelectionEnd());
undo(myEditor);
assertEquals(text0, document.getText());
assertEquals(caret0, caretModel.getOffset());
assertEquals(selStart0, selectionModel.getSelectionStart());
assertEquals(selEnd0, selectionModel.getSelectionEnd());
}
public void testEditorWithSeveralDocumentsUndo() {
final VirtualFile file1 = createChildData(myRoot, "file1.txt");
final VirtualFile file2 = createChildData(myRoot, "file2.txt");
final Document document1 = FileDocumentManager.getInstance().getDocument(file1);
final Document document2 = FileDocumentManager.getInstance().getDocument(file2);
Mock.MyFileEditor fileEditor = new Mock.MyFileEditor(document1, document2) {
@Override
public @NotNull VirtualFile getFile() {
return file1;
}
};
UndoManager undoManager = UndoManager.getInstance(myProject);
CommandProcessor.getInstance()
.executeCommand(myProject, () -> ApplicationManager.getApplication().runWriteAction(() -> document2.replaceString(0, 0, "text2")),
"test_command", null, UndoConfirmationPolicy.DO_NOT_REQUEST_CONFIRMATION);
assertTrue(undoManager.isUndoAvailable(fileEditor));
undoManager.undo(fileEditor);
assertFalse(myConfirmationWasRequested);
assertEquals("", document1.getText());
assertEquals("", document2.getText());
undoManager.redo(fileEditor);
assertFalse(myConfirmationWasRequested);
assertEquals("", document1.getText());
assertEquals("text2", document2.getText());
changeText(document1, "");
changeText(document2, "");
changeText(document1, "text1");
changeText(document2, "text2");
assertTrue(undoManager.isUndoAvailable(fileEditor));
undoManager.undo(fileEditor);
assertFalse(myConfirmationWasRequested);
assertEquals("text1", document1.getText());
assertEquals("", document2.getText());
undoManager.undo(fileEditor);
assertFalse(myConfirmationWasRequested);
assertEquals("", document1.getText());
assertEquals("", document2.getText());
undoManager.redo(fileEditor);
assertFalse(myConfirmationWasRequested);
assertEquals("text1", document1.getText());
assertEquals("", document2.getText());
undoManager.redo(fileEditor);
assertFalse(myConfirmationWasRequested);
assertEquals("text1", document1.getText());
assertEquals("text2", document2.getText());
//check documents changes backward
changeText(document1, "");
changeText(document2, "");
changeText(document2, "text2");
changeText(document1, "text1");
assertTrue(undoManager.isUndoAvailable(fileEditor));
undoManager.undo(fileEditor);
assertFalse(myConfirmationWasRequested);
assertEquals("text2", document2.getText());
assertEquals("", document1.getText());
undoManager.undo(fileEditor);
assertFalse(myConfirmationWasRequested);
assertEquals("", document1.getText());
assertEquals("", document2.getText());
undoManager.redo(fileEditor);
assertFalse(myConfirmationWasRequested);
assertEquals("", document1.getText());
assertEquals("text2", document2.getText());
undoManager.redo(fileEditor);
assertFalse(myConfirmationWasRequested);
assertEquals("text1", document1.getText());
assertEquals("text2", document2.getText());
}
public void testMergingSeveralDocumentCommands() {
final VirtualFile[] files = new VirtualFile[3];
files[0] = createChildData(myRoot, "f1.txt");
files[1] = createChildData(myRoot, "f2.txt");
files[2] = createChildData(myRoot, "f3.txt");
executeCommand("command", "ID", () -> setDocumentText(files[0], "text1"));
executeCommand("command", "ID", () -> setDocumentText(files[1], "text2"));
executeCommand("command", "ID", () -> setDocumentText(files[2], "text3"));
//assertGlobalUndoIsAvailable();
assertUndoIsAvailable(getEditor(files[0]));
assertUndoIsAvailable(getEditor(files[1]));
assertUndoIsAvailable(getEditor(files[2]));
//globalUndo();
undo(getEditor(files[0]));
assertEquals("", getDocumentText(files[0]));
assertEquals("", getDocumentText(files[1]));
assertEquals("", getDocumentText(files[2]));
//assertGlobalUndoNotAvailable();
assertUndoNotAvailable(getEditor(files[0]));
assertUndoNotAvailable(getEditor(files[1]));
assertUndoNotAvailable(getEditor(files[2]));
//assertGlobalRedoIsAvailable();
assertRedoIsAvailable(getEditor(files[0]));
assertRedoIsAvailable(getEditor(files[1]));
assertRedoIsAvailable(getEditor(files[2]));
//globalRedo();
redo(getEditor(files[0]));
assertEquals("text1", getDocumentText(files[0]));
assertEquals("text2", getDocumentText(files[1]));
assertEquals("text3", getDocumentText(files[2]));
}
public void testUndoConfirmationPolicy() {
doTest(UndoConfirmationPolicy.DO_NOT_REQUEST_CONFIRMATION, UndoConfirmationPolicy.DO_NOT_REQUEST_CONFIRMATION, false);
doTest(UndoConfirmationPolicy.DO_NOT_REQUEST_CONFIRMATION, UndoConfirmationPolicy.REQUEST_CONFIRMATION, true);
doTest(UndoConfirmationPolicy.REQUEST_CONFIRMATION, UndoConfirmationPolicy.REQUEST_CONFIRMATION, true);
doTest(UndoConfirmationPolicy.REQUEST_CONFIRMATION, UndoConfirmationPolicy.DO_NOT_REQUEST_CONFIRMATION, true);
doTest(UndoConfirmationPolicy.DEFAULT, UndoConfirmationPolicy.DEFAULT, true);
doTest(UndoConfirmationPolicy.REQUEST_CONFIRMATION, UndoConfirmationPolicy.DEFAULT, true);
doTest(UndoConfirmationPolicy.DO_NOT_REQUEST_CONFIRMATION, UndoConfirmationPolicy.DEFAULT, false);
doTest(UndoConfirmationPolicy.DEFAULT, UndoConfirmationPolicy.REQUEST_CONFIRMATION, true);
doTest(UndoConfirmationPolicy.DEFAULT, UndoConfirmationPolicy.DO_NOT_REQUEST_CONFIRMATION, false);
}
private void doTest(UndoConfirmationPolicy policy1, UndoConfirmationPolicy policy2, boolean expected) {
final VirtualFile file1 = createChildData(myRoot, "file1.txt");
final VirtualFile file2 = createChildData(myRoot, "file2.txt");
final Document document1 = FileDocumentManager.getInstance().getDocument(file1);
final Document document2 = FileDocumentManager.getInstance().getDocument(file2);
String groupId = "ID";
changeText(document1, "text1", policy1, groupId);
changeText(document2, "text2", policy2, groupId);
UndoManager undoManager = UndoManager.getInstance(myProject);
Mock.MyFileEditor fileEditor = new Mock.MyFileEditor(document1, document2) {
@Override
public @NotNull VirtualFile getFile() {
return file1;
}
};
assertTrue(undoManager.isUndoAvailable(fileEditor));
undoManager.undo(fileEditor);
assertEquals(expected, myConfirmationWasRequested);
assertEquals("", document1.getText());
assertEquals("", document2.getText());
delete(file1);
delete(file2);
myConfirmationWasRequested = false;
}
private void changeText(final Document document1, final String text) {
changeText(document1, text, UndoConfirmationPolicy.DO_NOT_REQUEST_CONFIRMATION, null);
}
private void changeText(final Document document1, final String text, UndoConfirmationPolicy policy, String groupId) {
CommandProcessor.getInstance().executeCommand(myProject, () -> ApplicationManager.getApplication()
.runWriteAction(() -> document1.replaceString(0, document1.getTextLength(), text)), "test_command", groupId, policy);
}
private void assertFileExists(String fileName, String content) {
assertFileExists(myRoot, fileName, content);
}
private static void assertFileExists(VirtualFile dir, String fileName, String content) {
assertFileExists(dir, fileName);
assertEquals(content, getDocumentText(findFile(fileName, dir)));
}
private static void assertFileDoesNotExist(String fileName, VirtualFile dir) {
assertNull(findFile(fileName, dir));
}
private static void assertFileExists(VirtualFile dir, String fileName) {
StoreUtil.saveDocumentsAndProjectsAndApp(false);
assertNotNull(findFile(fileName, dir));
}
protected static VirtualFile findFile(String className, VirtualFile dir) {
return dir.findChild(className + ".java");
}
private static void setDocumentText(final VirtualFile f, final String text) {
ApplicationManager.getApplication().runWriteAction(() -> FileDocumentManager.getInstance().getDocument(f).setText(text));
}
private static String getDocumentText(VirtualFile f) {
return FileDocumentManager.getInstance().getDocument(f).getText();
}
private void checkAllFilesDeleted() {
assertEquals(0, myRoot.getChildren().length);
}
private Editor openEditor(String fileName) {
return openEditor(myRoot.findChild(fileName));
}
private Editor openEditor(VirtualFile file) {
assertNotNull(file);
return FileEditorManager.getInstance(myProject).openTextEditor(new OpenFileDescriptor(myProject, file), false);
}
protected void deleteClass() {
executeCommand("Delete Class", () -> ApplicationManager.getApplication().runWriteAction(() -> myClass.delete()));
}
protected void createClass(@NonNls final String name) {
createClass(name, myRoot);
}
protected PsiJavaFile createClass(final String name, final VirtualFile dir) {
executeCommand("Create Class" + name, () -> {
ApplicationManager.getApplication().runWriteAction(() -> {
myClass = JavaDirectoryService.getInstance().createClass(myPsiManager.findDirectory(dir), name);
myClass = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(myClass);
});
myContainingFile = (PsiJavaFile)myClass.getContainingFile();
});
return myContainingFile;
}
}