blob: 7b885681994fdb16613a4ce25ef699fd07e097d1 [file] [log] [blame]
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package git4idea.history;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsConfiguration;
import com.intellij.openapi.vcs.VcsDirectoryMapping;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.annotate.FileAnnotation;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vcs.changes.VcsAnnotationLocalChangesListener;
import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
import com.intellij.openapi.vcs.ex.ProjectLevelVcsManagerEx;
import com.intellij.openapi.vcs.update.CommonUpdateProjectAction;
import com.intellij.openapi.vfs.VirtualFile;
import git4idea.GitUtil;
import git4idea.GitVcs;
import git4idea.repo.GitRepository;
import git4idea.test.GitTest;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.lang.reflect.Method;
import java.util.Collections;
/**
* Created with IntelliJ IDEA.
* User: Irina.Chernushina
* Date: 11/26/12
* Time: 1:00 PM
*/
public class GitAnnotationsClosedTest extends GitTest {
private VirtualFile first;
private VirtualFile second;
private volatile boolean myFirstClosed;
private volatile boolean mySecondClosed;
private VcsDirtyScopeManager myVcsDirtyScopeManager;
private ChangeListManager myChangeListManager;
@BeforeMethod
@Override
public void setUp(Method testMethod) throws Exception {
super.setUp(testMethod);
final String[] messages = {"one", "two", "alien1", "three", "alien2"};
final String[] content1 = {"1\n2\n3\n", "1\n2+\n3\n", "a\nb\nc", "1\n2+\n3-\n", "a\nb++\nc"};
first = myRepo.createVFile("a.txt", "init");
second = myRepo.createVFile("b.txt", "init");
myRepo.addCommit("init");
final VirtualFile[] files = {first, first, second, first, second};
for (int i = 0; i < content1.length; i++) {
editFileInCommand(myProject, files[i], content1[i]);
myRepo.addCommit(messages[i]);
}
myFirstClosed = false;
mySecondClosed = false;
myVcsDirtyScopeManager = VcsDirtyScopeManager.getInstance(myProject);
myChangeListManager = ChangeListManager.getInstance(myProject);
}
@Test
public void testClosedByCommitFromIdea() throws Exception {
annotateFirst(first);
editFileInCommand(myProject, first, "1\n2+\n3-ttt\n");
Assert.assertFalse(myFirstClosed);
myVcsDirtyScopeManager.markEverythingDirty();
myChangeListManager.ensureUpToDate(false);
final Change change = myChangeListManager.getChange(first);
Assert.assertNotNull(change);
myVcs.getCheckinEnvironment().commit(Collections.singletonList(change), "***");
myVcsDirtyScopeManager.fileDirty(first);
myChangeListManager.ensureUpToDate(false);
myChangeListManager.ensureUpToDate(false); //after-notifiers
sleep(100); // zipper-updater
Assert.assertTrue(myFirstClosed);
}
@Test
public void testClosedByExternalCommit() throws Exception {
annotateFirst(first);
editFileInCommand(myProject, first, "1\n2+\n3-ttt\n");
Assert.assertFalse(myFirstClosed);
myRepo.addCommit("external_commit");
imitateEvent(myWorkingCopyDir);
sleep(100); // zipper-updater
Assert.assertTrue(myFirstClosed);
}
@Test
public void testClosedByExternalUpdate() throws Exception {
final String head = myRepo.lastCommit();
final String prevHead = myRepo.log("--pretty=format:%H", "-1", "HEAD^");
myRepo.checkout(prevHead);
annotateFirst(first);
annotateSecond();
Assert.assertFalse(myFirstClosed);
Assert.assertFalse(mySecondClosed);
myRepo.checkout(head);
imitateEvent(myWorkingCopyDir);
sleep(100); // zipper-updater
Assert.assertFalse(myFirstClosed);
Assert.assertTrue(mySecondClosed);
}
@Test
public void testClosedByInternalUpdate() throws Exception {
myParentRepo.createFile("d.txt", "d");
myParentRepo.addCommit("empty");
myParentRepo.createBranch("someotherbranch");
annotateFirst(first);
annotateSecond();
Assert.assertFalse(myFirstClosed);
Assert.assertFalse(mySecondClosed);
myRepo.pull();
myRepo.push();
myBrotherRepo.pull();
myBrotherRepo.checkout("master");
final VirtualFile child = myBrotherRepo.getVFRootDir().findChild("a.txt");
Assert.assertNotNull(child);
editFileInCommand(myProject, child, "1\n2+\n3---\n");
myBrotherRepo.addCommit("brother_commit");
myBrotherRepo.push();
Assert.assertFalse(myFirstClosed);
Assert.assertFalse(mySecondClosed);
imitInternalUpdate();
Assert.assertTrue(myFirstClosed);
Assert.assertFalse(mySecondClosed);
}
@Test
public void testAnnotationsAndRenaming() throws Exception {
final String newName = "e.txt";
renameFileInCommand(myProject, first, newName);
final VirtualFile renamed = myRepo.getVFRootDir().findChild(newName);
Assert.assertNotNull(renamed);
sleep(500);
myRepo.run("status");
annotateFirst(renamed);
annotateSecond();
renameFileInCommand(myProject, second, "f.txt");
Assert.assertFalse(myFirstClosed);
Assert.assertFalse(mySecondClosed);
}
private void imitateEvent(final VirtualFile root) {
final GitRepository repository = GitUtil.getRepositoryManager(myProject).getRepositoryForRoot(root);
repository.update();
}
private void imitInternalUpdate() {
final ProjectLevelVcsManagerEx ex = ProjectLevelVcsManagerEx.getInstanceEx(myProject);
ex.setDirectoryMappings(Collections.singletonList(
new VcsDirectoryMapping(FileUtil.toSystemIndependentName(myWorkingCopyDir.getPath()), GitVcs.NAME)));
ex.getOptions(VcsConfiguration.StandardOption.UPDATE).setValue(false);
final CommonUpdateProjectAction action = new CommonUpdateProjectAction();
action.getTemplatePresentation().setText("1");
action.actionPerformed(new AnActionEvent(null,
new DataContext() {
@Nullable
@Override
public Object getData(@NonNls String dataId) {
if (CommonDataKeys.PROJECT.is(dataId)) {
return myProject;
}
return null;
}
}, "test", new Presentation(), null, 0));
myChangeListManager.ensureUpToDate(false);
myChangeListManager.ensureUpToDate(false); // wait for after-events like annotations recalculation
sleep(100); // zipper updater
}
private void annotateFirst(final VirtualFile first) throws VcsException {
final VcsAnnotationLocalChangesListener listener = ProjectLevelVcsManager.getInstance(myProject).getAnnotationLocalChangesListener();
final FileAnnotation annotation = createTestAnnotation(myVcs.getAnnotationProvider(), first);
annotation.setCloser(new Runnable() {
@Override
public void run() {
myFirstClosed = true;
listener.unregisterAnnotation(first, annotation);
}
});
listener.registerAnnotation(first, annotation);
}
private void annotateSecond() throws VcsException {
final VcsAnnotationLocalChangesListener listener = ProjectLevelVcsManager.getInstance(myProject).getAnnotationLocalChangesListener();
final FileAnnotation annotation = createTestAnnotation(myVcs.getAnnotationProvider(), second);
annotation.setCloser(new Runnable() {
@Override
public void run() {
mySecondClosed = true;
listener.unregisterAnnotation(second, annotation);
}
});
listener.registerAnnotation(second, annotation);
}
private void sleep(int time) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
//
}
}
}