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: 2 months ago
JSON representation

Neotest adapter for Haskell (cabal or stack) with support for Sydtest, Hspec and Tasty

Lists

README

        





neotest-haskell


Report Bug




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-8-orange.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

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
Perigord

πŸ’»
Sebastian Witte
Sebastian Witte

πŸ’» πŸš‡ πŸ“–
Andy Bell
Andy Bell

πŸ’»
Tom Sydney Kerckhove
Tom Sydney Kerckhove

πŸ§‘β€πŸ«
Nadeem Bitar
Nadeem Bitar

πŸ›
Mango The Fourth
Mango The Fourth

πŸ›
HΓ©cate Moonlight
HΓ©cate Moonlight

πŸ›


Amaan Qureshi
Amaan Qureshi

πŸ’»

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