Skip to content

Commit f6d6f65

Browse files
committed
Library doc now includes type doc ie. library, resource, ...
1 parent 7371b35 commit f6d6f65

File tree

6 files changed

+60
-25
lines changed

6 files changed

+60
-25
lines changed

.vscode/launch.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,18 @@
3333
"port": "${input:portNumber}"
3434
}
3535
},
36+
{
37+
"name": "Python: Pytest Current File",
38+
"type": "python",
39+
"request": "launch",
40+
"module": "pytest",
41+
"args": [
42+
"${file}"
43+
],
44+
"console": "integratedTerminal",
45+
"justMyCode": false,
46+
"cwd": "${workspaceFolder}",
47+
},
3648
{
3749
"name": "Python: robotcode.debugger",
3850
"type": "python",

robotcode/language_server/robotframework/diagnostics/imports_manager.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,10 @@ async def check_file_changed(self, changes: List[FileEvent]) -> Optional[FileCha
264264
return None
265265

266266
def __close_document(self, document: TextDocument) -> None:
267-
asyncio.run_coroutine_threadsafe(self.parent.parent_protocol.documents.close_document(document), self._loop)
267+
if self._loop.is_running():
268+
asyncio.run_coroutine_threadsafe(self.parent.parent_protocol.documents.close_document(document), self._loop)
269+
else:
270+
del document
268271

269272
async def _update(self) -> None:
270273
self._document = await self._get_document_coroutine()

robotcode/language_server/robotframework/diagnostics/library_doc.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ class KeywordDoc(Model):
241241
doc_format: str = DEFAULT_DOC_FORMAT
242242
is_error_handler: bool = False
243243
error_handler_message: Optional[str] = None
244+
is_initializer: bool = False
244245

245246
@validator("doc_format")
246247
def doc_format_validator(cls, v: str) -> str:
@@ -269,20 +270,24 @@ def range(self) -> Range:
269270
),
270271
)
271272

272-
def to_markdown(self, add_signature: bool = True) -> str:
273+
def to_markdown(self, add_signature: bool = True, header_level: int = 0) -> str:
273274
if self.doc_format == DEFAULT_DOC_FORMAT:
274-
return MarkDownFormatter().format(self.get_full_doc(add_signature))
275+
return MarkDownFormatter().format(self.get_full_doc(add_signature=add_signature, header_level=header_level))
275276

276277
return self.doc
277278

278-
def get_full_doc(self, add_signature: bool = True) -> str:
279+
def get_full_doc(self, add_signature: bool = True, header_level: int = 0) -> str:
279280
if self.doc_format == DEFAULT_DOC_FORMAT:
280281
result = ""
281282

282283
if add_signature:
283-
result += f"\n\n=== {self.name} ===\n"
284+
result += (
285+
f"\n\n={'='*header_level} "
286+
f"{'Library' if self.is_initializer else 'Keyword'} *{self.name}* "
287+
f"={'='*header_level}\n"
288+
)
284289
if self.args:
285-
result += "\n==== Arguments: ====\n"
290+
result += f"\n=={'='*header_level} Arguments: =={'='*header_level}\n"
286291
for a in self.args:
287292
result += f"\n| {str(a)}"
288293

@@ -293,7 +298,7 @@ def get_full_doc(self, add_signature: bool = True) -> str:
293298
if result:
294299
result += "\n\n"
295300

296-
result += "\n==== Documentation: ====\n\n"
301+
result += f"\n=={'='*header_level} Documentation: =={'='*header_level}\n\n"
297302

298303
result += self.doc
299304

@@ -493,7 +498,7 @@ def repl(m: re.Match) -> str: # type: ignore
493498
def get_full_doc(self, only_doc: bool = True) -> str:
494499
if self.doc_format == DEFAULT_DOC_FORMAT:
495500

496-
result = f"= {self.name} =\n"
501+
result = f"= {(self.type[0].upper()+self.type[1:].lower()) if self.type else 'Unknown'} *{self.name}* =\n"
497502

498503
if self.version:
499504
result += f"\n| **Library Version:** | {self.version} |"
@@ -536,7 +541,7 @@ def get_full_doc(self, only_doc: bool = True) -> str:
536541
result += "\n---\n"
537542
first = False
538543

539-
result += "\n" + kw.get_full_doc()
544+
result += "\n" + kw.get_full_doc(header_level=2)
540545

541546
return self._process_inline_links(result)
542547

@@ -1031,6 +1036,7 @@ def get_test_library(
10311036
source=lib.source if lib is not None else source,
10321037
module_spec=module_spec,
10331038
python_path=sys.path,
1039+
type="LIBRARY",
10341040
)
10351041

10361042
if lib is not None:
@@ -1056,6 +1062,7 @@ def get_test_library(
10561062
libname=kw[1].libname,
10571063
longname=kw[1].longname,
10581064
doc_format=str(lib.doc_format) or DEFAULT_DOC_FORMAT,
1065+
is_initializer=True,
10591066
)
10601067
for kw in [
10611068
(KeywordDocBuilder().build_keyword(k), k) for k in [KeywordWrapper(lib.init, source)]

tests/robotcode/language_server/robotframework/parts/data/hover.robot

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
*** Settings ***
22
Library Collections
3-
# ^^^^^^^^^^^ library import by module name: re.match(r'.*Collections.*', value)
4-
Variables ${CURDIR}/../myvariables.py
3+
# ^^^^^^^^^^^ library import by module name: re.match(r'## Library \*Collections\*.*', value)
4+
Library ${CURDIR}/lib/myvariables.py
5+
# ^^^^^^^^^^^^^^ library import by path name: re.match(r'## Library \*myvariables.*', value)
6+
# TODO ^^^^^^^^^ variable in library name: value == '(builtin variable) ${CURDIR}'
7+
Variables ${CURDIR}/lib/myvariables.py
8+
Resource ${CURDIR}/resources/firstresource.resource
9+
# ^^^^^^^^^^^^^^ library import by path name: re.match(r'## Resource \*firstresource.*', value)
510

611
*** Variables ***
712
${A VAR} i'm a var
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*** Keywords ***
2+
3+
do something in a resource
4+
Log done something

tests/robotcode/language_server/robotframework/parts/test_hover.py

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import asyncio
22
import re
33
from pathlib import Path
4-
from typing import Any, AsyncGenerator, Generator, Tuple, Union, cast
4+
from typing import Any, AsyncGenerator, Generator, Tuple, cast
55

66
import pytest
77

@@ -77,7 +77,9 @@ async def test_document(request: Any) -> AsyncGenerator[TextDocument, None]:
7777
data_path = Path(request.param)
7878
data = data_path.read_text()
7979

80-
document = TextDocument(document_uri=data_path.as_uri(), language_id="robotframework", version=1, text=data)
80+
document = TextDocument(
81+
document_uri=data_path.absolute().as_uri(), language_id="robotframework", version=1, text=data
82+
)
8183
try:
8284
yield document
8385
finally:
@@ -113,7 +115,7 @@ def generate_tests_from_doc(path: str) -> Generator[Tuple[str, str, int, int, st
113115

114116
@pytest.mark.parametrize(
115117
("test_document", "name", "line", "character", "expression"),
116-
generate_tests_from_doc(Path(Path(__file__).parent, "data/hover.robot")),
118+
generate_tests_from_doc(str(Path(Path(__file__).parent, "data/hover.robot").relative_to(Path(".").absolute()))),
117119
indirect=["test_document"],
118120
)
119121
@pytest.mark.asyncio
@@ -129,15 +131,17 @@ async def test_hover(
129131
protocol.hover, test_document, Position(line=line, character=character)
130132
)
131133

132-
assert eval(
133-
expression,
134-
{"re": re},
135-
{
136-
"result": result,
137-
"value": result.contents.value
138-
if result is not None and isinstance(result.contents, MarkupContent)
139-
else None,
140-
"line": line,
141-
"character": character,
142-
},
134+
assert bool(
135+
eval(
136+
expression,
137+
{"re": re},
138+
{
139+
"result": result,
140+
"value": result.contents.value
141+
if result is not None and isinstance(result.contents, MarkupContent)
142+
else None,
143+
"line": line,
144+
"character": character,
145+
},
146+
)
143147
), expression

0 commit comments

Comments
 (0)