Skip to content

Commit 37b6756

Browse files
authored
feat: add test suite and CI workflow (#9)
- Add integration test suite covering storage, utils, and core functionality - Add GitHub Actions workflow to run tests on PRs and main branch pushes Fix missing current_buffer variable in UI module for proper buffer tracking
1 parent 18cd98a commit 37b6756

File tree

3 files changed

+209
-0
lines changed

3 files changed

+209
-0
lines changed

.github/workflows/test.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Test
2+
3+
on:
4+
pull_request:
5+
branches: [ main ]
6+
push:
7+
branches: [ main ]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Install Neovim
17+
uses: rhysd/action-setup-vim@v1
18+
with:
19+
neovim: true
20+
version: stable
21+
22+
- name: Run tests
23+
run: nvim --headless -c "luafile tests/integration_test.lua" -c "qa!"

lua/marksman/ui.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ local M = {}
33

44
local config = {}
55
local current_window = nil
6+
local current_buffer = nil
67

78
-- Helper function for conditional notifications
89
local function notify(message, level)

tests/integration_test.lua

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
-- Set up runtime path for the plugin
2+
vim.opt.runtimepath:prepend(".")
3+
package.path = package.path .. ";./lua/?.lua;./lua/?/init.lua"
4+
5+
local abs_path = vim.fn.getcwd() .. "/lua"
6+
package.path = package.path .. ";" .. abs_path .. "/?.lua;" .. abs_path .. "/?/init.lua"
7+
8+
local test_count = 0
9+
local pass_count = 0
10+
11+
local function test(name, func)
12+
test_count = test_count + 1
13+
local ok, err = pcall(func)
14+
if ok then
15+
pass_count = pass_count + 1
16+
print("" .. name)
17+
else
18+
print("" .. name .. ": " .. tostring(err))
19+
end
20+
end
21+
22+
local function assert_eq(actual, expected, msg)
23+
if actual ~= expected then
24+
error(msg or string.format("Expected %s, got %s", tostring(expected), tostring(actual)))
25+
end
26+
end
27+
28+
local function assert_true(condition, msg)
29+
if not condition then
30+
error(msg or "Expected true")
31+
end
32+
end
33+
34+
-- Set up isolated test environment
35+
local function setup_test()
36+
local temp_dir = vim.fn.tempname() .. "_test"
37+
vim.fn.mkdir(temp_dir, "p")
38+
vim.fn.mkdir(temp_dir .. "/.git", "p")
39+
40+
local original_cwd = vim.fn.getcwd()
41+
vim.cmd("cd " .. temp_dir)
42+
43+
-- Clear module cache
44+
for name, _ in pairs(package.loaded) do
45+
if name:match("^marksman") then
46+
package.loaded[name] = nil
47+
end
48+
end
49+
50+
return temp_dir, original_cwd
51+
end
52+
53+
local function cleanup_test(temp_dir, original_cwd)
54+
vim.cmd("cd " .. original_cwd)
55+
vim.fn.delete(temp_dir, "rf")
56+
end
57+
58+
-- Core functionality tests
59+
print("Running Marksman.nvim tests...")
60+
61+
-- Storage tests
62+
local temp_dir, original_cwd = setup_test()
63+
64+
test("storage basic operations", function()
65+
local storage = require("marksman.storage")
66+
storage.setup({ auto_save = true, silent = true })
67+
68+
-- Should start empty
69+
assert_eq(storage.get_marks_count(), 0, "Should start with 0 marks")
70+
71+
-- Add mark
72+
local mark = { file = temp_dir .. "/test.lua", line = 10, col = 5, text = "test" }
73+
assert_true(storage.add_mark("test", mark), "Should add mark")
74+
assert_eq(storage.get_marks_count(), 1, "Should have 1 mark")
75+
76+
-- Get marks
77+
local marks = storage.get_marks()
78+
assert_true(marks["test"] ~= nil, "Mark should exist")
79+
assert_eq(marks["test"].line, 10, "Line should match")
80+
end)
81+
82+
test("storage delete and rename", function()
83+
-- Force fresh storage instance
84+
package.loaded["marksman.storage"] = nil
85+
local storage = require("marksman.storage")
86+
storage.setup({ auto_save = true, silent = true })
87+
88+
-- Ensure clean state
89+
storage.clear_all_marks()
90+
91+
local mark = { file = temp_dir .. "/test.lua", line = 5, col = 1, text = "test" }
92+
storage.add_mark("delete_me", mark)
93+
94+
assert_eq(storage.get_marks_count(), 1, "Should have 1 mark before delete")
95+
assert_true(storage.delete_mark("delete_me"), "Should delete mark")
96+
assert_eq(storage.get_marks_count(), 0, "Should be empty after delete")
97+
98+
storage.add_mark("old_name", mark)
99+
assert_true(storage.rename_mark("old_name", "new_name"), "Should rename mark")
100+
101+
local marks = storage.get_marks()
102+
assert_true(marks["new_name"] ~= nil, "New name should exist")
103+
assert_true(marks["old_name"] == nil, "Old name should not exist")
104+
end)
105+
106+
cleanup_test(temp_dir, original_cwd)
107+
108+
-- Utils tests
109+
test("utils mark name generation", function()
110+
local utils = require("marksman.utils")
111+
112+
-- Mock vim functions
113+
local orig_getline = vim.fn.getline
114+
local orig_fnamemodify = vim.fn.fnamemodify
115+
116+
vim.fn.getline = function()
117+
return "function test_func()"
118+
end
119+
vim.fn.fnamemodify = function(path, mod)
120+
if mod == ":t:r" then
121+
return "testfile"
122+
end
123+
if mod == ":e" then
124+
return "lua"
125+
end
126+
return path
127+
end
128+
129+
local name = utils.generate_mark_name("/test.lua", 10)
130+
assert_true(name:match("fn:test_func") or name:match("testfile"), "Should generate appropriate name")
131+
132+
vim.fn.getline = orig_getline
133+
vim.fn.fnamemodify = orig_fnamemodify
134+
end)
135+
136+
test("utils mark filtering", function()
137+
local utils = require("marksman.utils")
138+
139+
local marks = {
140+
api_func = { file = "/api.lua", line = 1, col = 1, text = "api function" },
141+
user_model = { file = "/user.lua", line = 2, col = 1, text = "user model" },
142+
}
143+
144+
local filtered = utils.filter_marks(marks, "api")
145+
assert_eq(vim.tbl_count(filtered), 1, "Should find 1 mark")
146+
assert_true(filtered["api_func"] ~= nil, "Should find api_func")
147+
end)
148+
149+
-- Main module tests
150+
temp_dir, original_cwd = setup_test()
151+
152+
test("marksman basic workflow", function()
153+
local marksman = require("marksman")
154+
marksman.setup({ auto_save = true, silent = true })
155+
156+
-- Create test file
157+
local test_file = temp_dir .. "/test.lua"
158+
vim.fn.writefile({ "local function test()", " return true", "end" }, test_file)
159+
160+
vim.cmd("edit " .. test_file)
161+
vim.fn.cursor(1, 1)
162+
163+
assert_true(marksman.add_mark("test_mark"), "Should add mark")
164+
assert_eq(marksman.get_marks_count(), 1, "Should have 1 mark")
165+
166+
assert_true(marksman.goto_mark("test_mark"), "Should go to mark")
167+
assert_eq(vim.fn.line("."), 1, "Should be on correct line")
168+
169+
assert_true(marksman.delete_mark("test_mark"), "Should delete mark")
170+
assert_eq(marksman.get_marks_count(), 0, "Should be empty")
171+
end)
172+
173+
cleanup_test(temp_dir, original_cwd)
174+
175+
-- Ensure we're back in the original directory
176+
vim.cmd("cd " .. vim.fn.expand("~"))
177+
178+
-- Report results
179+
print(string.format("\nResults: %d/%d tests passed", pass_count, test_count))
180+
if pass_count == test_count then
181+
print("All tests passed!")
182+
else
183+
print(string.format("%d tests failed", test_count - pass_count))
184+
os.exit(1)
185+
end

0 commit comments

Comments
 (0)