/** * Copyright (c) 2015 Codetrails GmbH. * 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: * Andreas Sewe - initial API and implementation. */ package org.eclipse.recommenders.internal.types.rcp; import static org.eclipse.recommenders.internal.types.rcp.TypesCompletionSessionProcessor.BOOST; import static org.eclipse.recommenders.testing.rcp.completion.SimpleProposalProcessorMatcher.processorWithBoost; import static org.eclipse.recommenders.utils.names.VmTypeName.INT; import static org.hamcrest.Matchers.*; import static org.junit.Assert.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Matchers.isA; import static org.mockito.Mockito.*; import java.util.Set; import org.eclipse.jdt.core.CompletionProposal; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.recommenders.completion.rcp.IRecommendersCompletionContext; import org.eclipse.recommenders.completion.rcp.processable.IProcessableProposal; import org.eclipse.recommenders.completion.rcp.processable.OverlayImageProposalProcessor; import org.eclipse.recommenders.completion.rcp.processable.ProcessableJavaCompletionProposal; import org.eclipse.recommenders.completion.rcp.processable.ProposalProcessorManager; import org.eclipse.recommenders.completion.rcp.processable.ProposalTag; import org.eclipse.recommenders.rcp.SharedImages; import org.eclipse.recommenders.utils.names.ITypeName; import org.eclipse.recommenders.utils.names.VmTypeName; import org.junit.Test; import com.google.common.base.Optional; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSetMultimap; import com.google.common.collect.SetMultimap; public class TypesCompletionSessionProcessorTest { private static final ITypeName COLLECTION = VmTypeName.get("Ljava/util/Collection"); private static final ITypeName LIST_ARRAY = VmTypeName.get("[Ljava/util/List"); private static final ITypeName LIST = VmTypeName.get("Ljava/util/List"); private static final ITypeName SET = VmTypeName.get("Ljava/util/Set"); private static final String ARRAY_LIST_SIGNATURE = "Ljava.util.ArrayList;"; private static final String LINKED_LIST_SIGNATURE = "Ljava.util.LinkedList;"; private static final String ABSTRACT_SET_SIGNATURE = "Ljava.util.AbstractSet;"; @Test public void testNoExpectedTypes() { ITypesIndexService service = mockTypesIndexServer(ImmutableSetMultimap.<ITypeName, String>of()); IRecommendersCompletionContext context = mockCompletionContextWithExpectedTypeNames(); TypesCompletionSessionProcessor sut = new TypesCompletionSessionProcessor(service, new SharedImages()); boolean shouldProcess = sut.startSession(context); assertThat(shouldProcess, is(equalTo(false))); // Should not run expensive searches verifyZeroInteractions(service); } @Test public void testPrimitiveTypeExpected() { ITypesIndexService service = mockTypesIndexServer(ImmutableSetMultimap.<ITypeName, String>of()); IRecommendersCompletionContext context = mockCompletionContextWithExpectedTypeNames(INT); TypesCompletionSessionProcessor sut = new TypesCompletionSessionProcessor(service, new SharedImages()); boolean shouldProcess = sut.startSession(context); assertThat(shouldProcess, is(equalTo(false))); // Should not run expensive searches verifyZeroInteractions(service); } @Test public void testArrayTypeExpected() { ITypesIndexService service = mockTypesIndexServer(ImmutableSetMultimap.of(LIST, "java.util.ArrayList")); IRecommendersCompletionContext context = mockCompletionContextWithExpectedTypeNames(LIST_ARRAY); TypesCompletionSessionProcessor sut = new TypesCompletionSessionProcessor(service, new SharedImages()); boolean shouldProcess = sut.startSession(context); assertThat(shouldProcess, is(equalTo(false))); // Should not run expensive searches verifyZeroInteractions(service); } @Test public void testNoSubtypesKnown() throws Exception { ITypesIndexService service = mockTypesIndexServer(ImmutableSetMultimap.<ITypeName, String>of()); IRecommendersCompletionContext context = mockCompletionContextWithExpectedTypeNames(LIST); TypesCompletionSessionProcessor sut = new TypesCompletionSessionProcessor(service, new SharedImages()); boolean shouldProcess = sut.startSession(context); assertThat(shouldProcess, is(equalTo(false))); } @Test public void testSingleTypeRefProposal() throws Exception { ITypesIndexService service = mockTypesIndexServer(ImmutableSetMultimap.of(LIST, "java.util.ArrayList")); IRecommendersCompletionContext context = mockCompletionContextWithExpectedTypeNames(LIST); TypesCompletionSessionProcessor sut = new TypesCompletionSessionProcessor(service, new SharedImages()); boolean shouldProcess = sut.startSession(context); assertThat(shouldProcess, is(equalTo(true))); IProcessableProposal arrayListProcessableProposal = mockProcessableProposal(CompletionProposal.TYPE_REF, ARRAY_LIST_SIGNATURE); sut.process(arrayListProcessableProposal); verifyWasBoosted(arrayListProcessableProposal); } @Test public void testMultipleTypeRefProposals() throws Exception { ITypesIndexService service = mockTypesIndexServer( ImmutableSetMultimap.of(LIST, "java.util.ArrayList", LIST, "java.util.LinkedList")); IRecommendersCompletionContext context = mockCompletionContextWithExpectedTypeNames(LIST, LIST_ARRAY, INT); TypesCompletionSessionProcessor sut = new TypesCompletionSessionProcessor(service, new SharedImages()); boolean shouldProcess = sut.startSession(context); assertThat(shouldProcess, is(equalTo(true))); IProcessableProposal arrayListProcessableProposal = mockProcessableProposal(CompletionProposal.TYPE_REF, ARRAY_LIST_SIGNATURE); IProcessableProposal linkedListProcessableProposal = mockProcessableProposal(CompletionProposal.TYPE_REF, LINKED_LIST_SIGNATURE); sut.process(arrayListProcessableProposal); verifyWasBoosted(arrayListProcessableProposal); sut.process(linkedListProcessableProposal); verifyWasBoosted(linkedListProcessableProposal); } @Test public void testMultipleTypeRefProposalsForDifferentTypes() throws Exception { ITypesIndexService service = mockTypesIndexServer( ImmutableSetMultimap.of(LIST, "java.util.ArrayList", SET, "java.util.AbstractSet")); IRecommendersCompletionContext context = mockCompletionContextWithExpectedTypeNames(LIST, SET); TypesCompletionSessionProcessor sut = new TypesCompletionSessionProcessor(service, new SharedImages()); boolean shouldProcess = sut.startSession(context); assertThat(shouldProcess, is(equalTo(true))); IProcessableProposal arrayListProcessableProposal = mockProcessableProposal(CompletionProposal.TYPE_REF, ARRAY_LIST_SIGNATURE); IProcessableProposal abstractSetProcessableProposal = mockProcessableProposal(CompletionProposal.TYPE_REF, ABSTRACT_SET_SIGNATURE); sut.process(arrayListProcessableProposal); verifyWasBoosted(arrayListProcessableProposal); sut.process(abstractSetProcessableProposal); verifyWasBoosted(abstractSetProcessableProposal); } @Test public void testConstructorInvocationProposalWithGenerics() throws Exception { ITypesIndexService service = mockTypesIndexServer(ImmutableSetMultimap.of(LIST, "java.util.ArrayList")); IRecommendersCompletionContext context = mockCompletionContextWithExpectedTypeNames(LIST); TypesCompletionSessionProcessor sut = new TypesCompletionSessionProcessor(service, new SharedImages()); boolean shouldProcess = sut.startSession(context); assertThat(shouldProcess, is(equalTo(true))); IProcessableProposal genericArrayListProcessableProposal = mockProcessableProposal( CompletionProposal.CONSTRUCTOR_INVOCATION, "Ljava.util.ArrayList<TE;>;"); sut.process(genericArrayListProcessableProposal); verifyWasBoosted(genericArrayListProcessableProposal); } @Test public void testAnonymousClassConstructorInvocationProposal() throws Exception { ITypesIndexService service = mockTypesIndexServer(ImmutableSetMultimap.of(SET, "java.util.AbstractSet")); IRecommendersCompletionContext context = mockCompletionContextWithExpectedTypeNames(SET); TypesCompletionSessionProcessor sut = new TypesCompletionSessionProcessor(service, new SharedImages()); boolean shouldProcess = sut.startSession(context); assertThat(shouldProcess, is(equalTo(true))); IProcessableProposal abstractSetProcessableProposal = mockProcessableProposal( CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, ABSTRACT_SET_SIGNATURE); sut.process(abstractSetProcessableProposal); verifyWasBoosted(abstractSetProcessableProposal); } @Test public void testMethodRefProposal() throws Exception { ITypesIndexService service = mockTypesIndexServer(ImmutableSetMultimap.of(COLLECTION, "java.util.List")); IRecommendersCompletionContext context = mockCompletionContextWithExpectedTypeNames(COLLECTION); TypesCompletionSessionProcessor sut = new TypesCompletionSessionProcessor(service, new SharedImages()); boolean shouldProcess = sut.startSession(context); assertThat(shouldProcess, is(equalTo(true))); IProcessableProposal arraysAsListProcessableProposal = mockProcessableProposal( // Signature of Arrays.asList(T...) CompletionProposal.METHOD_REF, "<T:Ljava.lang.Object;>([TT;)Ljava.util.List<TT;>;"); sut.process(arraysAsListProcessableProposal); verifyWasBoosted(arraysAsListProcessableProposal); } @Test public void testMethodRefWithCastedReceiverProposal() throws Exception { ITypesIndexService service = mockTypesIndexServer(ImmutableSetMultimap.of(COLLECTION, "java.util.List")); IRecommendersCompletionContext context = mockCompletionContextWithExpectedTypeNames(COLLECTION); TypesCompletionSessionProcessor sut = new TypesCompletionSessionProcessor(service, new SharedImages()); boolean shouldProcess = sut.startSession(context); assertThat(shouldProcess, is(equalTo(true))); IProcessableProposal arraysAsListProcessableProposal = mockProcessableProposal( // Receiver Signature of List.set(Object) CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, "Ljava.util.List;"); sut.process(arraysAsListProcessableProposal); verifyWasBoosted(arraysAsListProcessableProposal); } private IRecommendersCompletionContext mockCompletionContextWithExpectedTypeNames(ITypeName... expectedTypeNames) { IRecommendersCompletionContext context = mock(IRecommendersCompletionContext.class); when(context.getExpectedTypeNames()).thenReturn(ImmutableSet.copyOf(expectedTypeNames)); IJavaProject project = mock(IJavaProject.class); when(context.getProject()).thenReturn(project); return context; } private ITypesIndexService mockTypesIndexServer(SetMultimap<ITypeName, String> index) { ITypesIndexService service = mock(ITypesIndexService.class); for (ITypeName typeName : index.keySet()) { Set<String> subtypes = index.get(typeName); when(service.subtypes(eq(typeName), any(IJavaProject.class))).thenReturn(subtypes); } return service; } private IProcessableProposal mockProcessableProposal(int coreProposalKind, String coreProposalSig) { IProcessableProposal processableProposal = mock(ProcessableJavaCompletionProposal.class); ProposalProcessorManager manager = mock(ProposalProcessorManager.class); when(processableProposal.getProposalProcessorManager()).thenReturn(manager); CompletionProposal coreProposal = mock(CompletionProposal.class); when(coreProposal.getKind()).thenReturn(coreProposalKind); when(processableProposal.getCoreProposal()).thenReturn(Optional.fromNullable(coreProposal)); switch (coreProposalKind) { case CompletionProposal.FIELD_REF: case CompletionProposal.LOCAL_VARIABLE_REF: case CompletionProposal.METHOD_REF: case CompletionProposal.TYPE_REF: when(coreProposal.getSignature()).thenReturn(coreProposalSig.toCharArray()); break; case CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION: case CompletionProposal.CONSTRUCTOR_INVOCATION: when(coreProposal.getDeclarationSignature()).thenReturn(coreProposalSig.toCharArray()); break; case CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER: case CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER: when(coreProposal.getReceiverSignature()).thenReturn(coreProposalSig.toCharArray()); break; } return processableProposal; } private void verifyWasBoosted(IProcessableProposal processableProposal) { ProposalProcessorManager manager = processableProposal.getProposalProcessorManager(); verify(processableProposal).setTag(ProposalTag.RECOMMENDERS_SCORE, BOOST); verify(manager, times(1)).addProcessor(processorWithBoost(BOOST)); verify(manager, times(1)).addProcessor(isA(OverlayImageProposalProcessor.class)); verifyNoMoreInteractions(manager); } }