/*******************************************************************************
* Copyright (c) 2010, 2013 SAP AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Mathias Kinzler (SAP AG) - initial implementation
*******************************************************************************/
package org.eclipse.egit.ui.test.history;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.File;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.egit.ui.JobFamilies;
import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.egit.ui.test.ContextMenuHelper;
import org.eclipse.egit.ui.test.TestUtil;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
import org.eclipse.swtbot.swt.finder.SWTBot;
import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTableItem;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarToggleButton;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(SWTBotJunit4ClassRunner.class)
public class HistoryViewTest extends LocalRepositoryTestCase {
private static final String SECONDFOLDER = "secondFolder";
private static final String ADDEDFILE = "another.txt";
private static final String ADDEDMESSAGE = "A new file in a new folder";
private int commitCount;
private File repoFile;
@Before
public void setup() throws Exception {
repoFile = createProjectAndCommitToRepository();
IProject prj = ResourcesPlugin.getWorkspace().getRoot()
.getProject(PROJ1);
IFolder folder2 = prj.getFolder(SECONDFOLDER);
folder2.create(false, true, null);
IFile addedFile = folder2.getFile(ADDEDFILE);
addedFile.create(
new ByteArrayInputStream("More content".getBytes(prj
.getDefaultCharset())), false, null);
addAndCommit(addedFile, ADDEDMESSAGE);
// TODO count the commits
commitCount = 3;
}
@Test
public void testOpenHistoryOnFileNoFilter() throws Exception {
initFilter(0);
assertEquals("Wrong number of commits", commitCount,
getHistoryViewTable(PROJ1).rowCount());
assertEquals("Wrong number of commits", commitCount - 1,
getHistoryViewTable(PROJ1, FOLDER).rowCount());
assertEquals("Wrong number of commits", commitCount - 1,
getHistoryViewTable(PROJ1, FOLDER, FILE1).rowCount());
assertEquals("Wrong number of commits", 1,
getHistoryViewTable(PROJ1, FOLDER, FILE2).rowCount());
assertEquals("Wrong number of commits", 1,
getHistoryViewTable(PROJ1, SECONDFOLDER).rowCount());
assertEquals("Wrong number of commits", 1,
getHistoryViewTable(PROJ1, SECONDFOLDER, ADDEDFILE).rowCount());
assertEquals("Wrong number of commits", 1, getHistoryViewTable(PROJ2)
.rowCount());
assertEquals("Wrong commit message", ADDEDMESSAGE,
getHistoryViewTable(PROJ1, SECONDFOLDER, ADDEDFILE)
.getTableItem(0).getText(1));
assertEquals("Wrong commit message", "Initial commit",
getHistoryViewTable(PROJ1, FOLDER, FILE2).getTableItem(0)
.getText(1));
}
@Test
public void testOpenHistoryOnFileRepoFilter() throws Exception {
initFilter(1);
assertEquals("Wrong number of commits", commitCount,
getHistoryViewTable(PROJ1).rowCount());
assertEquals("Wrong number of commits", commitCount,
getHistoryViewTable(PROJ1, FOLDER).rowCount());
assertEquals("Wrong number of commits", commitCount,
getHistoryViewTable(PROJ1, FOLDER, FILE1).rowCount());
assertEquals("Wrong number of commits", commitCount,
getHistoryViewTable(PROJ1, FOLDER, FILE2).rowCount());
assertEquals("Wrong number of commits", commitCount,
getHistoryViewTable(PROJ1, SECONDFOLDER).rowCount());
assertEquals("Wrong number of commits", commitCount,
getHistoryViewTable(PROJ1, SECONDFOLDER, ADDEDFILE).rowCount());
assertEquals("Wrong number of commits", commitCount,
getHistoryViewTable(PROJ2).rowCount());
}
@Test
public void testOpenHistoryOnFileProjectFilter() throws Exception {
initFilter(2);
assertEquals("Wrong number of commits", commitCount,
getHistoryViewTable(PROJ1).rowCount());
assertEquals("Wrong number of commits", commitCount,
getHistoryViewTable(PROJ1, FOLDER).rowCount());
assertEquals("Wrong number of commits", commitCount,
getHistoryViewTable(PROJ1, FOLDER, FILE1).rowCount());
assertEquals("Wrong number of commits", commitCount,
getHistoryViewTable(PROJ1, FOLDER, FILE2).rowCount());
assertEquals("Wrong number of commits", commitCount,
getHistoryViewTable(PROJ1, SECONDFOLDER).rowCount());
assertEquals("Wrong number of commits", commitCount,
getHistoryViewTable(PROJ1, SECONDFOLDER, ADDEDFILE).rowCount());
assertEquals("Wrong number of commits", 1, getHistoryViewTable(PROJ2)
.rowCount());
}
@Test
public void testOpenHistoryOnFileFolderFilter() throws Exception {
initFilter(3);
assertEquals("Wrong number of commits", commitCount,
getHistoryViewTable(PROJ1).rowCount());
assertEquals("Wrong number of commits", commitCount,
getHistoryViewTable(PROJ1, FOLDER).rowCount());
assertEquals("Wrong number of commits", commitCount - 1,
getHistoryViewTable(PROJ1, FOLDER, FILE1).rowCount());
assertEquals("Wrong number of commits", commitCount - 1,
getHistoryViewTable(PROJ1, FOLDER, FILE2).rowCount());
assertEquals("Wrong number of commits", commitCount,
getHistoryViewTable(PROJ1, SECONDFOLDER).rowCount());
assertEquals("Wrong number of commits", 1,
getHistoryViewTable(PROJ1, SECONDFOLDER, ADDEDFILE).rowCount());
assertEquals("Wrong number of commits", 1,
getHistoryViewTable(PROJ2).rowCount());
}
/**
* @param filter
* 0: none, 1: repository, 2: project, 3: folder
* @throws Exception
*/
private void initFilter(int filter) throws Exception {
getHistoryViewTable(PROJ1);
SWTBotView view = bot
.viewById("org.eclipse.team.ui.GenericHistoryView");
SWTBotToolbarToggleButton folder = (SWTBotToolbarToggleButton) view
.toolbarButton(UIText.GitHistoryPage_AllInParentTooltip);
SWTBotToolbarToggleButton project = (SWTBotToolbarToggleButton) view
.toolbarButton(UIText.GitHistoryPage_AllInProjectTooltip);
SWTBotToolbarToggleButton repo = (SWTBotToolbarToggleButton) view
.toolbarButton(UIText.GitHistoryPage_AllInRepoTooltip);
switch (filter) {
case 0:
if (folder.isChecked())
folder.click();
if (project.isChecked())
project.click();
if (repo.isChecked())
repo.click();
break;
case 1:
if (!repo.isChecked())
repo.click();
break;
case 2:
if (!project.isChecked())
project.click();
break;
case 3:
if (!folder.isChecked())
folder.click();
break;
default:
break;
}
}
@Test
public void testOpenHistoryOnProject() throws Exception {
SWTBotTable table = getHistoryViewTable(PROJ1);
int rowCount = table.rowCount();
assertTrue(table.rowCount() > 0);
assertEquals(table.getTableItem(rowCount - 1).getText(1),
"Initial commit");
}
@Test
public void testAddCommit() throws Exception {
String commitMessage = "The special commit";
int countBefore = getHistoryViewTable(PROJ1).rowCount();
touchAndSubmit(commitMessage);
int countAfter = getHistoryViewTable(PROJ1).rowCount();
assertEquals("Wrong number of entries", countBefore + 1, countAfter);
assertEquals("Wrong comit message", commitMessage,
getHistoryViewTable(PROJ1).getTableItem(0).getText(1));
}
/**
* @param path
* must be length 2 or three (folder or file)
* @return the bale
* @throws Exception
*/
private SWTBotTable getHistoryViewTable(String... path) throws Exception {
SWTBotTree projectExplorerTree = TestUtil.getExplorerTree();
SWTBotTreeItem explorerItem;
SWTBotTreeItem projectItem = getProjectItem(projectExplorerTree, path[0]);
if (path.length == 1)
explorerItem = projectItem;
else if (path.length == 2)
explorerItem = TestUtil.getChildNode(projectItem.expand(), path[1]);
else {
SWTBotTreeItem childItem = TestUtil.getChildNode(
projectItem.expand(), path[1]);
explorerItem = TestUtil.getChildNode(childItem.expand(), path[2]);
}
explorerItem.select();
ContextMenuHelper.clickContextMenuSync(projectExplorerTree, "Team",
"Show in History");
// join GenerateHistoryJob
Job.getJobManager().join(JobFamilies.GENERATE_HISTORY, null);
// join UI update triggered by GenerateHistoryJob
projectExplorerTree.widget.getDisplay().syncExec(new Runnable() {
public void run() {
// empty
}
});
return getHistoryViewBot().table();
}
private SWTBot getHistoryViewBot() {
return TestUtil.showHistoryView().bot();
}
@Test
public void testAddBranch() throws Exception {
Repository repo = lookupRepository(repoFile);
assertNull(repo.resolve(Constants.R_HEADS + "NewBranch"));
SWTBotTable table = getHistoryViewTable(PROJ1);
SWTBotTableItem item = table.getTableItem(0);
item.select();
ContextMenuHelper.clickContextMenu(table,
UIText.GitHistoryPage_CreateBranchMenuLabel);
SWTBotShell dialog = bot
.shell(UIText.CreateBranchWizard_NewBranchTitle);
dialog.bot().textWithId("BranchName").setText("NewBranch");
// for some reason, checkboxwithlabel doesn't seem to work
dialog.bot().checkBox().deselect();
dialog.bot().button(IDialogConstants.FINISH_LABEL).click();
assertNotNull(repo.resolve(Constants.R_HEADS + "NewBranch"));
}
@Test
public void testAddTag() throws Exception {
Repository repo = lookupRepository(repoFile);
assertNull(repo.resolve(Constants.R_TAGS + "NewTag"));
final SWTBotTable table = getHistoryViewTable(PROJ1);
table.getTableItem(0).select();
final RevCommit[] commit = new RevCommit[1];
Display.getDefault().syncExec(new Runnable() {
public void run() {
TableItem tableItem = table.widget.getSelection()[0];
ensureTableItemLoaded(tableItem);
commit[0] = (RevCommit) tableItem.getData();
}
});
ContextMenuHelper.clickContextMenu(table,
UIText.GitHistoryPage_CreateTagMenuLabel);
SWTBotShell dialog = bot.shell(UIText.CreateTagDialog_NewTag);
dialog.bot().textWithLabel(UIText.CreateTagDialog_tagName)
.setText("NewTag");
dialog.bot().styledTextWithLabel(UIText.CreateTagDialog_tagMessage)
.setText("New Tag message");
dialog.bot().button(UIText.CreateTagDialog_CreateTagButton).click();
TestUtil.joinJobs(JobFamilies.TAG);
assertNotNull(repo.resolve(Constants.R_TAGS + "NewTag"));
}
@Test
public void testCheckOut() throws Exception {
Repository repo = lookupRepository(repoFile);
assertEquals(Constants.MASTER, repo.getBranch());
final SWTBotTable table = getHistoryViewTable(PROJ1);
// check out the second line
final RevCommit[] commit = checkoutLine(table, 1);
assertEquals(commit[0].getId().name(), repo.getBranch());
}
@Test
public void testShowAllBranches() throws Exception {
toggleShowAllBranchesButton(true);
final SWTBotTable table = getHistoryViewTable(PROJ1);
int commits = getHistoryViewTable(PROJ1).rowCount();
checkoutLine(table, 1);
toggleShowAllBranchesButton(false);
assertEquals("Wrong number of commits", commits - 1,
getHistoryViewTable(PROJ1).rowCount());
toggleShowAllBranchesButton(true);
assertEquals("Wrong number of commits", commits,
getHistoryViewTable(PROJ1).rowCount());
}
@Test
public void testRevertFailure() throws Exception {
touchAndSubmit(null);
setTestFileContent("dirty in working directory"
+ System.currentTimeMillis());
final SWTBotTable table = getHistoryViewTable(PROJ1);
assertTrue(table.rowCount() > 0);
table.getTableItem(0).select();
final RevCommit[] commit = new RevCommit[1];
Display.getDefault().syncExec(new Runnable() {
public void run() {
TableItem tableItem = table.widget.getSelection()[0];
ensureTableItemLoaded(tableItem);
commit[0] = (RevCommit) tableItem.getData();
}
});
assertEquals(1, commit[0].getParentCount());
ContextMenuHelper.clickContextMenu(table,
UIText.GitHistoryPage_revertMenuItem);
SWTBot dialog = bot.shell(UIText.RevertFailureDialog_Title).bot();
assertEquals(1, dialog.tree().rowCount());
assertEquals(1, dialog.tree().getAllItems()[0].rowCount());
assertTrue(dialog.tree().getAllItems()[0].getItems()[0].getText()
.startsWith(FILE1));
}
@Test
public void testOpenOfDeletedFile() throws Exception {
Git git = Git.wrap(lookupRepository(repoFile));
git.rm().addFilepattern(FILE1_PATH).call();
RevCommit commit = git.commit().setMessage("Delete file").call();
SWTBotTable commitsTable = getHistoryViewTable(PROJ1);
assertEquals(commitCount + 1, commitsTable.rowCount());
commitsTable.select(0);
SWTBot viewBot = getHistoryViewBot();
SWTBotTable fileDiffTable = viewBot.table(1);
assertEquals(1, fileDiffTable.rowCount());
fileDiffTable.select(0);
assertFalse(fileDiffTable.contextMenu(
UIText.CommitFileDiffViewer_OpenInEditorMenuLabel).isEnabled());
fileDiffTable.contextMenu(
UIText.CommitFileDiffViewer_OpenPreviousInEditorMenuLabel)
.click();
// Editor for old file version should be opened
bot.editorByTitle(FILE1 + " " + commit.getParent(0).getName());
}
@Test
@Ignore
public void testRebaseAlreadyUpToDate() throws Exception {
Repository repo = lookupRepository(repoFile);
Ref stable = repo.getRef("stable");
SWTBotTable table = getHistoryViewTable(PROJ1);
SWTBotTableItem stableItem = getTableItemWithId(table, stable.getObjectId());
stableItem.contextMenu(UIText.GitHistoryPage_rebaseMenuItem).click();
TestUtil.joinJobs(JobFamilies.REBASE);
}
private RevCommit[] checkoutLine(final SWTBotTable table, int line)
throws InterruptedException {
table.getTableItem(line).select();
final RevCommit[] commit = new RevCommit[1];
Display.getDefault().syncExec(new Runnable() {
public void run() {
TableItem tableItem = table.widget.getSelection()[0];
ensureTableItemLoaded(tableItem);
commit[0] = (RevCommit) tableItem.getData();
}
});
ContextMenuHelper.clickContextMenuSync(table,
UIText.GitHistoryPage_CheckoutMenuLabel);
TestUtil.joinJobs(JobFamilies.CHECKOUT);
return commit;
}
/**
* Workaround to ensure that the TableItem of a SWT table with style
* SWT_VIRTUAL is loaded.
*
* @param item
*/
private static void ensureTableItemLoaded(TableItem item) {
item.setText(item.getText()); // TODO: is there a better solution?
}
private void toggleShowAllBranchesButton(boolean checked) throws Exception{
getHistoryViewTable(PROJ1);
SWTBotView view = bot
.viewById("org.eclipse.team.ui.GenericHistoryView");
SWTBotToolbarToggleButton showAllBranches = (SWTBotToolbarToggleButton) view
.toolbarButton(UIText.GitHistoryPage_showAllBranches);
boolean isChecked = showAllBranches.isChecked();
if(isChecked && !checked || !isChecked && checked)
showAllBranches.click();
}
private static SWTBotTableItem getTableItemWithId(SWTBotTable table,
ObjectId wantedId) {
for (int i = 0; i < table.rowCount(); i++) {
String id = table.cell(i, UIText.CommitGraphTable_CommitId);
String idWithoutEllipsis = id.substring(0, 7);
if (wantedId.getName().startsWith(idWithoutEllipsis))
return table.getTableItem(i);
}
throw new IllegalStateException("TableItem for commit with ID " + wantedId + " not found.");
}
}