Neotest adapter for Haskell (cabal or stack) with support for Sydtest, Hspec and Tasty
A neotest adapter for Haskell.
π¦₯
[![Neovim][neovim-shield]][neovim-url] [![Lua][lua-shield]][lua-url] [![Haskell][haskell-shield]][haskell-url] [![Nix][nix-shield]][nix-url]
[![GPL2 License][license-shield]][license-url] [![Issues][issues-shield]][issues-url] [![Build Status][ci-shield]][ci-url] [![LuaRocks][luarocks-shield]][luarocks-url]
Quick links
Features
(single/multi-package) projects.- [x] Parses Hspec
--match filters for the cursor's position using tree-sitter.
- [x] Parses Tasty
--pattern filters for the cursor's position using tree-sitter.
- [x] Parses test results and displays error messages as diagnostics.
Requirements
neovim >= 0.12- neotest
Installation
rocks.nvim
:Rocks install neotest-haskell
rocks.nvim will install all dependencies if not already installed (including tree-sitter-haskell).
Other plugin managers
See also: neotest installation instructions.
- Requires the tree-sitter parser for haskell to be installed.
lazy.nvim:
{
'nvim-neotest/neotest',
dependencies = {
-- ...,
'mrcjkb/neotest-haskell',
'nvim-lua/plenary.nvim',
}
}
Configuration
Make sure the Haskell parser for tree-sitter is installed, you can do so via nvim-treesitter like so:
require('nvim-treesitter.configs').setup {
ensure_installed = {
'haskell',
--...,
},
}
Add neotest-haskell to your neotest adapters:
require('neotest').setup {
-- ...,
adapters = {
-- ...,
require('neotest-haskell')
},
}
You can also pass a config to the setup. The following are the defaults:
require('neotest').setup {
adapters = {
require('neotest-haskell') {
-- Default: Use stack if possible and then try cabal
build_tools = { 'stack', 'cabal' },
-- Default: Check for tasty first and then try hspec
frameworks = { 'tasty', 'hspec', 'sydtest' },
},
},
}
[!NOTE]>
If you were to use build_tools = { 'cabal', 'stack' }, then cabal will almost
always be chosen, because almost all stack projects can be built with cabal.
Alternately, you can pair each test framework with a list of modules, used to identify the respective framework in a test file:
require('neotest').setup {
adapters = {
require('neotest-haskell') {
frameworks = {
{ framework = 'tasty', modules = { 'Test.Tasty', 'MyTestModule' }, },
'hspec',
'sydtest',
},
},
},
}
This can be useful if you have test files that do not import one of the default modules used for framework identification:
tasty:modules = { 'Test.Tasty' }hspec:modules = { 'Test.Hspec' }sydtest:modules = { 'Test.Syd' }
Advanced configuration
This plugin uses tree-sitter queries in files that match <runtimepath>/queries/haskell/<framework>-positions.scm
For example, to add position queries for this plugin for tasty, without having to fork this plugin, you can add them to $XDGCONFIGHOME/nvim/after/queries/haskell/tasty-positions.scm.
[!NOTE]>
- :h runtimepath
- See examples in queries/haskell/.
Examples
module FixtureSpec ( spec ) where
import Test.Hspec
import Test.Hspec.QuickCheck
import Control.Exception ( evaluate )
spec :: Spec spec = describe "Prelude.head" $ do it "returns the first element of a list" $ head [23 ..] shouldBe (23 :: Int)
prop "returns the first element of an arbitrary list" $ \x xs -> head (x : xs) shouldBe (x :: Int)
describe "Empty list" $ it "throws an exception if used with an empty list" $ evaluate (head []) shouldThrow anyException
In the above listing, calling :lua require('neotest').run.run() with the cursor on the line...
describe "Empty list" $
...will run the tests with the following Cabal command:
# Assuming a Cabal package called "my_package"
cabal test my_package --test-option -m --test-option "/Prelude.head/Empty list/"
...or with the following Stack command:
# Assuming a Stack package called "my_package"
stack test my_package --ta "--match \"/Prelude.head/Empty list/\""
...which will run the "throws an exception if used with an empty list" test.
Calling :lua require('neotest').run.run() with the cursor on the line...
spec = describe "Prelude.head" $ do
...will run the tests with the following Cabal command:
# Assuming a Cabal package called "my_package"
cabal test my_package --test-option -m --test-option "/Prelude.head/"
...or with the following Stack command:
# Assuming a Stack package called "my_package"
stack test my_package --ta "--match \"/Prelude.head/\""
...which will run all tests in the module.
TODO
See issues.
Troubleshooting
To run a health check, run :checkhealth neotest-haskell in Neovim.
Limitations
- To run
sydtesttests of type'file',sydtest >= 0.13.0.4is required,
describe, context, ..).
Recommendations
Here are some other plugins I recommend for Haskell development:
Toolset to improve the Haskell experience in Neovim. Collection of Haskell snippets for LuaSnip. Hoogle search.Contributors β¨
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!
[neovim-shield]: https://img.shields.io/badge/NeoVim-%2357A143.svg?&style=for-the-badge&logo=neovim&logoColor=white [neovim-url]: https://neovim.io/ [lua-shield]: https://img.shields.io/badge/lua-%232C2D72.svg?style=for-the-badge&logo=lua&logoColor=white [lua-url]: https://www.lua.org/ [nix-shield]: https://img.shields.io/badge/nix-0175C2?style=for-the-badge&logo=NixOS&logoColor=white [nix-url]: https://nixos.org/ [haskell-shield]: https://img.shields.io/badge/Haskell-5e5086?style=for-the-badge&logo=haskell&logoColor=white [haskell-url]: https://www.haskell.org/ [issues-shield]: https://img.shields.io/github/issues/mrcjkb/neotest-haskell.svg?style=for-the-badge [issues-url]: https://github.com/mrcjkb/neotest-haskell/issues [license-shield]: https://img.shields.io/github/license/mrcjkb/neotest-haskell.svg?style=for-the-badge [license-url]: https://github.com/mrcjkb/neotest-haskell/blob/master/LICENSE [ci-shield]: https://img.shields.io/github/actions/workflow/status/mrcjkb/neotest-haskell/nix-build.yml?style=for-the-badge [ci-url]: https://github.com/mrcjkb/neotest-haskell/actions/workflows/nix-build.yml [luarocks-shield]: https://img.shields.io/luarocks/v/MrcJkb/neotest-haskell?logo=lua&color=purple&style=for-the-badge [luarocks-url]: https://luarocks.org/modules/MrcJkb/neotest-haskell