forked from haskell/haskell-language-server
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMain.hs
141 lines (125 loc) · 5.78 KB
/
Main.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Main (main) where
import Data.Foldable (find)
import Data.Text (Text)
import qualified Ide.Plugin.QualifyImportedNames as QualifyImportedNames
import System.FilePath ((</>))
import Test.Hls (CodeAction (CodeAction, _title),
Command, MonadIO (liftIO),
PluginTestDescriptor,
Position (Position),
Range (Range), Session,
TestName, TestTree,
TextDocumentIdentifier,
assertBool, assertFailure,
def, defaultTestRunner,
executeCodeAction,
getCodeActions,
goldenWithHaskellDoc,
mkPluginTestDescriptor',
openDoc, runSessionWithServer,
testCase, testGroup,
type (|?) (InR))
import Prelude
-- 1's based
data Point = Point {
line :: !Int,
column :: !Int
}
makePoint :: Int -> Int -> Point
makePoint line column
| line >= 1 && column >= 1 = Point line column
| otherwise = error "Line or column is less than 1."
isEmpty :: Foldable f => f a -> Bool
isEmpty = null
makeCodeActionNotFoundAtString :: Point -> String
makeCodeActionNotFoundAtString Point {..} =
"CodeAction not found at line: " <> show line <> ", column: " <> show column
makeCodeActionFoundAtString :: Point -> String
makeCodeActionFoundAtString Point {..} =
"CodeAction found at line: " <> show line <> ", column: " <> show column
main :: IO ()
main = defaultTestRunner $ testGroup "Qualify Imported Names"
[
testCase "No CodeAction when not at import" $
runSessionWithServer def pluginDescriptor testDataDir $ do
let point = makePoint 1 1
document <- openDoc "NoImport.hs" "haskell"
actions <- getCodeActions document $ pointToRange point
liftIO $ assertBool (makeCodeActionFoundAtString point) (isEmpty actions)
, testCase "No CodeAction when import is qualified" $
runSessionWithServer def pluginDescriptor testDataDir $ do
let point = makePoint 3 1
document <- openDoc "QualifiedImport.hs" "haskell"
actions <- getCodeActions document $ pointToRange point
liftIO $ assertBool (makeCodeActionFoundAtString point) (isEmpty actions)
, codeActionGoldenTest
"CodeAction qualifies names with alias if imported module is aliased"
"AliasedImport"
(makePoint 3 1)
, codeActionGoldenTest
"CodeAction qualifies names with module name if imported module is not aliased"
"UnaliasedImport"
(makePoint 3 1)
, codeActionGoldenTest
"CodeAction qualifies only names in import's explicit non-hiding list"
"ExplicitImport"
(makePoint 4 1)
, codeActionGoldenTest
"CodeAction qualifies only names outside of import's explicit hiding list"
"ExplicitHidingImport"
(makePoint 4 1)
, codeActionGoldenTest
"CodeAction can qualify names not defined in modules they are imported from"
"Reexported"
(makePoint 3 1)
, codeActionGoldenTest
"CodeAction can qualify explicitly imported Prelude"
"ExplicitPrelude"
(makePoint 3 1)
, codeActionGoldenTest
"CodeAction qualifies only imported names"
"OnlyImportedNames"
(makePoint 3 1)
, codeActionGoldenTest
"CodeAction qualifies parenthesized operators properly"
"Parenthesized"
(makePoint 3 1)
, codeActionGoldenTest
"CodeAction qualifies backticked operators properly"
"Backticked"
(makePoint 3 1)
, codeActionGoldenTest
"CodeAction qualifies parenthesized and backticked operators on the same line properly"
"SameLine"
(makePoint 3 1)
, codeActionGoldenTest
"CodeAction doesn't qualify already qualified names"
"NoDoubleQualify"
(makePoint 3 1)
]
codeActionGoldenTest :: TestName -> FilePath -> Point -> TestTree
codeActionGoldenTest testCaseName goldenFilename point =
goldenWithQualifyImportedNames testCaseName goldenFilename $ \document -> do
actions <- getCodeActions document $ pointToRange point
case find ((== Just "Qualify imported names") . getCodeActionTitle) actions of
Just (InR codeAction) -> executeCodeAction codeAction
_ -> liftIO $ assertFailure $ makeCodeActionNotFoundAtString point
testDataDir :: String
testDataDir = "plugins" </> "hls-qualify-imported-names-plugin" </> "test" </> "data"
pluginDescriptor :: PluginTestDescriptor ()
pluginDescriptor = mkPluginTestDescriptor' QualifyImportedNames.descriptor "qualifyImportedNames"
getCodeActionTitle :: (Command |? CodeAction) -> Maybe Text
getCodeActionTitle commandOrCodeAction
| InR CodeAction {_title} <- commandOrCodeAction = Just _title
| otherwise = Nothing
goldenWithQualifyImportedNames :: TestName -> FilePath -> (TextDocumentIdentifier -> Session ()) -> TestTree
goldenWithQualifyImportedNames testName path =
goldenWithHaskellDoc def pluginDescriptor testName testDataDir path "expected" "hs"
pointToRange :: Point -> Range
pointToRange Point {..}
| line <- fromIntegral $ subtract 1 line
, column <- fromIntegral $ subtract 1 column =
Range (Position line column) (Position line $ column + 1)