test: multiline assert_log()

Problem:
assert_log() only matches single lines. This was never an intentional
decision, it was merely a result of using read_file_list().

Note: any tests that indiscriminately match `.*` should be rewritten to
avoid (unlikely) "false positives". I checked all existing tests.

Solution:
Change assert_log() to match the concatenated lines instead of matching
per-line.
This commit is contained in:
Justin M. Keyes
2025-05-02 20:46:31 +02:00
parent 8f5bd569c5
commit af4f7f1618
2 changed files with 17 additions and 23 deletions

View File

@@ -1171,7 +1171,7 @@ describe('stdpath()', function()
set_paths_via_system(env_var_name, paths) set_paths_via_system(env_var_name, paths)
eq(expected_paths, t.fix_slashes(fn.stdpath(stdpath_arg))) eq(expected_paths, t.fix_slashes(fn.stdpath(stdpath_arg)))
if not is_os('win') then if not is_os('win') then
assert_log('$TMPDIR tempdir not a directory.*TMPDIR%-should%-be%-ignored', testlog, 100) assert_log('$TMPDIR tempdir not a directory[^\n]*TMPDIR%-should%-be%-ignored', testlog, 100)
end end
end) end)
@@ -1179,7 +1179,7 @@ describe('stdpath()', function()
set_paths_at_runtime(env_var_name, paths) set_paths_at_runtime(env_var_name, paths)
eq(expected_paths, t.fix_slashes(fn.stdpath(stdpath_arg))) eq(expected_paths, t.fix_slashes(fn.stdpath(stdpath_arg)))
if not is_os('win') then if not is_os('win') then
assert_log('$TMPDIR tempdir not a directory.*TMPDIR%-should%-be%-ignored', testlog, 100) assert_log('$TMPDIR tempdir not a directory[^\n]*TMPDIR%-should%-be%-ignored', testlog, 100)
end end
end) end)
end) end)

View File

@@ -155,11 +155,13 @@ function M.matches(pat, actual)
error(string.format('Pattern does not match.\nPattern:\n%s\nActual:\n%s', pat, actual)) error(string.format('Pattern does not match.\nPattern:\n%s\nActual:\n%s', pat, actual))
end end
--- Asserts that `pat` matches (or *not* if inverse=true) any line in the tail of `logfile`. --- Asserts that `pat` matches (or *not* if inverse=true) any text in the tail of `logfile`.
---
--- Matches are not restricted to a single line.
--- ---
--- Retries for 1 second in case of filesystem delay. --- Retries for 1 second in case of filesystem delay.
--- ---
---@param pat (string) Lua pattern to match lines in the log file ---@param pat (string) Lua pattern to match text in the log file
---@param logfile? (string) Full path to log file (default=$NVIM_LOG_FILE) ---@param logfile? (string) Full path to log file (default=$NVIM_LOG_FILE)
---@param nrlines? (number) Search up to this many log lines (default 10) ---@param nrlines? (number) Search up to this many log lines (default 10)
---@param inverse? (boolean) Assert that the pattern does NOT match. ---@param inverse? (boolean) Assert that the pattern does NOT match.
@@ -167,28 +169,20 @@ function M.assert_log(pat, logfile, nrlines, inverse)
logfile = logfile or os.getenv('NVIM_LOG_FILE') or '.nvimlog' logfile = logfile or os.getenv('NVIM_LOG_FILE') or '.nvimlog'
luaassert(logfile ~= nil, 'no logfile') luaassert(logfile ~= nil, 'no logfile')
nrlines = nrlines or 10 nrlines = nrlines or 10
inverse = inverse or false
M.retry(nil, 1000, function() M.retry(nil, 1000, function()
local lines = M.read_file_list(logfile, -nrlines) or {} local lines = M.read_file_list(logfile, -nrlines) or {}
local text = table.concat(lines, '\n')
local ismatch = not not text:match(pat)
if (ismatch and inverse) or not (ismatch or inverse) then
local msg = string.format( local msg = string.format(
'Pattern %q %sfound in log (last %d lines): %s:\n%s', 'Pattern %s %sfound in log (last %d lines): %s:\n%s',
pat, vim.inspect(pat),
(inverse and '' or 'not '), (inverse and '' or 'not '),
nrlines, nrlines,
logfile, logfile,
' ' .. table.concat(lines, '\n ') vim.text.indent(4, text)
) )
for _, line in ipairs(lines) do
if line:match(pat) then
if inverse then
error(msg)
else
return
end
end
end
if not inverse then
error(msg) error(msg)
end end
end) end)