Skip to content

Commit

Permalink
Add golden tests for public configs (#3922)
Browse files Browse the repository at this point in the history
Changes to the vscode schema need to be communicated to vscode-haskell plugin maintainers,
otherwise users can't make use of the new configurations.

In general, changes to the schema need to be done consciously when new plugin or features are added.
We add these golden tests as an additional contract to inform relevant
parties whenever the configs change.

To fix a failing of these tests, review the change. If it is expected, accept the change via:

    TASTY_PATTERN="generate schema" cabal test func-test --test-options=--accept

As changes need to be applied for all GHC version specific configs, you either need to run this command for each
GHC version that is affected by the config change, or manually add the change to all other golden config files.
Likely, the easiest way is to run CI and apply the generated diffs manually.

Co-authored-by: Michael Peyton Jones <me@michaelpj.com>
  • Loading branch information
fendor and michaelpj authored Jan 4, 2024
1 parent e5f6931 commit 93b6bf5
Show file tree
Hide file tree
Showing 16 changed files with 1,505 additions and 18 deletions.
8 changes: 4 additions & 4 deletions haskell-language-server.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -314,12 +314,12 @@ common floskell
cpp-options: -Dhls_floskell

common fourmolu
if flag(fourmolu)
if flag(fourmolu)
build-depends: hls-fourmolu-plugin == 2.5.0.0
cpp-options: -Dhls_fourmolu

common ormolu
if flag(ormolu)
if flag(ormolu)
build-depends: hls-ormolu-plugin == 2.5.0.0
cpp-options: -Dhls_ormolu

Expand Down Expand Up @@ -522,7 +522,6 @@ test-suite func-test
, data-default
, deepseq
, hashable
, hspec-expectations
, lens
, lens-aeson
, ghcide
Expand All @@ -541,6 +540,7 @@ test-suite func-test
main-is: Main.hs
other-modules:
Config
ConfigSchema
Format
FunctionalBadProject
HieBios
Expand All @@ -556,7 +556,7 @@ test-suite func-test
if flag(eval)
cpp-options: -Dhls_eval
-- formatters
if flag(floskell)
if flag(floskell)
cpp-options: -Dhls_floskell
if flag(fourmolu)
cpp-options: -Dhls_fourmolu
Expand Down
49 changes: 49 additions & 0 deletions test/functional/ConfigSchema.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
module ConfigSchema where


import qualified Data.ByteString.Lazy.Char8 as BS
import Data.Char (toLower)
import System.FilePath ((</>))
import System.Process.Extra
import Test.Hls
import Test.Hls.Command

-- | Integration test to capture changes to the generated default config and the vscode schema.
--
-- Changes to the vscode schema need to be communicated to vscode-haskell plugin maintainers,
-- otherwise users can't make use of the new configurations.
--
-- In general, changes to the schema need to be done consciously when new plugin or features are added.
-- To fix a failing of these tests, review the change. If it is expected, accept the change via:
--
-- @
-- TASTY_PATTERN="generate schema" cabal test func-test --test-options=--accept
-- @
--
-- As changes need to be applied for all GHC version specific configs, you either need to run this command for each
-- GHC version that is affected by the config change, or manually add the change to all other golden config files.
-- Likely, the easiest way is to run CI and apply the generated diffs manually.
tests :: TestTree
tests = testGroup "generate schema"
[ goldenGitDiff "vscode-extension-schema" (vscodeSchemaFp ghcVersion) $ do
stdout <- readProcess hlsExeCommand ["vscode-extension-schema"] ""
pure $ BS.pack stdout
, goldenGitDiff "generate-default-config" (defaultConfigFp ghcVersion) $ do
stdout <- readProcess hlsExeCommand ["generate-default-config"] ""
pure $ BS.pack stdout
]

vscodeSchemaFp :: GhcVersion -> FilePath
vscodeSchemaFp ghcVer = "test" </> "testdata" </> "schema" </> prettyGhcVersion ghcVer </> vscodeSchemaJson

defaultConfigFp :: GhcVersion -> FilePath
defaultConfigFp ghcVer = "test" </> "testdata" </> "schema" </> prettyGhcVersion ghcVer </> generateDefaultConfigJson

vscodeSchemaJson :: FilePath
vscodeSchemaJson = "vscode-extension-schema.golden.json"

generateDefaultConfigJson :: FilePath
generateDefaultConfigJson = "default-config.golden.json"

prettyGhcVersion :: GhcVersion -> String
prettyGhcVersion ghcVer = map toLower (show ghcVer)
4 changes: 2 additions & 2 deletions test/functional/Format.hs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ tests = testGroup "format document"

providerTests :: TestTree
providerTests = testGroup "lsp formatting provider"
[ testCase "respects none" $ runSessionWithConfig (formatConfig "none") hlsCommand fullCaps "test/testdata/format" $ do
[ testCase "respects none" $ runSessionWithConfig (formatConfig "none") hlsLspCommand fullCaps "test/testdata/format" $ do
void configurationRequest
doc <- openDoc "Format.hs" "haskell"
resp <- request SMethod_TextDocumentFormatting $ DocumentFormattingParams Nothing doc (FormattingOptions 2 True Nothing Nothing Nothing)
Expand All @@ -34,7 +34,7 @@ providerTests = testGroup "lsp formatting provider"
_ -> assertFailure $ "strange response from formatting provider:" ++ show result
result -> assertFailure $ "strange response from formatting provider:" ++ show result

, requiresOrmoluPlugin . requiresFloskellPlugin $ testCase "can change on the fly" $ runSessionWithConfig (formatConfig "none") hlsCommand fullCaps "test/testdata/format" $ do
, requiresOrmoluPlugin . requiresFloskellPlugin $ testCase "can change on the fly" $ runSessionWithConfig (formatConfig "none") hlsLspCommand fullCaps "test/testdata/format" $ do
void configurationRequest
formattedOrmolu <- liftIO $ T.readFile "test/testdata/format/Format.ormolu.formatted.hs"
formattedFloskell <- liftIO $ T.readFile "test/testdata/format/Format.floskell.formatted.hs"
Expand Down
4 changes: 2 additions & 2 deletions test/functional/FunctionalBadProject.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import Test.Hls.Command
tests :: TestTree
tests = testGroup "behaviour on malformed projects"
[ testCase "Missing module diagnostic" $ do
runSession hlsCommand fullCaps "test/testdata/missingModuleTest/missingModule/" $ do
runSession hlsLspCommand fullCaps "test/testdata/missingModuleTest/missingModule/" $ do
doc <- openDoc "src/MyLib.hs" "haskell"
[diag] <- waitForDiagnosticsFrom doc
liftIO $ assertBool "missing module name" $ "MyLib" `T.isInfixOf` (diag ^. L.message)
liftIO $ assertBool "module missing context" $ "may not be listed" `T.isInfixOf` (diag ^. L.message)
, testCase "Missing module diagnostic - no matching prefix" $ do
runSession hlsCommand fullCaps "test/testdata/missingModuleTest/noPrefixMatch/" $ do
runSession hlsLspCommand fullCaps "test/testdata/missingModuleTest/noPrefixMatch/" $ do
doc <- openDoc "app/Other.hs" "haskell"
[diag] <- waitForDiagnosticsFrom doc
liftIO $ assertBool "missing module name" $
Expand Down
2 changes: 1 addition & 1 deletion test/functional/HieBios.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Test.Hls.Command
tests :: TestTree
tests = testGroup "hie-bios"
[ testCase "loads main-is module" $ do
runSession hlsCommand fullCaps "test/testdata/hieBiosMainIs" $ do
runSession hlsLspCommand fullCaps "test/testdata/hieBiosMainIs" $ do
_ <- openDoc "Main.hs" "haskell"
(diag:_) <- waitForDiagnostics
liftIO $ "Top-level binding with no type signature:" `T.isInfixOf` (diag ^. L.message)
Expand Down
2 changes: 2 additions & 0 deletions test/functional/Main.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module Main where

import Config
import ConfigSchema
import Format
import FunctionalBadProject
import HieBios
Expand All @@ -10,6 +11,7 @@ import Test.Hls
main :: IO ()
main = defaultTestRunner $ testGroup "haskell-language-server"
[ Config.tests
, ConfigSchema.tests
, ignoreInEnv [HostOS Windows, GhcVer GHC90, GhcVer GHC92] "Tests gets stuck in ci" $ Format.tests
, FunctionalBadProject.tests
, HieBios.tests
Expand Down
8 changes: 4 additions & 4 deletions test/functional/Progress.hs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ tests =
testGroup
"window/workDoneProgress"
[ testCase "sends indefinite progress notifications" $
runSession hlsCommand progressCaps "test/testdata/diagnostics" $ do
runSession hlsLspCommand progressCaps "test/testdata/diagnostics" $ do
let path = "Foo.hs"
_ <- openDoc path "haskell"
expectProgressMessages [pack ("Setting up diagnostics (for " ++ path ++ ")"), "Processing", "Indexing"] []
, requiresEvalPlugin $ testCase "eval plugin sends progress reports" $
runSession hlsCommand progressCaps "plugins/hls-eval-plugin/test/testdata" $ do
runSession hlsLspCommand progressCaps "plugins/hls-eval-plugin/test/testdata" $ do
doc <- openDoc "T1.hs" "haskell"
lspId <- sendRequest SMethod_TextDocumentCodeLens (CodeLensParams Nothing Nothing doc)

Expand All @@ -57,15 +57,15 @@ tests =
expectProgressMessages ["Evaluating"] activeProgressTokens
_ -> error $ "Unexpected response result: " ++ show response
, requiresOrmoluPlugin $ testCase "ormolu plugin sends progress notifications" $ do
runSessionWithConfig (def { ignoreConfigurationRequests = False }) hlsCommand progressCaps "test/testdata/format" $ do
runSessionWithConfig (def { ignoreConfigurationRequests = False }) hlsLspCommand progressCaps "test/testdata/format" $ do
void configurationRequest
setHlsConfig (formatLspConfig "ormolu")
doc <- openDoc "Format.hs" "haskell"
expectProgressMessages ["Setting up testdata (for Format.hs)", "Processing", "Indexing"] []
_ <- sendRequest SMethod_TextDocumentFormatting $ DocumentFormattingParams Nothing doc (FormattingOptions 2 True Nothing Nothing Nothing)
expectProgressMessages ["Formatting Format.hs"] []
, requiresFourmoluPlugin $ testCase "fourmolu plugin sends progress notifications" $ do
runSessionWithConfig (def { ignoreConfigurationRequests = False }) hlsCommand progressCaps "test/testdata/format" $ do
runSessionWithConfig (def { ignoreConfigurationRequests = False }) hlsLspCommand progressCaps "test/testdata/format" $ do
void configurationRequest
setHlsConfig (formatLspConfig "fourmolu")
doc <- openDoc "Format.hs" "haskell"
Expand Down
121 changes: 121 additions & 0 deletions test/testdata/schema/ghc92/default-config.golden.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
{
"checkParents": "CheckOnSave",
"checkProject": true,
"formattingProvider": "ormolu",
"maxCompletions": 40,
"plugin": {
"alternateNumberFormat": {
"globalOn": true
},
"cabal": {
"codeActionsOn": true,
"completionOn": true
},
"callHierarchy": {
"globalOn": true
},
"changeTypeSignature": {
"globalOn": true
},
"class": {
"codeActionsOn": true,
"codeLensOn": true
},
"eval": {
"config": {
"diff": true,
"exception": false
},
"globalOn": true
},
"explicit-fields": {
"globalOn": true
},
"explicit-fixity": {
"globalOn": true
},
"fourmolu": {
"config": {
"external": false
}
},
"gadt": {
"globalOn": true
},
"ghcide-code-actions-bindings": {
"globalOn": true
},
"ghcide-code-actions-fill-holes": {
"globalOn": true
},
"ghcide-code-actions-imports-exports": {
"globalOn": true
},
"ghcide-code-actions-type-signatures": {
"globalOn": true
},
"ghcide-completions": {
"config": {
"autoExtendOn": true,
"snippetsOn": true
},
"globalOn": true
},
"ghcide-hover-and-symbols": {
"hoverOn": true,
"symbolsOn": true
},
"ghcide-type-lenses": {
"config": {
"mode": "always"
},
"globalOn": true
},
"hlint": {
"codeActionsOn": true,
"config": {
"flags": []
},
"diagnosticsOn": true
},
"importLens": {
"codeActionsOn": true,
"codeLensOn": true
},
"moduleName": {
"globalOn": true
},
"ormolu": {
"config": {
"external": false
}
},
"overloaded-record-dot": {
"globalOn": true
},
"pragmas-completion": {
"globalOn": true
},
"pragmas-disable": {
"globalOn": true
},
"pragmas-suggest": {
"globalOn": true
},
"qualifyImportedNames": {
"globalOn": true
},
"rename": {
"config": {
"crossModule": false
},
"globalOn": true
},
"retrie": {
"globalOn": true
},
"splice": {
"globalOn": true
}
}
}
Loading

0 comments on commit 93b6bf5

Please sign in to comment.