- Supports Cabal (single/multi-package) projects.
- Supports Stack (single/multi-package) projects.
- Parses Hspec
and Sydtest
--match
filters for the cursor's position using tree-sitter. - Parses Tasty
--pattern
filters for the cursor's position using tree-sitter. - Parses test results and displays error messages as diagnostics.
neotest.mp4
:Rocks install neotest-haskell
rocks.nvim will install all dependencies if not already installed (including tree-sitter-haskell).
See also: neotest installation instructions.
- Requires the tree-sitter parser for haskell to be installed.
The following example uses lazy.nvim
:
{
'nvim-neotest/neotest',
dependencies = {
-- ...,
'mrcjkb/neotest-haskell',
'nvim-lua/plenary.nvim',
}
}
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' }
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
$XDG_CONFIG_HOME/nvim/after/queries/haskell/tasty-positions.scm
.
Note
:h runtimepath
- See examples in
queries/haskell/
.
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.
See issues.
To run a health check, run :checkhealth neotest-haskell
in Neovim.
- To run
sydtest
tests of type'file'
,sydtest >= 0.13.0.4
is required, if the file has more than one top-level namespace (describe
,context
, ..).
Here are some other plugins I recommend for Haskell development:
- mrcjkb/haskell-tools.nvim: Toolset to improve the Haskell experience in Neovim.
- haskell-snippets.nvim Collection of Haskell snippets for LuaSnip.
- luc-tielen/telescope_hoogle: Hoogle search.
Thanks goes to these wonderful people (emoji key):
Perigord 💻 |
Sebastian Witte 💻 🚇 📖 |
Andy Bell 💻 |
Tom Sydney Kerckhove 🧑🏫 |
Nadeem Bitar 🐛 |
Mango The Fourth 🐛 |
Hécate Moonlight 🐛 |
Amaan Qureshi 💻 |
Brad Sherman 💻 |
This project follows the all-contributors specification. Contributions of any kind welcome!