PerforceIntegration/testSource/org/jetbrains/idea/perforce/OfflineModeTest.java (691 lines of code) (raw):
package org.jetbrains.idea.perforce;
import com.intellij.diagnostic.ThreadDumper;
import com.intellij.execution.process.ProcessOutput;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.changes.*;
import com.intellij.openapi.vcs.history.VcsFileRevision;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.perforce.application.PerforceFileRevision;
import org.jetbrains.idea.perforce.operations.P4EditOperation;
import org.jetbrains.idea.perforce.operations.P4MoveRenameOperation;
import org.jetbrains.idea.perforce.operations.VcsOperation;
import org.jetbrains.idea.perforce.operations.VcsOperationLog;
import org.jetbrains.idea.perforce.perforce.PerforceCachingContentRevision;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.intellij.testFramework.UsefulTestCase.*;
@SuppressWarnings("SameParameterValue")
public class OfflineModeTest extends PerforceTestCase {
private static final Logger LOG = Logger.getInstance(OfflineModeTest.class);
@Override
@Before
public void before() throws Exception {
super.before();
setStandardConfirmation("Perforce", VcsConfiguration.StandardConfirmation.ADD, VcsShowConfirmationOption.Value.DO_NOTHING_SILENTLY);
setStandardConfirmation("Perforce", VcsConfiguration.StandardConfirmation.REMOVE, VcsShowConfirmationOption.Value.DO_NOTHING_SILENTLY);
}
@Test
public void testOfflineAdd() {
enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
goOffline();
createFileInCommand("a.txt", null);
goOnline();
verifyOpened("a.txt", "add");
}
@Test
public void testOfflineDelete() {
enableSilentOperation(VcsConfiguration.StandardConfirmation.REMOVE);
VirtualFile file = createAndSubmit("a.txt", "original content");
goOffline();
deleteFileInCommand(file);
goOnline();
verifyOpened("a.txt", "delete");
}
@Test
public void testOfflineChanges() throws IOException {
WriteAction.computeAndWait(() -> myWorkingCopyDir.createChildData(this, "a.txt"));
addFile("a.txt");
ChangeListManagerImpl changeListManager = ChangeListManagerImpl.getInstanceImpl(myProject);
changeListManager.ensureUpToDate();
LocalChangeList list = changeListManager.getDefaultChangeList();
Assert.assertEquals(1, list.getChanges().size());
// this is needed since last successful update tracker gets notified after local changes update
// (on the same thread)
changeListManager.ensureUpToDate();
goOffline();
VcsDirtyScopeManager.getInstance(myProject).markEverythingDirty();
changeListManager.ensureUpToDate();
list = changeListManager.getDefaultChangeList();
Collection<Change> changes = list.getChanges();
Assert.assertEquals(1, changes.size());
Change c = changes.iterator().next();
Assert.assertNull(c.getBeforeRevision());
ContentRevision afterRevision = c.getAfterRevision();
Assert.assertTrue(afterRevision instanceof CurrentContentRevision);
}
@Test
public void testChangesForAddDoneOffline() {
enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
goOffline();
createFileInCommand("a.txt", null);
refreshChanges();
Collection<Change> changes = ChangeListManagerImpl.getInstanceImpl(myProject).getDefaultChangeList().getChanges();
Assert.assertEquals(1, changes.size());
}
@Test
public void testChangesForEditDoneOffline() throws Exception {
final VirtualFile fileToEdit = createAndSubmit("a.txt", "original content");
refreshChanges();
goOffline();
refreshChanges();
openForEdit(fileToEdit);
setFileText(fileToEdit, "new content");
refreshChanges();
assertEquals(FileStatus.MODIFIED, FileStatusManager.getInstance(myProject).getStatus(fileToEdit));
Change c = getSingleChange();
Assert.assertTrue(c.getBeforeRevision() instanceof PerforceCachingContentRevision);
Assert.assertTrue(c.getAfterRevision() instanceof CurrentContentRevision);
Assert.assertEquals("original content", c.getBeforeRevision().getContent());
Assert.assertEquals("new content", c.getAfterRevision().getContent());
}
@Test
public void testChangesForDeleteDoneOffline() {
enableSilentOperation(VcsConfiguration.StandardConfirmation.REMOVE);
final VirtualFile fileToEdit = createAndSubmit("a.txt", "original content");
goOffline();
deleteFileInCommand(fileToEdit);
refreshChanges();
Change c = getSingleChange();
Assert.assertTrue(c.getBeforeRevision() instanceof PerforceCachingContentRevision);
Assert.assertNull(c.getAfterRevision());
// TODO[yole]: implement when LocalVCS allows to retrieve content for deleted files
//Assert.assertEquals("original content", c.getBeforeRevision().getContent());
}
@Test
public void testChangesForRenameDoneOffline() {
final VirtualFile fileToEdit = doTestChangesForRenameDoneOffline();
final List<VcsFileRevision> revisionList = getFileHistory(fileToEdit);
assertEquals(2, revisionList.size());
assertEquals("move/add", ((PerforceFileRevision)revisionList.get(0)).getAction());
}
private VirtualFile doTestChangesForRenameDoneOffline() {
final VirtualFile fileToEdit = createAndSubmit("a.txt", "original content");
goOffline();
renameFileInCommand(fileToEdit, "b.txt");
refreshChanges();
Change c = getSingleChange();
Assert.assertTrue(c.getBeforeRevision().getFile().getPath().endsWith("a.txt"));
Assert.assertTrue(c.getAfterRevision().getFile().getPath().endsWith("b.txt"));
goOnline();
submitDefaultList("comment");
refreshChanges();
return fileToEdit;
}
@Test
public void testPreserveModifiedWithoutCheckout() {
VirtualFile file = createAndSubmit("a.txt", "something");
refreshVfs();
getChangeListManager().waitUntilRefreshed();
assertEmpty(getChangeListManager().getModifiedWithoutEditing());
editExternally(file, "something else");
getChangeListManager().waitUntilRefreshed();
assertOrderedEquals(getChangeListManager().getModifiedWithoutEditing(), file);
goOffline();
refreshChanges();
assertOrderedEquals(getChangeListManager().getModifiedWithoutEditing(), file);
goOnline();
refreshChanges();
assertOrderedEquals(getChangeListManager().getModifiedWithoutEditing(), file);
}
@Test
public void testExternalChangeAsModifiedWithoutCheckout() throws Exception {
VirtualFile file = createAndSubmit("a.txt", "something");
goOffline();
refreshChanges();
assertEmpty(getChangeListManager().getModifiedWithoutEditing());
editExternally(file, "something else");
refreshChanges();
assertOrderedEquals(getChangeListManager().getModifiedWithoutEditing(), file);
rollbackModifiedWithoutCheckout(file);
assertEquals("something", LoadTextUtil.loadText(file).toString());
assertFalse(file.isWritable());
getChangeListManager().waitUntilRefreshed();
assertEmpty(getChangeListManager().getModifiedWithoutEditing());
}
@Test
public void testTwoQuickChanges() {
VirtualFile file = createAndSubmit("a.txt", "something");
refreshChanges();
goOffline();
refreshChanges();
assertEmpty(getChangeListManager().getModifiedWithoutEditing());
openForEdit(file);
editFileInCommand(file, "something1");
editFileInCommand(file, "something2");
refreshChanges();
rollbackChange(getSingleChange());
assertEquals("something", LoadTextUtil.loadText(file).toString());
}
@Test
public void testRevertCheckedOut() {
VirtualFile file = createAndSubmit("a.txt", "something");
refreshChanges();
goOffline();
refreshChanges();
assertEmpty(getChangeListManager().getModifiedWithoutEditing());
openForEdit(file);
refreshChanges();
assertEmpty(getChangeListManager().getModifiedWithoutEditing());
rollbackChange(getSingleChange());
assertEquals("something", LoadTextUtil.loadText(file).toString());
}
@Test
public void testOfflineRevertForEditDoneOutsideIdea() throws Exception {
final File ioFile = new File(myClientRoot, "a.txt");
assertTrue(ioFile.createNewFile());
addFile("a.txt");
FileUtil.writeToFile(ioFile, "original content");
submitFile("//depot/a.txt");
verify(runP4WithClient("edit", ioFile.getAbsolutePath()));
FileUtil.writeToFile(ioFile, "new content");
final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(ioFile);
refreshChanges();
getSingleChange();
goOffline();
refreshChanges();
rollbackChange(getSingleChange());
assertEquals("original content", getFileText(file));
}
@Test
public void testOfflineContentForRenameDoneOnline() throws Exception {
final VirtualFile fileToEdit = createAndSubmit("a.txt", "original content");
refreshChanges();
renameFileInCommand(fileToEdit, "b.txt");
refreshChanges();
getSingleChange();
goOffline();
refreshChanges();
final Change change = getSingleChange();
assertNotNull(change.getBeforeRevision().getContent());
assertNotNull(change.getAfterRevision().getContent());
}
@Test
public void testChangesForRenameDoneOffline_Old() {
forceDisableMoveCommand();
final VirtualFile fileToEdit = doTestChangesForRenameDoneOffline();
final List<VcsFileRevision> revisionList = getFileHistory(fileToEdit);
assertEquals(2, revisionList.size());
assertEquals("add", ((PerforceFileRevision)revisionList.get(0)).getAction());
}
@Test
public void testSeveralRenameMoveOperationsOffline() {
final VirtualFile fileToEdit = doTestSeveralRenameMoveOperationsOffline();
final List<VcsFileRevision> revisionList = getFileHistory(fileToEdit);
assertEquals(2, revisionList.size());
assertEquals("move/add", ((PerforceFileRevision)revisionList.get(0)).getAction());
}
private VirtualFile doTestSeveralRenameMoveOperationsOffline() {
enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
final VirtualFile file1 = createFileInCommand("a.txt", "original content");
final VirtualFile file2 = createFileInCommand("b.txt", "original content");
submitDefaultList("initial");
refreshChanges();
goOffline();
watchVfsEvents();
final VirtualFile dir1 = createDirInCommand(myWorkingCopyDir, "dir1");
moveFileInCommand(file1, dir1);
renameFileInCommand(file1, "b.txt");
moveFileInCommand(dir1, createDirInCommand(myWorkingCopyDir, "dir2"));
assertNull(myWorkingCopyDir.findChild("dir1"));
renameFileInCommand(file1, "c.txt");
moveFileInCommand(file2, createDirInCommand(myWorkingCopyDir, "dir1"));
refreshChanges();
Collection<Change> changes = ChangeListManagerImpl.getInstanceImpl(myProject).getDefaultChangeList().getChanges();
assertUnorderedCollection(changes, c -> {
Assert.assertTrue(c.getBeforeRevision().getFile().getPath().endsWith("a.txt"));
Assert.assertTrue(c.getAfterRevision().getFile().getPath().endsWith("dir2/dir1/c.txt"));
}, c -> {
Assert.assertTrue(c.getBeforeRevision().getFile().getPath().endsWith("b.txt"));
Assert.assertTrue(c.getAfterRevision().getFile().getPath().endsWith("dir1/b.txt"));
}
);
goOnline();
submitDefaultList("comment");
refreshChanges();
return file1;
}
@Test
public void testSeveralRenameMoveOperationsOffline_Old() {
forceDisableMoveCommand();
final VirtualFile fileToEdit = doTestSeveralRenameMoveOperationsOffline();
final List<VcsFileRevision> revisionList = getFileHistory(fileToEdit);
assertEquals(2, revisionList.size());
assertEquals("add", ((PerforceFileRevision)revisionList.get(0)).getAction());
}
@Test
public void testOfflineRevertForOnlineEdit() throws Exception {
final VirtualFile fileToEdit = createAndSubmit("a.txt", "original content");
refreshChanges();
openForEdit(fileToEdit);
setFileText(fileToEdit, "new content");
refreshChanges();
assertEquals(FileStatus.MODIFIED, FileStatusManager.getInstance(myProject).getStatus(fileToEdit));
ensureContentCached(getSingleChange());
goOffline();
refreshChanges();
rollbackChange(getSingleChange());
Assert.assertEquals("original content", getFileText(fileToEdit));
Assert.assertFalse(fileToEdit.isWritable());
refreshChanges();
Assert.assertEquals(0, ChangeListManagerImpl.getInstanceImpl(myProject).getDefaultChangeList().getChanges().size());
goOnline();
refreshChanges();
Assert.assertEquals(0, getFilesInDefaultChangelist().size());
}
@Test
public void testOfflineRevertForOfflineEdit() throws Exception {
final VirtualFile fileToEdit = createAndSubmit("a.txt", "original content");
refreshChanges();
goOffline();
openForEdit(fileToEdit);
setFileText(fileToEdit, "new content");
refreshChanges();
Change c = getSingleChange();
rollbackChange(c);
Assert.assertEquals("original content", getFileText(fileToEdit));
refreshChanges();
Assert.assertEquals(0, ChangeListManagerImpl.getInstanceImpl(myProject).getDefaultChangeList().getChanges().size());
}
@Test
public void testOfflineRevertForOnlineAdd() {
enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
createFileInCommand("a.txt", "content");
refreshChanges();
goOffline();
rollbackChange(getSingleChange());
refreshChanges();
Assert.assertEquals(0, ChangeListManagerImpl.getInstanceImpl(myProject).getDefaultChangeList().getChanges().size());
goOnline();
Assert.assertEquals(0, getFilesInDefaultChangelist().size());
}
@Test
public void testOfflineRevertForOfflineAdd() {
enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
goOffline();
createFileInCommand("a.txt", "content");
refreshChanges();
rollbackChange(getSingleChange());
refreshChanges();
Assert.assertEquals(0, ChangeListManagerImpl.getInstanceImpl(myProject).getDefaultChangeList().getChanges().size());
Assert.assertEquals(0, VcsOperationLog.getInstance(myProject).getPendingOperations().size());
}
@Test
public void testRenameMoveRevert() {
enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
final VirtualFile foo = createDirInCommand(myWorkingCopyDir, "foo");
final VirtualFile file = createFileInCommand(foo, "a.txt", "");
refreshChanges();
getSingleChange();
submitDefaultList("initial");
refreshVfs();
refreshChanges();
goOffline();
refreshChanges();
assertEmpty(getChangeListManager().getModifiedWithoutEditing());
assertEmpty(getChangeListManager().getUnversionedFiles());
assertEmpty(getChangeListManager().getDefaultChangeList().getChanges());
renameFileInCommand(file, "b.txt");
assertNotNull(LastUnchangedContentTracker.getLastUnchangedContent(file));
getChangeListManager().waitUntilRefreshed();
assertNotNull(LastUnchangedContentTracker.getLastUnchangedContent(file));
watchVfsEvents();
renameFileInCommand(foo, "bar");
assertTrue(file.isValid());
assertNotNull(LastUnchangedContentTracker.getLastUnchangedContent(file));
getChangeListManager().waitUntilRefreshed();
assertTrue(file.isValid());
assertNotNull(LastUnchangedContentTracker.getLastUnchangedContent(file));
assertInstanceOf(assertOneElement(VcsOperationLog.getInstance(myProject).getPendingOperations()), P4MoveRenameOperation.class);
Change c = getSingleChange();
assertEquals(Change.Type.MOVED, c.getType());
rollbackChange(c);
getChangeListManager().waitUntilRefreshed();
assertEmpty(assertOneElement(getChangeListManager().getChangeLists()).getChanges());
assertNotNull(myWorkingCopyDir.findFileByRelativePath("foo/a.txt"));
assertNull(myWorkingCopyDir.findFileByRelativePath("bar/a.txt"));
assertNull(myWorkingCopyDir.findFileByRelativePath("bar/b.txt"));
assertNull(myWorkingCopyDir.findFileByRelativePath("foo/b.txt"));
}
private void watchVfsEvents() {
myProject.getMessageBus().connect().subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener() {
@Override
public void after(@NotNull List<? extends @NotNull VFileEvent> events) {
LOG.debug("OfflineModeTest.after: " + events);
LOG.debug(ThreadDumper.dumpThreadsToString());
}
});
}
@Test
public void testOfflineRevertForOfflineRename() {
setStandardConfirmation("Perforce", VcsConfiguration.StandardConfirmation.REMOVE, VcsShowConfirmationOption.Value.DO_ACTION_SILENTLY);
final VirtualFile file = createAndSubmit("a.txt", "content");
refreshChanges();
goOffline();
openForEdit(file);
renameFileInCommand(file, "b.txt");
refreshChanges();
Change c = getSingleChange();
rollbackChange(c);
refreshChanges();
Assert.assertEquals("a.txt", file.getName());
Assert.assertEquals(0, ChangeListManagerImpl.getInstanceImpl(myProject).getDefaultChangeList().getChanges().size());
Assert.assertEquals(0, VcsOperationLog.getInstance(myProject).getPendingOperations().size());
goOnline();
final VirtualFile anotherFile = createFileInCommand("c.txt", "");
getChangeListManager().waitUntilRefreshed();
deleteFileInCommand(anotherFile);
getChangeListManager().waitUntilRefreshed();
Assert.assertEquals(0, ChangeListManagerImpl.getInstanceImpl(myProject).getDefaultChangeList().getChanges().size());
}
@Test
public void testOfflineDeleteAfterOfflineAdd() {
enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
enableSilentOperation(VcsConfiguration.StandardConfirmation.REMOVE);
goOffline();
final VirtualFile file = createFileInCommand("a.txt", "content");
deleteFileInCommand(file);
refreshChanges();
Assert.assertEquals(0, ChangeListManagerImpl.getInstanceImpl(myProject).getDefaultChangeList().getChanges().size());
Assert.assertEquals(0, VcsOperationLog.getInstance(myProject).getPendingOperations().size());
}
@Test
public void testMergeAddAndRename() {
enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
goOffline();
final VirtualFile file = createFileInCommand("a.txt", "content");
renameFileInCommand(file, "b.txt");
refreshChanges();
Change c = getSingleChange();
Assert.assertTrue(c.getAfterRevision().getFile().getPath().endsWith("b.txt"));
Assert.assertEquals(1, VcsOperationLog.getInstance(myProject).getPendingOperations().size());
}
@Test
public void testMergeTwoRenames() {
final VirtualFile file = createAndSubmit("a.txt", "content");
refreshChanges();
goOffline();
renameFileInCommand(file, "b.txt");
renameFileInCommand(file, "c.txt");
refreshChanges();
Change c = getSingleChange();
Assert.assertTrue(c.getAfterRevision().getFile().getPath().endsWith("c.txt"));
Assert.assertEquals(1, VcsOperationLog.getInstance(myProject).getPendingOperations().size());
}
@Test
public void testCyclicRename() {
final VirtualFile file = createAndSubmit("a.txt", "content");
refreshChanges();
goOffline();
renameFileInCommand(file, "b.txt");
renameFileInCommand(file, "a.txt");
refreshChanges();
Change c = getSingleChange();
final ContentRevision beforeRevision = c.getBeforeRevision();
assertNotNull(c.toString(), beforeRevision);
Assert.assertTrue(beforeRevision.getFile().getPath().endsWith("a.txt"));
Assert.assertTrue(c.getAfterRevision().getFile().getPath().endsWith("a.txt"));
final List<VcsOperation> pendingOps = VcsOperationLog.getInstance(myProject).getPendingOperations();
Assert.assertEquals(1, pendingOps.size());
Assert.assertTrue(pendingOps.get(0) instanceof P4EditOperation);
}
@Test
public void testRevertCyclicRename() throws Exception {
final VirtualFile file = createAndSubmit("a.txt", "content");
refreshChanges();
goOffline();
openForEdit(file);
renameFileInCommand(file, "b.txt");
setFileText(file, "new content");
renameFileInCommand(file, "a.txt");
refreshChanges();
Change c = getSingleChange();
rollbackChange(c);
Assert.assertEquals("content", getFileText(file));
}
@Test
public void testAddInChangelist() {
goOffline();
enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
final LocalChangeList oldDefaultList = switchToChangeList("Second");
createFileInCommand("a.txt", "new content");
switchToChangeList(oldDefaultList);
refreshChanges();
final ChangeListManager clManager = ChangeListManagerImpl.getInstanceImpl(myProject);
final List<LocalChangeList> lists = clManager.getChangeLists();
Assert.assertEquals(2, lists.size());
final LocalChangeList list = clManager.findChangeList("Second");
Assert.assertEquals(1, list.getChanges().size());
goOnline();
verifyOpenedInList("Second", "a.txt");
}
@Test
public void testEditInChangelist() {
VirtualFile f = createAndSubmit("a.txt", "old content");
goOffline();
final LocalChangeList oldDefaultList = switchToChangeList("Second");
openForEdit(f);
switchToChangeList(oldDefaultList);
goOnline();
verifyOpenedInList("Second", "a.txt");
}
@Test
public void testDeleteInChangelist() {
enableSilentOperation(VcsConfiguration.StandardConfirmation.REMOVE);
VirtualFile f = createAndSubmit("a.txt", "old content");
goOffline();
final LocalChangeList oldDefaultList = switchToChangeList("Second");
deleteFileInCommand(f);
switchToChangeList(oldDefaultList);
goOnline();
verifyOpenedInList("Second", "a.txt");
}
@Test
public void testRenameInChangelist() {
doTestRenameInChangelist();
}
private void doTestRenameInChangelist() {
final VirtualFile fileToEdit = createAndSubmit("a.txt", "original content");
goOffline();
final LocalChangeList oldDefaultList = switchToChangeList("Second");
renameFileInCommand(fileToEdit, "b.txt");
switchToChangeList(oldDefaultList);
goOnline();
refreshChanges();
verifyOpenedInList("Second", "a.txt");
verifyOpenedInList("Second", "b.txt");
}
@Test
public void testRenameInChangelist_Old() {
forceDisableMoveCommand();
doTestRenameInChangelist();
}
@Test
public void testReopen() {
final VirtualFile file = createAndSubmit("a.txt", "original content");
openForEdit(file);
refreshChanges();
getSingleChange();
refreshChanges();
goOffline();
refreshChanges();
Change c = getSingleChange();
ChangeListManager clManager = ChangeListManagerImpl.getInstanceImpl(myProject);
final LocalChangeList list = clManager.addChangeList("Second", "");
clManager.moveChangesTo(list, c);
refreshChanges();
final List<LocalChangeList> lists = clManager.getChangeLists();
Assert.assertEquals(2, lists.size());
Assert.assertEquals(1, clManager.findChangeList("Second").getChanges().size());
final List<VcsOperation> pendingOps = VcsOperationLog.getInstance(myProject).getPendingOperations();
Assert.assertEquals(1, pendingOps.size());
goOnline();
verifyOpenedInList("Second", "a.txt");
}
@Test
public void testMergeReopen() {
final VirtualFile file = createAndSubmit("a.txt", "original content");
refreshChanges();
goOffline();
openForEdit(file);
refreshChanges();
Change c = getSingleChange();
ChangeListManager clManager = ChangeListManagerImpl.getInstanceImpl(myProject);
final LocalChangeList list = clManager.addChangeList("Second", "");
clManager.moveChangesTo(list, c);
final List<LocalChangeList> lists = clManager.getChangeLists();
Assert.assertEquals(2, lists.size());
Assert.assertEquals(1, clManager.findChangeList("Second").getChanges().size());
final List<VcsOperation> pendingOps = VcsOperationLog.getInstance(myProject).getPendingOperations();
Assert.assertEquals(1, pendingOps.size());
}
@Test
public void testMergeReopenRename() {
final VirtualFile file = createAndSubmit("a.txt", "original content");
refreshChanges();
goOffline();
openForEdit(file);
renameFileInCommand(file, "b.txt");
refreshChanges();
Change c = getSingleChange();
ChangeListManager clManager = ChangeListManagerImpl.getInstanceImpl(myProject);
final LocalChangeList list = clManager.addChangeList("Second", "");
clManager.moveChangesTo(list, c);
final List<LocalChangeList> lists = clManager.getChangeLists();
Assert.assertEquals(2, lists.size());
Assert.assertEquals(1, clManager.findChangeList("Second").getChanges().size());
final List<VcsOperation> pendingOps = VcsOperationLog.getInstance(myProject).getPendingOperations();
Assert.assertEquals(1, pendingOps.size());
}
@Test
public void testOfflineCopy() {
enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
final VirtualFile file = createAndSubmit("a.txt", "content");
goOffline();
copyFileInCommand(file, "b.txt");
goOnline();
verifyOpened("b.txt", "add");
ProcessOutput result = runP4WithClient("resolved");
String stdout = result.getStdout().trim();
Assert.assertTrue(stdout.endsWith("b.txt - branch from //depot/a.txt#1"));
}
@Test
public void testUnversionedVsHijacked() {
final VirtualFile fileA = createFileInCommand("a.txt", "content");
addFile("a.txt");
submitDefaultList("initial");
refreshVfs();
VirtualFile fileB = createFileInCommand("b.txt", "");
getChangeListManager().waitUntilRefreshed();
assertSameElements(getChangeListManager().getUnversionedFiles(), fileB);
assertEmpty(getChangeListManager().getModifiedWithoutEditing());
goOffline();
refreshChanges();
assertSameElements(getChangeListManager().getUnversionedFiles(), fileB);
assertEmpty(getChangeListManager().getModifiedWithoutEditing());
editExternally(fileA, "hijacked");
VirtualFile fileC = createFileInCommand("c.txt", "");
getChangeListManager().waitUntilRefreshed();
assertSameElements(getChangeListManager().getUnversionedFiles(), fileB, fileC);
assertSameElements(getChangeListManager().getModifiedWithoutEditing(), fileA);
}
@Test
public void testIgnoredInOfflineMode() {
createFileInCommand("a.txt", "content");
addFile("a.txt");
submitDefaultList("initial");
refreshVfs();
goOffline();
refreshChanges();
VirtualFile fileB = createFileInCommand("b.txt", "");
List<FilePath> ignoredFiles = new ArrayList<>();
ignoredFiles.add(VcsUtil.getFilePath(myP4IgnoreFile, false));
ignoredFiles.add(VcsUtil.getFilePath(myP4ConfigFile, false));
VcsDirtyScopeManager.getInstance(myProject).fileDirty(VcsUtil.getFilePath(new File(myClientRoot, "b.txt")));
refreshVfs();
refreshChanges();
getChangeListManager().waitUntilRefreshed();
assertSameElements(getChangeListManager().getUnversionedFiles(), fileB);
assertSameElements(getChangeListManager().getIgnoredFilePaths(), ignoredFiles);
}
private VirtualFile createAndSubmit(final String fileName, final String content) {
enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
final VirtualFile fileToEdit = createFileInCommand(fileName, content);
submitFile("//depot/" + fileName);
fileToEdit.refresh(false, false);
refreshChanges();
return fileToEdit;
}
private static String getFileText(final VirtualFile fileToEdit) throws IOException {
return CharsetToolkit.bytesToString(fileToEdit.contentsToByteArray(), StandardCharsets.UTF_8);
}
private static void ensureContentCached(final Change c) throws VcsException {
final ContentRevision beforeRevision = c.getBeforeRevision();
assert beforeRevision != null;
beforeRevision.getContent();
}
private LocalChangeList switchToChangeList(final String name) {
final ChangeListManager clManager = ChangeListManagerImpl.getInstanceImpl(myProject);
final LocalChangeList list = clManager.addChangeList(name, "");
final LocalChangeList oldDefaultList = clManager.getDefaultChangeList();
clManager.setDefaultChangeList(list);
return oldDefaultList;
}
private void switchToChangeList(final LocalChangeList oldDefaultList) {
ChangeListManagerImpl.getInstanceImpl(myProject).setDefaultChangeList(oldDefaultList);
}
private void verifyOpenedInList(final String changeListName, final String path) {
ProcessOutput execResult = runP4WithClient("changes", "-i", "-t", "-s", "pending");
final String stdout = execResult.getStdout().trim();
Pattern pattern = Pattern.compile("Change (\\d+).+'(.+) '");
Matcher m = pattern.matcher(stdout);
Assert.assertTrue("Unexpected pending changes: " + stdout, m.matches());
Assert.assertEquals(changeListName, m.group(2));
execResult = runP4WithClient("describe", "-s", m.group(1));
Assert.assertTrue(execResult.getStdout().contains("... //depot/" + path));
}
@Test
public void testAddAfterDelete() {
setStandardConfirmation("Perforce", VcsConfiguration.StandardConfirmation.ADD, VcsShowConfirmationOption.Value.DO_ACTION_SILENTLY);
setStandardConfirmation("Perforce", VcsConfiguration.StandardConfirmation.REMOVE, VcsShowConfirmationOption.Value.DO_ACTION_SILENTLY);
VirtualFile file = createFileInCommand("a.txt", "");
submitDefaultList("initial");
refreshVfs();
refreshChanges();
goOffline();
refreshChanges();
deleteFileInCommand(file);
assertFalse(file.isValid());
assertFalse(VfsUtilCore.virtualToIoFile(file).exists());
getChangeListManager().waitUntilRefreshed();
Assert.assertEquals(Change.Type.DELETED, getSingleChange().getType());
createFileInCommand("a.txt", "new content");
getChangeListManager().waitUntilRefreshed();
Assert.assertEquals(Change.Type.MODIFICATION, getSingleChange().getType());
goOnline();
refreshChanges();
Assert.assertEquals(Change.Type.MODIFICATION, getSingleChange().getType());
}
}