2
2
{-# LANGUAGE ScopedTypeVariables #-}
3
3
module Completion (tests ) where
4
4
5
+ import Control.Monad
5
6
import Control.Lens hiding ((.=) )
6
7
import Data.Aeson (object , (.=) )
7
8
import Data.Foldable (find )
@@ -11,6 +12,15 @@ import Language.LSP.Types.Lens hiding (applyEdit)
11
12
import Test.Hls
12
13
import Test.Hls.Command
13
14
15
+ getResolvedCompletions :: TextDocumentIdentifier -> Position -> Session [CompletionItem ]
16
+ getResolvedCompletions doc pos = do
17
+ xs <- getCompletions doc pos
18
+ forM xs $ \ item -> do
19
+ rsp <- request SCompletionItemResolve item
20
+ case rsp ^. result of
21
+ Left err -> liftIO $ assertFailure (" completionItem/resolve failed with: " <> show err)
22
+ Right x -> pure x
23
+
14
24
tests :: TestTree
15
25
tests = testGroup " completions" [
16
26
testCase " works" $ runSession hlsCommand fullCaps " test/testdata/completion" $ do
@@ -19,34 +29,29 @@ tests = testGroup "completions" [
19
29
let te = TextEdit (Range (Position 5 7 ) (Position 5 24 )) " put"
20
30
_ <- applyEdit doc te
21
31
22
- compls <- getCompletions doc (Position 5 9 )
32
+ compls <- getResolvedCompletions doc (Position 5 9 )
23
33
item <- getCompletionByLabel " putStrLn" compls
24
34
liftIO $ do
25
35
item ^. label @?= " putStrLn"
26
36
item ^. kind @?= Just CiFunction
27
- item ^. detail @?= Just " :: String -> IO ()"
37
+ item ^. detail @?= Just " :: String -> IO ()\n from Prelude "
28
38
item ^. insertTextFormat @?= Just Snippet
29
- item ^. insertText @?= Just " putStrLn ${1:String} "
39
+ item ^. insertText @?= Just " putStrLn"
30
40
31
- , ignoreTestBecause " no support for itemCompletion/resolve requests"
32
- $ testCase " itemCompletion/resolve works" $ runSession hlsCommand fullCaps " test/testdata/completion" $ do
41
+ , testCase " itemCompletion/resolve works" $ runSession hlsCommand fullCaps " test/testdata/completion" $ do
33
42
doc <- openDoc " Completion.hs" " haskell"
34
43
35
44
let te = TextEdit (Range (Position 5 7 ) (Position 5 24 )) " put"
36
45
_ <- applyEdit doc te
37
46
38
- compls <- getCompletions doc (Position 5 9 )
47
+ compls <- getResolvedCompletions doc (Position 5 9 )
39
48
item <- getCompletionByLabel " putStrLn" compls
40
- resolvedRes <- request SCompletionItemResolve item
41
- let eResolved = resolvedRes ^. result
42
- case eResolved of
43
- Right resolved -> liftIO $ do
44
- resolved ^. label @?= " putStrLn"
45
- resolved ^. kind @?= Just CiFunction
46
- resolved ^. detail @?= Just " String -> IO ()\n Prelude"
47
- resolved ^. insertTextFormat @?= Just Snippet
48
- resolved ^. insertText @?= Just " putStrLn ${1:String}"
49
- _ -> error $ " Unexpected resolved value: " ++ show eResolved
49
+ liftIO $ do
50
+ item ^. label @?= " putStrLn"
51
+ item ^. kind @?= Just CiFunction
52
+ item ^. detail @?= Just " :: String -> IO ()\n from Prelude"
53
+ item ^. insertTextFormat @?= Just Snippet
54
+ item ^. insertText @?= Just " putStrLn"
50
55
51
56
, testCase " completes imports" $ runSession (hlsCommand <> " --test" ) fullCaps " test/testdata/completion" $ do
52
57
doc <- openDoc " Completion.hs" " haskell"
@@ -56,7 +61,7 @@ tests = testGroup "completions" [
56
61
let te = TextEdit (Range (Position 1 17 ) (Position 1 26 )) " Data.M"
57
62
_ <- applyEdit doc te
58
63
59
- compls <- getCompletions doc (Position 1 23 )
64
+ compls <- getResolvedCompletions doc (Position 1 23 )
60
65
item <- getCompletionByLabel " Maybe" compls
61
66
liftIO $ do
62
67
item ^. label @?= " Maybe"
@@ -71,7 +76,7 @@ tests = testGroup "completions" [
71
76
let te = TextEdit (Range (Position 2 17 ) (Position 2 25 )) " Data.L"
72
77
_ <- applyEdit doc te
73
78
74
- compls <- getCompletions doc (Position 2 24 )
79
+ compls <- getResolvedCompletions doc (Position 2 24 )
75
80
item <- getCompletionByLabel " List" compls
76
81
liftIO $ do
77
82
item ^. label @?= " List"
@@ -81,7 +86,7 @@ tests = testGroup "completions" [
81
86
, testCase " completes with no prefix" $ runSession hlsCommand fullCaps " test/testdata/completion" $ do
82
87
doc <- openDoc " Completion.hs" " haskell"
83
88
84
- compls <- getCompletions doc (Position 5 7 )
89
+ compls <- getResolvedCompletions doc (Position 5 7 )
85
90
liftIO $ assertBool " Expected completions" $ not $ null compls
86
91
87
92
, expectFailIfBeforeGhc92 " record dot syntax is introduced in GHC 9.2"
@@ -92,7 +97,7 @@ tests = testGroup "completions" [
92
97
let te = TextEdit (Range (Position 25 0 ) (Position 25 5 )) " z = x.a"
93
98
_ <- applyEdit doc te
94
99
95
- compls <- getCompletions doc (Position 25 6 )
100
+ compls <- getResolvedCompletions doc (Position 25 6 )
96
101
item <- getCompletionByLabel " a" compls
97
102
98
103
liftIO $ do
@@ -103,7 +108,7 @@ tests = testGroup "completions" [
103
108
let te = TextEdit (Range (Position 27 0 ) (Position 27 8 )) " z2 = x.c.z"
104
109
_ <- applyEdit doc te
105
110
106
- compls <- getCompletions doc (Position 27 9 )
111
+ compls <- getResolvedCompletions doc (Position 27 9 )
107
112
item <- getCompletionByLabel " z" compls
108
113
109
114
liftIO $ do
@@ -117,7 +122,7 @@ tests = testGroup "completions" [
117
122
let te = TextEdit (Range (Position 5 0 ) (Position 5 2 )) " acc"
118
123
_ <- applyEdit doc te
119
124
120
- compls <- getCompletions doc (Position 5 4 )
125
+ compls <- getResolvedCompletions doc (Position 5 4 )
121
126
item <- getCompletionByLabel " accessor" compls
122
127
liftIO $ do
123
128
item ^. label @?= " accessor"
@@ -127,25 +132,25 @@ tests = testGroup "completions" [
127
132
128
133
let te = TextEdit (Range (Position 5 7 ) (Position 5 9 )) " id"
129
134
_ <- applyEdit doc te
130
- compls <- getCompletions doc (Position 5 9 )
135
+ compls <- getResolvedCompletions doc (Position 5 9 )
131
136
item <- getCompletionByLabel " id" compls
132
137
liftIO $ do
133
- item ^. detail @?= Just " :: a -> a"
138
+ item ^. detail @?= Just " :: a -> a\n from Prelude "
134
139
135
140
, testCase " have implicit foralls with multiple type variables" $ runSession hlsCommand fullCaps " test/testdata/completion" $ do
136
141
doc <- openDoc " Completion.hs" " haskell"
137
142
138
143
let te = TextEdit (Range (Position 5 7 ) (Position 5 24 )) " flip"
139
144
_ <- applyEdit doc te
140
- compls <- getCompletions doc (Position 5 11 )
145
+ compls <- getResolvedCompletions doc (Position 5 11 )
141
146
item <- getCompletionByLabel " flip" compls
142
147
liftIO $
143
- item ^. detail @?= Just " :: (a -> b -> c) -> b -> a -> c"
148
+ item ^. detail @?= Just " :: (a -> b -> c) -> b -> a -> c\n from Prelude "
144
149
145
150
, testCase " maxCompletions" $ runSession hlsCommand fullCaps " test/testdata/completion" $ do
146
151
doc <- openDoc " Completion.hs" " haskell"
147
152
148
- compls <- getCompletions doc (Position 5 7 )
153
+ compls <- getResolvedCompletions doc (Position 5 7 )
149
154
liftIO $ length compls @?= maxCompletions def
150
155
151
156
, testCase " import function completions" $ runSession hlsCommand fullCaps " test/testdata/completion" $ do
@@ -154,7 +159,7 @@ tests = testGroup "completions" [
154
159
let te = TextEdit (Range (Position 0 30 ) (Position 0 41 )) " A"
155
160
_ <- applyEdit doc te
156
161
157
- compls <- getCompletions doc (Position 0 31 )
162
+ compls <- getResolvedCompletions doc (Position 0 31 )
158
163
item <- getCompletionByLabel " Alternative" compls
159
164
liftIO $ do
160
165
item ^. label @?= " Alternative"
@@ -167,7 +172,7 @@ tests = testGroup "completions" [
167
172
let te = TextEdit (Range (Position 0 39 ) (Position 0 39 )) " , l"
168
173
_ <- applyEdit doc te
169
174
170
- compls <- getCompletions doc (Position 0 42 )
175
+ compls <- getResolvedCompletions doc (Position 0 42 )
171
176
item <- getCompletionByLabel " liftA" compls
172
177
liftIO $ do
173
178
item ^. label @?= " liftA"
@@ -177,7 +182,7 @@ tests = testGroup "completions" [
177
182
, testCase " completes locally defined associated type family" $ runSession hlsCommand fullCaps " test/testdata/completion" $ do
178
183
doc <- openDoc " AssociatedTypeFamily.hs" " haskell"
179
184
180
- compls <- getCompletions doc (Position 5 20 )
185
+ compls <- getResolvedCompletions doc (Position 5 20 )
181
186
item <- getCompletionByLabel " Fam" compls
182
187
liftIO $ do
183
188
item ^. label @?= " Fam"
@@ -195,7 +200,7 @@ snippetTests = testGroup "snippets" [
195
200
let te = TextEdit (Range (Position 5 7 ) (Position 5 24 )) " Nothing"
196
201
_ <- applyEdit doc te
197
202
198
- compls <- getCompletions doc (Position 5 14 )
203
+ compls <- getResolvedCompletions doc (Position 5 14 )
199
204
item <- getCompletionByLabel " Nothing" compls
200
205
liftIO $ do
201
206
item ^. insertTextFormat @?= Just Snippet
@@ -207,35 +212,35 @@ snippetTests = testGroup "snippets" [
207
212
let te = TextEdit (Range (Position 5 7 ) (Position 5 24 )) " fold"
208
213
_ <- applyEdit doc te
209
214
210
- compls <- getCompletions doc (Position 5 11 )
215
+ compls <- getResolvedCompletions doc (Position 5 11 )
211
216
item <- getCompletionByLabel " foldl" compls
212
217
liftIO $ do
213
218
item ^. label @?= " foldl"
214
219
item ^. kind @?= Just CiFunction
215
220
item ^. insertTextFormat @?= Just Snippet
216
- item ^. insertText @?= Just " foldl ${1:(b -> a -> b)} ${2:b} ${3:(t a)} "
221
+ item ^. insertText @?= Just " foldl"
217
222
218
223
, testCase " work for complex types" $ runSession hlsCommand fullCaps " test/testdata/completion" $ do
219
224
doc <- openDoc " Completion.hs" " haskell"
220
225
221
226
let te = TextEdit (Range (Position 5 7 ) (Position 5 24 )) " mapM"
222
227
_ <- applyEdit doc te
223
228
224
- compls <- getCompletions doc (Position 5 11 )
229
+ compls <- getResolvedCompletions doc (Position 5 11 )
225
230
item <- getCompletionByLabel " mapM" compls
226
231
liftIO $ do
227
232
item ^. label @?= " mapM"
228
233
item ^. kind @?= Just CiFunction
229
234
item ^. insertTextFormat @?= Just Snippet
230
- item ^. insertText @?= Just " mapM ${1:(a -> m b)} ${2:(t a)} "
235
+ item ^. insertText @?= Just " mapM"
231
236
232
237
, testCase " work for infix functions" $ runSession hlsCommand fullCaps " test/testdata/completion" $ do
233
238
doc <- openDoc " Completion.hs" " haskell"
234
239
235
240
let te = TextEdit (Range (Position 5 7 ) (Position 5 24 )) " even `filte"
236
241
_ <- applyEdit doc te
237
242
238
- compls <- getCompletions doc (Position 5 18 )
243
+ compls <- getResolvedCompletions doc (Position 5 18 )
239
244
item <- getCompletionByLabel " filter" compls
240
245
liftIO $ do
241
246
item ^. label @?= " filter"
@@ -249,7 +254,7 @@ snippetTests = testGroup "snippets" [
249
254
let te = TextEdit (Range (Position 5 7 ) (Position 5 24 )) " even `filte`"
250
255
_ <- applyEdit doc te
251
256
252
- compls <- getCompletions doc (Position 5 18 )
257
+ compls <- getResolvedCompletions doc (Position 5 18 )
253
258
item <- getCompletionByLabel " filter" compls
254
259
liftIO $ do
255
260
item ^. label @?= " filter"
@@ -263,7 +268,7 @@ snippetTests = testGroup "snippets" [
263
268
let te = TextEdit (Range (Position 5 7 ) (Position 5 24 )) " \"\" `Data.List.interspe"
264
269
_ <- applyEdit doc te
265
270
266
- compls <- getCompletions doc (Position 5 29 )
271
+ compls <- getResolvedCompletions doc (Position 5 29 )
267
272
item <- getCompletionByLabel " intersperse" compls
268
273
liftIO $ do
269
274
item ^. label @?= " intersperse"
@@ -277,7 +282,7 @@ snippetTests = testGroup "snippets" [
277
282
let te = TextEdit (Range (Position 5 7 ) (Position 5 24 )) " \"\" `Data.List.interspe`"
278
283
_ <- applyEdit doc te
279
284
280
- compls <- getCompletions doc (Position 5 29 )
285
+ compls <- getResolvedCompletions doc (Position 5 29 )
281
286
item <- getCompletionByLabel " intersperse" compls
282
287
liftIO $ do
283
288
item ^. label @?= " intersperse"
@@ -304,7 +309,7 @@ snippetTests = testGroup "snippets" [
304
309
let te = TextEdit (Range (Position 1 0 ) (Position 1 2 )) " MkF"
305
310
_ <- applyEdit doc te
306
311
307
- compls <- getCompletions doc (Position 1 6 )
312
+ compls <- getResolvedCompletions doc (Position 1 6 )
308
313
item <- case find (\ c -> (c ^. label == " MkFoo" ) && maybe False (" MkFoo {" `T.isPrefixOf` ) (c ^. insertText)) compls of
309
314
Just c -> pure c
310
315
Nothing -> liftIO . assertFailure $ " Completion with label 'MkFoo' and insertText starting with 'MkFoo {' not found among " <> show compls
@@ -317,7 +322,7 @@ snippetTests = testGroup "snippets" [
317
322
let te = TextEdit (Range (Position 5 7 ) (Position 5 24 )) " fold"
318
323
_ <- applyEdit doc te
319
324
320
- compls <- getCompletions doc (Position 5 11 )
325
+ compls <- getResolvedCompletions doc (Position 5 11 )
321
326
item <- getCompletionByLabel " foldl" compls
322
327
liftIO $ do
323
328
item ^. label @?= " foldl"
@@ -342,23 +347,23 @@ contextTests = testGroup "contexts" [
342
347
testCase " only provides type suggestions" $ runSession hlsCommand fullCaps " test/testdata/completion" $ do
343
348
doc <- openDoc " Context.hs" " haskell"
344
349
345
- compls <- getCompletions doc (Position 2 17 )
350
+ compls <- getResolvedCompletions doc (Position 2 17 )
346
351
liftIO $ do
347
352
compls `shouldContainCompl` " Integer"
348
353
compls `shouldNotContainCompl` " interact"
349
354
350
355
, testCase " only provides value suggestions" $ runSession hlsCommand fullCaps " test/testdata/completion" $ do
351
356
doc <- openDoc " Context.hs" " haskell"
352
357
353
- compls <- getCompletions doc (Position 3 10 )
358
+ compls <- getResolvedCompletions doc (Position 3 10 )
354
359
liftIO $ do
355
360
compls `shouldContainCompl` " abs"
356
361
compls `shouldNotContainCompl` " Applicative"
357
362
358
363
, testCase " completes qualified type suggestions" $ runSession hlsCommand fullCaps " test/testdata/completion" $ do
359
364
doc <- openDoc " Context.hs" " haskell"
360
365
361
- compls <- getCompletions doc (Position 2 26 )
366
+ compls <- getResolvedCompletions doc (Position 2 26 )
362
367
liftIO $ do
363
368
compls `shouldNotContainCompl` " forkOn"
364
369
compls `shouldContainCompl` " MVar"
0 commit comments