Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/mrcjkb/neotest-haskell
Neotest adapter for Haskell (cabal or stack) with support for Sydtest, Hspec and Tasty
https://github.com/mrcjkb/neotest-haskell
haskell hspec neovim neovim-plugin sydtest tasty testing treesitter
Last synced: 7 days ago
JSON representation
Neotest adapter for Haskell (cabal or stack) with support for Sydtest, Hspec and Tasty
- Host: GitHub
- URL: https://github.com/mrcjkb/neotest-haskell
- Owner: mrcjkb
- License: gpl-2.0
- Created: 2022-08-08T16:50:32.000Z (over 2 years ago)
- Default Branch: master
- Last Pushed: 2025-01-06T11:08:12.000Z (17 days ago)
- Last Synced: 2025-01-09T04:13:54.239Z (14 days ago)
- Topics: haskell, hspec, neovim, neovim-plugin, sydtest, tasty, testing, treesitter
- Language: Lua
- Homepage:
- Size: 491 KB
- Stars: 56
- Watchers: 2
- Forks: 5
- Open Issues: 13
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
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][![All Contributors](https://img.shields.io/badge/all_contributors-9-purple.svg?style=for-the-badge)](#contributors-)
## Quick links
- [Features](#features)
- [Installation](#installation)
- [Configuration](#configuration)
- [Examples](#examples)
- [TODO](#todo)
- [Troubleshooting](#troubleshooting)
- [Recommendations](#recommendations)## Features
- [x] Supports [Cabal](https://www.haskell.org/cabal/) (single/multi-package) projects.
- [x] Supports [Stack](https://docs.haskellstack.org/en/stable/)
(single/multi-package) projects.
- [x] Parses [Hspec](https://hackage.haskell.org/package/hspec)
and [Sydtest](https://hackage.haskell.org/package/sydtest)
`--match` filters for the cursor's position using tree-sitter.
- [x] Parses [Tasty](https://hackage.haskell.org/package/tasty)
`--pattern` filters for the cursor's position using tree-sitter.
- [x] Parses test results and displays error messages as diagnostics.https://user-images.githubusercontent.com/12857160/224197351-8ca64bd5-8d89-4689-8c40-18d1d018896e.mp4
## Installation
### rocks.nvim
```vim
: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](https://github.com/nvim-neotest/neotest#installation).
- Requires the tree-sitter parser for haskell to be installed.
The following example uses [`lazy.nvim`](https://github.com/folke/lazy.nvim):
```lua
{
'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`](https://github.com/nvim-treesitter/nvim-treesitter)
like so:```lua
require('nvim-treesitter.configs').setup {
ensure_installed = {
'haskell',
--...,
},
}
```Add `neotest-haskell` to your `neotest` adapters:
```lua
require('neotest').setup {
-- ...,
adapters = {
-- ...,
require('neotest-haskell')
},
}
```You can also pass a config to the setup. The following are the defaults:
```lua
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:```lua
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
`/queries/haskell/-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/`](./queries/haskell/).## Examples
```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...```haskell
describe "Empty list" $
```...will run the tests with the following Cabal command:
```console
# 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:
```console
# 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...```haskell
spec = describe "Prelude.head" $ do
```...will run the tests with the following Cabal command:
```console
# Assuming a Cabal package called "my_package"
cabal test my_package --test-option -m --test-option "/Prelude.head/"
```...or with the following Stack command:
```console
# 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](https://github.com/mrcjkb/neotest-haskell/issues).
## Troubleshooting
To run a health check, run `:checkhealth neotest-haskell` in Neovim.
## Limitations
- 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`, ..).## Recommendations
Here are some other plugins I recommend for Haskell development:
- [mrcjkb/haskell-tools.nvim](https://github.com/mrcjkb/haskell-tools.nvim):
Toolset to improve the Haskell experience in Neovim.
- [haskell-snippets.nvim](https://github.com/mrcjkb/haskell-snippets.nvim)
Collection of Haskell snippets for [LuaSnip](https://github.com/L3MON4D3/LuaSnip).
- [luc-tielen/telescope_hoogle](https://github.com/luc-tielen/telescope_hoogle):
Hoogle search.## Contributors β¨
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/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](https://github.com/all-contributors/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