Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Wolf2015-09-12 21:08:51 +0000
committerAndrey Loskutov2015-09-13 20:55:53 +0000
commit0831deae6fd973df0696b450f274e1a2b6cf73ef (patch)
treeba768981649b0997a038e3e839e06e7a32771078 /org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test
parentfbb66bdb00b81fc817d9ecd4eed70d4e7d2b4a3e (diff)
downloadegit-0831deae6fd973df0696b450f274e1a2b6cf73ef.tar.gz
egit-0831deae6fd973df0696b450f274e1a2b6cf73ef.tar.xz
egit-0831deae6fd973df0696b450f274e1a2b6cf73ef.zip
Check for objects adaptable to IResource in ShowBlameActionHandler
Includes a new test. Some refactoring in LocalRepositoryTestCase to avoid having to duplicate test repo creation, and to reduce code duplication. Bug: 401156 Change-Id: Ib78d62f11d3a5a52c672bb192e8baba189c49829 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
Diffstat (limited to 'org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test')
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/ShowBlameActionHandlerTest.java303
1 files changed, 303 insertions, 0 deletions
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/ShowBlameActionHandlerTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/ShowBlameActionHandlerTest.java
new file mode 100644
index 000000000..70dfdcd6c
--- /dev/null
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/ShowBlameActionHandlerTest.java
@@ -0,0 +1,303 @@
+/*******************************************************************************
+ * Copyright (C) 2015, Thomas Wolf <thomas.wolf@paranor.ch>
+ *
+ * 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
+ *******************************************************************************/
+package org.eclipse.egit.ui.test.team.actions;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceDescription;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.core.internal.indexdiff.IndexDiffCache;
+import org.eclipse.egit.core.op.CommitOperation;
+import org.eclipse.egit.core.op.ConnectProviderOperation;
+import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
+import org.eclipse.egit.ui.internal.actions.ShowBlameActionHandler;
+import org.eclipse.egit.ui.test.TestUtil;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.launching.JavaRuntime;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jgit.lib.Repository;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.runners.MockitoJUnitRunner;
+
+/**
+ * JUnit plugin test (non-SWTBot) to verify that {@link ShowBlameActionHandler}
+ * is enabled not only for {@link IResource} but also for other things that
+ * might be visible in the package explorer and that adapt to {@link IResource}.
+ * We verify by setting up a Java project with a simple test class and then
+ * checking for {@link IFile}, {@link ICompilationUnit}, and {@link IType}.
+ *
+ * @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=401156">Bug
+ * 401156</a>
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class ShowBlameActionHandlerTest extends LocalRepositoryTestCase {
+
+ private static final String JAVA_PROJECT_NAME = "javatestProject";
+
+ private static final String SRC_FOLDER_NAME = "src";
+
+ private static final String BIN_FOLDER_NAME = "bin";
+
+ private static final String PACKAGE_NAME = "p";
+
+ private static final String JAVA_CLASS_NAME = "A";
+
+ private static final String JAVA_FILE_NAME = JAVA_CLASS_NAME + ".java";
+
+ private static final int MAX_DELETE_RETRY = 5;
+
+ private static final int DELETE_RETRY_DELAY = 1000; // ms
+
+ private static boolean initialAutobuild;
+
+ private IJavaProject javaProject = null;
+
+ @BeforeClass
+ public static void setupAutobuildOff() throws CoreException {
+ // Switch off autobuild -- we don't need it, and a build job might
+ // interfere with our removing the Java project at the end.
+ initialAutobuild = setAutobuild(false);
+ }
+
+ @AfterClass
+ public static void teardownAutobuildReset() throws CoreException {
+ setAutobuild(initialAutobuild);
+ }
+
+ @Before
+ public void setup() throws Exception {
+ javaProject = createJavaProjectAndCommitToRepository();
+ }
+
+ @After
+ public void teardown() throws CoreException {
+ removeJavaProject();
+ }
+
+ @Test
+ public void testShowAnnotationsFromProjectExplorer() throws Exception {
+ IProject project = javaProject.getProject();
+ // Find the file
+ IFile file = project.getFolder(SRC_FOLDER_NAME).getFolder(PACKAGE_NAME)
+ .getFile(JAVA_FILE_NAME);
+ assertBlameEnabled(file, true);
+ // Now repeat the same with the ICompilationUnit.
+ IJavaElement element = JavaCore.create(file, javaProject);
+ assertTrue("Expected an ICompilationUnit",
+ element instanceof ICompilationUnit);
+ assertBlameEnabled(element, true);
+ // And with IType...
+ IType type = javaProject.findType(PACKAGE_NAME, JAVA_CLASS_NAME);
+ assertBlameEnabled(type, true);
+ // ... and finally with something that doesn't adapt to IResource:
+ assertBlameEnabled(this, false);
+ }
+
+ @SuppressWarnings("boxing")
+ private void assertBlameEnabled(Object selected, boolean expected) {
+ assertNotNull("Nothing selected", selected);
+ IStructuredSelection selection = mock(IStructuredSelection.class);
+ when(selection.getFirstElement()).thenReturn(selected);
+ when(selection.size()).thenReturn(1);
+ ShowBlameActionHandler blame = new ShowBlameActionHandler();
+ blame.setSelection(selection);
+ assertEquals("Unexpected enablement of blame action", expected,
+ blame.isEnabled());
+ }
+
+ // Java stuff below
+
+ private static boolean setAutobuild(boolean value) throws CoreException {
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ IWorkspaceDescription desc = workspace.getDescription();
+ boolean isAutoBuilding = desc.isAutoBuilding();
+ if (isAutoBuilding != value) {
+ desc.setAutoBuilding(value);
+ workspace.setDescription(desc);
+ }
+ return isAutoBuilding;
+ }
+
+ private IJavaProject createJavaProjectAndCommitToRepository()
+ throws Exception {
+ Repository myRepository = createLocalTestRepository(REPO1);
+ File gitDir = myRepository.getDirectory();
+ IJavaProject jProject = createJavaProject(myRepository,
+ JAVA_PROJECT_NAME);
+ IProject project = jProject.getProject();
+ try {
+ new ConnectProviderOperation(project, gitDir).execute(null);
+ } catch (Exception e) {
+ Activator.logError("Failed to connect project to repository", e);
+ }
+ assertConnected(project);
+ // Check in at least the java file
+ IFolder folder = project.getFolder(SRC_FOLDER_NAME)
+ .getFolder(PACKAGE_NAME);
+ IFile file = folder.getFile(JAVA_FILE_NAME);
+
+ IFile[] commitables = new IFile[] { file };
+ ArrayList<IFile> untracked = new ArrayList<IFile>();
+ untracked.addAll(Arrays.asList(commitables));
+ // commit to master
+ CommitOperation op = new CommitOperation(commitables, untracked,
+ TestUtil.TESTAUTHOR, TestUtil.TESTCOMMITTER, "Initial commit");
+ op.execute(null);
+
+ // Make sure cache entry is already listening for changes
+ IndexDiffCache cache = Activator.getDefault().getIndexDiffCache();
+ cache.getIndexDiffCacheEntry(lookupRepository(gitDir));
+ return jProject;
+ }
+
+ private IJavaProject createJavaProject(final Repository repository,
+ final String projectName) throws Exception {
+ final IJavaProject[] jProjectHolder = new IJavaProject[] { null };
+ IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
+ @Override
+ public void run(IProgressMonitor monitor) throws CoreException {
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ IProject project = root.getProject(projectName);
+ if (project.exists()) {
+ project.delete(true, null);
+ TestUtil.waitForJobs(100, 5000);
+ }
+ IProjectDescription desc = ResourcesPlugin.getWorkspace()
+ .newProjectDescription(projectName);
+ desc.setLocation(
+ new Path(new File(repository.getWorkTree(), projectName)
+ .getPath()));
+ project.create(desc, null);
+ project.open(null);
+ TestUtil.waitForJobs(50, 5000);
+ // Create a "bin" folder
+ IFolder bin = project.getFolder(BIN_FOLDER_NAME);
+ if (!bin.exists()) {
+ bin.create(IResource.FORCE | IResource.DERIVED, true, null);
+ }
+ IPath outputLocation = bin.getFullPath();
+ // Create a "src" folder
+ IFolder src = project.getFolder(SRC_FOLDER_NAME);
+ if (!src.exists()) {
+ src.create(IResource.FORCE, true, null);
+ }
+ addNatureToProject(project, JavaCore.NATURE_ID);
+ // Set up the IJavaProject
+ IJavaProject jProject = JavaCore.create(project);
+ IPackageFragmentRoot srcContainer = jProject
+ .getPackageFragmentRoot(src);
+ IClasspathEntry srcEntry = JavaCore
+ .newSourceEntry(srcContainer.getPath());
+ // Create a JRE classpath entry using the default JRE
+ IClasspathEntry jreEntry = JavaRuntime
+ .getDefaultJREContainerEntry();
+ jProject.setRawClasspath(
+ new IClasspathEntry[] { srcEntry, jreEntry },
+ outputLocation, true, null);
+ // Create a package with a single test class
+ IPackageFragment javaPackage = srcContainer
+ .createPackageFragment(PACKAGE_NAME, true, null);
+ javaPackage
+ .createCompilationUnit(JAVA_FILE_NAME,
+ "package " + PACKAGE_NAME + ";\nclass "
+ + JAVA_CLASS_NAME + " {\n\n}",
+ true, null);
+ jProjectHolder[0] = jProject;
+ }
+ };
+ ResourcesPlugin.getWorkspace().run(runnable, null);
+ return jProjectHolder[0];
+ }
+
+ private void addNatureToProject(IProject proj, String natureId)
+ throws CoreException {
+ IProjectDescription description = proj.getDescription();
+ String[] prevNatures = description.getNatureIds();
+ String[] newNatures = new String[prevNatures.length + 1];
+ System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
+ newNatures[prevNatures.length] = natureId;
+ description.setNatureIds(newNatures);
+ proj.setDescription(description, null);
+ }
+
+ private void removeJavaProject() throws CoreException {
+ if (javaProject == null) {
+ return;
+ }
+ final IProject project = javaProject.getProject();
+ IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
+ @Override
+ public void run(IProgressMonitor monitor) throws CoreException {
+ // Following code inspired by {@link
+ // org.eclipse.jdt.testplugin.JavaProjectHelper#delete(IResource)}.
+ // I don't like all this sleeping at all, but apparently it's
+ // needed because the Java indexer might still run and hold on
+ // to some resources.
+ for (int i = 0; i < MAX_DELETE_RETRY; i++) {
+ try {
+ project.delete(
+ IResource.FORCE
+ | IResource.ALWAYS_DELETE_PROJECT_CONTENT,
+ null);
+ break;
+ } catch (CoreException e) {
+ if (i == MAX_DELETE_RETRY - 1) {
+ throw e;
+ }
+ try {
+ Activator.logInfo(
+ "Sleep before retrying to delete project "
+ + project.getLocationURI());
+ // Give other threads the time to close and release
+ // the resource.
+ Thread.sleep(DELETE_RETRY_DELAY);
+ } catch (InterruptedException e1) {
+ // Ignore and retry to delete
+ }
+ }
+ }
+
+ }
+ };
+ ResourcesPlugin.getWorkspace().run(runnable, null);
+ }
+}

Back to the top