Files
openide/java/java-tests/testSrc/com/intellij/codeInsight/JavaExternalDocumentationTest.java
T

216 lines
8.7 KiB
Java

/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight;
import com.intellij.JavaTestUtil;
import com.intellij.codeInsight.documentation.DocumentationComponent;
import com.intellij.codeInsight.documentation.DocumentationManager;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.JavadocOrderRootType;
import com.intellij.openapi.roots.ModuleRootModificationUtil;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileFactory;
import com.intellij.testFramework.EditorTestUtil;
import com.intellij.testFramework.PlatformTestCase;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.ide.BuiltInServerManager;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class JavaExternalDocumentationTest extends PlatformTestCase {
public static final Pattern BASE_URL_PATTERN = Pattern.compile("(<base href=\")([^\"]*)");
public static final Pattern IMG_URL_PATTERN = Pattern.compile("<img src=\"([^\"]*)");
@Override
protected void setUp() throws Exception {
super.setUp();
final VirtualFile libClasses = getJarFile("library.jar");
final VirtualFile libJavadocJar = getJarFile("library-javadoc.jar");
ApplicationManager.getApplication().runWriteAction(() -> {
final Library library = LibraryTablesRegistrar.getInstance().getLibraryTable(myProject).createLibrary("myLib");
final Library.ModifiableModel model = library.getModifiableModel();
model.addRoot(libClasses, OrderRootType.CLASSES);
model.addRoot(libJavadocJar, JavadocOrderRootType.getInstance());
model.commit();
Module[] modules = ModuleManager.getInstance(myProject).getModules();
assertSize(1, modules);
ModuleRootModificationUtil.addDependency(modules[0], library);
});
}
public void testImagesInsideJavadocJar() throws Exception {
String text = getDocumentationText("class Foo { com.jetbrains.<caret>Test field; }");
Matcher baseUrlmatcher = BASE_URL_PATTERN.matcher(text);
assertTrue(baseUrlmatcher.find());
String baseUrl = baseUrlmatcher.group(2);
Matcher imgMatcher = IMG_URL_PATTERN.matcher(text);
assertTrue(imgMatcher.find());
String relativeUrl = imgMatcher.group(1);
URL imageUrl = new URL(new URL(baseUrl), relativeUrl);
URLConnection connection = imageUrl.openConnection();
BuiltInServerManager.getInstance().configureRequestToWebServer(connection);
try (InputStream stream = connection.getInputStream()) {
assertEquals(228, FileUtil.loadBytes(stream).length);
}
}
// We're guessing style of references in javadoc by bytecode version of library class file
// but displaying quick doc should work even if javadoc was generated using a JDK not corresponding to bytecode version
public void testReferenceStyleDoesntMatchBytecodeVersion() throws Exception {
doTest("@com.jetbrains.TestAnnotation(<caret>param = \"foo\") class Foo {}");
}
public void testLinkWithReference() throws Exception {
doTest("class Foo { com.jetbrains.<caret>ClassWithRefLink field;}");
}
public void testLinkToPackageSummaryWithReference() throws Exception {
doTest("class Foo implements com.jetbrains.<caret>SimpleInterface {}");
}
public void testLinkBetweenMethods() throws Exception {
doTest("class Foo {{ new com.jetbrains.LinkBetweenMethods().<caret>m1(); }}");
}
private void doTest(String text) throws Exception {
String actualText = getDocumentationText(text);
String expectedText = StringUtil.convertLineSeparators(FileUtil.loadFile(getDataFile(getTestName(false) + ".html")));
assertEquals(expectedText, replaceBaseUrlWithPlaceholder(actualText));
}
private static String replaceBaseUrlWithPlaceholder(String actualText) {
return BASE_URL_PATTERN.matcher(actualText).replaceAll("$1placeholder");
}
private static void waitTillDone(ActionCallback actionCallback) throws InterruptedException {
if (actionCallback == null) return;
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < 300000) {
//noinspection BusyWait
Thread.sleep(100);
UIUtil.dispatchAllInvocationEvents();
if (actionCallback.isProcessed()) return;
}
fail("Timed out waiting for documentation to show");
}
private static File getDataFile(String name) {
return new File(JavaTestUtil.getJavaTestDataPath() + "/codeInsight/documentation/" + name);
}
@NotNull
public static VirtualFile getJarFile(String name) {
VirtualFile file = getVirtualFile(getDataFile(name));
assertNotNull(file);
VirtualFile jarFile = JarFileSystem.getInstance().getJarRootForLocalFile(file);
assertNotNull(jarFile);
return jarFile;
}
private String getDocumentationText(String sourceEditorText) throws Exception {
return getDocumentationText(myProject, sourceEditorText);
}
public static String getDocumentationText(Project project, String sourceEditorText) throws Exception {
int caretPosition = sourceEditorText.indexOf(EditorTestUtil.CARET_TAG);
if (caretPosition >= 0) {
sourceEditorText = sourceEditorText.substring(0, caretPosition) +
sourceEditorText.substring(caretPosition + EditorTestUtil.CARET_TAG.length());
}
PsiFile psiFile = PsiFileFactory.getInstance(project).createFileFromText(JavaLanguage.INSTANCE, sourceEditorText);
return getDocumentationText(psiFile, caretPosition);
}
public static String getDocumentationText(@NotNull PsiFile psiFile, int caretPosition) throws InterruptedException {
Project project = psiFile.getProject();
Document document = PsiDocumentManager.getInstance(project).getDocument(psiFile);
assertNotNull(document);
Editor editor = EditorFactory.getInstance().createEditor(document, project);
try {
if (caretPosition >= 0) {
editor.getCaretModel().moveToOffset(caretPosition);
}
DocumentationManager documentationManager = DocumentationManager.getInstance(project);
MockDocumentationComponent documentationComponent = new MockDocumentationComponent(documentationManager);
try {
documentationManager.setDocumentationComponent(documentationComponent);
documentationManager.showJavaDocInfo(editor, psiFile, false);
waitTillDone(documentationManager.getLastAction());
return documentationComponent.getText();
}
finally {
JBPopup hint = documentationComponent.getHint();
if (hint != null) Disposer.dispose(hint);
Disposer.dispose(documentationComponent);
}
}
finally {
EditorFactory.getInstance().releaseEditor(editor);
}
}
private static class MockDocumentationComponent extends DocumentationComponent {
private String myText;
public MockDocumentationComponent(DocumentationManager manager) {
super(manager);
}
@Override
public void setText(String text, PsiElement element, boolean clean, boolean clearHistory) {
myText = text;
}
@Override
public void setData(PsiElement _element, String text, boolean clearHistory, String effectiveExternalUrl, String ref) {
myText = text;
}
public String getText() {
return myText;
}
}
}