blob: fe71e5d63bd9a601d9328b4e25e3c4e02fc8e276 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 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
*******************************************************************************/
package org.eclipse.lsp4e.test.hover;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.internal.text.html.BrowserInformationControl;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.tests.util.DisplayHelper;
import org.eclipse.lsp4e.operations.hover.LSPTextHover;
import org.eclipse.lsp4e.test.AllCleanRule;
import org.eclipse.lsp4e.test.TestUtils;
import org.eclipse.lsp4e.tests.mock.MockLanguageServer;
import org.eclipse.lsp4j.Hover;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.jsonrpc.messages.Either;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.ProgressAdapter;
import org.eclipse.swt.browser.ProgressEvent;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@SuppressWarnings("restriction")
public class HoverTest {
@Rule public AllCleanRule clear = new AllCleanRule();
private IProject project;
private LSPTextHover hover;
@Before
public void setUp() throws CoreException {
project = TestUtils.createProject("HoverTest" + System.currentTimeMillis());
hover = new LSPTextHover();
}
@Test
public void testHoverRegion() throws CoreException, InvocationTargetException {
Hover hoverResponse = new Hover(Collections.singletonList(Either.forLeft("HoverContent")), new Range(new Position(0, 0), new Position(0, 10)));
MockLanguageServer.INSTANCE.setHover(hoverResponse);
IFile file = TestUtils.createUniqueTestFile(project, "HoverRange Other Text");
ITextViewer viewer = TestUtils.openTextViewer(file);
assertEquals(new Region(0, 10), hover.getHoverRegion(viewer, 5));
}
@Test
public void testHoverRegionInvalidOffset() throws CoreException, InvocationTargetException {
MockLanguageServer.INSTANCE.setHover(null);
IFile file = TestUtils.createUniqueTestFile(project, "HoverRange Other Text");
ITextViewer viewer = TestUtils.openTextViewer(file);
assertEquals(new Region(15, 0), hover.getHoverRegion(viewer, 15));
}
@Test
public void testHoverInfo() throws CoreException, InvocationTargetException {
Hover hoverResponse = new Hover(Collections.singletonList(Either.forLeft("HoverContent")), new Range(new Position(0, 0), new Position(0, 10)));
MockLanguageServer.INSTANCE.setHover(hoverResponse);
IFile file = TestUtils.createUniqueTestFile(project, "HoverRange Other Text");
ITextViewer viewer = TestUtils.openTextViewer(file);
// TODO update test when MARKDOWN to HTML will be finished
assertTrue(hover.getHoverInfo(viewer, new Region(0, 10)).contains("HoverContent"));
}
@Test
public void testHoverInfoEmptyContentList() throws CoreException, InvocationTargetException {
Hover hoverResponse = new Hover(Collections.emptyList(), new Range(new Position(0, 0), new Position(0, 10)));
MockLanguageServer.INSTANCE.setHover(hoverResponse);
IFile file = TestUtils.createUniqueTestFile(project, "HoverRange Other Text");
ITextViewer viewer = TestUtils.openTextViewer(file);
assertEquals(null, hover.getHoverInfo(viewer, new Region(0, 10)));
}
@Test
public void testHoverInfoInvalidOffset() throws CoreException, InvocationTargetException {
MockLanguageServer.INSTANCE.setHover(null);
IFile file = TestUtils.createUniqueTestFile(project, "HoverRange Other Text");
ITextViewer viewer = TestUtils.openTextViewer(file);
assertEquals(null, hover.getHoverInfo(viewer, new Region(0, 10)));
}
@Test
public void testHoverEmptyContentItem() throws CoreException, InvocationTargetException {
Hover hoverResponse = new Hover(Collections.singletonList(Either.forLeft("")), new Range(new Position(0, 0), new Position(0, 10)));
MockLanguageServer.INSTANCE.setHover(hoverResponse);
IFile file = TestUtils.createUniqueTestFile(project, "HoverRange Other Text");
ITextViewer viewer = TestUtils.openTextViewer(file);
assertEquals(null, hover.getHoverInfo(viewer, new Region(0, 10)));
}
@Test
public void testHoverOnExternalFile()
throws CoreException, InvocationTargetException, IOException, InterruptedException {
Hover hoverResponse = new Hover(Collections.singletonList(Either.forLeft("blah")),
new Range(new Position(0, 0), new Position(0, 0)));
MockLanguageServer.INSTANCE.setHover(hoverResponse);
File file = File.createTempFile("testHoverOnExternalfile", ".lspt");
try {
ITextViewer viewer = TestUtils.getTextViewer(IDE.openInternalEditorOnFileStore(
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(), EFS.getStore(file.toURI())));
Assert.assertTrue(hover.getHoverInfo(viewer, new Region(0, 0)).contains("blah"));
} finally {
Files.deleteIfExists(file.toPath());
}
}
@Test
public void testMultipleHovers() throws Exception {
Hover hoverResponse = new Hover(Collections.singletonList(Either.forLeft("HoverContent")), new Range(new Position(0, 0), new Position(0, 10)));
MockLanguageServer.INSTANCE.setHover(hoverResponse);
IFile file = TestUtils.createUniqueTestFileMultiLS(project, "HoverRange Other Text");
ITextViewer viewer = TestUtils.openTextViewer(file);
// TODO update test when MARKDOWN to HTML will be finished
String hoverInfo = hover.getHoverInfo(viewer, new Region(0, 10));
int index = hoverInfo.indexOf("HoverContent");
assertNotEquals("Hover content not found", -1, index);
index += "HoverContent".length();
index = hoverInfo.indexOf("HoverContent", index);
assertNotEquals("Hover content found only once", -1, index);
}
@Test
public void testIntroUrlLink() throws Exception {
Hover hoverResponse = new Hover(
Collections.singletonList(Either.forLeft(
"[My intro URL link](http://org.eclipse.ui.intro/execute?command=org.eclipse.ui.file.close)")),
new Range(new Position(0, 0), new Position(0, 10)));
MockLanguageServer.INSTANCE.setHover(hoverResponse);
IFile file = TestUtils.createUniqueTestFile(project, "HoverRange Other Text");
ITextViewer viewer = TestUtils.openTextViewer(file);
String hoverContent = hover.getHoverInfo(viewer, new Region(0, 10));
LSPTextHover hoverManager = new LSPTextHover();
Display display = PlatformUI.getWorkbench().getDisplay();
final Shell shell = new Shell(display);
BrowserInformationControl wrapperControl = null, control = null;
try {
final RowLayout layout = new RowLayout(SWT.VERTICAL);
layout.fill = true;
shell.setLayout(layout);
shell.setSize(320, 200);
shell.open();
wrapperControl = (BrowserInformationControl) hoverManager.getHoverControlCreator()
.createInformationControl(shell);
control = (BrowserInformationControl) wrapperControl
.getInformationPresenterControlCreator().createInformationControl(shell);
Field f = BrowserInformationControl.class.getDeclaredField("fBrowser"); //
f.setAccessible(true);
Browser browser = (Browser) f.get(control);
browser.setJavascriptEnabled(true);
AtomicBoolean completed = new AtomicBoolean(false);
browser.addProgressListener(new ProgressAdapter() {
@Override
public void completed(ProgressEvent event) {
browser.removeProgressListener(this);
browser.execute("document.getElementsByTagName('a')[0].click()");
completed.set(true);
}
});
assertNotNull("Editor should be opened", viewer.getTextWidget());
browser.setText(hoverContent);
assertTrue("action didn't close editor", new DisplayHelper() {
@Override
protected boolean condition() {
return completed.get() && (viewer.getTextWidget() == null || viewer.getTextWidget().isDisposed());
}
}.waitForCondition(browser.getDisplay(), 10000));
} finally {
if (control != null) {
control.dispose();
}
if (wrapperControl != null) {
wrapperControl.dispose();
}
shell.dispose();
}
}
}