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()); } }