1
+ import asyncio
2
+ import re
3
+ from os import PathLike
1
4
from pathlib import Path
2
- from typing import AsyncGenerator , cast
5
+ from typing import Any , AsyncGenerator , Generator , Tuple , Union , cast
3
6
4
7
import pytest
5
8
13
16
MarkupContent ,
14
17
MarkupKind ,
15
18
Position ,
16
- Range ,
17
19
TextDocumentClientCapabilities ,
18
20
WorkspaceFolder ,
19
21
)
27
29
from robotcode .language_server .robotframework .server import RobotLanguageServer
28
30
29
31
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" )
31
40
async def protocol () -> AsyncGenerator [RobotLanguageServerProtocol , None ]:
32
41
root_path = Path ().resolve ()
33
42
server = RobotLanguageServer ()
@@ -64,9 +73,9 @@ async def protocol() -> AsyncGenerator[RobotLanguageServerProtocol, None]:
64
73
server .close ()
65
74
66
75
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 )
70
79
data = data_path .read_text ()
71
80
72
81
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]:
76
85
del document
77
86
78
87
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>.+)" )
91
89
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" )
98
90
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 )
99
95
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
111
111
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
114
115
115
116
116
117
@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" ],
127
121
)
128
122
@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 ,
131
130
) -> 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