1+ {-# LANGUAGE OverloadedLabels #-}
12{-# LANGUAGE OverloadedStrings #-}
23
34module Main (main ) where
45
6+ import Control.Lens ((^.) )
57import Data.Aeson
6- import qualified Data.Map as M
8+ import qualified Data.Map as M
9+ import Data.Maybe (fromJust )
10+ import Data.Row ((.+) , (.==) )
11+ import qualified Data.Text as T
712import Ide.Plugin.Config
8- import qualified Ide.Plugin.Rename as Rename
9- import Ide.Types (IdePlugins (IdePlugins ))
13+ import qualified Ide.Plugin.Rename as Rename
14+ import Ide.Types (IdePlugins (IdePlugins ))
15+ import qualified Language.LSP.Protocol.Lens as L
1016import System.FilePath
1117import Test.Hls
1218
@@ -65,6 +71,53 @@ tests = testGroup "Rename"
6571 rename doc (Position 2 17 ) " BinaryTree"
6672 , goldenWithRename " Type variable" " TypeVariable" $ \ doc ->
6773 rename doc (Position 0 13 ) " b"
74+
75+ , testCase " fails when module does not compile" $ runRenameSession " " $ do
76+ doc <- openDoc " CompileError.hs" " haskell"
77+ diags@ (tcDiag : _) <- waitForDiagnosticsFrom doc
78+
79+ -- Make sure there's a typecheck error
80+ liftIO $ do
81+ length diags @?= 1
82+ tcDiag ^. L. range @?= Range (Position 2 7 ) (Position 2 8 )
83+ tcDiag ^. L. severity @?= Just DiagnosticSeverity_Error
84+ tcDiag ^. L. source @?= Just " typecheck"
85+
86+ -- Make sure renaming fails
87+ renameErr <- expectRenameError doc (Position 3 0 ) " foo'"
88+ liftIO $ do
89+ renameErr ^. L. code @?= InL LSPErrorCodes_RequestFailed
90+ renameErr ^. L. message @?= " rename: Rule Failed: GetHieAst"
91+
92+ -- Update the document so it compiles
93+ let change = TextDocumentContentChangeEvent $ InL $ # range .== Range (Position 2 7 ) (Position 2 8 )
94+ .+ # rangeLength .== Nothing
95+ .+ # text .== " Int"
96+ changeDoc doc [change]
97+ expectNoMoreDiagnostics 3 doc " typecheck"
98+
99+ -- Make sure renaming succeeds
100+ rename doc (Position 3 0 ) " foo'"
101+
102+ -- Update it again so it doesn't compile
103+ let change' = TextDocumentContentChangeEvent $ InL $ # range .== Range (Position 2 7 ) (Position 2 11 )
104+ .+ # rangeLength .== Nothing
105+ .+ # text .== " A"
106+ changeDoc doc [change']
107+
108+ -- Make sure there's a compiler error again
109+ diags'@ (tcDiag' : _) <- waitForDiagnosticsFrom doc
110+ liftIO $ do
111+ length diags' @?= 1
112+ tcDiag' ^. L. range @?= Range (Position 2 7 ) (Position 2 8 )
113+ tcDiag' ^. L. severity @?= Just DiagnosticSeverity_Error
114+ tcDiag' ^. L. source @?= Just " typecheck"
115+
116+ -- Make sure renaming fails
117+ renameErr' <- expectRenameError doc (Position 3 0 ) " foo'"
118+ liftIO $ do
119+ renameErr' ^. L. code @?= InL LSPErrorCodes_RequestFailed
120+ renameErr' ^. L. message @?= " rename: Rule Failed: GetHieAst"
68121 ]
69122
70123goldenWithRename :: TestName -> FilePath -> (TextDocumentIdentifier -> Session () ) -> TestTree
@@ -73,3 +126,21 @@ goldenWithRename title path act =
73126
74127testDataDir :: FilePath
75128testDataDir = " test" </> " testdata"
129+
130+ -- | Attempts to renames the term at the specified position, expecting a failure
131+ expectRenameError ::
132+ TextDocumentIdentifier ->
133+ Position ->
134+ String ->
135+ Session ResponseError
136+ expectRenameError doc pos newName = do
137+ let params = RenameParams Nothing doc pos (T. pack newName)
138+ rsp <- request SMethod_TextDocumentRename params
139+ case rsp ^. L. result of
140+ Left err -> pure err
141+ Right x -> liftIO $ assertFailure $
142+ " Got unexpected successful rename response for " <> show (doc ^. L. uri)
143+
144+ runRenameSession :: FilePath -> Session a -> IO a
145+ runRenameSession subdir = failIfSessionTimeout
146+ . runSessionWithServerAndCaps def renamePlugin codeActionNoResolveCaps (testDataDir </> subdir)
0 commit comments