org.eclipse.egit.core.synchronize.GitSubscriberResourceMappingContextTest.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.egit.core.synchronize.GitSubscriberResourceMappingContextTest.java

Source

/*******************************************************************************
 * Copyright (C) 2013, Laurent Goubet <laurent.goubet@obeo.fr> and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/
package org.eclipse.egit.core.synchronize;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.UnsupportedEncodingException;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.mapping.RemoteResourceMappingContext;
import org.eclipse.core.resources.mapping.ResourceTraversal;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
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.TestRepository;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.junit.JGitTestUtil;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Before;
import org.junit.Test;

public class GitSubscriberResourceMappingContextTest extends GitTestCase {

    private static final String MASTER = Constants.R_HEADS + Constants.MASTER;

    private static final String BRANCH = Constants.R_HEADS + "branch";

    private Repository repo;

    private IProject iProject;

    private TestRepository testRepo;

    @Override
    @Before
    public void setUp() throws Exception {
        super.setUp();

        iProject = project.project;
        testRepo = new TestRepository(gitDir);
        testRepo.connect(iProject);
        repo = RepositoryMapping.getMapping(iProject).getRepository();

        // make initial commit
        new Git(repo).commit().setAuthor("JUnit", "junit@jgit.org").setMessage("Initial commit").call();
    }

    @Test
    public void hasLocalChange() throws Exception {
        File file1 = testRepo.createFile(iProject, "a.txt");
        File file2 = testRepo.createFile(iProject, "b.txt");
        testRepo.appendContentAndCommit(iProject, file1, "content a", "commit a");
        testRepo.appendContentAndCommit(iProject, file2, "content b", "commit b");

        IFile iFile1 = testRepo.getIFile(iProject, file1);
        IFile iFile2 = testRepo.getIFile(iProject, file2);

        RemoteResourceMappingContext context = prepareContext(MASTER, MASTER);
        assertFalse(context.hasLocalChange(iFile1, new NullProgressMonitor()));
        assertFalse(context.hasLocalChange(iFile2, new NullProgressMonitor()));

        JGitTestUtil.write(file1, "changed content a");
        JGitTestUtil.write(file2, "changed content b");

        refresh(context, iFile1, iFile2);
        assertTrue(context.hasLocalChange(iFile1, new NullProgressMonitor()));
        assertTrue(context.hasLocalChange(iFile2, new NullProgressMonitor()));

        JGitTestUtil.write(file2, "content b");

        refresh(context, iFile2);
        assertTrue(context.hasLocalChange(iFile1, new NullProgressMonitor()));
        assertFalse(context.hasLocalChange(iFile2, new NullProgressMonitor()));
    }

    @Test
    public void hasLocalChangeWithFileRemoval() throws Exception {
        File file1 = testRepo.createFile(iProject, "a.txt");
        File file2 = testRepo.createFile(iProject, "b.txt");
        File file3 = testRepo.createFile(iProject, "c.txt");

        IFile iFile1 = testRepo.getIFile(iProject, file1);
        IFile iFile2 = testRepo.getIFile(iProject, file2);
        IFile iFile3 = testRepo.getIFile(iProject, file3);

        RemoteResourceMappingContext context = prepareContext(MASTER, MASTER);
        assertTrue(context.hasLocalChange(iFile1, new NullProgressMonitor()));
        assertTrue(context.hasLocalChange(iFile2, new NullProgressMonitor()));
        assertTrue(context.hasLocalChange(iFile3, new NullProgressMonitor()));

        iFile1.delete(false, null);
        refresh(context, iFile1, iFile2, iFile3);
        assertTrue(context.hasLocalChange(iFile2, new NullProgressMonitor()));
        assertTrue(context.hasLocalChange(iFile3, new NullProgressMonitor()));
    }

    @Test
    public void hasLocalChangeInNewFolder() throws Exception {
        iProject.getFolder("folder").create(false, true, null);
        RemoteResourceMappingContext context = prepareContext(MASTER, MASTER);
        // Folder is now known, but not yet file in it

        File file = testRepo.createFile(iProject, "folder/b.txt");
        IFile iFile = testRepo.getIFile(iProject, file);
        refresh(context, iFile);
        assertTrue(context.hasLocalChange(iFile, new NullProgressMonitor()));

        testRepo.addToIndex(iProject, file);
        refresh(context, iFile);
        assertTrue(context.hasLocalChange(iFile, new NullProgressMonitor()));

        JGitTestUtil.write(file, "changed content b");
        refresh(context, iFile);
        assertTrue(context.hasLocalChange(iFile, new NullProgressMonitor()));
    }

    @Test
    public void hasRemoteChanges() throws Exception {
        File file1 = testRepo.createFile(iProject, "file1.sample");
        File file2 = testRepo.createFile(iProject, "file2.sample");

        testRepo.appendContentAndCommit(iProject, file1, "initial content - file 1",
                "first file - initial commit MASTER");
        testRepo.appendContentAndCommit(iProject, file2, "initial content - file 2",
                "second file - initial commit MASTER");

        IFile iFile1 = testRepo.getIFile(iProject, file1);
        IFile iFile2 = testRepo.getIFile(iProject, file2);

        testRepo.createAndCheckoutBranch(MASTER, BRANCH);

        setContentsAndCommit(iFile1, "change in branch - file 1", "branch commit - file1");
        setContentsAndCommit(iFile2, "change in branch - file 2", "branch commit - file2");

        testRepo.checkoutBranch(MASTER);

        RemoteResourceMappingContext context = prepareContext(MASTER, BRANCH);
        assertFalse(context.hasLocalChange(iFile1, new NullProgressMonitor()));
        assertTrue(context.hasRemoteChange(iFile1, new NullProgressMonitor()));
        assertFalse(context.hasLocalChange(iFile2, new NullProgressMonitor()));
        assertTrue(context.hasRemoteChange(iFile2, new NullProgressMonitor()));

        setContents(iFile1, "change in master - file 1");
        refresh(context, iFile1);
        assertTrue(context.hasLocalChange(iFile1, new NullProgressMonitor()));
        assertTrue(context.hasRemoteChange(iFile1, new NullProgressMonitor()));

        setContents(iFile2, "change in branch - file 2");
        refresh(context, iFile2);
        assertTrue(context.hasLocalChange(iFile2, new NullProgressMonitor()));
        assertTrue(context.hasRemoteChange(iFile2, new NullProgressMonitor()));

        setContentsAndCommit(iFile1, "change in branch - file 1", "change in master (same as in branch) - file 2");
        refresh(context, iFile1);
        assertTrue(context.hasLocalChange(iFile1, new NullProgressMonitor()));
        assertTrue(context.hasRemoteChange(iFile1, new NullProgressMonitor()));
    }

    @Test
    public void hasRemoteChangeInNewFile() throws Exception {
        File file1 = testRepo.createFile(iProject, "file1.sample");
        String initialContent1 = "some content for the first file";
        testRepo.appendContentAndCommit(iProject, file1, initialContent1, "first file - initial commit");
        IFile iFile1 = testRepo.getIFile(iProject, file1);

        testRepo.createAndCheckoutBranch(MASTER, BRANCH);

        File file2 = testRepo.createFile(iProject, "file2.sample");
        String initialContent2 = "some content for the second file";
        testRepo.appendContentAndCommit(iProject, file2, initialContent2, "second file - initial commit");
        IFile iFile2 = testRepo.getIFile(iProject, file2);

        testRepo.checkoutBranch(MASTER);

        RemoteResourceMappingContext context = prepareContext(MASTER, BRANCH);
        assertFalse(context.hasRemoteChange(iFile1, new NullProgressMonitor()));
        assertTrue(context.hasRemoteChange(iFile2, new NullProgressMonitor()));
    }

    @Test
    public void hasRemoteChangeInNewFolder() throws Exception {
        File file1 = testRepo.createFile(iProject, "file1.sample");
        String initialContent1 = "some content for the first file";
        testRepo.appendContentAndCommit(iProject, file1, initialContent1, "first file - initial commit");
        IFile iFile1 = testRepo.getIFile(iProject, file1);

        testRepo.createAndCheckoutBranch(MASTER, BRANCH);

        iProject.getFolder("folder").create(true, true, new NullProgressMonitor());
        File file2 = testRepo.createFile(iProject, "folder/file2.sample");
        String initialContent2 = "some content for the second file";
        testRepo.appendContentAndCommit(iProject, file2, initialContent2, "second file - initial commit");
        IFile iFile2 = testRepo.getIFile(iProject, file2);

        testRepo.checkoutBranch(MASTER);

        RemoteResourceMappingContext context = prepareContext(MASTER, BRANCH);
        assertFalse(context.hasRemoteChange(iFile1, new NullProgressMonitor()));
        assertTrue(context.hasRemoteChange(iFile2, new NullProgressMonitor()));
    }

    @Test
    public void hasLocalAndRemoteChange() throws Exception {
        File file1 = testRepo.createFile(iProject, "file1.sample");
        testRepo.appendContentAndCommit(iProject, file1, "initial content", "first commit in master");
        IFile iFile1 = testRepo.getIFile(iProject, file1);

        testRepo.createAndCheckoutBranch(MASTER, BRANCH);
        setContentsAndCommit(iFile1, "changed content in branch", "first commit in BRANCH");

        testRepo.checkoutBranch(MASTER);
        setContentsAndCommit(iFile1, "changed content in master", "second commit in MASTER");

        RemoteResourceMappingContext context = prepareContext(MASTER, BRANCH);
        assertTrue(context.hasRemoteChange(iFile1, new NullProgressMonitor()));
        assertTrue(context.hasLocalChange(iFile1, new NullProgressMonitor()));
    }

    @Test
    public void hasLocalAndRemoteChangeInSubFolder() throws Exception {
        File file1 = testRepo.createFile(iProject, "folder/file1.sample");
        testRepo.appendContentAndCommit(iProject, file1, "initial content", "first commit in master");
        IFile iFile1 = testRepo.getIFile(iProject, file1);

        testRepo.createAndCheckoutBranch(MASTER, BRANCH);
        setContentsAndCommit(iFile1, "changed content in branch", "first commit in BRANCH");

        testRepo.checkoutBranch(MASTER);
        setContentsAndCommit(iFile1, "changed content in master", "second commit in MASTER");

        RemoteResourceMappingContext context = prepareContext(MASTER, BRANCH);
        assertTrue(context.hasRemoteChange(iFile1, new NullProgressMonitor()));
        assertTrue(context.hasLocalChange(iFile1, new NullProgressMonitor()));
    }

    @Test
    public void hasLocalChangeWhenRefreshingParentFolder() throws Exception {
        IFolder folder = iProject.getFolder("newfolder");
        folder.create(false, true, null);

        IFile file = folder.getFile("a.txt");
        file.create(new ByteArrayInputStream("a".getBytes("UTF-8")), false, null);

        RemoteResourceMappingContext context = prepareContext(MASTER, MASTER);
        refresh(context, file);

        assertTrue(context.hasLocalChange(file, new NullProgressMonitor()));

        file.delete(false, null);

        // Refresh of folder, not file directly
        refresh(context, folder);

        assertFalse(context.hasLocalChange(file, new NullProgressMonitor()));
    }

    private RevCommit setContentsAndCommit(IFile targetFile, String newContents, String commitMessage)
            throws Exception {
        setContents(targetFile, newContents);
        return addAndCommit(targetFile, commitMessage);
    }

    private RevCommit addAndCommit(IFile targetFile, String commitMessage) throws Exception {
        testRepo.addToIndex(targetFile);
        return testRepo.commit(commitMessage);
    }

    private void setContents(IFile targetFile, String newContents)
            throws CoreException, UnsupportedEncodingException {
        targetFile.setContents(new ByteArrayInputStream(newContents.getBytes("UTF-8")), IResource.FORCE,
                new NullProgressMonitor());
    }

    private RemoteResourceMappingContext prepareContext(String srcRev, String dstRev) throws Exception {
        GitSynchronizeData gsd = new GitSynchronizeData(repo, srcRev, dstRev, true);
        GitSynchronizeDataSet gsds = new GitSynchronizeDataSet(gsd);
        GitResourceVariantTreeSubscriber subscriber = new GitResourceVariantTreeSubscriber(gsds);
        subscriber.init(new NullProgressMonitor());

        return new GitSubscriberResourceMappingContext(subscriber, gsds);
    }

    private void refresh(RemoteResourceMappingContext context, IResource... resources) throws Exception {
        context.refresh(new ResourceTraversal[] { new ResourceTraversal(resources, IResource.DEPTH_INFINITE, 0) },
                0, new NullProgressMonitor());
    }
}