packages feed

hls-test-utils 2.8.0.0 → 2.9.0.0

raw patch · 6 files changed

+859/−258 lines, 6 filesdep +lspdep +neat-interpolationdep +text-ropedep −row-typesdep ~ghcidedep ~hls-plugin-apidep ~lsp-typesPVP ok

version bump matches the API change (PVP)

Dependencies added: lsp, neat-interpolation, text-rope

Dependencies removed: row-types

Dependency ranges changed: ghcide, hls-plugin-api, lsp-types

API changes (from Hackage documentation)

- Test.Hls: TraceValues_Messages :: TraceValues
- Test.Hls: TraceValues_Off :: TraceValues
- Test.Hls: TraceValues_Verbose :: TraceValues
- Test.Hls: data () => TraceValues
- Test.Hls: pluginTestRecorder :: Pretty a => IO (Recorder (WithPriority a))
- Test.Hls: runSessionWithServer' :: IdePlugins IdeState -> Config -> SessionConfig -> ClientCapabilities -> FilePath -> Session a -> IO a
- Test.Hls: runSessionWithServerAndCaps :: Pretty b => Config -> PluginTestDescriptor b -> ClientCapabilities -> FilePath -> Session a -> IO a
- Test.Hls: runSessionWithServerAndCapsInTmpDir :: Pretty b => Config -> PluginTestDescriptor b -> ClientCapabilities -> VirtualFileTree -> Session a -> IO a
- Test.Hls: runSessionWithServerInTmpDir' :: IdePlugins IdeState -> Config -> SessionConfig -> ClientCapabilities -> VirtualFileTree -> Session a -> IO a
- Test.Hls.Util: expectSameLocations :: [Location] -> [SymbolLocation] -> Assertion
- Test.Hls.Util: type SymbolLocation = (FilePath, UInt, UInt)
+ Development.IDE.Test: canonicalizeUri :: Uri -> IO Uri
+ Development.IDE.Test: checkDiagnosticsForDoc :: HasCallStack => TextDocumentIdentifier -> [(DiagnosticSeverity, Cursor, Text)] -> [Diagnostic] -> Session ()
+ Development.IDE.Test: configureCheckProject :: Bool -> Session ()
+ Development.IDE.Test: cursorPosition :: Cursor -> Position
+ Development.IDE.Test: diagnostic :: Session (TNotificationMessage Method_TextDocumentPublishDiagnostics)
+ Development.IDE.Test: expectCurrentDiagnostics :: HasCallStack => TextDocumentIdentifier -> [(DiagnosticSeverity, Cursor, Text)] -> Session ()
+ Development.IDE.Test: expectDiagnostics :: HasCallStack => [(FilePath, [(DiagnosticSeverity, Cursor, Text)])] -> Session ()
+ Development.IDE.Test: expectDiagnosticsWithTags :: HasCallStack => [(String, [(DiagnosticSeverity, Cursor, Text, Maybe DiagnosticTag)])] -> Session ()
+ Development.IDE.Test: expectMessages :: SMethod m -> Seconds -> (TServerMessage m -> Session ()) -> Session ()
+ Development.IDE.Test: expectNoMoreDiagnostics :: HasCallStack => Seconds -> Session ()
+ Development.IDE.Test: flushMessages :: Session ()
+ Development.IDE.Test: garbageCollectDirtyKeys :: CheckParents -> Int -> Session [String]
+ Development.IDE.Test: getFilesOfInterest :: Session [FilePath]
+ Development.IDE.Test: getInterfaceFilesDir :: TextDocumentIdentifier -> Session FilePath
+ Development.IDE.Test: getStoredKeys :: Session [Text]
+ Development.IDE.Test: isReferenceReady :: FilePath -> Session ()
+ Development.IDE.Test: referenceReady :: (FilePath -> Bool) -> Session FilePath
+ Development.IDE.Test: requireDiagnostic :: (Foldable f, Show (f Diagnostic), HasCallStack) => f Diagnostic -> (DiagnosticSeverity, Cursor, Text, Maybe DiagnosticTag) -> Maybe ErrorMsg
+ Development.IDE.Test: standardizeQuotes :: Text -> Text
+ Development.IDE.Test: type Cursor = (UInt, UInt)
+ Development.IDE.Test: waitForAction :: String -> TextDocumentIdentifier -> Session WaitForIdeRuleResult
+ Development.IDE.Test: waitForBuildQueue :: Session ()
+ Development.IDE.Test: waitForCustomMessage :: Text -> (Value -> Maybe res) -> Session res
+ Development.IDE.Test: waitForGC :: Session [Text]
+ Development.IDE.Test: waitForTypecheck :: TextDocumentIdentifier -> Session Bool
+ Development.IDE.Test.Diagnostic: cursorPosition :: Cursor -> Position
+ Development.IDE.Test.Diagnostic: requireDiagnostic :: (Foldable f, Show (f Diagnostic), HasCallStack) => f Diagnostic -> (DiagnosticSeverity, Cursor, Text, Maybe DiagnosticTag) -> Maybe ErrorMsg
+ Development.IDE.Test.Diagnostic: standardizeQuotes :: Text -> Text
+ Development.IDE.Test.Diagnostic: type Cursor = (UInt, UInt)
+ Development.IDE.Test.Diagnostic: type ErrorMsg = String
+ Test.Hls: ChangeAnnotationsSupportOptions :: Maybe Bool -> ChangeAnnotationsSupportOptions
+ Test.Hls: ClientCodeActionKindOptions :: [CodeActionKind] -> ClientCodeActionKindOptions
+ Test.Hls: ClientCodeActionLiteralOptions :: ClientCodeActionKindOptions -> ClientCodeActionLiteralOptions
+ Test.Hls: ClientCodeActionResolveOptions :: [Text] -> ClientCodeActionResolveOptions
+ Test.Hls: ClientCompletionItemInsertTextModeOptions :: [InsertTextMode] -> ClientCompletionItemInsertTextModeOptions
+ Test.Hls: ClientCompletionItemOptions :: Maybe Bool -> Maybe Bool -> Maybe [MarkupKind] -> Maybe Bool -> Maybe Bool -> Maybe CompletionItemTagOptions -> Maybe Bool -> Maybe ClientCompletionItemResolveOptions -> Maybe ClientCompletionItemInsertTextModeOptions -> Maybe Bool -> ClientCompletionItemOptions
+ Test.Hls: ClientCompletionItemOptionsKind :: Maybe [CompletionItemKind] -> ClientCompletionItemOptionsKind
+ Test.Hls: ClientCompletionItemResolveOptions :: [Text] -> ClientCompletionItemResolveOptions
+ Test.Hls: ClientDiagnosticsTagOptions :: [DiagnosticTag] -> ClientDiagnosticsTagOptions
+ Test.Hls: ClientFoldingRangeKindOptions :: Maybe [FoldingRangeKind] -> ClientFoldingRangeKindOptions
+ Test.Hls: ClientFoldingRangeOptions :: Maybe Bool -> ClientFoldingRangeOptions
+ Test.Hls: ClientInfo :: Text -> Maybe Text -> ClientInfo
+ Test.Hls: ClientInlayHintResolveOptions :: [Text] -> ClientInlayHintResolveOptions
+ Test.Hls: ClientSemanticTokensRequestFullDelta :: Maybe Bool -> ClientSemanticTokensRequestFullDelta
+ Test.Hls: ClientSemanticTokensRequestOptions :: Maybe (Bool |? Rec (Empty :: Row Type)) -> Maybe (Bool |? ClientSemanticTokensRequestFullDelta) -> ClientSemanticTokensRequestOptions
+ Test.Hls: ClientShowMessageActionItemOptions :: Maybe Bool -> ClientShowMessageActionItemOptions
+ Test.Hls: ClientSignatureInformationOptions :: Maybe [MarkupKind] -> Maybe ClientSignatureParameterInformationOptions -> Maybe Bool -> ClientSignatureInformationOptions
+ Test.Hls: ClientSignatureParameterInformationOptions :: Maybe Bool -> ClientSignatureParameterInformationOptions
+ Test.Hls: ClientSymbolKindOptions :: Maybe [SymbolKind] -> ClientSymbolKindOptions
+ Test.Hls: ClientSymbolResolveOptions :: [Text] -> ClientSymbolResolveOptions
+ Test.Hls: ClientSymbolTagOptions :: [SymbolTag] -> ClientSymbolTagOptions
+ Test.Hls: CodeActionDisabled :: Text -> CodeActionDisabled
+ Test.Hls: CodeActionKind_Notebook :: CodeActionKind
+ Test.Hls: CompletionItemDefaults :: Maybe [Text] -> Maybe (Range |? EditRangeWithInsertReplace) -> Maybe InsertTextFormat -> Maybe InsertTextMode -> Maybe Value -> CompletionItemDefaults
+ Test.Hls: CompletionItemTagOptions :: [CompletionItemTag] -> CompletionItemTagOptions
+ Test.Hls: CompletionListCapabilities :: Maybe [Text] -> CompletionListCapabilities
+ Test.Hls: EditRangeWithInsertReplace :: Range -> Range -> EditRangeWithInsertReplace
+ Test.Hls: LanguageKind_ABAP :: LanguageKind
+ Test.Hls: LanguageKind_BibTeX :: LanguageKind
+ Test.Hls: LanguageKind_C :: LanguageKind
+ Test.Hls: LanguageKind_CPP :: LanguageKind
+ Test.Hls: LanguageKind_CSS :: LanguageKind
+ Test.Hls: LanguageKind_CSharp :: LanguageKind
+ Test.Hls: LanguageKind_Clojure :: LanguageKind
+ Test.Hls: LanguageKind_Coffeescript :: LanguageKind
+ Test.Hls: LanguageKind_Custom :: Text -> LanguageKind
+ Test.Hls: LanguageKind_Dart :: LanguageKind
+ Test.Hls: LanguageKind_Diff :: LanguageKind
+ Test.Hls: LanguageKind_Dockerfile :: LanguageKind
+ Test.Hls: LanguageKind_Elixir :: LanguageKind
+ Test.Hls: LanguageKind_Erlang :: LanguageKind
+ Test.Hls: LanguageKind_FSharp :: LanguageKind
+ Test.Hls: LanguageKind_GitCommit :: LanguageKind
+ Test.Hls: LanguageKind_GitRebase :: LanguageKind
+ Test.Hls: LanguageKind_Go :: LanguageKind
+ Test.Hls: LanguageKind_Groovy :: LanguageKind
+ Test.Hls: LanguageKind_HTML :: LanguageKind
+ Test.Hls: LanguageKind_Handlebars :: LanguageKind
+ Test.Hls: LanguageKind_Haskell :: LanguageKind
+ Test.Hls: LanguageKind_Ini :: LanguageKind
+ Test.Hls: LanguageKind_JSON :: LanguageKind
+ Test.Hls: LanguageKind_Java :: LanguageKind
+ Test.Hls: LanguageKind_JavaScript :: LanguageKind
+ Test.Hls: LanguageKind_JavaScriptReact :: LanguageKind
+ Test.Hls: LanguageKind_LaTeX :: LanguageKind
+ Test.Hls: LanguageKind_Less :: LanguageKind
+ Test.Hls: LanguageKind_Lua :: LanguageKind
+ Test.Hls: LanguageKind_Makefile :: LanguageKind
+ Test.Hls: LanguageKind_Markdown :: LanguageKind
+ Test.Hls: LanguageKind_ObjectiveC :: LanguageKind
+ Test.Hls: LanguageKind_ObjectiveCPP :: LanguageKind
+ Test.Hls: LanguageKind_PHP :: LanguageKind
+ Test.Hls: LanguageKind_Perl :: LanguageKind
+ Test.Hls: LanguageKind_Perl6 :: LanguageKind
+ Test.Hls: LanguageKind_Powershell :: LanguageKind
+ Test.Hls: LanguageKind_Pug :: LanguageKind
+ Test.Hls: LanguageKind_Python :: LanguageKind
+ Test.Hls: LanguageKind_R :: LanguageKind
+ Test.Hls: LanguageKind_Razor :: LanguageKind
+ Test.Hls: LanguageKind_Ruby :: LanguageKind
+ Test.Hls: LanguageKind_Rust :: LanguageKind
+ Test.Hls: LanguageKind_SASS :: LanguageKind
+ Test.Hls: LanguageKind_SCSS :: LanguageKind
+ Test.Hls: LanguageKind_SQL :: LanguageKind
+ Test.Hls: LanguageKind_Scala :: LanguageKind
+ Test.Hls: LanguageKind_ShaderLab :: LanguageKind
+ Test.Hls: LanguageKind_ShellScript :: LanguageKind
+ Test.Hls: LanguageKind_Swift :: LanguageKind
+ Test.Hls: LanguageKind_TeX :: LanguageKind
+ Test.Hls: LanguageKind_TypeScript :: LanguageKind
+ Test.Hls: LanguageKind_TypeScriptReact :: LanguageKind
+ Test.Hls: LanguageKind_VisualBasic :: LanguageKind
+ Test.Hls: LanguageKind_WindowsBat :: LanguageKind
+ Test.Hls: LanguageKind_XML :: LanguageKind
+ Test.Hls: LanguageKind_XSL :: LanguageKind
+ Test.Hls: LanguageKind_YAML :: LanguageKind
+ Test.Hls: LocationUriOnly :: Uri -> LocationUriOnly
+ Test.Hls: MarkedStringWithLanguage :: Text -> Text -> MarkedStringWithLanguage
+ Test.Hls: NotebookCellLanguage :: Text -> NotebookCellLanguage
+ Test.Hls: NotebookDocumentCellChangeStructure :: NotebookCellArrayChange -> Maybe [TextDocumentItem] -> Maybe [TextDocumentIdentifier] -> NotebookDocumentCellChangeStructure
+ Test.Hls: NotebookDocumentCellChanges :: Maybe NotebookDocumentCellChangeStructure -> Maybe [NotebookCell] -> Maybe [NotebookDocumentCellContentChanges] -> NotebookDocumentCellChanges
+ Test.Hls: NotebookDocumentCellContentChanges :: VersionedTextDocumentIdentifier -> [TextDocumentContentChangeEvent] -> NotebookDocumentCellContentChanges
+ Test.Hls: NotebookDocumentFilterNotebookType :: Text -> Maybe Text -> Maybe Text -> NotebookDocumentFilterNotebookType
+ Test.Hls: NotebookDocumentFilterPattern :: Maybe Text -> Maybe Text -> Text -> NotebookDocumentFilterPattern
+ Test.Hls: NotebookDocumentFilterScheme :: Maybe Text -> Text -> Maybe Text -> NotebookDocumentFilterScheme
+ Test.Hls: NotebookDocumentFilterWithCells :: Maybe (Text |? NotebookDocumentFilter) -> [NotebookCellLanguage] -> NotebookDocumentFilterWithCells
+ Test.Hls: NotebookDocumentFilterWithNotebook :: (Text |? NotebookDocumentFilter) -> Maybe [NotebookCellLanguage] -> NotebookDocumentFilterWithNotebook
+ Test.Hls: PrepareRenameDefaultBehavior :: Bool -> PrepareRenameDefaultBehavior
+ Test.Hls: PrepareRenamePlaceholder :: Range -> Text -> PrepareRenamePlaceholder
+ Test.Hls: RegularExpressionEngineKind :: Text -> RegularExpressionEngineKind
+ Test.Hls: SemanticTokensFullDelta :: Maybe Bool -> SemanticTokensFullDelta
+ Test.Hls: ServerCompletionItemOptions :: Maybe Bool -> ServerCompletionItemOptions
+ Test.Hls: ServerInfo :: Text -> Maybe Text -> ServerInfo
+ Test.Hls: StaleRequestSupportOptions :: Bool -> [Text] -> StaleRequestSupportOptions
+ Test.Hls: TestConfig :: Either FilePath VirtualFileTree -> Bool -> Maybe FilePath -> Maybe FilePath -> Bool -> Bool -> Bool -> PluginTestDescriptor b -> Config -> SessionConfig -> ClientCapabilities -> TestConfig b
+ Test.Hls: TextDocumentContentChangePartial :: Range -> Maybe UInt -> Text -> TextDocumentContentChangePartial
+ Test.Hls: TextDocumentContentChangeWholeDocument :: Text -> TextDocumentContentChangeWholeDocument
+ Test.Hls: TextDocumentFilterLanguage :: Text -> Maybe Text -> Maybe Text -> TextDocumentFilterLanguage
+ Test.Hls: TextDocumentFilterPattern :: Maybe Text -> Maybe Text -> Text -> TextDocumentFilterPattern
+ Test.Hls: TextDocumentFilterScheme :: Maybe Text -> Text -> Maybe Text -> TextDocumentFilterScheme
+ Test.Hls: TraceValue_Messages :: TraceValue
+ Test.Hls: TraceValue_Off :: TraceValue
+ Test.Hls: TraceValue_Verbose :: TraceValue
+ Test.Hls: WorkspaceOptions :: Maybe WorkspaceFoldersServerCapabilities -> Maybe FileOperationOptions -> WorkspaceOptions
+ Test.Hls: [$sel:_activeParameterSupport:ClientSignatureInformationOptions] :: ClientSignatureInformationOptions -> Maybe Bool
+ Test.Hls: [$sel:_additionalPropertiesSupport:ClientShowMessageActionItemOptions] :: ClientShowMessageActionItemOptions -> Maybe Bool
+ Test.Hls: [$sel:_array:NotebookDocumentCellChangeStructure] :: NotebookDocumentCellChangeStructure -> NotebookCellArrayChange
+ Test.Hls: [$sel:_cancel:StaleRequestSupportOptions] :: StaleRequestSupportOptions -> Bool
+ Test.Hls: [$sel:_cells:NotebookDocumentFilterWithCells] :: NotebookDocumentFilterWithCells -> [NotebookCellLanguage]
+ Test.Hls: [$sel:_cells:NotebookDocumentFilterWithNotebook] :: NotebookDocumentFilterWithNotebook -> Maybe [NotebookCellLanguage]
+ Test.Hls: [$sel:_changes:NotebookDocumentCellContentChanges] :: NotebookDocumentCellContentChanges -> [TextDocumentContentChangeEvent]
+ Test.Hls: [$sel:_codeActionKind:ClientCodeActionLiteralOptions] :: ClientCodeActionLiteralOptions -> ClientCodeActionKindOptions
+ Test.Hls: [$sel:_collapsedText:ClientFoldingRangeOptions] :: ClientFoldingRangeOptions -> Maybe Bool
+ Test.Hls: [$sel:_commitCharacters:CompletionItemDefaults] :: CompletionItemDefaults -> Maybe [Text]
+ Test.Hls: [$sel:_commitCharactersSupport:ClientCompletionItemOptions] :: ClientCompletionItemOptions -> Maybe Bool
+ Test.Hls: [$sel:_data_:CompletionItemDefaults] :: CompletionItemDefaults -> Maybe Value
+ Test.Hls: [$sel:_data_:NotebookDocumentCellChanges] :: NotebookDocumentCellChanges -> Maybe [NotebookCell]
+ Test.Hls: [$sel:_defaultBehavior:PrepareRenameDefaultBehavior] :: PrepareRenameDefaultBehavior -> Bool
+ Test.Hls: [$sel:_delta:ClientSemanticTokensRequestFullDelta] :: ClientSemanticTokensRequestFullDelta -> Maybe Bool
+ Test.Hls: [$sel:_delta:SemanticTokensFullDelta] :: SemanticTokensFullDelta -> Maybe Bool
+ Test.Hls: [$sel:_deprecatedSupport:ClientCompletionItemOptions] :: ClientCompletionItemOptions -> Maybe Bool
+ Test.Hls: [$sel:_didClose:NotebookDocumentCellChangeStructure] :: NotebookDocumentCellChangeStructure -> Maybe [TextDocumentIdentifier]
+ Test.Hls: [$sel:_didOpen:NotebookDocumentCellChangeStructure] :: NotebookDocumentCellChangeStructure -> Maybe [TextDocumentItem]
+ Test.Hls: [$sel:_document:NotebookDocumentCellContentChanges] :: NotebookDocumentCellContentChanges -> VersionedTextDocumentIdentifier
+ Test.Hls: [$sel:_documentationFormat:ClientCompletionItemOptions] :: ClientCompletionItemOptions -> Maybe [MarkupKind]
+ Test.Hls: [$sel:_documentationFormat:ClientSignatureInformationOptions] :: ClientSignatureInformationOptions -> Maybe [MarkupKind]
+ Test.Hls: [$sel:_editRange:CompletionItemDefaults] :: CompletionItemDefaults -> Maybe (Range |? EditRangeWithInsertReplace)
+ Test.Hls: [$sel:_fileOperations:WorkspaceOptions] :: WorkspaceOptions -> Maybe FileOperationOptions
+ Test.Hls: [$sel:_full:ClientSemanticTokensRequestOptions] :: ClientSemanticTokensRequestOptions -> Maybe (Bool |? ClientSemanticTokensRequestFullDelta)
+ Test.Hls: [$sel:_groupsOnLabel:ChangeAnnotationsSupportOptions] :: ChangeAnnotationsSupportOptions -> Maybe Bool
+ Test.Hls: [$sel:_insert:EditRangeWithInsertReplace] :: EditRangeWithInsertReplace -> Range
+ Test.Hls: [$sel:_insertReplaceSupport:ClientCompletionItemOptions] :: ClientCompletionItemOptions -> Maybe Bool
+ Test.Hls: [$sel:_insertTextFormat:CompletionItemDefaults] :: CompletionItemDefaults -> Maybe InsertTextFormat
+ Test.Hls: [$sel:_insertTextMode:CompletionItemDefaults] :: CompletionItemDefaults -> Maybe InsertTextMode
+ Test.Hls: [$sel:_insertTextModeSupport:ClientCompletionItemOptions] :: ClientCompletionItemOptions -> Maybe ClientCompletionItemInsertTextModeOptions
+ Test.Hls: [$sel:_itemDefaults:CompletionListCapabilities] :: CompletionListCapabilities -> Maybe [Text]
+ Test.Hls: [$sel:_labelDetailsSupport:ClientCompletionItemOptions] :: ClientCompletionItemOptions -> Maybe Bool
+ Test.Hls: [$sel:_labelDetailsSupport:ServerCompletionItemOptions] :: ServerCompletionItemOptions -> Maybe Bool
+ Test.Hls: [$sel:_labelOffsetSupport:ClientSignatureParameterInformationOptions] :: ClientSignatureParameterInformationOptions -> Maybe Bool
+ Test.Hls: [$sel:_language:MarkedStringWithLanguage] :: MarkedStringWithLanguage -> Text
+ Test.Hls: [$sel:_language:NotebookCellLanguage] :: NotebookCellLanguage -> Text
+ Test.Hls: [$sel:_language:TextDocumentFilterLanguage] :: TextDocumentFilterLanguage -> Text
+ Test.Hls: [$sel:_language:TextDocumentFilterPattern] :: TextDocumentFilterPattern -> Maybe Text
+ Test.Hls: [$sel:_language:TextDocumentFilterScheme] :: TextDocumentFilterScheme -> Maybe Text
+ Test.Hls: [$sel:_name:ClientInfo] :: ClientInfo -> Text
+ Test.Hls: [$sel:_name:ServerInfo] :: ServerInfo -> Text
+ Test.Hls: [$sel:_notebook:NotebookDocumentFilterWithCells] :: NotebookDocumentFilterWithCells -> Maybe (Text |? NotebookDocumentFilter)
+ Test.Hls: [$sel:_notebook:NotebookDocumentFilterWithNotebook] :: NotebookDocumentFilterWithNotebook -> Text |? NotebookDocumentFilter
+ Test.Hls: [$sel:_notebookType:NotebookDocumentFilterNotebookType] :: NotebookDocumentFilterNotebookType -> Text
+ Test.Hls: [$sel:_notebookType:NotebookDocumentFilterPattern] :: NotebookDocumentFilterPattern -> Maybe Text
+ Test.Hls: [$sel:_notebookType:NotebookDocumentFilterScheme] :: NotebookDocumentFilterScheme -> Maybe Text
+ Test.Hls: [$sel:_parameterInformation:ClientSignatureInformationOptions] :: ClientSignatureInformationOptions -> Maybe ClientSignatureParameterInformationOptions
+ Test.Hls: [$sel:_pattern:NotebookDocumentFilterNotebookType] :: NotebookDocumentFilterNotebookType -> Maybe Text
+ Test.Hls: [$sel:_pattern:NotebookDocumentFilterPattern] :: NotebookDocumentFilterPattern -> Text
+ Test.Hls: [$sel:_pattern:NotebookDocumentFilterScheme] :: NotebookDocumentFilterScheme -> Maybe Text
+ Test.Hls: [$sel:_pattern:TextDocumentFilterLanguage] :: TextDocumentFilterLanguage -> Maybe Text
+ Test.Hls: [$sel:_pattern:TextDocumentFilterPattern] :: TextDocumentFilterPattern -> Text
+ Test.Hls: [$sel:_pattern:TextDocumentFilterScheme] :: TextDocumentFilterScheme -> Maybe Text
+ Test.Hls: [$sel:_placeholder:PrepareRenamePlaceholder] :: PrepareRenamePlaceholder -> Text
+ Test.Hls: [$sel:_preselectSupport:ClientCompletionItemOptions] :: ClientCompletionItemOptions -> Maybe Bool
+ Test.Hls: [$sel:_properties:ClientCodeActionResolveOptions] :: ClientCodeActionResolveOptions -> [Text]
+ Test.Hls: [$sel:_properties:ClientCompletionItemResolveOptions] :: ClientCompletionItemResolveOptions -> [Text]
+ Test.Hls: [$sel:_properties:ClientInlayHintResolveOptions] :: ClientInlayHintResolveOptions -> [Text]
+ Test.Hls: [$sel:_properties:ClientSymbolResolveOptions] :: ClientSymbolResolveOptions -> [Text]
+ Test.Hls: [$sel:_range:ClientSemanticTokensRequestOptions] :: ClientSemanticTokensRequestOptions -> Maybe (Bool |? Rec (Empty :: Row Type))
+ Test.Hls: [$sel:_range:PrepareRenamePlaceholder] :: PrepareRenamePlaceholder -> Range
+ Test.Hls: [$sel:_range:TextDocumentContentChangePartial] :: TextDocumentContentChangePartial -> Range
+ Test.Hls: [$sel:_rangeLength:TextDocumentContentChangePartial] :: TextDocumentContentChangePartial -> Maybe UInt
+ Test.Hls: [$sel:_reason:CodeActionDisabled] :: CodeActionDisabled -> Text
+ Test.Hls: [$sel:_replace:EditRangeWithInsertReplace] :: EditRangeWithInsertReplace -> Range
+ Test.Hls: [$sel:_resolveSupport:ClientCompletionItemOptions] :: ClientCompletionItemOptions -> Maybe ClientCompletionItemResolveOptions
+ Test.Hls: [$sel:_retryOnContentModified:StaleRequestSupportOptions] :: StaleRequestSupportOptions -> [Text]
+ Test.Hls: [$sel:_scheme:NotebookDocumentFilterNotebookType] :: NotebookDocumentFilterNotebookType -> Maybe Text
+ Test.Hls: [$sel:_scheme:NotebookDocumentFilterPattern] :: NotebookDocumentFilterPattern -> Maybe Text
+ Test.Hls: [$sel:_scheme:NotebookDocumentFilterScheme] :: NotebookDocumentFilterScheme -> Text
+ Test.Hls: [$sel:_scheme:TextDocumentFilterLanguage] :: TextDocumentFilterLanguage -> Maybe Text
+ Test.Hls: [$sel:_scheme:TextDocumentFilterPattern] :: TextDocumentFilterPattern -> Maybe Text
+ Test.Hls: [$sel:_scheme:TextDocumentFilterScheme] :: TextDocumentFilterScheme -> Text
+ Test.Hls: [$sel:_snippetSupport:ClientCompletionItemOptions] :: ClientCompletionItemOptions -> Maybe Bool
+ Test.Hls: [$sel:_structure:NotebookDocumentCellChanges] :: NotebookDocumentCellChanges -> Maybe NotebookDocumentCellChangeStructure
+ Test.Hls: [$sel:_tagSupport:ClientCompletionItemOptions] :: ClientCompletionItemOptions -> Maybe CompletionItemTagOptions
+ Test.Hls: [$sel:_text:TextDocumentContentChangePartial] :: TextDocumentContentChangePartial -> Text
+ Test.Hls: [$sel:_text:TextDocumentContentChangeWholeDocument] :: TextDocumentContentChangeWholeDocument -> Text
+ Test.Hls: [$sel:_textContent:NotebookDocumentCellChanges] :: NotebookDocumentCellChanges -> Maybe [NotebookDocumentCellContentChanges]
+ Test.Hls: [$sel:_uri:LocationUriOnly] :: LocationUriOnly -> Uri
+ Test.Hls: [$sel:_value:MarkedStringWithLanguage] :: MarkedStringWithLanguage -> Text
+ Test.Hls: [$sel:_valueSet:ClientCodeActionKindOptions] :: ClientCodeActionKindOptions -> [CodeActionKind]
+ Test.Hls: [$sel:_valueSet:ClientCompletionItemInsertTextModeOptions] :: ClientCompletionItemInsertTextModeOptions -> [InsertTextMode]
+ Test.Hls: [$sel:_valueSet:ClientCompletionItemOptionsKind] :: ClientCompletionItemOptionsKind -> Maybe [CompletionItemKind]
+ Test.Hls: [$sel:_valueSet:ClientDiagnosticsTagOptions] :: ClientDiagnosticsTagOptions -> [DiagnosticTag]
+ Test.Hls: [$sel:_valueSet:ClientFoldingRangeKindOptions] :: ClientFoldingRangeKindOptions -> Maybe [FoldingRangeKind]
+ Test.Hls: [$sel:_valueSet:ClientSymbolKindOptions] :: ClientSymbolKindOptions -> Maybe [SymbolKind]
+ Test.Hls: [$sel:_valueSet:ClientSymbolTagOptions] :: ClientSymbolTagOptions -> [SymbolTag]
+ Test.Hls: [$sel:_valueSet:CompletionItemTagOptions] :: CompletionItemTagOptions -> [CompletionItemTag]
+ Test.Hls: [$sel:_version:ClientInfo] :: ClientInfo -> Maybe Text
+ Test.Hls: [$sel:_version:ServerInfo] :: ServerInfo -> Maybe Text
+ Test.Hls: [$sel:_workspaceFolders:WorkspaceOptions] :: WorkspaceOptions -> Maybe WorkspaceFoldersServerCapabilities
+ Test.Hls: [$sel:testCheckProject:TestConfig] :: TestConfig b -> Bool
+ Test.Hls: [$sel:testClientRoot:TestConfig] :: TestConfig b -> Maybe FilePath
+ Test.Hls: [$sel:testConfigCaps:TestConfig] :: TestConfig b -> ClientCapabilities
+ Test.Hls: [$sel:testConfigSession:TestConfig] :: TestConfig b -> SessionConfig
+ Test.Hls: [$sel:testDirLocation:TestConfig] :: TestConfig b -> Either FilePath VirtualFileTree
+ Test.Hls: [$sel:testDisableDefaultPlugin:TestConfig] :: TestConfig b -> Bool
+ Test.Hls: [$sel:testDisableKick:TestConfig] :: TestConfig b -> Bool
+ Test.Hls: [$sel:testLspConfig:TestConfig] :: TestConfig b -> Config
+ Test.Hls: [$sel:testPluginDescriptor:TestConfig] :: TestConfig b -> PluginTestDescriptor b
+ Test.Hls: [$sel:testServerRoot:TestConfig] :: TestConfig b -> Maybe FilePath
+ Test.Hls: [$sel:testShiftRoot:TestConfig] :: TestConfig b -> Bool
+ Test.Hls: [callStack_] :: WithPriority a -> CallStack
+ Test.Hls: [payload] :: WithPriority a -> a
+ Test.Hls: [priority] :: WithPriority a -> Priority
+ Test.Hls: data () => ChangeAnnotationsSupportOptions
+ Test.Hls: data () => ClientCodeActionKindOptions
+ Test.Hls: data () => ClientCodeActionLiteralOptions
+ Test.Hls: data () => ClientCodeActionResolveOptions
+ Test.Hls: data () => ClientCompletionItemInsertTextModeOptions
+ Test.Hls: data () => ClientCompletionItemOptions
+ Test.Hls: data () => ClientCompletionItemOptionsKind
+ Test.Hls: data () => ClientCompletionItemResolveOptions
+ Test.Hls: data () => ClientDiagnosticsTagOptions
+ Test.Hls: data () => ClientFoldingRangeKindOptions
+ Test.Hls: data () => ClientFoldingRangeOptions
+ Test.Hls: data () => ClientInfo
+ Test.Hls: data () => ClientInlayHintResolveOptions
+ Test.Hls: data () => ClientSemanticTokensRequestFullDelta
+ Test.Hls: data () => ClientSemanticTokensRequestOptions
+ Test.Hls: data () => ClientShowMessageActionItemOptions
+ Test.Hls: data () => ClientSignatureInformationOptions
+ Test.Hls: data () => ClientSignatureParameterInformationOptions
+ Test.Hls: data () => ClientSymbolKindOptions
+ Test.Hls: data () => ClientSymbolResolveOptions
+ Test.Hls: data () => ClientSymbolTagOptions
+ Test.Hls: data () => CodeActionDisabled
+ Test.Hls: data () => CompletionItemDefaults
+ Test.Hls: data () => CompletionItemTagOptions
+ Test.Hls: data () => CompletionListCapabilities
+ Test.Hls: data () => EditRangeWithInsertReplace
+ Test.Hls: data () => LanguageKind
+ Test.Hls: data () => LocationUriOnly
+ Test.Hls: data () => MarkedStringWithLanguage
+ Test.Hls: data () => NotebookCellLanguage
+ Test.Hls: data () => NotebookDocumentCellChangeStructure
+ Test.Hls: data () => NotebookDocumentCellChanges
+ Test.Hls: data () => NotebookDocumentCellContentChanges
+ Test.Hls: data () => NotebookDocumentFilterNotebookType
+ Test.Hls: data () => NotebookDocumentFilterPattern
+ Test.Hls: data () => NotebookDocumentFilterScheme
+ Test.Hls: data () => NotebookDocumentFilterWithCells
+ Test.Hls: data () => NotebookDocumentFilterWithNotebook
+ Test.Hls: data () => PrepareRenameDefaultBehavior
+ Test.Hls: data () => PrepareRenamePlaceholder
+ Test.Hls: data () => SemanticTokensFullDelta
+ Test.Hls: data () => ServerCompletionItemOptions
+ Test.Hls: data () => ServerInfo
+ Test.Hls: data () => StaleRequestSupportOptions
+ Test.Hls: data TestConfig b
+ Test.Hls: data () => TextDocumentContentChangePartial
+ Test.Hls: data () => TextDocumentContentChangeWholeDocument
+ Test.Hls: data () => TextDocumentFilterLanguage
+ Test.Hls: data () => TextDocumentFilterPattern
+ Test.Hls: data () => TextDocumentFilterScheme
+ Test.Hls: data () => TraceValue
+ Test.Hls: data () => WorkspaceOptions
+ Test.Hls: goldenWithTestConfig :: Pretty b => TestConfig b -> TestName -> FilePath -> FilePath -> FilePath -> FilePath -> (TextDocumentIdentifier -> Session ()) -> TestTree
+ Test.Hls: hlsPluginTestRecorder :: Pretty a => IO (Recorder (WithPriority a))
+ Test.Hls: instance Data.Default.Class.Default (Test.Hls.TestConfig b)
+ Test.Hls: newtype () => RegularExpressionEngineKind
+ Test.Hls: parameterisedCursorTest :: (Show a, Eq a) => String -> Text -> [a] -> (Text -> PosPrefixInfo -> IO a) -> TestTree
+ Test.Hls: runSessionWithTestConfig :: Pretty b => TestConfig b -> (FilePath -> Session a) -> IO a
+ Test.Hls: waitForProgressBegin :: Session ()
+ Test.Hls.FileSystem: copyDir :: FilePath -> FileTree
+ Test.Hls.Util: GHC910 :: GhcVersion
+ Test.Hls.Util: extractCursorPositions :: Text -> (Text, [PosPrefixInfo])
+ Test.Hls.Util: mkParameterisedLabel :: PosPrefixInfo -> String
+ Test.Hls.Util: trimming :: QuasiQuoter
- Test.Hls: CodeAction :: Text -> Maybe CodeActionKind -> Maybe [Diagnostic] -> Maybe Bool -> Maybe (Rec (("reason" .== Text) .+ (Empty :: Row Type))) -> Maybe WorkspaceEdit -> Maybe Command -> Maybe Value -> CodeAction
+ Test.Hls: CodeAction :: Text -> Maybe CodeActionKind -> Maybe [Diagnostic] -> Maybe Bool -> Maybe CodeActionDisabled -> Maybe WorkspaceEdit -> Maybe Command -> Maybe Value -> CodeAction
- Test.Hls: CodeActionClientCapabilities :: Maybe Bool -> Maybe (Rec (("codeActionKind" .== Rec (("valueSet" .== [CodeActionKind]) .+ (Empty :: Row Type))) .+ (Empty :: Row Type))) -> Maybe Bool -> Maybe Bool -> Maybe Bool -> Maybe (Rec (("properties" .== [Text]) .+ (Empty :: Row Type))) -> Maybe Bool -> CodeActionClientCapabilities
+ Test.Hls: CodeActionClientCapabilities :: Maybe Bool -> Maybe ClientCodeActionLiteralOptions -> Maybe Bool -> Maybe Bool -> Maybe Bool -> Maybe ClientCodeActionResolveOptions -> Maybe Bool -> CodeActionClientCapabilities
- Test.Hls: CompletionClientCapabilities :: Maybe Bool -> Maybe (Rec (("snippetSupport" .== Maybe Bool) .+ (("commitCharactersSupport" .== Maybe Bool) .+ (("documentationFormat" .== Maybe [MarkupKind]) .+ (("deprecatedSupport" .== Maybe Bool) .+ (("preselectSupport" .== Maybe Bool) .+ (("tagSupport" .== Maybe (Rec (("valueSet" .== [CompletionItemTag]) .+ (Empty :: Row Type)))) .+ (("insertReplaceSupport" .== Maybe Bool) .+ (("resolveSupport" .== Maybe (Rec (("properties" .== [Text]) .+ (Empty :: Row Type)))) .+ (("insertTextModeSupport" .== Maybe (Rec (("valueSet" .== [InsertTextMode]) .+ (Empty :: Row Type)))) .+ (("labelDetailsSupport" .== Maybe Bool) .+ (Empty :: Row Type)))))))))))) -> Maybe (Rec (("valueSet" .== Maybe [CompletionItemKind]) .+ (Empty :: Row Type))) -> Maybe InsertTextMode -> Maybe Bool -> Maybe (Rec (("itemDefaults" .== Maybe [Text]) .+ (Empty :: Row Type))) -> CompletionClientCapabilities
+ Test.Hls: CompletionClientCapabilities :: Maybe Bool -> Maybe ClientCompletionItemOptions -> Maybe ClientCompletionItemOptionsKind -> Maybe InsertTextMode -> Maybe Bool -> Maybe CompletionListCapabilities -> CompletionClientCapabilities
- Test.Hls: CompletionList :: Bool -> Maybe (Rec (("commitCharacters" .== Maybe [Text]) .+ (("editRange" .== Maybe (Range |? Rec (("insert" .== Range) .+ (("replace" .== Range) .+ (Empty :: Row Type))))) .+ (("insertTextFormat" .== Maybe InsertTextFormat) .+ (("insertTextMode" .== Maybe InsertTextMode) .+ (("data" .== Maybe Value) .+ (Empty :: Row Type))))))) -> [CompletionItem] -> CompletionList
+ Test.Hls: CompletionList :: Bool -> Maybe CompletionItemDefaults -> [CompletionItem] -> CompletionList
- Test.Hls: CompletionOptions :: Maybe Bool -> Maybe [Text] -> Maybe [Text] -> Maybe Bool -> Maybe (Rec (("labelDetailsSupport" .== Maybe Bool) .+ (Empty :: Row Type))) -> CompletionOptions
+ Test.Hls: CompletionOptions :: Maybe Bool -> Maybe [Text] -> Maybe [Text] -> Maybe Bool -> Maybe ServerCompletionItemOptions -> CompletionOptions
- Test.Hls: CompletionRegistrationOptions :: (DocumentSelector |? Null) -> Maybe Bool -> Maybe [Text] -> Maybe [Text] -> Maybe Bool -> Maybe (Rec (("labelDetailsSupport" .== Maybe Bool) .+ (Empty :: Row Type))) -> CompletionRegistrationOptions
+ Test.Hls: CompletionRegistrationOptions :: (DocumentSelector |? Null) -> Maybe Bool -> Maybe [Text] -> Maybe [Text] -> Maybe Bool -> Maybe ServerCompletionItemOptions -> CompletionRegistrationOptions
- Test.Hls: ConfigurationItem :: Maybe Text -> Maybe Text -> ConfigurationItem
+ Test.Hls: ConfigurationItem :: Maybe Uri -> Maybe Text -> ConfigurationItem
- Test.Hls: DocumentLink :: Range -> Maybe Text -> Maybe Text -> Maybe Value -> DocumentLink
+ Test.Hls: DocumentLink :: Range -> Maybe Uri -> Maybe Text -> Maybe Value -> DocumentLink
- Test.Hls: DocumentSymbolClientCapabilities :: Maybe Bool -> Maybe (Rec (("valueSet" .== Maybe [SymbolKind]) .+ (Empty :: Row Type))) -> Maybe Bool -> Maybe (Rec (("valueSet" .== [SymbolTag]) .+ (Empty :: Row Type))) -> Maybe Bool -> DocumentSymbolClientCapabilities
+ Test.Hls: DocumentSymbolClientCapabilities :: Maybe Bool -> Maybe ClientSymbolKindOptions -> Maybe Bool -> Maybe ClientSymbolTagOptions -> Maybe Bool -> DocumentSymbolClientCapabilities
- Test.Hls: FoldingRangeClientCapabilities :: Maybe Bool -> Maybe UInt -> Maybe Bool -> Maybe (Rec (("valueSet" .== Maybe [FoldingRangeKind]) .+ (Empty :: Row Type))) -> Maybe (Rec (("collapsedText" .== Maybe Bool) .+ (Empty :: Row Type))) -> FoldingRangeClientCapabilities
+ Test.Hls: FoldingRangeClientCapabilities :: Maybe Bool -> Maybe UInt -> Maybe Bool -> Maybe ClientFoldingRangeKindOptions -> Maybe ClientFoldingRangeOptions -> FoldingRangeClientCapabilities
- Test.Hls: GeneralClientCapabilities :: Maybe (Rec (("cancel" .== Bool) .+ (("retryOnContentModified" .== [Text]) .+ (Empty :: Row Type)))) -> Maybe RegularExpressionsClientCapabilities -> Maybe MarkdownClientCapabilities -> Maybe [PositionEncodingKind] -> GeneralClientCapabilities
+ Test.Hls: GeneralClientCapabilities :: Maybe StaleRequestSupportOptions -> Maybe RegularExpressionsClientCapabilities -> Maybe MarkdownClientCapabilities -> Maybe [PositionEncodingKind] -> GeneralClientCapabilities
- Test.Hls: InitializeParams :: Maybe ProgressToken -> (Int32 |? Null) -> Maybe (Rec (("name" .== Text) .+ (("version" .== Maybe Text) .+ (Empty :: Row Type)))) -> Maybe Text -> Maybe (Text |? Null) -> (Uri |? Null) -> ClientCapabilities -> Maybe Value -> Maybe TraceValues -> Maybe ([WorkspaceFolder] |? Null) -> InitializeParams
+ Test.Hls: InitializeParams :: Maybe ProgressToken -> (Int32 |? Null) -> Maybe ClientInfo -> Maybe Text -> Maybe (Text |? Null) -> (Uri |? Null) -> ClientCapabilities -> Maybe Value -> Maybe TraceValue -> Maybe ([WorkspaceFolder] |? Null) -> InitializeParams
- Test.Hls: InitializeResult :: ServerCapabilities -> Maybe (Rec (("name" .== Text) .+ (("version" .== Maybe Text) .+ (Empty :: Row Type)))) -> InitializeResult
+ Test.Hls: InitializeResult :: ServerCapabilities -> Maybe ServerInfo -> InitializeResult
- Test.Hls: InlayHintClientCapabilities :: Maybe Bool -> Maybe (Rec (("properties" .== [Text]) .+ (Empty :: Row Type))) -> InlayHintClientCapabilities
+ Test.Hls: InlayHintClientCapabilities :: Maybe Bool -> Maybe ClientInlayHintResolveOptions -> InlayHintClientCapabilities
- Test.Hls: MarkedString :: (Text |? Rec (("language" .== Text) .+ (("value" .== Text) .+ (Empty :: Row Type)))) -> MarkedString
+ Test.Hls: MarkedString :: (Text |? MarkedStringWithLanguage) -> MarkedString
- Test.Hls: NotebookDocumentChangeEvent :: Maybe Object -> Maybe (Rec (("structure" .== Maybe (Rec (("array" .== NotebookCellArrayChange) .+ (("didOpen" .== Maybe [TextDocumentItem]) .+ (("didClose" .== Maybe [TextDocumentIdentifier]) .+ (Empty :: Row Type)))))) .+ (("data" .== Maybe [NotebookCell]) .+ (("textContent" .== Maybe [Rec (("document" .== VersionedTextDocumentIdentifier) .+ (("changes" .== [TextDocumentContentChangeEvent]) .+ (Empty :: Row Type)))]) .+ (Empty :: Row Type))))) -> NotebookDocumentChangeEvent
+ Test.Hls: NotebookDocumentChangeEvent :: Maybe Object -> Maybe NotebookDocumentCellChanges -> NotebookDocumentChangeEvent
- Test.Hls: NotebookDocumentFilter :: (Rec (("notebookType" .== Text) .+ (("scheme" .== Maybe Text) .+ (("pattern" .== Maybe Text) .+ (Empty :: Row Type)))) |? (Rec (("notebookType" .== Maybe Text) .+ (("scheme" .== Text) .+ (("pattern" .== Maybe Text) .+ (Empty :: Row Type)))) |? Rec (("notebookType" .== Maybe Text) .+ (("scheme" .== Maybe Text) .+ (("pattern" .== Text) .+ (Empty :: Row Type)))))) -> NotebookDocumentFilter
+ Test.Hls: NotebookDocumentFilter :: (NotebookDocumentFilterNotebookType |? (NotebookDocumentFilterScheme |? NotebookDocumentFilterPattern)) -> NotebookDocumentFilter
- Test.Hls: NotebookDocumentSyncOptions :: [Rec (("notebook" .== (Text |? NotebookDocumentFilter)) .+ (("cells" .== Maybe [Rec (("language" .== Text) .+ (Empty :: Row Type))]) .+ (Empty :: Row Type))) |? Rec (("notebook" .== Maybe (Text |? NotebookDocumentFilter)) .+ (("cells" .== [Rec (("language" .== Text) .+ (Empty :: Row Type))]) .+ (Empty :: Row Type)))] -> Maybe Bool -> NotebookDocumentSyncOptions
+ Test.Hls: NotebookDocumentSyncOptions :: [NotebookDocumentFilterWithNotebook |? NotebookDocumentFilterWithCells] -> Maybe Bool -> NotebookDocumentSyncOptions
- Test.Hls: NotebookDocumentSyncRegistrationOptions :: [Rec (("notebook" .== (Text |? NotebookDocumentFilter)) .+ (("cells" .== Maybe [Rec (("language" .== Text) .+ (Empty :: Row Type))]) .+ (Empty :: Row Type))) |? Rec (("notebook" .== Maybe (Text |? NotebookDocumentFilter)) .+ (("cells" .== [Rec (("language" .== Text) .+ (Empty :: Row Type))]) .+ (Empty :: Row Type)))] -> Maybe Bool -> Maybe Text -> NotebookDocumentSyncRegistrationOptions
+ Test.Hls: NotebookDocumentSyncRegistrationOptions :: [NotebookDocumentFilterWithNotebook |? NotebookDocumentFilterWithCells] -> Maybe Bool -> Maybe Text -> NotebookDocumentSyncRegistrationOptions
- Test.Hls: PrepareRenameResult :: (Range |? (Rec (("range" .== Range) .+ (("placeholder" .== Text) .+ (Empty :: Row Type))) |? Rec (("defaultBehavior" .== Bool) .+ (Empty :: Row Type)))) -> PrepareRenameResult
+ Test.Hls: PrepareRenameResult :: (Range |? (PrepareRenamePlaceholder |? PrepareRenameDefaultBehavior)) -> PrepareRenameResult
- Test.Hls: PublishDiagnosticsClientCapabilities :: Maybe Bool -> Maybe (Rec (("valueSet" .== [DiagnosticTag]) .+ (Empty :: Row Type))) -> Maybe Bool -> Maybe Bool -> Maybe Bool -> PublishDiagnosticsClientCapabilities
+ Test.Hls: PublishDiagnosticsClientCapabilities :: Maybe Bool -> Maybe ClientDiagnosticsTagOptions -> Maybe Bool -> Maybe Bool -> Maybe Bool -> PublishDiagnosticsClientCapabilities
- Test.Hls: RegularExpressionsClientCapabilities :: Text -> Maybe Text -> RegularExpressionsClientCapabilities
+ Test.Hls: RegularExpressionsClientCapabilities :: RegularExpressionEngineKind -> Maybe Text -> RegularExpressionsClientCapabilities
- Test.Hls: SemanticTokensClientCapabilities :: Maybe Bool -> Rec (("range" .== Maybe (Bool |? Rec (Empty :: Row Type))) .+ (("full" .== Maybe (Bool |? Rec (("delta" .== Maybe Bool) .+ (Empty :: Row Type)))) .+ (Empty :: Row Type))) -> [Text] -> [Text] -> [TokenFormat] -> Maybe Bool -> Maybe Bool -> Maybe Bool -> Maybe Bool -> SemanticTokensClientCapabilities
+ Test.Hls: SemanticTokensClientCapabilities :: Maybe Bool -> ClientSemanticTokensRequestOptions -> [Text] -> [Text] -> [TokenFormat] -> Maybe Bool -> Maybe Bool -> Maybe Bool -> Maybe Bool -> SemanticTokensClientCapabilities
- Test.Hls: SemanticTokensOptions :: Maybe Bool -> SemanticTokensLegend -> Maybe (Bool |? Rec (Empty :: Row Type)) -> Maybe (Bool |? Rec (("delta" .== Maybe Bool) .+ (Empty :: Row Type))) -> SemanticTokensOptions
+ Test.Hls: SemanticTokensOptions :: Maybe Bool -> SemanticTokensLegend -> Maybe (Bool |? Rec (Empty :: Row Type)) -> Maybe (Bool |? SemanticTokensFullDelta) -> SemanticTokensOptions
- Test.Hls: SemanticTokensRegistrationOptions :: (DocumentSelector |? Null) -> Maybe Bool -> SemanticTokensLegend -> Maybe (Bool |? Rec (Empty :: Row Type)) -> Maybe (Bool |? Rec (("delta" .== Maybe Bool) .+ (Empty :: Row Type))) -> Maybe Text -> SemanticTokensRegistrationOptions
+ Test.Hls: SemanticTokensRegistrationOptions :: (DocumentSelector |? Null) -> Maybe Bool -> SemanticTokensLegend -> Maybe (Bool |? Rec (Empty :: Row Type)) -> Maybe (Bool |? SemanticTokensFullDelta) -> Maybe Text -> SemanticTokensRegistrationOptions
- Test.Hls: ServerCapabilities :: Maybe PositionEncodingKind -> Maybe (TextDocumentSyncOptions |? TextDocumentSyncKind) -> Maybe (NotebookDocumentSyncOptions |? NotebookDocumentSyncRegistrationOptions) -> Maybe CompletionOptions -> Maybe (Bool |? HoverOptions) -> Maybe SignatureHelpOptions -> Maybe (Bool |? (DeclarationOptions |? DeclarationRegistrationOptions)) -> Maybe (Bool |? DefinitionOptions) -> Maybe (Bool |? (TypeDefinitionOptions |? TypeDefinitionRegistrationOptions)) -> Maybe (Bool |? (ImplementationOptions |? ImplementationRegistrationOptions)) -> Maybe (Bool |? ReferenceOptions) -> Maybe (Bool |? DocumentHighlightOptions) -> Maybe (Bool |? DocumentSymbolOptions) -> Maybe (Bool |? CodeActionOptions) -> Maybe CodeLensOptions -> Maybe DocumentLinkOptions -> Maybe (Bool |? (DocumentColorOptions |? DocumentColorRegistrationOptions)) -> Maybe (Bool |? WorkspaceSymbolOptions) -> Maybe (Bool |? DocumentFormattingOptions) -> Maybe (Bool |? DocumentRangeFormattingOptions) -> Maybe DocumentOnTypeFormattingOptions -> Maybe (Bool |? RenameOptions) -> Maybe (Bool |? (FoldingRangeOptions |? FoldingRangeRegistrationOptions)) -> Maybe (Bool |? (SelectionRangeOptions |? SelectionRangeRegistrationOptions)) -> Maybe ExecuteCommandOptions -> Maybe (Bool |? (CallHierarchyOptions |? CallHierarchyRegistrationOptions)) -> Maybe (Bool |? (LinkedEditingRangeOptions |? LinkedEditingRangeRegistrationOptions)) -> Maybe (SemanticTokensOptions |? SemanticTokensRegistrationOptions) -> Maybe (Bool |? (MonikerOptions |? MonikerRegistrationOptions)) -> Maybe (Bool |? (TypeHierarchyOptions |? TypeHierarchyRegistrationOptions)) -> Maybe (Bool |? (InlineValueOptions |? InlineValueRegistrationOptions)) -> Maybe (Bool |? (InlayHintOptions |? InlayHintRegistrationOptions)) -> Maybe (DiagnosticOptions |? DiagnosticRegistrationOptions) -> Maybe (Rec (("workspaceFolders" .== Maybe WorkspaceFoldersServerCapabilities) .+ (("fileOperations" .== Maybe FileOperationOptions) .+ (Empty :: Row Type)))) -> Maybe Value -> ServerCapabilities
+ Test.Hls: ServerCapabilities :: Maybe PositionEncodingKind -> Maybe (TextDocumentSyncOptions |? TextDocumentSyncKind) -> Maybe (NotebookDocumentSyncOptions |? NotebookDocumentSyncRegistrationOptions) -> Maybe CompletionOptions -> Maybe (Bool |? HoverOptions) -> Maybe SignatureHelpOptions -> Maybe (Bool |? (DeclarationOptions |? DeclarationRegistrationOptions)) -> Maybe (Bool |? DefinitionOptions) -> Maybe (Bool |? (TypeDefinitionOptions |? TypeDefinitionRegistrationOptions)) -> Maybe (Bool |? (ImplementationOptions |? ImplementationRegistrationOptions)) -> Maybe (Bool |? ReferenceOptions) -> Maybe (Bool |? DocumentHighlightOptions) -> Maybe (Bool |? DocumentSymbolOptions) -> Maybe (Bool |? CodeActionOptions) -> Maybe CodeLensOptions -> Maybe DocumentLinkOptions -> Maybe (Bool |? (DocumentColorOptions |? DocumentColorRegistrationOptions)) -> Maybe (Bool |? WorkspaceSymbolOptions) -> Maybe (Bool |? DocumentFormattingOptions) -> Maybe (Bool |? DocumentRangeFormattingOptions) -> Maybe DocumentOnTypeFormattingOptions -> Maybe (Bool |? RenameOptions) -> Maybe (Bool |? (FoldingRangeOptions |? FoldingRangeRegistrationOptions)) -> Maybe (Bool |? (SelectionRangeOptions |? SelectionRangeRegistrationOptions)) -> Maybe ExecuteCommandOptions -> Maybe (Bool |? (CallHierarchyOptions |? CallHierarchyRegistrationOptions)) -> Maybe (Bool |? (LinkedEditingRangeOptions |? LinkedEditingRangeRegistrationOptions)) -> Maybe (SemanticTokensOptions |? SemanticTokensRegistrationOptions) -> Maybe (Bool |? (MonikerOptions |? MonikerRegistrationOptions)) -> Maybe (Bool |? (TypeHierarchyOptions |? TypeHierarchyRegistrationOptions)) -> Maybe (Bool |? (InlineValueOptions |? InlineValueRegistrationOptions)) -> Maybe (Bool |? (InlayHintOptions |? InlayHintRegistrationOptions)) -> Maybe (DiagnosticOptions |? DiagnosticRegistrationOptions) -> Maybe WorkspaceOptions -> Maybe Value -> ServerCapabilities
- Test.Hls: SetTraceParams :: TraceValues -> SetTraceParams
+ Test.Hls: SetTraceParams :: TraceValue -> SetTraceParams
- Test.Hls: ShowMessageRequestClientCapabilities :: Maybe (Rec (("additionalPropertiesSupport" .== Maybe Bool) .+ (Empty :: Row Type))) -> ShowMessageRequestClientCapabilities
+ Test.Hls: ShowMessageRequestClientCapabilities :: Maybe ClientShowMessageActionItemOptions -> ShowMessageRequestClientCapabilities
- Test.Hls: SignatureHelp :: [SignatureInformation] -> Maybe UInt -> Maybe UInt -> SignatureHelp
+ Test.Hls: SignatureHelp :: [SignatureInformation] -> Maybe UInt -> Maybe (UInt |? Null) -> SignatureHelp
- Test.Hls: SignatureHelpClientCapabilities :: Maybe Bool -> Maybe (Rec (("documentationFormat" .== Maybe [MarkupKind]) .+ (("parameterInformation" .== Maybe (Rec (("labelOffsetSupport" .== Maybe Bool) .+ (Empty :: Row Type)))) .+ (("activeParameterSupport" .== Maybe Bool) .+ (Empty :: Row Type))))) -> Maybe Bool -> SignatureHelpClientCapabilities
+ Test.Hls: SignatureHelpClientCapabilities :: Maybe Bool -> Maybe ClientSignatureInformationOptions -> Maybe Bool -> SignatureHelpClientCapabilities
- Test.Hls: SignatureInformation :: Text -> Maybe (Text |? MarkupContent) -> Maybe [ParameterInformation] -> Maybe UInt -> SignatureInformation
+ Test.Hls: SignatureInformation :: Text -> Maybe (Text |? MarkupContent) -> Maybe [ParameterInformation] -> Maybe (UInt |? Null) -> SignatureInformation
- Test.Hls: TextDocumentContentChangeEvent :: (Rec (("range" .== Range) .+ (("rangeLength" .== Maybe UInt) .+ (("text" .== Text) .+ (Empty :: Row Type)))) |? Rec (("text" .== Text) .+ (Empty :: Row Type))) -> TextDocumentContentChangeEvent
+ Test.Hls: TextDocumentContentChangeEvent :: (TextDocumentContentChangePartial |? TextDocumentContentChangeWholeDocument) -> TextDocumentContentChangeEvent
- Test.Hls: TextDocumentFilter :: (Rec (("language" .== Text) .+ (("scheme" .== Maybe Text) .+ (("pattern" .== Maybe Text) .+ (Empty :: Row Type)))) |? (Rec (("language" .== Maybe Text) .+ (("scheme" .== Text) .+ (("pattern" .== Maybe Text) .+ (Empty :: Row Type)))) |? Rec (("language" .== Maybe Text) .+ (("scheme" .== Maybe Text) .+ (("pattern" .== Text) .+ (Empty :: Row Type)))))) -> TextDocumentFilter
+ Test.Hls: TextDocumentFilter :: (TextDocumentFilterLanguage |? (TextDocumentFilterScheme |? TextDocumentFilterPattern)) -> TextDocumentFilter
- Test.Hls: TextDocumentItem :: Uri -> Text -> Int32 -> Text -> TextDocumentItem
+ Test.Hls: TextDocumentItem :: Uri -> LanguageKind -> Int32 -> Text -> TextDocumentItem
- Test.Hls: UInitializeParams :: Maybe ProgressToken -> (Int32 |? Null) -> Maybe (Rec (("name" .== Text) .+ (("version" .== Maybe Text) .+ (Empty :: Row Type)))) -> Maybe Text -> Maybe (Text |? Null) -> (Uri |? Null) -> ClientCapabilities -> Maybe Value -> Maybe TraceValues -> UInitializeParams
+ Test.Hls: UInitializeParams :: Maybe ProgressToken -> (Int32 |? Null) -> Maybe ClientInfo -> Maybe Text -> Maybe (Text |? Null) -> (Uri |? Null) -> ClientCapabilities -> Maybe Value -> Maybe TraceValue -> UInitializeParams
- Test.Hls: WorkspaceEditClientCapabilities :: Maybe Bool -> Maybe [ResourceOperationKind] -> Maybe FailureHandlingKind -> Maybe Bool -> Maybe (Rec (("groupsOnLabel" .== Maybe Bool) .+ (Empty :: Row Type))) -> WorkspaceEditClientCapabilities
+ Test.Hls: WorkspaceEditClientCapabilities :: Maybe Bool -> Maybe [ResourceOperationKind] -> Maybe FailureHandlingKind -> Maybe Bool -> Maybe ChangeAnnotationsSupportOptions -> WorkspaceEditClientCapabilities
- Test.Hls: WorkspaceSymbol :: Text -> SymbolKind -> Maybe [SymbolTag] -> Maybe Text -> (Location |? Rec (("uri" .== Uri) .+ (Empty :: Row Type))) -> Maybe Value -> WorkspaceSymbol
+ Test.Hls: WorkspaceSymbol :: Text -> SymbolKind -> Maybe [SymbolTag] -> Maybe Text -> (Location |? LocationUriOnly) -> Maybe Value -> WorkspaceSymbol
- Test.Hls: WorkspaceSymbolClientCapabilities :: Maybe Bool -> Maybe (Rec (("valueSet" .== Maybe [SymbolKind]) .+ (Empty :: Row Type))) -> Maybe (Rec (("valueSet" .== [SymbolTag]) .+ (Empty :: Row Type))) -> Maybe (Rec (("properties" .== [Text]) .+ (Empty :: Row Type))) -> WorkspaceSymbolClientCapabilities
+ Test.Hls: WorkspaceSymbolClientCapabilities :: Maybe Bool -> Maybe ClientSymbolKindOptions -> Maybe ClientSymbolTagOptions -> Maybe ClientSymbolResolveOptions -> WorkspaceSymbolClientCapabilities
- Test.Hls: [$sel:_activeParameter:SignatureHelp] :: SignatureHelp -> Maybe UInt
+ Test.Hls: [$sel:_activeParameter:SignatureHelp] :: SignatureHelp -> Maybe (UInt |? Null)
- Test.Hls: [$sel:_activeParameter:SignatureInformation] :: SignatureInformation -> Maybe UInt
+ Test.Hls: [$sel:_activeParameter:SignatureInformation] :: SignatureInformation -> Maybe (UInt |? Null)
- Test.Hls: [$sel:_cells:NotebookDocumentChangeEvent] :: NotebookDocumentChangeEvent -> Maybe (Rec (("structure" .== Maybe (Rec (("array" .== NotebookCellArrayChange) .+ (("didOpen" .== Maybe [TextDocumentItem]) .+ (("didClose" .== Maybe [TextDocumentIdentifier]) .+ (Empty :: Row Type)))))) .+ (("data" .== Maybe [NotebookCell]) .+ (("textContent" .== Maybe [Rec (("document" .== VersionedTextDocumentIdentifier) .+ (("changes" .== [TextDocumentContentChangeEvent]) .+ (Empty :: Row Type)))]) .+ (Empty :: Row Type)))))
+ Test.Hls: [$sel:_cells:NotebookDocumentChangeEvent] :: NotebookDocumentChangeEvent -> Maybe NotebookDocumentCellChanges
- Test.Hls: [$sel:_changeAnnotationSupport:WorkspaceEditClientCapabilities] :: WorkspaceEditClientCapabilities -> Maybe (Rec (("groupsOnLabel" .== Maybe Bool) .+ (Empty :: Row Type)))
+ Test.Hls: [$sel:_changeAnnotationSupport:WorkspaceEditClientCapabilities] :: WorkspaceEditClientCapabilities -> Maybe ChangeAnnotationsSupportOptions
- Test.Hls: [$sel:_clientInfo:InitializeParams] :: InitializeParams -> Maybe (Rec (("name" .== Text) .+ (("version" .== Maybe Text) .+ (Empty :: Row Type))))
+ Test.Hls: [$sel:_clientInfo:InitializeParams] :: InitializeParams -> Maybe ClientInfo
- Test.Hls: [$sel:_clientInfo:UInitializeParams] :: UInitializeParams -> Maybe (Rec (("name" .== Text) .+ (("version" .== Maybe Text) .+ (Empty :: Row Type))))
+ Test.Hls: [$sel:_clientInfo:UInitializeParams] :: UInitializeParams -> Maybe ClientInfo
- Test.Hls: [$sel:_codeActionLiteralSupport:CodeActionClientCapabilities] :: CodeActionClientCapabilities -> Maybe (Rec (("codeActionKind" .== Rec (("valueSet" .== [CodeActionKind]) .+ (Empty :: Row Type))) .+ (Empty :: Row Type)))
+ Test.Hls: [$sel:_codeActionLiteralSupport:CodeActionClientCapabilities] :: CodeActionClientCapabilities -> Maybe ClientCodeActionLiteralOptions
- Test.Hls: [$sel:_completionItem:CompletionClientCapabilities] :: CompletionClientCapabilities -> Maybe (Rec (("snippetSupport" .== Maybe Bool) .+ (("commitCharactersSupport" .== Maybe Bool) .+ (("documentationFormat" .== Maybe [MarkupKind]) .+ (("deprecatedSupport" .== Maybe Bool) .+ (("preselectSupport" .== Maybe Bool) .+ (("tagSupport" .== Maybe (Rec (("valueSet" .== [CompletionItemTag]) .+ (Empty :: Row Type)))) .+ (("insertReplaceSupport" .== Maybe Bool) .+ (("resolveSupport" .== Maybe (Rec (("properties" .== [Text]) .+ (Empty :: Row Type)))) .+ (("insertTextModeSupport" .== Maybe (Rec (("valueSet" .== [InsertTextMode]) .+ (Empty :: Row Type)))) .+ (("labelDetailsSupport" .== Maybe Bool) .+ (Empty :: Row Type))))))))))))
+ Test.Hls: [$sel:_completionItem:CompletionClientCapabilities] :: CompletionClientCapabilities -> Maybe ClientCompletionItemOptions
- Test.Hls: [$sel:_completionItem:CompletionOptions] :: CompletionOptions -> Maybe (Rec (("labelDetailsSupport" .== Maybe Bool) .+ (Empty :: Row Type)))
+ Test.Hls: [$sel:_completionItem:CompletionOptions] :: CompletionOptions -> Maybe ServerCompletionItemOptions
- Test.Hls: [$sel:_completionItem:CompletionRegistrationOptions] :: CompletionRegistrationOptions -> Maybe (Rec (("labelDetailsSupport" .== Maybe Bool) .+ (Empty :: Row Type)))
+ Test.Hls: [$sel:_completionItem:CompletionRegistrationOptions] :: CompletionRegistrationOptions -> Maybe ServerCompletionItemOptions
- Test.Hls: [$sel:_completionItemKind:CompletionClientCapabilities] :: CompletionClientCapabilities -> Maybe (Rec (("valueSet" .== Maybe [CompletionItemKind]) .+ (Empty :: Row Type)))
+ Test.Hls: [$sel:_completionItemKind:CompletionClientCapabilities] :: CompletionClientCapabilities -> Maybe ClientCompletionItemOptionsKind
- Test.Hls: [$sel:_completionList:CompletionClientCapabilities] :: CompletionClientCapabilities -> Maybe (Rec (("itemDefaults" .== Maybe [Text]) .+ (Empty :: Row Type)))
+ Test.Hls: [$sel:_completionList:CompletionClientCapabilities] :: CompletionClientCapabilities -> Maybe CompletionListCapabilities
- Test.Hls: [$sel:_disabled:CodeAction] :: CodeAction -> Maybe (Rec (("reason" .== Text) .+ (Empty :: Row Type)))
+ Test.Hls: [$sel:_disabled:CodeAction] :: CodeAction -> Maybe CodeActionDisabled
- Test.Hls: [$sel:_engine:RegularExpressionsClientCapabilities] :: RegularExpressionsClientCapabilities -> Text
+ Test.Hls: [$sel:_engine:RegularExpressionsClientCapabilities] :: RegularExpressionsClientCapabilities -> RegularExpressionEngineKind
- Test.Hls: [$sel:_foldingRange:FoldingRangeClientCapabilities] :: FoldingRangeClientCapabilities -> Maybe (Rec (("collapsedText" .== Maybe Bool) .+ (Empty :: Row Type)))
+ Test.Hls: [$sel:_foldingRange:FoldingRangeClientCapabilities] :: FoldingRangeClientCapabilities -> Maybe ClientFoldingRangeOptions
- Test.Hls: [$sel:_foldingRangeKind:FoldingRangeClientCapabilities] :: FoldingRangeClientCapabilities -> Maybe (Rec (("valueSet" .== Maybe [FoldingRangeKind]) .+ (Empty :: Row Type)))
+ Test.Hls: [$sel:_foldingRangeKind:FoldingRangeClientCapabilities] :: FoldingRangeClientCapabilities -> Maybe ClientFoldingRangeKindOptions
- Test.Hls: [$sel:_full:SemanticTokensOptions] :: SemanticTokensOptions -> Maybe (Bool |? Rec (("delta" .== Maybe Bool) .+ (Empty :: Row Type)))
+ Test.Hls: [$sel:_full:SemanticTokensOptions] :: SemanticTokensOptions -> Maybe (Bool |? SemanticTokensFullDelta)
- Test.Hls: [$sel:_full:SemanticTokensRegistrationOptions] :: SemanticTokensRegistrationOptions -> Maybe (Bool |? Rec (("delta" .== Maybe Bool) .+ (Empty :: Row Type)))
+ Test.Hls: [$sel:_full:SemanticTokensRegistrationOptions] :: SemanticTokensRegistrationOptions -> Maybe (Bool |? SemanticTokensFullDelta)
- Test.Hls: [$sel:_itemDefaults:CompletionList] :: CompletionList -> Maybe (Rec (("commitCharacters" .== Maybe [Text]) .+ (("editRange" .== Maybe (Range |? Rec (("insert" .== Range) .+ (("replace" .== Range) .+ (Empty :: Row Type))))) .+ (("insertTextFormat" .== Maybe InsertTextFormat) .+ (("insertTextMode" .== Maybe InsertTextMode) .+ (("data" .== Maybe Value) .+ (Empty :: Row Type)))))))
+ Test.Hls: [$sel:_itemDefaults:CompletionList] :: CompletionList -> Maybe CompletionItemDefaults
- Test.Hls: [$sel:_languageId:TextDocumentItem] :: TextDocumentItem -> Text
+ Test.Hls: [$sel:_languageId:TextDocumentItem] :: TextDocumentItem -> LanguageKind
- Test.Hls: [$sel:_location:WorkspaceSymbol] :: WorkspaceSymbol -> Location |? Rec (("uri" .== Uri) .+ (Empty :: Row Type))
+ Test.Hls: [$sel:_location:WorkspaceSymbol] :: WorkspaceSymbol -> Location |? LocationUriOnly
- Test.Hls: [$sel:_messageActionItem:ShowMessageRequestClientCapabilities] :: ShowMessageRequestClientCapabilities -> Maybe (Rec (("additionalPropertiesSupport" .== Maybe Bool) .+ (Empty :: Row Type)))
+ Test.Hls: [$sel:_messageActionItem:ShowMessageRequestClientCapabilities] :: ShowMessageRequestClientCapabilities -> Maybe ClientShowMessageActionItemOptions
- Test.Hls: [$sel:_notebookSelector:NotebookDocumentSyncOptions] :: NotebookDocumentSyncOptions -> [Rec (("notebook" .== (Text |? NotebookDocumentFilter)) .+ (("cells" .== Maybe [Rec (("language" .== Text) .+ (Empty :: Row Type))]) .+ (Empty :: Row Type))) |? Rec (("notebook" .== Maybe (Text |? NotebookDocumentFilter)) .+ (("cells" .== [Rec (("language" .== Text) .+ (Empty :: Row Type))]) .+ (Empty :: Row Type)))]
+ Test.Hls: [$sel:_notebookSelector:NotebookDocumentSyncOptions] :: NotebookDocumentSyncOptions -> [NotebookDocumentFilterWithNotebook |? NotebookDocumentFilterWithCells]
- Test.Hls: [$sel:_notebookSelector:NotebookDocumentSyncRegistrationOptions] :: NotebookDocumentSyncRegistrationOptions -> [Rec (("notebook" .== (Text |? NotebookDocumentFilter)) .+ (("cells" .== Maybe [Rec (("language" .== Text) .+ (Empty :: Row Type))]) .+ (Empty :: Row Type))) |? Rec (("notebook" .== Maybe (Text |? NotebookDocumentFilter)) .+ (("cells" .== [Rec (("language" .== Text) .+ (Empty :: Row Type))]) .+ (Empty :: Row Type)))]
+ Test.Hls: [$sel:_notebookSelector:NotebookDocumentSyncRegistrationOptions] :: NotebookDocumentSyncRegistrationOptions -> [NotebookDocumentFilterWithNotebook |? NotebookDocumentFilterWithCells]
- Test.Hls: [$sel:_requests:SemanticTokensClientCapabilities] :: SemanticTokensClientCapabilities -> Rec (("range" .== Maybe (Bool |? Rec (Empty :: Row Type))) .+ (("full" .== Maybe (Bool |? Rec (("delta" .== Maybe Bool) .+ (Empty :: Row Type)))) .+ (Empty :: Row Type)))
+ Test.Hls: [$sel:_requests:SemanticTokensClientCapabilities] :: SemanticTokensClientCapabilities -> ClientSemanticTokensRequestOptions
- Test.Hls: [$sel:_resolveSupport:CodeActionClientCapabilities] :: CodeActionClientCapabilities -> Maybe (Rec (("properties" .== [Text]) .+ (Empty :: Row Type)))
+ Test.Hls: [$sel:_resolveSupport:CodeActionClientCapabilities] :: CodeActionClientCapabilities -> Maybe ClientCodeActionResolveOptions
- Test.Hls: [$sel:_resolveSupport:InlayHintClientCapabilities] :: InlayHintClientCapabilities -> Maybe (Rec (("properties" .== [Text]) .+ (Empty :: Row Type)))
+ Test.Hls: [$sel:_resolveSupport:InlayHintClientCapabilities] :: InlayHintClientCapabilities -> Maybe ClientInlayHintResolveOptions
- Test.Hls: [$sel:_resolveSupport:WorkspaceSymbolClientCapabilities] :: WorkspaceSymbolClientCapabilities -> Maybe (Rec (("properties" .== [Text]) .+ (Empty :: Row Type)))
+ Test.Hls: [$sel:_resolveSupport:WorkspaceSymbolClientCapabilities] :: WorkspaceSymbolClientCapabilities -> Maybe ClientSymbolResolveOptions
- Test.Hls: [$sel:_scopeUri:ConfigurationItem] :: ConfigurationItem -> Maybe Text
+ Test.Hls: [$sel:_scopeUri:ConfigurationItem] :: ConfigurationItem -> Maybe Uri
- Test.Hls: [$sel:_serverInfo:InitializeResult] :: InitializeResult -> Maybe (Rec (("name" .== Text) .+ (("version" .== Maybe Text) .+ (Empty :: Row Type))))
+ Test.Hls: [$sel:_serverInfo:InitializeResult] :: InitializeResult -> Maybe ServerInfo
- Test.Hls: [$sel:_signatureInformation:SignatureHelpClientCapabilities] :: SignatureHelpClientCapabilities -> Maybe (Rec (("documentationFormat" .== Maybe [MarkupKind]) .+ (("parameterInformation" .== Maybe (Rec (("labelOffsetSupport" .== Maybe Bool) .+ (Empty :: Row Type)))) .+ (("activeParameterSupport" .== Maybe Bool) .+ (Empty :: Row Type)))))
+ Test.Hls: [$sel:_signatureInformation:SignatureHelpClientCapabilities] :: SignatureHelpClientCapabilities -> Maybe ClientSignatureInformationOptions
- Test.Hls: [$sel:_staleRequestSupport:GeneralClientCapabilities] :: GeneralClientCapabilities -> Maybe (Rec (("cancel" .== Bool) .+ (("retryOnContentModified" .== [Text]) .+ (Empty :: Row Type))))
+ Test.Hls: [$sel:_staleRequestSupport:GeneralClientCapabilities] :: GeneralClientCapabilities -> Maybe StaleRequestSupportOptions
- Test.Hls: [$sel:_symbolKind:DocumentSymbolClientCapabilities] :: DocumentSymbolClientCapabilities -> Maybe (Rec (("valueSet" .== Maybe [SymbolKind]) .+ (Empty :: Row Type)))
+ Test.Hls: [$sel:_symbolKind:DocumentSymbolClientCapabilities] :: DocumentSymbolClientCapabilities -> Maybe ClientSymbolKindOptions
- Test.Hls: [$sel:_symbolKind:WorkspaceSymbolClientCapabilities] :: WorkspaceSymbolClientCapabilities -> Maybe (Rec (("valueSet" .== Maybe [SymbolKind]) .+ (Empty :: Row Type)))
+ Test.Hls: [$sel:_symbolKind:WorkspaceSymbolClientCapabilities] :: WorkspaceSymbolClientCapabilities -> Maybe ClientSymbolKindOptions
- Test.Hls: [$sel:_tagSupport:DocumentSymbolClientCapabilities] :: DocumentSymbolClientCapabilities -> Maybe (Rec (("valueSet" .== [SymbolTag]) .+ (Empty :: Row Type)))
+ Test.Hls: [$sel:_tagSupport:DocumentSymbolClientCapabilities] :: DocumentSymbolClientCapabilities -> Maybe ClientSymbolTagOptions
- Test.Hls: [$sel:_tagSupport:PublishDiagnosticsClientCapabilities] :: PublishDiagnosticsClientCapabilities -> Maybe (Rec (("valueSet" .== [DiagnosticTag]) .+ (Empty :: Row Type)))
+ Test.Hls: [$sel:_tagSupport:PublishDiagnosticsClientCapabilities] :: PublishDiagnosticsClientCapabilities -> Maybe ClientDiagnosticsTagOptions
- Test.Hls: [$sel:_tagSupport:WorkspaceSymbolClientCapabilities] :: WorkspaceSymbolClientCapabilities -> Maybe (Rec (("valueSet" .== [SymbolTag]) .+ (Empty :: Row Type)))
+ Test.Hls: [$sel:_tagSupport:WorkspaceSymbolClientCapabilities] :: WorkspaceSymbolClientCapabilities -> Maybe ClientSymbolTagOptions
- Test.Hls: [$sel:_target:DocumentLink] :: DocumentLink -> Maybe Text
+ Test.Hls: [$sel:_target:DocumentLink] :: DocumentLink -> Maybe Uri
- Test.Hls: [$sel:_trace:InitializeParams] :: InitializeParams -> Maybe TraceValues
+ Test.Hls: [$sel:_trace:InitializeParams] :: InitializeParams -> Maybe TraceValue
- Test.Hls: [$sel:_trace:UInitializeParams] :: UInitializeParams -> Maybe TraceValues
+ Test.Hls: [$sel:_trace:UInitializeParams] :: UInitializeParams -> Maybe TraceValue
- Test.Hls: [$sel:_value:SetTraceParams] :: SetTraceParams -> TraceValues
+ Test.Hls: [$sel:_value:SetTraceParams] :: SetTraceParams -> TraceValue
- Test.Hls: [$sel:_workspace:ServerCapabilities] :: ServerCapabilities -> Maybe (Rec (("workspaceFolders" .== Maybe WorkspaceFoldersServerCapabilities) .+ (("fileOperations" .== Maybe FileOperationOptions) .+ (Empty :: Row Type))))
+ Test.Hls: [$sel:_workspace:ServerCapabilities] :: ServerCapabilities -> Maybe WorkspaceOptions
- Test.Hls: getLastBuildKeys :: Session (Either ResponseError [Text])
+ Test.Hls: getLastBuildKeys :: Session (Either (TResponseError @ClientToServer (Method_CustomMethod "test")) [Text])
- Test.Hls: waitForAction :: String -> TextDocumentIdentifier -> Session (Either ResponseError WaitForIdeRuleResult)
+ Test.Hls: waitForAction :: String -> TextDocumentIdentifier -> Session (Either (TResponseError @ClientToServer (Method_CustomMethod "test")) WaitForIdeRuleResult)
- Test.Hls: waitForTypecheck :: TextDocumentIdentifier -> Session (Either ResponseError Bool)
+ Test.Hls: waitForTypecheck :: TextDocumentIdentifier -> Session (Either (TResponseError @ClientToServer (Method_CustomMethod "test")) Bool)

Files

hls-test-utils.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name:          hls-test-utils-version:       2.8.0.0+version:       2.9.0.0 synopsis:      Utilities used in the tests of Haskell Language Server description:   Please see the README on GitHub at <https://github.com/haskell/haskell-language-server#readme>@@ -29,6 +29,8 @@     Test.Hls     Test.Hls.Util     Test.Hls.FileSystem+    Development.IDE.Test+    Development.IDE.Test.Diagnostic    hs-source-dirs:   src   build-depends:@@ -41,11 +43,13 @@     , directory     , extra     , filepath-    , ghcide                  == 2.8.0.0-    , hls-plugin-api          == 2.8.0.0+    , ghcide                  == 2.9.0.0+    , hls-plugin-api          == 2.9.0.0     , lens+    , lsp     , lsp-test                ^>=0.17-    , lsp-types               ^>=2.1+    , lsp-types               ^>=2.3+    , neat-interpolation     , safe-exceptions     , tasty     , tasty-expected-failure@@ -54,8 +58,13 @@     , tasty-rerun     , temporary     , text-    , row-types-  ghc-options:      -Wall -Wunused-packages+    , text-rope++  ghc-options:+    -Wall+    -Wunused-packages+    -Wno-name-shadowing+    -Wno-unticked-promoted-constructors    if flag(pedantic)     ghc-options: -Werror
+ src/Development/IDE/Test.hs view
@@ -0,0 +1,259 @@+-- Copyright (c) 2019 The DAML Authors. All rights reserved.+-- SPDX-License-Identifier: Apache-2.0++{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE GADTs                 #-}+{-# LANGUAGE LambdaCase            #-}+{-# LANGUAGE OverloadedStrings     #-}++module Development.IDE.Test+  ( Cursor+  , cursorPosition+  , requireDiagnostic+  , diagnostic+  , expectDiagnostics+  , expectDiagnosticsWithTags+  , expectNoMoreDiagnostics+  , expectMessages+  , expectCurrentDiagnostics+  , checkDiagnosticsForDoc+  , canonicalizeUri+  , standardizeQuotes+  , flushMessages+  , waitForAction+  , getInterfaceFilesDir+  , garbageCollectDirtyKeys+  , getFilesOfInterest+  , waitForTypecheck+  , waitForBuildQueue+  , getStoredKeys+  , waitForCustomMessage+  , waitForGC+  , configureCheckProject+  , isReferenceReady+  , referenceReady) where++import           Control.Applicative.Combinators+import           Control.Lens                    hiding (List)+import           Control.Monad+import           Control.Monad.IO.Class+import           Data.Aeson                      (toJSON)+import qualified Data.Aeson                      as A+import           Data.Bifunctor                  (second)+import           Data.Default+import qualified Data.Map.Strict                 as Map+import           Data.Maybe                      (fromJust)+import           Data.Proxy+import           Data.Text                       (Text)+import qualified Data.Text                       as T+import           Development.IDE.Plugin.Test     (TestRequest (..),+                                                  WaitForIdeRuleResult,+                                                  ideResultSuccess)+import           Development.IDE.Test.Diagnostic+import           GHC.TypeLits                    (symbolVal)+import           Ide.Plugin.Config               (CheckParents, checkProject)+import qualified Language.LSP.Protocol.Lens      as L+import           Language.LSP.Protocol.Message+import           Language.LSP.Protocol.Types+import           Language.LSP.Test               hiding (message)+import qualified Language.LSP.Test               as LspTest+import           System.Directory                (canonicalizePath)+import           System.FilePath                 (equalFilePath)+import           System.Time.Extra+import           Test.Tasty.HUnit++requireDiagnosticM+    :: (Foldable f, Show (f Diagnostic), HasCallStack)+    => f Diagnostic+    -> (DiagnosticSeverity, Cursor, T.Text, Maybe DiagnosticTag)+    -> Assertion+requireDiagnosticM actuals expected = case requireDiagnostic actuals expected of+    Nothing  -> pure ()+    Just err -> assertFailure err++-- |wait for @timeout@ seconds and report an assertion failure+-- if any diagnostic messages arrive in that period+expectNoMoreDiagnostics :: HasCallStack => Seconds -> Session ()+expectNoMoreDiagnostics timeout =+  expectMessages SMethod_TextDocumentPublishDiagnostics timeout $ \diagsNot -> do+    let fileUri = diagsNot ^. L.params . L.uri+        actual = diagsNot ^. L.params . L.diagnostics+    unless (null actual) $ liftIO $+      assertFailure $+        "Got unexpected diagnostics for " <> show fileUri+          <> " got "+          <> show actual++expectMessages :: SMethod m -> Seconds -> (TServerMessage m -> Session ()) -> Session ()+expectMessages m timeout handle = do+    -- Give any further diagnostic messages time to arrive.+    liftIO $ sleep timeout+    -- Send a dummy message to provoke a response from the server.+    -- This guarantees that we have at least one message to+    -- process, so message won't block or timeout.+    let cm = SMethod_CustomMethod (Proxy @"test")+    i <- sendRequest cm $ A.toJSON GetShakeSessionQueueCount+    go cm i+  where+    go cm i = handleMessages+      where+        handleMessages = (LspTest.message m >>= handle) <|> (void $ responseForId cm i) <|> ignoreOthers+        ignoreOthers = void anyMessage >> handleMessages++flushMessages :: Session ()+flushMessages = do+    let cm = SMethod_CustomMethod (Proxy @"non-existent-method")+    i <- sendRequest cm A.Null+    void (responseForId cm i) <|> ignoreOthers cm i+    where+        ignoreOthers cm i = skipManyTill anyMessage (responseForId cm i) >> flushMessages++-- | It is not possible to use 'expectDiagnostics []' to assert the absence of diagnostics,+--   only that existing diagnostics have been cleared.+--+--   Rather than trying to assert the absence of diagnostics, introduce an+--   expected diagnostic (e.g. a redundant import) and assert the singleton diagnostic.+expectDiagnostics :: HasCallStack => [(FilePath, [(DiagnosticSeverity, Cursor, T.Text)])] -> Session ()+expectDiagnostics+  = expectDiagnosticsWithTags+  . map (second (map (\(ds, c, t) -> (ds, c, t, Nothing))))++unwrapDiagnostic :: TServerMessage Method_TextDocumentPublishDiagnostics  -> (Uri, [Diagnostic])+unwrapDiagnostic diagsNot = (diagsNot^. L.params . L.uri, diagsNot^. L.params . L.diagnostics)++expectDiagnosticsWithTags :: HasCallStack => [(String, [(DiagnosticSeverity, Cursor, T.Text, Maybe DiagnosticTag)])] -> Session ()+expectDiagnosticsWithTags expected = do+    let f = getDocUri >=> liftIO . canonicalizeUri >=> pure . toNormalizedUri+        next = unwrapDiagnostic <$> skipManyTill anyMessage diagnostic+    expected' <- Map.fromListWith (<>) <$> traverseOf (traverse . _1) f expected+    expectDiagnosticsWithTags' next expected'++expectDiagnosticsWithTags' ::+  (HasCallStack, MonadIO m) =>+  m (Uri, [Diagnostic]) ->+  Map.Map NormalizedUri [(DiagnosticSeverity, Cursor, T.Text, Maybe DiagnosticTag)] ->+  m ()+expectDiagnosticsWithTags' next m | null m = do+    (_,actual) <- next+    case actual of+        [] ->+            return ()+        _ ->+            liftIO $ assertFailure $ "Got unexpected diagnostics:" <> show actual++expectDiagnosticsWithTags' next expected = go expected+  where+    go m+      | Map.null m = pure ()+      | otherwise = do+        (fileUri, actual) <- next+        canonUri <- liftIO $ toNormalizedUri <$> canonicalizeUri fileUri+        case Map.lookup canonUri m of+          Nothing -> do+            liftIO $+              assertFailure $+                "Got diagnostics for " <> show fileUri+                  <> " but only expected diagnostics for "+                  <> show (Map.keys m)+                  <> " got "+                  <> show actual+          Just expected -> do+            liftIO $ mapM_ (requireDiagnosticM actual) expected+            liftIO $+              unless (length expected == length actual) $+                assertFailure $+                  "Incorrect number of diagnostics for " <> show fileUri+                    <> ", expected "+                    <> show expected+                    <> " but got "+                    <> show actual+            go $ Map.delete canonUri m++expectCurrentDiagnostics :: HasCallStack => TextDocumentIdentifier -> [(DiagnosticSeverity, Cursor, T.Text)] -> Session ()+expectCurrentDiagnostics doc expected = do+    diags <- getCurrentDiagnostics doc+    checkDiagnosticsForDoc doc expected diags++checkDiagnosticsForDoc :: HasCallStack => TextDocumentIdentifier -> [(DiagnosticSeverity, Cursor, T.Text)] -> [Diagnostic] -> Session ()+checkDiagnosticsForDoc TextDocumentIdentifier {_uri} expected obtained = do+    let expected' = Map.singleton nuri (map (\(ds, c, t) -> (ds, c, t, Nothing)) expected)+        nuri = toNormalizedUri _uri+    expectDiagnosticsWithTags' (return (_uri, obtained)) expected'++canonicalizeUri :: Uri -> IO Uri+canonicalizeUri uri = filePathToUri <$> canonicalizePath (fromJust (uriToFilePath uri))++diagnostic :: Session (TNotificationMessage Method_TextDocumentPublishDiagnostics)+diagnostic = LspTest.message SMethod_TextDocumentPublishDiagnostics++tryCallTestPlugin :: (A.FromJSON b) => TestRequest -> Session (Either (TResponseError @ClientToServer (Method_CustomMethod "test")) b)+tryCallTestPlugin cmd = do+    let cm = SMethod_CustomMethod (Proxy @"test")+    waitId <- sendRequest cm (A.toJSON cmd)+    TResponseMessage{_result} <- skipManyTill anyMessage $ responseForId cm waitId+    return $ case _result of+         Left e -> Left e+         Right json -> case A.fromJSON json of+             A.Success a -> Right a+             A.Error e   -> error e++callTestPlugin :: (A.FromJSON b) => TestRequest -> Session b+callTestPlugin cmd = do+    res <- tryCallTestPlugin cmd+    case res of+        Left (TResponseError t err _) -> error $ show t <> ": " <> T.unpack err+        Right a                       -> pure a+++waitForAction :: String -> TextDocumentIdentifier -> Session WaitForIdeRuleResult+waitForAction key TextDocumentIdentifier{_uri} =+    callTestPlugin (WaitForIdeRule key _uri)++getInterfaceFilesDir :: TextDocumentIdentifier -> Session FilePath+getInterfaceFilesDir TextDocumentIdentifier{_uri} = callTestPlugin (GetInterfaceFilesDir _uri)++garbageCollectDirtyKeys :: CheckParents -> Int -> Session [String]+garbageCollectDirtyKeys parents age = callTestPlugin (GarbageCollectDirtyKeys parents age)++getStoredKeys :: Session [Text]+getStoredKeys = callTestPlugin GetStoredKeys++waitForTypecheck :: TextDocumentIdentifier -> Session Bool+waitForTypecheck tid = ideResultSuccess <$> waitForAction "typecheck" tid++waitForBuildQueue :: Session ()+waitForBuildQueue = callTestPlugin WaitForShakeQueue++getFilesOfInterest :: Session [FilePath]+getFilesOfInterest = callTestPlugin GetFilesOfInterest++waitForCustomMessage :: T.Text -> (A.Value -> Maybe res) -> Session res+waitForCustomMessage msg pred =+    skipManyTill anyMessage $ satisfyMaybe $ \case+        FromServerMess (SMethod_CustomMethod p) (NotMess TNotificationMessage{_params = value})+            | symbolVal p == T.unpack msg -> pred value+        _ -> Nothing++waitForGC :: Session [T.Text]+waitForGC = waitForCustomMessage "ghcide/GC" $ \v ->+    case A.fromJSON v of+        A.Success x -> Just x+        _           -> Nothing++configureCheckProject :: Bool -> Session ()+configureCheckProject overrideCheckProject = setConfigSection "haskell" (toJSON $ def{checkProject = overrideCheckProject})++-- | Pattern match a message from ghcide indicating that a file has been indexed+isReferenceReady :: FilePath -> Session ()+isReferenceReady p = void $ referenceReady (equalFilePath p)++referenceReady :: (FilePath -> Bool) -> Session FilePath+referenceReady pred = satisfyMaybe $ \case+  FromServerMess (SMethod_CustomMethod p) (NotMess TNotificationMessage{_params})+    | A.Success fp <- A.fromJSON _params+    , pred fp+    , symbolVal p == "ghcide/reference/ready"+    -> Just fp+  _ -> Nothing+
+ src/Development/IDE/Test/Diagnostic.hs view
@@ -0,0 +1,47 @@+module Development.IDE.Test.Diagnostic where++import           Control.Lens                ((^.))+import qualified Data.Text                   as T+import           GHC.Stack                   (HasCallStack)+import           Language.LSP.Protocol.Lens+import           Language.LSP.Protocol.Types++-- | (0-based line number, 0-based column number)+type Cursor = (UInt, UInt)++cursorPosition :: Cursor -> Position+cursorPosition (line,  col) = Position line col++type ErrorMsg = String++requireDiagnostic+    :: (Foldable f, Show (f Diagnostic), HasCallStack)+    => f Diagnostic+    -> (DiagnosticSeverity, Cursor, T.Text, Maybe DiagnosticTag)+    -> Maybe ErrorMsg+requireDiagnostic actuals expected@(severity, cursor, expectedMsg, expectedTag)+    | any match actuals = Nothing+    | otherwise = Just $+            "Could not find " <> show expected <>+            " in " <> show actuals+  where+    match :: Diagnostic -> Bool+    match d =+        Just severity == _severity d+        && cursorPosition cursor == d ^. range . start+        && standardizeQuotes (T.toLower expectedMsg) `T.isInfixOf`+           standardizeQuotes (T.toLower $ d ^. message)+        && hasTag expectedTag (d ^. tags)++    hasTag :: Maybe DiagnosticTag -> Maybe [DiagnosticTag] -> Bool+    hasTag Nothing  _                   = True+    hasTag (Just _) Nothing             = False+    hasTag (Just actualTag) (Just tags) = actualTag `elem` tags++standardizeQuotes :: T.Text -> T.Text+standardizeQuotes msg = let+        repl '‘' = '\''+        repl '’' = '\''+        repl '`' = '\''+        repl  c  = c+    in  T.map repl msg
src/Test/Hls.hs view
@@ -4,6 +4,9 @@ {-# LANGUAGE LambdaCase            #-} {-# LANGUAGE OverloadedLists       #-} {-# LANGUAGE OverloadedStrings     #-}+{-# LANGUAGE RecordWildCards       #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeApplications      #-} module Test.Hls   ( module Test.Tasty.HUnit,     module Test.Tasty,@@ -25,14 +28,14 @@     goldenWithHaskellDocFormatterInTmpDir,     goldenWithCabalDocFormatter,     goldenWithCabalDocFormatterInTmpDir,+    goldenWithTestConfig,     def,     -- * Running HLS for integration tests     runSessionWithServer,-    runSessionWithServerAndCaps,     runSessionWithServerInTmpDir,-    runSessionWithServerAndCapsInTmpDir,-    runSessionWithServer',-    runSessionWithServerInTmpDir',+    runSessionWithTestConfig,+    -- * Running parameterised tests for a set of test configurations+    parameterisedCursorTest,     -- * Helpful re-exports     PluginDescriptor,     IdeState,@@ -40,6 +43,7 @@     waitForProgressDone,     waitForAllProgressDone,     waitForBuildQueue,+    waitForProgressBegin,     waitForTypecheck,     waitForAction,     hlsConfigToClientConfig,@@ -49,7 +53,7 @@     waitForKickStart,     -- * Plugin descriptor helper functions for tests     PluginTestDescriptor,-    pluginTestRecorder,+    hlsPluginTestRecorder,     mkPluginTestDescriptor,     mkPluginTestDescriptor',     -- * Re-export logger types@@ -57,67 +61,81 @@     WithPriority(..),     Recorder,     Priority(..),+    TestConfig(..),     ) where  import           Control.Applicative.Combinators-import           Control.Concurrent.Async           (async, cancel, wait)+import           Control.Concurrent.Async                 (async, cancel, wait) import           Control.Concurrent.Extra import           Control.Exception.Safe-import           Control.Lens.Extras                (is)-import           Control.Monad                      (guard, unless, void)-import           Control.Monad.Extra                (forM)+import           Control.Lens.Extras                      (is)+import           Control.Monad                            (guard, unless, void)+import           Control.Monad.Extra                      (forM) import           Control.Monad.IO.Class-import           Data.Aeson                         (Result (Success),-                                                     Value (Null), fromJSON,-                                                     toJSON)-import qualified Data.Aeson                         as A-import           Data.ByteString.Lazy               (ByteString)-import           Data.Default                       (def)-import qualified Data.Map                           as M-import           Data.Maybe                         (fromMaybe)-import           Data.Proxy                         (Proxy (Proxy))-import qualified Data.Text                          as T-import qualified Data.Text.Lazy                     as TL-import qualified Data.Text.Lazy.Encoding            as TL-import           Development.IDE                    (IdeState,-                                                     LoggingColumn (ThreadIdColumn))-import           Development.IDE.Main               hiding (Log)-import qualified Development.IDE.Main               as IDEMain-import           Development.IDE.Plugin.Test        (TestRequest (GetBuildKeysBuilt, WaitForIdeRule, WaitForShakeQueue),-                                                     WaitForIdeRuleResult (ideResultSuccess))-import qualified Development.IDE.Plugin.Test        as Test+import           Data.Aeson                               (Result (Success),+                                                           Value (Null),+                                                           fromJSON, toJSON)+import qualified Data.Aeson                               as A+import           Data.ByteString.Lazy                     (ByteString)+import           Data.Default                             (Default, def)+import qualified Data.Map                                 as M+import           Data.Maybe                               (fromMaybe)+import           Data.Proxy                               (Proxy (Proxy))+import qualified Data.Text                                as T+import qualified Data.Text.Lazy                           as TL+import qualified Data.Text.Lazy.Encoding                  as TL+import           Development.IDE                          (IdeState,+                                                           LoggingColumn (ThreadIdColumn),+                                                           defaultLayoutOptions,+                                                           layoutPretty,+                                                           renderStrict)+import           Development.IDE.Main                     hiding (Log)+import qualified Development.IDE.Main                     as IDEMain+import           Development.IDE.Plugin.Completions.Types (PosPrefixInfo)+import           Development.IDE.Plugin.Test              (TestRequest (GetBuildKeysBuilt, WaitForIdeRule, WaitForShakeQueue),+                                                           WaitForIdeRuleResult (ideResultSuccess))+import qualified Development.IDE.Plugin.Test              as Test import           Development.IDE.Types.Options import           GHC.IO.Handle import           GHC.TypeLits-import           Ide.Logger                         (Pretty (pretty),-                                                     Priority (..), Recorder,-                                                     WithPriority (WithPriority, priority),-                                                     cfilter, cmapWithPrio,-                                                     defaultLoggingColumns,-                                                     logWith,-                                                     makeDefaultStderrRecorder,-                                                     (<+>))+import           Ide.Logger                               (Pretty (pretty),+                                                           Priority (..),+                                                           Recorder,+                                                           WithPriority (WithPriority, priority),+                                                           cfilter,+                                                           cmapWithPrio,+                                                           defaultLoggingColumns,+                                                           logWith,+                                                           makeDefaultStderrRecorder,+                                                           (<+>))+import qualified Ide.Logger                               as Logger+import           Ide.PluginUtils                          (idePluginsToPluginDesc,+                                                           pluginDescToIdePlugins) import           Ide.Types import           Language.LSP.Protocol.Capabilities import           Language.LSP.Protocol.Message-import           Language.LSP.Protocol.Types        hiding (Null)+import qualified Language.LSP.Protocol.Message            as LSP+import           Language.LSP.Protocol.Types              hiding (Null)+import qualified Language.LSP.Server                      as LSP import           Language.LSP.Test-import           Prelude                            hiding (log)-import           System.Directory                   (createDirectoryIfMissing,-                                                     getCurrentDirectory,-                                                     getTemporaryDirectory,-                                                     setCurrentDirectory)-import           System.Environment                 (lookupEnv, setEnv)+import           Prelude                                  hiding (log)+import           System.Directory                         (canonicalizePath,+                                                           createDirectoryIfMissing,+                                                           getCurrentDirectory,+                                                           getTemporaryDirectory,+                                                           makeAbsolute,+                                                           setCurrentDirectory)+import           System.Environment                       (lookupEnv, setEnv) import           System.FilePath-import           System.IO.Extra                    (newTempDirWithin)-import           System.IO.Unsafe                   (unsafePerformIO)-import           System.Process.Extra               (createPipe)+import           System.IO.Extra                          (newTempDirWithin)+import           System.IO.Unsafe                         (unsafePerformIO)+import           System.Process.Extra                     (createPipe) import           System.Time.Extra-import qualified Test.Hls.FileSystem                as FS+import qualified Test.Hls.FileSystem                      as FS import           Test.Hls.FileSystem import           Test.Hls.Util-import           Test.Tasty                         hiding (Timeout)+import           Test.Tasty                               hiding (Timeout) import           Test.Tasty.ExpectedFailure import           Test.Tasty.Golden import           Test.Tasty.HUnit@@ -165,7 +183,7 @@   -> FilePath   -> (TextDocumentIdentifier -> Session ())   -> TestTree-goldenWithHaskellDoc = goldenWithDoc "haskell"+goldenWithHaskellDoc = goldenWithDoc LanguageKind_Haskell  goldenWithHaskellDocInTmpDir   :: Pretty b@@ -178,7 +196,7 @@   -> FilePath   -> (TextDocumentIdentifier -> Session ())   -> TestTree-goldenWithHaskellDocInTmpDir = goldenWithDocInTmpDir "haskell"+goldenWithHaskellDocInTmpDir = goldenWithDocInTmpDir LanguageKind_Haskell  goldenWithHaskellAndCaps   :: Pretty b@@ -194,7 +212,14 @@   -> TestTree goldenWithHaskellAndCaps config clientCaps plugin title testDataDir path desc ext act =   goldenGitDiff title (testDataDir </> path <.> desc <.> ext)-  $ runSessionWithServerAndCaps config plugin clientCaps testDataDir+  $ runSessionWithTestConfig def {+    testDirLocation = Left testDataDir,+    testConfigCaps = clientCaps,+    testLspConfig = config,+    testPluginDescriptor = plugin+  }+  $ const+--   runSessionWithServerAndCaps config plugin clientCaps testDataDir   $ TL.encodeUtf8 . TL.fromStrict   <$> do     doc <- openDoc (path <.> ext) "haskell"@@ -202,6 +227,26 @@     act doc     documentContents doc +goldenWithTestConfig+  :: Pretty b+  => TestConfig b+  -> TestName+  -> FilePath+  -> FilePath+  -> FilePath+  -> FilePath+  -> (TextDocumentIdentifier -> Session ())+  -> TestTree+goldenWithTestConfig config title testDataDir path desc ext act =+  goldenGitDiff title (testDataDir </> path <.> desc <.> ext)+  $ runSessionWithTestConfig config $ const+  $ TL.encodeUtf8 . TL.fromStrict+  <$> do+    doc <- openDoc (path <.> ext) "haskell"+    void waitForBuildQueue+    act doc+    documentContents doc+ goldenWithHaskellAndCapsInTmpDir   :: Pretty b   => Config@@ -216,7 +261,13 @@   -> TestTree goldenWithHaskellAndCapsInTmpDir config clientCaps plugin title tree path desc ext act =   goldenGitDiff title (vftOriginalRoot tree </> path <.> desc <.> ext)-  $ runSessionWithServerAndCapsInTmpDir config plugin clientCaps tree+  $+  runSessionWithTestConfig def {+    testDirLocation = Right tree,+    testConfigCaps = clientCaps,+    testLspConfig = config,+    testPluginDescriptor = plugin+  } $ const   $ TL.encodeUtf8 . TL.fromStrict   <$> do     doc <- openDoc (path <.> ext) "haskell"@@ -235,11 +286,11 @@   -> FilePath   -> (TextDocumentIdentifier -> Session ())   -> TestTree-goldenWithCabalDoc = goldenWithDoc "cabal"+goldenWithCabalDoc = goldenWithDoc (LanguageKind_Custom "cabal")  goldenWithDoc   :: Pretty b-  => T.Text+  => LanguageKind   -> Config   -> PluginTestDescriptor b   -> TestName@@ -249,19 +300,19 @@   -> FilePath   -> (TextDocumentIdentifier -> Session ())   -> TestTree-goldenWithDoc fileType config plugin title testDataDir path desc ext act =+goldenWithDoc languageKind config plugin title testDataDir path desc ext act =   goldenGitDiff title (testDataDir </> path <.> desc <.> ext)   $ runSessionWithServer config plugin testDataDir   $ TL.encodeUtf8 . TL.fromStrict   <$> do-    doc <- openDoc (path <.> ext) fileType+    doc <- openDoc (path <.> ext) languageKind     void waitForBuildQueue     act doc     documentContents doc  goldenWithDocInTmpDir   :: Pretty b-  => T.Text+  => LanguageKind   -> Config   -> PluginTestDescriptor b   -> TestName@@ -271,16 +322,66 @@   -> FilePath   -> (TextDocumentIdentifier -> Session ())   -> TestTree-goldenWithDocInTmpDir fileType config plugin title tree path desc ext act =+goldenWithDocInTmpDir languageKind config plugin title tree path desc ext act =   goldenGitDiff title (vftOriginalRoot tree </> path <.> desc <.> ext)   $ runSessionWithServerInTmpDir config plugin tree   $ TL.encodeUtf8 . TL.fromStrict   <$> do-    doc <- openDoc (path <.> ext) fileType+    doc <- openDoc (path <.> ext) languageKind     void waitForBuildQueue     act doc     documentContents doc +-- | A parameterised test is similar to a normal test case but allows to run+-- the same test case multiple times with different inputs.+-- A 'parameterisedCursorTest' allows to define a test case based on an input file+-- that specifies one or many cursor positions via the identification value '^'.+--+-- For example:+--+-- @+--  parameterisedCursorTest "Cursor Test" [trimming|+--       foo = 2+--        ^+--       bar = 3+--       baz = foo + bar+--         ^+--       |]+--       ["foo", "baz"]+--       (\input cursor -> findFunctionNameUnderCursor input cursor)+-- @+--+-- Assuming a fitting implementation for 'findFunctionNameUnderCursor'.+--+-- This test definition will run the test case 'findFunctionNameUnderCursor' for+-- each cursor position, each in its own isolated 'testCase'.+-- Cursor positions are identified via the character '^', which points to the+-- above line as the actual cursor position.+-- Lines containing '^' characters, are removed from the final text, that is+-- passed to the testing function.+--+-- TODO: Many Haskell and Cabal source may contain '^' characters for good reasons.+-- We likely need a way to change the character for certain test cases in the future.+--+-- The quasi quoter 'trimming' is very helpful to define such tests, as it additionally+-- allows to interpolate haskell values and functions. We reexport this quasi quoter+-- for easier usage.+parameterisedCursorTest :: (Show a, Eq a) => String -> T.Text -> [a] -> (T.Text -> PosPrefixInfo -> IO a) -> TestTree+parameterisedCursorTest title content expectations act+  | lenPrefs /= lenExpected = error $ "parameterisedCursorTest: Expected " <> show lenExpected <> " cursors but found: " <> show lenPrefs+  | otherwise = testGroup title $+      map singleTest testCaseSpec+  where+    lenPrefs = length prefInfos+    lenExpected = length expectations+    (cleanText, prefInfos) = extractCursorPositions content++    testCaseSpec = zip [1 ::Int ..] (zip expectations prefInfos)++    singleTest (n, (expected, info)) = testCase (title <> " " <> show n) $ do+      actual <- act cleanText info+      assertEqual (mkParameterisedLabel info) expected actual+ -- ------------------------------------------------------------ -- Helper function for initialising plugins under test -- ------------------------------------------------------------@@ -319,10 +420,29 @@   -> PluginTestDescriptor b mkPluginTestDescriptor' pluginDesc plId _recorder = IdePlugins [pluginDesc plId] --- | Initialise a recorder that can be instructed to write to stderr by--- setting the environment variable "HLS_TEST_PLUGIN_LOG_STDERR=1" before--- running the tests.+-- | Initialize a recorder that can be instructed to write to stderr by+-- setting one of the environment variables: --+-- * HLS_TEST_HARNESS_STDERR=1+-- * HLS_TEST_LOG_STDERR=1+--+-- "HLS_TEST_LOG_STDERR" is intended to enable all logging for the server and the plugins+-- under test.+hlsHelperTestRecorder :: Pretty a => IO (Recorder (WithPriority a))+hlsHelperTestRecorder = initializeTestRecorder ["HLS_TEST_HARNESS_STDERR", "HLS_TEST_LOG_STDERR"]+++-- | Initialize a recorder that can be instructed to write to stderr by+-- setting one of the environment variables:+--+-- * HLS_TEST_PLUGIN_LOG_STDERR=1+-- * HLS_TEST_LOG_STDERR=1+--+-- before running the tests.+--+-- "HLS_TEST_LOG_STDERR" is intended to enable all logging for the server and the plugins+-- under test.+-- -- On the cli, use for example: -- -- @@@ -334,11 +454,10 @@ -- @ --   HLS_TEST_LOG_STDERR=1 cabal test <test-suite-of-plugin> -- @-pluginTestRecorder :: Pretty a => IO (Recorder (WithPriority a))-pluginTestRecorder = do-  initialiseTestRecorder ["HLS_TEST_PLUGIN_LOG_STDERR", "HLS_TEST_LOG_STDERR"]+hlsPluginTestRecorder :: Pretty a => IO (Recorder (WithPriority a))+hlsPluginTestRecorder = initializeTestRecorder ["HLS_TEST_PLUGIN_LOG_STDERR", "HLS_TEST_LOG_STDERR"] --- | Generic recorder initialisation for plugins and the HLS server for test-cases.+-- | Generic recorder initialization for plugins and the HLS server for test-cases. -- -- The created recorder writes to stderr if any of the given environment variables -- have been set to a value different to @0@.@@ -347,11 +466,12 @@ -- -- We have to return the base logger function for HLS server logging initialisation. -- See 'runSessionWithServer'' for details.-initialiseTestRecorder :: Pretty a => [String] -> IO (Recorder (WithPriority a))-initialiseTestRecorder envVars = do+initializeTestRecorder :: Pretty a => [String] -> IO (Recorder (WithPriority a))+initializeTestRecorder envVars = do     docWithPriorityRecorder <- makeDefaultStderrRecorder (Just $ ThreadIdColumn : defaultLoggingColumns)+    -- lspClientLogRecorder     -- There are potentially multiple environment variables that enable this logger-    definedEnvVars <- forM envVars (\var -> fromMaybe "0" <$> lookupEnv var)+    definedEnvVars <- forM envVars (fmap (fromMaybe "0") . lookupEnv)     let logStdErr = any (/= "0") definedEnvVars          docWithFilteredPriorityRecorder =@@ -364,87 +484,62 @@ -- Run an HLS server testing a specific plugin -- ------------------------------------------------------------ -runSessionWithServer :: Pretty b => Config -> PluginTestDescriptor b -> FilePath -> Session a -> IO a-runSessionWithServer config plugin fp act = do-  recorder <- pluginTestRecorder-  runSessionWithServer' (plugin recorder) config def fullCaps fp act--runSessionWithServerAndCaps :: Pretty b => Config -> PluginTestDescriptor b -> ClientCapabilities -> FilePath -> Session a -> IO a-runSessionWithServerAndCaps config plugin caps fp act = do-  recorder <- pluginTestRecorder-  runSessionWithServer' (plugin recorder) config def caps fp act- runSessionWithServerInTmpDir :: Pretty b => Config -> PluginTestDescriptor b -> VirtualFileTree -> Session a -> IO a-runSessionWithServerInTmpDir config plugin tree act = do-  recorder <- pluginTestRecorder-  runSessionWithServerInTmpDir' (plugin recorder) config def fullCaps tree act+runSessionWithServerInTmpDir config plugin tree act =+    runSessionWithTestConfig def+    {testLspConfig=config, testPluginDescriptor = plugin,  testDirLocation=Right tree}+    (const act) -runSessionWithServerAndCapsInTmpDir :: Pretty b => Config ->  PluginTestDescriptor b -> ClientCapabilities -> VirtualFileTree -> Session a -> IO a-runSessionWithServerAndCapsInTmpDir config plugin caps tree act = do-  recorder <- pluginTestRecorder-  runSessionWithServerInTmpDir' (plugin recorder) config def caps tree act+runWithLockInTempDir :: VirtualFileTree -> (FileSystem -> IO a) ->  IO a+runWithLockInTempDir tree act = withLock lockForTempDirs $ do+    testRoot <- setupTestEnvironment+    helperRecorder <- hlsHelperTestRecorder+    -- Do not clean up the temporary directory if this variable is set to anything but '0'.+    -- Aids debugging.+    cleanupTempDir <- lookupEnv "HLS_TEST_HARNESS_NO_TESTDIR_CLEANUP"+    let runTestInDir action = case cleanupTempDir of+            Just val | val /= "0" -> do+                (tempDir, _) <- newTempDirWithin testRoot+                a <- action tempDir+                logWith helperRecorder Debug LogNoCleanup+                pure a --- | Host a server, and run a test session on it.------ Creates a temporary directory, and materializes the VirtualFileTree--- in the temporary directory.------ To debug test cases and verify the file system is correctly set up,--- you should set the environment variable 'HLS_TEST_HARNESS_NO_TESTDIR_CLEANUP=1'.--- Further, we log the temporary directory location on startup. To view--- the logs, set the environment variable 'HLS_TEST_HARNESS_STDERR=1'.------ Example invocation to debug test cases:------ @---   HLS_TEST_HARNESS_NO_TESTDIR_CLEANUP=1 HLS_TEST_HARNESS_STDERR=1 cabal test <plugin-name>--- @------ Don't forget to use 'TASTY_PATTERN' to debug only a subset of tests.------ For plugin test logs, look at the documentation of 'mkPluginTestDescriptor'.------ Note: cwd will be shifted into a temporary directory in @Session a@-runSessionWithServerInTmpDir' ::-  -- | Plugins to load on the server.-  ---  -- For improved logging, make sure these plugins have been initalised with-  -- the recorder produced by @pluginTestRecorder@.-  IdePlugins IdeState ->-  -- | lsp config for the server-  Config ->-  -- | config for the test session-  SessionConfig ->-  ClientCapabilities ->-  VirtualFileTree ->-  Session a ->-  IO a-runSessionWithServerInTmpDir' plugins conf sessConf caps tree act = withLock lockForTempDirs $ do-  testRoot <- setupTestEnvironment-  recorder <- initialiseTestRecorder-    ["LSP_TEST_LOG_STDERR", "HLS_TEST_HARNESS_STDERR", "HLS_TEST_LOG_STDERR"]+            _ -> do+                (tempDir, cleanup) <- newTempDirWithin testRoot+                a <- action tempDir `finally` cleanup+                logWith helperRecorder Debug LogCleanup+                pure a+    runTestInDir $ \tmpDir' -> do+        -- we canonicalize the path, so that we do not need to do+        -- cannibalization during the test when we compare two paths+        tmpDir <- canonicalizePath tmpDir'+        logWith helperRecorder Info $ LogTestDir tmpDir+        fs <- FS.materialiseVFT tmpDir tree+        act fs -  -- Do not clean up the temporary directory if this variable is set to anything but '0'.-  -- Aids debugging.-  cleanupTempDir <- lookupEnv "HLS_TEST_HARNESS_NO_TESTDIR_CLEANUP"-  let runTestInDir action = case cleanupTempDir of-        Just val-          | val /= "0" -> do-            (tempDir, _) <- newTempDirWithin testRoot-            a <- action tempDir-            logWith recorder Debug LogNoCleanup-            pure a+runSessionWithServer :: Pretty b => Config -> PluginTestDescriptor b -> FilePath -> Session a -> IO a+runSessionWithServer config plugin fp act =+    runSessionWithTestConfig def {+        testLspConfig=config+        , testPluginDescriptor=plugin+        , testDirLocation = Left fp+        } (const act) -        _ -> do-          (tempDir, cleanup) <- newTempDirWithin testRoot-          a <- action tempDir `finally` cleanup-          logWith recorder Debug LogCleanup-          pure a -  runTestInDir $ \tmpDir -> do-    logWith recorder Info $ LogTestDir tmpDir-    _fs <- FS.materialiseVFT tmpDir tree-    runSessionWithServer' plugins conf sessConf caps tmpDir act+instance Default (TestConfig b) where+  def = TestConfig {+    testDirLocation = Right $ VirtualFileTree [] "",+    testClientRoot = Nothing,+    testServerRoot = Nothing,+    testShiftRoot = False,+    testDisableKick = False,+    testDisableDefaultPlugin = False,+    testPluginDescriptor = mempty,+    testLspConfig = def,+    testConfigSession = def,+    testConfigCaps = fullLatestClientCaps,+    testCheckProject = False+  }  -- | Setup the test environment for isolated tests. --@@ -577,61 +672,93 @@ lockForTempDirs :: Lock lockForTempDirs = unsafePerformIO newLock --- | Host a server, and run a test session on it--- Note: cwd will be shifted into @root@ in @Session a@-runSessionWithServer' ::-  -- | Plugins to load on the server.-  ---  -- For improved logging, make sure these plugins have been initalised with-  -- the recorder produced by @pluginTestRecorder@.-  IdePlugins IdeState ->-  -- | lsp config for the server-  Config ->-  -- | config for the test session-  SessionConfig ->-  ClientCapabilities ->-  FilePath ->-  Session a ->-  IO a-runSessionWithServer' plugins conf sconf caps root s =  withLock lock $ keepCurrentDirectory $ do-    (inR, inW) <- createPipe-    (outR, outW) <- createPipe+data TestConfig b = TestConfig+  {+    testDirLocation          :: Either FilePath VirtualFileTree+    -- ^ Client capabilities+    -- ^ The file tree to use for the test, either a directory or a virtual file tree+    -- if using a virtual file tree,+    -- Creates a temporary directory, and materializes the VirtualFileTree+    -- in the temporary directory.+    --+    -- To debug test cases and verify the file system is correctly set up,+    -- you should set the environment variable 'HLS_TEST_HARNESS_NO_TESTDIR_CLEANUP=1'.+    -- Further, we log the temporary directory location on startup. To view+    -- the logs, set the environment variable 'HLS_TEST_HARNESS_STDERR=1'.+    -- Example invocation to debug test cases:+    --+    -- @+    --   HLS_TEST_HARNESS_NO_TESTDIR_CLEANUP=1 HLS_TEST_HARNESS_STDERR=1 cabal test <plugin-name>+    -- @+    --+    -- Don't forget to use 'TASTY_PATTERN' to debug only a subset of tests.+    --+    -- For plugin test logs, look at the documentation of 'mkPluginTestDescriptor'.+  , testShiftRoot            :: Bool+    -- ^ Whether to shift the current directory to the root of the project+  , testClientRoot           :: Maybe FilePath+    -- ^ Specify the root of (the client or LSP context),+    -- if Nothing it is the same as the testDirLocation+    -- if Just, it is subdirectory of the testDirLocation+  , testServerRoot           :: Maybe FilePath+    -- ^ Specify root of the server, in exe, it can be specify in command line --cwd,+    -- or just the server start directory+    -- if Nothing it is the same as the testDirLocation+    -- if Just, it is subdirectory of the testDirLocation+  , testDisableKick          :: Bool+    -- ^ Whether to disable the kick action+  , testDisableDefaultPlugin :: Bool+    -- ^ Whether to disable the default plugin comes with ghcide+  , testCheckProject         :: Bool+    -- ^ Whether to typecheck check the project after the session is loaded+  , testPluginDescriptor     :: PluginTestDescriptor b+    -- ^ Plugin to load on the server.+  , testLspConfig            :: Config+    -- ^ lsp config for the server+  , testConfigSession        :: SessionConfig+    -- ^ config for the test session+  , testConfigCaps           :: ClientCapabilities+    -- ^ Client capabilities+  } -    -- Allow three environment variables, because "LSP_TEST_LOG_STDERR" has been used before,-    -- (thus, backwards compatibility) and "HLS_TEST_SERVER_LOG_STDERR" because it-    -- uses a more descriptive name.-    -- It is also in better accordance with 'pluginTestRecorder' which uses "HLS_TEST_PLUGIN_LOG_STDERR".-    -- At last, "HLS_TEST_LOG_STDERR" is intended to enable all logging for the server and the plugins-    -- under test.-    recorder <- initialiseTestRecorder-      ["LSP_TEST_LOG_STDERR", "HLS_TEST_SERVER_LOG_STDERR", "HLS_TEST_LOG_STDERR"] -    let-        sconf' = sconf { lspConfig = hlsConfigToClientConfig conf }--        hlsPlugins = IdePlugins [Test.blockCommandDescriptor "block-command"] <> plugins+wrapClientLogger :: Pretty a => Recorder (WithPriority a) ->+    IO (Recorder (WithPriority a), LSP.LanguageContextEnv Config -> IO ())+wrapClientLogger logger = do+    (lspLogRecorder', cb1) <- Logger.withBacklog Logger.lspClientLogRecorder+    let lspLogRecorder = cmapWithPrio (renderStrict . layoutPretty defaultLayoutOptions. pretty) lspLogRecorder'+    return (lspLogRecorder <> logger, cb1) -        arguments@Arguments{ argsIdeOptions } =-            testing (cmapWithPrio LogIDEMain recorder) hlsPlugins+-- | Host a server, and run a test session on it.+-- For setting custom timeout, set the environment variable 'LSP_TIMEOUT'+-- * LSP_TIMEOUT=10 cabal test+-- For more detail of the test configuration, see 'TestConfig'+runSessionWithTestConfig :: Pretty b => TestConfig b -> (FilePath -> Session a) -> IO a+runSessionWithTestConfig TestConfig{..} session =+    runSessionInVFS testDirLocation $ \root -> shiftRoot root $ do+    (inR, inW) <- createPipe+    (outR, outW) <- createPipe+    let serverRoot = fromMaybe root testServerRoot+    let clientRoot = fromMaybe root testClientRoot -        ideOptions config ghcSession =-            let defIdeOptions = argsIdeOptions config ghcSession-            in defIdeOptions-                    { optTesting = IdeTesting True-                    , optCheckProject = pure False-                    }+    (recorder, cb1) <- wrapClientLogger =<< hlsPluginTestRecorder+    (recorderIde, cb2) <- wrapClientLogger =<< hlsHelperTestRecorder+    -- This plugin just installs a handler for the `initialized` notification, which then+    -- picks up the LSP environment and feeds it to our recorders+    let lspRecorderPlugin = pluginDescToIdePlugins [(defaultPluginDescriptor "LSPRecorderCallback" "Internal plugin")+          { pluginNotificationHandlers = mkPluginNotificationHandler LSP.SMethod_Initialized $ \_ _ _ _ -> do+              env <- LSP.getLspEnv+              liftIO $ (cb1 <> cb2) env+          }] +    let plugins = testPluginDescriptor recorder <> lspRecorderPlugin+    timeoutOverride <- fmap read <$> lookupEnv "LSP_TIMEOUT"+    let sconf' = testConfigSession { lspConfig = hlsConfigToClientConfig testLspConfig, messageTimeout = fromMaybe (messageTimeout defaultConfig) timeoutOverride}+        arguments = testingArgs serverRoot recorderIde plugins     server <- async $-        IDEMain.defaultMain (cmapWithPrio LogIDEMain recorder)-            arguments-                { argsHandleIn = pure inR-                , argsHandleOut = pure outW-                , argsDefaultHlsConfig = conf-                , argsIdeOptions = ideOptions-                , argsProjectRoot = Just root-                }--    x <- runSessionWithHandles inW outR sconf' caps root s+        IDEMain.defaultMain (cmapWithPrio LogIDEMain recorderIde)+            arguments { argsHandleIn = pure inR , argsHandleOut = pure outW }+    result <- runSessionWithHandles inW outR sconf' testConfigCaps clientRoot (session root)     hClose inW     timeout 3 (wait server) >>= \case         Just () -> pure ()@@ -639,8 +766,45 @@             putStrLn "Server does not exit in 3s, canceling the async task..."             (t, _) <- duration $ cancel server             putStrLn $ "Finishing canceling (took " <> showDuration t <> "s)"-    pure x+    pure result +    where+        shiftRoot shiftTarget f  =+            if testShiftRoot+                then withLock lock $ keepCurrentDirectory $ setCurrentDirectory shiftTarget >> f+                else f+        runSessionInVFS (Left testConfigRoot) act = do+            root <- makeAbsolute testConfigRoot+            act root+        runSessionInVFS (Right vfs) act = runWithLockInTempDir vfs $ \fs -> act (fsRoot fs)+        testingArgs prjRoot recorderIde plugins =+            let+                arguments@Arguments{ argsHlsPlugins, argsIdeOptions, argsLspOptions } = defaultArguments (cmapWithPrio LogIDEMain recorderIde) prjRoot plugins+                argsHlsPlugins' = if testDisableDefaultPlugin+                                then plugins+                                else argsHlsPlugins+                hlsPlugins = pluginDescToIdePlugins $ idePluginsToPluginDesc argsHlsPlugins'+                    ++ [Test.blockCommandDescriptor "block-command", Test.plugin]+                ideOptions config sessionLoader = (argsIdeOptions config sessionLoader){+                    optTesting = IdeTesting True+                    , optCheckProject = pure testCheckProject+                    }+            in+                arguments+                { argsHlsPlugins = hlsPlugins+                , argsIdeOptions = ideOptions+                , argsLspOptions = argsLspOptions { LSP.optProgressStartDelay = 0, LSP.optProgressUpdateDelay = 0 }+                , argsDefaultHlsConfig = testLspConfig+                , argsProjectRoot = prjRoot+                , argsDisableKick = testDisableKick+                }++-- | Wait for the next progress begin step+waitForProgressBegin :: Session ()+waitForProgressBegin = skipManyTill anyMessage $ satisfyMaybe $ \case+  FromServerMess  SMethod_Progress  (TNotificationMessage _ _ (ProgressParams _ v)) | is _workDoneProgressBegin v-> Just ()+  _ -> Nothing+ -- | Wait for the next progress end step waitForProgressDone :: Session () waitForProgressDone = skipManyTill anyMessage $ satisfyMaybe $ \case@@ -670,7 +834,7 @@         -- assume a ghcide binary lacking the WaitForShakeQueue method         _                                    -> return 0 -callTestPlugin :: (A.FromJSON b) => TestRequest -> Session (Either ResponseError b)+callTestPlugin :: (A.FromJSON b) => TestRequest -> Session (Either (TResponseError @ClientToServer (Method_CustomMethod "test")) b) callTestPlugin cmd = do     let cm = SMethod_CustomMethod (Proxy @"test")     waitId <- sendRequest cm (A.toJSON cmd)@@ -678,17 +842,17 @@     return $ do       e <- _result       case A.fromJSON e of-        A.Error err -> Left $ ResponseError (InR ErrorCodes_InternalError) (T.pack err) Nothing+        A.Error err -> Left $ TResponseError (InR ErrorCodes_InternalError) (T.pack err) Nothing         A.Success a -> pure a -waitForAction :: String -> TextDocumentIdentifier -> Session (Either ResponseError WaitForIdeRuleResult)+waitForAction :: String -> TextDocumentIdentifier -> Session (Either (TResponseError @ClientToServer (Method_CustomMethod "test")) WaitForIdeRuleResult) waitForAction key TextDocumentIdentifier{_uri} =     callTestPlugin (WaitForIdeRule key _uri) -waitForTypecheck :: TextDocumentIdentifier -> Session (Either ResponseError Bool)+waitForTypecheck :: TextDocumentIdentifier -> Session (Either (TResponseError @ClientToServer (Method_CustomMethod "test")) Bool) waitForTypecheck tid = fmap ideResultSuccess <$> waitForAction "typecheck" tid -getLastBuildKeys :: Session (Either ResponseError [T.Text])+getLastBuildKeys :: Session (Either (TResponseError @ClientToServer (Method_CustomMethod "test")) [T.Text]) getLastBuildKeys = callTestPlugin GetBuildKeysBuilt  hlsConfigToClientConfig :: Config -> A.Object
src/Test/Hls/FileSystem.hs view
@@ -20,6 +20,7 @@   , directory   , text   , ref+  , copyDir   -- * Cradle helpers   , directCradle   , simpleCabalCradle@@ -37,6 +38,7 @@ import           Language.LSP.Protocol.Types (toNormalizedFilePath) import           System.Directory import           System.FilePath             as FP+import           System.Process.Extra        (readProcess)  -- ---------------------------------------------------------------------------- -- Top Level definitions@@ -64,8 +66,9 @@     } deriving (Eq, Ord, Show)  data FileTree-  = File FilePath Content-  | Directory FilePath [FileTree]+  = File FilePath Content -- ^ Create a file with the given content.+  | Directory FilePath [FileTree] -- ^ Create a directory with the given files.+  | CopiedDirectory FilePath -- ^ Copy a directory from the test data dir.   deriving (Show, Eq, Ord)  data Content@@ -99,13 +102,22 @@       rootDir = FP.normalise rootDir'        persist :: FilePath -> FileTree -> IO ()-      persist fp (File name cts) = case cts of-        Inline txt -> T.writeFile (fp </> name) txt-        Ref path -> copyFile (testDataDir </> FP.normalise path) (fp </> takeFileName name)-      persist fp (Directory name nodes) = do-        createDirectory (fp </> name)-        mapM_ (persist (fp </> name)) nodes+      persist root (File name cts) = case cts of+        Inline txt -> T.writeFile (root </> name) txt+        Ref path -> copyFile (testDataDir </> FP.normalise path) (root </> takeFileName name)+      persist root (Directory name nodes) = do+        createDirectory (root </> name)+        mapM_ (persist (root </> name)) nodes+      persist root (CopiedDirectory name) = do+        copyDir' root name +      copyDir' :: FilePath -> FilePath -> IO ()+      copyDir' root dir = do+        files <- fmap FP.normalise . lines <$> withCurrentDirectory (testDataDir </> dir) (readProcess "git" ["ls-files", "--cached", "--modified", "--others"] "")+        mapM_ (createDirectoryIfMissing True . ((root </>) . takeDirectory)) files+        mapM_ (\f -> copyFile (testDataDir </> dir </> f) (root </> f)) files+        return ()+   traverse_ (persist rootDir) fileTree   pure $ FileSystem rootDir fileTree testDataDir @@ -115,8 +127,7 @@ -- -- File references in 'virtualFileTree' are resolved relative to the @vftOriginalRoot@. materialiseVFT :: FilePath -> VirtualFileTree -> IO FileSystem-materialiseVFT root fs =-  materialise root (vftTree fs) (vftOriginalRoot fs)+materialiseVFT root fs = materialise root (vftTree fs) (vftOriginalRoot fs)  -- ---------------------------------------------------------------------------- -- Test definition helpers@@ -153,6 +164,11 @@ -- The filepath is always resolved to the root of the test data dir. copy :: FilePath -> FileTree copy fp = File fp (Ref fp)++-- | Copy a directory into a test project.+-- The filepath is always resolved to the root of the test data dir.+copyDir :: FilePath -> FileTree+copyDir dir = CopiedDirectory dir  directory :: FilePath -> [FileTree] -> FileTree directory name nodes = Directory name nodes
src/Test/Hls/Util.hs view
@@ -2,7 +2,6 @@ {-# LANGUAGE DataKinds             #-} {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE GADTs                 #-}-{-# LANGUAGE OverloadedLabels      #-} {-# LANGUAGE OverloadedStrings     #-} module Test.Hls.Util   (  -- * Test Capabilities@@ -30,14 +29,12 @@     , dontExpectCodeAction     , expectDiagnostic     , expectNoMoreDiagnostics-    , expectSameLocations     , failIfSessionTimeout     , getCompletionByLabel     , noLiteralCaps     , inspectCodeAction     , inspectCommand     , inspectDiagnostic-    , SymbolLocation     , waitForDiagnosticsFrom     , waitForDiagnosticsFromSource     , waitForDiagnosticsFromSourceWithTimeout@@ -45,39 +42,49 @@     , withCurrentDirectoryInTmp     , withCurrentDirectoryInTmp'     , withCanonicalTempDir+    -- * Extract positions from input file.+    , extractCursorPositions+    , mkParameterisedLabel+    , trimming   ) where -import           Control.Applicative.Combinators (skipManyTill, (<|>))-import           Control.Exception               (catch, throwIO)-import           Control.Lens                    (_Just, (&), (.~), (?~), (^.))+import           Control.Applicative.Combinators          (skipManyTill, (<|>))+import           Control.Exception                        (catch, throwIO)+import           Control.Lens                             (_Just, (&), (.~),+                                                           (?~), (^.)) import           Control.Monad import           Control.Monad.IO.Class-import qualified Data.Aeson                      as A-import           Data.Bool                       (bool)+import qualified Data.Aeson                               as A+import           Data.Bool                                (bool) import           Data.Default-import           Data.List.Extra                 (find)+import           Data.List.Extra                          (find) import           Data.Proxy-import           Data.Row-import qualified Data.Set                        as Set-import qualified Data.Text                       as T-import           Development.IDE                 (GhcVersion (..), ghcVersion)-import qualified Language.LSP.Protocol.Lens      as L+import qualified Data.Text                                as T+import           Development.IDE                          (GhcVersion (..),+                                                           ghcVersion)+import qualified Language.LSP.Protocol.Lens               as L import           Language.LSP.Protocol.Message import           Language.LSP.Protocol.Types-import qualified Language.LSP.Test               as Test+import qualified Language.LSP.Test                        as Test import           System.Directory import           System.FilePath-import           System.Info.Extra               (isMac, isWindows)+import           System.Info.Extra                        (isMac, isWindows) import qualified System.IO.Extra import           System.IO.Temp-import           System.Time.Extra               (Seconds, sleep)-import           Test.Tasty                      (TestTree)-import           Test.Tasty.ExpectedFailure      (expectFailBecause,-                                                  ignoreTestBecause)-import           Test.Tasty.HUnit                (Assertion, assertFailure,-                                                  (@?=))+import           System.Time.Extra                        (Seconds, sleep)+import           Test.Tasty                               (TestTree)+import           Test.Tasty.ExpectedFailure               (expectFailBecause,+                                                           ignoreTestBecause)+import           Test.Tasty.HUnit                         (assertFailure) +import qualified Data.List                                as List+import qualified Data.Text.Internal.Search                as T+import qualified Data.Text.Utf16.Rope.Mixed               as Rope+import           Development.IDE.Plugin.Completions.Logic (getCompletionPrefixFromRope)+import           Development.IDE.Plugin.Completions.Types (PosPrefixInfo (..))+import           NeatInterpolation                        (trimming)+ noLiteralCaps :: ClientCapabilities noLiteralCaps = def & L.textDocument ?~ textDocumentCaps   where@@ -89,15 +96,15 @@   where     textDocumentCaps = def { _codeAction = Just codeActionCaps }     codeActionCaps = CodeActionClientCapabilities (Just True) (Just literalSupport) (Just True) Nothing Nothing Nothing Nothing-    literalSupport = #codeActionKind .==  (#valueSet .== [])+    literalSupport = ClientCodeActionLiteralOptions (ClientCodeActionKindOptions [])  codeActionResolveCaps :: ClientCapabilities-codeActionResolveCaps = Test.fullCaps-                          & (L.textDocument . _Just . L.codeAction . _Just . L.resolveSupport . _Just) .~ (#properties .== ["edit"])+codeActionResolveCaps = Test.fullLatestClientCaps+                          & (L.textDocument . _Just . L.codeAction . _Just . L.resolveSupport . _Just) .~ ClientCodeActionResolveOptions {_properties= ["edit"]}                           & (L.textDocument . _Just . L.codeAction . _Just . L.dataSupport . _Just) .~ True  codeActionNoResolveCaps :: ClientCapabilities-codeActionNoResolveCaps = Test.fullCaps+codeActionNoResolveCaps = Test.fullLatestClientCaps                           & (L.textDocument . _Just . L.codeAction . _Just . L.resolveSupport) .~ Nothing                           & (L.textDocument . _Just . L.codeAction . _Just . L.dataSupport . _Just) .~ False -- ---------------------------------------------------------------------@@ -316,23 +323,6 @@           errorHandler e@(Test.Timeout _) = assertFailure $ show e           errorHandler e                  = throwIO e --- | To locate a symbol, we provide a path to the file from the HLS root--- directory, the line number, and the column number. (0 indexed.)-type SymbolLocation = (FilePath, UInt, UInt)--expectSameLocations :: [Location] -> [SymbolLocation] -> Assertion-actual `expectSameLocations` expected = do-    let actual' =-            Set.map (\location -> (location ^. L.uri-                                   , location ^. L.range . L.start . L.line-                                   , location ^. L.range . L.start . L.character))-            $ Set.fromList actual-    expected' <- Set.fromList <$>-        (forM expected $ \(file, l, c) -> do-                              fp <- canonicalizePath file-                              return (filePathToUri fp, l, c))-    actual' @?= expected'- -- --------------------------------------------------------------------- getCompletionByLabel :: MonadIO m => T.Text -> [CompletionItem] -> m CompletionItem getCompletionByLabel desiredLabel compls =@@ -348,3 +338,119 @@ withCanonicalTempDir f = System.IO.Extra.withTempDir $ \dir -> do   dir' <- canonicalizePath dir   f dir'++-- ----------------------------------------------------------------------------+-- Extract Position data from the source file itself.+-- ----------------------------------------------------------------------------++-- | Pretty labelling for tests that use the parameterised test helpers.+mkParameterisedLabel :: PosPrefixInfo -> String+mkParameterisedLabel posPrefixInfo = unlines+    [ "Full Line:       \"" <> T.unpack (fullLine posPrefixInfo) <> "\""+    , "Cursor Column:   \"" <> replicate (fromIntegral $ cursorPos posPrefixInfo ^. L.character) ' ' ++ "^" <> "\""+    , "Prefix Text:     \"" <> T.unpack (prefixText posPrefixInfo) <> "\""+    ]++-- | Given a in-memory representation of a file, where a user can specify the+-- current cursor position using a '^' in the next line.+--+-- This function allows to generate multiple tests for a single input file, without+-- the hassle of calculating by hand where there cursor is supposed to be.+--+-- Example (line number has been added for readability):+--+-- @+--   0: foo = 2+--   1:  ^+--   2: bar =+--   3:      ^+-- @+--+-- This example input file contains two cursor positions (y, x), at+--+-- * (1, 1), and+-- * (3, 5).+--+-- 'extractCursorPositions' will search for '^' characters, and determine there are+-- two cursor positions in the text.+-- First, it will normalise the text to:+--+-- @+--   0: foo = 2+--   1: bar =+-- @+--+-- stripping away the '^' characters. Then, the actual cursor positions are:+--+-- * (0, 1) and+-- * (2, 5).+--+extractCursorPositions :: T.Text -> (T.Text, [PosPrefixInfo])+extractCursorPositions t =+    let+        textLines = T.lines t+        foldState = List.foldl' go emptyFoldState textLines+        finalText = foldStateToText foldState+        reconstructCompletionPrefix pos = getCompletionPrefixFromRope pos (Rope.fromText finalText)+        cursorPositions = reverse . fmap reconstructCompletionPrefix $ foldStatePositions foldState+    in+        (finalText, cursorPositions)++    where+        go foldState l = case T.indices "^" l of+            [] -> addTextLine foldState l+            xs -> List.foldl' addTextCursor foldState xs++-- | 'FoldState' is an implementation detail used to parse some file contents,+-- extracting the cursor positions identified by '^' and producing a cleaned+-- representation of the file contents.+data FoldState = FoldState+    { foldStateRows      :: !Int+    -- ^ The row index of the cleaned file contents.+    --+    -- For example, the file contents+    --+    -- @+    --   0: foo+    --   1: ^+    --   2: bar+    -- @+    -- will report that 'bar' is actually occurring in line '1', as '^' is+    -- a cursor position.+    -- Lines containing cursor positions are removed.+    , foldStatePositions :: ![Position]+    -- ^ List of cursors positions found in the file contents.+    --+    -- List is stored in reverse for efficient 'cons'ing+    , foldStateFinalText :: ![T.Text]+    -- ^ Final file contents with all lines containing cursor positions removed.+    --+    -- List is stored in reverse for efficient 'cons'ing+    }++emptyFoldState :: FoldState+emptyFoldState = FoldState+    { foldStateRows = 0+    , foldStatePositions = []+    , foldStateFinalText = []+    }++-- | Produce the final file contents, without any lines containing cursor positions.+foldStateToText :: FoldState -> T.Text+foldStateToText state = T.unlines $ reverse $ foldStateFinalText state++-- | We found a '^' at some location! Add it to the list of known cursor positions.+--+-- If the row index is '0', we throw an error, as there can't be a cursor position above the first line.+addTextCursor :: FoldState -> Int -> FoldState+addTextCursor state col+    | foldStateRows state <= 0 = error $ "addTextCursor: Invalid '^' found at: " <> show (col, foldStateRows state)+    | otherwise = state+        { foldStatePositions = Position (fromIntegral (foldStateRows state) - 1) (fromIntegral col) : foldStatePositions state+        }++addTextLine :: FoldState -> T.Text -> FoldState+addTextLine state l = state+    { foldStateFinalText = l : foldStateFinalText state+    , foldStateRows = foldStateRows state + 1+    }