Skip to content

Commit 4aaee05

Browse files
committed
test(tests): add missing unit tests for autocmds, highlights, toggle
1 parent 02db162 commit 4aaee05

3 files changed

Lines changed: 426 additions & 0 deletions

File tree

tests/test_autocmds.lua

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
local H = require("tests.helpers")
2+
local MiniTest = require("mini.test")
3+
local autocmds = require("tiny-inline-diagnostic.autocmds")
4+
5+
local T = MiniTest.new_set()
6+
7+
local function noop() end
8+
9+
local function make_buf_opts()
10+
return H.make_opts({
11+
options = {
12+
enable_on_insert = false,
13+
experimental = { use_window_local_extmarks = false },
14+
},
15+
})
16+
end
17+
18+
local function count_buffer_autocmds(augroup, bufnr)
19+
return #vim.api.nvim_get_autocmds({ group = augroup, buffer = bufnr })
20+
end
21+
22+
local function count_event_autocmds(augroup, event)
23+
return #vim.api.nvim_get_autocmds({ group = augroup, event = event })
24+
end
25+
26+
T["detach"] = MiniTest.new_set()
27+
28+
T["detach"]["clears buffer-scoped autocmds"] = function()
29+
H.with_buf({ "line" }, function(buf)
30+
local augroup = autocmds.create_augroup()
31+
autocmds.setup_buffer_autocmds(augroup, make_buf_opts(), buf, noop, noop, noop, noop)
32+
autocmds.setup_cursor_autocmds(augroup, make_buf_opts(), buf, noop, noop)
33+
autocmds.setup_mode_change_autocmds(augroup, buf, noop)
34+
35+
MiniTest.expect.equality(count_buffer_autocmds(augroup, buf) > 0, true)
36+
MiniTest.expect.equality(autocmds.is_attached(buf), true)
37+
38+
autocmds.detach(buf)
39+
40+
MiniTest.expect.equality(count_buffer_autocmds(augroup, buf), 0)
41+
MiniTest.expect.equality(autocmds.is_attached(buf), false)
42+
end)
43+
end
44+
45+
T["detach"]["invokes cleanup_callback with bufnr"] = function()
46+
H.with_buf({ "line" }, function(buf)
47+
autocmds.create_augroup()
48+
49+
local received
50+
autocmds.detach(buf, function(b)
51+
received = b
52+
end)
53+
54+
MiniTest.expect.equality(received, buf)
55+
end)
56+
end
57+
58+
T["setup_buffer_autocmds"] = MiniTest.new_set()
59+
60+
T["setup_buffer_autocmds"]["re-attach after detach does not duplicate autocmds"] = function()
61+
H.with_buf({ "line" }, function(buf)
62+
local augroup = autocmds.create_augroup()
63+
local opts = make_buf_opts()
64+
65+
autocmds.setup_buffer_autocmds(augroup, opts, buf, noop, noop, noop, noop)
66+
autocmds.setup_cursor_autocmds(augroup, opts, buf, noop, noop)
67+
autocmds.setup_mode_change_autocmds(augroup, buf, noop)
68+
local first_count = count_buffer_autocmds(augroup, buf)
69+
70+
autocmds.detach(buf)
71+
MiniTest.expect.equality(count_buffer_autocmds(augroup, buf), 0)
72+
73+
autocmds.setup_buffer_autocmds(augroup, opts, buf, noop, noop, noop, noop)
74+
autocmds.setup_cursor_autocmds(augroup, opts, buf, noop, noop)
75+
autocmds.setup_mode_change_autocmds(augroup, buf, noop)
76+
local second_count = count_buffer_autocmds(augroup, buf)
77+
78+
MiniTest.expect.equality(second_count, first_count)
79+
end)
80+
end
81+
82+
T["setup_buffer_autocmds"]["guards against double setup without detach"] = function()
83+
H.with_buf({ "line" }, function(buf)
84+
local augroup = autocmds.create_augroup()
85+
local opts = make_buf_opts()
86+
87+
autocmds.setup_buffer_autocmds(augroup, opts, buf, noop, noop, noop, noop)
88+
local first_count = count_buffer_autocmds(augroup, buf)
89+
90+
autocmds.setup_buffer_autocmds(augroup, opts, buf, noop, noop, noop, noop)
91+
local second_count = count_buffer_autocmds(augroup, buf)
92+
93+
MiniTest.expect.equality(second_count, first_count)
94+
end)
95+
end
96+
97+
T["setup_buffer_autocmds"]["multiple attach/detach cycles do not leak autocmds"] = function()
98+
H.with_buf({ "line" }, function(buf)
99+
local augroup = autocmds.create_augroup()
100+
local opts = make_buf_opts()
101+
102+
autocmds.setup_buffer_autocmds(augroup, opts, buf, noop, noop, noop, noop)
103+
autocmds.setup_cursor_autocmds(augroup, opts, buf, noop, noop)
104+
autocmds.setup_mode_change_autocmds(augroup, buf, noop)
105+
local baseline = count_buffer_autocmds(augroup, buf)
106+
107+
for _ = 1, 5 do
108+
autocmds.detach(buf)
109+
autocmds.setup_buffer_autocmds(augroup, opts, buf, noop, noop, noop, noop)
110+
autocmds.setup_cursor_autocmds(augroup, opts, buf, noop, noop)
111+
autocmds.setup_mode_change_autocmds(augroup, buf, noop)
112+
end
113+
114+
MiniTest.expect.equality(count_buffer_autocmds(augroup, buf), baseline)
115+
end)
116+
end
117+
118+
T["setup_global_autocmds"] = MiniTest.new_set()
119+
120+
T["setup_global_autocmds"]["creates one resize autocmd regardless of attached buffers"] = function()
121+
local augroup = autocmds.create_augroup()
122+
local opts = make_buf_opts()
123+
124+
autocmds.setup_global_autocmds(augroup, opts, noop, noop)
125+
126+
local resize_count = count_event_autocmds(augroup, "VimResized")
127+
+ count_event_autocmds(augroup, "WinResized")
128+
129+
H.with_buf({ "a" }, function(buf_a)
130+
autocmds.setup_buffer_autocmds(augroup, opts, buf_a, noop, noop, noop, noop)
131+
H.with_buf({ "b" }, function(buf_b)
132+
autocmds.setup_buffer_autocmds(augroup, opts, buf_b, noop, noop, noop, noop)
133+
134+
local after = count_event_autocmds(augroup, "VimResized")
135+
+ count_event_autocmds(augroup, "WinResized")
136+
MiniTest.expect.equality(after, resize_count)
137+
end)
138+
end)
139+
end
140+
141+
T["setup_global_autocmds"]["creates WinEnter only when experimental flag is set"] = function()
142+
local augroup_off = autocmds.create_augroup()
143+
autocmds.setup_global_autocmds(augroup_off, make_buf_opts(), noop, noop)
144+
MiniTest.expect.equality(count_event_autocmds(augroup_off, "WinEnter"), 0)
145+
146+
local augroup_on = autocmds.create_augroup()
147+
local opts_on = H.make_opts({
148+
options = { experimental = { use_window_local_extmarks = true } },
149+
})
150+
autocmds.setup_global_autocmds(augroup_on, opts_on, noop, noop)
151+
MiniTest.expect.equality(count_event_autocmds(augroup_on, "WinEnter") >= 1, true)
152+
end
153+
154+
T["create_augroup"] = MiniTest.new_set()
155+
156+
T["create_augroup"]["resets attached buffer tracking"] = function()
157+
H.with_buf({ "line" }, function(buf)
158+
local augroup = autocmds.create_augroup()
159+
autocmds.setup_buffer_autocmds(augroup, make_buf_opts(), buf, noop, noop, noop, noop)
160+
MiniTest.expect.equality(autocmds.is_attached(buf), true)
161+
162+
autocmds.create_augroup()
163+
164+
MiniTest.expect.equality(autocmds.is_attached(buf), false)
165+
end)
166+
end
167+
168+
return T

tests/test_highlights.lua

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
local MiniTest = require("mini.test")
2+
local highlights = require("tiny-inline-diagnostic.highlights")
3+
4+
local T = MiniTest.new_set()
5+
6+
T["get_diagnostic_highlights"] = MiniTest.new_set()
7+
8+
-- Test: Regular diagnostic NOT on cursor line
9+
T["get_diagnostic_highlights"]["not on cursor line uses regular highlights"] = function()
10+
local diag_ret = { line = 5, severity = 1 }
11+
local curline = 10
12+
local blend_factor = 0.5
13+
local index_diag = 1
14+
15+
local diag_hi, diag_inv_hi, body_hi = highlights.get_diagnostic_highlights(
16+
blend_factor,
17+
diag_ret,
18+
curline,
19+
index_diag
20+
)
21+
22+
-- Should use regular highlights, not CursorLine variants
23+
MiniTest.expect.equality(diag_hi, "TinyInlineDiagnosticVirtualTextError")
24+
MiniTest.expect.equality(diag_inv_hi, "TinyInlineInvDiagnosticVirtualTextErrorNoBg")
25+
MiniTest.expect.equality(body_hi, "TinyInlineInvDiagnosticVirtualTextErrorNoBg")
26+
end
27+
28+
-- Test: Diagnostic on cursor line with blend_factor = 0 (transparent mode)
29+
T["get_diagnostic_highlights"]["on cursor line with blend_factor=0 uses CursorLine"] = function()
30+
vim.opt.cursorline = true
31+
vim.api.nvim_set_hl(0, "CursorLine", { bg = "#ff0000" })
32+
33+
local diag_ret = { line = 10, severity = 1 }
34+
local curline = 10
35+
local blend_factor = 0
36+
local index_diag = 1
37+
38+
local diag_hi, diag_inv_hi, body_hi = highlights.get_diagnostic_highlights(
39+
blend_factor,
40+
diag_ret,
41+
curline,
42+
index_diag
43+
)
44+
45+
-- With blend_factor=0, should use CursorLine variants to show cursor line through
46+
MiniTest.expect.equality(diag_hi, "TinyInlineDiagnosticVirtualTextErrorCursorLine")
47+
MiniTest.expect.equality(diag_inv_hi, "TinyInlineInvDiagnosticVirtualTextErrorCursorLine")
48+
MiniTest.expect.equality(body_hi, "TinyInlineInvDiagnosticVirtualTextErrorNoBg")
49+
end
50+
51+
-- Test: Diagnostic on cursor line with blend_factor != 0 (colored mode)
52+
T["get_diagnostic_highlights"]["on cursor line with blend_factor!=0 uses colored background"] =
53+
function()
54+
vim.opt.cursorline = true
55+
vim.api.nvim_set_hl(0, "CursorLine", { bg = "#ff0000" })
56+
57+
local diag_ret = { line = 10, severity = 1 }
58+
local curline = 10
59+
local blend_factor = 0.5
60+
local index_diag = 1
61+
62+
local diag_hi, diag_inv_hi, body_hi = highlights.get_diagnostic_highlights(
63+
blend_factor,
64+
diag_ret,
65+
curline,
66+
index_diag
67+
)
68+
69+
-- With blend_factor!=0, should use ERROR background color, NOT cursor line background
70+
-- The message should have red background for errors, not the cursor line background
71+
MiniTest.expect.equality(diag_hi, "TinyInlineDiagnosticVirtualTextError")
72+
MiniTest.expect.equality(diag_inv_hi, "TinyInlineInvDiagnosticVirtualTextError")
73+
MiniTest.expect.equality(body_hi, "TinyInlineInvDiagnosticVirtualTextErrorNoBg")
74+
end
75+
76+
-- Test: Diagnostic on cursor line with need_to_be_under (overflow to next line)
77+
T["get_diagnostic_highlights"]["with need_to_be_under uses NoBg"] = function()
78+
vim.opt.cursorline = true
79+
vim.api.nvim_set_hl(0, "CursorLine", { bg = "#ff0000" })
80+
81+
local diag_ret = { line = 10, severity = 1, need_to_be_under = true }
82+
local curline = 10
83+
local blend_factor = 0.5
84+
local index_diag = 1
85+
86+
local diag_hi, diag_inv_hi, body_hi = highlights.get_diagnostic_highlights(
87+
blend_factor,
88+
diag_ret,
89+
curline,
90+
index_diag
91+
)
92+
93+
-- With need_to_be_under, should NOT use CursorLine, should use NoBg
94+
MiniTest.expect.equality(diag_hi, "TinyInlineDiagnosticVirtualTextError")
95+
MiniTest.expect.equality(diag_inv_hi, "TinyInlineInvDiagnosticVirtualTextErrorNoBg")
96+
MiniTest.expect.equality(body_hi, "TinyInlineInvDiagnosticVirtualTextErrorNoBg")
97+
end
98+
99+
-- Test: Second diagnostic (index_diag > 1) uses NoBg
100+
T["get_diagnostic_highlights"]["second diagnostic uses NoBg"] = function()
101+
local diag_ret = { line = 10, severity = 1 }
102+
local curline = 10
103+
local blend_factor = 0.5
104+
local index_diag = 2
105+
106+
local diag_hi, diag_inv_hi, body_hi = highlights.get_diagnostic_highlights(
107+
blend_factor,
108+
diag_ret,
109+
curline,
110+
index_diag
111+
)
112+
113+
-- Second diagnostic should use NoBg for inv highlights
114+
MiniTest.expect.equality(diag_hi, "TinyInlineDiagnosticVirtualTextError")
115+
MiniTest.expect.equality(diag_inv_hi, "TinyInlineInvDiagnosticVirtualTextErrorNoBg")
116+
MiniTest.expect.equality(body_hi, "TinyInlineInvDiagnosticVirtualTextErrorNoBg")
117+
end
118+
119+
-- Test: Different severity levels
120+
T["get_diagnostic_highlights"]["respects severity levels"] = function()
121+
local severities = { 1, 2, 3, 4 }
122+
local expected = { "Error", "Warn", "Info", "Hint" }
123+
124+
for i, severity in ipairs(severities) do
125+
local diag_ret = { line = 5, severity = severity }
126+
local curline = 10
127+
local blend_factor = 0.5
128+
local index_diag = 1
129+
130+
local diag_hi, _, _ = highlights.get_diagnostic_highlights(blend_factor, diag_ret, curline, index_diag)
131+
132+
MiniTest.expect.equality(diag_hi, "TinyInlineDiagnosticVirtualText" .. expected[i])
133+
end
134+
end
135+
136+
-- Test: When cursorline is disabled but CursorLine highlight exists
137+
T["get_diagnostic_highlights"]["cursorline disabled uses NoBg for signs"] = function()
138+
-- Cursorline is disabled
139+
vim.opt.cursorline = false
140+
-- But CursorLine highlight is still defined
141+
vim.api.nvim_set_hl(0, "CursorLine", { bg = "#ff0000" })
142+
143+
local diag_ret = { line = 10, severity = 1 }
144+
local curline = 10
145+
local blend_factor = 0.5
146+
local index_diag = 1
147+
148+
local diag_hi, diag_inv_hi, body_hi = highlights.get_diagnostic_highlights(
149+
blend_factor,
150+
diag_ret,
151+
curline,
152+
index_diag
153+
)
154+
155+
-- When cursorline is disabled, even if on cursor line, signs should be NoBg (transparent)
156+
-- The message can have colored background, but signs should be transparent
157+
MiniTest.expect.equality(diag_hi, "TinyInlineDiagnosticVirtualTextError")
158+
MiniTest.expect.equality(diag_inv_hi, "TinyInlineInvDiagnosticVirtualTextErrorNoBg")
159+
MiniTest.expect.equality(body_hi, "TinyInlineInvDiagnosticVirtualTextErrorNoBg")
160+
end
161+
162+
return T

0 commit comments

Comments
 (0)