blob: dbf8dc18d3a4f40ff9857691bf1e57d606391cf1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016, 2017 Rogue Wave Software Inc. and others.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Michał Niewrzał (Rogue Wave Software Inc.) - initial implementation
* Max Bureck (Fraunhofer FOKUS) - added test for executing commands on completions
*******************************************************************************/
package org.eclipse.lsp4e.test.completion;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.tests.util.DisplayHelper;
import org.eclipse.lsp4e.LanguageServerWrapper;
import org.eclipse.lsp4e.LanguageServersRegistry;
import org.eclipse.lsp4e.LanguageServersRegistry.LanguageServerDefinition;
import org.eclipse.lsp4e.LanguageServiceAccessor;
import org.eclipse.lsp4e.LanguageServiceAccessor.LSPDocumentInfo;
import org.eclipse.lsp4e.operations.completion.LSCompletionProposal;
import org.eclipse.lsp4e.test.TestUtils;
import org.eclipse.lsp4e.tests.mock.MockLanguageServer;
import org.eclipse.lsp4j.Command;
import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.CompletionItemKind;
import org.eclipse.lsp4j.CompletionList;
import org.eclipse.lsp4j.ExecuteCommandParams;
import org.eclipse.lsp4j.InsertTextFormat;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.TextEdit;
import org.eclipse.lsp4j.jsonrpc.messages.Either;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ST;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.junit.Assert;
import org.junit.Test;
import com.google.gson.JsonPrimitive;
public class CompleteCompletionTest extends AbstractCompletionTest {
/*
* This tests the not-so-official way to associate a LS to a file programmatically, and then to retrieve the LS
* for the file independently of the content-types. Although doing it programatically isn't recommended, consuming
* file-specific LS already associated is something we want to support.
*/
@Test
public void testAssistForUnknownButConnectedType() throws CoreException, InvocationTargetException, IOException, InterruptedException {
List<CompletionItem> items = new ArrayList<>();
items.add(createCompletionItem("FirstClass", CompletionItemKind.Class));
MockLanguageServer.INSTANCE.setCompletionList(new CompletionList(false, items));
IFile testFile = TestUtils.createUniqueTestFileOfUnknownType(project, "");
ITextViewer viewer = TestUtils.openTextViewer(testFile);
LanguageServerDefinition serverDefinition = LanguageServersRegistry.getInstance().getDefinition("org.eclipse.lsp4e.test.server");
assertNotNull(serverDefinition);
LanguageServerWrapper lsWrapperForConnection = LanguageServiceAccessor
.getLSWrapperForConnection(testFile.getProject(), serverDefinition);
URI fileLocation = testFile.getLocationURI();
// force connection (that's what LSP4E should be designed to prevent 3rd party from having to use it).
lsWrapperForConnection.connect(testFile, null);
new DisplayHelper() {
@Override
protected boolean condition() {
return lsWrapperForConnection.isConnectedTo(fileLocation);
}
}.waitForCondition(Display.getCurrent(), 3000);
Assert.assertTrue(lsWrapperForConnection.isConnectedTo(fileLocation));
ICompletionProposal[] proposals = contentAssistProcessor.computeCompletionProposals(viewer, 0);
assertEquals(items.size(), proposals.length);
// TODO compare both structures
LSCompletionProposal lsCompletionProposal = (LSCompletionProposal)proposals[0];
lsCompletionProposal.apply(viewer, '\n', 0, 0);
assertEquals(new Point("FirstClass".length(), 0), lsCompletionProposal.getSelection(viewer.getDocument()));
}
@Test
public void testNoPrefix() throws CoreException, InvocationTargetException {
List<CompletionItem> items = new ArrayList<>();
items.add(createCompletionItem("FirstClass", CompletionItemKind.Class));
MockLanguageServer.INSTANCE.setCompletionList(new CompletionList(false, items));
IFile testFile = TestUtils.createUniqueTestFile(project, "");
ITextViewer viewer = TestUtils.openTextViewer(testFile);
ICompletionProposal[] proposals = contentAssistProcessor.computeCompletionProposals(viewer, 0);
assertEquals(items.size(), proposals.length);
// TODO compare both structures
LSCompletionProposal lsCompletionProposal = (LSCompletionProposal)proposals[0];
lsCompletionProposal.apply(viewer, '\n', 0, 0);
assertEquals(new Point("FirstClass".length(), 0), lsCompletionProposal.getSelection(viewer.getDocument()));
}
@Test
public void testPrefix() throws CoreException, InvocationTargetException {
List<CompletionItem> items = new ArrayList<>();
items.add(createCompletionItem("FirstClass", CompletionItemKind.Class));
items.add(createCompletionItem("SecondClass", CompletionItemKind.Class));
MockLanguageServer.INSTANCE.setCompletionList(new CompletionList(false, items));
String content = "First";
ITextViewer viewer = TestUtils.openTextViewer(TestUtils.createUniqueTestFile(project, content));
ICompletionProposal[] proposals = contentAssistProcessor.computeCompletionProposals(viewer, content.length());
assertEquals(1, proposals.length);
// TODO compare items
LSCompletionProposal lsCompletionProposal = (LSCompletionProposal)proposals[0];
lsCompletionProposal.apply(viewer, '\n', 0, 0);
assertEquals(new Point("FirstClass".length(), 0), lsCompletionProposal.getSelection(viewer.getDocument()));
}
/*
* This test checks if a Command associated with a completion that is applied will be executed.
* The test will use a Command that shall be handled by the langauge server.
*/
@Test
public void testCommandExecution() throws CoreException, InvocationTargetException, InterruptedException, ExecutionException, TimeoutException {
CompletionItem completionItem = createCompletionItem("Bla", CompletionItemKind.Class);
String expectedParameter = "command execution parameter";
List<Object> commandArguments = Arrays.asList(expectedParameter);
completionItem.setCommand(new Command("TestCommand", MockLanguageServer.SUPPORTED_COMMAND_ID, commandArguments));
MockLanguageServer.INSTANCE.setCompletionList(new CompletionList(false, Arrays.asList(completionItem)));
ITextViewer viewer = TestUtils.openTextViewer(TestUtils.createUniqueTestFile(project, ""));
ICompletionProposal[] proposals = contentAssistProcessor.computeCompletionProposals(viewer, 0);
assertEquals(1, proposals.length);
LSCompletionProposal lsCompletionProposal = (LSCompletionProposal)proposals[0];
lsCompletionProposal.apply(viewer, '\n', 0, 0);
// Assert command was invoked on langauge server
ExecuteCommandParams executedCommand = MockLanguageServer.INSTANCE.getWorkspaceService().getExecutedCommand().get(2, TimeUnit.SECONDS);
assertEquals(MockLanguageServer.SUPPORTED_COMMAND_ID, executedCommand.getCommand());
List<JsonPrimitive> expectedParameterList = Arrays.asList(new JsonPrimitive(expectedParameter));
assertEquals(expectedParameterList, executedCommand.getArguments());
}
@Test
public void testPrefixCaseSensitivity() throws CoreException, InvocationTargetException {
List<CompletionItem> items = new ArrayList<>();
items.add(createCompletionItem("FirstClass", CompletionItemKind.Class));
MockLanguageServer.INSTANCE.setCompletionList(new CompletionList(false, items));
String content = "FIRST";
ITextViewer viewer = TestUtils.openTextViewer(TestUtils.createUniqueTestFile(project, content));
ICompletionProposal[] proposals = contentAssistProcessor.computeCompletionProposals(viewer, content.length());
assertEquals(1, proposals.length);
// TODO compare items
LSCompletionProposal lsCompletionProposal = (LSCompletionProposal)proposals[0];
lsCompletionProposal.apply(viewer, '\n', 0, 0);
assertEquals(new Point("FirstClass".length(), 0), lsCompletionProposal.getSelection(viewer.getDocument()));
}
@Test
public void testCompleteOnFileEnd() throws CoreException, InvocationTargetException { // bug 508842
CompletionItem item = new CompletionItem();
item.setLabel("1024M");
item.setKind(CompletionItemKind.Value);
item.setTextEdit(Either.forLeft(new TextEdit(new Range(new Position(2, 10), new Position(2, 10)), "1024M")));
CompletionList completionList = new CompletionList(false, Collections.singletonList(item));
MockLanguageServer.INSTANCE.setCompletionList(completionList);
String content = "applications:\n" + "- name: hello\n" + " memory: ";
ITextViewer viewer = TestUtils.openTextViewer(TestUtils.createUniqueTestFile(project, content));
ICompletionProposal[] proposals = contentAssistProcessor.computeCompletionProposals(viewer, content.length());
assertEquals(1, proposals.length);
LSCompletionProposal lsCompletionProposal = (LSCompletionProposal)proposals[0];
lsCompletionProposal.apply(viewer, '\n', 0, content.length());
assertEquals(content + "1024M", viewer.getDocument().get());
assertEquals(new Point(viewer.getDocument().getLength(), 0), lsCompletionProposal.getSelection(viewer.getDocument()));
}
@Test
public void testTriggerCharsWithoutPreliminaryCompletion() throws CoreException, InvocationTargetException { // bug 508463
Set<String> triggers = new HashSet<>();
triggers.add("a");
triggers.add("b");
MockLanguageServer.INSTANCE.setCompletionTriggerChars(triggers);
String content = "First";
TestUtils.openTextViewer(TestUtils.createUniqueTestFile(project, content));
assertTrue(new DisplayHelper() {
@Override
protected boolean condition() {
return Arrays.equals(new char[]{ 'a', 'b'}, contentAssistProcessor.getCompletionProposalAutoActivationCharacters());
}
}.waitForCondition(Display.getDefault(), 3000));
}
@Test
public void testTriggerCharsNullList() throws CoreException, InvocationTargetException {
MockLanguageServer.INSTANCE.setCompletionTriggerChars(null);
TestUtils.openTextViewer(TestUtils.createUniqueTestFile(project, "First"));
assertArrayEquals(new char[0], contentAssistProcessor.getCompletionProposalAutoActivationCharacters());
}
@Test
public void testApplyCompletionWithPrefix() throws CoreException, InvocationTargetException {
Range range = new Range(new Position(0, 0), new Position(0, 5));
List<CompletionItem> items = Collections
.singletonList(createCompletionItem("FirstClass", CompletionItemKind.Class, range));
MockLanguageServer.INSTANCE.setCompletionList(new CompletionList(false, items));
String content = "First";
ITextViewer viewer = TestUtils.openTextViewer(TestUtils.createUniqueTestFile(project, content));
ICompletionProposal[] proposals = contentAssistProcessor.computeCompletionProposals(viewer, content.length());
LSCompletionProposal lsCompletionProposal = (LSCompletionProposal)proposals[0];
lsCompletionProposal.apply(viewer, '\n', 0, content.length());
assertEquals(true, viewer.getDocument().get().equals("FirstClass"));
assertEquals(new Point(viewer.getDocument().getLength(), 0), lsCompletionProposal.getSelection(viewer.getDocument()));
}
@Test
public void testApplyCompletionReplace() throws CoreException, InvocationTargetException {
Range range = new Range(new Position(0, 0), new Position(0, 20));
List<CompletionItem> items = Collections
.singletonList(createCompletionItem("FirstClass", CompletionItemKind.Class, range));
MockLanguageServer.INSTANCE.setCompletionList(new CompletionList(false, items));
String content = "FirstNotMatchedLabel";
ITextViewer viewer = TestUtils.openTextViewer(TestUtils.createUniqueTestFile(project, content));
ICompletionProposal[] proposals = contentAssistProcessor.computeCompletionProposals(viewer, 5);
LSCompletionProposal lsCompletionProposal = (LSCompletionProposal)proposals[0];
lsCompletionProposal.apply(viewer, '\n', 0, 5);
assertEquals("FirstClass", viewer.getDocument().get());
assertEquals(new Point("FirstClass".length(), 0), lsCompletionProposal.getSelection(viewer.getDocument()));
}
@Test
public void testApplyCompletionReplaceAndTypingWithTextEdit() throws CoreException, InvocationTargetException, BadLocationException {
Range range = new Range(new Position(0, 0), new Position(0, 20));
List<CompletionItem> items = Collections
.singletonList(createCompletionItem("FirstClass", CompletionItemKind.Class, range));
MockLanguageServer.INSTANCE.setCompletionList(new CompletionList(false, items));
String content = "FirstNotMatchedLabel";
ITextViewer viewer = TestUtils.openTextViewer(TestUtils.createUniqueTestFile(project,content));
int invokeOffset = 5;
ICompletionProposal[] proposals = contentAssistProcessor.computeCompletionProposals(viewer, invokeOffset);
LSCompletionProposal lsCompletionProposal = (LSCompletionProposal)proposals[0];
// simulate additional typing (to filter) after invoking completion
viewer.getDocument().replace(5, 0, "No");
lsCompletionProposal.apply(viewer, '\n', 0, invokeOffset + "No".length());
assertEquals("FirstClass", viewer.getDocument().get());
assertEquals(new Point("FirstClass".length(), 0), lsCompletionProposal.getSelection(viewer.getDocument()));
}
@Test
public void testApplyCompletionReplaceAndTyping()
throws CoreException, InvocationTargetException, BadLocationException {
CompletionItem item = new CompletionItem("strncasecmp");
item.setKind(CompletionItemKind.Function);
item.setInsertText("strncasecmp()");
MockLanguageServer.INSTANCE.setCompletionList(new CompletionList(false, Collections.singletonList(item)));
String content = "str";
ITextViewer viewer = TestUtils.openTextViewer(TestUtils.createUniqueTestFile(project, content));
int invokeOffset = content.length();
ICompletionProposal[] proposals = contentAssistProcessor.computeCompletionProposals(viewer, invokeOffset);
assertEquals(1, proposals.length);
LSCompletionProposal lsCompletionProposal = (LSCompletionProposal) proposals[0];
// simulate additional typing (to filter) after invoking completion
viewer.getDocument().replace(content.length(), 0, "nc");
lsCompletionProposal.apply(viewer, '\0', 0, invokeOffset + "nc".length());
assertEquals(item.getInsertText(), viewer.getDocument().get());
assertEquals(new Point(item.getInsertText().length(), 0), lsCompletionProposal.getSelection(viewer.getDocument()));
}
@Test
public void testCompletionReplace() throws CoreException, InvocationTargetException {
IFile file = TestUtils.createUniqueTestFile(project, "line1\nlineInsertHere");
ITextViewer viewer = TestUtils.openTextViewer(file);
MockLanguageServer.INSTANCE.setCompletionList(new CompletionList(false, Collections.singletonList(
createCompletionItem("Inserted", CompletionItemKind.Text, new Range(new Position(1, 4), new Position(1, 4 + "InsertHere".length())))
)));
int invokeOffset = viewer.getDocument().getLength() - "InsertHere".length();
ICompletionProposal[] proposals = contentAssistProcessor.computeCompletionProposals(viewer, invokeOffset);
LSCompletionProposal lsCompletionProposal = (LSCompletionProposal)proposals[0];
lsCompletionProposal.apply(viewer, '\n', 0, invokeOffset);
assertEquals("line1\nlineInserted", viewer.getDocument().get());
assertEquals(new Point(viewer.getDocument().getLength(), 0), lsCompletionProposal.getSelection(viewer.getDocument()));
}
@Test
public void testItemOrdering() throws Exception {
Range range = new Range(new Position(0, 0), new Position(0, 1));
List<CompletionItem> items = Arrays.asList(new CompletionItem[] {
createCompletionItem("AA", CompletionItemKind.Class, range),
createCompletionItem("AB", CompletionItemKind.Class, range),
createCompletionItem("BA", CompletionItemKind.Class, range),
createCompletionItem("BB", CompletionItemKind.Class, range),
createCompletionItem("CB", CompletionItemKind.Class, range),
createCompletionItem("CC", CompletionItemKind.Class, range),
});
MockLanguageServer.INSTANCE.setCompletionList(new CompletionList(false, items));
String content = "B";
ITextViewer viewer = TestUtils.openTextViewer(TestUtils.createUniqueTestFile(project,content));
int invokeOffset = 1;
ICompletionProposal[] proposals = contentAssistProcessor.computeCompletionProposals(viewer, invokeOffset);
assertEquals(4, proposals.length); // only those containing a "B"
assertEquals("BA", proposals[0].getDisplayString());
assertEquals("BB", proposals[1].getDisplayString());
assertEquals("AB", proposals[2].getDisplayString());
assertEquals("CB", proposals[3].getDisplayString());
((LSCompletionProposal) proposals[0]).apply(viewer, '\n', 0, invokeOffset);
assertEquals("BA", viewer.getDocument().get());
}
@Test
public void testBasicSnippet() throws PartInitException, InvocationTargetException, CoreException {
CompletionItem completionItem = createCompletionItem("$1 and ${2:foo}", CompletionItemKind.Class, new Range(new Position(0, 0), new Position(0, 1)));
completionItem.setInsertTextFormat(InsertTextFormat.Snippet);
MockLanguageServer.INSTANCE.setCompletionList(new CompletionList(false, Collections.singletonList(completionItem)));
ITextViewer viewer = TestUtils.openTextViewer(TestUtils.createUniqueTestFile(project,""));
int invokeOffset = 0;
ICompletionProposal[] proposals = contentAssistProcessor.computeCompletionProposals(viewer, invokeOffset);
assertEquals(1, proposals.length);
((LSCompletionProposal) proposals[0]).apply(viewer, '\n', 0, invokeOffset);
assertEquals(" and foo", viewer.getDocument().get());
// TODO check link edit groups
}
@Test
public void testChoiceSnippet() throws PartInitException, InvocationTargetException, CoreException {
CompletionItem completionItem = createCompletionItem("1${1|a,b|}2", CompletionItemKind.Class);
completionItem.setInsertTextFormat(InsertTextFormat.Snippet);
MockLanguageServer.INSTANCE.setCompletionList(new CompletionList(false, Collections.singletonList(completionItem)));
ITextViewer viewer = TestUtils.openTextViewer(TestUtils.createUniqueTestFile(project,""));
int invokeOffset = 0;
ICompletionProposal[] proposals = contentAssistProcessor.computeCompletionProposals(viewer, invokeOffset);
assertEquals(1, proposals.length);
Set<Shell> beforeShells = new HashSet<>(Arrays.asList(viewer.getTextWidget().getDisplay().getShells()));
((LSCompletionProposal) proposals[0]).apply(viewer, '\n', 0, invokeOffset);
assertEquals("1a2", viewer.getDocument().get());
Set<Shell> newShells = new HashSet<>(Arrays.asList(viewer.getTextWidget().getDisplay().getShells()));
newShells.removeAll(beforeShells);
assertNotEquals(Collections.emptySet(), newShells);
Table proposalList = (Table)newShells.iterator().next().getChildren()[0];
String[] itemLabels = Arrays.stream(proposalList.getItems()).map(TableItem::getText).toArray(String[]::new);
assertArrayEquals(new String[] {"a", "b"}, itemLabels);
}
@Test
public void testDuplicateVariable() throws PartInitException, InvocationTargetException, CoreException {
CompletionItem completionItem = createCompletionItem("${1:foo} and ${1:foo}", CompletionItemKind.Class, new Range(new Position(0, 0), new Position(0, 1)));
completionItem.setInsertTextFormat(InsertTextFormat.Snippet);
MockLanguageServer.INSTANCE.setCompletionList(new CompletionList(false, Collections.singletonList(completionItem)));
ITextViewer viewer = TestUtils.openTextViewer(TestUtils.createUniqueTestFile(project,""));
int invokeOffset = 0;
ICompletionProposal[] proposals = contentAssistProcessor.computeCompletionProposals(viewer, invokeOffset);
assertEquals(1, proposals.length);
((LSCompletionProposal) proposals[0]).apply(viewer, '\n', 0, invokeOffset);
assertEquals("foo and foo", viewer.getDocument().get());
// TODO check link edit groups
}
@Test
public void testSnippetTabStops() throws PartInitException, InvocationTargetException, CoreException {
CompletionItem completionItem = createCompletionItem("sum(${1:x}, ${2:y})", CompletionItemKind.Method,
new Range(new Position(0, 0), new Position(0, 1)));
completionItem.setInsertTextFormat(InsertTextFormat.Snippet);
MockLanguageServer.INSTANCE
.setCompletionList(new CompletionList(false, Collections.singletonList(completionItem)));
ITextViewer viewer = TestUtils.openTextViewer(TestUtils.createUniqueTestFile(project, ""));
int invokeOffset = 0;
ICompletionProposal[] proposals = contentAssistProcessor.computeCompletionProposals(viewer, invokeOffset);
assertEquals(1, proposals.length);
((LSCompletionProposal) proposals[0]).apply(viewer, '\n', 0, invokeOffset);
assertEquals("sum(x, y)", viewer.getDocument().get());
// after the proposal is applied, the x parameter should be selected
Point range = proposals[0].getSelection(viewer.getDocument());
assertEquals(4, range.x);
assertEquals(1, range.y);
// fake a VerifyKey tabbing event to jump to the y parameter
Event event = new Event();
event.character = SWT.TAB;
viewer.getTextWidget().notifyListeners(ST.VerifyKey, event);
range = viewer.getSelectedRange();
assertEquals(7, range.x);
assertEquals(1, range.y);
}
@Test
public void testMultipleLS() throws Exception {
List<CompletionItem> items = new ArrayList<>();
items.add(createCompletionItem("FirstClass", CompletionItemKind.Class));
MockLanguageServer.INSTANCE.setCompletionList(new CompletionList(false, items));
IFile testFile = TestUtils.createUniqueTestFileMultiLS(project, "");
ITextViewer viewer = TestUtils.openTextViewer(testFile);
ICompletionProposal[] proposals = contentAssistProcessor.computeCompletionProposals(viewer, 0);
assertEquals(2 * (long)(items.size()), proposals.length);
}
@Test
public void testReopeningFileAndReusingContentAssist() throws CoreException, InvocationTargetException {
List<CompletionItem> items = new ArrayList<>();
items.add(createCompletionItem("FirstClass", CompletionItemKind.Class));
MockLanguageServer.INSTANCE.setCompletionList(new CompletionList(false, items));
IFile testFile = TestUtils.createUniqueTestFile(project, "");
ITextViewer viewer = TestUtils.openTextViewer(testFile);
ICompletionProposal[] proposals = contentAssistProcessor.computeCompletionProposals(viewer, 0);
assertEquals(items.size(), proposals.length); // TODO compare both structures
LSCompletionProposal lsCompletionProposal = (LSCompletionProposal) proposals[0];
lsCompletionProposal.apply(viewer, '\n', 0, 0);
assertEquals(new Point("FirstClass".length(), 0), lsCompletionProposal.getSelection(viewer.getDocument()));
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().closeAllEditors(false);
MockLanguageServer.reset();
MockLanguageServer.INSTANCE.setCompletionList(new CompletionList(false, items));
viewer = TestUtils.openTextViewer(testFile);
proposals = contentAssistProcessor.computeCompletionProposals(viewer, 0);
assertEquals(items.size(), proposals.length); // TODO compare both structures
lsCompletionProposal = (LSCompletionProposal) proposals[0];
lsCompletionProposal.apply(viewer, '\n', 0, 0);
assertEquals(new Point("FirstClass".length(), 0), lsCompletionProposal.getSelection(viewer.getDocument()));
}
@Test
public void testFilterNonmatchingCompletions() throws Exception {
List<CompletionItem> items = new ArrayList<>();
CompletionItem item = new CompletionItem("server.web");
item.setFilterText("server.web");
item.setTextEdit(Either.forLeft(new TextEdit(new Range(new Position(0, 0), new Position(0, 10)), item.getFilterText())));
items.add(item);
// 'soup' replacing the 'ver' in 'server' does not make sense when knowing that
// ver should have been a filter
item = new CompletionItem("soup");
item.setFilterText("soup");
item.setTextEdit(Either.forLeft(new TextEdit(new Range(new Position(0, 3), new Position(0, 7)), item.getFilterText())));
items.add(item);
items.add(new CompletionItem(": 1.0.1"));
items.add(new CompletionItem("s.Status"));
confirmCompletionResults(items, "server", 6, new String[] { "server.web", ": 1.0.1", "s.Status" });
}
@Test
public void testFilterNonmatchingCompletionsMovieOffset() throws Exception {
IDocument document = TestUtils.openTextViewer(TestUtils.createUniqueTestFile(project, "servers")).getDocument();
LSPDocumentInfo info = LanguageServiceAccessor
.getLSPDocumentInfosFor(document, capabilities -> capabilities.getCompletionProvider() != null
|| capabilities.getSignatureHelpProvider() != null)
.get(0);
// The completion ': 1.0.1' was given, then the user types a 's', which is used
// as a filter and removes the completion
LSCompletionProposal completionProposal = new LSCompletionProposal(document, 0, new CompletionItem(": 1.0.1"),
info.getLanguageClient());
assertTrue(completionProposal.isValidFor(document, 6));
assertFalse(completionProposal.isValidFor(document, 7));
}
}