aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDariusz Luksza2010-06-25 17:53:15 (EDT)
committerMatthias Sohn2010-06-30 09:23:04 (EDT)
commitfd5bd31f476676e77e6c67c28fe12391f85d9fa0 (patch)
tree8c02bd3f3058cf51512c776e4573415504640684
parentfd6e59cf068ba625ccbe857b76e6267b2a4e97a5 (diff)
downloadegit-fd5bd31f476676e77e6c67c28fe12391f85d9fa0.zip
egit-fd5bd31f476676e77e6c67c28fe12391f85d9fa0.tar.gz
egit-fd5bd31f476676e77e6c67c28fe12391f85d9fa0.tar.bz2
Add tests for integration with Synchronize viewrefs/changes/74/874/16
Adds test cases for GitSynchInfo.getKind(), GitResourceVariantComparator .compare() methods and SWTBot tests for UI testing of Synchronize View. Bug: 316957 CQ: 4275 CQ: 4291 Change-Id: I169d38c33102494ac7f9dfc5e274aec1392850d9 Signed-off-by: Dariusz Luksza <dariusz@luksza.org> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
-rw-r--r--org.eclipse.egit.core.test/META-INF/MANIFEST.MF3
-rw-r--r--org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantComparatorTest.java672
-rw-r--r--org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeTest.java365
-rw-r--r--org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitSyncInfoTest.java732
-rw-r--r--org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitTestResourceVariantTree.java43
-rw-r--r--org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/TestProject.java9
-rw-r--r--org.eclipse.egit.core/META-INF/MANIFEST.MF3
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/EGitTestCase.java36
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/GitImportRepoWizard.java49
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/AllTests.java10
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTest.java5
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/synchronize/SynchronizeViewTest.java331
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/wizards/clone/GitCloneWizardTest.java3
13 files changed, 2249 insertions, 12 deletions
diff --git a/org.eclipse.egit.core.test/META-INF/MANIFEST.MF b/org.eclipse.egit.core.test/META-INF/MANIFEST.MF
index e3ee59b..9dd88e3 100644
--- a/org.eclipse.egit.core.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.core.test/META-INF/MANIFEST.MF
@@ -13,7 +13,8 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.4.0,4.0.0)",
org.eclipse.jdt.launching;bundle-version="[3.4.0,4.0.0)",
org.junit4;bundle-version="[4.3.0,5.0.0)"
Bundle-ActivationPolicy: lazy
-Import-Package: org.eclipse.egit.core;version="[0.9.0,0.10.0)",
+Import-Package: org.easymock;version="[2.4.0,3.0.0)",
+ org.eclipse.egit.core;version="[0.9.0,0.10.0)",
org.eclipse.egit.core.op;version="[0.9.0,0.10.0)",
org.eclipse.egit.core.project;version="[0.9.0,0.10.0)",
org.eclipse.jgit.junit;version="[0.9.0,0.10.0)",
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantComparatorTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantComparatorTest.java
new file mode 100644
index 0000000..2628e2f
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantComparatorTest.java
@@ -0,0 +1,672 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * 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.core.synchronize;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+import java.io.ByteArrayInputStream;
+import java.util.Arrays;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.egit.core.op.ConnectProviderOperation;
+import org.eclipse.egit.core.project.RepositoryMapping;
+import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.egit.core.test.GitTestCase;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.team.core.variants.IResourceVariant;
+import org.junit.Before;
+import org.junit.Test;
+
+public class GitResourceVariantComparatorTest extends GitTestCase {
+
+ private Repository repo;
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+
+ IProject iProject = project.project;
+ if (!gitDir.exists())
+ new Repository(gitDir).create();
+
+ new ConnectProviderOperation(iProject, gitDir).execute(null);
+ repo = RepositoryMapping.getMapping(iProject).getRepository();
+ }
+
+ /*============================================
+ * compare(IResource, IResourceVariant) tests
+ *============================================*/
+
+ /**
+ * When remote variant wasn't found, compare method is called with null as
+ * second parameter. In this case compare should return false.
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnFalseWhenRemoteDoesNotExist() {
+ // when
+ GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+ null, null);
+
+ // given
+ IResource local = createMock(IResource.class);
+ expect(local.exists()).andReturn(false);
+ replay(local);
+
+ // then
+ assertFalse(grvc.compare(local, null));
+ verify(local);
+ }
+
+ /**
+ * It is possible to have a local file that has same name as a remote folder.
+ * In some cases that two resources can be compared. In this case compare
+ * method should return false, because they aren't same resources
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnFalseWhenComparingFileAndContainer() {
+ // when
+ GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+ null, null);
+
+ // given
+ IFile local = createMock(IFile.class);
+ expect(local.exists()).andReturn(true);
+ replay(local);
+
+ IResourceVariant remote = createMock(IResourceVariant.class);
+ expect(remote.isContainer()).andReturn(true);
+ replay(remote);
+
+ // then
+ assertFalse(grvc.compare(local, remote));
+ verify(local, remote);
+ }
+
+ /**
+ * Comparing two folders that have different path should return false.
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnFalseWhenComparingContainerAndContainer() {
+ // when
+ GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+ null, null);
+
+ // given
+ IPath localPath = createMock(IPath.class);
+ replay(localPath);
+ IContainer local = createMock(IContainer.class);
+ expect(local.exists()).andReturn(true);
+ expect(local.getFullPath()).andReturn(localPath);
+ replay(local);
+
+ IPath remotePath = createMock(IPath.class);
+ replay(remotePath);
+ IResource remoteResource = createMock(IResource.class);
+ expect(remoteResource.getFullPath()).andReturn(remotePath);
+ replay(remoteResource);
+ GitFolderResourceVariant remote = new GitFolderResourceVariant(
+ remoteResource);
+
+ // then
+ assertFalse(grvc.compare(local, remote));
+ verify(local, localPath, remotePath, remoteResource);
+ }
+
+ /**
+ * When comparing two folders that have same path, compare() method should
+ * return true.
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnTrueWhenComparingContainerAndContainer() {
+ // when
+ GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+ null, null);
+
+ // given
+ IPath path = createMock(IPath.class);
+ replay(path);
+
+ IContainer local = createMock(IContainer.class);
+ expect(local.exists()).andReturn(true);
+ expect(local.getFullPath()).andReturn(path);
+ replay(local);
+
+ IResource remoteResource = createMock(IResource.class);
+ expect(remoteResource.getFullPath()).andReturn(path);
+ replay(remoteResource);
+ GitFolderResourceVariant remote = new GitFolderResourceVariant(
+ remoteResource);
+
+ // then
+ assertTrue(grvc.compare(local, remote));
+ verify(local, path, remoteResource);
+ }
+
+ /**
+ * Compare() should return false when comparing two files with different
+ * content length
+ * @throws Exception
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnFalseWhenContentLengthIsDifferent()
+ throws Exception {
+ // when
+ byte[] shortContent = "short content".getBytes();
+ byte[] longContent = "very long long content".getBytes();
+ GitSynchronizeData data = new GitSynchronizeData(repo, "", "", true);
+ GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+ GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+ dataSet, null);
+
+ // given
+ IFile local = createMock(IFile.class);
+ expect(local.exists()).andReturn(true);
+ expect(local.getProject()).andReturn(project.getProject()).anyTimes();
+ expect(local.getContents()).andReturn(
+ new ByteArrayInputStream(longContent));
+ replay(local);
+
+ IStorage storage = createMock(IStorage.class);
+ expect(storage.getContents()).andReturn(
+ new ByteArrayInputStream(shortContent));
+ replay(storage);
+
+ IResourceVariant remote = createMock(IResourceVariant.class);
+ expect(remote.isContainer()).andReturn(false);
+ expect(remote.getStorage((IProgressMonitor) anyObject())).andReturn(
+ storage).anyTimes();
+ replay(remote);
+
+ // then
+ assertFalse(grvc.compare(local, remote));
+ verify(local, remote, storage);
+ }
+
+ /**
+ * Comparing two files that have same content length but having small
+ * difference inside content should return false.
+ * @throws Exception
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnFalseWhenShortContentIsDifferent() throws Exception {
+ // when
+ byte[] localContent = "very long long content".getBytes();
+ // this typo should be here
+ byte[] remoteContent = "very long lonk content".getBytes();
+ GitSynchronizeData data = new GitSynchronizeData(repo, "", "", true);
+ GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+ GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+ dataSet, null);
+
+ // given
+ IFile local = createMock(IFile.class);
+ expect(local.exists()).andReturn(true);
+ expect(local.getProject()).andReturn(project.getProject());
+ expect(local.getContents()).andReturn(
+ new ByteArrayInputStream(localContent));
+ replay(local);
+
+ IStorage storage = createMock(IStorage.class);
+ expect(storage.getContents()).andReturn(
+ new ByteArrayInputStream(remoteContent));
+ replay(storage);
+
+ IResourceVariant remote = createMock(IResourceVariant.class);
+ expect(remote.isContainer()).andReturn(false);
+ expect(remote.getStorage((IProgressMonitor) anyObject())).andReturn(
+ storage).anyTimes();
+ replay(remote);
+
+ // then
+ assertFalse(grvc.compare(local, remote));
+ verify(local, remote);
+ }
+
+ /**
+ * Comparing two 'large' files that have same length and almost identical
+ * content should return false.
+ * @throws Exception
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnFalseWhenLongContentIsDifferent() throws Exception {
+ // when
+ byte[] localContent = new byte[8192];
+ Arrays.fill(localContent, (byte) 'a');
+ byte[] remoteContent = new byte[8192];
+ Arrays.fill(remoteContent, (byte) 'a');
+ remoteContent[8101] = 'b';
+ GitSynchronizeData data = new GitSynchronizeData(repo, "", "", true);
+ GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+ GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+ dataSet, null);
+
+ // given
+ IFile local = createMock(IFile.class);
+ expect(local.exists()).andReturn(true);
+ expect(local.getProject()).andReturn(project.getProject());
+ expect(local.getContents()).andReturn(
+ new ByteArrayInputStream(localContent));
+ replay(local);
+
+ IStorage storage = createMock(IStorage.class);
+ expect(storage.getContents()).andReturn(
+ new ByteArrayInputStream(remoteContent));
+ replay(storage);
+
+ IResourceVariant remote = createMock(IResourceVariant.class);
+ expect(remote.isContainer()).andReturn(false);
+ expect(remote.getStorage((IProgressMonitor) anyObject())).andReturn(
+ storage).anyTimes();
+ replay(remote);
+
+ // then
+ assertFalse(grvc.compare(local, remote));
+ verify(local, remote);
+ }
+
+ /**
+ * Comparing two 'large' files that have different length but same content
+ * should return false.
+ * <p>
+ * This and previous three test cases cover almost the same functionality
+ * but they are covering all return points in compare methods that can be
+ * used when comparing files content
+ * @throws Exception
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnFalseWhenLongContentLengthIsDifferent()
+ throws Exception {
+ // when
+ byte[] localContent = new byte[8192];
+ Arrays.fill(localContent, (byte) 'a');
+ byte[] remoteContent = new byte[8200];
+ Arrays.fill(remoteContent, (byte) 'a');
+ GitSynchronizeData data = new GitSynchronizeData(repo, "", "", true);
+ GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+ GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+ dataSet, null);
+
+ // given
+ IFile local = createMock(IFile.class);
+ expect(local.exists()).andReturn(true);
+ expect(local.getProject()).andReturn(project.getProject());
+ expect(local.getContents()).andReturn(
+ new ByteArrayInputStream(localContent));
+ replay(local);
+
+ IStorage storage = createMock(IStorage.class);
+ expect(storage.getContents()).andReturn(
+ new ByteArrayInputStream(remoteContent));
+ replay(storage);
+
+ IResourceVariant remote = createMock(IResourceVariant.class);
+ expect(remote.isContainer()).andReturn(false);
+ expect(remote.getStorage((IProgressMonitor) anyObject())).andReturn(
+ storage).anyTimes();
+ replay(remote);
+
+ // then
+ assertFalse(grvc.compare(local, remote));
+ verify(local, remote, storage);
+ }
+
+ /**
+ * Comparing two files that have the same content and content length should
+ * return true
+ * @throws Exception
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnTrueWhenShortContentIsDifferent() throws Exception {
+ // when
+ byte[] localContent = "very long long content".getBytes();
+ byte[] remoteContent = "very long long content".getBytes();
+ GitSynchronizeData data = new GitSynchronizeData(repo, "", "", true);
+ GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+ GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+ dataSet, null);
+
+ // given
+ IFile local = createMock(IFile.class);
+ expect(local.exists()).andReturn(true);
+ expect(local.getProject()).andReturn(project.getProject());
+ expect(local.getContents()).andReturn(
+ new ByteArrayInputStream(localContent));
+ replay(local);
+
+ IStorage storage = createMock(IStorage.class);
+ expect(storage.getContents()).andReturn(
+ new ByteArrayInputStream(remoteContent));
+ replay(storage);
+
+ IResourceVariant remote = createMock(IResourceVariant.class);
+ expect(remote.isContainer()).andReturn(false);
+ expect(remote.getStorage((IProgressMonitor) anyObject())).andReturn(
+ storage).anyTimes();
+ replay(remote);
+
+ // then
+ assertTrue(grvc.compare(local, remote));
+ verify(local, remote);
+ }
+
+ /**
+ * Compare two 'large' files that have same content length and content
+ * should return true.
+ * @throws Exception
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnTrueWhenLongContentLengthIsDifferent()
+ throws Exception {
+ // when
+ byte[] localContent = new byte[8192];
+ Arrays.fill(localContent, (byte) 'a');
+ byte[] remoteContent = new byte[8192];
+ Arrays.fill(remoteContent, (byte) 'a');
+ GitSynchronizeData data = new GitSynchronizeData(repo, "", "", true);
+ GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+ GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+ dataSet, null);
+
+ // given
+ IFile local = createMock(IFile.class);
+ expect(local.exists()).andReturn(true);
+ expect(local.getProject()).andReturn(project.getProject());
+ expect(local.getContents()).andReturn(
+ new ByteArrayInputStream(localContent));
+ replay(local);
+
+ IStorage storage = createMock(IStorage.class);
+ expect(storage.getContents()).andReturn(
+ new ByteArrayInputStream(remoteContent));
+ replay(storage);
+
+ IResourceVariant remote = createMock(IResourceVariant.class);
+ expect(remote.isContainer()).andReturn(false);
+ expect(remote.getStorage((IProgressMonitor) anyObject())).andReturn(
+ storage).anyTimes();
+ replay(remote);
+
+ // then
+ assertTrue(grvc.compare(local, remote));
+ verify(local, remote, storage);
+ }
+
+ /**
+ * When comparing locally not existing file with file that exists in remote,
+ * compare method should return false.
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnFalseWhenBaseDoesntExist() {
+ // when
+ GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+ null, null);
+
+ // given
+ IResource baseResource = createMock(IResource.class);
+ expect(baseResource.exists()).andReturn(false);
+ replay(baseResource);
+ GitBlobResourceVariant base = new GitBlobResourceVariant(baseResource,
+ repo, ObjectId.zeroId(), null);
+ IResource remoteResource = createMock(IResource.class);
+ replay(remoteResource);
+ GitBlobResourceVariant remote = new GitBlobResourceVariant(
+ remoteResource, repo, ObjectId.zeroId(), null);
+
+ // then
+ assertFalse(grvc.compare(base, remote));
+ verify(baseResource, remoteResource);
+ }
+
+ /**
+ * Compare() should return false when remote file does not exists, but
+ * equivalent local file exist.
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnFalseWhenRemoteVariantDoesntExist() {
+ // when
+ GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+ null, null);
+
+ // given
+ IResource baseResource = createMock(IResource.class);
+ expect(baseResource.exists()).andReturn(true);
+ replay(baseResource);
+ GitBlobResourceVariant base = new GitBlobResourceVariant(baseResource,
+ repo, ObjectId.zeroId(), null);
+ IResource remoteResource = createMock(IResource.class);
+ expect(remoteResource.exists()).andReturn(false);
+ replay(remoteResource);
+ GitBlobResourceVariant remote = new GitBlobResourceVariant(
+ remoteResource, repo, ObjectId.zeroId(), null);
+
+ // then
+ assertFalse(grvc.compare(base, remote));
+ verify(baseResource, remoteResource);
+ }
+
+ /*==================================================
+ * compare(IResourceVariant, IResourceVariant) tests
+ *==================================================*/
+
+ /**
+ * Return false when comparing incompatible types (file against folder) that
+ * also maps onto different resources
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnFalseWhenComparingRemoteVariantFileWithContainer() {
+ // when
+ GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+ null, null);
+
+ // given
+ IResource baseResource = createMock(IResource.class);
+ expect(baseResource.exists()).andReturn(true);
+ replay(baseResource);
+ GitBlobResourceVariant base = new GitBlobResourceVariant(baseResource,
+ repo, ObjectId.zeroId(), null);
+ IResource remoteResource = createMock(IResource.class);
+ expect(remoteResource.exists()).andReturn(true);
+ replay(remoteResource);
+ GitFolderResourceVariant remote = new GitFolderResourceVariant(
+ remoteResource);
+
+ // then
+ assertFalse(grvc.compare(base, remote));
+ verify(baseResource, remoteResource);
+ }
+
+ /**
+ * Return false when comparing incompatible types (folder against file) that
+ * also map onto different resources
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnFalseWhenComparingRemoteVariantContainerWithFile() {
+ // when
+ GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+ null, null);
+
+ // given
+ IResource baseResource = createMock(IResource.class);
+ expect(baseResource.exists()).andReturn(true);
+ replay(baseResource);
+ GitFolderResourceVariant base = new GitFolderResourceVariant(
+ baseResource);
+ IResource remoteResource = createMock(IResource.class);
+ expect(remoteResource.exists()).andReturn(true);
+ replay(remoteResource);
+ GitBlobResourceVariant remote = new GitBlobResourceVariant(
+ remoteResource, repo, ObjectId.zeroId(), null);
+
+ // then
+ assertFalse(grvc.compare(base, remote));
+ verify(baseResource, remoteResource);
+ }
+
+ /**
+ * When comparing two remote variants that have different path compare
+ * method should return false
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnFalseWhenComparingRemoteVariantContainerWithContainer() {
+ // when
+ GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+ null, null);
+
+ // given
+ IPath basePath = createMock(IPath.class);
+ replay(basePath);
+ IResource baseResource = createMock(IResource.class);
+ expect(baseResource.exists()).andReturn(true);
+ expect(baseResource.getFullPath()).andReturn(basePath);
+ replay(baseResource);
+ GitFolderResourceVariant base = new GitFolderResourceVariant(
+ baseResource);
+
+ IPath remotePath = createMock(IPath.class);
+ replay(remotePath);
+ IResource remoteResource = createMock(IResource.class);
+ expect(remoteResource.exists()).andReturn(true);
+ expect(remoteResource.getFullPath()).andReturn(remotePath);
+ replay(remoteResource);
+ GitFolderResourceVariant remote = new GitFolderResourceVariant(
+ remoteResource);
+
+ // then
+ assertFalse(grvc.compare(base, remote));
+ verify(baseResource, remoteResource, basePath, remotePath);
+ }
+
+ /**
+ * Comparing two remote folders that have same path should return true
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnTrueWhenComparingRemoteVariantContainerWithContainer() {
+ // when
+ GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+ null, null);
+
+ // given
+ IPath path = createMock(IPath.class);
+ replay(path);
+
+ IResource baseResource = createMock(IResource.class);
+ expect(baseResource.exists()).andReturn(true);
+ expect(baseResource.getFullPath()).andReturn(path);
+ replay(baseResource);
+ GitFolderResourceVariant base = new GitFolderResourceVariant(
+ baseResource);
+
+ IResource remoteResource = createMock(IResource.class);
+ expect(remoteResource.exists()).andReturn(true);
+ expect(remoteResource.getFullPath()).andReturn(path);
+ replay(remoteResource);
+ GitFolderResourceVariant remote = new GitFolderResourceVariant(
+ remoteResource);
+
+ // then
+ assertTrue(grvc.compare(base, remote));
+ verify(baseResource, remoteResource, path);
+ }
+
+ @Test
+ @SuppressWarnings("boxing")
+ /**
+ * Comparing two remote files that have different git ObjectId should return false.
+ */
+ public void shouldReturnFalseWhenComparingRemoteVariantWithDifferentObjectId() {
+ // when
+ GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+ null, null);
+
+ // given
+ IResource baseResource = createMock(IResource.class);
+ expect(baseResource.exists()).andReturn(true);
+ replay(baseResource);
+ GitBlobResourceVariant base = new GitBlobResourceVariant(
+ baseResource,
+ repo,
+ ObjectId.fromString("0123456789012345678901234567890123456789"),
+ null);
+
+ IResource remoteResource = createMock(IResource.class);
+ expect(remoteResource.exists()).andReturn(true);
+ replay(remoteResource);
+ GitBlobResourceVariant remote = new GitBlobResourceVariant(
+ remoteResource, repo, ObjectId.zeroId(), null);
+
+ // then
+ assertFalse(grvc.compare(base, remote));
+ verify(baseResource, remoteResource);
+ }
+
+ /**
+ * Comparing two remote files that have the same git ObjectId should return
+ * true.
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnTrueWhenComparingRemoteVariant() {
+ // when
+ GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+ null, null);
+
+ // given
+ IResource baseResource = createMock(IResource.class);
+ expect(baseResource.exists()).andReturn(true);
+ replay(baseResource);
+ GitBlobResourceVariant base = new GitBlobResourceVariant(
+ baseResource,
+ repo,
+ ObjectId.fromString("0123456789012345678901234567890123456789"),
+ null);
+
+ IResource remoteResource = createMock(IResource.class);
+ expect(remoteResource.exists()).andReturn(true);
+ replay(remoteResource);
+ GitBlobResourceVariant remote = new GitBlobResourceVariant(
+ remoteResource,
+ repo,
+ ObjectId.fromString("0123456789012345678901234567890123456789"),
+ null);
+
+ // then
+ assertTrue(grvc.compare(base, remote));
+ verify(baseResource, remoteResource);
+ }
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeTest.java
new file mode 100644
index 0000000..c80bffb
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeTest.java
@@ -0,0 +1,365 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * 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.core.synchronize;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.egit.core.op.BranchOperation;
+import org.eclipse.egit.core.op.ConnectProviderOperation;
+import org.eclipse.egit.core.op.DisconnectProviderOperation;
+import org.eclipse.egit.core.op.TrackOperation;
+import org.eclipse.egit.core.project.RepositoryMapping;
+import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.egit.core.test.GitTestCase;
+import org.eclipse.egit.core.test.TestProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IType;
+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.RefUpdate;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.team.core.variants.IResourceVariant;
+import org.eclipse.team.core.variants.ResourceVariantByteStore;
+import org.eclipse.team.core.variants.SessionResourceVariantByteStore;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class GitResourceVariantTreeTest extends GitTestCase {
+
+ private Repository repo;
+
+ private ResourceVariantByteStore store;
+
+ @Before
+ public void createGitRepository() throws Exception {
+ IProject iProject = project.project;
+ if (!gitDir.exists())
+ new Repository(gitDir).create();
+
+ new ConnectProviderOperation(iProject, gitDir).execute(null);
+ repo = RepositoryMapping.getMapping(iProject).getRepository();
+
+ store = new SessionResourceVariantByteStore();
+ }
+
+ @After
+ public void clearGitResources() throws Exception {
+ List<IProject> projects = new ArrayList<IProject>();
+ projects.add(project.project);
+ new DisconnectProviderOperation(projects).execute(null);
+
+ repo.close();
+ }
+
+ /**
+ * roots() method should return list of projects that are associated with
+ * given repository. In this case there is only one project associated with
+ * this repository therefore only one root should be returned.
+ */
+ @Test
+ public void shouldReturnOneRoot() {
+ // when
+ GitSynchronizeData data = new GitSynchronizeData(repo, "", "", false);
+ GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+
+ // given
+ GitResourceVariantTree grvt = new GitTestResourceVariantTree(dataSet,
+ store);
+
+ // then
+ assertEquals(1, grvt.roots().length);
+ IResource actualProject = grvt.roots()[0];
+ assertEquals(this.project.getProject(), actualProject);
+ }
+
+ /**
+ * When we have two or more project associated with repository, roots()
+ * method should return list of project. In this case we have two project
+ * associated with particular repository, therefore '2' value is expected.
+ * @throws Exception
+ */
+ @Test
+ public void shouldReturnTwoRoots() throws Exception {
+ // when
+ // create second project
+ TestProject secondProject = new TestProject(false, "Project-2");
+ IProject secondIProject = secondProject.project;
+ // add connect project with repository
+ new ConnectProviderOperation(secondIProject, gitDir).execute(null);
+ GitSynchronizeData data = new GitSynchronizeData(repo, "", "", false);
+ GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+
+ // given
+ GitResourceVariantTree grvt = new GitTestResourceVariantTree(dataSet,
+ store);
+
+ // then
+ assertEquals(2, grvt.roots().length);
+ IResource actualProject = grvt.roots()[1];
+ assertEquals(this.project.project, actualProject);
+ IResource actualProject1 = grvt.roots()[0];
+ assertEquals(secondIProject, actualProject1);
+ }
+
+ /**
+ * When we want to obtain list of members, members() method should return
+ * only members that are in repository. In this test we create Main.java
+ * file, stage it and commit it. Then we create Main2.java file with we don't
+ * add to repository. members() method should return one member because only
+ * one file is in repository.
+ * @throws Exception
+ */
+ @Test
+ public void shouldReturnOneMember() throws Exception {
+ // when
+ createResourceAndCommit("org.egit.test", "Main.java", "class Main {}",
+ "Initial commit");
+ // create second file that isn't tracked
+ IPackageFragment iPackage = project
+ .createPackage("org.egit.test.nested");
+ project.createType(iPackage, "Main2.java", "class Main2 {}");
+ GitSynchronizeData data = new GitSynchronizeData(repo, Constants.HEAD,
+ Constants.MASTER, false);
+ GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+
+ // given
+ GitResourceVariantTree grvt = new GitRemoteResourceVariantTree(dataSet,
+ store);
+
+ // then
+ assertEquals(1, grvt.members(project.project).length);
+ IResource[] members = grvt.members(project.project);
+ assertEquals("src", members[0].getName());
+ }
+
+ /**
+ * members() method should return only members that are on same level (it
+ * cannot work recursively). In this test it should return one file and one
+ * folder member.
+ * @throws Exception
+ */
+ @Ignore
+ @Test
+ public void shouldReturnTwoMembers() throws Exception {
+ // when
+ IPackageFragment iPackage = project.createPackage("org.egit.test");
+ createResourceAndCommit(iPackage, "Main.java", "class Main {}",
+ "Initial commit");
+ // create second file that isn't tracked
+ createResourceAndCommit("org.egit.test.nested", "Main2.java",
+ "class Main2 {}", "Second commit");
+
+ GitSynchronizeData data = new GitSynchronizeData(repo, Constants.HEAD,
+ Constants.MASTER, false);
+ GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+
+ // given
+ GitResourceVariantTree grvt = new GitRemoteResourceVariantTree(dataSet,
+ store);
+
+ // then
+ assertEquals(2, grvt.members(iPackage.getResource()).length);
+ IResource[] members = grvt.members(iPackage.getResource());
+ assertEquals("nested", members[0].getName());
+ assertEquals("Main.java", members[1].getName());
+ }
+
+ /**
+ * Checks that getResourceVariant will not throw NPE for null argument. This
+ * method is called with null argument when local or remote resource does
+ * not exist.
+ * @throws Exception
+ */
+ @Test
+ public void shouldReturnNullResourceVariant() throws Exception {
+ // when
+ GitSynchronizeData data = new GitSynchronizeData(repo, Constants.HEAD,
+ Constants.MASTER, false);
+ GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+
+ // given
+ GitResourceVariantTree grvt = new GitRemoteResourceVariantTree(dataSet,
+ store);
+
+ // then
+ assertNull(grvt.getResourceVariant(null));
+ }
+
+ /**
+ * getResourceVariant() should return null when given resource doesn't exist
+ * in repository.
+ * @throws Exception
+ */
+ @Test
+ public void shouldReturnNullResourceVariant2() throws Exception {
+ // when
+ IPackageFragment iPackage = project.createPackage("org.egit.test");
+ IType mainJava = project.createType(iPackage, "Main.java",
+ "class Main {}");
+ GitSynchronizeData data = new GitSynchronizeData(repo, Constants.HEAD,
+ Constants.MASTER, false);
+ GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+
+ // given
+ GitResourceVariantTree grvt = new GitRemoteResourceVariantTree(dataSet,
+ store);
+
+ // then
+ assertNull(grvt.getResourceVariant(mainJava.getResource()));
+ }
+
+ /**
+ * Check if getResourceVariant() does return the same resource that was
+ * committed. Passes only when it is run as a single test, not as a part of
+ * largest test suite
+ * @throws Exception
+ */
+ @Ignore
+ @Test
+ public void shoulReturnSameResourceVariant() throws Exception {
+ // when
+ IType mainJava = createResourceAndCommit("org.egit.test", "Main.java",
+ "class Main {}", "Initial commit");
+ GitSynchronizeData data = new GitSynchronizeData(repo, Constants.HEAD,
+ Constants.MASTER, false);
+ GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+
+ // given
+ GitResourceVariantTree grvt = new GitRemoteResourceVariantTree(dataSet,
+ store);
+
+ // then
+ IResourceVariant actual = grvt.getResourceVariant(mainJava
+ .getResource());
+ assertNotNull(actual);
+ assertEquals("Main.java", actual.getName());
+
+ InputStream actualIn = actual.getStorage(new NullProgressMonitor())
+ .getContents();
+ byte[] actualByte = new byte[actualIn.available()];
+ actualIn.read(actualByte);
+ InputStream expectedIn = ((IFile) mainJava.getResource()).getContents();
+ byte[] expectedByte = new byte[expectedIn.available()];
+ expectedIn.read(expectedByte);
+ assertArrayEquals(expectedByte, actualByte);
+ }
+
+ /**
+ * Create and commit Main.java file in master branch, then create branch
+ * "test" checkout nearly created branch and modify Main.java file.
+ * getResourceVariant() should obtain Main.java file content from "master"
+ * branch. Passes only when it is run as a single test, not as a part of
+ * largest test suite
+ * @throws Exception
+ */
+ @Ignore
+ @Test
+ public void shouldReturnDifferentResourceVariant() throws Exception {
+ // when
+ IType mainJava = createResourceAndCommit("org.egit.test", "Main.java",
+ "class Main {}", "Initial commit");
+ createBranch("test");
+ // checkout branch
+ new BranchOperation(repo, "refs/heads/test").execute(null);
+ ((IFile) mainJava.getResource()).appendContents(
+ new ByteArrayInputStream("// test".getBytes()), 0, null);
+ addAndCommitResource(mainJava, "Second commit");
+ GitSynchronizeData data = new GitSynchronizeData(repo, Constants.HEAD,
+ Constants.MASTER, false);
+ GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+
+ // given
+ GitResourceVariantTree grvt = new GitRemoteResourceVariantTree(dataSet,
+ store);
+
+ // then
+ IResourceVariant actual = grvt.getResourceVariant(mainJava
+ .getResource());
+ assertNotNull(actual);
+ assertEquals("Main.java", actual.getName());
+
+ InputStream actualIn = actual.getStorage(new NullProgressMonitor())
+ .getContents();
+ byte[] actualByte = new byte[actualIn.available()];
+ actualIn.read(actualByte);
+ InputStream expectedIn = ((IFile) mainJava.getResource()).getContents();
+ byte[] expectedByte = new byte[expectedIn.available()];
+ expectedIn.read(expectedByte);
+
+ // assert arrays not equals
+ if (Arrays.equals(expectedByte, actualByte)) {
+ fail();
+ } else {
+ assertTrue(true);
+ }
+ }
+
+ private IType createResourceAndCommit(String packageName, String fileName,
+ String fileContent, String commitMsg) throws Exception {
+ IPackageFragment iPackage = project.createPackage(packageName);
+ return createResourceAndCommit(iPackage, fileName, fileContent,
+ commitMsg);
+ }
+
+ private IType createResourceAndCommit(IPackageFragment iPackage,
+ String fileName, String fileContent, String commitMsg)
+ throws Exception {
+ IType mainJava = project.createType(iPackage, fileName, fileContent);
+ addAndCommitResource(mainJava, commitMsg);
+
+ return mainJava;
+ }
+
+ private void addAndCommitResource(IType mainJava, String commitMsg)
+ throws Exception {
+ List<IResource> resources = new ArrayList<IResource>();
+ resources.add(mainJava.getResource());
+ IResource[] track = resources.toArray(new IResource[resources.size()]);
+ new TrackOperation(track).execute(null); // add resource to git
+ new Git(repo).commit().setMessage(commitMsg).call(); // make commit
+ }
+
+ private void createBranch(String branchName) throws Exception {
+ RefUpdate updateRef;
+ updateRef = repo.updateRef(Constants.R_HEADS + branchName);
+ Ref startRef = repo.getRef(branchName);
+ ObjectId startAt = repo.resolve(Constants.HEAD);
+ String startBranch;
+ if (startRef != null)
+ startBranch = branchName;
+ else
+ startBranch = startAt.name();
+ startBranch = repo.shortenRefName(startBranch);
+ updateRef.setNewObjectId(startAt);
+ updateRef
+ .setRefLogMessage("branch: Created from " + startBranch, false); //$NON-NLS-1$
+ updateRef.update();
+ }
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitSyncInfoTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitSyncInfoTest.java
new file mode 100644
index 0000000..a0bc11b
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitSyncInfoTest.java
@@ -0,0 +1,732 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * 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.core.synchronize;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.eclipse.team.core.synchronize.SyncInfo.ADDITION;
+import static org.eclipse.team.core.synchronize.SyncInfo.CHANGE;
+import static org.eclipse.team.core.synchronize.SyncInfo.CONFLICTING;
+import static org.eclipse.team.core.synchronize.SyncInfo.DELETION;
+import static org.eclipse.team.core.synchronize.SyncInfo.INCOMING;
+import static org.eclipse.team.core.synchronize.SyncInfo.IN_SYNC;
+import static org.eclipse.team.core.synchronize.SyncInfo.OUTGOING;
+import static org.eclipse.team.core.synchronize.SyncInfo.PSEUDO_CONFLICT;
+import static org.junit.Assert.assertEquals;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.util.Arrays;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.egit.core.op.ConnectProviderOperation;
+import org.eclipse.egit.core.project.RepositoryMapping;
+import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.egit.core.test.GitTestCase;
+import org.eclipse.jgit.api.CommitCommand;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.lib.GitIndex;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.GitIndex.Entry;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevCommitList;
+import org.junit.Before;
+import org.junit.Test;
+
+public class GitSyncInfoTest extends GitTestCase {
+
+ private Repository repo;
+
+ private GitResourceVariantComparator comparator;
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ IProject iProject = project.project;
+ if (!gitDir.exists())
+ new Repository(gitDir).create();
+
+ new ConnectProviderOperation(iProject, gitDir).execute(null);
+ repo = RepositoryMapping.getMapping(iProject).getRepository();
+
+ GitSynchronizeData data = new GitSynchronizeData(repo, "", "", true);
+ GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+ comparator = new GitResourceVariantComparator(dataSet, null);
+ }
+
+ /**
+ * File is in sync when local, base and remote objects refer to identical
+ * file (same git ObjectId).
+ * @throws Exception
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnResourceFileInSync() throws Exception {
+ // when
+
+ // given
+ String fileName = "test-file";
+ byte[] localBytes = new byte[8200];
+ Arrays.fill(localBytes, (byte) 'a');
+
+ IFile local = createMock(IFile.class);
+ expect(local.isDerived()).andReturn(false);
+ expect(local.exists()).andReturn(true).times(2);
+ expect(local.getName()).andReturn(fileName).anyTimes();
+ expect(local.getProject()).andReturn(project.getProject());
+ expect(local.getContents()).andReturn(
+ new ByteArrayInputStream(localBytes));
+ replay(local);
+
+ ObjectId objectId = stageAndCommit(fileName, localBytes);
+
+ IFile baseResource = createMock(IFile.class);
+ replay(baseResource);
+ GitBlobResourceVariant base = new GitBlobResourceVariant(baseResource,
+ repo, objectId, null);
+
+ IResource remoteResource = createMock(IResource.class);
+ replay(remoteResource);
+ GitBlobResourceVariant remote = new GitBlobResourceVariant(
+ remoteResource, repo, objectId, null);
+
+ GitSyncInfo gsi = new GitSyncInfo(local, base, remote, comparator);
+ gsi.init();
+
+ // then
+ assertEquals(IN_SYNC, gsi.getKind());
+ verify(local, baseResource, remoteResource);
+ }
+
+ /**
+ * Folders are in sync when they have same name.
+ * @throws Exception
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnResourceFolderInSync() throws Exception {
+ // when
+
+ // given
+ IResource local = createMock(IResource.class);
+ expect(local.isDerived()).andReturn(false);
+ expect(local.exists()).andReturn(true).times(3);
+ expect(local.getName()).andReturn("src").anyTimes();
+ replay(local);
+
+ GitFolderResourceVariant base = new GitFolderResourceVariant(local);
+ GitFolderResourceVariant remote = new GitFolderResourceVariant(local);
+
+ GitSyncInfo gsi = new GitSyncInfo(local, base, remote, comparator);
+ gsi.init();
+
+ // then
+ assertEquals(IN_SYNC, gsi.getKind());
+ verify(local);
+ }
+
+ /**
+ * Outgoing change should be returned when base RevCommitList has more
+ * commits than remote RevCommitList
+ * @throws Exception
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnOutgoingFileChange() throws Exception {
+ // when
+
+ // given
+ String fileName = "test-file";
+ byte[] localBytes = new byte[8200];
+ Arrays.fill(localBytes, (byte) 'a');
+
+ IFile local = createMock(IFile.class);
+ expect(local.isDerived()).andReturn(false);
+ expect(local.exists()).andReturn(true).times(2);
+ expect(local.getName()).andReturn(fileName).anyTimes();
+ expect(local.getProject()).andReturn(project.getProject());
+ expect(local.getContents()).andReturn(
+ new ByteArrayInputStream(localBytes));
+ replay(local);
+
+ stage(fileName, localBytes);
+ RevCommit firstCommit = commit();
+ localBytes[8120] = 'b';
+ ObjectId objectId = stage(fileName, localBytes);
+ RevCommit secondCommit = commit();
+ RevCommitList<RevCommit> baseCommits = new RevCommitList<RevCommit>();
+ baseCommits.add(firstCommit);
+ baseCommits.add(secondCommit);
+
+ IFile baseResource = createMock(IFile.class);
+ replay(baseResource);
+ GitBlobResourceVariant base = new GitBlobResourceVariant(baseResource,
+ repo, objectId, baseCommits); // baseComits has two entry
+
+ IResource remoteResource = createMock(IResource.class);
+ replay(remoteResource);
+ RevCommitList<RevCommit> remoteCommits = new RevCommitList<RevCommit>();
+ remoteCommits.add(firstCommit);
+ GitBlobResourceVariant remote = new GitBlobResourceVariant(
+ remoteResource,
+ repo,
+ ObjectId.fromString("0123456789012345678901234567890123456789"),
+ remoteCommits); // remoteCommits has only one entry
+
+ GitSyncInfo gsi = new GitSyncInfo(local, base, remote, comparator);
+ gsi.init();
+
+ // then
+ assertEquals(OUTGOING | CHANGE, gsi.getKind());
+ verify(local, baseResource, remoteResource);
+ }
+
+ /**
+ * Should return incoming change when remote RevCommitList has more commit
+ * objects then base RevCommitList
+ * @throws Exception
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnIncomingFileChange() throws Exception {
+ // when
+
+ // given
+ String fileName = "test-file";
+ byte[] localBytes = new byte[8200];
+ Arrays.fill(localBytes, (byte) 'a');
+
+ IFile local = createMock(IFile.class);
+ expect(local.isDerived()).andReturn(false);
+ expect(local.exists()).andReturn(true).times(2);
+ expect(local.getName()).andReturn(fileName).anyTimes();
+ expect(local.getProject()).andReturn(project.getProject());
+ expect(local.getContents()).andReturn(
+ new ByteArrayInputStream(localBytes));
+ replay(local);
+
+ ObjectId objectId = stage(fileName, localBytes);
+ RevCommit firstCommit = commit();
+ RevCommitList<RevCommit> baseCommits = new RevCommitList<RevCommit>();
+ baseCommits.add(firstCommit);
+
+ IFile baseResource = createMock(IFile.class);
+ replay(baseResource);
+ GitBlobResourceVariant base = new GitBlobResourceVariant(baseResource,
+ repo, objectId, baseCommits); // baseCommits has one element
+
+ IResource remoteResource = createMock(IResource.class);
+ replay(remoteResource);
+
+ stage(fileName, localBytes);
+ RevCommit secondCommit = commit();
+ RevCommitList<RevCommit> remoteCommits = new RevCommitList<RevCommit>();
+ remoteCommits.add(secondCommit);
+ remoteCommits.add(firstCommit);
+ GitBlobResourceVariant remote = new GitBlobResourceVariant(
+ remoteResource,
+ repo,
+ ObjectId.fromString("0123456789012345678901234567890123456789"),
+ remoteCommits); // remoteCommits has two elements
+
+ GitSyncInfo gsi = new GitSyncInfo(local, base, remote, comparator);
+ gsi.init();
+
+ // then
+ assertEquals(INCOMING | CHANGE, gsi.getKind());
+ verify(local, baseResource, remoteResource);
+ }
+
+ /**
+ * Outgoing deletion should be returned when resource exist in base and
+ * remote but does not exist locally.
+ * @throws Exception
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnOutgoingDeletion() throws Exception {
+ // when
+
+ // given
+ IResource local = createMock(IResource.class);
+ expect(local.isDerived()).andReturn(false);
+ expect(local.exists()).andReturn(false);
+ expect(local.getName()).andReturn("Mian.java").anyTimes();
+ replay(local);
+
+ IPath path = createMock(IPath.class);
+ replay(path);
+
+ IResource baseResource = createMock(IResource.class);
+ expect(baseResource.exists()).andReturn(true);
+ expect(baseResource.getFullPath()).andReturn(path);
+ replay(baseResource);
+ GitFolderResourceVariant base = new GitFolderResourceVariant(
+ baseResource);
+
+ IResource remoteResource = createMock(IResource.class);
+ expect(remoteResource.exists()).andReturn(true);
+ expect(remoteResource.getFullPath()).andReturn(path);
+ replay(remoteResource);
+ GitFolderResourceVariant remote = new GitFolderResourceVariant(
+ remoteResource);
+
+ GitSyncInfo gsi = new GitSyncInfo(local, base, remote, comparator);
+ gsi.init();
+
+ // then
+ assertEquals(OUTGOING | DELETION, gsi.getKind());
+ verify(local, baseResource, remoteResource, path);
+ }
+
+ /**
+ * Incoming deletion should be returned when file exists locally and in base
+ * but does not exist in remote resource variant.
+ * @throws Exception
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnIncomingFileDeletion() throws Exception {
+ // when
+
+ // given
+ String fileName = "test-file";
+ byte[] localBytes = new byte[8200];
+ Arrays.fill(localBytes, (byte) 'a');
+
+ IFile local = createMock(IFile.class);
+ expect(local.isDerived()).andReturn(false);
+ expect(local.exists()).andReturn(true).times(2);
+ expect(local.getName()).andReturn(fileName).anyTimes();
+ expect(local.getProject()).andReturn(project.getProject());
+ expect(local.getContents()).andReturn(
+ new ByteArrayInputStream(localBytes));
+ replay(local);
+
+ stage(fileName, localBytes);
+ RevCommit firstCommit = commit();
+ ObjectId objectId = stage(fileName, localBytes);
+ RevCommit secondCommit = commit();
+ RevCommitList<RevCommit> baseCommits = new RevCommitList<RevCommit>();
+ baseCommits.add(firstCommit);
+ baseCommits.add(secondCommit);
+
+ IFile baseResource = createMock(IFile.class);
+ replay(baseResource);
+ GitBlobResourceVariant base = new GitBlobResourceVariant(baseResource,
+ repo, objectId, baseCommits);
+
+ GitSyncInfo gsi = new GitSyncInfo(local, base, null, comparator);
+ gsi.init();
+
+ // then
+ assertEquals(INCOMING | DELETION, gsi.getKind());
+ verify(local, baseResource);
+ }
+
+ /**
+ * Outgoing addition should be returned when resource exists locally but it
+ * can't be found in base and remote resource variant.
+ * @throws Exception
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnOutgoingAddition() throws Exception {
+ // when
+
+ // given
+ IResource baseResource = createMock(IResource.class);
+ expect(baseResource.exists()).andReturn(true).times(2);
+ expect(baseResource.isDerived()).andReturn(false);
+ expect(baseResource.getName()).andReturn("Mian.java").anyTimes();
+ replay(baseResource);
+ GitSyncInfo gsi = new GitSyncInfo(baseResource, null, null, comparator);
+ gsi.init();
+
+ // then
+ assertEquals(OUTGOING | ADDITION, gsi.getKind());
+ verify(baseResource);
+ }
+
+ /**
+ * Conflicting change should be returned when remote and base RevCommitList
+ * have same number of RevCommit object's but these lists have one ore more
+ * different RevCommit objects.
+ * @throws Exception
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnConflictingFileChange() throws Exception {
+ // when
+
+ // given
+ String fileName = "test-file";
+ byte[] localBytes = new byte[8200];
+ Arrays.fill(localBytes, (byte) 'a');
+
+ IFile local = createMock(IFile.class);
+ expect(local.isDerived()).andReturn(false);
+ expect(local.exists()).andReturn(true).times(2);
+ expect(local.getName()).andReturn(fileName).anyTimes();
+ expect(local.getProject()).andReturn(project.getProject());
+ expect(local.getContents()).andReturn(
+ new ByteArrayInputStream(localBytes));
+ replay(local);
+
+ ObjectId objectId = stage(fileName, localBytes);
+ RevCommit firstCommit = commit();
+ RevCommitList<RevCommit> baseCommits = new RevCommitList<RevCommit>();
+ baseCommits.add(firstCommit);
+
+ IFile baseResource = createMock(IFile.class);
+ replay(baseResource);
+ GitBlobResourceVariant base = new GitBlobResourceVariant(baseResource,
+ repo, objectId, baseCommits);
+
+ IResource remoteResource = createMock(IResource.class);
+ replay(remoteResource);
+
+ stage(fileName, localBytes);
+ RevCommit secondCommit = commit();
+ RevCommitList<RevCommit> remoteCommits = new RevCommitList<RevCommit>();
+ remoteCommits.add(secondCommit);
+ GitBlobResourceVariant remote = new GitBlobResourceVariant(
+ remoteResource,
+ repo,
+ ObjectId.fromString("0123456789012345678901234567890123456789"),
+ remoteCommits);
+
+ GitSyncInfo gsi = new GitSyncInfo(local, base, remote, comparator);
+ gsi.init();
+
+ // then
+ assertEquals(CONFLICTING | CHANGE, gsi.getKind());
+ verify(local, baseResource, remoteResource);
+ }
+
+ /**
+ * Conflicting change should be returned when file was created locally with
+ * same name as incoming folder in remote.
+ * @throws Exception
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnConflictingFileChange1() throws Exception {
+ // when
+
+ // given
+ IFile local = createMock(IFile.class);
+ expect(local.isDerived()).andReturn(false);
+ expect(local.exists()).andReturn(true).times(1);
+ expect(local.getName()).andReturn("test-file").anyTimes();
+ replay(local);
+
+ IFile baseResource = createMock(IFile.class);
+ replay(baseResource);
+ GitBlobResourceVariant base = new GitBlobResourceVariant(baseResource,
+ repo, null, null);
+ IResource remoteResource = createMock(IResource.class);
+ replay(remoteResource);
+ GitFolderResourceVariant remote = new GitFolderResourceVariant(
+ remoteResource);
+
+ GitSyncInfo gsi = new GitSyncInfo(local, base, remote, comparator);
+ gsi.init();
+
+ // then
+ assertEquals(CONFLICTING | CHANGE, gsi.getKind());
+ verify(local, baseResource, remoteResource);
+ }
+
+ /**
+ * Conflicting change should be returned when local resource differ from
+ * base resource variant and remote variant does not exist.
+ * @throws Exception
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnConflictingFileChange2() throws Exception {
+ // when
+
+ // given
+ String fileName = "test-file";
+ byte[] localBytes = new byte[8200];
+ Arrays.fill(localBytes, (byte) 'a');
+
+ IFile local = createMock(IFile.class);
+ expect(local.isDerived()).andReturn(false);
+ expect(local.exists()).andReturn(true).times(2);
+ expect(local.getName()).andReturn(fileName).anyTimes();
+ expect(local.getProject()).andReturn(project.getProject());
+ expect(local.getContents()).andReturn(
+ new ByteArrayInputStream(localBytes));
+ replay(local);
+
+ stage(fileName, localBytes);
+ RevCommit firstCommit = commit();
+ byte[] remoteBytes = Arrays.copyOf(localBytes, localBytes.length);
+ remoteBytes[8100] = 'b';
+ ObjectId objectId = stage(fileName, remoteBytes);
+ RevCommit secondCommit = commit();
+ RevCommitList<RevCommit> baseCommits = new RevCommitList<RevCommit>();
+ baseCommits.add(firstCommit);
+ baseCommits.add(secondCommit);
+
+ IFile baseResource = createMock(IFile.class);
+ replay(baseResource);
+ GitBlobResourceVariant base = new GitBlobResourceVariant(baseResource,
+ repo, objectId, baseCommits);
+
+ GitSyncInfo gsi = new GitSyncInfo(local, base, null, comparator);
+ gsi.init();
+
+ // then
+ assertEquals(CONFLICTING | CHANGE, gsi.getKind());
+ verify(local, baseResource);
+ }
+
+ /**
+ * Conflicting change when folder exists locally and remotely but it does
+ * not exist in base resource variant.
+ * @throws Exception
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnConflictingFolderChange() throws Exception {
+ // when
+
+ // given
+ IResource local = createMock(IResource.class);
+ expect(local.exists()).andReturn(true);
+ expect(local.isDerived()).andReturn(false);
+ expect(local.getName()).andReturn("Mian.java").anyTimes();
+ replay(local);
+
+ IResource baseResource = createMock(IResource.class);
+ expect(baseResource.exists()).andReturn(false);
+ replay(baseResource);
+ GitFolderResourceVariant base = new GitFolderResourceVariant(
+ baseResource);
+
+ IResource remoteResource = createMock(IResource.class);
+ expect(remoteResource.exists()).andReturn(true);
+ replay(remoteResource);
+ GitFolderResourceVariant remote = new GitFolderResourceVariant(
+ remoteResource);
+ GitSyncInfo gsi = new GitSyncInfo(local, base, remote, comparator);
+ gsi.init();
+
+ // then
+ assertEquals(CONFLICTING | CHANGE, gsi.getKind());
+ verify(local, baseResource, remoteResource);
+ }
+
+ /**
+ * Conflicting change when folder exists in base but it does not exist in
+ * local and remote.
+ * @throws Exception
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnConflictingFolderChange1() throws Exception {
+ // when
+
+ // given
+ IResource local = createMock(IResource.class);
+ expect(local.exists()).andReturn(false);
+ expect(local.isDerived()).andReturn(false);
+ expect(local.getName()).andReturn("Mian.java").anyTimes();
+ replay(local);
+
+ IResource baseResource = createMock(IResource.class);
+ expect(baseResource.exists()).andReturn(true);
+ replay(baseResource);
+ GitFolderResourceVariant base = new GitFolderResourceVariant(
+ baseResource);
+
+ IResource remoteResource = createMock(IResource.class);
+ expect(remoteResource.exists()).andReturn(false);
+ replay(remoteResource);
+ GitFolderResourceVariant remote = new GitFolderResourceVariant(
+ remoteResource);
+ GitSyncInfo gsi = new GitSyncInfo(local, base, remote, comparator);
+ gsi.init();
+
+ // then
+ assertEquals(CONFLICTING | CHANGE, gsi.getKind());
+ verify(local, baseResource, remoteResource);
+ }
+
+ /*
+ * When local resource is file, base resource variant is folder and remote
+ * variant is a file, then getKind() should return conflicting change.
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnConflictingFolderAndFileChange() throws Exception {
+ // when
+
+ // given
+ IResource local = createMock(IResource.class);
+ expect(local.exists()).andReturn(false);
+ expect(local.isDerived()).andReturn(false);
+ expect(local.getName()).andReturn("Mian.java").anyTimes();
+ replay(local);
+
+ IResource baseResource = createMock(IResource.class);
+ expect(baseResource.exists()).andReturn(true);
+ replay(baseResource);
+ GitFolderResourceVariant base = new GitFolderResourceVariant(
+ baseResource);
+
+ IResource remoteResource = createMock(IResource.class);
+ expect(remoteResource.exists()).andReturn(true);
+ replay(remoteResource);
+ GitBlobResourceVariant remote = new GitBlobResourceVariant(
+ remoteResource, repo, ObjectId.zeroId(), null);
+ GitSyncInfo gsi = new GitSyncInfo(local, base, remote, comparator);
+ gsi.init();
+
+ // then
+ assertEquals(CONFLICTING | CHANGE, gsi.getKind());
+ verify(local, baseResource, remoteResource);
+ }
+
+ /**
+ * When remote is folder and base is a file getKind() should return
+ * conflicting change
+ * @throws Exception
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnConflictingFileAndFolderChange() throws Exception {
+ // when
+
+ // given
+ IResource local = createMock(IResource.class);
+ expect(local.exists()).andReturn(false);
+ expect(local.isDerived()).andReturn(false);
+ expect(local.getName()).andReturn("Mian.java").anyTimes();
+ replay(local);
+
+ IResource baseResource = createMock(IResource.class);
+ expect(baseResource.exists()).andReturn(true);
+ replay(baseResource);
+ GitBlobResourceVariant base = new GitBlobResourceVariant(baseResource,
+ repo, ObjectId.zeroId(), null);
+
+ IResource remoteResource = createMock(IResource.class);
+ expect(remoteResource.exists()).andReturn(true);
+ replay(remoteResource);
+ GitFolderResourceVariant remote = new GitFolderResourceVariant(
+ remoteResource);
+ GitSyncInfo gsi = new GitSyncInfo(local, base, remote, comparator);
+ gsi.init();
+
+ // then
+ assertEquals(CONFLICTING | CHANGE, gsi.getKind());
+ verify(local, baseResource, remoteResource);
+ }
+
+ /**
+ * Remote resource variant was not found, local resource does not exist but
+ * there is a base resource. In such situation we should return conflicting
+ * deletion.
+ * @throws Exception
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnConflictingDeletationPseudoConflict()
+ throws Exception {
+ // when
+
+ // given
+ IResource local = createMock(IResource.class);
+ expect(local.exists()).andReturn(false);
+ expect(local.isDerived()).andReturn(false);
+ expect(local.getName()).andReturn("Mian.java").anyTimes();
+ replay(local);
+
+ IResource baseResource = createMock(IResource.class);
+ replay(baseResource);
+ GitFolderResourceVariant base = new GitFolderResourceVariant(
+ baseResource);
+
+ GitSyncInfo gsi = new GitSyncInfo(local, base, null, comparator);
+ gsi.init();
+
+ // then
+ assertEquals(CONFLICTING | DELETION | PSEUDO_CONFLICT, gsi.getKind());
+ verify(local, baseResource);
+ }
+
+ /**
+ * Conflicting addition should be returned when resource exists in local and
+ * remote but cannot be found in base
+ * @throws Exception
+ */
+ @Test
+ @SuppressWarnings("boxing")
+ public void shouldReturnConflictingAddition() throws Exception {
+ // when
+
+ // given
+ IResource local = createMock(IResource.class);
+ expect(local.exists()).andReturn(true).times(3);
+ expect(local.isDerived()).andReturn(false);
+ expect(local.getName()).andReturn("Mian.java").anyTimes();
+ replay(local);
+
+ IResource remoteResource = createMock(IResource.class);
+ replay(remoteResource);
+ GitBlobResourceVariant remote = new GitBlobResourceVariant(
+ remoteResource, repo, ObjectId.zeroId(), null);
+ GitSyncInfo gsi = new GitSyncInfo(local, null, remote, comparator);
+ gsi.init();
+
+ // then
+ assertEquals(CONFLICTING | ADDITION, gsi.getKind());
+ verify(local, remoteResource);
+ }
+
+ private ObjectId stageAndCommit(String fileName, byte[] content)
+ throws Exception {
+ ObjectId objectId = stage(fileName, content);
+ commit();
+
+ return objectId;
+ }
+
+ private ObjectId stage(String fileName, byte[] content) throws Exception {
+ // TODO reimplement using DirCache class
+ GitIndex index = repo.getIndex();
+ File workdir = project.getProject().getFullPath().toFile();
+ File file = new File(workdir, fileName);
+ Entry entry = index.add(workdir, file, content);
+ index.write();
+
+ return entry.getObjectId();
+ }
+
+ private RevCommit commit() throws Exception {
+ Git git = new Git(repo);
+ CommitCommand commit = git.commit();
+ commit.setMessage("Initial commit");
+ commit.setAuthor("EGit", "egi@eclipse.org");
+ return commit.call();
+ }
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitTestResourceVariantTree.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitTestResourceVariantTree.java
new file mode 100644
index 0000000..0cdd595
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitTestResourceVariantTree.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * 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.core.synchronize;
+
+import java.io.IOException;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Tree;
+import org.eclipse.team.core.variants.ResourceVariantByteStore;
+
+/**
+ * Implementation of abstract {@link GitResourceVariantTree} class. It is only
+ * used in {@link GitResourceVariantTreeTest} for testing public methods that
+ * are implemented in base class.
+ */
+class GitTestResourceVariantTree extends GitResourceVariantTree {
+
+ GitTestResourceVariantTree(GitSynchronizeDataSet data,
+ ResourceVariantByteStore store) {
+ super(data, store);
+ }
+
+ @Override
+ ObjectId getRevObjId(IResource resource) throws IOException {
+ // not used in test case
+ return null;
+ }
+
+ @Override
+ Tree getRevTree(IResource resource) throws IOException {
+ // TODO not used in test case
+ return null;
+ }
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/TestProject.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/TestProject.java
index 24ab17b..a20c4b4 100644
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/TestProject.java
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/TestProject.java
@@ -49,14 +49,19 @@ public class TestProject {
this(false);
}
+ public TestProject(boolean remove) throws CoreException {
+ this(remove, "Project-1");
+ }
+
/**
* @param remove
* should project be removed if already exists
+ * @param projectName
* @throws CoreException
*/
- public TestProject(final boolean remove) throws CoreException {
+ public TestProject(final boolean remove, String projectName) throws CoreException {
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
- project = root.getProject("Project-1");
+ project = root.getProject(projectName);
if (remove)
project.delete(true, null);
project.create(null);
diff --git a/org.eclipse.egit.core/META-INF/MANIFEST.MF b/org.eclipse.egit.core/META-INF/MANIFEST.MF
index 86dbec0..4e7b438 100644
--- a/org.eclipse.egit.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.core/META-INF/MANIFEST.MF
@@ -35,7 +35,8 @@ Export-Package: org.eclipse.egit.core;version="0.9.0";
org.eclipse.egit.core.synchronize.dto;version="0.9.0";uses:="org.eclipse.jgit.lib,org.eclipse.core.resources"
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: J2SE-1.5
-Import-Package: org.eclipse.jgit.api;version="[0.9.0,0.10.0)",
+Import-Package: org.easymock;version="[2.4.0,3.0.0)",
+ org.eclipse.jgit.api;version="[0.9.0,0.10.0)",
org.eclipse.jgit.dircache;version="[0.9.0,0.10.0)",
org.eclipse.jgit.errors;version="[0.9.0,0.10.0)",
org.eclipse.jgit.lib;version="[0.9.0,0.10.0)",
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/EGitTestCase.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/EGitTestCase.java
index 56ba1eb..809d579 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/EGitTestCase.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/EGitTestCase.java
@@ -10,12 +10,19 @@
*******************************************************************************/
package org.eclipse.egit.ui.common;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.egit.ui.test.Eclipse;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
import org.junit.After;
import org.junit.BeforeClass;
+import org.junit.runner.RunWith;
+@RunWith(SWTBotJunit4ClassRunner.class)
public abstract class EGitTestCase {
static {
@@ -38,4 +45,33 @@ public abstract class EGitTestCase {
new Eclipse().reset();
}
+ protected static void waitForWorkspaceRefresh() {
+ WorkspaceRefreshHook wrh = new WorkspaceRefreshHook();
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(wrh);
+
+ try {
+ bot.waitUntil(wrh, 120000);
+ } finally {
+ ResourcesPlugin.getWorkspace().removeResourceChangeListener(wrh);
+ }
+ }
+
+ private static class WorkspaceRefreshHook extends DefaultCondition
+ implements IResourceChangeListener {
+ private boolean state = false;
+
+ public void resourceChanged(IResourceChangeEvent event) {
+ if (event.getType() == IResourceChangeEvent.POST_CHANGE)
+ state = true;
+ }
+
+ public String getFailureMessage() {
+ return "Failed waiting for workspace refresh.";
+ }
+
+ public boolean test() throws Exception {
+ return state;
+ }
+ }
+
}
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/GitImportRepoWizard.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/GitImportRepoWizard.java
index 0a0da09..8e551ce 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/GitImportRepoWizard.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/GitImportRepoWizard.java
@@ -10,7 +10,11 @@
*******************************************************************************/
package org.eclipse.egit.ui.common;
+import static org.eclipse.swtbot.swt.finder.waits.Conditions.shellCloses;
+
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable;
public class GitImportRepoWizard {
@@ -36,4 +40,49 @@ public class GitImportRepoWizard {
return new RepoPropertiesPage();
}
+ public int configuredRepoCount() {
+ bot.shell("Import Projects from Git").activate();
+
+ return bot.table(0).rowCount();
+ }
+
+ public boolean containsRepo(String projectName) {
+ SWTBotTable table = bot.table(0);
+ int repoCount = configuredRepoCount();
+
+ for (int i = 0; i < repoCount; i++) {
+ String rowName = table.getTableItem(i).getText();
+ if (rowName.contains(projectName))
+ return true;
+ }
+ return false;
+ }
+
+ public void selectAndCloneRepository(String repoName) {
+ bot.shell("Import Projects from Git").activate();
+
+ SWTBotTable table = bot.table(0);
+ for (int i = 0; i < table.rowCount(); i++) {
+ String rowName = table.getTableItem(i).getText();
+ if (rowName != null && rowName.startsWith(repoName)) {
+ table.select(i);
+ break;
+ }
+ }
+
+ bot.button("Next >").click();
+
+ bot.button("Next >").click();
+
+ bot.button("Select All").click();
+ }
+
+ public void waitForCreate() {
+ bot.button("Finish").click();
+
+ SWTBotShell shell = bot.shell("Import Projects from Git");
+
+ bot.waitUntil(shellCloses(shell), 120000);
+ }
+
}
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/AllTests.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/AllTests.java
index ace9fb3..fc5de09 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/AllTests.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/AllTests.java
@@ -1,4 +1,4 @@
-/*******************************************************************************
+/*******************************************************************************
* Copyright (C) 2010, Ketan Padegaonkar <KetanPadegaonkar@gmail.com>
*
* All rights reserved. This program and the accompanying materials
@@ -10,6 +10,7 @@ package org.eclipse.egit.ui.test;
import org.eclipse.egit.ui.prefpages.configuration.GlobalConfigurationPageTest;
import org.eclipse.egit.ui.view.repositories.AllRepositoriesViewTests;
+import org.eclipse.egit.ui.view.synchronize.SynchronizeViewTest;
import org.eclipse.egit.ui.wizards.clone.GitCloneWizardTest;
import org.eclipse.egit.ui.wizards.share.SharingWizardTest;
import org.junit.runner.RunWith;
@@ -17,8 +18,11 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
-@SuiteClasses( { GitCloneWizardTest.class, GlobalConfigurationPageTest.class,
- SharingWizardTest.class, AllRepositoriesViewTests.class })
+@SuiteClasses( { AllRepositoriesViewTests.class, //
+ GitCloneWizardTest.class, //
+ GlobalConfigurationPageTest.class, //
+ SharingWizardTest.class, //
+ SynchronizeViewTest.class })
public class AllTests {
// empty class, don't need anything here
}
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTest.java
index 1327f8e..d50736e 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTest.java
@@ -1,4 +1,4 @@
-/*******************************************************************************
+/*******************************************************************************
* Copyright (c) 2010 SAP AG.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -508,4 +508,5 @@ public class GitRepositoriesViewTest extends GitRepositoriesViewTestBase {
perspective.activate();
}
}
-} \ No newline at end of file
+}
+
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/synchronize/SynchronizeViewTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/synchronize/SynchronizeViewTest.java
new file mode 100644
index 0000000..3118417
--- /dev/null
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/synchronize/SynchronizeViewTest.java
@@ -0,0 +1,331 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * 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.view.synchronize;
+
+import static org.eclipse.swtbot.swt.finder.waits.Conditions.shellCloses;
+import static org.eclipse.swtbot.swt.finder.waits.Conditions.shellIsActive;
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceDescription;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.egit.ui.common.EGitTestCase;
+import org.eclipse.egit.ui.common.GitImportRepoWizard;
+import org.eclipse.egit.ui.common.RepoPropertiesPage;
+import org.eclipse.egit.ui.common.RepoRemoteBranchesPage;
+import org.eclipse.egit.ui.test.ContextMenuHelper;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotEditor;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class SynchronizeViewTest extends EGitTestCase {
+
+ private static boolean changePerspective = false;
+
+ // this test fails when is run inside eclipse with Maven POM editor
+ @Test
+ public void shouldReturnNoChanges() throws Exception {
+ // when
+ changeFilesInProject();
+ showSynchronizationDialog("org.eclipse.egit.ui");
+
+ // given
+ bot.shell("Synchronize repository: egit" + File.separator + ".git")
+ .activate();
+
+ bot.comboBox(0).setSelection("local .git");
+ bot.comboBox(1).setSelection("HEAD");
+
+ bot.comboBox(2).setSelection("local .git");
+ bot.comboBox(3).setSelection("master");
+
+ // do not check 'Include local changes'
+
+ // fire action
+ bot.button("OK").click();
+
+ handleConfirmOpenPerspective();
+
+ // wait for dispose "Git Resource Synchronization"
+ bot.waitUntil(shellIsActive("Git Resource Synchronization"), 15000);
+ SWTBotShell gitResSyncShell = bot.shell("Git Resource Synchronization");
+ bot.waitUntil(shellCloses(gitResSyncShell), 300000);
+
+ // then
+ SWTBotTree syncViewTree = bot.viewByTitle("Synchronize").bot().tree();
+ assertEquals(0, syncViewTree.getAllItems().length);
+ }
+
+ // this test fails when is run inside eclipse with Maven POM editor
+ @Test
+ public void shouldReturnListOfChanges() throws Exception {
+ // when
+ changeFilesInProject();
+ showSynchronizationDialog("org.eclipse.egit.ui");
+
+ // given
+ bot.shell("Synchronize repository: egit" + File.separator + ".git")
+ .activate();
+
+ bot.comboBox(0).setSelection("local .git");
+ bot.comboBox(1).setSelection("HEAD");
+
+ bot.comboBox(2).setSelection("local .git");
+ bot.comboBox(3).setSelection("master");
+
+ // include local changes
+ bot.checkBox("Include local uncommited changes in comparison").click();
+
+ // fire action
+ bot.button("OK").click();
+
+ handleConfirmOpenPerspective();
+
+ // wait for dispose "Git Resource Synchronization"
+ bot.waitUntil(shellIsActive("Git Resource Synchronization"), 15000);
+ SWTBotShell shell = bot.shell("Git Resource Synchronization");
+ bot.waitUntil(shellCloses(shell), 300000);
+
+ // then
+ SWTBotTree syncViewTree = bot.viewByTitle("Synchronize").bot().tree();
+ assertEquals(2, syncViewTree.getAllItems().length);
+
+ SWTBotTreeItem[] syncItems = syncViewTree.getAllItems();
+ assertEquals("org.eclipse.egit.core", syncItems[0].getText());
+ assertEquals("org.eclipse.egit.ui", syncItems[1].getText());
+
+ syncItems[0].expand();
+ syncItems[1].expand();
+
+ assertEquals(1, syncItems[0].getNodes().size());
+ assertEquals("pom.xml", syncItems[0].getNodes().get(0));
+ assertEquals(1, syncItems[1].getNodes().size());
+ assertEquals("pom.xml", syncItems[1].getNodes().get(0));
+ }
+
+ @Test
+ public void shouldCompareBranchAgainstTag() throws Exception {
+ // when
+ showSynchronizationDialog("org.eclipse.egit.ui");
+
+ // given
+ bot.shell("Synchronize repository: egit" + File.separator + ".git")
+ .activate();
+
+ bot.comboBox(0).setSelection("origin");
+ bot.comboBox(1).setSelection("stable-0.7");
+
+ bot.comboBox(2).setSelection("local .git");
+ bot.comboBox(3).setSelection("v0.8.1");
+
+ // fire action
+ bot.button("OK").click();
+
+ handleConfirmOpenPerspective();
+
+ // wait for dispose "Git Resource Synchronization"
+ bot.waitUntil(shellIsActive("Git Resource Synchronization"), 15000);
+ SWTBotShell shell = bot.shell("Git Resource Synchronization");
+ bot.waitUntil(shellCloses(shell), 300000);
+
+ // then
+ SWTBotTree syncViewTree = bot.viewByTitle("Synchronize").bot().tree();
+ assertEquals(8, syncViewTree.getAllItems().length);
+ }
+
+ @Test
+ public void shouldCompareTagAgainstTag() throws Exception {
+ // when
+ showSynchronizationDialog("org.eclipse.egit.ui");
+
+ // given
+ bot.shell("Synchronize repository: egit" + File.separator + ".git")
+ .activate();
+
+ bot.comboBox(0).setSelection("local .git");
+ bot.comboBox(1).setSelection("v0.7.0");
+
+ bot.comboBox(2).setSelection("local .git");
+ bot.comboBox(3).setSelection("v0.8.1");
+
+ // fire action
+ bot.button("OK").click();
+
+ handleConfirmOpenPerspective();
+
+ // wait for dispose "Git Resource Synchronization"
+ bot.waitUntil(shellIsActive("Git Resource Synchronization"), 15000);
+ SWTBotShell shell = bot.shell("Git Resource Synchronization");
+ bot.waitUntil(shellCloses(shell), 300000);
+
+ // then
+ SWTBotTree syncViewTree = bot.viewByTitle("Synchronize").bot().tree();
+ assertEquals(8, syncViewTree.getAllItems().length);
+ }
+
+ // this test always fails with cause:
+ // Timeout after: 5000 ms.: Could not find context menu with text:
+ // Synchronize
+ @Ignore
+ @Test
+ public void shouldLaunchSynchronizationFromGitRepositories()
+ throws Exception {
+ // when
+ bot.menu("Window").menu("Show View").menu("Other...").click();
+ bot.shell("Show View").bot().tree().expandNode("Git").getNode(
+ "Git Repositories").doubleClick();
+
+ SWTBotTree repositoriesTree = bot.viewByTitle("Git Repositories").bot()
+ .tree();
+ SWTBotTreeItem egitRoot = repositoriesTree.getAllItems()[0];
+ egitRoot.expand();
+ egitRoot.collapse();
+ egitRoot.expand();
+ SWTBotTreeItem remoteBranch = egitRoot.expandNode("Branches")
+ .expandNode("Remote Branches");
+ SWTBotTreeItem branchNode = remoteBranch.getNode("origin/stable-0.7");
+ branchNode.select();
+ branchNode.contextMenu("Synchronize").click();
+
+ handleConfirmOpenPerspective();
+
+ // wait for dispose "Git Resource Synchronization"
+ bot.waitUntil(shellIsActive("Git Resource Synchronization"), 15000);
+ SWTBotShell shell = bot.shell("Git Resource Synchronization");
+ bot.waitUntil(shellCloses(shell), 300000);
+
+ // given
+
+ // then
+ SWTBotTree syncViewTree = bot.viewByTitle("Synchronize").bot().tree();
+ assertEquals(8, syncViewTree.getAllItems().length);
+ }
+
+ @Before
+ public void setupViews() {
+ bot.perspectiveById("org.eclipse.jdt.ui.JavaPerspective").activate();
+ bot.viewByTitle("Package Explorer").show();
+ }
+
+ @BeforeClass
+ public static void setupEnvironment() throws Exception {
+ // turn off auto building
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ IWorkspaceDescription description = workspace.getDescription();
+ description.setAutoBuilding(false);
+ workspace.setDescription(description);
+
+ // obtain copy of EGit project
+ GitImportRepoWizard importWizard = new GitImportRepoWizard();
+
+ importWizard.openWizard();
+ String repoName = "egit";
+ String repoUrl = "git://egit.eclipse.org/egit.git";
+ if (!importWizard.containsRepo(repoName))
+ addRepository(importWizard, repoUrl);
+
+ importWizard.selectAndCloneRepository(repoName);
+ importWizard.waitForCreate();
+ waitForWorkspaceRefresh();
+ }
+
+ @AfterClass
+ public static void restoreEnvironmentSetup() throws Exception {
+ // turn off auto building
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ IWorkspaceDescription description = workspace.getDescription();
+ description.setAutoBuilding(true);
+ workspace.setDescription(description);
+ }
+
+ private static void addRepository(GitImportRepoWizard importWizard,
+ String repoUrl) {
+ RepoPropertiesPage propertiesPage = importWizard.openCloneWizard();
+
+ RepoRemoteBranchesPage remoteBranches = propertiesPage
+ .nextToRemoteBranches(repoUrl);
+ remoteBranches.selectBranches("master");
+
+ remoteBranches.nextToWorkingCopy().waitForCreate();
+ }
+
+ private void changeFilesInProject() throws Exception {
+ SWTBot packageExplorerBot = bot.viewByTitle("Package Explorer").bot();
+ packageExplorerBot.activeShell();
+ SWTBotTree tree = packageExplorerBot.tree();
+
+ SWTBotTreeItem coreTreeItem = tree.getAllItems()[3];
+ coreTreeItem.expand();
+ for (String node : coreTreeItem.getNodes()) {
+ if (node.contains("pom.xml")) {
+ coreTreeItem.getNode(node).doubleClick();
+ break;
+ }
+ }
+
+ SWTBotEditor corePomEditor = bot.editorByTitle("pom.xml");
+ corePomEditor.toTextEditor()
+ .insertText("<!-- EGit jUnit test case -->");
+ corePomEditor.saveAndClose();
+ coreTreeItem.collapse();
+
+ SWTBotTreeItem uiTreeItem = tree.getAllItems()[6];
+ uiTreeItem.expand();
+ for (String node : uiTreeItem.getNodes()) {
+ if (node.contains("pom.xml")) {
+ uiTreeItem.getNode(node).doubleClick();
+ break;
+ }
+ }
+
+ SWTBotEditor uiPomEditor = bot.editorByTitle("pom.xml");
+ uiPomEditor.toTextEditor().insertText("<!-- EGit jUnit test case -->");
+ uiPomEditor.saveAndClose();
+ uiTreeItem.collapse();
+ }
+
+ private void showSynchronizationDialog(String projectName) {
+ SWTBot packageExplorerBot = bot.viewByTitle("Package Explorer").bot();
+ packageExplorerBot.activeShell();
+ SWTBotTree tree = packageExplorerBot.tree();
+
+ // EGit decorates the project node shown in the package explorer. The
+ // '>' decorator indicates that there are uncommitted changes present in
+ // the project. Also the repository and branch name are added as a
+ // suffix ('[<repo name> <branch name>]' suffix). To bypass this
+ // decoration we use here this loop.
+ for (SWTBotTreeItem item : tree.getAllItems()) {
+ if (item.getText().contains(projectName)) {
+ item.select();
+ break;
+ }
+ }
+
+ ContextMenuHelper.clickContextMenu(tree, "Team", "Synchronize...");
+ }
+
+ private void handleConfirmOpenPerspective() {
+ if (!changePerspective) {
+ changePerspective = true;
+ bot.waitUntil(shellIsActive("Confirm Open Perspective"), 15000);
+ bot.checkBox("Remember my decision").click();
+ bot.button("No").click();
+ }
+ }
+
+}
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/wizards/clone/GitCloneWizardTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/wizards/clone/GitCloneWizardTest.java
index 603fdc2..272ce2a 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/wizards/clone/GitCloneWizardTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/wizards/clone/GitCloneWizardTest.java
@@ -25,13 +25,10 @@ import org.eclipse.egit.ui.common.RepoPropertiesPage;
import org.eclipse.egit.ui.common.RepoRemoteBranchesPage;
import org.eclipse.egit.ui.common.WorkingCopyPage;
import org.eclipse.jgit.lib.Repository;
-import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
-import org.junit.runner.RunWith;
-@RunWith(SWTBotJunit4ClassRunner.class)
public class GitCloneWizardTest extends EGitTestCase {
private GitImportRepoWizard importWizard;