blob: ff07a3a6a9f1948cee362310e86335bd3baf787d [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 hg4idea.test.merge;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.merge.MergeData;
import com.intellij.openapi.vcs.merge.MergeProvider;
import com.intellij.openapi.vfs.VirtualFile;
import hg4idea.test.HgPlatformTest;
import hg4idea.test.HgTestUtil;
import org.testng.Assert;
import org.zmlx.hg4idea.HgVcs;
import java.io.IOException;
import static com.intellij.openapi.vcs.Executor.cd;
import static com.intellij.openapi.vcs.Executor.echo;
import static com.intellij.openapi.vcs.Executor.touch;
import static hg4idea.test.HgExecutor.*;
public class HgMergeProviderTest extends HgPlatformTest {
protected MergeProvider myMergeProvider;
@Override
protected void setUp() throws Exception {
super.setUp();
HgVcs vcs = HgVcs.getInstance(myProject);
assertNotNull(vcs);
myMergeProvider = vcs.getMergeProvider();
assertNotNull(myMergeProvider);
}
public void testMerge2BranchesIfFileCreatedSeparatelyInBoth() throws VcsException {
cd(myRepository);
hg("branch branchA");
hg("commit -m 'create branchA' ");
String aFile = "A.txt";
touch(aFile, "a");
hg("add " + aFile);
hg("commit -m 'create file in branchA' ");
hg("up default");
touch(aFile, "default");
hg("add " + aFile);
hg("commit -m 'create file in default branch'");
hgMergeWith("branchA");
verifyMergeData(myRepository.findChild(aFile), "", "default", "a");
}
public void testMerge2Branches() throws VcsException {
cd(myRepository);
String aFile = "A.txt";
touch(aFile, "base");
hg("add " + aFile);
hg("commit -m 'create file'");
hg("branch branchA");
hg("commit -m 'create branchA'");
echo(aFile, " modify with a");
hg("commit -m 'modify file in branchA'");
hg("up default");
echo(aFile, " modify with b");
hg("commit -m 'modify file in default'");
hgMergeWith("branchA");
verifyMergeData(myRepository.findChild(aFile), "base", "base modify with b", "base modify with a");
}
public void testMergeWithCommittedLocalChange() throws Exception {
prepareSecondRepository();
final Pair<VirtualFile, VirtualFile> files = prepareFileInBothRepositories();
final VirtualFile parentFile = files.first;
final VirtualFile childFile = files.second;
//Edit the file in parent repository, commit the change.
cd(myRepository);
HgTestUtil.printToFile(parentFile, "server");
hg("commit -m " + COMMIT_MESSAGE);
//Edit the file in child repository, commit the change.
cd(myChildRepo);
HgTestUtil.printToFile(childFile, "local");
hg("commit -m " + COMMIT_MESSAGE);
updateProject();
//committing conflicting change
verifyMergeData(myChildRepo.findChild(childFile.getName()), "basic", "local", "server");
}
public void testMergeWithUncommittedLocalChange() throws Exception {
prepareSecondRepository();
final Pair<VirtualFile, VirtualFile> files = prepareFileInBothRepositories();
final VirtualFile parentFile = files.first;
final VirtualFile childFile = files.second;
//Edit the file in parent repository, commit the change.
cd(myRepository);
HgTestUtil.printToFile(parentFile, "server");
hg("commit -m " + COMMIT_MESSAGE);
// Edit the file in child repository, don't commit the change.
cd(myChildRepo);
HgTestUtil.printToFile(childFile, "local");
updateProject();
//uncommitted conflicting change
verifyMergeData(myChildRepo.findChild(childFile.getName()), "basic", "local", "server");
}
public void testFileAddedAndCommitted() throws Exception {
// this is needed to have the same root changeset - otherwise conflicting root changeset will cause
// an error during 'hg pull': "abort: repository is unrelated"
prepareSecondRepository();
prepareFileInBothRepositories();
//Add a file in parent repository, commit.
cd(myRepository);
String bFile = "B.txt";
touch(bFile, "server");
hg("add " + bFile);
hg("commit -m " + COMMIT_MESSAGE);
//Add a file with the same name, but different content in child repository, commit.
cd(myChildRepo);
touch(bFile, "local");
hg("add " + bFile);
hg("commit -m " + COMMIT_MESSAGE);
updateProject();
verifyMergeData(myChildRepo.findChild(bFile), "", "local", "server");
}
public void testFileAddedNotCommitted() throws Exception {
// this is needed to have the same root changeset - otherwise conflicting root changeset will cause
// an error during 'hg pull': "abort: repository is unrelated"
prepareSecondRepository();
prepareFileInBothRepositories();
// Add a file in parent repository, commit.
cd(myRepository);
String bFile = "B.txt";
touch(bFile, "server");
hg("add " + bFile);
hg("commit -m " + COMMIT_MESSAGE);
//Add a file with the same name, but different content in child repository, don't commit.
cd(myChildRepo);
touch(bFile, "local");
myChildRepo.refresh(false, true);
hg("add " + bFile);
updateProject();
verifyMergeData(myChildRepo.findChild(bFile), "", "local", "server");
}
/**
* Creates a file with initial content in the parent repository, pulls & updates it to the child repository.
*
* @return References to the files in parent and child repositories respectively.
*/
private Pair<VirtualFile, VirtualFile> prepareFileInBothRepositories() throws IOException {
cd(myRepository);
String aFile = "A.txt";
touch(aFile, "basic");
hg("add " + aFile);
hg("commit -m 'create file' ");
hg("update");
myRepository.refresh(false, true);
final VirtualFile parentFile = myRepository.findChild(aFile);
assertNotNull("Can't find " + aFile + " in parent repo!", parentFile);
cd(myChildRepo);
hg("pull");
hg("update");
myChildRepo.refresh(false, true);
final VirtualFile childFile = myChildRepo.findChild(aFile);
return Pair.create(parentFile, childFile);
}
private void verifyMergeData(final VirtualFile file, String expectedBase, String expectedLocal, String expectedServer)
throws VcsException {
final MergeData mergeData = myMergeProvider.loadRevisions(file);
assertEquals(expectedBase, mergeData.ORIGINAL);
assertEquals(expectedServer, mergeData.LAST);
assertEquals(expectedLocal, mergeData.CURRENT);
}
private static void assertEquals(String s, byte[] bytes) {
Assert.assertEquals(s, new String(bytes));
}
}