@@ -36,6 +36,7 @@ import Development.IDE.Core.PositionMapping (PositionResult (..),
36
36
positionResultToMaybe ,
37
37
toCurrent )
38
38
import Development.IDE.Core.Shake (Q (.. ))
39
+ import Development.IDE.Main as IDE
39
40
import Development.IDE.GHC.Util
40
41
import Development.IDE.Plugin.Completions.Types (extendImportCommandId )
41
42
import Development.IDE.Plugin.TypeLenses (typeLensCommandId )
@@ -75,7 +76,7 @@ import qualified System.IO.Extra
75
76
import System.Info.Extra (isWindows )
76
77
import System.Process.Extra (CreateProcess (cwd ),
77
78
proc ,
78
- readCreateProcessWithExitCode )
79
+ readCreateProcessWithExitCode , createPipe )
79
80
import Test.QuickCheck
80
81
-- import Test.QuickCheck.Instances ()
81
82
import Control.Lens ((^.) )
@@ -92,6 +93,14 @@ import Test.Tasty.ExpectedFailure
92
93
import Test.Tasty.HUnit
93
94
import Test.Tasty.Ingredients.Rerun
94
95
import Test.Tasty.QuickCheck
96
+ import Data.IORef
97
+ import Ide.PluginUtils (pluginDescToIdePlugins )
98
+ import Control.Concurrent.Async
99
+ import Ide.Types
100
+ import Data.String (IsString (fromString ))
101
+ import qualified Language.LSP.Types as LSP
102
+ import Data.IORef.Extra (atomicModifyIORef_ )
103
+ import qualified Development.IDE.Plugin.HLS.GhcIde as Ghcide
95
104
96
105
waitForProgressBegin :: Session ()
97
106
waitForProgressBegin = skipManyTill anyMessage $ satisfyMaybe $ \ case
@@ -5143,21 +5152,26 @@ runInDir' dir startExeIn startSessionIn extraOptions s = do
5143
5152
-- HIE calls getXgdDirectory which assumes that HOME is set.
5144
5153
-- Only sets HOME if it wasn't already set.
5145
5154
setEnv " HOME" " /homeless-shelter" False
5146
- let lspTestCaps = fullCaps { _window = Just $ WindowClientCapabilities $ Just True }
5155
+ conf <- getConfigFromEnv
5156
+ runSessionWithConfig conf cmd lspTestCaps projDir s
5157
+
5158
+ getConfigFromEnv :: IO SessionConfig
5159
+ getConfigFromEnv = do
5147
5160
logColor <- fromMaybe True <$> checkEnv " LSP_TEST_LOG_COLOR"
5148
5161
timeoutOverride <- fmap read <$> getEnv " LSP_TIMEOUT"
5149
- let conf = defaultConfig{messageTimeout = fromMaybe (messageTimeout defaultConfig) timeoutOverride}
5150
- -- uncomment this or set LSP_TEST_LOG_STDERR=1 to see all logging
5151
- -- { logStdErr = True }
5152
- -- uncomment this or set LSP_TEST_LOG_MESSAGES=1 to see all messages
5153
- -- { logMessages = True }
5154
- runSessionWithConfig conf{logColor} cmd lspTestCaps projDir s
5162
+ return defaultConfig
5163
+ { messageTimeout = fromMaybe (messageTimeout defaultConfig) timeoutOverride
5164
+ , logColor
5165
+ }
5155
5166
where
5156
5167
checkEnv :: String -> IO (Maybe Bool )
5157
5168
checkEnv s = fmap convertVal <$> getEnv s
5158
5169
convertVal " 0" = False
5159
5170
convertVal _ = True
5160
5171
5172
+ lspTestCaps :: ClientCapabilities
5173
+ lspTestCaps = fullCaps { _window = Just $ WindowClientCapabilities $ Just True }
5174
+
5161
5175
openTestDataDoc :: FilePath -> Session TextDocumentIdentifier
5162
5176
openTestDataDoc path = do
5163
5177
source <- liftIO $ readFileUtf8 $ " test/data" </> path
@@ -5225,8 +5239,39 @@ unitTests = do
5225
5239
let expected = " 1:2-3:4"
5226
5240
assertBool (unwords [" expected to find range" , expected, " in diagnostic" , shown]) $
5227
5241
expected `isInfixOf` shown
5242
+ , testCase " notification handlers run sequentially" $ do
5243
+ orderRef <- newIORef []
5244
+ let plugins = pluginDescToIdePlugins $
5245
+ [ (defaultPluginDescriptor $ fromString $ show i)
5246
+ { pluginNotificationHandlers = mconcat
5247
+ [ mkPluginNotificationHandler LSP. STextDocumentDidOpen $ \ _ _ _ ->
5248
+ liftIO $ atomicModifyIORef_ orderRef (i: )
5249
+ ]
5250
+ }
5251
+ | i <- [(1 :: Int ).. 20 ]
5252
+ ] ++ Ghcide. descriptors
5253
+
5254
+ testIde def{argsHlsPlugins = plugins} $ do
5255
+ _ <- createDoc " haskell" " A.hs" " module A where"
5256
+ waitForProgressDone
5257
+ actualOrder <- liftIO $ readIORef orderRef
5258
+
5259
+ liftIO $ actualOrder @?= reverse [(1 :: Int ).. 20 ]
5228
5260
]
5229
5261
5262
+ testIde :: Arguments -> Session () -> IO ()
5263
+ testIde arguments session = do
5264
+ config <- getConfigFromEnv
5265
+ (hInRead, hInWrite) <- createPipe
5266
+ (hOutRead, hOutWrite) <- createPipe
5267
+ let server = IDE. defaultMain arguments
5268
+ { argsHandleIn = pure hInRead
5269
+ , argsHandleOut = pure hOutWrite
5270
+ }
5271
+
5272
+ withAsync server $ \ _ ->
5273
+ runSessionWithHandles hInWrite hOutRead config lspTestCaps " ." session
5274
+
5230
5275
positionMappingTests :: TestTree
5231
5276
positionMappingTests =
5232
5277
testGroup " position mapping"
0 commit comments