@@ -14,7 +14,7 @@ import Control.Applicative.Combinators
1414import Control.Exception (bracket_ , catch )
1515import qualified Control.Lens as Lens
1616import Control.Monad
17- import Control.Monad.IO.Class (liftIO )
17+ import Control.Monad.IO.Class (MonadIO , liftIO )
1818import Data.Aeson (FromJSON , Value , toJSON )
1919import qualified Data.Binary as Binary
2020import Data.Default
@@ -64,6 +64,7 @@ import Development.IDE.Plugin.Test (WaitForIdeRuleResult(..), TestRequest(BlockS
6464import Control.Monad.Extra (whenJust )
6565import qualified Language.Haskell.LSP.Types.Lens as L
6666import Control.Lens ((^.) )
67+ import Data.Functor
6768
6869main :: IO ()
6970main = do
@@ -676,6 +677,7 @@ codeActionTests = testGroup "code actions"
676677 , removeImportTests
677678 , extendImportTests
678679 , suggestImportTests
680+ , disableWarningTests
679681 , fixConstructorImportTests
680682 , importRenameActionTests
681683 , fillTypedHoleTests
@@ -881,9 +883,8 @@ removeImportTests = testGroup "remove import actions"
881883 ]
882884 docB <- createDoc " ModuleB.hs" " haskell" contentB
883885 _ <- waitForDiagnostics
884- [CACodeAction action@ CodeAction { _title = actionTitle }, _]
885- <- getCodeActions docB (Range (Position 2 0 ) (Position 2 5 ))
886- liftIO $ " Remove import" @=? actionTitle
886+ action <- assertJust " Code action not found" . firstJust (caWithTitle " Remove import" )
887+ =<< getCodeActions docB (Range (Position 2 0 ) (Position 2 5 ))
887888 executeCodeAction action
888889 contentAfterAction <- documentContents docB
889890 let expectedContentAfterAction = T. unlines
@@ -907,9 +908,8 @@ removeImportTests = testGroup "remove import actions"
907908 ]
908909 docB <- createDoc " ModuleB.hs" " haskell" contentB
909910 _ <- waitForDiagnostics
910- [CACodeAction action@ CodeAction { _title = actionTitle }, _]
911- <- getCodeActions docB (Range (Position 2 0 ) (Position 2 5 ))
912- liftIO $ " Remove import" @=? actionTitle
911+ action <- assertJust " Code action not found" . firstJust (caWithTitle " Remove import" )
912+ =<< getCodeActions docB (Range (Position 2 0 ) (Position 2 5 ))
913913 executeCodeAction action
914914 contentAfterAction <- documentContents docB
915915 let expectedContentAfterAction = T. unlines
@@ -936,9 +936,8 @@ removeImportTests = testGroup "remove import actions"
936936 ]
937937 docB <- createDoc " ModuleB.hs" " haskell" contentB
938938 _ <- waitForDiagnostics
939- [CACodeAction action@ CodeAction { _title = actionTitle }, _]
940- <- getCodeActions docB (Range (Position 2 0 ) (Position 2 5 ))
941- liftIO $ " Remove stuffA, stuffC from import" @=? actionTitle
939+ action <- assertJust " Code action not found" . firstJust (caWithTitle " Remove stuffA, stuffC from import" )
940+ =<< getCodeActions docB (Range (Position 2 0 ) (Position 2 5 ))
942941 executeCodeAction action
943942 contentAfterAction <- documentContents docB
944943 let expectedContentAfterAction = T. unlines
@@ -965,9 +964,8 @@ removeImportTests = testGroup "remove import actions"
965964 ]
966965 docB <- createDoc " ModuleB.hs" " haskell" contentB
967966 _ <- waitForDiagnostics
968- [CACodeAction action@ CodeAction { _title = actionTitle }, _]
969- <- getCodeActions docB (Range (Position 2 0 ) (Position 2 5 ))
970- liftIO $ " Remove !!, <?> from import" @=? actionTitle
967+ action <- assertJust " Code action not found" . firstJust (caWithTitle " Remove !!, <?> from import" )
968+ =<< getCodeActions docB (Range (Position 2 0 ) (Position 2 5 ))
971969 executeCodeAction action
972970 contentAfterAction <- documentContents docB
973971 let expectedContentAfterAction = T. unlines
@@ -993,9 +991,8 @@ removeImportTests = testGroup "remove import actions"
993991 ]
994992 docB <- createDoc " ModuleB.hs" " haskell" contentB
995993 _ <- waitForDiagnostics
996- [CACodeAction action@ CodeAction { _title = actionTitle }, _]
997- <- getCodeActions docB (Range (Position 2 0 ) (Position 2 5 ))
998- liftIO $ " Remove A from import" @=? actionTitle
994+ action <- assertJust " Code action not found" . firstJust (caWithTitle " Remove A from import" )
995+ =<< getCodeActions docB (Range (Position 2 0 ) (Position 2 5 ))
999996 executeCodeAction action
1000997 contentAfterAction <- documentContents docB
1001998 let expectedContentAfterAction = T. unlines
@@ -1020,9 +1017,8 @@ removeImportTests = testGroup "remove import actions"
10201017 ]
10211018 docB <- createDoc " ModuleB.hs" " haskell" contentB
10221019 _ <- waitForDiagnostics
1023- [CACodeAction action@ CodeAction { _title = actionTitle }, _]
1024- <- getCodeActions docB (Range (Position 2 0 ) (Position 2 5 ))
1025- liftIO $ " Remove A, E, F from import" @=? actionTitle
1020+ action <- assertJust " Code action not found" . firstJust (caWithTitle " Remove A, E, F from import" )
1021+ =<< getCodeActions docB (Range (Position 2 0 ) (Position 2 5 ))
10261022 executeCodeAction action
10271023 contentAfterAction <- documentContents docB
10281024 let expectedContentAfterAction = T. unlines
@@ -1044,9 +1040,8 @@ removeImportTests = testGroup "remove import actions"
10441040 ]
10451041 docB <- createDoc " ModuleB.hs" " haskell" contentB
10461042 _ <- waitForDiagnostics
1047- [CACodeAction action@ CodeAction { _title = actionTitle }, _]
1048- <- getCodeActions docB (Range (Position 2 0 ) (Position 2 5 ))
1049- liftIO $ " Remove import" @=? actionTitle
1043+ action <- assertJust " Code action not found" . firstJust (caWithTitle " Remove import" )
1044+ =<< getCodeActions docB (Range (Position 2 0 ) (Position 2 5 ))
10501045 executeCodeAction action
10511046 contentAfterAction <- documentContents docB
10521047 let expectedContentAfterAction = T. unlines
@@ -1069,9 +1064,8 @@ removeImportTests = testGroup "remove import actions"
10691064 ]
10701065 doc <- createDoc " ModuleC.hs" " haskell" content
10711066 _ <- waitForDiagnostics
1072- [_, _, _, _, CACodeAction action@ CodeAction { _title = actionTitle }]
1073- <- getCodeActions doc (Range (Position 2 0 ) (Position 2 5 ))
1074- liftIO $ " Remove all redundant imports" @=? actionTitle
1067+ action <- assertJust " Code action not found" . firstJust (caWithTitle " Remove all redundant imports" )
1068+ =<< getCodeActions doc (Range (Position 2 0 ) (Position 2 5 ))
10751069 executeCodeAction action
10761070 contentAfterAction <- documentContents doc
10771071 let expectedContentAfterAction = T. unlines
@@ -1087,6 +1081,10 @@ removeImportTests = testGroup "remove import actions"
10871081 ]
10881082 liftIO $ expectedContentAfterAction @=? contentAfterAction
10891083 ]
1084+ where
1085+ caWithTitle t = \ case
1086+ CACodeAction a@ CodeAction {_title} -> guard (_title == t) >> Just a
1087+ _ -> Nothing
10901088
10911089extendImportTests :: TestTree
10921090extendImportTests = testGroup " extend import actions"
@@ -1441,6 +1439,57 @@ suggestImportTests = testGroup "suggest import actions"
14411439 else
14421440 liftIO $ [_title | CACodeAction CodeAction {_title} <- actions, _title == newImp ] @?= []
14431441
1442+ disableWarningTests :: TestTree
1443+ disableWarningTests =
1444+ testGroup " disable warnings" $
1445+ [
1446+ ( " missing-signatures"
1447+ , T. unlines
1448+ [ " {-# OPTIONS_GHC -Wall #-}"
1449+ , " main = putStrLn \" hello\" "
1450+ ]
1451+ , T. unlines
1452+ [ " {-# OPTIONS_GHC -Wall #-}"
1453+ , " {-# OPTIONS_GHC -Wno-missing-signatures #-}"
1454+ , " main = putStrLn \" hello\" "
1455+ ]
1456+ )
1457+ ,
1458+ ( " unused-imports"
1459+ , T. unlines
1460+ [ " {-# OPTIONS_GHC -Wall #-}"
1461+ , " "
1462+ , " "
1463+ , " module M where"
1464+ , " "
1465+ , " import Data.Functor"
1466+ ]
1467+ , T. unlines
1468+ [ " {-# OPTIONS_GHC -Wall #-}"
1469+ , " {-# OPTIONS_GHC -Wno-unused-imports #-}"
1470+ , " "
1471+ , " "
1472+ , " module M where"
1473+ , " "
1474+ , " import Data.Functor"
1475+ ]
1476+ )
1477+ ]
1478+ <&> \ (warning, initialContent, expectedContent) -> testSession (T. unpack warning) $ do
1479+ doc <- createDoc " Module.hs" " haskell" initialContent
1480+ _ <- waitForDiagnostics
1481+ codeActs <- mapMaybe caResultToCodeAct <$> getCodeActions doc (Range (Position 0 0 ) (Position 0 0 ))
1482+ case find (\ CodeAction {_title} -> _title == " Disable \" " <> warning <> " \" warnings" ) codeActs of
1483+ Nothing -> liftIO $ assertFailure " No code action with expected title"
1484+ Just action -> do
1485+ executeCodeAction action
1486+ contentAfterAction <- documentContents doc
1487+ liftIO $ expectedContent @=? contentAfterAction
1488+ where
1489+ caResultToCodeAct = \ case
1490+ CACommand _ -> Nothing
1491+ CACodeAction c -> Just c
1492+
14441493insertNewDefinitionTests :: TestTree
14451494insertNewDefinitionTests = testGroup " insert new definition actions"
14461495 [ testSession " insert new function definition" $ do
@@ -2192,7 +2241,12 @@ removeRedundantConstraintsTests = let
21922241 doc <- createDoc " Testing.hs" " haskell" code
21932242 _ <- waitForDiagnostics
21942243 actionsOrCommands <- getCodeActions doc (Range (Position 4 0 ) (Position 4 maxBound ))
2195- liftIO $ assertBool " Found some actions" (null actionsOrCommands)
2244+ liftIO $ assertBool " Found some actions (other than \" disable warnings\" )"
2245+ $ all isDisableWarningAction actionsOrCommands
2246+ where
2247+ isDisableWarningAction = \ case
2248+ CACodeAction CodeAction {_title} -> " Disable" `T.isPrefixOf` _title && " warnings" `T.isSuffixOf` _title
2249+ _ -> False
21962250
21972251 in testGroup " remove redundant function constraints"
21982252 [ check
@@ -4037,7 +4091,10 @@ asyncTests = testGroup "async"
40374091 ]
40384092 void waitForDiagnostics
40394093 actions <- getCodeActions doc (Range (Position 1 0 ) (Position 1 0 ))
4040- liftIO $ [ _title | CACodeAction CodeAction {_title} <- actions] @=? [" add signature: foo :: a -> a" ]
4094+ liftIO $ [ _title | CACodeAction CodeAction {_title} <- actions] @=?
4095+ [ " add signature: foo :: a -> a"
4096+ , " Disable \" missing-signatures\" warnings"
4097+ ]
40414098 , testSession " request" $ do
40424099 -- Execute a custom request that will block for 1000 seconds
40434100 void $ sendRequest (CustomClientMethod " test" ) $ BlockSeconds 1000
@@ -4048,7 +4105,10 @@ asyncTests = testGroup "async"
40484105 ]
40494106 void waitForDiagnostics
40504107 actions <- getCodeActions doc (Range (Position 0 0 ) (Position 0 0 ))
4051- liftIO $ [ _title | CACodeAction CodeAction {_title} <- actions] @=? [" add signature: foo :: a -> a" ]
4108+ liftIO $ [ _title | CACodeAction CodeAction {_title} <- actions] @=?
4109+ [ " add signature: foo :: a -> a"
4110+ , " Disable \" missing-signatures\" warnings"
4111+ ]
40524112 ]
40534113
40544114
@@ -4425,3 +4485,9 @@ withTempDir :: (FilePath -> IO a) -> IO a
44254485withTempDir f = System.IO.Extra. withTempDir $ \ dir -> do
44264486 dir' <- canonicalizePath dir
44274487 f dir'
4488+
4489+ -- | Assert that a value is not 'Nothing', and extract the value.
4490+ assertJust :: MonadIO m => String -> Maybe a -> m a
4491+ assertJust s = \ case
4492+ Nothing -> liftIO $ assertFailure s
4493+ Just x -> pure x
0 commit comments