/******************************************************************************* * Copyright (C) 2013, François Rey <eclipse.org_@_francois_._rey_._name> * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * François Rey - First implementation as part of handling linked resources *******************************************************************************/ package org.eclipse.egit.core.test; import static org.hamcrest.Matchers.hasItem; import static org.junit.Assert.assertThat; import java.util.Collection; import java.util.HashSet; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IResourceDeltaVisitor; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.egit.core.internal.indexdiff.GitResourceDeltaVisitor; import org.eclipse.egit.core.project.RepositoryMapping; import org.eclipse.jgit.lib.Repository; /** * Helper class for test cases that need to know what workspace changes egit * will detect. Changes to files within the git repository folder are ignored * by default, however this behavior can be changed by a constructor parameter. * Usage: create one instance per test case and call {@link #setUp()} and * {@link #tearDown()} before and after the test case. Use other functions * to test and assert what changed resources are expected. * Implementation is mainly an {@link IResourceChangeListener} which calls * a {@link GitResourceDeltaVisitor} for each change that occurs in a project * that uses egit. */ public class GitResourceDeltaTestHelper { private Repository repository; private IResourceChangeListener resourceChangeListener; private final Collection<IResource> changedResources; private final boolean ignoreTeamPrivateMember; public GitResourceDeltaTestHelper(Repository repository) { this(repository, true); } public GitResourceDeltaTestHelper(Repository repository, boolean ignoreTeamPrivateMember) { this.repository = repository; this.changedResources = new HashSet<IResource>(); this.ignoreTeamPrivateMember = ignoreTeamPrivateMember; } public void setUp() { resourceChangeListener = new IResourceChangeListener() { @Override public void resourceChanged(final IResourceChangeEvent event) { try { event.getDelta().accept(new IResourceDeltaVisitor() { @Override public boolean visit(IResourceDelta delta) throws CoreException { final IResource resource = delta.getResource(); IProject project = resource.getProject(); if (project == null) return true; RepositoryMapping mapping = RepositoryMapping .getMapping(resource); if (mapping == null) return true; if (mapping.getRepository() != repository) return false; GitResourceDeltaVisitor visitor = new GitResourceDeltaVisitor( repository); try { event.getDelta().accept(visitor); } catch (CoreException e) { String msg = "Exception during accept of GitResourceDeltaVisitor for resource delta"; throw new RuntimeException(msg, e); } IPath gitDirAbsolutePath = mapping .getGitDirAbsolutePath(); for (IResource res : visitor.getResourcesToUpdate()) { if (ignoreTeamPrivateMember && (res.isTeamPrivateMember() || gitDirAbsolutePath .isPrefixOf(res .getRawLocation() .makeAbsolute()))) continue; changedResources.add(res); } return false; } }); } catch (CoreException e) { throw new RuntimeException( "Exception during accept of test visitor for resource delta", e); } } }; ResourcesPlugin.getWorkspace().addResourceChangeListener( resourceChangeListener, IResourceChangeEvent.POST_CHANGE); } public void tearDown() { if (resourceChangeListener != null) { ResourcesPlugin.getWorkspace().removeResourceChangeListener( resourceChangeListener); resourceChangeListener = null; } } public Collection<IResource> getChangedResources() { return changedResources; } public boolean noChangedResources() { return changedResources.isEmpty(); } public boolean anyChangedResources() { return !changedResources.isEmpty(); } public void assertChangedResources(String[] expected) { IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); for (String file : expected) assertThat(changedResources, hasItem(root.findMember(file))); } }