Package org.eclipse.egit.core.test

Source Code of org.eclipse.egit.core.test.ContainerTreeIteratorResourceFilterTest$Entry

/*******************************************************************************
* Copyright (C) 2012, Robin Stocker <robin@nibor.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.test;

import static org.eclipse.core.resources.IResourceFilterDescription.EXCLUDE_ALL;
import static org.eclipse.core.resources.IResourceFilterDescription.FILES;
import static org.eclipse.core.resources.IResourceFilterDescription.FOLDERS;
import static org.eclipse.core.resources.IResourceFilterDescription.INHERITABLE;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.FileInfoMatcherDescription;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;
import org.eclipse.egit.core.AdaptableFileTreeIterator;
import org.eclipse.egit.core.ContainerTreeIterator;
import org.eclipse.egit.core.op.ConnectProviderOperation;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.jgit.treewalk.AbstractTreeIterator;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.junit.Before;
import org.junit.Test;

/**
* Test for how {@link ContainerTreeIterator} handles filtered resources.
* <p>
* The tricky thing is that they are not returned from API like
* {@link IContainer#members()}. So we have to fall back to using an
* {@link AdaptableFileTreeIterator} if there may be resource filters active.
* <p>
* In case of nested projects where the subproject is filtered in the parent
* project with resource filters, we want the nested project to be walked with
* {@link ContainerTreeIterator} again. That is, it should "recover" from
* falling back to {@link AdaptableFileTreeIterator}.
*/
public class ContainerTreeIteratorResourceFilterTest extends GitTestCase {

  private Repository repository;

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

    repository = FileRepositoryBuilder.create(gitDir);
    repository.create();

    connectProject(project.getProject());
  }

  @Test
  public void simpleNonInheritableFilter() throws Exception {
    IProject p = project.getProject();
    IFile filtered = testUtils.addFileToProject(p, "filtered.txt", "");
    IFile unfiltered = testUtils.addFileToProject(p, "unfiltered.txt", "");
    assertTrue("IFile should exist before filtering.", filtered.exists());
    assertTrue("IFile should exist before filtering.", unfiltered.exists());

    createFilter(p, EXCLUDE_ALL | FILES, "filtered.txt");
    assertFalse("IFile should no longer exist after filtering.", filtered.exists());
    assertTrue("IFile should exist after filtering.", unfiltered.exists());

    List<Entry> entries = walkTree();

    assertThat(entries, hasItem(containerTreeEntry("Project-1/filtered.txt")));
    assertThat(entries, hasItem(containerTreeEntry("Project-1/unfiltered.txt")));
  }

  @Test
  public void simpleNonInheritableFolderFilter() throws Exception {
    IProject p = project.getProject();
    IFile filtered = testUtils.addFileToProject(p, "folder/filtered.txt", "");
    IFile unfiltered = testUtils.addFileToProject(p, "folder2/unfiltered.txt", "");

    createFilter(p, EXCLUDE_ALL | FOLDERS, "folder");
    assertFalse("IFile should no longer exist after filtering.", filtered.exists());
    assertTrue("IFile should exist after filtering.", unfiltered.exists());

    List<Entry> entries = walkTree();

    assertThat(entries, hasItem(adaptableFileTreeEntry("Project-1/folder/filtered.txt")));
    assertThat(entries, hasItem(containerTreeEntry("Project-1/folder2/unfiltered.txt")));
  }

  @Test
  public void inheritableFilter() throws Exception {
    IProject p = project.getProject();
    IFile filtered1 = testUtils.addFileToProject(p, "folder1/filtered.txt", "");
    IFile filtered2 = testUtils.addFileToProject(p, "folder1/folder2/filtered.txt", "");
    IFile unfiltered = testUtils.addFileToProject(p, "folder1/folder2/unfiltered.txt", "");

    createFilter(p, EXCLUDE_ALL | FILES | INHERITABLE, "filtered.txt");
    assertFalse("IFile should no longer exist after filtering.", filtered1.exists());
    assertFalse("IFile should no longer exist after filtering.", filtered2.exists());
    assertTrue("IFile should exist after filtering.", unfiltered.exists());

    List<Entry> entries = walkTree();

    assertThat(entries, hasItem(containerTreeEntry("Project-1/folder1/filtered.txt")));
    assertThat(entries, hasItem(containerTreeEntry("Project-1/folder1/folder2/filtered.txt")));
    assertThat(entries, hasItem(containerTreeEntry("Project-1/folder1/folder2/unfiltered.txt")));
  }

  @Test
  public void directlyNestedProject() throws Exception {
    IProject p = project.getProject();
    testUtils.addFileToProject(p, "file.txt", "");

    TestProject testProject2 = new TestProject(true, "Project-1/Project-2");
    testUtils.addFileToProject(testProject2.getProject(), "project2.txt", "");

    createFilter(p, EXCLUDE_ALL | FOLDERS, "Project-2");

    List<Entry> entries = walkTree();

    assertThat(entries, hasItem(containerTreeEntry("Project-1/file.txt")));
    // Should be handled by container tree iterator because it exists, even
    // when it's not returned by members() of Project-1.
    assertThat(entries, hasItem(containerTreeEntry("Project-1/Project-2/project2.txt")));
  }

  @Test
  public void nestedProject() throws Exception {
    IProject p = project.getProject();
    testUtils.addFileToProject(p, "folder1/file.txt", "");
    testUtils.addFileToProject(p, "folder1/subfolder/filtered.txt", "");

    TestProject testProject2 = new TestProject(true, "Project-1/folder1/subfolder/Project-2");
    connectProject(testProject2.getProject());
    IFile project2File = testUtils.addFileToProject(testProject2.getProject(), "project2.txt", "");
    assertThat(project2File.getProject(), is(testProject2.getProject()));

    createFilter(p.getFolder("folder1"), EXCLUDE_ALL | FOLDERS, "subfolder");
    assertFalse("IFolder should be filtered",
        p.getFolder(new Path("folder1/subfolder")).exists());

    List<Entry> entries = walkTree();

    assertThat(entries, hasItem(containerTreeEntry("Project-1/folder1/file.txt")));
    assertThat(entries, hasItem(adaptableFileTreeEntry("Project-1/folder1/subfolder/filtered.txt")));
    // Should be handled by container tree iterator again, because the project exists.
    assertThat(entries, hasItem(containerTreeEntry("Project-1/folder1/subfolder/Project-2/project2.txt")));

    testProject2.dispose();
  }

  private static void createFilter(IContainer container, int type, String regexFilterArguments) throws CoreException {
    FileInfoMatcherDescription matcherDescription = new FileInfoMatcherDescription(
        "org.eclipse.core.resources.regexFilterMatcher",
        regexFilterArguments);
    container.createFilter(type, matcherDescription, 0, null);
  }

  private void connectProject(IProject p) throws CoreException {
    final ConnectProviderOperation operation = new ConnectProviderOperation(
        p, gitDir);
    operation.execute(null);
  }

  private List<Entry> walkTree() throws IOException {
    TreeWalk treeWalk = new TreeWalk(repository);
    ContainerTreeIterator tree = new ContainerTreeIterator(repository, project.getProject());
    int treeIndex = treeWalk.addTree(tree);
    treeWalk.setRecursive(true);
    List<Entry> entries = new ArrayList<Entry>();
    while (treeWalk.next()) {
      AbstractTreeIterator it = treeWalk.getTree(treeIndex, AbstractTreeIterator.class);
      Entry entry = new Entry(treeWalk.getPathString(), it.getClass());
      entries.add(entry);
    }
    return entries;
  }

  private static Entry containerTreeEntry(String path) {
    return new Entry(path, ContainerTreeIterator.class);
  }

  private static Entry adaptableFileTreeEntry(String path) {
    return new Entry(path, AdaptableFileTreeIterator.class);
  }

  // Value object (case class).
  private static class Entry {
    private final String path;
    private Class<? extends AbstractTreeIterator> iteratorClass;

    public Entry(String path, Class<? extends AbstractTreeIterator> iteratorClass) {
      this.path = path;
      this.iteratorClass = iteratorClass;
    }

    @Override
    public String toString() {
      return path + " (" + iteratorClass.getSimpleName() + ")";
    }

    @Override
    public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result
          + ((iteratorClass == null) ? 0 : iteratorClass.hashCode());
      result = prime * result + ((path == null) ? 0 : path.hashCode());
      return result;
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj)
        return true;
      if (obj == null)
        return false;
      if (getClass() != obj.getClass())
        return false;
      Entry other = (Entry) obj;
      if (iteratorClass == null) {
        if (other.iteratorClass != null)
          return false;
      } else if (!iteratorClass.equals(other.iteratorClass))
        return false;
      if (path == null) {
        if (other.path != null)
          return false;
      } else if (!path.equals(other.path))
        return false;
      return true;
    }
  }
}
TOP

Related Classes of org.eclipse.egit.core.test.ContainerTreeIteratorResourceFilterTest$Entry

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.