package org.eclipse.recommenders.internal.types.rcp;
import static com.google.common.base.Optional.of;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;
import java.util.Set;
import org.eclipse.jdt.core.ElementChangedEvent;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaElementDelta;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.recommenders.utils.names.ITypeName;
import org.eclipse.recommenders.utils.names.VmTypeName;
import org.hamcrest.Matchers;
import org.junit.Test;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableSet;
public class TypesIndexServiceTest {
private static final Optional<IProjectTypesIndex> NO_INDEX = Optional.<IProjectTypesIndex>absent();
private static final ITypeName JAVA_UTIL_LIST = VmTypeName.get("Ljava/util/List");
private static final String JAVA_UTIL_LIST_NAME = "List";
private static final int ELEMENT_DELTA_KIND_UNSET = 0;
private static final int ELEMENT_DELTA_FLAGS_UNSET = 0;
@Test
public void testSubtypesOfUnseenProject() {
IIndexProvider provider = mock(IIndexProvider.class);
IJavaProject project = mock(IJavaProject.class);
mockProspectiveIndex(project, provider);
TypesIndexService sut = new TypesIndexService(provider);
Set<String> subtypes = sut.subtypes(JAVA_UTIL_LIST, project);
assertThat(subtypes.isEmpty(), is(true));
}
@Test
public void testSubtypesOfSeenProject() {
IIndexProvider provider = mock(IIndexProvider.class);
IJavaProject project = mock(IJavaProject.class);
mockExistingIndex(project, provider, JAVA_UTIL_LIST_NAME);
TypesIndexService sut = new TypesIndexService(provider);
Set<String> subtypes = sut.subtypes(JAVA_UTIL_LIST, project);
assertThat(subtypes, Matchers.contains(JAVA_UTIL_LIST_NAME));
assertThat(subtypes.size(), is(1));
}
@Test
public void testEventForNewProject() {
IJavaProject newJavaProject = mockProject();
IJavaElement element = mockElement(newJavaProject);
IJavaElementDelta newProjectDelta = mockElementDelta(newJavaProject, IJavaElementDelta.ADDED,
ELEMENT_DELTA_FLAGS_UNSET);
IJavaElementDelta javaModelDelta = mockElementDelta(element, ELEMENT_DELTA_KIND_UNSET,
IJavaElementDelta.F_CHILDREN, newProjectDelta);
ElementChangedEvent projectAddedEvent = mockElementChangedEvent(javaModelDelta);
IIndexProvider provider = mock(IIndexProvider.class);
IProjectTypesIndex index = mockProspectiveIndex(newJavaProject, provider);
TypesIndexService sut = new TypesIndexService(provider);
sut.elementChanged(projectAddedEvent);
verifyZeroInteractions(index);
}
@Test
public void testEventForClasspathChangeOfUnseenProject() {
IJavaProject project = mockProject();
IJavaElementDelta changedProjectDelta = mockElementDelta(project, IJavaElementDelta.CHANGED,
IJavaElementDelta.F_RESOLVED_CLASSPATH_CHANGED);
ElementChangedEvent projectChangedEvent = mockElementChangedEvent(changedProjectDelta);
IIndexProvider provider = mock(IIndexProvider.class);
IProjectTypesIndex index = mockProspectiveIndex(project, provider);
TypesIndexService sut = new TypesIndexService(provider);
sut.elementChanged(projectChangedEvent);
verifyZeroInteractions(index);
}
@Test
public void testEventForClasspathChangeOfSeenProject() {
IJavaProject project = mockProject();
IJavaElementDelta changedProjectDelta = mockElementDelta(project, IJavaElementDelta.CHANGED,
IJavaElementDelta.F_RESOLVED_CLASSPATH_CHANGED);
ElementChangedEvent projectChangedEvent = mockElementChangedEvent(changedProjectDelta);
IIndexProvider provider = mock(IIndexProvider.class);
IProjectTypesIndex index = mockExistingIndex(project, provider);
TypesIndexService sut = new TypesIndexService(provider);
sut.elementChanged(projectChangedEvent);
verify(index).suggestRebuild();
}
@Test
public void testEventForContentChangeOfPackageFragmentRootInSeenProject() {
IJavaProject project = mockProject();
IPackageFragmentRoot fragmentRoot = mockPackageFragmentRoot(project);
IJavaElementDelta changedFragmentRootDelta = mockElementDelta(fragmentRoot, IJavaElementDelta.CHANGED,
IJavaElementDelta.F_ARCHIVE_CONTENT_CHANGED);
ElementChangedEvent projectChangedEvent = mockElementChangedEvent(changedFragmentRootDelta);
IIndexProvider provider = mock(IIndexProvider.class);
IProjectTypesIndex index = mockExistingIndex(project, provider);
TypesIndexService sut = new TypesIndexService(provider);
sut.elementChanged(projectChangedEvent);
verify(index).suggestRebuild();
}
@Test
public void testEventForReorderOfPackageFragmentRootInSeenProject() {
IJavaProject project = mockProject();
IPackageFragmentRoot fragmentRoot = mockPackageFragmentRoot(project);
IJavaElementDelta changedFragmentRootDelta = mockElementDelta(fragmentRoot, IJavaElementDelta.CHANGED,
IJavaElementDelta.F_REORDER);
ElementChangedEvent projectChangedEvent = mockElementChangedEvent(changedFragmentRootDelta);
IIndexProvider provider = mock(IIndexProvider.class);
IProjectTypesIndex index = mockExistingIndex(project, provider);
TypesIndexService sut = new TypesIndexService(provider);
sut.elementChanged(projectChangedEvent);
verifyZeroInteractions(index);
}
@Test
public void testEventForChangeOfCompilationUnitInSeenProject() {
IJavaProject project = mockProject();
ICompilationUnit cu = mockCompilationUnit(project);
IJavaElementDelta changedCompilationUnitDelta = mockElementDelta(cu, IJavaElementDelta.CHANGED, 0);
ElementChangedEvent projectChangedEvent = mockElementChangedEvent(changedCompilationUnitDelta);
IIndexProvider provider = mock(IIndexProvider.class);
IProjectTypesIndex index = mockExistingIndex(project, provider);
TypesIndexService sut = new TypesIndexService(provider);
sut.elementChanged(projectChangedEvent);
verifyZeroInteractions(index);
}
@Test
public void testEventForProjectRemoved() {
IJavaProject project = mockProject();
IJavaElementDelta removedProjectDelta = mockElementDelta(project, IJavaElementDelta.REMOVED, 0);
ElementChangedEvent projectRemovedEvent = mockElementChangedEvent(removedProjectDelta);
IIndexProvider provider = mock(IIndexProvider.class);
TypesIndexService sut = new TypesIndexService(provider);
sut.elementChanged(projectRemovedEvent);
verify(provider).deleteIndex(project);
}
public IProjectTypesIndex mockProspectiveIndex(IJavaProject newJavaProject, IIndexProvider provider,
String... subtypes) {
IProjectTypesIndex index = mock(IProjectTypesIndex.class);
when(index.subtypes(any(ITypeName.class))).thenReturn(ImmutableSet.copyOf(subtypes));
when(provider.findIndex(newJavaProject)).thenReturn(NO_INDEX);
when(provider.findOrCreateIndex(newJavaProject)).thenReturn(index);
return index;
}
public IProjectTypesIndex mockExistingIndex(IJavaProject newJavaProject, IIndexProvider provider,
String... subtypes) {
IProjectTypesIndex index = mock(IProjectTypesIndex.class);
when(index.subtypes(any(ITypeName.class))).thenReturn(ImmutableSet.copyOf(subtypes));
when(provider.findIndex(newJavaProject)).thenReturn(of(index));
when(provider.findOrCreateIndex(newJavaProject)).thenReturn(index);
return index;
}
private IJavaProject mockProject() {
IJavaProject project = mock(IJavaProject.class);
when(project.getJavaProject()).thenReturn(project);
when(project.getElementType()).thenReturn(IJavaElement.JAVA_PROJECT);
return project;
}
private IJavaElement mockElement(IJavaProject project) {
IJavaElement element = mock(IJavaElement.class);
when(element.getJavaProject()).thenReturn(project);
return element;
}
private IPackageFragmentRoot mockPackageFragmentRoot(IJavaProject project) {
IPackageFragmentRoot root = mock(IPackageFragmentRoot.class);
when(root.getJavaProject()).thenReturn(project);
when(root.getElementType()).thenReturn(IJavaElement.PACKAGE_FRAGMENT_ROOT);
return root;
}
private ICompilationUnit mockCompilationUnit(IJavaProject project) {
ICompilationUnit cu = mock(ICompilationUnit.class);
when(cu.getJavaProject()).thenReturn(project);
when(cu.getElementType()).thenReturn(IJavaElement.COMPILATION_UNIT);
return cu;
}
private ElementChangedEvent mockElementChangedEvent(IJavaElementDelta javaElementDelta) {
ElementChangedEvent event = mock(ElementChangedEvent.class);
when(event.getDelta()).thenReturn(javaElementDelta);
return event;
}
private IJavaElementDelta mockElementDelta(IJavaElement element, int kind, int flags,
IJavaElementDelta... affectedChildren) {
IJavaElementDelta delta = mock(IJavaElementDelta.class);
when(delta.getFlags()).thenReturn(flags);
when(delta.getElement()).thenReturn(element);
when(delta.getKind()).thenReturn(kind);
when(delta.getAffectedChildren()).thenReturn(affectedChildren);
return delta;
}
}