blob: 28526580e65a3f58718d2bc9b03f58db358e8fd4 [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.assertNull;
import static org.junit.Assert.assertTrue;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.internal.text.html.BrowserInformationControl;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;
import org.eclipse.lsp4e.operations.hover.LSBasedHover;
import org.eclipse.lsp4e.test.TestUtils;
import org.eclipse.lsp4e.tests.mock.MockLanguageSever;
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.junit.After;
import org.junit.Before;
import org.junit.Test;
@SuppressWarnings("restriction")
public class HoverTest {
private IProject project;
private LSBasedHover hover;
@Before
public void setUp() throws CoreException {
project = TestUtils.createProject("HoverTest" + System.currentTimeMillis());
hover = new LSBasedHover();
}
@After
public void tearDown() throws CoreException {
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().closeAllEditors(false);
project.delete(true, true, new NullProgressMonitor());
MockLanguageSever.INSTANCE.shutdown();
}
@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)));
MockLanguageSever.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 {
MockLanguageSever.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)));
MockLanguageSever.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)));
MockLanguageSever.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 {
MockLanguageSever.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)));
MockLanguageSever.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 testMultipleHovers() throws Exception {
Hover hoverResponse = new Hover(Collections.singletonList(Either.forLeft("HoverContent")), new Range(new Position(0, 0), new Position(0, 10)));
MockLanguageSever.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)));
MockLanguageSever.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));
LSBasedHover hoverManager = new LSBasedHover();
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);
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()");
while (display.readAndDispatch()) {
}
completed.set(true);
}
});
assertNotNull("Editor should be opened", viewer.getTextWidget());
browser.setText(hoverContent);
long maxTimestamp = System.currentTimeMillis() + 10000;
while (!completed.get() && System.currentTimeMillis() < maxTimestamp) {
display.readAndDispatch();
}
// Editor opened at the beginining is closed
assertNull("Editor should be closed", viewer.getTextWidget());
} finally {
if (control != null) {
control.dispose();
}
if (wrapperControl != null) {
wrapperControl.dispose();
}
shell.dispose();
while (display.readAndDispatch()) {
}
}
}
}