-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Functional test framework for LSP servers.
--   
--   A test framework for writing tests against <a>Language Server Protocol
--   servers</a>. <tt>Language.Haskell.LSP.Test</tt> launches your server
--   as a subprocess and allows you to simulate a session down to the wire,
--   and <tt>Language.Haskell.LSP.Test</tt> can replay captured sessions
--   from <a>https://hackage.haskell.org/package/haskell-lsp</a>. It's
--   currently used for testing in <a>haskell-ide-engine</a>.
@package lsp-test
@version 0.5.0.2


-- | Provides the framework to start functionally testing <a>Language
--   Server Protocol servers</a>. You should import
--   <a>Language.Haskell.LSP.Types</a> alongside this.
module Language.Haskell.LSP.Test

-- | A session representing one instance of launching and connecting to a
--   server.
--   
--   You can send and receive messages to the server within <a>Session</a>
--   via <tt>getMessage</tt>, <tt>sendRequest</tt> and
--   <tt>sendNotification</tt>.
type Session = ParserStateReader FromServerMessage SessionState SessionContext IO

-- | Starts a new session.
--   
--   <pre>
--   runSession "hie" fullCaps "path/to/root/dir" $ do
--     doc &lt;- openDoc "Desktop/simple.hs" "haskell"
--     diags &lt;- waitForDiagnostics
--     let pos = Position 12 5
--         params = TextDocumentPositionParams doc
--     hover &lt;- request TextDocumentHover params
--   </pre>
runSession :: String -> ClientCapabilities -> FilePath -> Session a -> IO a

-- | Starts a new sesion with a custom configuration.
runSessionWithConfig :: SessionConfig -> String -> ClientCapabilities -> FilePath -> Session a -> IO a

-- | Stuff you can configure for a <a>Session</a>.
data SessionConfig
SessionConfig :: Int -> Bool -> Bool -> Bool -> Maybe Value -> SessionConfig

-- | Maximum time to wait for a message in seconds, defaults to 60.
[messageTimeout] :: SessionConfig -> Int

-- | Redirect the server's stderr to this stdout, defaults to False.
[logStdErr] :: SessionConfig -> Bool

-- | Trace the messages sent and received to stdout, defaults to False.
[logMessages] :: SessionConfig -> Bool

-- | Add ANSI color to the logged messages, defaults to True.
[logColor] :: SessionConfig -> Bool

-- | The initial LSP config as JSON value, defaults to Nothing.
[lspConfig] :: SessionConfig -> Maybe Value

-- | The configuration used in <a>runSession</a>.
defaultConfig :: SessionConfig

-- | The whole shebang. The real deal. Capabilities for full conformance to
--   the current (v3.10) LSP specification.
fullCaps :: ClientCapabilities

-- | An exception that can be thrown during a <a>Session</a>
data SessionException
Timeout :: SessionException
UnexpectedMessage :: String -> FromServerMessage -> SessionException
ReplayOutOfOrder :: FromServerMessage -> [FromServerMessage] -> SessionException
UnexpectedDiagnostics :: SessionException
IncorrectApplyEditRequest :: String -> SessionException
UnexpectedResponseError :: LspIdRsp -> ResponseError -> SessionException

-- | A predicate that matches on any <a>SessionException</a>
anySessionException :: SessionException -> Bool

-- | Execute a block f that will throw a <tt>TimeoutException</tt> after
--   duration seconds. This will override the global timeout for waiting
--   for messages to arrive defined in <a>SessionConfig</a>.
withTimeout :: Int -> Session a -> Session a

-- | Sends a request to the server and waits for its response. Will skip
--   any messages in between the request and the response <tt> rsp &lt;-
--   request TextDocumentDocumentSymbol params :: Session
--   DocumentSymbolsResponse </tt> Note: will skip any messages in between
--   the request and the response.
request :: (ToJSON params, FromJSON a) => ClientMethod -> params -> Session (ResponseMessage a)

-- | The same as <a>sendRequest</a>, but discard the response.
request_ :: ToJSON params => ClientMethod -> params -> Session ()

-- | Sends a request to the server. Unlike <a>request</a>, this doesn't
--   wait for the response.
sendRequest :: ToJSON params => ClientMethod -> params -> Session LspId

-- | Sends a notification to the server.
sendNotification :: ToJSON a => ClientMethod -> a -> Session ()

-- | Sends a response to the server.
sendResponse :: ToJSON a => ResponseMessage a -> Session ()

-- | Matches a message of type <tt>a</tt>.
message :: forall a. (Typeable a, FromJSON a) => Session a

-- | Matches if the message is a request.
anyRequest :: Session FromServerMessage

-- | Matches if the message is a response.
anyResponse :: Session FromServerMessage

-- | Matches if the message is a notification.
anyNotification :: Session FromServerMessage

-- | Matches any type of message.
anyMessage :: Session FromServerMessage

-- | Matches if the message is a log message notification or a show message
--   notification/request.
loggingNotification :: Session FromServerMessage

-- | Matches a <a>PublishDiagnosticsNotification</a>
--   (textDocument/publishDiagnostics) notification.
publishDiagnosticsNotification :: Session PublishDiagnosticsNotification

-- | Matches a response for a specific id.
responseForId :: forall a. FromJSON a => LspId -> Session (ResponseMessage a)

-- | Returns the initialize response that was received from the server. The
--   initialize requests and responses are not included the session, so if
--   you need to test it use this.
initializeResponse :: Session InitializeResponse

-- | Opens a text document and sends a notification to the client.
openDoc :: FilePath -> String -> Session TextDocumentIdentifier

-- | Closes a text document and sends a notification to the client.
closeDoc :: TextDocumentIdentifier -> Session ()

-- | The current text contents of a document.
documentContents :: TextDocumentIdentifier -> Session Text

-- | Parses an ApplyEditRequest, checks that it is for the passed document
--   and returns the new content
getDocumentEdit :: TextDocumentIdentifier -> Session Text

-- | Gets the Uri for the file corrected to the session directory.
getDocUri :: FilePath -> Session Uri

-- | Adds the current version to the document, as tracked by the session.
getVersionedDoc :: TextDocumentIdentifier -> Session VersionedTextDocumentIdentifier

-- | Returns the symbols in a document.
getDocumentSymbols :: TextDocumentIdentifier -> Session (Either [DocumentSymbol] [SymbolInformation])

-- | Waits for diagnostics to be published and returns them.
waitForDiagnostics :: Session [Diagnostic]

-- | The same as <a>waitForDiagnostics</a>, but will only match a specific
--   <a>$sel:_source:Diagnostic</a>.
waitForDiagnosticsSource :: String -> Session [Diagnostic]

-- | Expects a <a>PublishDiagnosticsNotification</a> and throws an
--   <tt>UnexpectedDiagnosticsException</tt> if there are any diagnostics
--   returned.
noDiagnostics :: Session ()

-- | Returns the current diagnostics that have been sent to the client.
--   Note that this does not wait for more to come in.
getCurrentDiagnostics :: TextDocumentIdentifier -> Session [Diagnostic]

-- | Executes a command.
executeCommand :: Command -> Session ()

-- | Returns the code actions in the specified range.
getCodeActions :: TextDocumentIdentifier -> Range -> Session [CAResult]

-- | Returns all the code actions in a document by querying the code
--   actions at each of the current diagnostics' positions.
getAllCodeActions :: TextDocumentIdentifier -> Session [CAResult]

-- | Executes a code action. Matching with the specification, if a code
--   action contains both an edit and a command, the edit will be applied
--   first.
executeCodeAction :: CodeAction -> Session ()

-- | Returns the completions for the position in the document.
getCompletions :: TextDocumentIdentifier -> Position -> Session [CompletionItem]

-- | Returns the references for the position in the document.
getReferences :: TextDocumentIdentifier -> Position -> Bool -> Session [Location]

-- | Returns the definition(s) for the term at the specified position.
getDefinitions :: TextDocumentIdentifier -> Position -> Session [Location]

-- | Renames the term at the specified position.
rename :: TextDocumentIdentifier -> Position -> String -> Session ()

-- | Returns the hover information at the specified position.
getHover :: TextDocumentIdentifier -> Position -> Session (Maybe Hover)

-- | Returns the highlighted occurences of the term at the specified
--   position
getHighlights :: TextDocumentIdentifier -> Position -> Session [DocumentHighlight]

-- | Applies formatting to the specified document.
formatDoc :: TextDocumentIdentifier -> FormattingOptions -> Session ()

-- | Applies formatting to the specified range in a document.
formatRange :: TextDocumentIdentifier -> FormattingOptions -> Range -> Session ()

-- | Applys an edit to the document and returns the updated document
--   version.
applyEdit :: TextDocumentIdentifier -> TextEdit -> Session VersionedTextDocumentIdentifier
instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.LSP.Test.RequestMessage' a)


-- | 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

-- | Replays a captured client output and makes sure it matches up with an
--   expected response. The session directory should have a captured
--   session file in it named "session.log".
replaySession :: String -> FilePath -> IO ()
