├── .bumpversion.cfg
├── .github
└── workflows
│ └── tests.yml
├── .gitignore
├── .vimrc.lua
├── LICENSE
├── Makefile
├── README.md
├── doc
└── nvim-test.txt
├── lua
└── nvim-test
│ ├── config.lua
│ ├── info.lua
│ ├── init.lua
│ ├── notify.lua
│ ├── runner.lua
│ ├── runners
│ ├── busted.lua
│ ├── cargo-test.lua
│ ├── cypress.lua
│ ├── dotnet.lua
│ ├── go-test.lua
│ ├── hspec.lua
│ ├── init.lua
│ ├── jest.lua
│ ├── mocha.lua
│ ├── pytest.lua
│ ├── pyunit.lua
│ ├── rspec.lua
│ ├── stack.lua
│ ├── ts-mocha.lua
│ ├── vusted.lua
│ └── zig.lua
│ ├── terms
│ ├── callbacks.lua
│ ├── terminal.lua
│ └── toggleterm.lua
│ └── utils.lua
├── packspec.json
└── spec
├── conftest.lua
├── fixtures
├── Spec.hs
├── Tests.cs
├── go
│ ├── go.mod
│ └── mypackage_test.go
├── js
│ ├── name.js
│ └── name.test.js
├── rust
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── crate
│ │ ├── Cargo.lock
│ │ ├── Cargo.toml
│ │ └── src
│ │ │ ├── lib.rs
│ │ │ ├── nested
│ │ │ └── mod.rs
│ │ │ ├── nomod.rs
│ │ │ └── somemod.rs
│ ├── crate2
│ │ ├── Cargo.toml
│ │ └── src
│ │ │ └── main.rs
│ └── some
│ │ └── main.rs
├── test.lua
├── test.py
├── test.ts
├── test_spec.rb
└── zig
│ ├── .gitignore
│ ├── build.zig
│ └── src
│ ├── main.zig
│ ├── nested
│ └── mod.zig
│ └── somemod.zig
├── helpers.lua
├── init_spec.lua
├── runner_spec.lua
├── runners
├── busted_spec.lua
├── cargo-test_spec.lua
├── dotnet_spec.lua
├── go-test_spec.lua
├── hspec_spec.lua
├── init_spec.lua
├── jest_spec.lua
├── mocha_spec.lua
├── pytest_spec.lua
├── pyunit_spec.lua
├── rspec_spec.lua
├── stack_spec.lua
├── ts-mocha_spec.lua
├── vusted_spec.lua
└── zig_spec.lua
└── utils_spec.lua
/.bumpversion.cfg:
--------------------------------------------------------------------------------
1 | [bumpversion]
2 | commit = True
3 | current_version = 1.4.1
4 | tag = True
5 | tag_name = {new_version}
6 | message = build(version): {current_version} -> {new_version}
7 |
8 | [bumpversion:file:packspec.json]
9 |
10 | [bumpversion:file:README.md]
11 |
--------------------------------------------------------------------------------
/.github/workflows/tests.yml:
--------------------------------------------------------------------------------
1 | name: tests
2 | on:
3 | push:
4 | branches: [main]
5 | pull_request:
6 | branches: [main]
7 |
8 | jobs:
9 | test:
10 | name: Test
11 | runs-on: ${{ matrix.os }}
12 | strategy:
13 | matrix:
14 | os:
15 | - ubuntu-latest
16 | - macos-latest
17 | # - windows-latest
18 | version:
19 | - 'v0.8.2'
20 | - 'v0.9.0'
21 | - 'nightly'
22 |
23 | steps:
24 | - uses: actions/checkout@v2
25 |
26 | # Setup nvim
27 | - uses: notomo/action-setup-nvim-lua@v1
28 | with:
29 | luarocks-version: '3.5.0'
30 |
31 | # Install vusted
32 | - run: luarocks install vusted
33 |
34 | - uses: rhysd/action-setup-vim@v1
35 | id: vim
36 | with:
37 | neovim: true
38 | version: ${{matrix.version}}
39 |
40 | - run: make test
41 | env:
42 | VUSTED_NVIM: ${{ steps.vim.outputs.executable }}
43 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /doc/tags
2 | /_
3 | /nvim-treesitter
4 | /todo.txt
5 | /spec/fixtures/**/target/
6 |
--------------------------------------------------------------------------------
/.vimrc.lua:
--------------------------------------------------------------------------------
1 | require("nvim-test").setup {
2 | runners = {
3 | lua = "nvim-test.runners.vusted",
4 | },
5 | }
6 |
7 | require("nvim-test.runners.vusted"):setup {
8 | args = { "--helper=spec/conftest.lua" },
9 | env = {
10 | VIRTUAL_ENV = "",
11 | VUSTED_ARGS = "--headless --clean",
12 | },
13 |
14 | find_files = function(filename)
15 | local path, _ = vim.fn.fnamemodify(filename, ":p:h"):gsub("lua/nvim%-test", "spec")
16 | return string.format("%s/%s_spec.lua", path, vim.fn.fnamemodify(filename, ":t:r"))
17 | end,
18 | }
19 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 klen
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | nvim-treesitter:
2 | git clone https://github.com/nvim-treesitter/nvim-treesitter.git --depth=1
3 |
4 | LUA_PATH := $(LUA_PATH):$(CURDIR)
5 | test t: nvim-treesitter
6 | @echo $(CURDIR)
7 | vusted \
8 | --shuffle --lpath="./?.lua;./?/?.lua;./?/init.lua" \
9 | --helper=$(CURDIR)/spec/conftest.lua
10 | .PHONY: test t
11 |
12 | RELEASE ?= patch
13 | release patch:
14 | bumpversion $(RELEASE)
15 | git push
16 | git push --tags
17 |
18 | minor:
19 | make release RELEASE=minor
20 |
21 | major:
22 | make release RELEASE=major
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # nvim-test 1.4.1
4 |
5 | Test Runner for neovim
6 |
7 | [](https://github.com/klen/nvim-test/actions/workflows/tests.yml)
8 | [](https://github.com/rockerBOO/awesome-neovim)
9 |
10 |
11 | ## Features
12 |
13 | | Language | Test Runners |
14 | | -------------: | :------------------------------- |
15 | | **C Sharp** | `dotnet test` |
16 | | **Go** | `go-test` |
17 | | **Haskell** | `hspec`, `stack` |
18 | | **Javascript** | `jest`, `mocha` |
19 | | **Lua** | `busted`, `vusted` |
20 | | **Python** | `pytest`, `pyunit` |
21 | | **Ruby** | `rspec` |
22 | | **Rust** | `cargo-test` |
23 | | **Typescript** | `jest`, `mocha`, `ts-mocha` |
24 |
25 | ## Install
26 |
27 | with [packer](https://github.com/wbthomason/packer.nvim):
28 |
29 | ```lua
30 |
31 | use {
32 | "klen/nvim-test",
33 | config = function()
34 | require('nvim-test').setup()
35 | end
36 | }
37 | ```
38 |
39 | ## Commands
40 |
41 | The plugin defines the commands:
42 |
43 | - `TestSuite` - run the whole test suite
44 | - `TestFile` - run all tests for the current file
45 | - `TestEdit` - edit tests for the current file
46 | - `TestNearest` - run the test nearest to the cursor
47 | - `TestLast` - rerun the latest test
48 | - `TestVisit` - open the last run test in the current buffer
49 | - `TestInfo` - show an information about the plugin
50 |
51 | ## Setup
52 |
53 | This plugin must be explicitly enabled by using `require("nvim-test").setup{}`
54 |
55 | Default options:
56 |
57 | ```lua
58 | require('nvim-test').setup {
59 | run = true, -- run tests (using for debug)
60 | commands_create = true, -- create commands (TestFile, TestLast, ...)
61 | filename_modifier = ":.", -- modify filenames before tests run(:h filename-modifiers)
62 | silent = false, -- less notifications
63 | term = "terminal", -- a terminal to run ("terminal"|"toggleterm")
64 | termOpts = {
65 | direction = "vertical", -- terminal's direction ("horizontal"|"vertical"|"float")
66 | width = 96, -- terminal's width (for vertical|float)
67 | height = 24, -- terminal's height (for horizontal|float)
68 | go_back = false, -- return focus to original window after executing
69 | stopinsert = "auto", -- exit from insert mode (true|false|"auto")
70 | keep_one = true, -- keep only one terminal for testing
71 | },
72 | runners = { -- setup tests runners
73 | cs = "nvim-test.runners.dotnet",
74 | go = "nvim-test.runners.go-test",
75 | haskell = "nvim-test.runners.hspec",
76 | javascriptreact = "nvim-test.runners.jest",
77 | javascript = "nvim-test.runners.jest",
78 | lua = "nvim-test.runners.busted",
79 | python = "nvim-test.runners.pytest",
80 | ruby = "nvim-test.runners.rspec",
81 | rust = "nvim-test.runners.cargo-test",
82 | typescript = "nvim-test.runners.jest",
83 | typescriptreact = "nvim-test.runners.jest",
84 | }
85 | }
86 | ```
87 |
88 | Setup a runner:
89 | ```lua
90 | require('nvim-test.runners.jest'):setup {
91 | command = "~/node_modules/.bin/jest", -- a command to run the test runner
92 | args = { "--collectCoverage=false" }, -- default arguments
93 | env = { CUSTOM_VAR = 'value' }, -- custom environment variables
94 |
95 | file_pattern = "\\v(__tests__/.*|(spec|test))\\.(js|jsx|coffee|ts|tsx)$", -- determine whether a file is a testfile
96 | find_files = { "{name}.test.{ext}", "{name}.spec.{ext}" }, -- find testfile for a file
97 |
98 | filename_modifier = nil, -- modify filename before tests run (:h filename-modifiers)
99 | working_directory = nil, -- set working directory (cwd by default)
100 | }
101 | ```
102 |
--------------------------------------------------------------------------------
/doc/nvim-test.txt:
--------------------------------------------------------------------------------
1 | *nvim-test.txt* nvim-test
2 |
3 | ==============================================================================
4 | INTRODUCTION *nvim-test-introduction*
5 |
6 | Test Runner for neovim
7 |
8 | ------------------------------------------------------------------------------
9 | COMMANDS *nvim-test-command*
10 |
11 | :TestSuite *:TestSuite*
12 | Run the whole test suite
13 |
14 | :TestFile *:TestFile*
15 | Run all tests in the current file
16 |
17 | :TestEdit *:TestEdit*
18 | Edit tests for the current file
19 |
20 | :TestNearest *:TestNearest*
21 | Run the test nearest to the cursor
22 |
23 | :TestLast *:TestLast*
24 | Rerun the latest test
25 |
26 | :TestVisit *:TestVisit*
27 | Open the last run test in the current buffer
28 |
29 | :TestInfo *:TestInfo*
30 | Show an information about plugin
31 |
32 | ------------------------------------------------------------------------------
33 | SETUP *nvim-test-setup*
34 |
35 | Setup the plugin (default values): >
36 |
37 | require('nvim-test').setup {
38 | run = true, -- run tests (using for debug)
39 | commands_create = true, -- create commands (TestFile, TestLast, ...)
40 | filename_modifier = ":.", -- modify filenames before tests run(:h filename-modifiers)
41 | silent = false, -- less notifications
42 | term = "terminal", -- a terminal to run ("terminal"|"toggleterm")
43 | termOpts = {
44 | direction = "vertical", -- terminal's direction ("horizontal"|"vertical"|"float")
45 | width = 96, -- terminal's width (for vertical|float)
46 | height = 24, -- terminal's height (for horizontal|float)
47 | go_back = false, -- return focus to original window after executing
48 | stopinsert = "auto", -- exit from insert mode (true|false|"auto")
49 | keep_one = true, -- keep only one terminal for testing
50 | },
51 | runners = { -- setup tests runners
52 | go = "nvim-test.runners.go-test",
53 | javascript = "nvim-test.runners.jest",
54 | lua = "nvim-test.runners.busted",
55 | python = "nvim-test.runners.pytest",
56 | rust = "nvim-test.runners.cargo-test",
57 | typescript = "nvim-test.runners.jest",
58 | }
59 | }
60 |
61 | Setup a runner: >
62 |
63 | require('nvim-test.runners.jest'):setup {
64 | command = "~/node_modules/.bin/jest", -- a command to run the test runner
65 | args = { "--collectCoverage=false" }, -- default arguments
66 | env = { CUSTOM_VAR = 'value' }, -- custom environment variables
67 |
68 | file_pattern = "\\v(__tests__/.*|(spec|test))\\.(js|jsx|coffee|ts|tsx)$", -- determine whether a file is a testfile
69 | find_files = { "{name}.test.{ext}", "{name}.spec.{ext}" }, -- find testfile for a file
70 |
71 | filename_modifier = nil, -- modify filename before tests run (:h filename-modifiers)
72 | working_directory = nil, -- set working directory (cwd by default)
73 | }
74 |
75 | ------------------------------------------------------------------------------
76 | RUNNERS *nvim-test-runners*
77 |
78 | *nvim-test-busted*
79 |
80 | Default options: >
81 |
82 | require('nvim-test.runners.busted'):setup {
83 | command = "busted",
84 | file_pattern = "\\v_spec\\.(lua|moon)$",
85 | find_files = "{name}_spec.{ext}",
86 | }
87 | <
88 | *nvim-test-cargo-test*
89 |
90 | Cargotest runner may find the nearest crate root.
91 |
92 | Default options: >
93 |
94 | require('nvim-test.runners.cargo-test'):setup {
95 | command = "cargo",
96 | args = { "test" },
97 |
98 | package = false, -- Set to true, to find the nearest create root
99 | }
100 | <
101 | *nvim-test-cypress*
102 |
103 | Default options: >
104 |
105 | require('nvim-test.runners.cypress'):setup {
106 | command = "go",
107 | args = { "test", "-v" }
108 | }
109 | <
110 | *nvim-test-go-test*
111 |
112 | Default options: >
113 |
114 | require('nvim-test.runners.go-test'):setup {
115 | command = {"./node_modules/.bin/cypress", "cypress"},
116 | args = { "run" },
117 | file_pattern = "\\v(__tests__/.*|(spec|test))\\.(js|jsx|coffee|ts|tsx)$",
118 | find_files = { "{name}.test.{ext}", "{name}.spec.{ext}" },
119 | }
120 | <
121 | *nvim-test-jest*
122 |
123 | Default options: >
124 |
125 | require('nvim-test.runners.jest'):setup {
126 | command = { "./node_modules/.bin/jest", "jest" },
127 | file_pattern = "\\v(__tests__/.*|(spec|test))\\.(js|jsx|coffee|ts|tsx)$",
128 | find_files = { "{name}.test.{ext}", "{name}.spec.{ext}" },
129 | }
130 | <
131 | *nvim-test-mocha*
132 |
133 | Default options: >
134 |
135 | require('nvim-test.runners.mocha'):setup {
136 | command = { "./node_modules/.bin/mocha", "mocha" },
137 | file_pattern = "\\v(tests?/.*|test)\\.(js|jsx|coffee)$",
138 | find_files = { "{name}.test.{ext}" },
139 | }
140 | <
141 | *nvim-test-pytest*
142 |
143 | Default options: >
144 |
145 | require('nvim-test.runners.pytest'):setup {
146 | command = { (vim.env.VIRTUAL_ENV or "venv") .. "/bin/pytest", "pytest" },
147 | file_pattern = "\\v(test_[^.]+|[^.]+_test|tests)\\.py$",
148 | find_files = { "test_{name}.py", "{name}_test.py", "tests.py" },
149 | }
150 | <
151 | *nvim-test-pyunit*
152 |
153 | Default options: >
154 |
155 | require('nvim-test.runners.pytest'):setup {
156 | command = { (vim.env.VIRTUAL_ENV or "venv") .. "/bin/python", "python" },
157 | args = { "-m", "unittest" },
158 | file_pattern = "\\v^test.*\\.py$",
159 | find_files = { "test_{name}.py" },
160 | }
161 | <
162 | *nvim-test-ts-mocha*
163 |
164 | Default options: >
165 |
166 | require('nvim-test.runners.ts-mocha'):setup {
167 | command = { "./node_modules/.bin/ts-mocha", "ts-mocha" },
168 | file_pattern = "\\v(tests?/.*|test)\\.(ts|tsx)$",
169 | find_files = { "{name}.test.{ext}" },
170 | }
171 | <
172 | *nvim-test-ts-vusted*
173 |
174 | Default options: >
175 |
176 | require('nvim-test.runners.vusted'):setup {
177 | command = "vusted",
178 | file_pattern = "\\v_spec\\.(lua|moon)$",
179 | find_files = "{name}_spec.{ext}",
180 | }
181 | <
182 |
183 | ------------------------------------------------------------------------------
184 | ABOUT *nvim-test-about*
185 |
186 | Author: Kirill Klenove
187 | License: Same terms as Vim itself (see |license|)
188 |
189 | Grab the latest version or report a bug on GitHub:
190 |
191 | https://github.com/klen/nvim-test
192 |
193 | vim:tw=78:et:ft=help:norl:
194 |
195 |
--------------------------------------------------------------------------------
/lua/nvim-test/config.lua:
--------------------------------------------------------------------------------
1 | -- Default configuration
2 | --
3 | -- stylua: ignore
4 | return {
5 | run = true, -- run tests (using for debug)
6 | commands_create = true, -- create commands (TestFile, TestLast, ...)
7 | filename_modifier = ":.", -- modify filenames before tests run(:h filename-modifiers)
8 | silent = false, -- less notifications
9 | term = "terminal", -- a terminal to run ("terminal"|"toggleterm")
10 | termOpts = {
11 | direction = "vertical", -- terminal's direction ("horizontal"|"vertical"|"float")
12 | width = 96, -- terminal's width (for vertical|float)
13 | height = 24, -- terminal's height (for horizontal|float)
14 | go_back = false, -- return focus to original window after executing
15 | stopinsert = "auto", -- exit from insert mode (true|false|"auto")
16 | keep_one = true, -- keep only one terminal for testing
17 | },
18 | }
19 |
--------------------------------------------------------------------------------
/lua/nvim-test/info.lua:
--------------------------------------------------------------------------------
1 | local function open_window()
2 | local width = math.floor(vim.o.columns * 0.7)
3 | local height = math.floor(vim.o.lines * 0.7)
4 | local bufnr = vim.api.nvim_create_buf(false, true)
5 | local win = vim.api.nvim_open_win(bufnr, true, {
6 | width = width,
7 | height = height,
8 | row = math.floor(((vim.o.lines - height) / 2) - 1),
9 | col = math.floor((vim.o.columns - width) / 2),
10 | relative = "editor",
11 | style = "minimal",
12 | border = {
13 | { " ", "NormalFloat" },
14 | { " ", "NormalFloat" },
15 | { " ", "NormalFloat" },
16 | { " ", "NormalFloat" },
17 | { " ", "NormalFloat" },
18 | { " ", "NormalFloat" },
19 | { " ", "NormalFloat" },
20 | { " ", "NormalFloat" },
21 | },
22 | })
23 | vim.api.nvim_win_set_buf(win, bufnr)
24 | vim.cmd "setlocal nocursorcolumn ts=2 sw=2"
25 | vim.api.nvim_buf_set_keymap(bufnr, "n", "", "bd", { noremap = true })
26 | vim.api.nvim_buf_set_keymap(bufnr, "n", "", "bd", { noremap = true })
27 | vim.api.nvim_command(
28 | string.format(
29 | "autocmd BufHidden,BufLeave ++once lua pcall(vim.api.nvim_win_close, %d, true)",
30 | win
31 | )
32 | )
33 | return { win = win, bufnr = bufnr }
34 | end
35 |
36 | local function print_table(t, indent)
37 | local result = {}
38 | if t then
39 | indent = indent == nil and "" or indent
40 | for key, value in pairs(t) do
41 | if type(value) == "table" then
42 | table.insert(result, indent .. key .. ": ")
43 | vim.list_extend(result, print_table(value, indent .. "\t"))
44 | else
45 | table.insert(result, indent .. key .. ": " .. vim.inspect(value))
46 | end
47 | end
48 | end
49 | return result
50 | end
51 |
52 | return function()
53 | local plugin = require "nvim-test"
54 | local filetype = vim.bo.filetype
55 | local window = open_window()
56 |
57 | local lines = {}
58 |
59 | if filetype then
60 | vim.list_extend(lines, { "Detected filetype: *" .. filetype .. "*" })
61 | local runner_module = plugin.runners[filetype]
62 | if runner_module then
63 | table.insert(lines, "Found test runner: *" .. runner_module .. "*")
64 | local _, runner = pcall(require, runner_module)
65 | if runner then
66 | vim.list_extend(lines, { "", "Runner Config:~", ">" })
67 | vim.list_extend(lines, print_table(runner.config, "\t"))
68 | table.insert(lines, "<")
69 | end
70 | else
71 | table.insert(lines, "Test runner not found")
72 | end
73 | end
74 |
75 | if vim.g.test_latest then
76 | vim.list_extend(lines, { "", "Latest test params:~", ">" })
77 | vim.list_extend(lines, print_table(vim.g.test_latest, "\t"))
78 | table.insert(lines, "<")
79 | end
80 |
81 | vim.list_extend(lines, { "", "Plugin Config:~", ">" })
82 | vim.list_extend(lines, print_table(plugin.config, "\t"))
83 | table.insert(lines, "<")
84 |
85 | vim.api.nvim_buf_set_lines(window.bufnr, 0, -1, true, lines)
86 | vim.api.nvim_buf_set_option(window.bufnr, "modifiable", false)
87 | vim.api.nvim_buf_set_option(window.bufnr, "filetype", "help")
88 | end
89 |
--------------------------------------------------------------------------------
/lua/nvim-test/init.lua:
--------------------------------------------------------------------------------
1 | local notifier = require "nvim-test.notify"
2 | local api = vim.api
3 | local suite_runner
4 | local Runner = require "nvim-test.runner"
5 | local M = {
6 | config = vim.deepcopy(require "nvim-test.config"),
7 | runners = require "nvim-test.runners",
8 | }
9 |
10 | -- Run tests
11 | ---
12 | ---@param scope string: (suite|file|nearest|last)
13 | function M.run(scope)
14 | -- Run latest
15 | if scope == "last" then
16 | return M.run_latest()
17 | end
18 |
19 | -- Check for is the filetype is supported
20 | local filetype = vim.bo.filetype
21 | local runner = M.get_runner(filetype, scope == "suite" and suite_runner or nil)
22 | if runner then
23 | suite_runner = runner
24 | local opts = {}
25 | local filename = nil
26 |
27 | -- Find tests
28 | if scope == "nearest" then
29 | opts.tests = runner:find_nearest_test(filetype)
30 | end
31 |
32 | -- Find file
33 | if scope ~= "suite" then
34 | filename =
35 | vim.fn.expand("%" .. (runner.config.filename_modifier or M.config.filename_modifier))
36 | if not runner:is_testfile(filename) then
37 | filename = runner:find_file(filename)
38 | end
39 | end
40 |
41 | -- Find the current working directory
42 | local cwd = runner:find_working_directory(filename)
43 | if filename and cwd and #cwd > 0 then
44 | filename = string.gsub(filename, "^" .. cwd .. "/", "", 1)
45 | end
46 |
47 | -- Prepare run context
48 | local cmd = runner:build_cmd(filename, opts)
49 | local cfg = { env = runner.config.env, working_directory = cwd }
50 |
51 | -- Save last run
52 | vim.g.test_latest = {
53 | cmd = cmd,
54 | cfg = cfg,
55 | filename = filename,
56 | line = api.nvim_win_get_cursor(0)[0],
57 | }
58 |
59 | return M.run_cmd(cmd, cfg)
60 | end
61 | end
62 |
63 | --- Repeat a latest test command
64 | function M.run_last()
65 | local latest = vim.g.test_latest
66 | if not latest then
67 | return notifier:notify("No tests were run so far", 3)
68 | end
69 | return M.run_cmd(latest.cmd, latest.cfg)
70 | end
71 |
72 | ---Get a runner by the given filetype
73 | ---@return Runner runner
74 | function M.get_runner(filetype, default)
75 | local runner_module = M.runners[filetype]
76 | if runner_module then
77 | local _, runner = pcall(require, runner_module)
78 | if runner then
79 | return runner
80 | end
81 | end
82 | local runner = default
83 | if not runner then
84 | notifier:notify(string.format("Test runner for `%s` is not found", filetype), 4)
85 | end
86 | return runner
87 | end
88 |
89 | -- Visit the latest test
90 | function M.visit()
91 | local opts = vim.g.test_latest
92 | if opts and opts.filename then
93 | local args = opts.line and string.format("+%s", opts.line) or ""
94 | return api.nvim_command(string.format("edit %s%s", opts.filename, args))
95 | end
96 | return notifier:notify("No tests were run so far", 3)
97 | end
98 |
99 | function M.edit()
100 | local runner = M.get_runner(vim.bo.filetype)
101 | local filename =
102 | vim.fn.expand("%" .. (runner.config.filename_modifier or M.config.filename_modifier))
103 | if not runner:is_testfile(filename) then
104 | vim.api.nvim_command("edit " .. runner:find_file(filename, true))
105 | end
106 | end
107 |
108 | --- Run the given command
109 | ---
110 | ---@param cmd table: a command to run
111 | ---@param cfg table: a runner's config
112 | function M.run_cmd(cmd, cfg)
113 | notifier:log(table.concat(cmd, " "))
114 | if not M.config.run then
115 | return
116 | end
117 | local supported, termExec = pcall(require, "nvim-test.terms." .. M.config.term)
118 | if not supported then
119 | return notifier:notify(string.format("Term: %s is not supported", M.config.term), 4)
120 | end
121 | local opts = M.config.termOpts
122 | vim.validate {
123 | direction = { opts.direction, "string" },
124 | width = { opts.width, "number" },
125 | height = { opts.height, "number" },
126 | go_back = { opts.go_back, "boolean" },
127 | -- stopinsert = { opts.stopinsert, "boolean" },
128 | }
129 | return termExec(cmd, cfg, opts)
130 | end
131 |
132 | -- Setup the plugin
133 | ---
134 | ---@param cfg table: a table with configuration
135 | function M.setup(cfg)
136 | -- Update config
137 | if cfg ~= nil then
138 | M.config = vim.tbl_deep_extend("force", M.config, cfg)
139 | end
140 |
141 | if M.config.runners then
142 | M.runners = vim.tbl_deep_extend("force", M.runners, M.config.runners)
143 | end
144 |
145 | -- Reset latest
146 | vim.g.test_latest = nil
147 |
148 | -- Setup notifies
149 | notifier:setup(M.config.silent)
150 |
151 | -- Create commands
152 | if M.config.commands_create then
153 | api.nvim_command "command! TestFile lua require'nvim-test'.run('file')"
154 | api.nvim_command "command! TestLast lua require'nvim-test'.run_last()"
155 | api.nvim_command "command! TestNearest lua require'nvim-test'.run('nearest')"
156 | api.nvim_command "command! TestSuite lua require'nvim-test'.run('suite')"
157 | api.nvim_command "command! TestVisit lua require'nvim-test'.visit()"
158 | api.nvim_command "command! TestInfo lua require'nvim-test.info'()"
159 | api.nvim_command "command! TestEdit lua require'nvim-test'.edit()"
160 | end
161 | end
162 |
163 | return M
164 |
--------------------------------------------------------------------------------
/lua/nvim-test/notify.lua:
--------------------------------------------------------------------------------
1 | local Notifier = {}
2 | Notifier.__index = Notifier
3 |
4 | --Initialize hash helper
5 | ---@returns Notifier
6 | function Notifier:init()
7 | self = {}
8 | setmetatable(self, Notifier)
9 | self.silent = false
10 | self.prefix = "[nvim-test]: "
11 | return self
12 | end
13 |
14 | ---@param silent boolean: is silent mode enabled
15 | function Notifier:setup(silent)
16 | self.silent = silent
17 | return self
18 | end
19 |
20 | --Send notify
21 | function Notifier:notify(msg, level)
22 | vim.notify(self.prefix .. msg, level or 2)
23 | end
24 |
25 | --Send optional notify
26 | function Notifier:onotify(msg, level)
27 | if not self.silent then
28 | self:notify(msg, level)
29 | end
30 | end
31 |
32 | -- Log a message
33 | function Notifier:log(msg)
34 | vim.api.nvim_echo({ { self.prefix .. msg } }, true, {})
35 | end
36 |
37 | --Ask for a confirmation
38 | function Notifier:confirm(msg, choices)
39 | local _, choice = pcall(vim.fn.confirm, self.prefix .. msg, choices, 1)
40 | return choice
41 | end
42 |
43 | return Notifier:init()
44 |
--------------------------------------------------------------------------------
/lua/nvim-test/runner.lua:
--------------------------------------------------------------------------------
1 | ---@diagnostic disable: unused-local
2 | local utils = require "nvim-test.utils"
3 | local ts_utils = require "nvim-treesitter.ts_utils"
4 | local ts_parsers = require "nvim-treesitter.parsers"
5 | local ts = vim.treesitter
6 |
7 | ---@class Runner
8 | local Runner = {
9 | config = {
10 | args = {},
11 |
12 | filename_modifier = nil,
13 | working_directory = nil,
14 | },
15 | }
16 | Runner.__index = Runner
17 |
18 | function Runner:init(config, queries)
19 | self = setmetatable({}, Runner)
20 | self.queries = queries or {}
21 | for ft, query in pairs(self.queries) do
22 | local set_query = ts.query.set or ts.set_query -- neovim 0.8 support
23 | set_query(ft, "nvim-test", query)
24 | end
25 | self:setup(config)
26 | return self
27 | end
28 |
29 | function Runner:setup(config)
30 | if config then
31 | self.config = vim.tbl_deep_extend("force", self.config, config)
32 | end
33 | if type(self.config.command) == "table" then
34 | self.config.command = utils.check_executable(self.config.command)
35 | end
36 | return self
37 | end
38 |
39 | function Runner:find_nearest_test(filetype)
40 | local query_get = ts.query.get or ts.get_query -- neovim 0.8 support
41 | local query = query_get(ts_parsers.ft_to_lang(filetype), "nvim-test")
42 | local result = {}
43 | if query then
44 | local curnode = ts_utils.get_node_at_cursor()
45 | while curnode do
46 | local iter = query:iter_captures(curnode, 0)
47 | local capture_id, capture_node = iter()
48 | if capture_node == curnode and query.captures[capture_id] == "scope-root" then
49 | while query.captures[capture_id] ~= "test-name" do
50 | capture_id, capture_node = iter()
51 | if not capture_id then
52 | return result
53 | end
54 | end
55 | local name = self:parse_testname(ts.get_node_text(capture_node, 0))
56 | table.insert(result, 1, name)
57 | end
58 | curnode = curnode:parent()
59 | end
60 | end
61 | return result
62 | end
63 |
64 | ---Check is the given filename is a test file
65 | --
66 | ---@param filename string
67 | ---@return boolean
68 | function Runner:is_testfile(filename)
69 | local file_pattern = self.config.file_pattern
70 | if file_pattern and #file_pattern > 0 then
71 | return vim.fn.match(filename, self.config.file_pattern) >= 0
72 | end
73 | return true
74 | end
75 |
76 | ---Find a test file for the given filename
77 | --
78 | ---@param filename string
79 | ---@return string
80 | function Runner:find_file(filename, force)
81 | local finder = self.config.find_files
82 | if not finder then
83 | return filename
84 | end
85 | if type(finder) == "function" then
86 | return finder(filename)
87 | end
88 | if type(finder) == "string" then
89 | finder = { finder }
90 | end
91 | return utils.find_file_by_patterns(filename, finder, force)
92 | end
93 |
94 | ---@param name string
95 | ---@return string
96 | function Runner:parse_testname(name)
97 | return name
98 | end
99 |
100 | -- Find root directory
101 | ---@param filename string
102 | ---@return string
103 | function Runner:find_working_directory(filename)
104 | return self.config.working_directory
105 | end
106 |
107 | -- Build command list
108 | ---
109 | ---@return table cmd command list
110 | function Runner:build_cmd(filename, opts)
111 | local args = utils.concat({}, self.config.args)
112 | self:build_args(args, filename, opts or {})
113 | table.insert(args, 1, self.config.command)
114 | return args
115 | end
116 |
117 | -- Build arguments
118 | function Runner:build_args(args, filename, opts)
119 | if filename then
120 | table.insert(args, filename)
121 | end
122 | if opts.tests and #opts.tests > 0 then
123 | self:build_test_args(args, opts.tests)
124 | end
125 | end
126 |
127 | ---@return table test_args test arguments list
128 | function Runner:build_test_args(args, tests) end
129 |
130 | return Runner
131 |
--------------------------------------------------------------------------------
/lua/nvim-test/runners/busted.lua:
--------------------------------------------------------------------------------
1 | local Runner = require "nvim-test.runner"
2 |
3 | local busted = Runner:init({
4 | command = "busted",
5 | file_pattern = "\\v_spec\\.(lua|moon)$",
6 | find_files = "{name}_spec.{ext}",
7 | }, {
8 | lua = [[
9 | ((function_call (identifier) (arguments (string) @test-name (function_definition))) @scope-root)
10 | ]],
11 | })
12 |
13 | function busted:parse_testname(name)
14 | return name:gsub("^[\"']", ""):gsub("[\"']$", "")
15 | end
16 |
17 | function busted:build_test_args(args, tests)
18 | table.insert(args, "--filter")
19 | table.insert(args, table.concat(tests, " "))
20 | end
21 |
22 | return busted
23 |
--------------------------------------------------------------------------------
/lua/nvim-test/runners/cargo-test.lua:
--------------------------------------------------------------------------------
1 | -- TODO
2 | --
3 | local Runner = require "nvim-test.runner"
4 |
5 | local cargotest = Runner:init({ command = "cargo", args = { "test" }, package = false }, {
6 | rust = [[
7 | (
8 | (
9 | mod_item name: (identifier) @test-name
10 | (#match? @test-name "[Tt]est")
11 | )
12 | @scope-root)
13 |
14 | (
15 | (
16 | function_item name: (identifier) @test-name
17 | (#match? @test-name "[Tt]est")
18 | )
19 | @scope-root)
20 | ]],
21 | })
22 |
23 | function cargotest:build_args(args, filename, opts)
24 | -- for whole suite do nothing
25 | if not filename then
26 | return
27 | end
28 |
29 | -- Find a package
30 | if self.config.package then
31 | local crate = vim.fn.findfile("Cargo.toml", vim.fn.fnamemodify(filename, ":p") .. ";")
32 | if crate and #crate > 0 then
33 | table.insert(args, "-p")
34 | table.insert(args, vim.fn.fnamemodify(crate, ":p:h:t"))
35 | end
36 | end
37 |
38 | if opts.tests and #opts.tests > 0 then
39 | table.insert(args, table.concat(opts.tests, "::"))
40 | table.insert(args, "--")
41 | table.insert(args, "--exact")
42 | else
43 | local parts = vim.fn.split(vim.fn.fnamemodify(filename, ":.:r"), "/")
44 | if parts[#parts] == "main" or parts[#parts] == "lib" or parts[#parts] == "mod" then
45 | parts[#parts] = nil
46 | end
47 | if parts[1] == "src" then
48 | table.remove(parts, 1)
49 | end
50 |
51 | local modname = (#parts > 0) and table.concat(parts, "::")
52 | if modname then
53 | table.insert(args, modname .. "::")
54 | end
55 | end
56 | end
57 |
58 | return cargotest
59 |
--------------------------------------------------------------------------------
/lua/nvim-test/runners/cypress.lua:
--------------------------------------------------------------------------------
1 | local Runner = require "nvim-test.runner"
2 | local jest = require "nvim-test.runners.jest"
3 |
4 | local cypress = Runner:init({
5 | command = { "./node_modules/.bin/cypress", "cypress" },
6 | args = { "run" },
7 | file_pattern = jest.config.file_pattern,
8 | find_files = jest.config.find_files,
9 | }, {
10 | javascript = jest.queries.javascript,
11 | })
12 |
13 | function cypress:build_args(args, filename, _)
14 | if filename then
15 | table.insert(args, "--spec")
16 | table.insert(args, filename)
17 | end
18 | end
19 |
20 | return cypress
21 |
--------------------------------------------------------------------------------
/lua/nvim-test/runners/dotnet.lua:
--------------------------------------------------------------------------------
1 | local Runner = require "nvim-test.runner"
2 |
3 | local cstest = Runner:init({
4 | command = "dotnet",
5 | args = { "test" },
6 | file_pattern = "\\v(test/.*|Tests)\\.cs$",
7 | find_files = { "{name}Tests.{ext}", "Tests.{ext}" }, -- find testfile for a file
8 | }, {
9 | c_sharp = [[
10 | ; Namespace
11 | ((namespace_declaration name: (identifier) @test-name) @scope-root)
12 |
13 | ; Class
14 | ((class_declaration name: (identifier) @test-name) @scope-root)
15 |
16 | ; Method
17 | ((method_declaration
18 | (attribute_list
19 | (attribute name: (identifier) @attribute-name
20 | (#match? @attribute-name "(Fact|Theory|Test|TestMethod)")
21 | ; attributes used by xunit, nunit and mstest
22 | ))
23 | name: (identifier) @test-name)
24 | @scope-root)
25 |
26 | ]],
27 | })
28 |
29 | function cstest:build_test_args(args, tests)
30 | table.insert(args, "--filter")
31 | table.insert(args, "FullyQualifiedName=" .. table.concat(tests, "."))
32 | end
33 |
34 | return cstest
35 |
--------------------------------------------------------------------------------
/lua/nvim-test/runners/go-test.lua:
--------------------------------------------------------------------------------
1 | -- TODO
2 | --
3 | local Runner = require "nvim-test.runner"
4 |
5 | local gotest = Runner:init({
6 | command = "go",
7 | args = { "test", "-v" },
8 | file_pattern = "\\v([^.]+_test)\\.go$", -- determine whether a file is a testfile
9 | find_files = { "{name}_test.go" }, -- find testfile for a file
10 | }, {
11 | go = [[
12 | (
13 | (
14 | function_declaration name: (identifier) @test-name
15 | (#match? @test-name "^(Test|Benchmark|Fuzz)")
16 | )
17 | @scope-root)
18 | ]],
19 | })
20 |
21 | function gotest:build_args(args, filename, opts)
22 | if filename then
23 | local path = vim.fn.fnamemodify(filename, ":.:h")
24 | if path ~= "." then
25 | table.insert(args, string.format("./%s/...", path))
26 | end
27 | if opts.tests and next(opts.tests) ~= nil then
28 | table.insert(args, "-run")
29 | table.insert(args, opts.tests[1] .. "$")
30 | end
31 | else
32 | table.insert(args, "./...")
33 | end
34 | end
35 |
36 | return gotest
37 |
--------------------------------------------------------------------------------
/lua/nvim-test/runners/hspec.lua:
--------------------------------------------------------------------------------
1 | local Runner = require "nvim-test.runner"
2 |
3 | local hspec = Runner:init({
4 | command = { "runhaskell" },
5 | file_pattern = "\\v(Spec)\\.hs$",
6 | find_files = { "{name}Spec.hs", "Spec.hs" },
7 | }, {
8 | haskell = [[
9 | ((stmt (exp_infix (exp_apply
10 | (exp_name) @exp-name
11 | (#match? @exp-name "^(describe|it)")
12 | (exp_literal) @test-name
13 | )
14 | ))
15 | @scope-root)
16 | ]],
17 | })
18 |
19 | function hspec:parse_testname(name)
20 | return name:gsub("^[\"'`]", ""):gsub("[\"'`]$", "")
21 | end
22 |
23 | function hspec:build_test_args(args, tests)
24 | table.insert(args, "--match")
25 | table.insert(args, table.concat(tests, "/"))
26 | end
27 |
28 | return hspec
29 |
--------------------------------------------------------------------------------
/lua/nvim-test/runners/init.lua:
--------------------------------------------------------------------------------
1 | return {
2 | cs = "nvim-test.runners.dotnet",
3 | go = "nvim-test.runners.go-test",
4 | haskell = "nvim-test.runners.hspec",
5 | javascript = "nvim-test.runners.jest",
6 | javascriptreact = "nvim-test.runners.jest",
7 | lua = "nvim-test.runners.busted",
8 | python = "nvim-test.runners.pytest",
9 | ruby = "nvim-test.runners.rspec",
10 | rust = "nvim-test.runners.cargo-test",
11 | typescript = "nvim-test.runners.jest",
12 | typescriptreact = "nvim-test.runners.jest",
13 | zig = "nvim-test.runners.zig",
14 | }
15 |
--------------------------------------------------------------------------------
/lua/nvim-test/runners/jest.lua:
--------------------------------------------------------------------------------
1 | local Runner = require "nvim-test.runner"
2 | local utils = require "nvim-test.utils"
3 |
4 | local query = [[
5 | ((expression_statement
6 | (call_expression
7 | function: (identifier) @method-name
8 | (#match? @method-name "^(describe|test|it)")
9 | arguments: (arguments [
10 | ((string) @test-name)
11 | ((template_string) @test-name)
12 | ]
13 | )))
14 | @scope-root)
15 | ]]
16 |
17 | local jest = Runner:init({
18 | command = { "./node_modules/.bin/jest", "jest" },
19 | file_pattern = "\\v(__tests__/.*|(spec|test))\\.(js|jsx|coffee|ts|tsx)$",
20 | find_files = { "{name}.test.{ext}", "{name}.spec.{ext}" },
21 | }, {
22 | javascript = query,
23 | typescript = query,
24 | })
25 |
26 | function jest:parse_testname(name)
27 | return name:gsub("^[\"'`]", ""):gsub("[\"'`]$", "")
28 | end
29 |
30 | function jest:build_test_args(args, tests)
31 | table.insert(args, "-t")
32 | table.insert(args, "^" .. table.concat(tests, " ") .. "$")
33 | end
34 |
35 | function jest:find_working_directory(filename)
36 | local root = self.config.working_directory
37 | if not root then
38 | root = utils.find_relative_root(filename, "package.json")
39 | end
40 | return root
41 | end
42 |
43 | return jest
44 |
--------------------------------------------------------------------------------
/lua/nvim-test/runners/mocha.lua:
--------------------------------------------------------------------------------
1 | local Runner = require "nvim-test.runner"
2 | local jest = require "nvim-test.runners.jest"
3 |
4 | local mocha = Runner:init({
5 | command = { "./node_modules/.bin/mocha", "mocha" },
6 | file_pattern = "\\v(tests?/.*|test)\\.(js|jsx|coffee)$",
7 | find_files = { "{name}.test.{ext}" },
8 | }, {
9 | javascript = jest.queries.javascript,
10 | typescript = jest.queries.typescript,
11 | })
12 |
13 | function mocha:parse_testname(name)
14 | return jest:parse_testname(name)
15 | end
16 |
17 | function mocha:build_test_args(args, tests)
18 | table.insert(args, "-f")
19 | table.insert(args, table.concat(tests, " "))
20 | end
21 |
22 | return mocha
23 |
--------------------------------------------------------------------------------
/lua/nvim-test/runners/pytest.lua:
--------------------------------------------------------------------------------
1 | local Runner = require "nvim-test.runner"
2 |
3 | local pytest = Runner:init({
4 | command = { (vim.env.VIRTUAL_ENV or "venv") .. "/bin/pytest", "pytest" },
5 | file_pattern = "\\v(test_[^.]+|[^.]+_test|tests)\\.py$",
6 | find_files = { "test_{name}.py", "{name}_test.py", "tests.py", "tests" },
7 | }, {
8 | python = [[
9 | ; Class
10 | (
11 | (
12 | class_definition name: (identifier) @test-name
13 | (#match? @test-name "[Tt]est")
14 | )
15 | @scope-root)
16 |
17 | ; Function
18 | (
19 | (
20 | function_definition name: (identifier) @test-name
21 | (#match? @test-name "^[Tt]est")
22 | )
23 | @scope-root)
24 | ]],
25 | })
26 |
27 | function pytest:build_test_args(args, tests)
28 | args[#args] = args[#args] .. "::" .. table.concat(tests, "::")
29 | end
30 |
31 | return pytest
32 |
--------------------------------------------------------------------------------
/lua/nvim-test/runners/pyunit.lua:
--------------------------------------------------------------------------------
1 | local Runner = require "nvim-test.runner"
2 | local pytest = require "nvim-test.runners.pytest"
3 |
4 | local pyunit = Runner:init({
5 | command = { (vim.env.VIRTUAL_ENV or "venv") .. "/bin/python", "python" },
6 | args = { "-m", "unittest" },
7 | file_pattern = "\\v^test.*\\.py$",
8 | find_files = { "test_{name}.py" },
9 | }, {
10 | python = pytest.queries.python,
11 | })
12 |
13 | function pyunit:build_args(args, filename, opts)
14 | if filename then
15 | local path, _ = vim.fn.fnamemodify(filename, ":.:r"):gsub("/", ".")
16 | table.insert(args, path)
17 | end
18 | if opts.tests and #opts.tests > 0 then
19 | args[#args] = args[#args] .. "." .. table.concat(opts.tests, ".")
20 | end
21 | end
22 |
23 | return pyunit
24 |
--------------------------------------------------------------------------------
/lua/nvim-test/runners/rspec.lua:
--------------------------------------------------------------------------------
1 | local Runner = require "nvim-test.runner"
2 | local utils = require "nvim-test.utils"
3 |
4 | local rspec = Runner:init({
5 | command = { "rspec", "bundle" },
6 | file_pattern = "\\v(spec_[^.]+|[^.]+_spec)\\.rb$",
7 | find_files = { "{name}_spec.rb" },
8 | }, {
9 | ruby = [[
10 | (
11 | (call
12 | method: (identifier) @method-name
13 | (#match? @method-name "(describe|it|context)")
14 | arguments: (argument_list (string (string_content) @test-name))
15 | )
16 | @scope-root)
17 | ]],
18 | })
19 |
20 | function rspec:find_working_directory(filename)
21 | local root = self.config.working_directory
22 | if not root then
23 | root = utils.find_relative_root(filename, "Gemfile")
24 | end
25 | return root
26 | end
27 |
28 | function rspec:build_args(args, filename, opts)
29 | if self.config.command == "bundle" then
30 | table.insert(args, "exec")
31 | table.insert(args, "rspec")
32 | end
33 |
34 | if filename then
35 | table.insert(args, filename)
36 | end
37 | if opts.tests and #opts.tests > 0 then
38 | self:build_test_args(args, opts.tests)
39 | end
40 | end
41 |
42 | function rspec:build_test_args(args, tests)
43 | table.insert(args, "--example")
44 | table.insert(args, table.concat(tests, " "))
45 | end
46 |
47 | return rspec
48 |
--------------------------------------------------------------------------------
/lua/nvim-test/runners/stack.lua:
--------------------------------------------------------------------------------
1 | local Runner = require "nvim-test.runner"
2 | local hspec = require "nvim-test.runners.hspec"
3 |
4 | local stack = Runner:init({
5 | command = { "stack" },
6 | args = { "test" },
7 | file_pattern = hspec.config.file_pattern,
8 | find_files = hspec.config.find_files,
9 | }, {
10 | haskell = hspec.queries.haskell,
11 | })
12 |
13 | function stack:parse_testname(name)
14 | return hspec:parse_testname(name)
15 | end
16 |
17 | function stack:build_test_args(args, tests)
18 | table.insert(
19 | args,
20 | "--test-arguments=" .. string.format("'--match \"%s\"'", table.concat(tests, "/"))
21 | )
22 | end
23 |
24 | return stack
25 |
--------------------------------------------------------------------------------
/lua/nvim-test/runners/ts-mocha.lua:
--------------------------------------------------------------------------------
1 | local Runner = require "nvim-test.runner"
2 | local mocha = require "nvim-test.runners.mocha"
3 |
4 | local tsmocha = Runner:init({
5 | command = { "./node_modules/.bin/ts-mocha", "ts-mocha" },
6 | file_pattern = "\\v(tests?/.*|test)\\.(ts|tsx)$",
7 | find_files = { "{name}.test.{ext}" },
8 | }, {
9 | typescript = mocha.queries.typescript,
10 | })
11 |
12 | function tsmocha:parse_testname(name)
13 | return mocha:parse_testname(name)
14 | end
15 |
16 | function tsmocha:build_test_args(args, tests)
17 | return mocha:build_test_args(args, tests)
18 | end
19 |
20 | return tsmocha
21 |
--------------------------------------------------------------------------------
/lua/nvim-test/runners/vusted.lua:
--------------------------------------------------------------------------------
1 | local Runner = require "nvim-test.runner"
2 | local busted = require "nvim-test.runners.busted"
3 |
4 | local vusted = Runner:init({
5 | command = "vusted",
6 | file_pattern = busted.config.file_pattern,
7 | find_files = busted.config.find_files,
8 | }, {
9 | lua = busted.queries.lua,
10 | })
11 |
12 | function vusted:parse_testname(name)
13 | return busted:parse_testname(name)
14 | end
15 |
16 | function vusted:build_test_args(args, tests)
17 | return busted:build_test_args(args, tests)
18 | end
19 |
20 | return vusted
21 |
--------------------------------------------------------------------------------
/lua/nvim-test/runners/zig.lua:
--------------------------------------------------------------------------------
1 | local Runner = require("nvim-test.runner")
2 |
3 | local zig_test = Runner:init({ command = "zig" }, {
4 | zig = [[
5 | (TestDecl . [(STRINGLITERALSINGLE) @test-name (IDENTIFIER) @test-name]) @scope-root
6 | ]],
7 | })
8 |
9 | function zig_test:parse_testname(name)
10 | return name:gsub('^@?"', ""):gsub('"$', "")
11 | end
12 |
13 | function zig_test:build_args(args, filename, opts)
14 | if not filename then
15 | table.insert(args, "build")
16 | table.insert(args, "test")
17 | return
18 | end
19 |
20 | table.insert(args, "test")
21 | table.insert(args, filename)
22 |
23 | if opts.tests and #opts.tests > 0 then
24 | for _, test in ipairs(opts.tests) do
25 | table.insert(args, "--test-filter")
26 | table.insert(args, test)
27 | end
28 | end
29 | end
30 |
31 | return zig_test
32 |
--------------------------------------------------------------------------------
/lua/nvim-test/terms/callbacks.lua:
--------------------------------------------------------------------------------
1 | local notifier = require "nvim-test.notify"
2 |
3 | local M = {}
4 |
5 | ---Bind on_exit callback
6 | ---@param cfg table
7 | ---@return function
8 | function M.bind_on_exit(cfg)
9 | return function(_, status)
10 | local stopinsert = cfg.stopinsert
11 | if status ~= 0 then
12 | notifier:onotify("Tests are failed", 3)
13 | if stopinsert == "auto" then
14 | stopinsert = true
15 | end
16 | end
17 | if stopinsert == true or cfg.go_back then
18 | vim.cmd "stopinsert!"
19 | end
20 | if cfg.go_back then
21 | vim.cmd "wincmd p"
22 | end
23 | end
24 | end
25 |
26 | return M
27 |
--------------------------------------------------------------------------------
/lua/nvim-test/terms/terminal.lua:
--------------------------------------------------------------------------------
1 | local callbacks = require "nvim-test.terms.callbacks"
2 |
3 | local directionsMap = {
4 | vertical = "vsplit",
5 | horizontal = "split",
6 | }
7 | local term = nil
8 | local next = next
9 |
10 | local exec = function(cmd, cfg, termCfg)
11 | local opts = {
12 | on_exit = callbacks.bind_on_exit(termCfg),
13 | }
14 | if cfg.env and next(cfg.env) then
15 | opts.env = cfg.env
16 | end
17 | if cfg.working_directory and #cfg.working_directory > 0 then
18 | opts.cwd = cfg.working_directory
19 | end
20 | return vim.fn.termopen(cmd, opts)
21 | end
22 |
23 | return function(cmd, cfg, termCfg)
24 | if termCfg.direction == "float" then
25 | local bufnr = vim.api.nvim_create_buf(false, false)
26 | vim.api.nvim_open_win(bufnr, true, {
27 | row = math.ceil(vim.o.lines - termCfg.height) / 2 - 1,
28 | col = math.ceil(vim.o.columns - termCfg.width) / 2 - 1,
29 | relative = "editor",
30 | width = termCfg.width,
31 | height = termCfg.height,
32 | style = "minimal",
33 | border = "single",
34 | })
35 | return exec(cmd, cfg, termCfg)
36 | end
37 |
38 | local split = directionsMap[termCfg.direction]
39 | if termCfg.direction == "vertical" and termCfg.width then
40 | split = termCfg.width .. split
41 | end
42 | if termCfg.direction == "horizontal" and termCfg.height then
43 | split = termCfg.height .. split
44 | end
45 |
46 | -- Clean buffers
47 | if termCfg.keep_one and term then
48 | if vim.fn.bufexists(term) > 0 then
49 | vim.api.nvim_buf_delete(term, { force = true })
50 | end
51 | end
52 |
53 | vim.cmd(string.format("botright %s new", split))
54 | exec(cmd, cfg, termCfg)
55 | term = vim.api.nvim_get_current_buf()
56 | end
57 |
--------------------------------------------------------------------------------
/lua/nvim-test/terms/toggleterm.lua:
--------------------------------------------------------------------------------
1 | local callbacks = require "nvim-test.terms.callbacks"
2 |
3 | local terminal = require "toggleterm.terminal"
4 | -- local ok, terminal = pcall(require, "toggleterm.terminal")
5 | -- if not ok then
6 | -- error "Install toggleterm.nvim to use toggleterm"
7 | -- end
8 |
9 | local term = nil
10 |
11 | ---Run terminal
12 | ---@param cmd table
13 | ---@param cfg table
14 | ---@param termCfg table
15 | return function(cmd, cfg, termCfg)
16 | local command = cmd[1]
17 | for i = 2, #cmd do
18 | command = command .. " " .. vim.fn.shellescape(cmd[i])
19 | end
20 | local on_exit = callbacks.bind_on_exit(termCfg)
21 |
22 | -- Clean terminals
23 | if termCfg.keep_one and term then
24 | term:close()
25 | end
26 |
27 | term = terminal.Terminal:new {
28 | cmd = command,
29 | dir = cfg.working_directory,
30 | direction = termCfg.direction,
31 | close_on_exit = false,
32 | on_exit = function(_, _, status)
33 | on_exit(_, status)
34 | end,
35 | }
36 | term:open(
37 | termCfg.direction == "vertical" and termCfg.width or termCfg.height,
38 | termCfg.direction,
39 | true
40 | )
41 | end
42 |
--------------------------------------------------------------------------------
/lua/nvim-test/utils.lua:
--------------------------------------------------------------------------------
1 | local M = {}
2 |
3 | ---Get a text from the given treesitter node
4 | ---@return string s a text
5 | function M.get_node_text(node, bufnr)
6 | bufnr = bufnr or vim.api.nvim_get_current_buf()
7 | local start_row, start_col, _, end_col = node:range()
8 | local line = vim.api.nvim_buf_get_lines(bufnr, start_row, start_row + 1, false)[1]
9 | return line and string.sub(line, start_col + 1, end_col) or ""
10 | end
11 |
12 | function M.get_node_at_cursor()
13 | local cursor = vim.api.nvim_win_get_cursor(0)
14 | local line = cursor[1] - 1
15 | local col = cursor[2]
16 | local parser = vim.treesitter.get_parser()
17 | if not parser then
18 | return
19 | end
20 | local lang_tree = parser:language_for_range { line, col, line, col }
21 | for _, tree in ipairs(lang_tree:trees()) do
22 | local root = tree:root()
23 | local node = root:named_descendant_for_range(line, col, line, col)
24 | if node then
25 | return node
26 | end
27 | end
28 | end
29 |
30 | ---Concat tables
31 | --
32 | ---@param r table a target table
33 | ---@param t table a table
34 | ---@return table r a target table
35 | function M.concat(r, t)
36 | for _, value in ipairs(t) do
37 | table.insert(r, value)
38 | end
39 | return r
40 | end
41 |
42 | function M.check_executable(cmds)
43 | for _, cmd in ipairs(cmds) do
44 | if vim.fn.executable(cmd) == 1 then
45 | return cmd
46 | end
47 | end
48 | return cmds[#cmds]
49 | end
50 |
51 | ---Find file by patterns
52 | --
53 | ---@param source string
54 | ---@param patterns table
55 | ---@return string
56 | function M.find_file_by_patterns(source, patterns, force)
57 | local ctx = {
58 | name = vim.fn.fnamemodify(source, ":t:r"),
59 | ext = vim.fn.fnamemodify(source, ":e"),
60 | }
61 | for _, pat in ipairs(patterns) do
62 | local filename = M.format_pattern(pat, ctx)
63 | local testfile = vim.fn.findfile(filename, source .. ";")
64 | if #testfile > 0 then
65 | return testfile
66 | end
67 | testfile = vim.fn.finddir(filename, source .. ";")
68 | if #testfile > 0 then
69 | return testfile
70 | end
71 | end
72 | if force then
73 | return vim.fn.fnamemodify(source, ":h") .. "/" .. M.format_pattern(patterns[1], ctx)
74 | end
75 | return source
76 | end
77 |
78 | ---@param pattern string
79 | ---@return string
80 | function M.format_pattern(pattern, ctx)
81 | local res = pattern
82 | for var in pattern:gmatch "{[^}]+}" do
83 | var = var:gsub("{", ""):gsub("}", "")
84 | res = res:gsub("{" .. var .. "}", ctx[var] or "")
85 | end
86 | return res
87 | end
88 |
89 | ---Find the project root based on an indicating filename
90 | ---@param source string
91 | ---@param indicator string
92 | ---@return string
93 | function M.find_relative_root(source, indicator)
94 | local path = vim.fn.findfile(indicator, vim.fn.fnamemodify(source, ":p") .. ";")
95 | if path and #path > 0 then
96 | path = vim.fn.fnamemodify(path, ":p:h")
97 | end
98 | return path
99 | end
100 |
101 | return M
102 |
--------------------------------------------------------------------------------
/packspec.json:
--------------------------------------------------------------------------------
1 | {
2 | "package": "nvim-test",
3 | "version": "1.4.1",
4 | "source": "git://github.com/klen/nvim-test.git",
5 | "description": {
6 | "summary": "Test Runner for Neovim",
7 | "homepage": "https://github.com/klen/nvim-test/",
8 | "license": "MIT"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/spec/conftest.lua:
--------------------------------------------------------------------------------
1 | -- Setup tests
2 |
3 | -- -- Setup nvim-test
4 | -- local nvim_test = require "nvim-test"
5 | -- nvim_test.setup {
6 | -- run = false,
7 | -- }
8 |
9 | -- Setup nvim-treesitter
10 | vim.o.runtimepath = vim.fn.getcwd() .. "/nvim-treesitter," .. vim.o.runtimepath
11 | local nvim_treesitter = require "nvim-treesitter.configs"
12 | nvim_treesitter.setup {
13 | ensure_installed = {
14 | "c_sharp",
15 | "go",
16 | "haskell",
17 | "javascript",
18 | "lua",
19 | "python",
20 | "ruby",
21 | "rust",
22 | "typescript",
23 | "zig",
24 | },
25 | sync_install = true,
26 | }
27 |
28 | return true
29 |
--------------------------------------------------------------------------------
/spec/fixtures/Spec.hs:
--------------------------------------------------------------------------------
1 | import Test.Hspec
2 | import Test.QuickCheck
3 | import Control.Exception (evaluate)
4 |
5 | main :: IO ()
6 | main = hspec $ do
7 | describe "Prelude.head" $ do
8 | it "returns the first element of a list" $ do
9 | head [23 ..] `shouldBe` (23 :: Int)
10 |
11 | it "returns the first element of an *arbitrary* list" $
12 | property $ \x xs -> head (x:xs) == (x :: Int)
13 |
14 | describe "nested" $ do
15 | it "throws an exception if used with an empty list" $ do
16 | evaluate (head []) `shouldThrow` anyException
17 |
--------------------------------------------------------------------------------
/spec/fixtures/Tests.cs:
--------------------------------------------------------------------------------
1 | namespace Namespace
2 | {
3 | public class Tests
4 | {
5 |
6 | [Fact]
7 | public void Test()
8 | {
9 | Assert.Equal(true, false);
10 | }
11 |
12 | [Fact]
13 | public async void TestAsync()
14 | {
15 | Assert.Equal(true, false);
16 | }
17 |
18 | [Fact]
19 | public async Task TestAsyncWithTaskReturn()
20 | {
21 | Assert.Equal(true, false);
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/spec/fixtures/go/go.mod:
--------------------------------------------------------------------------------
1 | module nvim-test/m
2 |
3 | go 1.17
4 |
--------------------------------------------------------------------------------
/spec/fixtures/go/mypackage_test.go:
--------------------------------------------------------------------------------
1 | package mypackage
2 |
3 | import "testing"
4 |
5 | func TestNumbers(*testing.T) {
6 | // assertions
7 | }
8 |
9 | func Testテスト(*testing.T) {
10 | // assertions
11 | }
12 |
13 | func ExampleSomething() {
14 | // Output:
15 | }
16 |
17 | func Something() {
18 | }
19 |
--------------------------------------------------------------------------------
/spec/fixtures/js/name.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/klen/nvim-test/e06f3d029ee161f3ead6193cf27354d1eb8723c3/spec/fixtures/js/name.js
--------------------------------------------------------------------------------
/spec/fixtures/js/name.test.js:
--------------------------------------------------------------------------------
1 | describe('jstest', function () {
2 | describe(`ns`, function () {
3 | it('test1', function () {
4 | // assertions
5 | some('some', function () {
6 | console.log('passed')
7 | })
8 | })
9 | })
10 | })
11 |
--------------------------------------------------------------------------------
/spec/fixtures/rust/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | [[package]]
4 | name = "nvim-test"
5 | version = "0.0.1"
6 | dependencies = [
7 | "tokio",
8 | ]
9 |
10 | [[package]]
11 | name = "nvim-test2"
12 | version = "0.0.1"
13 |
14 | [[package]]
15 | name = "pin-project-lite"
16 | version = "0.2.8"
17 | source = "registry+https://github.com/rust-lang/crates.io-index"
18 | checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c"
19 |
20 | [[package]]
21 | name = "tokio"
22 | version = "1.17.0"
23 | source = "registry+https://github.com/rust-lang/crates.io-index"
24 | checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee"
25 | dependencies = [
26 | "pin-project-lite",
27 | ]
28 |
--------------------------------------------------------------------------------
/spec/fixtures/rust/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 | members = [
3 | "crate", "crate2"
4 | ]
5 |
--------------------------------------------------------------------------------
/spec/fixtures/rust/crate/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | [[package]]
4 | name = "nvim-test"
5 | version = "0.0.1"
6 | dependencies = [
7 | "tokio",
8 | ]
9 |
10 | [[package]]
11 | name = "pin-project-lite"
12 | version = "0.2.8"
13 | source = "registry+https://github.com/rust-lang/crates.io-index"
14 | checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c"
15 |
16 | [[package]]
17 | name = "tokio"
18 | version = "1.17.0"
19 | source = "registry+https://github.com/rust-lang/crates.io-index"
20 | checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee"
21 | dependencies = [
22 | "pin-project-lite",
23 | ]
24 |
--------------------------------------------------------------------------------
/spec/fixtures/rust/crate/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "nvim-test"
3 | version = "0.0.1"
4 | edition = "2018"
5 |
6 | [dependencies]
7 | tokio = "1.17.0"
8 |
--------------------------------------------------------------------------------
/spec/fixtures/rust/crate/src/lib.rs:
--------------------------------------------------------------------------------
1 | #![warn(rust_2018_idioms)]
2 | #![cfg(feature = "full")]
3 |
4 | mod tests {
5 | #[test]
6 | fn first_test () {
7 | // body
8 | }
9 |
10 | #[test]
11 | fn second_test () {
12 | // body
13 | }
14 |
15 | #[test]
16 | fn third_test () {
17 | // body
18 | }
19 |
20 | #[tokio::test]
21 | async fn tokio_async_test() {
22 | // body
23 | }
24 |
25 | #[rstest(input,
26 | case(1),
27 | case(2),
28 | )]
29 | fn rstest_test(_: u8) {
30 | // body
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/spec/fixtures/rust/crate/src/nested/mod.rs:
--------------------------------------------------------------------------------
1 | fn main() {}
2 |
3 | mod tests {
4 | #[test]
5 | fn first_test() {
6 | // body
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/spec/fixtures/rust/crate/src/nomod.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn first_test() {
3 | // body
4 | }
5 |
6 | #[test]
7 | fn second_test() {
8 | // body
9 | }
10 |
11 | #[test]
12 | fn third_test() {
13 | // body
14 | }
15 |
--------------------------------------------------------------------------------
/spec/fixtures/rust/crate/src/somemod.rs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/klen/nvim-test/e06f3d029ee161f3ead6193cf27354d1eb8723c3/spec/fixtures/rust/crate/src/somemod.rs
--------------------------------------------------------------------------------
/spec/fixtures/rust/crate2/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "nvim-test2"
3 | version = "0.0.1"
4 | edition = "2018"
5 |
--------------------------------------------------------------------------------
/spec/fixtures/rust/crate2/src/main.rs:
--------------------------------------------------------------------------------
1 | fn main() {}
2 |
3 | mod tests {
4 | #[test]
5 | fn first_test() {
6 | // body
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/spec/fixtures/rust/some/main.rs:
--------------------------------------------------------------------------------
1 | fn main() {}
2 |
3 | mod tests {
4 | #[test]
5 | fn first_test() {
6 | // body
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/spec/fixtures/test.lua:
--------------------------------------------------------------------------------
1 | describe("luatest", function()
2 | it("test1", function()
3 | assert.is_true(true)
4 | end)
5 |
6 | it("test2", function()
7 | assert.is_true(true)
8 | end)
9 | end)
10 |
--------------------------------------------------------------------------------
/spec/fixtures/test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 |
4 | def test_base():
5 | assert True
6 |
7 |
8 | class MyTest(unittest.TestCase):
9 | def test_method1(self):
10 | assert True
11 |
12 | def test_method2(self):
13 | assert True
14 |
--------------------------------------------------------------------------------
/spec/fixtures/test.ts:
--------------------------------------------------------------------------------
1 | describe("tstest", (): void => {
2 | describe(`ns`, (): void => {
3 | it("test1", (): void => {
4 | // assertions
5 | });
6 | })
7 | });
8 |
--------------------------------------------------------------------------------
/spec/fixtures/test_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Game do
2 | describe '#score' do
3 | it 'returns 0 for an all gutter game' do
4 | game = Game.new
5 | 20.times { game.roll(0) }
6 | expect(game.score).to eq(0)
7 | end
8 | end
9 | end
10 |
11 |
--------------------------------------------------------------------------------
/spec/fixtures/zig/.gitignore:
--------------------------------------------------------------------------------
1 | zig-out/ zig-cache/
2 |
--------------------------------------------------------------------------------
/spec/fixtures/zig/build.zig:
--------------------------------------------------------------------------------
1 | const std = @import("std");
2 |
3 | // Although this function looks imperative, note that its job is to
4 | // declaratively construct a build graph that will be executed by an external
5 | // runner.
6 | pub fn build(b: *std.Build) void {
7 | // Standard target options allows the person running `zig build` to choose
8 | // what target to build for. Here we do not override the defaults, which
9 | // means any target is allowed, and the default is native. Other options
10 | // for restricting supported target set are available.
11 | const target = b.standardTargetOptions(.{});
12 |
13 | // Standard optimization options allow the person running `zig build` to select
14 | // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not
15 | // set a preferred release mode, allowing the user to decide how to optimize.
16 | const optimize = b.standardOptimizeOption(.{});
17 |
18 | const lib = b.addStaticLibrary(.{
19 | .name = "zig",
20 | // In this case the main source file is merely a path, however, in more
21 | // complicated build scripts, this could be a generated file.
22 | .root_source_file = .{ .path = "src/main.zig" },
23 | .target = target,
24 | .optimize = optimize,
25 | });
26 |
27 | // This declares intent for the library to be installed into the standard
28 | // location when the user invokes the "install" step (the default step when
29 | // running `zig build`).
30 | lib.install();
31 |
32 | // Creates a step for unit testing.
33 | const main_tests = b.addTest(.{
34 | .root_source_file = .{ .path = "src/main.zig" },
35 | .target = target,
36 | .optimize = optimize,
37 | });
38 |
39 | // This creates a build step. It will be visible in the `zig build --help` menu,
40 | // and can be selected like this: `zig build test`
41 | // This will evaluate the `test` step rather than the default, which is "install".
42 | const test_step = b.step("test", "Run library tests");
43 | test_step.dependOn(&main_tests.step);
44 | }
45 |
--------------------------------------------------------------------------------
/spec/fixtures/zig/src/main.zig:
--------------------------------------------------------------------------------
1 | const std = @import("std");
2 | const testing = std.testing;
3 |
4 | export fn add(a: i32, b: i32) i32 {
5 | return a + b;
6 | }
7 |
8 | test "basic add functionality" {
9 | try testing.expect(add(3, 7) == 10);
10 | }
11 |
12 | test "other functionality" {
13 | try testing.expect(add(3, 7) == 10);
14 | }
15 |
--------------------------------------------------------------------------------
/spec/fixtures/zig/src/nested/mod.zig:
--------------------------------------------------------------------------------
1 | test "some nested test" {}
2 |
--------------------------------------------------------------------------------
/spec/fixtures/zig/src/somemod.zig:
--------------------------------------------------------------------------------
1 | test "some other test" {}
2 |
--------------------------------------------------------------------------------
/spec/helpers.lua:
--------------------------------------------------------------------------------
1 | -- local plugin_name = vim.split((...):gsub("%.", "/"), "/", true)[1]
2 | local M = require "vusted.helper"
3 |
4 | -- print(plugin_name, (...):gsub("%", "/"))
5 | -- M.root = M.find_plugin_root(plugin_name)
6 |
7 | function M.before_each(config)
8 | vim.cmd "filetype on"
9 | vim.cmd "syntax enable"
10 | require("nvim-test").setup(config or { run = false })
11 | end
12 |
13 | function M.after_each()
14 | -- vim.cmd "tabedit"
15 | -- vim.cmd "tabonly!"
16 | vim.cmd "silent %bwipeout!"
17 | vim.cmd "filetype off"
18 | vim.cmd "syntax off"
19 | M.cleanup_loaded_modules "nvim-test"
20 | print " "
21 | end
22 |
23 | function M.set_lines(lines)
24 | vim.api.nvim_buf_set_lines(0, 0, -1, false, vim.split(lines, "\n"))
25 | end
26 |
27 | function M.input(text)
28 | vim.api.nvim_put({ text }, "c", true, true)
29 | end
30 |
31 | function M.edit(filename, line)
32 | local opts = line and string.format("+%s ", line) or ""
33 | vim.api.nvim_command(string.format("edit %s%s", opts, filename))
34 | end
35 |
36 | function M.view(filename, line)
37 | local opts = line and string.format("+%s ", line) or ""
38 | vim.api.nvim_command(string.format("view %s%s", opts, filename))
39 | end
40 |
41 | function M.debug(val)
42 | print(vim.inspect(val))
43 | end
44 |
45 | function M.search(pattern)
46 | local result = vim.fn.search(pattern)
47 | if result == 0 then
48 | local info = debug.getinfo(2)
49 | local pos = ("%s:%d"):format(info.source, info.currentline)
50 | local lines = table.concat(vim.fn.getbufline("%", 1, "$"), "\n")
51 | local msg = ("on %s: `%s` not found in buffer:\n%s"):format(pos, pattern, lines)
52 | assert(false, msg)
53 | end
54 | return result
55 | end
56 |
57 | local asserts = require("vusted.assert").asserts
58 |
59 | asserts.create("filetype"):register_eq(function()
60 | return vim.bo.filetype
61 | end)
62 |
63 | asserts.create("buffer"):register_eq(function()
64 | return vim.api.nvim_buf_get_name(0)
65 | end)
66 |
67 | asserts.create("bufnr"):register_eq(function()
68 | return vim.api.nvim_get_current_buf()
69 | end)
70 |
71 | asserts.create("window"):register_eq(function()
72 | return vim.api.nvim_get_current_win()
73 | end)
74 |
75 | asserts.create("tab_count"):register_eq(function()
76 | return vim.fn.tabpagenr "$"
77 | end)
78 |
79 | asserts.create("window_count"):register_eq(function()
80 | return vim.fn.tabpagewinnr(vim.fn.tabpagenr(), "$")
81 | end)
82 |
83 | asserts.create("current_line"):register_eq(function()
84 | return vim.fn.getline "."
85 | end)
86 |
87 | asserts.create("current_col"):register_eq(function()
88 | return vim.fn.col "."
89 | end)
90 |
91 | asserts.create("current_row"):register_eq(function()
92 | return vim.fn.line "."
93 | end)
94 |
95 | asserts.create("current_word"):register_eq(function()
96 | return vim.fn.expand ""
97 | end)
98 |
99 | asserts.create("exists_pattern"):register(function(self)
100 | return function(_, args)
101 | local pattern = args[1]
102 | pattern = pattern:gsub("\n", "\\n")
103 | local result = vim.fn.search(pattern, "n")
104 | self:set_positive(("`%s` not found"):format(pattern))
105 | self:set_negative(("`%s` found"):format(pattern))
106 | return result ~= 0
107 | end
108 | end)
109 |
110 | asserts.create("exists_message"):register(function(self)
111 | return function(_, args)
112 | local expected = args[1]
113 | self:set_positive(("`%s` not found message"):format(expected))
114 | self:set_negative(("`%s` found message"):format(expected))
115 | local messages = vim.split(vim.api.nvim_exec("messages", true), "\n")
116 | for _, msg in ipairs(messages) do
117 | if msg:match(expected) then
118 | return true
119 | end
120 | end
121 | return false
122 | end
123 | end)
124 |
125 | return M
126 |
--------------------------------------------------------------------------------
/spec/init_spec.lua:
--------------------------------------------------------------------------------
1 | local helpers = require "spec.helpers"
2 |
3 | describe("nvim-test", function()
4 | after_each(helpers.after_each)
5 | before_each(helpers.before_each)
6 |
7 | it("test config", function()
8 | local nvim_test = require "nvim-test"
9 | nvim_test.setup { split = "abo split" }
10 | assert.are.equal(nvim_test.config.split, "abo split")
11 | end)
12 |
13 | it("test commands", function()
14 | assert.is_true(vim.fn.exists ":TestSuite" > 0)
15 | assert.is_true(vim.fn.exists ":TestFile" > 0)
16 | assert.is_true(vim.fn.exists ":TestNearest" > 0)
17 | assert.is_true(vim.fn.exists ":TestLast" > 0)
18 | assert.is_true(vim.fn.exists ":TestVisit" > 0)
19 | end)
20 |
21 | it("test visit", function()
22 | local filename = vim.fn.fnamemodify("spec/fixtures/test.lua", ":p")
23 | helpers.view(filename)
24 | vim.api.nvim_command "TestFile"
25 | helpers.view "unkwnown"
26 | vim.api.nvim_command "TestVisit"
27 | assert.buffer(filename)
28 | end)
29 |
30 | it("test edit", function()
31 | helpers.view "spec/fixtures/unknown.py"
32 | vim.api.nvim_command "TestEdit"
33 | assert.buffer(vim.fn.fnamemodify("spec/fixtures/test_unknown.py", ":p"))
34 | end)
35 |
36 | it("test suite", function()
37 | local filename = "spec/lua/test/fixtures/test.lua"
38 | helpers.view(filename)
39 | vim.api.nvim_command "TestFile"
40 | helpers.view "unkwnown"
41 | vim.api.nvim_command "TestSuite"
42 | assert.are.same(vim.g.test_latest.cmd, { "busted" })
43 | end)
44 | end)
45 |
--------------------------------------------------------------------------------
/spec/runner_spec.lua:
--------------------------------------------------------------------------------
1 | describe("runner", function()
2 | it("test runners", function()
3 | local nvim_test = require "nvim-test"
4 | local runner = nvim_test.get_runner "javascript"
5 | assert.are.equal(runner.config.command, "jest")
6 |
7 | nvim_test.setup { runners = { javascript = "nvim-test.runners.mocha" } }
8 | assert.are.equal(nvim_test.config.runners.javascript, "nvim-test.runners.mocha")
9 |
10 | runner = nvim_test.get_runner "javascript"
11 | assert.are.equal(runner.config.command, "mocha")
12 | end)
13 | end)
14 |
--------------------------------------------------------------------------------
/spec/runners/busted_spec.lua:
--------------------------------------------------------------------------------
1 | local helpers = require "spec.helpers"
2 |
3 | describe("busted", function()
4 | before_each(helpers.before_each)
5 | after_each(helpers.after_each)
6 |
7 | local filename = "spec/fixtures/test.lua"
8 |
9 | it("runner", function()
10 | local runner = require "nvim-test.runners.busted"
11 | assert.is.truthy(runner)
12 |
13 | assert.is_false(runner:is_testfile "somefile.lua")
14 | assert.is_true(runner:is_testfile "somefile_spec.lua")
15 | assert.is_true(runner:is_testfile "somefile_spec.moon")
16 | end)
17 |
18 | it("run suite", function()
19 | helpers.view(filename)
20 | vim.api.nvim_command "TestSuite"
21 | assert.are.same({ "busted" }, vim.g.test_latest.cmd)
22 | end)
23 |
24 | it("run file", function()
25 | helpers.view(filename)
26 | vim.api.nvim_command "TestFile"
27 | assert.are.same({ "busted", filename }, vim.g.test_latest.cmd)
28 | end)
29 |
30 | it("run nearest function", function()
31 | helpers.view(filename, 4)
32 | vim.api.nvim_command "TestNearest"
33 | assert.are.same({ "busted", filename, "--filter", "luatest test1" }, vim.g.test_latest.cmd)
34 | end)
35 |
36 | it("run latest", function()
37 | helpers.view(filename)
38 | vim.api.nvim_command "TestFile"
39 | assert.are.same(vim.g.test_latest.cmd, { "busted", filename })
40 |
41 | vim.api.nvim_command "TestLast"
42 | assert.are.same(vim.g.test_latest.cmd, { "busted", filename })
43 | end)
44 | end)
45 |
--------------------------------------------------------------------------------
/spec/runners/cargo-test_spec.lua:
--------------------------------------------------------------------------------
1 | local helpers = require "spec.helpers"
2 |
3 | describe("cargotest", function()
4 | before_each(function()
5 | helpers.before_each()
6 | vim.api.nvim_command "cd spec/fixtures/rust/crate"
7 | end)
8 | after_each(function()
9 | helpers.after_each()
10 | vim.api.nvim_command "cd -"
11 | end)
12 |
13 | it("run suite", function()
14 | helpers.view "src/main.rs"
15 | vim.api.nvim_command "TestSuite"
16 | assert.are.same(vim.g.test_latest.cmd, { "cargo", "test" })
17 | end)
18 |
19 | it("run file", function()
20 | helpers.view "src/main.rs"
21 | vim.api.nvim_command "TestFile"
22 | assert.are.same(vim.g.test_latest.cmd, { "cargo", "test" })
23 |
24 | helpers.view "src/somemod.rs"
25 | vim.api.nvim_command "TestFile"
26 | assert.are.same(vim.g.test_latest.cmd, { "cargo", "test", "somemod::" })
27 |
28 | helpers.view "src/nested/mod.rs"
29 | vim.api.nvim_command "TestFile"
30 | assert.are.same(vim.g.test_latest.cmd, { "cargo", "test", "nested::" })
31 | end)
32 |
33 | it("run nearest function", function()
34 | helpers.view("src/lib.rs", 7)
35 | assert.exists_pattern "first_test"
36 | vim.api.nvim_command "TestNearest"
37 | assert.are.same(
38 | { "cargo", "test", "tests::first_test", "--", "--exact" },
39 | vim.g.test_latest.cmd
40 | )
41 | end)
42 |
43 | it("run latest", function()
44 | helpers.view "src/main.rs"
45 | vim.api.nvim_command "TestFile"
46 | assert.are.same(vim.g.test_latest.cmd, { "cargo", "test" })
47 |
48 | vim.api.nvim_command "TestLast"
49 | assert.are.same(vim.g.test_latest.cmd, { "cargo", "test" })
50 | end)
51 | end)
52 |
--------------------------------------------------------------------------------
/spec/runners/dotnet_spec.lua:
--------------------------------------------------------------------------------
1 | local helpers = require "spec.helpers"
2 |
3 | describe("dotnet", function()
4 | before_each(helpers.before_each)
5 | after_each(helpers.after_each)
6 |
7 | local filename = "spec/fixtures/Tests.cs"
8 |
9 | it("runner", function()
10 | local runner = require "nvim-test.runners.dotnet"
11 | assert.is.truthy(runner)
12 | assert.is.equal("dotnet", runner.config.command)
13 | --
14 | assert.is_false(runner:is_testfile "somefile.cs")
15 | assert.is_true(runner:is_testfile "test/somefile.cs")
16 | assert.is_true(runner:is_testfile "Tests.cs")
17 | end)
18 |
19 | it("run suite", function()
20 | helpers.view(filename)
21 | vim.api.nvim_command "TestSuite"
22 | assert.are.same({ "dotnet", "test" }, vim.g.test_latest.cmd)
23 | end)
24 |
25 | it("run file", function()
26 | helpers.view(filename)
27 | vim.api.nvim_command "TestFile"
28 | assert.are.same({ "dotnet", "test", filename }, vim.g.test_latest.cmd)
29 | end)
30 |
31 | it("run nearest function", function()
32 | helpers.view(filename, 4)
33 | vim.api.nvim_command "TestNearest"
34 | assert.are.same(
35 | { "dotnet", "test", filename, "--filter", "FullyQualifiedName=Namespace.Tests" },
36 | vim.g.test_latest.cmd
37 | )
38 | helpers.view(filename, 8)
39 | vim.api.nvim_command "TestNearest"
40 | assert.are.same(
41 | { "dotnet", "test", filename, "--filter", "FullyQualifiedName=Namespace.Tests.Test" },
42 | vim.g.test_latest.cmd
43 | )
44 | end)
45 |
46 | it("run latest", function()
47 | helpers.view(filename)
48 | vim.api.nvim_command "TestFile"
49 | assert.are.same({ "dotnet", "test", filename }, vim.g.test_latest.cmd)
50 |
51 | vim.api.nvim_command "TestLast"
52 | assert.are.same({ "dotnet", "test", filename }, vim.g.test_latest.cmd)
53 | end)
54 | end)
55 |
--------------------------------------------------------------------------------
/spec/runners/go-test_spec.lua:
--------------------------------------------------------------------------------
1 | local helpers = require "spec.helpers"
2 |
3 | describe("gotest", function()
4 | local pwd
5 |
6 | before_each(function()
7 | helpers.before_each()
8 | pwd = vim.fn.getcwd()
9 | vim.api.nvim_command "cd spec/fixtures/go"
10 | end)
11 | after_each(function()
12 | helpers.after_each()
13 | vim.api.nvim_command("cd " .. pwd)
14 | end)
15 |
16 | local filename = "mypackage_test.go"
17 |
18 | it("run suite", function()
19 | helpers.view(filename)
20 | vim.api.nvim_command "TestSuite"
21 | assert.are.same(vim.g.test_latest.cmd, { "go", "test", "-v", "./..." })
22 | end)
23 |
24 | it("run file", function()
25 | helpers.view(filename)
26 | vim.api.nvim_command "TestFile"
27 | assert.are.same(vim.g.test_latest.cmd, { "go", "test", "-v" })
28 | end)
29 |
30 | it("run nested file", function()
31 | helpers.view(filename)
32 | vim.api.nvim_command "cd ../"
33 | vim.api.nvim_command "TestFile"
34 | assert.are.same(vim.g.test_latest.cmd, { "go", "test", "-v", "./go/..." })
35 | end)
36 |
37 | it("run nearest function", function()
38 | helpers.view(filename, 6)
39 | vim.api.nvim_command "TestNearest"
40 | assert.are.same(vim.g.test_latest.cmd, { "go", "test", "-v", "-run", "TestNumbers$" })
41 | end)
42 |
43 | it("run latest", function()
44 | helpers.view(filename)
45 | vim.api.nvim_command "TestFile"
46 | assert.are.same(vim.g.test_latest.cmd, { "go", "test", "-v" })
47 |
48 | vim.api.nvim_command "TestLast"
49 | assert.are.same(vim.g.test_latest.cmd, { "go", "test", "-v" })
50 | end)
51 | end)
52 |
--------------------------------------------------------------------------------
/spec/runners/hspec_spec.lua:
--------------------------------------------------------------------------------
1 | local helpers = require "spec.helpers"
2 |
3 | describe("hspec", function()
4 | before_each(helpers.before_each)
5 | after_each(helpers.after_each)
6 |
7 | local filename = "spec/fixtures/Spec.hs"
8 |
9 | it("run suite", function()
10 | helpers.view(filename)
11 | vim.api.nvim_command "TestSuite"
12 | assert.are.same({ "runhaskell" }, vim.g.test_latest.cmd)
13 | end)
14 |
15 | it("run file", function()
16 | helpers.view(filename)
17 | vim.api.nvim_command "TestFile"
18 | assert.are.same({ "runhaskell", filename }, vim.g.test_latest.cmd)
19 | end)
20 |
21 | it("run nearest function", function()
22 | helpers.view(filename, 16)
23 | vim.api.nvim_command "TestNearest"
24 | assert.are.same({
25 | "runhaskell",
26 | filename,
27 | "--match",
28 | "Prelude.head/nested/throws an exception if used with an empty list",
29 | }, vim.g.test_latest.cmd)
30 | end)
31 |
32 | it("run latest", function()
33 | helpers.view(filename)
34 | vim.api.nvim_command "TestFile"
35 | assert.are.same({ "runhaskell", filename }, vim.g.test_latest.cmd)
36 |
37 | vim.api.nvim_command "TestLast"
38 | assert.are.same({ "runhaskell", filename }, vim.g.test_latest.cmd)
39 | end)
40 | end)
41 |
--------------------------------------------------------------------------------
/spec/runners/init_spec.lua:
--------------------------------------------------------------------------------
1 | describe("runners", function()
2 | it("basic", function()
3 | local runners = require "nvim-test.runners"
4 | assert.is.truthy(runners)
5 | end)
6 | end)
7 |
--------------------------------------------------------------------------------
/spec/runners/jest_spec.lua:
--------------------------------------------------------------------------------
1 | -- Type: test
2 | -- @spec: jest_spec.lua
3 | -- @tags: jest
4 | -- @description: Jest test runner
5 |
6 | local helpers = require "spec.helpers"
7 |
8 | describe("jest", function()
9 | before_each(helpers.before_each)
10 | after_each(helpers.after_each)
11 |
12 | local filename = "spec/fixtures/js/name.test.js"
13 |
14 | it("runner", function()
15 | local runner = require "nvim-test.runners.jest"
16 | assert.is.truthy(runner)
17 | assert.is.equal("jest", runner.config.command)
18 |
19 | assert.is_false(runner:is_testfile "somefile.js")
20 | assert.is_true(runner:is_testfile "somefile.spec.js")
21 | assert.is_true(runner:is_testfile "somefile.test.js")
22 | assert.is_true(runner:is_testfile "__tests__/somefile.js")
23 |
24 | assert.is.equal("spec/fixtures/js/name.test.js", runner:find_file "spec/fixtures/js/name.js")
25 | end)
26 |
27 | it("run suite", function()
28 | helpers.view(filename)
29 | vim.api.nvim_command "TestSuite"
30 | assert.are.same({ "jest" }, vim.g.test_latest.cmd)
31 | end)
32 |
33 | it("run file", function()
34 | helpers.view(filename)
35 | vim.api.nvim_command "TestFile"
36 | assert.are.same({ "jest", filename }, vim.g.test_latest.cmd)
37 | end)
38 |
39 | it("run nearest function", function()
40 | helpers.view(filename, 4)
41 | vim.api.nvim_command "TestNearest"
42 | assert.are.same({ "jest", filename, "-t", "^jstest ns test1$" }, vim.g.test_latest.cmd)
43 | helpers.view(filename, 6)
44 | vim.api.nvim_command "TestNearest"
45 | assert.are.same({ "jest", filename, "-t", "^jstest ns test1$" }, vim.g.test_latest.cmd)
46 | end)
47 |
48 | it("run latest", function()
49 | helpers.view(filename)
50 | vim.api.nvim_command "TestFile"
51 | assert.are.same({ "jest", filename }, vim.g.test_latest.cmd)
52 |
53 | vim.api.nvim_command "TestLast"
54 | assert.are.same({ "jest", filename }, vim.g.test_latest.cmd)
55 | end)
56 | end)
57 |
--------------------------------------------------------------------------------
/spec/runners/mocha_spec.lua:
--------------------------------------------------------------------------------
1 | local helpers = require "spec.helpers"
2 |
3 | describe("mocha", function()
4 | before_each(function()
5 | helpers.before_each { run = false, runners = { javascript = "nvim-test.runners.mocha" } }
6 | end)
7 | after_each(helpers.after_each)
8 |
9 | local filename = "spec/fixtures/js/name.test.js"
10 |
11 | it("runner", function()
12 | local runner = require "nvim-test.runners.mocha"
13 | assert.is.truthy(runner)
14 |
15 | assert.is_false(runner:is_testfile "somefile.js")
16 | assert.is_true(runner:is_testfile "somefile.test.js")
17 | assert.is_true(runner:is_testfile "test/somefile.js")
18 | end)
19 |
20 | it("run suite", function()
21 | helpers.view(filename)
22 | vim.api.nvim_command "TestSuite"
23 | assert.are.same(vim.g.test_latest.cmd, { "mocha" })
24 | end)
25 |
26 | it("run file", function()
27 | helpers.view(filename)
28 | vim.api.nvim_command "TestFile"
29 | assert.are.same(vim.g.test_latest.cmd, { "mocha", filename })
30 | end)
31 |
32 | it("run nearest function", function()
33 | helpers.view(filename, 4)
34 | vim.api.nvim_command "TestNearest"
35 | assert.are.same(vim.g.test_latest.cmd, { "mocha", filename, "-f", "jstest ns test1" })
36 | end)
37 |
38 | it("run latest", function()
39 | helpers.view(filename)
40 | vim.api.nvim_command "TestFile"
41 | assert.are.same(vim.g.test_latest.cmd, { "mocha", filename })
42 |
43 | vim.api.nvim_command "TestLast"
44 | assert.are.same(vim.g.test_latest.cmd, { "mocha", filename })
45 | end)
46 | end)
47 |
--------------------------------------------------------------------------------
/spec/runners/pytest_spec.lua:
--------------------------------------------------------------------------------
1 | local helpers = require "spec.helpers"
2 |
3 | describe("pytest", function()
4 | before_each(helpers.before_each)
5 | after_each(helpers.after_each)
6 |
7 | local filename = "spec/fixtures/test.py"
8 |
9 | it("runner", function()
10 | local runner = require "nvim-test.runners.pytest"
11 | assert.is.truthy(runner)
12 | assert.is.equal("pytest", runner.config.command)
13 |
14 | assert.is_false(runner:is_testfile "somefile.py")
15 | assert.is_true(runner:is_testfile "somefile_test.py")
16 | assert.is_true(runner:is_testfile "test_somefile.py")
17 | assert.is_true(runner:is_testfile "tests.py")
18 | end)
19 |
20 | it("run suite", function()
21 | helpers.view(filename)
22 | vim.api.nvim_command "TestSuite"
23 | assert.are.same(vim.g.test_latest.cmd, { "pytest" })
24 | end)
25 |
26 | it("run file", function()
27 | helpers.view(filename)
28 | vim.api.nvim_command "TestFile"
29 | assert.are.same(vim.g.test_latest.cmd, { "pytest", filename })
30 | end)
31 |
32 | it("run nearest function", function()
33 | helpers.view(filename, 4)
34 | vim.api.nvim_command "TestNearest"
35 | assert.are.same(vim.g.test_latest.cmd, { "pytest", filename .. "::test_base" })
36 | end)
37 |
38 | it("run nearest method", function()
39 | helpers.view(filename, 13)
40 | vim.api.nvim_command "TestNearest"
41 | assert.are.same(vim.g.test_latest.cmd, { "pytest", filename .. "::MyTest::test_method2" })
42 | end)
43 |
44 | it("run latest", function()
45 | helpers.view(filename)
46 | vim.api.nvim_command "TestFile"
47 | assert.are.same(vim.g.test_latest.cmd, { "pytest", filename })
48 |
49 | vim.api.nvim_command "TestLast"
50 | assert.are.same(vim.g.test_latest.cmd, { "pytest", filename })
51 | end)
52 |
53 | it("setup args", function()
54 | require("nvim-test.runners.pytest"):setup { args = { "-v" } }
55 | helpers.view(filename)
56 | vim.api.nvim_command "TestFile"
57 | assert.are.same(vim.g.test_latest.cmd, { "pytest", "-v", filename })
58 | end)
59 | end)
60 |
--------------------------------------------------------------------------------
/spec/runners/pyunit_spec.lua:
--------------------------------------------------------------------------------
1 | local helpers = require "spec.helpers"
2 |
3 | describe("pyunit", function()
4 | before_each(function()
5 | helpers.before_each { run = false, runners = { python = "nvim-test.runners.pyunit" } }
6 | end)
7 | after_each(helpers.after_each)
8 |
9 | local filename = "spec/fixtures/test.py"
10 |
11 | it("runner", function()
12 | local runner = require "nvim-test.runners.pyunit"
13 | assert.is.truthy(runner)
14 |
15 | assert.is_false(runner:is_testfile "somefile.py")
16 | assert.is_true(runner:is_testfile "test_somefile.py")
17 | end)
18 |
19 | it("run suite", function()
20 | helpers.view(filename)
21 | vim.api.nvim_command "TestSuite"
22 | assert.are.same(vim.g.test_latest.cmd, { "python", "-m", "unittest" })
23 | end)
24 |
25 | it("run file", function()
26 | helpers.view(filename)
27 | vim.api.nvim_command "TestFile"
28 | assert.are.same(vim.g.test_latest.cmd, { "python", "-m", "unittest", "spec.fixtures.test" })
29 | end)
30 |
31 | it("run nearest function", function()
32 | helpers.view(filename, 4)
33 | vim.api.nvim_command "TestNearest"
34 | assert.are.same(
35 | vim.g.test_latest.cmd,
36 | { "python", "-m", "unittest", "spec.fixtures.test.test_base" }
37 | )
38 | end)
39 |
40 | it("run nearest method", function()
41 | helpers.view(filename, 13)
42 | vim.api.nvim_command "TestNearest"
43 | assert.are.same(
44 | vim.g.test_latest.cmd,
45 | { "python", "-m", "unittest", "spec.fixtures.test.MyTest.test_method2" }
46 | )
47 | end)
48 |
49 | it("run latest", function()
50 | helpers.view(filename)
51 | vim.api.nvim_command "TestFile"
52 | assert.are.same(vim.g.test_latest.cmd, { "python", "-m", "unittest", "spec.fixtures.test" })
53 |
54 | vim.api.nvim_command "TestLast"
55 | assert.are.same(vim.g.test_latest.cmd, { "python", "-m", "unittest", "spec.fixtures.test" })
56 | end)
57 | end)
58 |
--------------------------------------------------------------------------------
/spec/runners/rspec_spec.lua:
--------------------------------------------------------------------------------
1 | local helpers = require "spec.helpers"
2 |
3 | describe("rspec", function()
4 | before_each(helpers.before_each)
5 | after_each(helpers.after_each)
6 |
7 | local filename = "spec/fixtures/test_spec.rb"
8 |
9 | it("run suite", function()
10 | helpers.view(filename)
11 | vim.api.nvim_command "TestSuite"
12 | assert.are.same({ "bundle", "exec", "rspec" }, vim.g.test_latest.cmd)
13 | end)
14 |
15 | it("run file", function()
16 | helpers.view(filename)
17 | vim.api.nvim_command "TestFile"
18 | assert.are.same({ "bundle", "exec", "rspec", filename }, vim.g.test_latest.cmd)
19 | end)
20 |
21 | it("run nearest function", function()
22 | helpers.view(filename, 4)
23 | vim.api.nvim_command "TestNearest"
24 | assert.are.same({
25 | "bundle",
26 | "exec",
27 | "rspec",
28 | filename,
29 | "--example",
30 | "#score returns 0 for an all gutter game",
31 | }, vim.g.test_latest.cmd)
32 | end)
33 |
34 | it("run latest", function()
35 | helpers.view(filename)
36 | vim.api.nvim_command "TestFile"
37 | assert.are.same({ "bundle", "exec", "rspec", filename }, vim.g.test_latest.cmd)
38 |
39 | vim.api.nvim_command "TestLast"
40 | assert.are.same({ "bundle", "exec", "rspec", filename }, vim.g.test_latest.cmd)
41 | end)
42 | end)
43 |
--------------------------------------------------------------------------------
/spec/runners/stack_spec.lua:
--------------------------------------------------------------------------------
1 | local helpers = require "spec.helpers"
2 |
3 | describe("hspec", function()
4 | before_each(function()
5 | helpers.before_each { run = false, runners = { haskell = "nvim-test.runners.stack" } }
6 | end)
7 | after_each(helpers.after_each)
8 |
9 | local filename = "spec/fixtures/Spec.hs"
10 |
11 | it("run suite", function()
12 | helpers.view(filename)
13 | vim.api.nvim_command "TestSuite"
14 | assert.are.same({ "stack", "test" }, vim.g.test_latest.cmd)
15 | end)
16 |
17 | it("run file", function()
18 | helpers.view(filename)
19 | vim.api.nvim_command "TestFile"
20 | assert.are.same({ "stack", "test", filename }, vim.g.test_latest.cmd)
21 | end)
22 |
23 | it("run nearest function", function()
24 | helpers.view(filename, 16)
25 | vim.api.nvim_command "TestNearest"
26 | assert.are.same({
27 | "stack",
28 | "test",
29 | filename,
30 | "--test-arguments='--match \"Prelude.head/nested/throws an exception if used with an empty list\"'",
31 | }, vim.g.test_latest.cmd)
32 | end)
33 |
34 | it("run latest", function()
35 | helpers.view(filename)
36 | vim.api.nvim_command "TestFile"
37 | assert.are.same({ "stack", "test", filename }, vim.g.test_latest.cmd)
38 |
39 | vim.api.nvim_command "TestLast"
40 | assert.are.same({ "stack", "test", filename }, vim.g.test_latest.cmd)
41 | end)
42 | end)
43 |
--------------------------------------------------------------------------------
/spec/runners/ts-mocha_spec.lua:
--------------------------------------------------------------------------------
1 | local helpers = require "spec.helpers"
2 |
3 | describe("tsmocha", function()
4 | before_each(function()
5 | helpers.before_each { run = false, runners = { typescript = "nvim-test.runners.ts-mocha" } }
6 | end)
7 | after_each(helpers.after_each)
8 |
9 | local filename = "spec/fixtures/test.ts"
10 |
11 | it("run suite", function()
12 | helpers.view(filename)
13 | vim.api.nvim_command "TestSuite"
14 | assert.are.same(vim.g.test_latest.cmd, { "ts-mocha" })
15 | end)
16 |
17 | it("run file", function()
18 | helpers.view(filename)
19 | vim.api.nvim_command "TestFile"
20 | assert.are.same(vim.g.test_latest.cmd, { "ts-mocha", filename })
21 | end)
22 |
23 | it("run nearest function", function()
24 | helpers.view(filename, 4)
25 | vim.api.nvim_command "TestNearest"
26 | assert.are.same(vim.g.test_latest.cmd, { "ts-mocha", filename, "-f", "tstest ns test1" })
27 | end)
28 |
29 | it("run latest", function()
30 | helpers.view(filename)
31 | vim.api.nvim_command "TestFile"
32 | assert.are.same(vim.g.test_latest.cmd, { "ts-mocha", filename })
33 |
34 | vim.api.nvim_command "TestLast"
35 | assert.are.same(vim.g.test_latest.cmd, { "ts-mocha", filename })
36 | end)
37 | end)
38 |
--------------------------------------------------------------------------------
/spec/runners/vusted_spec.lua:
--------------------------------------------------------------------------------
1 | local helpers = require "spec.helpers"
2 |
3 | describe("vusted", function()
4 | before_each(function()
5 | helpers.before_each { run = false, runners = { lua = "nvim-test.runners.vusted" } }
6 | end)
7 | after_each(helpers.after_each)
8 |
9 | require("nvim-test").setup { runners = { lua = "nvim-test.runners.vusted" } }
10 |
11 | local filename = "spec/fixtures/test.lua"
12 |
13 | it("runner", function()
14 | local runner = require "nvim-test.runners.vusted"
15 | assert.is.truthy(runner)
16 |
17 | assert.is_false(runner:is_testfile "somefile.lua")
18 | assert.is_true(runner:is_testfile "somefile_spec.lua")
19 | assert.is_true(runner:is_testfile "somefile_spec.moon")
20 | end)
21 |
22 | it("run suite", function()
23 | helpers.view(filename)
24 | vim.api.nvim_command "TestSuite"
25 | assert.are.same({ "vusted" }, vim.g.test_latest.cmd)
26 | end)
27 |
28 | it("run file", function()
29 | helpers.view(filename)
30 | vim.api.nvim_command "TestFile"
31 | assert.are.same({ "vusted", filename }, vim.g.test_latest.cmd)
32 | end)
33 |
34 | it("run nearest function", function()
35 | helpers.view(filename, 4)
36 | vim.api.nvim_command "TestNearest"
37 | assert.are.same({ "vusted", filename, "--filter", "luatest test1" }, vim.g.test_latest.cmd)
38 | end)
39 |
40 | it("run latest", function()
41 | helpers.view(filename)
42 | vim.api.nvim_command "TestFile"
43 | assert.are.same({ "vusted", filename }, vim.g.test_latest.cmd)
44 |
45 | vim.api.nvim_command "TestLast"
46 | assert.are.same({ "vusted", filename }, vim.g.test_latest.cmd)
47 | end)
48 | end)
49 |
--------------------------------------------------------------------------------
/spec/runners/zig_spec.lua:
--------------------------------------------------------------------------------
1 | local helpers = require("spec.helpers")
2 |
3 | describe("zigtest", function()
4 | before_each(function()
5 | helpers.before_each()
6 | vim.api.nvim_command("cd spec/fixtures/zig")
7 | end)
8 | after_each(function()
9 | helpers.after_each()
10 | vim.api.nvim_command("cd -")
11 | end)
12 |
13 | it("run suite", function()
14 | helpers.view("src/main.zig")
15 | vim.api.nvim_command("TestSuite")
16 | assert.are.same(vim.g.test_latest.cmd, { "zig", "build", "test" })
17 | end)
18 |
19 | it("run file", function()
20 | helpers.view("src/main.zig")
21 | vim.api.nvim_command("TestFile")
22 | assert.are.same(vim.g.test_latest.cmd, { "zig", "test", "src/main.zig" })
23 |
24 | helpers.view("src/somemod.zig")
25 | vim.api.nvim_command("TestFile")
26 | assert.are.same(vim.g.test_latest.cmd, { "zig", "test", "src/somemod.zig" })
27 |
28 | helpers.view("src/nested/mod.zig")
29 | vim.api.nvim_command("TestFile")
30 | assert.are.same(vim.g.test_latest.cmd, { "zig", "test", "src/nested/mod.zig" })
31 | end)
32 |
33 | it("run nearest function", function()
34 | helpers.view("src/main.zig", 8)
35 | -- assert.exists_pattern("first_test")
36 | vim.api.nvim_command("TestNearest")
37 | assert.are.same(
38 | { "zig", "test", "src/main.zig", "--test-filter", "basic add functionality" },
39 | vim.g.test_latest.cmd
40 | )
41 | end)
42 |
43 | it("run latest", function()
44 | helpers.view("src/main.zig")
45 | vim.api.nvim_command("TestFile")
46 | assert.are.same(vim.g.test_latest.cmd, { "zig", "test", "src/main.zig" })
47 |
48 | vim.api.nvim_command("TestLast")
49 | assert.are.same(vim.g.test_latest.cmd, { "zig", "test", "src/main.zig" })
50 | end)
51 | end)
52 |
--------------------------------------------------------------------------------
/spec/utils_spec.lua:
--------------------------------------------------------------------------------
1 | describe("utils", function()
2 | local utils = require "nvim-test.utils"
3 | it("find file by patterns", function()
4 | assert.is.equal(
5 | "spec/fixtures/js/name.test.js",
6 | utils.find_file_by_patterns(
7 | "spec/fixtures/js/name.js",
8 | { "{name}.spec.{ext}", "{name}.test.{ext}" }
9 | )
10 | )
11 | assert.is.equal(
12 | "spec/fixtures/js/unknown.js",
13 | utils.find_file_by_patterns(
14 | "spec/fixtures/js/unknown.js",
15 | { "{name}.spec.{ext}", "{name}.test.{ext}" }
16 | )
17 | )
18 | assert.is.equal(
19 | "spec/fixtures/js/unknown.spec.js",
20 | utils.find_file_by_patterns(
21 | "spec/fixtures/js/unknown.js",
22 | { "{name}.spec.{ext}", "{name}.test.{ext}" },
23 | true
24 | )
25 | )
26 | end)
27 | end)
28 |
--------------------------------------------------------------------------------