1+ import asyncio
2+ import re
3+ from os import PathLike
14from pathlib import Path
2- from typing import AsyncGenerator , cast
5+ from typing import Any , AsyncGenerator , Generator , Tuple , Union , cast
36
47import pytest
58
1316 MarkupContent ,
1417 MarkupKind ,
1518 Position ,
16- Range ,
1719 TextDocumentClientCapabilities ,
1820 WorkspaceFolder ,
1921)
2729from robotcode .language_server .robotframework .server import RobotLanguageServer
2830
2931
30- @pytest .fixture
32+ @pytest .fixture (scope = "module" )
33+ def event_loop () -> Generator [asyncio .AbstractEventLoop , None , None ]:
34+ loop = asyncio .new_event_loop ()
35+ yield loop
36+ loop .close ()
37+
38+
39+ @pytest .fixture (scope = "module" )
3140async def protocol () -> AsyncGenerator [RobotLanguageServerProtocol , None ]:
3241 root_path = Path ().resolve ()
3342 server = RobotLanguageServer ()
@@ -64,9 +73,9 @@ async def protocol() -> AsyncGenerator[RobotLanguageServerProtocol, None]:
6473 server .close ()
6574
6675
67- @pytest .fixture
68- async def test_document () -> AsyncGenerator [TextDocument , None ]:
69- data_path = Path (Path ( __file__ ). parent , "data/hover.robot" )
76+ @pytest .fixture ( scope = "module" )
77+ async def test_document (request : Any ) -> AsyncGenerator [TextDocument , None ]:
78+ data_path = Path (request . param )
7079 data = data_path .read_text ()
7180
7281 document = TextDocument (document_uri = data_path .as_uri (), language_id = "robotframework" , version = 1 , text = data )
@@ -76,61 +85,62 @@ async def test_document() -> AsyncGenerator[TextDocument, None]:
7685 del document
7786
7887
79- @pytest .mark .parametrize (
80- ("position" ,),
81- [
82- (Position (line = 9 , character = 4 ),),
83- (Position (line = 9 , character = 5 ),),
84- (Position (line = 9 , character = 6 ),),
85- ],
86- )
87- @pytest .mark .asyncio
88- async def test_hover_should_find_simple_keyword (
89- protocol : RobotLanguageServerProtocol , test_document : TextDocument , position : Position
90- ) -> None :
88+ TEST_EXPRESSION_LINE = re .compile (r"^\#\s*(?P<position>\^+)\s*(?P<name>[^:]+)\s*:\s*(?P<expression>.+)" )
9189
92- result = await protocol ._robot_hover .collect (protocol .hover , test_document , position )
93- assert result
94- assert result .range == Range (start = Position (line = 9 , character = 4 ), end = Position (line = 9 , character = 7 ))
95- assert isinstance (result .contents , MarkupContent )
96- assert result .contents .kind == MarkupKind .MARKDOWN
97- assert result .contents .value .startswith ("#### Log" )
9890
91+ def generate_tests_from_doc (
92+ path : Union [PathLike [str ], str ]
93+ ) -> Generator [Tuple [Union [PathLike [str ], str ], str , int , int , str ], None , None ]:
94+ file = Path (path )
9995
100- @pytest .mark .parametrize (
101- ("position" ,),
102- [
103- (Position (line = 9 , character = 3 ),),
104- (Position (line = 9 , character = 7 ),),
105- ],
106- )
107- @pytest .mark .asyncio
108- async def test_hover_should_not_find_simple_keyword_on_boundaries (
109- protocol : RobotLanguageServerProtocol , test_document : TextDocument , position : Position
110- ) -> None :
96+ current_line = 0
97+ for line , text in enumerate (file .read_text ().splitlines ()):
98+
99+ match = TEST_EXPRESSION_LINE .match (text )
100+ if match :
101+ name = match .group ("name" ).strip ()
102+ start , end = match .span ("position" )
103+ expression = match .group ("expression" ).strip ()
104+ if name and expression :
105+ if end - start == 1 :
106+ yield path , name , current_line , start , expression
107+ else :
108+ yield path , name , current_line , start , expression
109+ if end - start > 2 :
110+ yield path , name , current_line , int (start + (end - start ) / 2 ), expression
111111
112- result = await protocol ._robot_hover .collect (protocol .hover , test_document , position )
113- assert result is None
112+ yield path , name , current_line , end - 1 , expression
113+ else :
114+ current_line = line
114115
115116
116117@pytest .mark .parametrize (
117- ("position" , "variable" ),
118- [
119- (Position (line = 4 , character = 2 ), "(Variable) ${A VAR}" ),
120- (Position (line = 9 , character = 18 ), "(Variable) ${A VAR}" ),
121- (Position (line = 5 , character = 7 ), "(Variable) &{A DICT}" ),
122- (Position (line = 10 , character = 36 ), "(Variable) &{A DICT}" ),
123- (Position (line = 11 , character = 13 ), "(Variable) ${key}" ), # FOR Variable
124- (Position (line = 11 , character = 24 ), "(Variable) ${value}" ), # FOR Variable
125- (Position (line = 14 , character = 14 ), "(Command Line Variable) ${CMD_VAR}" ), # CMD LINE Variable
126- ],
118+ ("test_document" , "name" , "line" , "character" , "expression" ),
119+ generate_tests_from_doc (Path (Path (__file__ ).parent , "data/hover.robot" )),
120+ indirect = ["test_document" ],
127121)
128122@pytest .mark .asyncio
129- async def test_hover_should_find_variable (
130- protocol : RobotLanguageServerProtocol , test_document : TextDocument , position : Position , variable : str
123+ async def test_hover (
124+ protocol : RobotLanguageServerProtocol ,
125+ test_document : TextDocument ,
126+ name : str ,
127+ line : int ,
128+ character : int ,
129+ expression : str ,
131130) -> None :
132-
133- result = await protocol ._robot_hover .collect (protocol .hover , test_document , position )
134- assert result
135- assert isinstance (result .contents , MarkupContent )
136- assert result .contents .value == variable
131+ result = await protocol ._robot_hover .collect (
132+ protocol .hover , test_document , Position (line = line , character = character )
133+ )
134+
135+ assert 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+ ), expression
0 commit comments