lsp-test is a functional testing framework for Language Server Protocol servers.
```haskell
-import Language.Haskell.LSP.Test
+import Language.LSP.Test
main = runSession "hie" fullCaps "proj/dir" $ do
doc <- openDoc "Foo.hs" "haskell"
skipMany anyNotification
source-repository-package
type: git
location: https://github.com/alanz/lsp.git
- tag: fd92be6d65f82f098cc0576e7e2200e38fb1cf94
+ tag: ba6a7409f830be09f815489265a76499d7b7debb
subdir: .
lsp-types
import Control.Applicative.Combinators
import Control.Monad.IO.Class
-import Language.Haskell.LSP.Test
-import Language.Haskell.LSP.Types
+import Language.LSP.Test
+import Language.LSP.Types
main = runSession "haskell-language-server" fullCaps "../test/data/" $ do
doc <- openDoc "Rename.hs" "haskell"
description:
A test framework for writing tests against
<https://microsoft.github.io/language-server-protocol/ Language Server Protocol servers>.
- @Language.Haskell.LSP.Test@ launches your server as a subprocess and allows you to simulate a session
- down to the wire, and @Language.Haskell.LSP.Test@ can replay captured sessions from
+ @Language.LSP.Test@ launches your server as a subprocess and allows you to simulate a session
+ down to the wire, and @Language.LSP.Test@ can replay captured sessions from
<haskell-lsp https://hackage.haskell.org/package/haskell-lsp>.
To see examples of it in action, check out <https://github.com/haskell/haskell-ide-engine haskell-ide-engine>,
<https://github.com/haskell/haskell-language-server haskell-language-server> and
library
hs-source-dirs: src
- exposed-modules: Language.Haskell.LSP.Test
- reexported-modules: lsp-types:Language.Haskell.LSP.Types
- , lsp-types:Language.Haskell.LSP.Types.Capabilities
+ exposed-modules: Language.LSP.Test
+ reexported-modules: lsp-types:Language.LSP.Types
+ , lsp-types:Language.LSP.Types.Capabilities
, parser-combinators:Control.Applicative.Combinators
default-language: Haskell2010
build-depends: base >= 4.10 && < 5
build-depends: Win32
else
build-depends: unix
- other-modules: Language.Haskell.LSP.Test.Compat
- Language.Haskell.LSP.Test.Decoding
- Language.Haskell.LSP.Test.Exceptions
- Language.Haskell.LSP.Test.Files
- Language.Haskell.LSP.Test.Parsing
- Language.Haskell.LSP.Test.Server
- Language.Haskell.LSP.Test.Session
+ other-modules: Language.LSP.Test.Compat
+ Language.LSP.Test.Decoding
+ Language.LSP.Test.Exceptions
+ Language.LSP.Test.Files
+ Language.LSP.Test.Parsing
+ Language.LSP.Test.Server
+ Language.LSP.Test.Session
ghc-options: -W
executable dummy-server
{-# LANGUAGE ExistentialQuantification #-}
{-|
-Module : Language.Haskell.LSP.Test
+Module : Language.LSP.Test
Description : A functional testing framework for LSP servers.
Maintainer : luke_lau@icloud.com
Stability : experimental
Provides the framework to start functionally testing
<https://github.com/Microsoft/language-server-protocol Language Server Protocol servers>.
-You should import "Language.Haskell.LSP.Types" alongside this.
+You should import "Language.LSP.Types" alongside this.
-}
-module Language.Haskell.LSP.Test
+module Language.LSP.Test
(
-- * Sessions
Session
, defaultConfig
, C.fullCaps
-- ** Exceptions
- , module Language.Haskell.LSP.Test.Exceptions
+ , module Language.LSP.Test.Exceptions
, withTimeout
-- * Sending
, request
, sendNotification
, sendResponse
-- * Receving
- , module Language.Haskell.LSP.Test.Parsing
+ , module Language.LSP.Test.Parsing
-- * Utilities
-- | Quick helper functions for common tasks.
import qualified Data.HashMap.Strict as HashMap
import Data.List
import Data.Maybe
-import Language.Haskell.LSP.Types
-import Language.Haskell.LSP.Types.Lens hiding
+import Language.LSP.Types
+import Language.LSP.Types.Lens hiding
(id, capabilities, message, executeCommand, applyEdit, rename)
-import qualified Language.Haskell.LSP.Types.Lens as LSP
-import qualified Language.Haskell.LSP.Types.Capabilities as C
-import Language.Haskell.LSP.VFS
-import Language.Haskell.LSP.Test.Compat
-import Language.Haskell.LSP.Test.Decoding
-import Language.Haskell.LSP.Test.Exceptions
-import Language.Haskell.LSP.Test.Parsing
-import Language.Haskell.LSP.Test.Session
-import Language.Haskell.LSP.Test.Server
+import qualified Language.LSP.Types.Lens as LSP
+import qualified Language.LSP.Types.Capabilities as C
+import Language.LSP.VFS
+import Language.LSP.Test.Compat
+import Language.LSP.Test.Decoding
+import Language.LSP.Test.Exceptions
+import Language.LSP.Test.Parsing
+import Language.LSP.Test.Session
+import Language.LSP.Test.Server
import System.Environment
import System.IO
import System.Directory
return diags
-- | The same as 'waitForDiagnostics', but will only match a specific
--- 'Language.Haskell.LSP.Types._source'.
+-- 'Language.LSP.Types._source'.
waitForDiagnosticsSource :: String -> Session [Diagnostic]
waitForDiagnosticsSource src = do
diags <- waitForDiagnostics
-- Control.Monad.IO.Class but it's needed for
-- MonadIO
{-# OPTIONS_GHC -Wunused-imports #-}
-module Language.Haskell.LSP.Test.Compat where
+module Language.LSP.Test.Compat where
import Data.Maybe
import System.IO
-import Language.Haskell.LSP.Types
+import Language.LSP.Types
#if MIN_VERSION_process(1,6,3)
-- We have to hide cleanupProcess for process-1.6.3.0
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE DataKinds #-}
-module Language.Haskell.LSP.Test.Decoding where
+module Language.LSP.Test.Decoding where
import Prelude hiding ( id )
import Data.Aeson
import Data.Maybe
import System.IO
import System.IO.Error
-import Language.Haskell.LSP.Types
-import Language.Haskell.LSP.Types.Lens
-import Language.Haskell.LSP.Test.Exceptions
+import Language.LSP.Types
+import Language.LSP.Types.Lens
+import Language.LSP.Test.Exceptions
import Data.IxMap
import Data.Kind
-module Language.Haskell.LSP.Test.Exceptions where
+module Language.LSP.Test.Exceptions where
import Control.Exception
-import Language.Haskell.LSP.Types
+import Language.LSP.Types
import Data.Aeson
import Data.Aeson.Encode.Pretty
import Data.Algorithm.Diff
{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE OverloadedStrings #-}
-module Language.Haskell.LSP.Test.Files
+module Language.LSP.Test.Files
( swapFiles
, rootDir
)
where
-import Language.Haskell.LSP.Types
-import Language.Haskell.LSP.Types.Lens
+import Language.LSP.Types
+import Language.LSP.Types.Lens
import Control.Lens
import qualified Data.HashMap.Strict as HM
import qualified Data.Text as T
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE OverloadedStrings #-}
-module Language.Haskell.LSP.Test.Parsing
+module Language.LSP.Test.Parsing
( -- $receiving
satisfy
, satisfyMaybe
import qualified Data.Conduit.Parser (named)
import qualified Data.Text as T
import Data.Typeable
-import Language.Haskell.LSP.Types
-import Language.Haskell.LSP.Test.Session
+import Language.LSP.Types
+import Language.LSP.Test.Session
-- $receiving
-- To receive a message, specify the method of the message to expect:
-- msg2 <- message STextDocumentHover
-- @
--
--- 'Language.Haskell.LSP.Test.Session' is actually just a parser
+-- 'Language.LSP.Test.Session' is actually just a parser
-- that operates on messages under the hood. This means that you
-- can create and combine parsers to match speicifc sequences of
-- messages that you expect.
shouldSkip (FromServerMess SWindowShowMessageRequest _) = True
shouldSkip _ = False
--- | Matches a 'Language.Haskell.LSP.Test.PublishDiagnosticsNotification'
+-- | Matches a 'Language.LSP.Test.PublishDiagnosticsNotification'
-- (textDocument/publishDiagnostics) notification.
publishDiagnosticsNotification :: Session PublishDiagnosticsNotification
publishDiagnosticsNotification = named "Publish diagnostics notification" $
-- | A testing tool for replaying captured client logs back to a server,
-- and validating that the server output matches up with another log.
-module Language.Haskell.LSP.Test.Replay
+module Language.LSP.Test.Replay
( -- replaySession
)
where
import Control.Monad.IO.Class
import qualified Data.ByteString.Lazy.Char8 as B
import qualified Data.Text as T
-import Language.Haskell.LSP.Types
-import Language.Haskell.LSP.Types.Lens as LSP
+import Language.LSP.Types
+import Language.LSP.Types.Lens as LSP
import Data.Aeson
import Data.Default
import Data.List
import Control.Monad
import System.FilePath
import System.IO
-import Language.Haskell.LSP.Test
-import Language.Haskell.LSP.Test.Compat
-import Language.Haskell.LSP.Test.Files
-import Language.Haskell.LSP.Test.Decoding
-import Language.Haskell.LSP.Test.Server
-import Language.Haskell.LSP.Test.Session
+import Language.LSP.Test
+import Language.LSP.Test.Compat
+import Language.LSP.Test.Files
+import Language.LSP.Test.Decoding
+import Language.LSP.Test.Server
+import Language.LSP.Test.Session
{-
-- | Replays a captured client output and
-module Language.Haskell.LSP.Test.Server (withServer) where
+module Language.LSP.Test.Server (withServer) where
import Control.Concurrent.Async
import Control.Monad
-import Language.Haskell.LSP.Test.Compat
+import Language.LSP.Test.Compat
import System.IO
import System.Process hiding (withCreateProcess)
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
-module Language.Haskell.LSP.Test.Session
+module Language.LSP.Test.Session
( Session(..)
, SessionConfig(..)
, defaultConfig
import qualified Data.HashMap.Strict as HashMap
import Data.Maybe
import Data.Function
-import Language.Haskell.LSP.Types.Capabilities
-import Language.Haskell.LSP.Types
-import Language.Haskell.LSP.Types.Lens
-import qualified Language.Haskell.LSP.Types.Lens as LSP
-import Language.Haskell.LSP.VFS
-import Language.Haskell.LSP.Test.Compat
-import Language.Haskell.LSP.Test.Decoding
-import Language.Haskell.LSP.Test.Exceptions
+import Language.LSP.Types.Capabilities
+import Language.LSP.Types
+import Language.LSP.Types.Lens
+import qualified Language.LSP.Types.Lens as LSP
+import Language.LSP.VFS
+import Language.LSP.Test.Compat
+import Language.LSP.Test.Decoding
+import Language.LSP.Test.Exceptions
import System.Console.ANSI
import System.Directory
import System.IO
-- | A session representing one instance of launching and connecting to a server.
--
-- You can send and receive messages to the server within 'Session' via
--- 'Language.Haskell.LSP.Test.message',
--- 'Language.Haskell.LSP.Test.sendRequest' and
--- 'Language.Haskell.LSP.Test.sendNotification'.
+-- 'Language.LSP.Test.message',
+-- 'Language.LSP.Test.sendRequest' and
+-- 'Language.LSP.Test.sendNotification'.
newtype Session a = Session (ConduitParser FromServerMessage (StateT SessionState (ReaderT SessionContext IO)) a)
deriving (Functor, Applicative, Monad, MonadIO, Alternative)
, logColor :: Bool -- ^ Add ANSI color to the logged messages, defaults to True.
, lspConfig :: Maybe Value -- ^ The initial LSP config as JSON value, defaults to Nothing.
, ignoreLogNotifications :: Bool
- -- ^ Whether or not to ignore 'Language.Haskell.LSP.Types.ShowMessageNotification' and
- -- 'Language.Haskell.LSP.Types.LogMessageNotification', defaults to False.
+ -- ^ Whether or not to ignore 'Language.LSP.Types.ShowMessageNotification' and
+ -- 'Language.LSP.Types.LogMessageNotification', defaults to False.
--
-- @since 0.9.0.0
, initialWorkspaceFolders :: Maybe [WorkspaceFolder]
-- Defaults to Nothing.
}
--- | The configuration used in 'Language.Haskell.LSP.Test.runSession'.
+-- | The configuration used in 'Language.LSP.Test.runSession'.
defaultConfig :: SessionConfig
defaultConfig = SessionConfig 60 False False True Nothing False Nothing
logMsg LogClient msg
liftIO $ B.hPut h (addHeader $ encode msg)
--- | Execute a block f that will throw a 'Language.Haskell.LSP.Test.Exception.Timeout' exception
+-- | Execute a block f that will throw a 'Language.LSP.Test.Exception.Timeout' exception
-- after duration seconds. This will override the global timeout
-- for waiting for messages to arrive defined in 'SessionConfig'.
withTimeout :: Int -> Session a -> Session a
import Control.Monad.IO.Class
import Control.Monad
import Control.Lens hiding (List)
-import Language.Haskell.LSP.Test
-import Language.Haskell.LSP.Types
-import Language.Haskell.LSP.Types.Lens hiding
+import Language.LSP.Test
+import Language.LSP.Types
+import Language.LSP.Types.Lens hiding
(capabilities, message, rename, applyEdit)
-import qualified Language.Haskell.LSP.Types.Lens as LSP
-import Language.Haskell.LSP.Types.Capabilities as LSP
+import qualified Language.LSP.Types.Lens as LSP
+import Language.LSP.Types.Capabilities as LSP
import System.Directory
import System.FilePath
import System.Timeout
import Data.Default
import qualified Data.HashMap.Strict as HM
import Data.List (isSuffixOf)
-import Language.Haskell.LSP.Control
-import Language.Haskell.LSP.Core
-import Language.Haskell.LSP.Types
+import Language.LSP.Control
+import Language.LSP.Core
+import Language.LSP.Types
import System.Directory
import System.FilePath
import UnliftIO