11
11
module Main (main ) where
12
12
13
13
import Control.Applicative.Combinators
14
- import Control.Exception (catch )
14
+ import Control.Exception (bracket_ , catch )
15
15
import qualified Control.Lens as Lens
16
16
import Control.Monad
17
17
import Control.Monad.IO.Class (liftIO )
@@ -41,7 +41,7 @@ import Language.Haskell.LSP.Types.Capabilities
41
41
import qualified Language.Haskell.LSP.Types.Lens as Lsp (diagnostics , params , message )
42
42
import Language.Haskell.LSP.VFS (applyChange )
43
43
import Network.URI
44
- import System.Environment.Blank (getEnv , setEnv )
44
+ import System.Environment.Blank (unsetEnv , getEnv , setEnv )
45
45
import System.FilePath
46
46
import System.IO.Extra hiding (withTempDir )
47
47
import qualified System.IO.Extra
@@ -58,8 +58,10 @@ import Test.Tasty.HUnit
58
58
import Test.Tasty.QuickCheck
59
59
import System.Time.Extra
60
60
import Development.IDE.Plugin.CodeAction (typeSignatureCommandId , blockCommandId , matchRegExMultipleImports )
61
- import Development.IDE.Plugin.Test (WaitForIdeRuleResult (.. ), TestRequest (WaitForIdeRule , BlockSeconds ,GetInterfaceFilesDir ))
61
+ import Development.IDE.Plugin.Test (WaitForIdeRuleResult (.. ), TestRequest (BlockSeconds ,GetInterfaceFilesDir ))
62
62
import Control.Monad.Extra (whenJust )
63
+ import qualified Language.Haskell.LSP.Types.Lens as L
64
+ import Control.Lens ((^.) )
63
65
64
66
main :: IO ()
65
67
main = do
@@ -630,11 +632,6 @@ cancellationTemplate (edit, undoEdit) mbKey = testCase (maybe "-" fst mbKey) $ r
630
632
-- similar to run except it disables kick
631
633
runTestNoKick s = withTempDir $ \ dir -> runInDir' dir " ." " ." [" --test-no-kick" ] s
632
634
633
- waitForAction key TextDocumentIdentifier {_uri} = do
634
- waitId <- sendRequest (CustomClientMethod " test" ) (WaitForIdeRule key _uri)
635
- ResponseMessage {_result} <- skipManyTill anyMessage $ responseForId waitId
636
- return _result
637
-
638
635
typeCheck doc = do
639
636
Right WaitForIdeRuleResult {.. } <- waitForAction " TypeCheck" doc
640
637
liftIO $ assertBool " The file should typecheck" ideResultSuccess
@@ -3388,7 +3385,7 @@ cradleTests :: TestTree
3388
3385
cradleTests = testGroup " cradle"
3389
3386
[testGroup " dependencies" [sessionDepsArePickedUp]
3390
3387
,testGroup " ignore-fatal" [ignoreFatalWarning]
3391
- ,testGroup " loading" [loadCradleOnlyonce]
3388
+ ,testGroup " loading" [loadCradleOnlyonce, retryFailedCradle ]
3392
3389
,testGroup " multi" [simpleMultiTest, simpleMultiTest2]
3393
3390
,testGroup " sub-directory" [simpleSubDirectoryTest]
3394
3391
]
@@ -3415,6 +3412,43 @@ loadCradleOnlyonce = testGroup "load cradle only once"
3415
3412
msgs <- manyTill (skipManyTill anyMessage cradleLoadedMessage) (skipManyTill anyMessage (message @ PublishDiagnosticsNotification ))
3416
3413
liftIO $ length msgs @?= 0
3417
3414
3415
+ retryFailedCradle :: TestTree
3416
+ retryFailedCradle = testSession' " retry failed" $ \ dir -> do
3417
+ -- The false cradle always fails
3418
+ let hieContents = " cradle: {bios: {shell: \" false\" }}"
3419
+ hiePath = dir </> " hie.yaml"
3420
+ liftIO $ writeFile hiePath hieContents
3421
+ hieDoc <- createDoc hiePath " yaml" $ T. pack hieContents
3422
+ let aPath = dir </> " A.hs"
3423
+ doc <- createDoc aPath " haskell" " main = return ()"
3424
+ Right WaitForIdeRuleResult {.. } <- waitForAction " TypeCheck" doc
3425
+ liftIO $ " Test assumption failed: cradle should error out" `assertBool` not ideResultSuccess
3426
+
3427
+ -- Fix the cradle and typecheck again
3428
+ let validCradle = " cradle: {bios: {shell: \" echo A.hs\" }}"
3429
+ liftIO $ writeFileUTF8 hiePath $ T. unpack validCradle
3430
+ changeDoc
3431
+ hieDoc
3432
+ [ TextDocumentContentChangeEvent
3433
+ { _range = Nothing ,
3434
+ _rangeLength = Nothing ,
3435
+ _text = validCradle
3436
+ }
3437
+ ]
3438
+
3439
+ -- Force a session restart by making an edit, just to dirty the typecheck node
3440
+ changeDoc
3441
+ doc
3442
+ [ TextDocumentContentChangeEvent
3443
+ { _range = Just Range {_start = Position 0 0 , _end = Position 0 0 },
3444
+ _rangeLength = Nothing ,
3445
+ _text = " \n "
3446
+ }
3447
+ ]
3448
+
3449
+ Right WaitForIdeRuleResult {.. } <- waitForAction " TypeCheck" doc
3450
+ liftIO $ " No joy after fixing the cradle" `assertBool` ideResultSuccess
3451
+
3418
3452
3419
3453
dependentFileTest :: TestTree
3420
3454
dependentFileTest = testGroup " addDependentFile"
@@ -3479,17 +3513,19 @@ simpleSubDirectoryTest =
3479
3513
expectNoMoreDiagnostics 0.5
3480
3514
3481
3515
simpleMultiTest :: TestTree
3482
- simpleMultiTest = testCase " simple-multi-test" $ runWithExtraFiles " multi" $ \ dir -> do
3516
+ simpleMultiTest = testCase " simple-multi-test" $ withLongTimeout $ runWithExtraFiles " multi" $ \ dir -> do
3483
3517
let aPath = dir </> " a/A.hs"
3484
3518
bPath = dir </> " b/B.hs"
3485
3519
aSource <- liftIO $ readFileUtf8 aPath
3486
- (TextDocumentIdentifier adoc) <- createDoc aPath " haskell" aSource
3487
- expectNoMoreDiagnostics 0.5
3520
+ adoc <- createDoc aPath " haskell" aSource
3521
+ Right WaitForIdeRuleResult {.. } <- waitForAction " TypeCheck" adoc
3522
+ liftIO $ assertBool " A should typecheck" ideResultSuccess
3488
3523
bSource <- liftIO $ readFileUtf8 bPath
3489
3524
bdoc <- createDoc bPath " haskell" bSource
3490
- expectNoMoreDiagnostics 0.5
3525
+ Right WaitForIdeRuleResult {.. } <- waitForAction " TypeCheck" bdoc
3526
+ liftIO $ assertBool " B should typecheck" ideResultSuccess
3491
3527
locs <- getDefinitions bdoc (Position 2 7 )
3492
- let fooL = mkL adoc 2 0 2 3
3528
+ let fooL = mkL ( adoc ^. L. uri) 2 0 2 3
3493
3529
checkDefs locs (pure [fooL])
3494
3530
expectNoMoreDiagnostics 0.5
3495
3531
@@ -3855,6 +3891,9 @@ run' s = withTempDir $ \dir -> runInDir dir (s dir)
3855
3891
runInDir :: FilePath -> Session a -> IO a
3856
3892
runInDir dir = runInDir' dir " ." " ." []
3857
3893
3894
+ withLongTimeout :: IO a -> IO a
3895
+ withLongTimeout = bracket_ (setEnv " LSP_TIMEOUT" " 120" True ) (unsetEnv " LSP_TIMEOUT" )
3896
+
3858
3897
-- | Takes a directory as well as relative paths to where we should launch the executable as well as the session root.
3859
3898
runInDir' :: FilePath -> FilePath -> FilePath -> [String ] -> Session a -> IO a
3860
3899
runInDir' dir startExeIn startSessionIn extraOptions s = do
@@ -3875,19 +3914,19 @@ runInDir' dir startExeIn startSessionIn extraOptions s = do
3875
3914
setEnv " HOME" " /homeless-shelter" False
3876
3915
let lspTestCaps = fullCaps { _window = Just $ WindowClientCapabilities $ Just True }
3877
3916
logColor <- fromMaybe True <$> checkEnv " LSP_TEST_LOG_COLOR"
3917
+ timeoutOverride <- fmap read <$> getEnv " LSP_TIMEOUT"
3918
+ let conf = defaultConfig{messageTimeout = fromMaybe (messageTimeout defaultConfig) timeoutOverride}
3919
+ -- uncomment this or set LSP_TEST_LOG_STDERR=1 to see all logging
3920
+ -- { logStdErr = True }
3921
+ -- uncomment this or set LSP_TEST_LOG_MESSAGES=1 to see all messages
3922
+ -- { logMessages = True }
3878
3923
runSessionWithConfig conf{logColor} cmd lspTestCaps projDir s
3879
3924
where
3880
3925
checkEnv :: String -> IO (Maybe Bool )
3881
3926
checkEnv s = fmap convertVal <$> getEnv s
3882
3927
convertVal " 0" = False
3883
3928
convertVal _ = True
3884
3929
3885
- conf = defaultConfig
3886
- -- uncomment this or set LSP_TEST_LOG_STDERR=1 to see all logging
3887
- -- { logStdErr = True }
3888
- -- uncomment this or set LSP_TEST_LOG_MESSAGES=1 to see all messages
3889
- -- { logMessages = True }
3890
-
3891
3930
openTestDataDoc :: FilePath -> Session TextDocumentIdentifier
3892
3931
openTestDataDoc path = do
3893
3932
source <- liftIO $ readFileUtf8 $ " test/data" </> path
0 commit comments