/* * Copyright 2013-2017 Grzegorz Ligas <[email protected]> and other contributors * (see the CONTRIBUTORS file). * * 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 org.intellij.xquery.documentation; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.openapi.util.Condition; import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.containers.ContainerUtil; import org.intellij.xquery.BaseFunctionalTestCase; import org.intellij.xquery.XQueryFlavour; import org.intellij.xquery.completion.function.BuiltInFunctionSignature; import org.intellij.xquery.psi.XQueryFunctionCall; import org.intellij.xquery.psi.XQueryFunctionDecl; import org.intellij.xquery.psi.XQueryFunctionName; import org.intellij.xquery.psi.XQueryVarName; import org.intellij.xquery.settings.XQuerySettings; import org.jetbrains.annotations.NotNull; import static org.intellij.xquery.Assertions.assertChildOf; import static org.intellij.xquery.documentation.CommentAndSignatureBasedDocumentation.FILE_LINK_TEMPLATE; import static org.intellij.xquery.documentation.CommentAndSignatureBasedDocumentation.NAMESPACE_LABEL; import static org.intellij.xquery.documentation.DocumentationStylist.DD_END; import static org.intellij.xquery.documentation.DocumentationStylist.DD_START; import static org.intellij.xquery.documentation.DocumentationStylist.DL_END; import static org.intellij.xquery.documentation.DocumentationStylist.DL_START; import static org.intellij.xquery.documentation.DocumentationStylist.FUNCTION_END; import static org.intellij.xquery.documentation.DocumentationStylist.FUNCTION_START; import static org.intellij.xquery.documentation.DocumentationStylist.HTML_BR; import static org.intellij.xquery.documentation.DocumentationStylist.LABEL_END; import static org.intellij.xquery.documentation.DocumentationStylist.LABEL_START; import static org.intellij.xquery.documentation.DocumentationStylist.WRAPPER_END; import static org.intellij.xquery.documentation.DocumentationStylist.WRAPPER_START; import static org.intellij.xquery.reference.ReferenceUtil.getTargetOfReferenceAtCaret; /** * User: ligasgr * Date: 16/12/13 * Time: 14:59 */ public class XQueryDocumentationProviderTest extends BaseFunctionalTestCase { private static final String SOURCE_FILE_NAME = "a.xq"; private static final String FILE_LINK = String.format(FILE_LINK_TEMPLATE, SOURCE_FILE_NAME, SOURCE_FILE_NAME); private static final String VARIABLE_DECLARATION = "declare variable $ns:var as xs:string := 'var'"; private static final String NAMESPACE = "ns"; private static final String FUN_SIGNATURE = "declare function " + FUNCTION_START + "ns:f" + FUNCTION_END + "()"; private static final String SIGNATURE_BASED_HEADER = FILE_LINK + HTML_BR + NAMESPACE_LABEL + NAMESPACE + HTML_BR + FUN_SIGNATURE; private XQueryDocumentationProvider documentationProvider = new XQueryDocumentationProvider(); public void testUserVariableReference() throws Exception { doTestGenerateVariableDoc(WRAPPER_START + FILE_LINK + HTML_BR + NAMESPACE_LABEL + NAMESPACE + HTML_BR + VARIABLE_DECLARATION + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + VARIABLE_DECLARATION + ";\n" + "declare variable $ns:another := $ns:v<caret>ar"); } public void testUserExternalVariableReference() throws Exception { doTestGenerateVariableDoc(WRAPPER_START + FILE_LINK + HTML_BR + NAMESPACE_LABEL + NAMESPACE + HTML_BR + "declare variable $ns:var as xs:string external := 'var'" + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "declare variable $ns:var as xs:string external := 'var';\n" + "declare variable $ns:another := $ns:v<caret>ar"); } public void testUserVariableReferenceInMainModule() throws Exception { doTestGenerateVariableDoc(WRAPPER_START + FILE_LINK + HTML_BR + NAMESPACE_LABEL + NAMESPACE + HTML_BR + VARIABLE_DECLARATION + WRAPPER_END, "declare namespace ns = '" + NAMESPACE + "';\n" + VARIABLE_DECLARATION + ";\n" + "declare variable $ns:another := $ns:v<caret>ar"); } public void testUserVariableDeclaration() throws Exception { doTestGenerateVariableDoc(WRAPPER_START + FILE_LINK + HTML_BR + NAMESPACE_LABEL + NAMESPACE + HTML_BR + VARIABLE_DECLARATION + WRAPPER_END, "declare namespace ns = '" + NAMESPACE + "';\n" + "declare variable $ns:v<caret>ar as xs:string := 'var';"); } public void testUserVariableDeclarationWithComment() throws Exception { doTestGenerateVariableDoc(WRAPPER_START + FILE_LINK + HTML_BR + NAMESPACE_LABEL + NAMESPACE + HTML_BR + VARIABLE_DECLARATION + DL_START + LABEL_START + "Summary" + LABEL_END + DD_START + "my description" + DD_END + DL_END + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "(:~ my description :)" + "declare variable $ns:v<caret>ar as xs:string := 'var';"); } public void testLetBindingReference() throws Exception { doTestGenerateVariableDoc(WRAPPER_START + FILE_LINK + HTML_BR + "let $var as xs:string := 'var'" + WRAPPER_END, "let $var as xs:string := 'var' return $v<caret>ar"); } public void testForBindingReference() throws Exception { doTestGenerateVariableDoc(WRAPPER_START + FILE_LINK + HTML_BR + "for $var as xs:string in 1 to 10" + WRAPPER_END, "for $var as xs:string in 1 to 10 return $v<caret>ar"); } public void testSecondForBindingReference() throws Exception { doTestGenerateVariableDoc(WRAPPER_START + FILE_LINK + HTML_BR + "for $var2 in 5 to 10" + WRAPPER_END, "for $var as xs:string in 1 to 10, $var2 in 5 to 10 return $v<caret>ar2"); } public void testGroupingSpec() throws Exception { doTestGenerateVariableDoc(WRAPPER_START + FILE_LINK + HTML_BR + "group by $var2 := 'a' collation 'mine'" + WRAPPER_END, "for $var as xs:string in 1 to 10 group by $v<caret>ar2 := 'a' collation 'mine' return $var"); } public void testParameter() throws Exception { doTestGenerateVariableDoc(WRAPPER_START + FILE_LINK + HTML_BR + "$param as xs:int" + WRAPPER_END, "declare namespace ns = '" + NAMESPACE + "';\n" + "declare function ns:f($pa<caret>ram as xs:int) {()};"); } public void testParameterReference() throws Exception { doTestGenerateVariableDoc(WRAPPER_START + FILE_LINK + HTML_BR + "$param as xs:int" + WRAPPER_END, "declare namespace ns = '" + NAMESPACE + "';\n" + "declare function ns:f($param as xs:int) {$par<caret>am};"); } public void testWindow() throws Exception { doTestGenerateVariableDoc(WRAPPER_START + FILE_LINK + HTML_BR + "for tumbling window $w in (2, 4, 6, 8, 10, 12, 14)" + "start at $s when fn:true() " + "only end at $e when $e - $s eq 2" + WRAPPER_END, "for tumbling window $w in (2, 4, 6, 8, 10, 12, 14)" + "start at $s when fn:true() " + "only end at $<caret>e when $e - $s eq 2 " + "return <window>{ $w }</window>"); } public void testTypeswitchCaseClause() throws Exception { doTestGenerateVariableDoc(WRAPPER_START + FILE_LINK + HTML_BR + "case $a as element() return $a" + WRAPPER_END, "typeswitch ($node) case $a as element() return $<caret>a default return $node"); } public void testTypeswitchDefaultReturnClause() throws Exception { doTestGenerateVariableDoc(WRAPPER_START + FILE_LINK + HTML_BR + "default $b return $b" + WRAPPER_END, "typeswitch ($node) case $a as element() return $a default $b return $<caret>b"); } public void testQuantifiedExpressionSome() throws Exception { doTestGenerateVariableDoc(WRAPPER_START + FILE_LINK + HTML_BR + "some $searchString in ('a', 'b')" + WRAPPER_END, "some $searchString in ('a', 'b') satisfies contains('ag', $s<caret>earchString)"); } public void testQuantifiedExpressionEvery() throws Exception { doTestGenerateVariableDoc(WRAPPER_START + FILE_LINK + HTML_BR + "every $searchString in ('a', 'b')" + WRAPPER_END, "every $searchString in ('a', 'b') satisfies contains('ag', $s<caret>earchString)"); } public void testQuantifiedExpressionSomeForSecondBinding() throws Exception { doTestGenerateVariableDoc(WRAPPER_START + FILE_LINK + HTML_BR + "some $a in ('a')" + WRAPPER_END, "some $searchString in ('a', 'b'), $a in ('a') satisfies $<caret>a = ('a')"); } public void testUserVariableReferenceToAnotherFile() throws Exception { doTestGenerateVariableDoc(WRAPPER_START + String.format(FILE_LINK_TEMPLATE, "x.xq", "x.xq") + HTML_BR + NAMESPACE_LABEL + NAMESPACE + HTML_BR + VARIABLE_DECLARATION + WRAPPER_END, "import module namespace x = '" + NAMESPACE + "' at 'x.xq'" + "$x:v<caret>ar", new FileData("x.xq", "module namespace ns = '" + NAMESPACE + "';\n" + VARIABLE_DECLARATION + ";")); } public void testLookupItemForVariableWithDocComment() throws Exception { doTestGenerateLookupItemDoc(WRAPPER_START + FILE_LINK + HTML_BR + NAMESPACE_LABEL + NAMESPACE + HTML_BR + VARIABLE_DECLARATION + DL_START + LABEL_START + "Summary" + LABEL_END + DD_START + "my description" + DD_END + DL_END + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "(:~ my description :)\n" + VARIABLE_DECLARATION + ";\n" + "declare function ns:x() {$ns:<caret>};", XQueryVarName.class); } public void testUserFunctionReference() throws Exception { doTestGenerateFunctionDoc(WRAPPER_START + FILE_LINK + HTML_BR + NAMESPACE_LABEL + NAMESPACE + HTML_BR + "declare %private function " + FUNCTION_START + "ns:f" + FUNCTION_END + "($a) as item()" + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "declare %private function ns:f($a) as item() {()};\n" + "declare variable $ns:another := ns:<caret>f(1);"); } public void testUserFunctionDeclaration() throws Exception { doTestGenerateFunctionDoc(WRAPPER_START + SIGNATURE_BASED_HEADER + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "declare function ns:<caret>f() {()};"); } public void testUserFunctionDeclarationWithThreeAnnotationsAndNoParams() throws Exception { doTestGenerateFunctionDoc(WRAPPER_START + FILE_LINK + HTML_BR + NAMESPACE_LABEL + NAMESPACE + HTML_BR + "declare %private %my %ns:another function " + FUNCTION_START + "ns:f" + FUNCTION_END + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "declare %private %my %ns:another function ns:<caret>f"); } public void testUserFunctionDeclarationWithDefaultFunctionNamespace() throws Exception { doTestGenerateFunctionDoc(WRAPPER_START + FILE_LINK + HTML_BR + NAMESPACE_LABEL + "def" + HTML_BR + "declare function " + FUNCTION_START + "fun" + FUNCTION_END + "()" + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "declare default function namespace 'def';\n" + "declare function f<caret>un() {()};"); } public void testUserFunctionDeclarationWithIncorrectNamespace() throws Exception { doTestGenerateFunctionDoc(WRAPPER_START + FILE_LINK + HTML_BR + FUN_SIGNATURE + WRAPPER_END, "declare function ns:<caret>f() {()};"); } public void testUserFunctionDeclarationWithDocComment() throws Exception { doTestGenerateFunctionDoc(WRAPPER_START + SIGNATURE_BASED_HEADER + DL_START + LABEL_START + "Summary" + LABEL_END + DD_START + "my description" + DD_END + DL_END + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "(:~ my description :)" + "declare function ns:<caret>f() {()};"); } public void testUserFunctionDeclarationWithMultiLineDocComment() throws Exception { doTestGenerateFunctionDoc(WRAPPER_START + SIGNATURE_BASED_HEADER + DL_START + LABEL_START + "Summary" + LABEL_END + DD_START + "my description in multiple lines" + DD_END + DL_END + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "(:~ my description\n" + " : in\n" + " : multiple\n" + " :lines\n" + " :)" + "declare function ns:<caret>f() {()};"); } public void testUserFunctionDeclarationWithDocCommentForPreviousFunction() throws Exception { doTestGenerateFunctionDoc(WRAPPER_START + SIGNATURE_BASED_HEADER + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "(:~ my description :)" + "declare function ns:a() {()};\n" + "declare function ns:<caret>f() {()};"); } public void testUserFunctionDeclarationWithNonDocComment() throws Exception { doTestGenerateFunctionDoc(WRAPPER_START + SIGNATURE_BASED_HEADER + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "(: my description :)" + "declare function ns:<caret>f() {()};"); } public void testLookupItemForUserFunctionDeclarationWithDocComment() throws Exception { doTestGenerateLookupItemDoc(WRAPPER_START + SIGNATURE_BASED_HEADER + DL_START + LABEL_START + "Summary" + LABEL_END + DD_START + "my description" + DD_END + DL_END + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "(:~ my description :)" + "declare function ns:f() {(<caret>)};", XQueryFunctionName.class); } public void testUserFunctionDeclarationWithDocCommentWithParameter() throws Exception { doTestGenerateFunctionDoc(WRAPPER_START + FILE_LINK + HTML_BR + NAMESPACE_LABEL + NAMESPACE + HTML_BR + "declare function " + FUNCTION_START + "ns:f" + FUNCTION_END + "($a)" + HTML_BR + HTML_BR + DL_START + LABEL_START + "Parameters" + LABEL_END + DD_START + "a - my parameter" + DD_END + DL_END + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "(:~ \n" + " : @param a my parameter\n" + " :)" + "declare function ns:<caret>f($a) {()};"); } public void testUserFunctionDeclarationWithDocCommentWithParameterWithDollar() throws Exception { doTestGenerateFunctionDoc(WRAPPER_START + FILE_LINK + HTML_BR + NAMESPACE_LABEL + NAMESPACE + HTML_BR + "declare function " + FUNCTION_START + "ns:f" + FUNCTION_END + "($a)" + HTML_BR + HTML_BR + DL_START + LABEL_START + "Parameters" + LABEL_END + DD_START + "a - my parameter" + DD_END + DL_END + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "(:~ \n" + " : @param $a my parameter\n" + " :)" + "declare function ns:<caret>f($a) {()};"); } public void testUserFunctionDeclarationWithDocCommentWithParameters() throws Exception { doTestGenerateFunctionDoc(WRAPPER_START + FILE_LINK + HTML_BR + NAMESPACE_LABEL + NAMESPACE + HTML_BR + "declare function " + FUNCTION_START + "ns:f" + FUNCTION_END + "($a, $b, $c)" + HTML_BR + HTML_BR + DL_START + LABEL_START + "Parameters" + LABEL_END + DD_START + "a - my parameter" + HTML_BR + "b - my parameter 1" + HTML_BR + "c - my parameter 2" + DD_END + DL_END + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "(:~ @param a my parameter\n" + " : @param b my parameter 1\n" + " : @param c my parameter 2\n" + " :)" + "declare function ns:<caret>f($a, $b, $c) {()};"); } public void testUserFunctionDeclarationWithDocCommentWithParametersWithoutDescriptions() throws Exception { doTestGenerateFunctionDoc(WRAPPER_START + FILE_LINK + HTML_BR + NAMESPACE_LABEL + NAMESPACE + HTML_BR + "declare function " + FUNCTION_START + "ns:f" + FUNCTION_END + "($a, $b, $c)" + HTML_BR + HTML_BR + DL_START + LABEL_START + "Parameters" + LABEL_END + DD_START + "a - " + HTML_BR + "b - " + HTML_BR + "c - " + DD_END + DL_END + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "(:~ @param a\n" + " : @param b\n" + " : @param c\n" + " :)" + "declare function ns:<caret>f($a, $b, $c) {()};"); } public void testUserFunctionDeclarationWithDocCommentWithAuthor() throws Exception { doTestGenerateFunctionDoc(WRAPPER_START + SIGNATURE_BASED_HEADER + HTML_BR + HTML_BR + DL_START + LABEL_START + "Author" + LABEL_END + DD_START + "author with spaces" + DD_END + DL_END + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "(:~ @author author with spaces :)" + "declare function ns:<caret>f() {()};"); } public void testUserFunctionDeclarationWithDocCommentWithVersion() throws Exception { doTestGenerateFunctionDoc(WRAPPER_START + SIGNATURE_BASED_HEADER + HTML_BR + HTML_BR + DL_START + LABEL_START + "Version" + LABEL_END + DD_START + "1.0" + DD_END + DL_END + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "(:~ \n" + " : @version 1.0\n" + " :)" + "declare function ns:<caret>f() {()};"); } public void testUserFunctionDeclarationWithDocCommentWithReturn() throws Exception { doTestGenerateFunctionDoc(WRAPPER_START + SIGNATURE_BASED_HEADER + HTML_BR + HTML_BR + DL_START + LABEL_START + "Returns" + LABEL_END + DD_START + "value described" + DD_END + DL_END + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "(:~ \n" + " : @return value described\n" + " :)" + "declare function ns:<caret>f() {()};"); } public void testUserFunctionDeclarationWithDocCommentWithError() throws Exception { doTestGenerateFunctionDoc(WRAPPER_START + SIGNATURE_BASED_HEADER + HTML_BR + HTML_BR + DL_START + LABEL_START + "Throws errors" + LABEL_END + DD_START + "err:SomeError - if condition is met" + DD_END + DL_END + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "(:~ \n" + " : @error err:SomeError if condition is met\n" + " :)" + "declare function ns:<caret>f() {()};"); } public void testUserFunctionDeclarationWithDocCommentWithSince() throws Exception { doTestGenerateFunctionDoc(WRAPPER_START + SIGNATURE_BASED_HEADER + HTML_BR + HTML_BR + DL_START + LABEL_START + "Since" + LABEL_END + DD_START + "2.3" + DD_END + DL_END + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "(:~ \n" + " : @since 2.3\n" + " :)" + "declare function ns:<caret>f() {()};"); } public void testUserFunctionDeclarationWithDocCommentWithSee() throws Exception { doTestGenerateFunctionDoc(WRAPPER_START + SIGNATURE_BASED_HEADER + HTML_BR + HTML_BR + DL_START + LABEL_START + "See" + LABEL_END + DD_START + "anotherModule.xq" + DD_END + DL_END + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "(:~ \n" + " : @see anotherModule.xq\n" + " :)" + "declare function ns:<caret>f() {()};"); } public void testUserFunctionDeclarationWithDocCommentWithDeprecated() throws Exception { doTestGenerateFunctionDoc(WRAPPER_START + SIGNATURE_BASED_HEADER + HTML_BR + HTML_BR + DL_START + LABEL_START + "Deprecated" + LABEL_END + DD_START + "because of a reason" + DD_END + DL_END + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "(:~ \n" + " : @deprecated because of a reason\n" + " :)" + "declare function ns:<caret>f() {()};"); } public void testUserFunctionDeclarationWithDocCommentForAllTags() throws Exception { doTestGenerateFunctionDoc(WRAPPER_START + SIGNATURE_BASED_HEADER + HTML_BR + HTML_BR + DL_START + LABEL_START + "Summary" + LABEL_END + DD_START + "my comment" + DD_END + LABEL_START + "Author" + LABEL_END + DD_START + "author with spaces" + DD_END + LABEL_START + "Version" + LABEL_END + DD_START + "2.0" + DD_END + LABEL_START + "Since" + LABEL_END + DD_START + "1.0" + DD_END + LABEL_START + "Deprecated" + LABEL_END + DD_START + "because of a reason" + DD_END + LABEL_START + "Parameters" + LABEL_END + DD_START + "a - my parameter" + DD_END + LABEL_START + "Returns" + LABEL_END + DD_START + "value described" + DD_END + LABEL_START + "Throws errors" + LABEL_END + DD_START + "err:SomeError - if condition is met" + DD_END + LABEL_START + "See" + LABEL_END + DD_START + "anotherModule.xq" + DD_END + DL_END + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "(:~ my comment\n" + " : @author author with spaces\n" + " : @version 2.0\n" + " : @since 1.0\n" + " : @deprecated because of a reason\n" + " : @param $a my parameter\n" + " : @return value described\n" + " : @error err:SomeError if condition is met\n" + " : @see anotherModule.xq\n" + " :)" + "declare function ns:<caret>f() {()};"); } public void testBuiltInFunctionReference() throws Exception { doTestGenerateFunctionDoc(WRAPPER_START + "<dl><dt class=\"label\">Summary</dt> <dd> <p>Returns the <code>xs:boolean</code> value " + "<code>true</code>.</p> </dd> <dt class=\"label\">Signature</dt> <dd> <div class=\"exampleInner\"> " + "<div class=\"proto\"><code class= \"function\">fn:true</code>()<code class= \"as\"> as " + "</code><code class= \"return-type\">xs:boolean</code></div> </div> </dd> <dt " + "class=\"label\">Properties</dt> <dd> <p>This function is <a title=\"deterministic\" " + "class=\"termref\" href= \"#dt-deterministic\"><span class= \"arrow\">·</span>deterministic<span " + "class=\"arrow\">·</span></a>, <a title=\"context-independent\" class=\"termref\" href= " + "\"#dt-context-independent\"><span class= \"arrow\">·</span>context-independent<span class= " + "\"arrow\">·</span></a>, and <a title=\"focus-dependent\" class= \"termref\" " + "href=\"#dt-focus-independent\"><span class= \"arrow\">·</span>focus-independent<span class= " + "\"arrow\">·</span></a>.</p> </dd> <dt class=\"label\">Rules</dt> <dd> <p>The result is equivalent to" + " <code>xs:boolean(\"1\")</code>.</p> </dd> <dt class=\"label\">Examples</dt> <dd> <p>The expression " + "<code>fn:true()</code> returns <code>xs:boolean(1)</code>.</p> </dd> </dl>" + WRAPPER_END, "fn:<caret>true()"); } public void testLookupItemForBuiltInFunction() throws Exception { doTestGenerateLookupItemDoc(WRAPPER_START + "<dl><dt class=\"label\">Summary</dt> <dd> <p>Returns the <code>xs:boolean</code> value " + "<code>true</code>.</p> </dd> <dt class=\"label\">Signature</dt> <dd> <div class=\"exampleInner\"> " + "<div class=\"proto\"><code class= \"function\">fn:true</code>()<code class= \"as\"> as " + "</code><code class= \"return-type\">xs:boolean</code></div> </div> </dd> <dt " + "class=\"label\">Properties</dt> <dd> <p>This function is <a title=\"deterministic\" " + "class=\"termref\" href= \"#dt-deterministic\"><span class= \"arrow\">·</span>deterministic<span " + "class=\"arrow\">·</span></a>, <a title=\"context-independent\" class=\"termref\" href= " + "\"#dt-context-independent\"><span class= \"arrow\">·</span>context-independent<span class= " + "\"arrow\">·</span></a>, and <a title=\"focus-dependent\" class= \"termref\" " + "href=\"#dt-focus-independent\"><span class= \"arrow\">·</span>focus-independent<span class= " + "\"arrow\">·</span></a>.</p> </dd> <dt class=\"label\">Rules</dt> <dd> <p>The result is equivalent to" + " <code>xs:boolean(\"1\")</code>.</p> </dd> <dt class=\"label\">Examples</dt> <dd> <p>The expression " + "<code>fn:true()</code> returns <code>xs:boolean(1)</code>.</p> </dd> </dl>" + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "declare variable $v := fn:tru<caret>;", BuiltInFunctionSignature.class); } public void testBuiltInFunctionReferenceForXQuery31() throws Exception { XQuerySettings settings = XQuerySettings.getInstance(myFixture.getProject()); XQueryFlavour previous = settings.getFlavour(); settings.setFlavour(XQueryFlavour.STANDARD_31); try { doTestGenerateFunctionDoc(WRAPPER_START + "<dl> <dt class=\"label\">Summary</dt> <dd> <p>Returns the <code>xs:boolean</code> value " + "<code>true</code>. </p> </dd> <dt class=\"label\">Signature</dt> <dd> <div class=\"proto\">" + "<code class=\"function\">fn:true</code>()<code class=\"as\"> as </code>" + "<code class=\"return-type\">xs:boolean</code></div> </dd> <dt class=\"label\">Properties</dt>" + " <dd> <p>This function is <a title=\"deterministic\" class=\"termref\" " + "href=\"https://www.w3.org/TR/xpath-functions-31/#dt-deterministic\"><span class=\"arrow\">·" + "</span>deterministic<span class=\"arrow\">·</span></a>, <a title=\"context-independent\"" + " class=\"termref\" href=\"https://www.w3.org/TR/xpath-functions-31/#dt-context-independent\">" + "<span class=\"arrow\">·</span>context-independent<span class=\"arrow\">·</span></a>, and " + "<a title=\"focus-dependent\" class=\"termref\" " + "href=\"https://www.w3.org/TR/xpath-functions-31/#dt-focus-independent\"><span class=\"arrow\">·" + "</span>focus-independent<span class=\"arrow\">·</span></a>. </p> </dd> " + "<dt class=\"label\">Rules</dt> <dd> <p>The result is equivalent to <code>xs:boolean(\"1\")</code>. " + "</p> </dd> <dt class=\"label\">Examples</dt> <dd> <div class=\"example\"> " + "<p>The expression <code>fn:true()</code> returns <code>xs:boolean(1)</code>. </p> </div> </dd> </dl>" + WRAPPER_END, "fn:<caret>true()"); } finally { settings.setFlavour(previous); } } public void testLookupItemForBuiltInFunctionForXQuery31() throws Exception { XQuerySettings settings = XQuerySettings.getInstance(myFixture.getProject()); XQueryFlavour previous = settings.getFlavour(); settings.setFlavour(XQueryFlavour.STANDARD_31); try { doTestGenerateLookupItemDoc(WRAPPER_START + "<dl> <dt class=\"label\">Summary</dt> <dd> <p>Returns the <code>xs:boolean</code> value " + "<code>true</code>. </p> </dd> <dt class=\"label\">Signature</dt> <dd> <div class=\"proto\">" + "<code class=\"function\">fn:true</code>()<code class=\"as\"> as </code>" + "<code class=\"return-type\">xs:boolean</code></div> </dd> <dt class=\"label\">Properties</dt>" + " <dd> <p>This function is <a title=\"deterministic\" class=\"termref\" " + "href=\"https://www.w3.org/TR/xpath-functions-31/#dt-deterministic\"><span class=\"arrow\">·" + "</span>deterministic<span class=\"arrow\">·</span></a>, <a title=\"context-independent\"" + " class=\"termref\" href=\"https://www.w3.org/TR/xpath-functions-31/#dt-context-independent\">" + "<span class=\"arrow\">·</span>context-independent<span class=\"arrow\">·</span></a>, and " + "<a title=\"focus-dependent\" class=\"termref\" " + "href=\"https://www.w3.org/TR/xpath-functions-31/#dt-focus-independent\"><span class=\"arrow\">·" + "</span>focus-independent<span class=\"arrow\">·</span></a>. </p> </dd> " + "<dt class=\"label\">Rules</dt> <dd> <p>The result is equivalent to <code>xs:boolean(\"1\")</code>. " + "</p> </dd> <dt class=\"label\">Examples</dt> <dd> <div class=\"example\"> " + "<p>The expression <code>fn:true()</code> returns <code>xs:boolean(1)</code>. </p> </div> </dd> </dl>" + WRAPPER_END, "module namespace ns = '" + NAMESPACE + "';\n" + "declare variable $v := fn:tru<caret>;", BuiltInFunctionSignature.class); } finally { settings.setFlavour(previous); } } private void doTestGenerateVariableDoc(@NotNull String expected, @NotNull String text, FileData... otherFiles) throws Exception { doTestGenerateDoc(expected, text, XQueryVarName.class, otherFiles); } private void doTestGenerateFunctionDoc(@NotNull String expected, @NotNull String text, FileData... otherFiles) throws Exception { doTestGenerateDoc(expected, text, XQueryFunctionName.class, otherFiles); } private void doTestGenerateLookupItemDoc(@NotNull String expected, @NotNull String text, final Class documentationSourceClass) throws Exception { myFixture.configureByText(SOURCE_FILE_NAME, text); LookupElement[] lookupItems = myFixture.completeBasic(); LookupElement interestingElement = ContainerUtil.find(lookupItems, new Condition<LookupElement>() { @Override public boolean value(LookupElement lookupElement) { return documentationSourceClass.isAssignableFrom(lookupElement.getObject().getClass()); } }); assertNotNull(interestingElement); PsiElement elementAtCaret = myFixture.getFile().findElementAt(myFixture.getCaretOffset()); PsiElement sourceOfDocumentation = documentationProvider.getDocumentationElementForLookupItem(getPsiManager() , interestingElement.getObject(), elementAtCaret); assertEquals(expected, documentationProvider.generateDoc(sourceOfDocumentation, null)); } private void doTestGenerateDoc(@NotNull String expected, @NotNull String text, Class<? extends PsiElement> documentationSourceClass, FileData... otherFiles) throws Exception { for (FileData otherFile : otherFiles) { myFixture.configureByText(otherFile.name, otherFile.contents); } myFixture.configureByText(SOURCE_FILE_NAME, text); final int caretPosition = myFixture.getEditor().getCaretModel().getOffset(); PsiElement elementAtCaret = myFixture.getFile().findElementAt(caretPosition); PsiElement element = PsiTreeUtil.getParentOfType(elementAtCaret, documentationSourceClass); assertEquals(expected, documentationProvider.generateDoc(element, null)); } private class FileData { public String name; public String contents; public FileData(String name, String contents) { this.name = name; this.contents = contents; } } }