Skip to content

Commit dcc4abf

Browse files
authored
Merge pull request #148 from FluxxField/dev
test: comprehensive integration test suite (470 tests)
2 parents 59746e4 + 790dd3a commit dcc4abf

47 files changed

Lines changed: 11444 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/test.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Tests
2+
on:
3+
push:
4+
branches: [master, dev]
5+
pull_request:
6+
branches: [master, dev]
7+
8+
jobs:
9+
test:
10+
runs-on: ubuntu-latest
11+
strategy:
12+
matrix:
13+
nvim-version: ['v0.10.4', 'stable', 'nightly']
14+
steps:
15+
- uses: actions/checkout@v4
16+
- uses: rhysd/action-setup-vim@v1
17+
with:
18+
neovim: true
19+
version: ${{ matrix.nvim-version }}
20+
- name: Run tests
21+
run: make test

CLAUDE.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Claude Code Instructions
2+
3+
## Git Commits
4+
- Never add `Co-Authored-By` lines to commit messages
5+
- The commit author should always be the repository owner

Makefile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
NVIM ?= nvim
2+
3+
.PHONY: test test-file
4+
5+
test:
6+
$(NVIM) --headless -u tests/run_tests.lua
7+
8+
test-file:
9+
$(NVIM) --headless -u tests/run_tests.lua -- $(FILE)

deps/mini_test.lua

Lines changed: 2489 additions & 0 deletions
Large diffs are not rendered by default.

tests/helpers.lua

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
-- Shared test utilities for smart-motion.nvim integration tests
2+
3+
local M = {}
4+
5+
--- Default test config that disables timing-dependent features
6+
M.test_config = {
7+
keys = "fjdksleirughtynm",
8+
flow_state_timeout_ms = 0,
9+
native_search = false,
10+
auto_select_target = false,
11+
dim_background = false,
12+
presets = {},
13+
}
14+
15+
--- Setup the plugin with optional config overrides
16+
---@param overrides? table
17+
function M.setup_plugin(overrides)
18+
local config = vim.tbl_deep_extend("force", vim.deepcopy(M.test_config), overrides or {})
19+
require("smart-motion").setup(config)
20+
end
21+
22+
--- Create a scratch buffer with the given lines and set it as current
23+
---@param lines string[]
24+
---@return integer bufnr
25+
function M.create_buf(lines)
26+
local bufnr = vim.api.nvim_create_buf(false, true)
27+
vim.api.nvim_set_current_buf(bufnr)
28+
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines)
29+
vim.bo[bufnr].filetype = "text"
30+
return bufnr
31+
end
32+
33+
--- Set cursor position (1-indexed row, 0-indexed col)
34+
---@param row integer
35+
---@param col integer
36+
function M.set_cursor(row, col)
37+
vim.api.nvim_win_set_cursor(0, { row, col })
38+
end
39+
40+
--- Get cursor position (1-indexed row, 0-indexed col)
41+
---@return integer row, integer col
42+
function M.get_cursor()
43+
local pos = vim.api.nvim_win_get_cursor(0)
44+
return pos[1], pos[2]
45+
end
46+
47+
--- Get the contents of a register
48+
---@param reg string
49+
---@return string
50+
function M.get_register(reg)
51+
return vim.fn.getreg(reg)
52+
end
53+
54+
--- Get all lines from the current buffer
55+
---@return string[]
56+
function M.get_buf_lines()
57+
return vim.api.nvim_buf_get_lines(0, 0, -1, false)
58+
end
59+
60+
--- Build a minimal SmartMotionContext
61+
---@param overrides? table
62+
---@return SmartMotionContext
63+
function M.build_ctx(overrides)
64+
local bufnr = vim.api.nvim_get_current_buf()
65+
local winid = vim.api.nvim_get_current_win()
66+
local cursor = vim.api.nvim_win_get_cursor(winid)
67+
local last_line = vim.api.nvim_buf_line_count(bufnr)
68+
69+
local ctx = {
70+
bufnr = bufnr,
71+
winid = winid,
72+
cursor_line = cursor[1] - 1, -- 0-indexed
73+
cursor_col = cursor[2],
74+
last_line = last_line,
75+
}
76+
77+
if overrides then
78+
ctx = vim.tbl_extend("force", ctx, overrides)
79+
end
80+
81+
return ctx
82+
end
83+
84+
--- Clean up all scratch buffers and reset plugin state
85+
function M.cleanup()
86+
-- Delete all scratch buffers
87+
for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do
88+
if vim.api.nvim_buf_is_valid(bufnr) then
89+
pcall(vim.api.nvim_buf_delete, bufnr, { force = true })
90+
end
91+
end
92+
93+
-- Clear relevant package.loaded entries for fresh state between test files
94+
for key, _ in pairs(package.loaded) do
95+
if key:match("^smart%-motion") then
96+
package.loaded[key] = nil
97+
end
98+
end
99+
end
100+
101+
return M

tests/run_tests.lua

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
-- Test runner entry point
2+
-- Usage: nvim --headless -u tests/run_tests.lua
3+
-- Or: make test
4+
5+
-- Determine project root from this script's location
6+
local this_file = debug.getinfo(1, "S").source:sub(2)
7+
local project_root = vim.fn.fnamemodify(this_file, ":h:h")
8+
9+
-- Add project to runtimepath so require("smart-motion") works
10+
vim.opt.runtimepath:prepend(project_root)
11+
12+
-- Add deps/ to package.path so require("mini_test") works
13+
package.path = project_root .. "/deps/?.lua;" .. package.path
14+
15+
-- Disable swap files and shada for test isolation
16+
vim.o.swapfile = false
17+
vim.o.shadafile = "NONE"
18+
19+
-- Load mini.test
20+
local MiniTest = require("mini_test")
21+
22+
-- Collect test files: all tests/test_*.lua files
23+
local test_dir = project_root .. "/tests"
24+
local test_files = {}
25+
26+
-- Check if a specific file was passed via command line args
27+
local cli_file = nil
28+
for i, arg in ipairs(vim.v.argv) do
29+
if arg == "--" and vim.v.argv[i + 1] then
30+
cli_file = vim.v.argv[i + 1]
31+
break
32+
end
33+
end
34+
35+
if cli_file then
36+
table.insert(test_files, test_dir .. "/" .. cli_file)
37+
else
38+
local files = vim.fn.glob(test_dir .. "/test_*.lua", false, true)
39+
table.sort(files)
40+
test_files = files
41+
end
42+
43+
-- Run tests with stdout reporter for headless
44+
MiniTest.setup({
45+
collect = {
46+
find_files = function()
47+
return test_files
48+
end,
49+
},
50+
script_path = this_file,
51+
})
52+
53+
MiniTest.run()

0 commit comments

Comments
 (0)