refactor: extract helpers, dedup patterns, add regression tests

Mechanical cleanup pass, behavior-preserving:
- remove dead code: reposition_bars (unused), sbar click infrastructure
  (zones never populated, handler iterated empty list)
- extract helpers in mode.lua: win_ok, buf_ok, is_dapui_pane_ft,
  for_each_dapui_pane (asymmetric filter preserved), safe_extmark,
  bar_set_lines, safe_set_height, if_still_active, invalidate_dead_bars,
  focus_source_win, unset_and_restore
- inline install_cs_listener inside define_highlights to dedup the three
  ColorScheme augroup+autocmd triples (italic, key, sep)
- data-drive sign_define in breakpoints.lua
- data-drive python interpreter candidate probing
- add tests/test_render_bars.lua pinning sbar/cbar output dimensions,
  zones, and overflow fallback behavior
- add tests/test_highlights_cs.lua verifying ColorScheme augroups and
  highlight group existence / re-apply on event
- add tests/test_helpers.lua unit-testing keyof and source_window
- expose M._test (direct function refs) so render/highlight internals are
  testable in headless mode
This commit is contained in:
swaits committed 2026-04-12 19:42:54 -06:00
1 parent 7a21d372ff
commit 85ff3b1688
7 files changed
+414 -164

No files matched your search

+147
View File
@@ -0,0 +1,147 @@
local h = require("helpers")
local assert_eq = h.assert_eq
local assert_true = h.assert_true
local assert_false = h.assert_false
local mode = require("turbo-debug.mode")
local config = require("turbo-debug.config")
-- Ensure config is initialized with defaults so keyof/render_cbar can read it
config.merge({})
-- Helpers --------------------------------------------------------------------
local function make_bar_win()
vim.cmd("noautocmd keepalt topleft split")
local win = vim.api.nvim_get_current_win()
local buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_win_set_buf(win, buf)
vim.api.nvim_win_set_height(win, 2)
return win, buf
end
local function cleanup(win)
if win and vim.api.nvim_win_is_valid(win) then
pcall(vim.api.nvim_win_close, win, true)
end
end
local function line(buf, i)
return vim.api.nvim_buf_get_lines(buf, i, i + 1, false)[1] or ""
end
-- build_control_text -------------------------------------------------------
-- Inline form when key matches first letter case-insensitively.
local text, kcol, kend, icol, iend = mode._test.build_control_text(">", "s", "step", "over")
assert_true(text:find("%(s%)tep") ~= nil, "inline form: (s)tep present")
assert_true(kcol < kend, "inline form: key_col < key_end_col")
assert_true(icol ~= nil and iend ~= nil, "inline form: italic span present")
assert_true(text:sub(icol + 1, iend) == "over", "inline form: italic text is 'over'")
-- Prefix form when key does NOT match first letter.
local text2, _, _, icol2 = mode._test.build_control_text(">", "n", "step", "over")
assert_true(text2:find("%(n%) step") ~= nil, "prefix form: (n) step present")
assert_true(icol2 ~= nil, "prefix form: italic still rendered")
-- No italic when italic param is nil.
local text3, _, _, icol3 = mode._test.build_control_text(">", "c", "continue", nil)
assert_eq(icol3, nil, "no italic span when italic=nil")
assert_true(text3:find("%(c%)ontinue") ~= nil, "no italic: (c)ontinue rendered")
-- keyof ----------------------------------------------------------------------
-- Save any user override then reset to defaults
config.merge({})
assert_eq(mode._test.keyof("continue", "c"), "c", "keyof returns default when unset")
-- Disabled action returns nil
config.merge({ keys = { continue = false } })
assert_eq(mode._test.keyof("continue", "c"), nil, "keyof returns nil when key=false")
-- User override
config.merge({ keys = { continue = "g" } })
assert_eq(mode._test.keyof("continue", "c"), "g", "keyof returns user override")
-- Empty string falls back to default
config.merge({ keys = { continue = "" } })
assert_eq(mode._test.keyof("continue", "c"), "c", "keyof falls back on empty string")
-- Reset config to defaults for subsequent render tests
config.merge({})
-- render_sbar ----------------------------------------------------------------
do
local win, buf = make_bar_win()
mode._test.set_bars(win, buf, nil, nil)
mode._test.render_sbar()
local count = vim.api.nvim_buf_line_count(buf)
assert_eq(count, 2, "sbar has exactly 2 lines")
local sep = line(buf, 0)
local content = line(buf, 1)
assert_true(#sep > 0, "sbar separator non-empty")
assert_true(content:find(" turbo%-debug ") ~= nil, "sbar contains brand text")
assert_true(content:find("DEBUG") ~= nil, "sbar contains DEBUG chip")
-- sbar has no click zones
local zones = mode._test.get_sbar_zones()
assert_eq(#zones, 0, "sbar has zero click zones")
mode._test.set_bars(nil, nil, nil, nil)
cleanup(win)
end
-- render_cbar ----------------------------------------------------------------
do
local win, buf = make_bar_win()
vim.api.nvim_win_set_width(win, 120)
mode._test.set_bars(nil, nil, win, buf)
mode._test.render_cbar()
local count = vim.api.nvim_buf_line_count(buf)
assert_eq(count, 2, "cbar has exactly 2 lines")
local content = line(buf, 0)
local sep = line(buf, 1)
assert_true(#sep > 0, "cbar separator non-empty")
assert_true(content:find(" help ") ~= nil, "cbar contains 'help' text")
-- Click zones: at least 5 controls (continue, step_over, step_into, step_out, terminate) + 1 help
-- When no session, restart is hidden so zone count = 5 + 1 = 6.
local zones = mode._test.get_cbar_zones()
assert_true(#zones >= 6, "cbar has at least 6 click zones: " .. #zones)
mode._test.set_bars(nil, nil, nil, nil)
cleanup(win)
end
-- overflow fallback: at narrow widths, italic qualifiers are dropped
do
local win, buf = make_bar_win()
vim.api.nvim_win_set_width(win, 25)
mode._test.set_bars(nil, nil, win, buf)
mode._test.render_cbar()
local content = line(buf, 0)
-- italic qualifiers are "over", "into", "out" — on overflow they're omitted.
-- At width 25 with 5+ controls, there's no way they all fit with italics.
assert_false(content:find(" over ") or content:find(" into ") or content:find(" out "),
"overflow: italic qualifiers absent at narrow width")
mode._test.set_bars(nil, nil, nil, nil)
cleanup(win)
end
-- disabling step_over reduces zone count
do
local win, buf = make_bar_win()
vim.api.nvim_win_set_width(win, 120)
mode._test.set_bars(nil, nil, win, buf)
mode._test.render_cbar()
local default_count = #mode._test.get_cbar_zones()
config.merge({ keys = { step_over = false } })
mode._test.render_cbar()
local disabled_count = #mode._test.get_cbar_zones()
assert_eq(disabled_count, default_count - 1, "disabling step_over drops one zone")
config.merge({}) -- reset
mode._test.set_bars(nil, nil, nil, nil)
cleanup(win)
end
print("ALL RENDER BAR TESTS PASSED")