mirror of
https://github.com/neovim/neovim.git
synced 2026-06-15 08:13:45 +00:00
test(autoread): make "debounce" test actually valid
This commit is contained in:
@@ -14,7 +14,21 @@ local watchers = {}
|
||||
--- @type table<integer, uv.uv_timer_t> bufnr -> debounce timer
|
||||
local timers = {}
|
||||
|
||||
local DEBOUNCE_MS = 100
|
||||
local debounce_ms = 100
|
||||
|
||||
--- @private
|
||||
--- Test-only: override the debounce window so tests can run faster.
|
||||
--- @param ms integer
|
||||
function M._set_debounce(ms)
|
||||
debounce_ms = ms
|
||||
end
|
||||
|
||||
--- @private
|
||||
--- @param bufnr integer
|
||||
--- @return boolean
|
||||
function M._is_watching(bufnr)
|
||||
return watchers[bufnr] ~= nil
|
||||
end
|
||||
|
||||
--- Returns the effective 'autoread' value for a buffer.
|
||||
--- 'autoread' is global-local: vim.bo[bufnr].autoread is nil when not set locally,
|
||||
@@ -84,7 +98,7 @@ local function ensure_watcher(bufnr)
|
||||
local cancel = watch.watch(name, {}, function(_, change_type)
|
||||
-- Debounce: restart the same timer on each event, so only the last
|
||||
-- event in a rapid series (e.g. truncate + write) triggers checktime.
|
||||
timer:start(DEBOUNCE_MS, 0, function()
|
||||
timer:start(debounce_ms, 0, function()
|
||||
vim.schedule(function()
|
||||
if not vim.api.nvim_buf_is_loaded(bufnr) or not buf_autoread(bufnr) then
|
||||
return
|
||||
@@ -102,13 +116,6 @@ local function ensure_watcher(bufnr)
|
||||
watchers[bufnr] = cancel
|
||||
end
|
||||
|
||||
--- @private
|
||||
--- @param bufnr integer
|
||||
--- @return boolean
|
||||
function M._is_watching(bufnr)
|
||||
return watchers[bufnr] ~= nil
|
||||
end
|
||||
|
||||
function M.enable()
|
||||
local group = vim.api.nvim_create_augroup('nvim.autoread', { clear = true })
|
||||
|
||||
|
||||
@@ -17,6 +17,11 @@ local function is_watching(bufnr)
|
||||
end, bufnr)
|
||||
end
|
||||
|
||||
--- Shortens the 'autoread' debounce window so each test doesn't pay the 100ms time-cost.
|
||||
local function shorten_debounce()
|
||||
n.exec_lua([[require('nvim.autoread')._set_debounce(10)]])
|
||||
end
|
||||
|
||||
--- Edits a fresh tempfile with the given initial content and asserts the watcher attached.
|
||||
--- Returns the file path.
|
||||
local function open_watched(content)
|
||||
@@ -30,6 +35,7 @@ end
|
||||
describe('autoread file watcher', function()
|
||||
before_each(function()
|
||||
clear({ args = { '--clean' } })
|
||||
shorten_debounce()
|
||||
end)
|
||||
|
||||
it('watches file opened on startup (nvim foo.txt)', function()
|
||||
@@ -40,6 +46,7 @@ describe('autoread file watcher', function()
|
||||
-- boot order: plugins must load before the initial file is read so that
|
||||
-- the BufReadPost autocmd is registered in time to attach a watcher.
|
||||
clear({ args = { '--clean', path } })
|
||||
shorten_debounce()
|
||||
|
||||
eq({ 'startup original' }, api.nvim_buf_get_lines(0, 0, -1, true))
|
||||
eq(true, is_watching())
|
||||
@@ -91,7 +98,7 @@ describe('autoread file watcher', function()
|
||||
|
||||
-- Give the watcher time to fire; the buffer must NOT be reloaded because
|
||||
-- it has unsaved changes (autoread only reloads unmodified buffers).
|
||||
sleep(200)
|
||||
sleep(50)
|
||||
-- Also do a manual checktime to be sure
|
||||
command('silent! checktime')
|
||||
-- Buffer should still have local changes (autoread doesn't override modified buffers)
|
||||
@@ -106,7 +113,7 @@ describe('autoread file watcher', function()
|
||||
|
||||
-- Modify externally while noautoread
|
||||
write_file(path, 'while disabled\n')
|
||||
sleep(200)
|
||||
sleep(50)
|
||||
eq({ 'original' }, api.nvim_buf_get_lines(0, 0, -1, true))
|
||||
|
||||
-- Re-enable autoread
|
||||
@@ -132,25 +139,32 @@ describe('autoread file watcher', function()
|
||||
eq({ 'will be deleted' }, api.nvim_buf_get_lines(0, 0, -1, true))
|
||||
end)
|
||||
|
||||
-- TODO: revisit this test
|
||||
it('handles rapid changes with debouncing', function()
|
||||
local path = testdir .. '/test_debounce.txt'
|
||||
write_file(path, 'v1\n')
|
||||
it('coalesces rapid changes via debouncing', function()
|
||||
local path = open_watched('v1\n')
|
||||
|
||||
command('edit ' .. path)
|
||||
eq({ 'v1' }, api.nvim_buf_get_lines(0, 0, -1, true))
|
||||
eq(true, is_watching())
|
||||
-- Count buffer reloads triggered by the watcher.
|
||||
n.exec_lua([[
|
||||
_G.reloads = 0
|
||||
vim.api.nvim_create_autocmd('FileChangedShellPost', {
|
||||
callback = function() _G.reloads = _G.reloads + 1 end,
|
||||
})
|
||||
]])
|
||||
|
||||
-- Make several rapid changes
|
||||
-- 4 back-to-back writes well inside one debounce window.
|
||||
write_file(path, 'v2\n')
|
||||
write_file(path, 'v3\n')
|
||||
write_file(path, 'v4\n')
|
||||
write_file(path, 'final\n')
|
||||
|
||||
-- Should eventually settle on final content
|
||||
retry(nil, 3000, function()
|
||||
eq({ 'final' }, api.nvim_buf_get_lines(0, 0, -1, true))
|
||||
end)
|
||||
|
||||
-- Let any late-arriving event flush, then assert all 4 writes coalesced.
|
||||
-- Every fs_event restarts the debounce timer, and 4 sub-millisecond
|
||||
-- write_file calls fit well inside one window, so the timer fires once.
|
||||
sleep(50)
|
||||
eq(1, n.exec_lua('return _G.reloads'))
|
||||
end)
|
||||
|
||||
it('detects changes after atomic rename (external editor save)', function()
|
||||
|
||||
Reference in New Issue
Block a user