|
24 | 24 | Token, |
25 | 25 | get_nodes_at_position, |
26 | 26 | get_tokens_at_position, |
| 27 | + range_from_node, |
27 | 28 | range_from_token, |
28 | 29 | range_from_token_or_node, |
29 | 30 | tokenize_variables, |
30 | 31 | ) |
| 32 | +from ..utils.markdownformatter import MarkDownFormatter |
31 | 33 |
|
32 | 34 | if TYPE_CHECKING: |
33 | 35 | from ..protocol import RobotLanguageServerProtocol |
@@ -72,13 +74,16 @@ async def run() -> Optional[Hover]: |
72 | 74 | if not result_nodes: |
73 | 75 | return None |
74 | 76 |
|
75 | | - result_node = result_nodes[-1] |
| 77 | + while result_nodes: |
| 78 | + result_node = result_nodes[-1] |
76 | 79 |
|
77 | | - method = self._find_method(type(result_node)) |
78 | | - if method is not None: |
79 | | - result = await method(result_node, document, position) |
80 | | - if result is not None: |
81 | | - return result |
| 80 | + method = self._find_method(type(result_node)) |
| 81 | + if method is not None: |
| 82 | + result = await method(result_node, document, position) |
| 83 | + if result is not None: |
| 84 | + return result |
| 85 | + |
| 86 | + result_nodes = result_nodes[:-1] |
82 | 87 |
|
83 | 88 | return await self._hover_default(result_nodes, document, position) |
84 | 89 |
|
@@ -306,3 +311,40 @@ async def hover_ResourceImport( # noqa: N802 |
306 | 311 | except BaseException: |
307 | 312 | pass |
308 | 313 | return None |
| 314 | + |
| 315 | + async def hover_TestCase( # noqa: N802 |
| 316 | + self, node: ast.AST, document: TextDocument, position: Position |
| 317 | + ) -> Optional[Hover]: |
| 318 | + from robot.parsing.lexer.tokens import Token as RobotToken |
| 319 | + from robot.parsing.model.blocks import TestCase |
| 320 | + from robot.parsing.model.statements import Documentation, Tags |
| 321 | + |
| 322 | + test_case = cast(TestCase, node) |
| 323 | + |
| 324 | + if not position.is_in_range(range_from_node(test_case.header)): |
| 325 | + return None |
| 326 | + |
| 327 | + name_token = cast(RobotToken, test_case.header.get_token(RobotToken.TESTCASE_NAME)) |
| 328 | + if name_token is None: |
| 329 | + return None |
| 330 | + |
| 331 | + doc = next((e for e in test_case.body if isinstance(e, Documentation)), None) |
| 332 | + tags = next((e for e in test_case.body if isinstance(e, Tags)), None) |
| 333 | + |
| 334 | + txt = f"= Test Case *{test_case.name}* =\n" |
| 335 | + |
| 336 | + if doc is not None: |
| 337 | + txt += "\n== Documentation ==\n" |
| 338 | + txt += f"\n{doc.value}\n" |
| 339 | + |
| 340 | + if tags is not None: |
| 341 | + txt += "\n*Tags*: " |
| 342 | + txt += f"{', '.join(tags.values)}\n" |
| 343 | + |
| 344 | + return Hover( |
| 345 | + contents=MarkupContent( |
| 346 | + kind=MarkupKind.MARKDOWN, |
| 347 | + value=MarkDownFormatter().format(txt), |
| 348 | + ), |
| 349 | + range=range_from_token_or_node(test_case, name_token), |
| 350 | + ) |
0 commit comments