Skip to content

Content of file BranchAndResetActionTest.java

/*******************************************************************************
 * 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 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *    Mathias Kinzler (SAP AG) - initial implementation
 *    Chris Aniszczyk <caniszczyk@gmail.com> - tag API changes
 *******************************************************************************/
package org.eclipse.egit.ui.test.team.actions;

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.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.egit.core.RepositoryUtil;
import org.eclipse.egit.core.op.CommitOperation;
import org.eclipse.egit.core.op.TagOperation;
import org.eclipse.egit.core.test.TestUtils;
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.JobJoiner;
import org.eclipse.egit.ui.test.TestUtil;
import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.util.FileUtils;
import org.eclipse.jgit.util.RawParseUtils;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swtbot.swt.finder.SWTBot;
import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
import org.eclipse.swtbot.swt.finder.utils.TableCollection;
import org.eclipse.swtbot.swt.finder.waits.ICondition;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotStyledText;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarDropDownButton;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
import org.eclipse.swtbot.swt.finder.widgets.TimeoutException;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE.SharedImages;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

/**
 * Tests for the Team->Branch action
 */
@RunWith(SWTBotJunit4ClassRunner.class)
public class BranchAndResetActionTest extends LocalRepositoryTestCase {

	private static String LOCAL_BRANCHES;
	private static String TAGS;

	private File repositoryFile;

	@Before
	public void setup() throws Exception {
		repositoryFile = createProjectAndCommitToRepository();
		Repository repo = lookupRepository(repositoryFile);

		TagOperation top = new TagOperation(repo)
				.setAnnotated(true)
				.setName("SomeTag")
				.setTagger(RawParseUtils.parsePersonIdent(TestUtil.TESTAUTHOR))
				.setMessage("I'm just a little tag")
				.setTarget(repo.parseCommit(repo.resolve(repo.getFullBranch())));
		top.execute(null);
		touchAndSubmit(null);

		LOCAL_BRANCHES = UIText.RepositoriesViewLabelProvider_LocalNodetext;
Write to static field org.eclipse.egit.ui.test.team.actions.BranchAndResetActionTest.LOCAL_BRANCHES from instance method org.eclipse.egit.ui.test.team.actions.BranchAndResetActionTest.setup()

This instance method writes to a static field. This is tricky to get correct if multiple instances are being manipulated, and generally bad practice.

TAGS = UIText.RepositoriesViewLabelProvider_TagsNodeText; } @Test public void testCheckoutLocalBranches() throws Exception { checkoutAndVerify(new String[] { LOCAL_BRANCHES, "stable" }); checkoutAndVerify(new String[] { LOCAL_BRANCHES, "master" }); } @Test public void testCheckoutWithConflicts() throws Exception { String charset = ResourcesPlugin.getWorkspace().getRoot().getProject( PROJ1).getDefaultCharset(); try { checkoutAndVerify(new String[] { LOCAL_BRANCHES, "stable" }); ResourcesPlugin.getWorkspace().getRoot().getProject(PROJ1) .getFolder(FOLDER).getFile(FILE1).setContents( new ByteArrayInputStream("New content" .getBytes(charset)), IResource.NONE, null); checkout(new String[] { LOCAL_BRANCHES, "master" }); SWTBotShell showConflicts = bot .shell(UIText.BranchResultDialog_CheckoutConflictsTitle); assertEquals(FILE1, showConflicts.bot().tree().getAllItems()[0] .getItems()[0].getItems()[0].getText()); showConflicts.close(); } finally { ResourcesPlugin.getWorkspace().getRoot().getProject(PROJ1) .getFolder(FOLDER).getFile(FILE1).setContents( new ByteArrayInputStream("Hello, world" .getBytes(charset)), IResource.NONE, null); } } private void checkoutWithConflictsAndReset(boolean stage) throws Exception { String charset = ResourcesPlugin.getWorkspace().getRoot() .getProject(PROJ1).getDefaultCharset(); String file1Content = getTestFileContent(); checkoutAndVerify(new String[] { LOCAL_BRANCHES, "stable" }); ResourcesPlugin.getWorkspace().getRoot().getProject(PROJ1) .getFolder(FOLDER).getFile(FILE1).setContents( new ByteArrayInputStream( "New content".getBytes(charset)), IResource.NONE, null); if (stage) { try (Git git = new Git(lookupRepository(repositoryFile))) { git.add().addFilepattern(FILE1_PATH).call(); } } String file2Content = "Also changed"; ResourcesPlugin.getWorkspace().getRoot().getProject(PROJ1) .getFolder(FOLDER).getFile(FILE2).setContents( new ByteArrayInputStream( file2Content.getBytes(charset)), IResource.NONE, null); checkout(new String[] { LOCAL_BRANCHES, "master" }); SWTBotShell showConflicts = bot .shell(UIText.BranchResultDialog_CheckoutConflictsTitle); SWTBot shellBot = showConflicts.bot(); SWTBotTreeItem[] items = shellBot.tree().getAllItems(); assertEquals(1, items.length); assertEquals(FILE1, items[0].getItems()[0].getItems()[0].getText()); shellBot.button(UIText.BranchResultDialog_buttonDiscardChanges).click(); TestUtils.waitForJobs(500, 5000, JobFamilies.DISCARD_CHANGES); TestUtil.joinJobs(JobFamilies.CHECKOUT); assertEquals(file1Content, getTestFileContent()); // FILE2 should _not_ have been reset since it didn't conflict with the // checkout and wasn't shown in the conflict dialog assertEquals(file2Content, getTestFileContent(FILE2)); } @Test public void testCheckoutWithConflictsAndReset() throws Exception { checkoutWithConflictsAndReset(false); } @Test public void testCheckoutWithStagedConflictsAndReset() throws Exception { checkoutWithConflictsAndReset(true); } @Test public void testCheckoutWithNonDeleted() throws Exception { // we need to check if this file system has problems to // delete a file with an open FileInputStrem IFile test = ResourcesPlugin.getWorkspace().getRoot().getProject(PROJ1) .getFolder(FOLDER).getFile("temp.txt"); test.create(new ByteArrayInputStream(new byte[0]), false, null); File testFile = new File(test.getLocation().toString()); assertTrue(testFile.exists()); try (InputStream fis = Files.newInputStream(testFile.toPath())) { FileUtils.delete(testFile); return; } catch (IOException e) { // the test makes sense only if deletion of // a file with open stream fails } finally { if (testFile.exists()) { FileUtils.delete(testFile); } } final Image folderImage = PlatformUI.getWorkbench().getSharedImages() .getImage(ISharedImages.IMG_OBJ_FOLDER); final Image projectImage = PlatformUI.getWorkbench().getSharedImages() .getImage(SharedImages.IMG_OBJ_PROJECT); // checkout stable checkoutAndVerify(new String[] { LOCAL_BRANCHES, "stable" }); // add a file IFile toBeDeleted = ResourcesPlugin.getWorkspace().getRoot() .getProject(PROJ1).getFolder(FOLDER).getFile("ToBeDeleted"); toBeDeleted.create(new ByteArrayInputStream(new byte[0]), false, null); ArrayList<IFile> untracked = new ArrayList<>(); untracked.add(toBeDeleted); // commit to stable CommitOperation op = new CommitOperation(new IFile[] { toBeDeleted }, untracked, TestUtil.TESTAUTHOR, TestUtil.TESTCOMMITTER, "Add to stable"); op.execute(null); try (InputStream is = toBeDeleted.getContents()) { checkout(new String[] { LOCAL_BRANCHES, "master" }); final SWTBotShell showUndeleted = bot .shell(UIText.NonDeletedFilesDialog_NonDeletedFilesTitle); // repo relative path assertEquals("ToBeDeleted", showUndeleted.bot().tree() .getAllItems()[0].getItems()[0].getItems()[0].getText()); PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { @Override public void run() { assertSame(folderImage, showUndeleted.bot().tree() .getAllItems()[0].widget.getImage()); } }); SWTBotToolbarDropDownButton pathButton = showUndeleted.bot().toolbarDropDownButton(); pathButton.menuItem(UIText.NonDeletedFilesTree_FileSystemPathsButton).click(); // see http://www.eclipse.org/forums/index.php/t/159133/ why we need this pathButton.pressShortcut(KeyStroke.getInstance("ESC")); // fs path IPath path = new Path(lookupRepository(repositoryFile) .getWorkTree().getPath()).append(PROJ1).append(FOLDER) .append("ToBeDeleted"); SWTBotTreeItem[] items = showUndeleted.bot().tree().getAllItems(); for (int i = 0; i < path.segmentCount(); i++) { boolean found = false; String segment = path.segment(i); for (SWTBotTreeItem item : items) if (item.getText().equals(segment)) { found = true; items = item.getItems(); } assertTrue(found); } pathButton.menuItem(UIText.NonDeletedFilesTree_ResourcePathsButton).click(); // see http://www.eclipse.org/forums/index.php/t/159133/ why we need this pathButton.pressShortcut(KeyStroke.getInstance("ESC")); // resource path assertEquals("ToBeDeleted", showUndeleted.bot().tree() .getAllItems()[0].getItems()[0].getItems()[0].getText()); PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { @Override public void run() { assertSame(projectImage, showUndeleted.bot().tree() .getAllItems()[0].widget.getImage()); } }); ICondition treeEmpty = new ICondition() { @Override public boolean test() throws Exception { return showUndeleted.bot().tree().getAllItems().length == 0; } @Override public void init(SWTBot actBot) { // nothing } @Override public String getFailureMessage() { return "Not deleted"; } }; showUndeleted.bot().button( UIText.NonDeletedFilesDialog_RetryDeleteButton).click(); try { showUndeleted.bot().waitUntil(treeEmpty, 1000, 100); fail("Should have failed"); } catch (TimeoutException e) { // expected } is.close(); showUndeleted.bot().button( UIText.NonDeletedFilesDialog_RetryDeleteButton).click(); showUndeleted.bot().waitUntil(treeEmpty, 1000, 100); showUndeleted.close(); } } @Test public void testResetToLocalBranch() throws Exception { checkoutAndVerify(new String[] { LOCAL_BRANCHES, "stable" }); String stable = getTestFileContent(); checkoutAndVerify(new String[] { LOCAL_BRANCHES, "master" }); String master = getTestFileContent(); assertFalse(stable.equals(master)); SWTBotShell resetDialog = openResetDialog(); SWTBotTreeItem localBranches = TestUtil.expandAndWait( resetDialog.bot().tree().getTreeItem(LOCAL_BRANCHES)); TestUtil.getChildNode(localBranches, "stable").select(); resetDialog.bot().radio( UIText.ResetTargetSelectionDialog_ResetTypeHardButton).click(); resetDialog.bot().button(UIText.ResetTargetSelectionDialog_ResetButton) .click(); bot.shell(UIText.ResetTargetSelectionDialog_ResetConfirmTitle).bot() .button(UIText.CommandConfirmationHardResetDialog_resetButtonLabel) .click(); Job.getJobManager().join(JobFamilies.RESET, null); String reset = getTestFileContent(); assertEquals("Wrong content after reset", stable, reset); } @Test public void testCreateDeleteBranch() throws Exception { assertNull(lookupRepository(repositoryFile).resolve("newBranch")); SWTBotShell newBranchDialog = openCreateBranchDialog(); newBranchDialog.bot().textWithId("BranchName").setText("newBranch"); newBranchDialog.bot().checkBox(UIText.CreateBranchPage_CheckoutButton).deselect(); newBranchDialog.bot().button(IDialogConstants.FINISH_LABEL).click(); TestUtil.joinJobs(JobFamilies.CHECKOUT); assertNotNull(lookupRepository(repositoryFile).resolve("newBranch")); SWTBotShell deleteBranchDialog = openDeleteBranchDialog(); SWTBotTreeItem localBranches = TestUtil.expandAndWait( deleteBranchDialog.bot().tree().getTreeItem(LOCAL_BRANCHES)); TestUtil.getChildNode(localBranches, "newBranch").select(); deleteBranchDialog.bot().button(IDialogConstants.OK_LABEL).click(); TestUtil.joinJobs(JobFamilies.CHECKOUT); assertNull(lookupRepository(repositoryFile).resolve("newBranch")); } @Test public void testCreateBranchSelectSource() throws Exception { Repository repo = lookupRepository(repositoryFile); assertNull(repo.resolve("branch-from-tag")); SWTBotShell createBranchDialog = openCreateBranchDialog(); createBranchDialog.bot() .button(UIText.CreateBranchPage_SourceSelectButton).click(); SWTBotShell sourceSelectionDialog = bot .shell(UIText.CreateBranchPage_SourceSelectionDialogTitle); SWTBotTree tree = sourceSelectionDialog.bot().tree(); SWTBotTreeItem tags = tree .expandNode(UIText.RepositoriesViewLabelProvider_TagsNodeText); TestUtil.getChildNode(tags, "SomeTag").select(); sourceSelectionDialog.bot().button(IDialogConstants.OK_LABEL).click(); SWTBotStyledText sourceLabel = createBranchDialog.bot().styledText(0); assertEquals("SomeTag", sourceLabel.getText()); createBranchDialog.bot().textWithId("BranchName") .setText("branch-from-tag"); createBranchDialog.bot() .checkBox(UIText.CreateBranchPage_CheckoutButton).deselect(); createBranchDialog.bot().button(IDialogConstants.FINISH_LABEL).click(); TestUtil.waitForJobs(100, 5000); ObjectId resolvedBranch = repo.resolve("branch-from-tag"); ObjectId resolvedTagCommit = repo.resolve("SomeTag^{commit}"); assertNotNull(resolvedBranch); assertEquals(resolvedTagCommit, resolvedBranch); } private SWTBotShell openCheckoutBranchDialog() { SWTBotTree projectExplorerTree = TestUtil.getExplorerTree(); getProjectItem(projectExplorerTree, PROJ1).select(); String[] menuPath = new String[] { util.getPluginLocalizedValue("TeamMenu.label"), util.getPluginLocalizedValue("SwitchToMenu.label"), UIText.SwitchToMenu_OtherMenuLabel }; ContextMenuHelper.clickContextMenu(projectExplorerTree, menuPath); SWTBotShell dialog = bot .shell(UIText.BranchSelectionAndEditDialog_WindowTitle); return dialog; } private SWTBotShell openCreateBranchDialog() { SWTBotTree projectExplorerTree = TestUtil.getExplorerTree(); getProjectItem(projectExplorerTree, PROJ1).select(); String[] menuPath = new String[] { util.getPluginLocalizedValue("TeamMenu.label"), util.getPluginLocalizedValue("SwitchToMenu.label"), UIText.SwitchToMenu_NewBranchMenuLabel }; ContextMenuHelper.clickContextMenu(projectExplorerTree, menuPath); SWTBotShell dialog = bot .shell(UIText.CreateBranchWizard_NewBranchTitle); return dialog; } private SWTBotShell openRenameBranchDialog() { SWTBotTree projectExplorerTree = TestUtil.getExplorerTree(); getProjectItem(projectExplorerTree, PROJ1).select(); String[] menuPath = new String[] { util.getPluginLocalizedValue("TeamMenu.label"), util.getPluginLocalizedValue("AdvancedMenu.label"), util.getPluginLocalizedValue("RenameBranchMenu.label") }; ContextMenuHelper.clickContextMenu(projectExplorerTree, menuPath); SWTBotShell dialog = bot.shell(UIText.RenameBranchDialog_WindowTitle); return dialog; } private SWTBotShell openDeleteBranchDialog() { SWTBotTree projectExplorerTree = TestUtil.getExplorerTree(); getProjectItem(projectExplorerTree, PROJ1).select(); String[] menuPath = new String[] { util.getPluginLocalizedValue("TeamMenu.label"), util.getPluginLocalizedValue("AdvancedMenu.label"), util.getPluginLocalizedValue("DeleteBranchMenu.label") }; ContextMenuHelper.clickContextMenu(projectExplorerTree, menuPath); SWTBotShell dialog = bot.shell(UIText.DeleteBranchDialog_WindowTitle); return dialog; } private SWTBotShell openResetDialog() { SWTBotTree projectExplorerTree = TestUtil.getExplorerTree(); getProjectItem(projectExplorerTree, PROJ1).select(); String menuString = util.getPluginLocalizedValue("ResetAction_label"); ContextMenuHelper.clickContextMenu(projectExplorerTree, util .getPluginLocalizedValue("TeamMenu.label"), menuString); SWTBotShell dialog = bot .shell(UIText.ResetTargetSelectionDialog_WindowTitle); return dialog; } @Test public void testRenameBranch() throws Exception { SWTBotShell dialog = openRenameBranchDialog(); SWTBotTreeItem localBranches = TestUtil .expandAndWait(dialog.bot().tree().getTreeItem(LOCAL_BRANCHES)); TestUtil.getChildNode(localBranches, "stable").select(); dialog.bot().button(UIText.RenameBranchDialog_RenameButtonLabel) .click(); // rename stable to renamed SWTBotShell newNameDialog = bot.shell(UIText.BranchRenameDialog_Title); newNameDialog.bot().text().setText("master"); assertFalse(newNameDialog.bot() .button(UIText.RenameBranchDialog_RenameButtonLabel) .isEnabled()); newNameDialog.bot().text().setText("renamed"); newNameDialog.bot().button(UIText.RenameBranchDialog_RenameButtonLabel) .click(); TestUtil.joinJobs(JobFamilies.CHECKOUT); dialog = openRenameBranchDialog(); SWTBotTreeItem localBranches2 = TestUtil .expandAndWait(dialog.bot().tree().getTreeItem(LOCAL_BRANCHES)); TestUtil.getChildNode(localBranches2, "renamed").select(); dialog.bot().button(UIText.RenameBranchDialog_RenameButtonLabel) .click(); // rename renamed to stable newNameDialog = bot.shell(UIText.BranchRenameDialog_Title); newNameDialog.bot().text().setText("stable"); newNameDialog.bot().button(UIText.RenameBranchDialog_RenameButtonLabel) .click(); TestUtil.joinJobs(JobFamilies.CHECKOUT); dialog = openRenameBranchDialog(); SWTBotTreeItem localBranches3 = TestUtil .expandAndWait(dialog.bot().tree().getTreeItem(LOCAL_BRANCHES)); TestUtil.getChildNode(localBranches3, "stable").select(); dialog.close(); } @Test public void testCheckoutTags() throws Exception { checkoutAndVerify(new String[] { TAGS, "SomeTag" }); } private void checkoutAndVerify(String[] nodeTexts) throws IOException, Exception { SWTBotShell dialog = openCheckoutBranchDialog(); TableCollection tc = dialog.bot().tree().selection(); assertEquals("Wrong selection count", 1, tc.rowCount()); TestUtil.navigateTo(dialog.bot().tree(), nodeTexts).select(); tc = dialog.bot().tree().selection(); assertEquals("Wrong selection count", 1, tc.rowCount()); assertTrue("Wrong item selected", tc.get(0, 0).startsWith(nodeTexts[1])); Repository repo = lookupRepository(repositoryFile); JobJoiner joiner = JobJoiner.startListening(JobFamilies.CHECKOUT, 10, TimeUnit.SECONDS); dialog.bot().button(UIText.CheckoutDialog_OkCheckout).click(); joiner.join(); if (ObjectId.isId(repo.getBranch())) { String mapped = RepositoryUtil.INSTANCE.mapCommitToRef(repo, repo.getBranch(), false); assertEquals("Wrong branch", nodeTexts[1], mapped.substring(mapped .lastIndexOf('/') + 1)); } else assertEquals("Wrong branch", nodeTexts[1], repo.getBranch()); } private void checkout(String[] nodeTexts) throws Exception { SWTBotShell dialog = openCheckoutBranchDialog(); TestUtil.navigateTo(dialog.bot().tree(), nodeTexts).select(); TableCollection tc = dialog.bot().tree().selection(); assertEquals("Wrong selection count", 1, tc.rowCount()); assertTrue("Wrong item selected", tc.get(0, 0).startsWith(nodeTexts[1])); JobJoiner joiner = JobJoiner.startListening(JobFamilies.CHECKOUT, 10, TimeUnit.SECONDS); dialog.bot().button(UIText.CheckoutDialog_OkCheckout).click(); joiner.join(); } }