diff --git a/.gitignore b/.gitignore index b165dd910..a36bebdd9 100644 --- a/.gitignore +++ b/.gitignore @@ -5,21 +5,16 @@ /tags /cabal.project.local /cabal.project.local~ +cabal.sandbox.config .stack-work stack*.yaml.lock /.dir-locals.el /.vscode /.ghc.environment* -/lsp-types/cabal.project.local -/lsp-types/cabal.project.local~ *.swp *.swo *.orig *.DS_Store .hspec-failures -/lsp-types/dist/ -/lsp-types/dist-newstyle/ -/lsp-types/TAGS -/lsp-types/tags -/lsp-types/ctags +hie .hie diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index a054b5a5a..000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "submodules/yi-rope"] - path = submodules/yi-rope - url = https://github.com/alanz/yi-rope.git diff --git a/README.md b/README.md index 8ce9d82de..9fb308f62 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,13 @@ ![CI](https://github.com/alanz/lsp/workflows/Haskell%20CI/badge.svg) [![Hackage](https://img.shields.io/hackage/v/lsp?label=lsp)](https://hackage.haskell.org/package/lsp) [![Hackage](https://img.shields.io/hackage/v/lsp?label=lsp-types)](https://hackage.haskell.org/package/lsp-types) +[![Hackage](https://img.shields.io/hackage/v/lsp?label=lsp-test)](https://hackage.haskell.org/package/lsp-test) # lsp Haskell library for the Microsoft Language Server Protocol. It currently implements all of the [3.15 specification](https://microsoft.github.io/language-server-protocol/specifications/specification-3-15/). -It is split into two separate packages, `lsp` and `lsp-types` +It is split into three separate packages, `lsp`, `lsp-types`, and `lsp-test`: - `lsp-types` provides *type-safe* definitions that match up with the typescript definitions laid out in the specification - `lsp` is a library for building language servers, handling: @@ -17,14 +18,14 @@ typescript definitions laid out in the specification - Dynamic registration of capabilities - Cancellable requests and progress notifications - Publishing and flushing of diagnostics +- `lsp-test` is a functional testing framework for Language Server Protocol servers. ## Language servers built on lsp -- [ghcide](https://github.com/haskell/ghcide) - [haskell-language-server](https://github.com/haskell/haskell-language-server) - [dhall-lsp-server](https://github.com/dhall-lang/dhall-haskell/tree/master/dhall-lsp-server#readme) ## Example language servers -There are two example language servers in the `example/` folder. `Simple.hs` provides a minimal example: +There are two example language servers in the `lsp/example/` folder. `Simple.hs` provides a minimal example: ```haskell {-# LANGUAGE OverloadedStrings #-} @@ -80,12 +81,61 @@ from source with cabal install lsp-demo-simple-server lsp-demo-reactor-server stack install :lsp-demo-simple-server :lsp-demo-reactor-server --flag haskell-lsp:demo + +## Examples of using lsp-test + +### Setting up a session + +```haskell +import Language.LSP.Test +main = runSession "hie" fullCaps "proj/dir" $ do + doc <- openDoc "Foo.hs" "haskell" + skipMany anyNotification + symbols <- getDocumentSymbols doc +``` + +### Unit tests with HSpec + +```haskell +describe "diagnostics" $ + it "report errors" $ runSession "hie" fullCaps "test/data" $ do + openDoc "Error.hs" "haskell" + [diag] <- waitForDiagnosticsSource "ghcmod" + liftIO $ do + diag ^. severity `shouldBe` Just DsError + diag ^. source `shouldBe` Just "ghcmod" +``` + +### Replaying captured session +```haskell +replaySession "hie" "test/data/renamePass" +``` + +### Parsing with combinators +```haskell +skipManyTill loggingNotification publishDiagnosticsNotification +count 4 (message :: Session ApplyWorkspaceEditRequest) +anyRequest <|> anyResponse +``` + +Try out the example tests in the `lsp-test/example` directory with `cabal test`. +For more examples check the [Wiki](https://github.com/bubba/lsp-test/wiki/Introduction), or see this [introductory blog post](https://lukelau.me/haskell/posts/lsp-test/). + +Whilst writing your tests you may want to debug them to see what's going wrong. +You can set the `logMessages` and `logStdErr` options in `SessionConfig` to see what the server is up to. +There are also corresponding environment variables so you can turn them on from the command line: +``` +LSP_TEST_LOG_MESSAGES=1 LSP_TEST_LOG_STDERR=1 cabal test +``` + +## Troubleshooting +Seeing funny stuff when running lsp-test via stack? If your server is built upon Haskell tooling, [keep in mind that stack sets some environment variables related to GHC, and you may want to unset them.](https://github.com/alanz/haskell-ide-engine/blob/bfb16324d396da71000ef81d51acbebbdaa854ab/test/utils/TestUtils.hs#L290-L298) ## Useful links -- https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md +- [Language Server Protocol Specification](https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md) ## Other resources -See #haskell-ide-engine on IRC freenode +See #haskell-language-server on IRC freenode. diff --git a/Setup.hs b/Setup.hs deleted file mode 100644 index 9a994af67..000000000 --- a/Setup.hs +++ /dev/null @@ -1,2 +0,0 @@ -import Distribution.Simple -main = defaultMain diff --git a/bench/simple-bench.cabal b/bench/simple-bench.cabal deleted file mode 100644 index df2a5396e..000000000 --- a/bench/simple-bench.cabal +++ /dev/null @@ -1,15 +0,0 @@ -cabal-version: >=1.10 -name: simple-bench -version: 0.1.0.0 -build-type: Simple - -benchmark simple-bench - main-is: SimpleBench.hs - type: exitcode-stdio-1.0 - build-depends: base <4.15 - , lsp-test - , lsp - , process - , extra - default-language: Haskell2010 - ghc-options: -Wall -O2 -eventlog -rtsopts diff --git a/cabal.project b/cabal.project index 52dd92d39..c6b74a36a 100644 --- a/cabal.project +++ b/cabal.project @@ -1,14 +1,12 @@ packages: - ./ + ./lsp ./lsp-types/ ./lsp-test/ - ./lsp-test/example - ./func-test/ - ./bench/ package lsp flags: +demo tests: True +benchmarks: True test-show-details: direct haddock-quickjump: True diff --git a/hie.yaml b/hie.yaml index c4d7df62d..6e22fcb1b 100644 --- a/hie.yaml +++ b/hie.yaml @@ -7,19 +7,21 @@ # https://github.com/digital-asset/ghcide/issues/113 cradle: cabal: - - path: "./lsp-test/test" - component: "lsp-test:test:tests" - path: "./lsp-test" component: "lsp-test" + - path: "./lsp-test/test" + component: "lsp-test:test:tests" + - path: "./lsp-test/func-test" + component: "lsp-test:test:func-test" + - path: "./lsp-test/bench" + component: "lsp-test:bench:simple-bench" - path: "./lsp-types" component: "lsp-types" - - path: "./src" + - path: "./lsp" component: "lsp" - - path: "./test" + - path: "./lsp/test" component: "unit-test" - - path: "./func-test" - component: "func-test" - - path: "./example/Reactor.hs" + - path: "./lsp/example/Reactor.hs" component: "lsp-demo-reactor-server" - - path: "./example/Simple.hs" + - path: "./lsp/example/Simple.hs" component: "lsp-demo-simple-server" diff --git a/lsp-test/.gitignore b/lsp-test/.gitignore deleted file mode 100644 index 2e1608d49..000000000 --- a/lsp-test/.gitignore +++ /dev/null @@ -1,22 +0,0 @@ -.stack-work -stack.yaml.lock -dist -.cabal-sandbox -cabal.sandbox.config -dist-newstyle -cabal.project.local* -.ghc.environment.* -**/.DS_Store -*.swp - -example/dist -example/dist-newstyle -example/cabal.project.local -example/.ghc.environment.* - -# used for rerunning failed hspec tests -.hspec-failures - -# downloaded by .download-hie.sh on travis -hie -.hie \ No newline at end of file diff --git a/lsp-test/README.md b/lsp-test/README.md deleted file mode 100644 index 7ba10d6a2..000000000 --- a/lsp-test/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# lsp-test [![Actions Status](https://github.com/bubba/lsp-test/workflows/Haskell%20CI/badge.svg)](https://github.com/bubba/lsp-test/actions) [![Hackage](https://img.shields.io/hackage/v/lsp-test.svg)](https://hackage.haskell.org/package/lsp-test) -lsp-test is a functional testing framework for Language Server Protocol servers. - -```haskell -import Language.LSP.Test -main = runSession "hie" fullCaps "proj/dir" $ do - doc <- openDoc "Foo.hs" "haskell" - skipMany anyNotification - symbols <- getDocumentSymbols doc -``` - -## Examples - -### Unit tests with HSpec -```haskell -describe "diagnostics" $ - it "report errors" $ runSession "hie" fullCaps "test/data" $ do - openDoc "Error.hs" "haskell" - [diag] <- waitForDiagnosticsSource "ghcmod" - liftIO $ do - diag ^. severity `shouldBe` Just DsError - diag ^. source `shouldBe` Just "ghcmod" -``` - -### Replaying captured session -```haskell -replaySession "hie" "test/data/renamePass" -``` - -### Parsing with combinators -```haskell -skipManyTill loggingNotification publishDiagnosticsNotification -count 4 (message :: Session ApplyWorkspaceEditRequest) -anyRequest <|> anyResponse -``` - -Try out the example tests in the `example` directory with `cabal test`. -For more examples check the [Wiki](https://github.com/bubba/lsp-test/wiki/Introduction), or see this [introductory blog post](https://lukelau.me/haskell/posts/lsp-test/). - -Whilst writing your tests you may want to debug them to see what's going wrong. -You can set the `logMessages` and `logStdErr` options in `SessionConfig` to see what the server is up to. -There are also corresponding environment variables so you can turn them on from the command line: -``` -LSP_TEST_LOG_MESSAGES=1 LSP_TEST_LOG_STDERR=1 cabal test -``` - -## Developing -The tests for lsp-test use a dummy server found in `test/dummy-server/`. -Run the tests with `cabal test` or `stack test`. -Tip: If you want to filter the tests, use `cabal run test:tests -- -m "foo"` - -## Troubleshooting -Seeing funny stuff when running lsp-test via stack? If your server is built upon Haskell tooling, [keep in mind that stack sets some environment variables related to GHC, and you may want to unset them.](https://github.com/alanz/haskell-ide-engine/blob/bfb16324d396da71000ef81d51acbebbdaa854ab/test/utils/TestUtils.hs#L290-L298) diff --git a/bench/SimpleBench.hs b/lsp-test/bench/SimpleBench.hs similarity index 100% rename from bench/SimpleBench.hs rename to lsp-test/bench/SimpleBench.hs diff --git a/lsp-test/example/Test.hs b/lsp-test/example/Test.hs index 273ee636a..7763edb70 100644 --- a/lsp-test/example/Test.hs +++ b/lsp-test/example/Test.hs @@ -4,7 +4,7 @@ import Control.Monad.IO.Class import Language.LSP.Test import Language.LSP.Types -main = runSession "lsp-demo-reactor-server" fullCaps "../test/data/" $ do +main = runSession "lsp-demo-reactor-server" fullCaps "test/data/" $ do doc <- openDoc "Rename.hs" "haskell" -- Use your favourite favourite combinators. diff --git a/lsp-test/example/cabal.project b/lsp-test/example/cabal.project deleted file mode 100644 index 2aea019c9..000000000 --- a/lsp-test/example/cabal.project +++ /dev/null @@ -1,2 +0,0 @@ -packages: . - ../ diff --git a/lsp-test/example/example.cabal b/lsp-test/example/example.cabal deleted file mode 100644 index a5b52602b..000000000 --- a/lsp-test/example/example.cabal +++ /dev/null @@ -1,12 +0,0 @@ -name: example -version: 0.0.0.0 -cabal-version: >= 1.22 -build-type: Simple - -test-suite tests - type: exitcode-stdio-1.0 - main-is: Test.hs - build-depends: base - , lsp-test - , parser-combinators - build-tool-depends: lsp:lsp-demo-reactor-server diff --git a/func-test/FuncTest.hs b/lsp-test/func-test/FuncTest.hs similarity index 100% rename from func-test/FuncTest.hs rename to lsp-test/func-test/FuncTest.hs diff --git a/func-test/func-test.cabal b/lsp-test/func-test/func-test.cabal similarity index 100% rename from func-test/func-test.cabal rename to lsp-test/func-test/func-test.cabal diff --git a/lsp-test/hie.yaml b/lsp-test/hie.yaml deleted file mode 100644 index bea636037..000000000 --- a/lsp-test/hie.yaml +++ /dev/null @@ -1,16 +0,0 @@ -cradle: - multi: - - path: "./test/data/" - config: { cradle: { none: } } - - path: "./example/" - config: { cradle: { none: } } - - path: "./" - config: - cradle: - cabal: - - path: "src" - component: "lib:lsp-test" - - path: "test/dummy-server" - component: "exe:dummy-server" - - path: "test" - component: "test:tests" diff --git a/lsp-test/lsp-test.cabal b/lsp-test/lsp-test.cabal index ca9eada4b..1fbcca70f 100644 --- a/lsp-test/lsp-test.cabal +++ b/lsp-test/lsp-test.cabal @@ -94,3 +94,39 @@ test-suite tests , mtl , aeson default-language: Haskell2010 + +test-suite func-test + main-is: FuncTest.hs + hs-source-dirs: func-test + type: exitcode-stdio-1.0 + build-depends: base <4.15 + , lsp-test + , lsp + , data-default + , process + , lens + , unliftio + , hspec + , async + default-language: Haskell2010 + +test-suite example + main-is: Test.hs + hs-source-dirs: example + type: exitcode-stdio-1.0 + build-depends: base + , lsp-test + , parser-combinators + build-tool-depends: lsp:lsp-demo-reactor-server + +benchmark simple-bench + main-is: SimpleBench.hs + hs-source-dirs: bench + type: exitcode-stdio-1.0 + build-depends: base <4.15 + , lsp-test + , lsp + , process + , extra + default-language: Haskell2010 + ghc-options: -Wall -O2 -eventlog -rtsopts diff --git a/lsp-types/.hlint.yaml b/lsp-types/.hlint.yaml deleted file mode 100644 index 1563177ed..000000000 --- a/lsp-types/.hlint.yaml +++ /dev/null @@ -1 +0,0 @@ -- ignore: {name: Use newtype instead of data} diff --git a/lsp-types/ChangeLog.md b/lsp-types/ChangeLog.md index 4672e0497..5e48ef438 100644 --- a/lsp-types/ChangeLog.md +++ b/lsp-types/ChangeLog.md @@ -1,4 +1,4 @@ -# Revision history for haskell-lsp-types +# Revision history for lsp-types ## 1.1.0.0 diff --git a/lsp-types/README.md b/lsp-types/README.md deleted file mode 100644 index 8f04133cd..000000000 --- a/lsp-types/README.md +++ /dev/null @@ -1,13 +0,0 @@ -[![Hackage](https://img.shields.io/hackage/v/lsp-types.svg)](https://hackage.haskell.org/package/lsp-types) - -# lsp-types -Haskell library for the data types for Microsoft Language Server Protocol - -## Useful links - -- https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md - -## Other resource - -See #haskell-ide-engine on IRC freenode - diff --git a/lsp-types/Setup.hs b/lsp-types/Setup.hs deleted file mode 100644 index 9a994af67..000000000 --- a/lsp-types/Setup.hs +++ /dev/null @@ -1,2 +0,0 @@ -import Distribution.Simple -main = defaultMain diff --git a/ChangeLog.md b/lsp/ChangeLog.md similarity index 100% rename from ChangeLog.md rename to lsp/ChangeLog.md diff --git a/LICENSE b/lsp/LICENSE similarity index 100% rename from LICENSE rename to lsp/LICENSE diff --git a/example/Reactor.hs b/lsp/example/Reactor.hs similarity index 100% rename from example/Reactor.hs rename to lsp/example/Reactor.hs diff --git a/example/Simple.hs b/lsp/example/Simple.hs similarity index 100% rename from example/Simple.hs rename to lsp/example/Simple.hs diff --git a/lsp.cabal b/lsp/lsp.cabal similarity index 100% rename from lsp.cabal rename to lsp/lsp.cabal diff --git a/src/Language/LSP/Diagnostics.hs b/lsp/src/Language/LSP/Diagnostics.hs similarity index 100% rename from src/Language/LSP/Diagnostics.hs rename to lsp/src/Language/LSP/Diagnostics.hs diff --git a/src/Language/LSP/Server.hs b/lsp/src/Language/LSP/Server.hs similarity index 100% rename from src/Language/LSP/Server.hs rename to lsp/src/Language/LSP/Server.hs diff --git a/src/Language/LSP/Server/Control.hs b/lsp/src/Language/LSP/Server/Control.hs similarity index 100% rename from src/Language/LSP/Server/Control.hs rename to lsp/src/Language/LSP/Server/Control.hs diff --git a/src/Language/LSP/Server/Core.hs b/lsp/src/Language/LSP/Server/Core.hs similarity index 100% rename from src/Language/LSP/Server/Core.hs rename to lsp/src/Language/LSP/Server/Core.hs diff --git a/src/Language/LSP/Server/Processing.hs b/lsp/src/Language/LSP/Server/Processing.hs similarity index 100% rename from src/Language/LSP/Server/Processing.hs rename to lsp/src/Language/LSP/Server/Processing.hs diff --git a/test/CapabilitiesSpec.hs b/lsp/test/CapabilitiesSpec.hs similarity index 100% rename from test/CapabilitiesSpec.hs rename to lsp/test/CapabilitiesSpec.hs diff --git a/test/DiagnosticsSpec.hs b/lsp/test/DiagnosticsSpec.hs similarity index 100% rename from test/DiagnosticsSpec.hs rename to lsp/test/DiagnosticsSpec.hs diff --git a/test/JsonSpec.hs b/lsp/test/JsonSpec.hs similarity index 100% rename from test/JsonSpec.hs rename to lsp/test/JsonSpec.hs diff --git a/test/Main.hs b/lsp/test/Main.hs similarity index 100% rename from test/Main.hs rename to lsp/test/Main.hs diff --git a/test/MethodSpec.hs b/lsp/test/MethodSpec.hs similarity index 100% rename from test/MethodSpec.hs rename to lsp/test/MethodSpec.hs diff --git a/test/ServerCapabilitiesSpec.hs b/lsp/test/ServerCapabilitiesSpec.hs similarity index 100% rename from test/ServerCapabilitiesSpec.hs rename to lsp/test/ServerCapabilitiesSpec.hs diff --git a/test/Spec.hs b/lsp/test/Spec.hs similarity index 100% rename from test/Spec.hs rename to lsp/test/Spec.hs diff --git a/test/TypesSpec.hs b/lsp/test/TypesSpec.hs similarity index 100% rename from test/TypesSpec.hs rename to lsp/test/TypesSpec.hs diff --git a/test/URIFilePathSpec.hs b/lsp/test/URIFilePathSpec.hs similarity index 100% rename from test/URIFilePathSpec.hs rename to lsp/test/URIFilePathSpec.hs diff --git a/test/VspSpec.hs b/lsp/test/VspSpec.hs similarity index 100% rename from test/VspSpec.hs rename to lsp/test/VspSpec.hs diff --git a/test/WorkspaceEditSpec.hs b/lsp/test/WorkspaceEditSpec.hs similarity index 100% rename from test/WorkspaceEditSpec.hs rename to lsp/test/WorkspaceEditSpec.hs diff --git a/stack-8.4.2.yaml b/stack-8.4.2.yaml index 7749bbfe0..0a30953af 100644 --- a/stack-8.4.2.yaml +++ b/stack-8.4.2.yaml @@ -1,9 +1,9 @@ resolver: nightly-2018-05-30 # last nightly for GHC 8.4.2 packages: -- '.' +- ./lsp - ./lsp-types -- ./func-test +- ./lsp-test extra-deps: - rope-utf16-splay-0.3.1.0 diff --git a/stack-8.4.3.yaml b/stack-8.4.3.yaml index e34d8d3f3..64e98ea02 100644 --- a/stack-8.4.3.yaml +++ b/stack-8.4.3.yaml @@ -1,9 +1,9 @@ resolver: lts-12.5 # GHC 8.4.3 packages: -- '.' +- ./lsp - ./lsp-types -- ./func-test +- ./lsp-test extra-deps: - rope-utf16-splay-0.3.1.0 diff --git a/stack-8.4.4.yaml b/stack-8.4.4.yaml index 2cd372ba1..61d0f47ec 100644 --- a/stack-8.4.4.yaml +++ b/stack-8.4.4.yaml @@ -1,9 +1,9 @@ resolver: lts-12.26 # GHC 8.4.4 packages: -- '.' +- ./lsp - ./lsp-types -- ./func-test +- ./lsp-test extra-deps: - rope-utf16-splay-0.3.1.0 diff --git a/stack-8.6.4.yaml b/stack-8.6.4.yaml index aba47c11d..934d7f8de 100644 --- a/stack-8.6.4.yaml +++ b/stack-8.6.4.yaml @@ -1,9 +1,9 @@ resolver: lts-13.16 # GHC 8.6.4 packages: -- '.' +- ./lsp - ./lsp-types -- ./func-test +- ./lsp-test extra-deps: - rope-utf16-splay-0.3.1.0 diff --git a/stack-8.6.5.yaml b/stack-8.6.5.yaml index 790f60d78..3593afd8d 100644 --- a/stack-8.6.5.yaml +++ b/stack-8.6.5.yaml @@ -1,9 +1,9 @@ resolver: lts-14.11 # GHC 8.6.5 packages: -- '.' +- ./lsp - ./lsp-types -- ./func-test +- ./lsp-test extra-deps: - some-1.0.1@sha256:26e5bab7276f48b25ea8660d3fd1166c0f20fd497dac879a40f408e23211f93e,2055 diff --git a/stack-8.8.1.yaml b/stack-8.8.1.yaml index bf30f5c40..9eb0c1c80 100644 --- a/stack-8.8.1.yaml +++ b/stack-8.8.1.yaml @@ -1,9 +1,9 @@ resolver: nightly-2020-01-21 # last GHC 8.8.1 packages: -- '.' +- ./lsp - ./lsp-types -- ./func-test +- ./lsp-test extra-deps: - dependent-map-0.4.0.0@sha256:ca2b131046f4340a1c35d138c5a003fe4a5be96b14efc26291ed35fd08c62221,1657 diff --git a/stack-8.8.2.yaml b/stack-8.8.2.yaml index 0e794a03f..14eeb736a 100644 --- a/stack-8.8.2.yaml +++ b/stack-8.8.2.yaml @@ -1,9 +1,9 @@ resolver: nightly-2020-01-31 packages: -- '.' +- ./lsp - ./lsp-types -- ./func-test +- ./lsp-test extra-deps: - dependent-map-0.4.0.0@sha256:ca2b131046f4340a1c35d138c5a003fe4a5be96b14efc26291ed35fd08c62221,1657