neovim/test/functional/lua/watch_spec.lua
github-actions[bot] a41930bcf0
[Backport release-0.9] fix(watchfiles): skip Created events when poll starts (#23197)
fix(watchfiles): skip Created events when poll starts

(cherry picked from commit 8ca1bae217)

Co-authored-by: Jon Huhn <huhnjon@gmail.com>
2023-04-19 16:55:06 +02:00

190 lines
5.2 KiB
Lua

local helpers = require('test.functional.helpers')(after_each)
local eq = helpers.eq
local exec_lua = helpers.exec_lua
local clear = helpers.clear
local is_os = helpers.is_os
local mkdir = helpers.mkdir
describe('vim._watch', function()
before_each(function()
clear()
end)
describe('watch', function()
it('detects file changes', function()
local root_dir = helpers.tmpname()
os.remove(root_dir)
mkdir(root_dir)
local result = exec_lua(
[[
local root_dir = ...
local events = {}
local expected_events = 0
local function wait_for_events()
assert(vim.wait(100, function() return #events == expected_events end), 'Timed out waiting for expected number of events. Current events seen so far: ' .. vim.inspect(events))
end
local stop = vim._watch.watch(root_dir, {}, function(path, change_type)
table.insert(events, { path = path, change_type = change_type })
end)
-- Only BSD seems to need some extra time for the watch to be ready to respond to events
if vim.fn.has('bsd') then
vim.wait(50)
end
local watched_path = root_dir .. '/file'
local watched, err = io.open(watched_path, 'w')
assert(not err, err)
expected_events = expected_events + 1
wait_for_events()
watched:close()
os.remove(watched_path)
expected_events = expected_events + 1
wait_for_events()
stop()
-- No events should come through anymore
local watched_path = root_dir .. '/file'
local watched, err = io.open(watched_path, 'w')
assert(not err, err)
vim.wait(50)
watched:close()
os.remove(watched_path)
vim.wait(50)
return events
]],
root_dir
)
local expected = {
{
change_type = exec_lua([[return vim._watch.FileChangeType.Created]]),
path = root_dir .. '/file',
},
{
change_type = exec_lua([[return vim._watch.FileChangeType.Deleted]]),
path = root_dir .. '/file',
},
}
-- kqueue only reports events on the watched path itself, so creating a file within a
-- watched directory results in a "rename" libuv event on the directory.
if is_os('bsd') then
expected = {
{
change_type = exec_lua([[return vim._watch.FileChangeType.Created]]),
path = root_dir,
},
{
change_type = exec_lua([[return vim._watch.FileChangeType.Created]]),
path = root_dir,
},
}
end
eq(expected, result)
end)
end)
describe('poll', function()
it('detects file changes', function()
local root_dir = helpers.tmpname()
os.remove(root_dir)
mkdir(root_dir)
local result = exec_lua(
[[
local root_dir = ...
local events = {}
local poll_interval_ms = 1000
local poll_wait_ms = poll_interval_ms+200
local expected_events = 0
local function wait_for_events()
assert(vim.wait(poll_wait_ms, function() return #events == expected_events end), 'Timed out waiting for expected number of events. Current events seen so far: ' .. vim.inspect(events))
end
local stop = vim._watch.poll(root_dir, { interval = poll_interval_ms }, function(path, change_type)
table.insert(events, { path = path, change_type = change_type })
end)
vim.wait(100)
local watched_path = root_dir .. '/file'
local watched, err = io.open(watched_path, 'w')
assert(not err, err)
expected_events = expected_events + 2
wait_for_events()
watched:close()
os.remove(watched_path)
expected_events = expected_events + 2
wait_for_events()
stop()
-- No events should come through anymore
local watched_path = root_dir .. '/file'
local watched, err = io.open(watched_path, 'w')
assert(not err, err)
vim.wait(poll_wait_ms)
watched:close()
os.remove(watched_path)
return events
]],
root_dir
)
eq(4, #result)
eq({
change_type = exec_lua([[return vim._watch.FileChangeType.Created]]),
path = root_dir .. '/file',
}, result[1])
eq({
change_type = exec_lua([[return vim._watch.FileChangeType.Changed]]),
path = root_dir,
}, result[2])
-- The file delete and corresponding directory change events do not happen in any
-- particular order, so allow either
if result[3].path == root_dir then
eq({
change_type = exec_lua([[return vim._watch.FileChangeType.Changed]]),
path = root_dir,
}, result[3])
eq({
change_type = exec_lua([[return vim._watch.FileChangeType.Deleted]]),
path = root_dir .. '/file',
}, result[4])
else
eq({
change_type = exec_lua([[return vim._watch.FileChangeType.Deleted]]),
path = root_dir .. '/file',
}, result[3])
eq({
change_type = exec_lua([[return vim._watch.FileChangeType.Changed]]),
path = root_dir,
}, result[4])
end
end)
end)
end)