chore: import upstream snapshot with attribution
Python CI / Python bindings (ubuntu-latest) (push) Failing after 0s
Build & Publish / Build Neovim aarch64-linux-android (push) Failing after 0s
Build & Publish / Build Neovim aarch64-unknown-linux-gnu (push) Failing after 0s
Build & Publish / Build MCP x86_64-unknown-linux-musl (push) Failing after 1s
Build & Publish / Build Python wheels aarch64 (ubuntu-latest) (push) Failing after 0s
Build & Publish / Build Python wheels x86_64 (ubuntu-latest) (push) Failing after 1s
Build & Publish / Build Python sdist (push) Failing after 1s
Rust CI / Fuzz Tests (ubuntu-latest) (push) Failing after 1s
Rust CI / Build i686-unknown-linux-gnu (push) Failing after 0s
Rust CI / cargo clippy (push) Failing after 1s
e2e Tests / e2e (ubuntu-latest) (push) Failing after 1s
Lua CI / luacheck lint (push) Failing after 1s
Build & Publish / Build Neovim aarch64-unknown-linux-musl (push) Failing after 1s
Build & Publish / Build Neovim x86_64-unknown-linux-gnu (push) Failing after 0s
Build & Publish / Build Neovim x86_64-unknown-linux-musl (push) Failing after 1s
Build & Publish / Build C FFI aarch64-linux-android (push) Failing after 0s
Build & Publish / Build C FFI aarch64-unknown-linux-gnu (push) Failing after 0s
Build & Publish / Build C FFI aarch64-unknown-linux-musl (push) Failing after 1s
Build & Publish / Build C FFI x86_64-unknown-linux-gnu (push) Failing after 0s
Build & Publish / Build C FFI x86_64-unknown-linux-musl (push) Failing after 1s
Build & Publish / Build MCP aarch64-unknown-linux-gnu (push) Failing after 1s
Build & Publish / Build MCP aarch64-unknown-linux-musl (push) Failing after 0s
Build & Publish / Build MCP x86_64-unknown-linux-gnu (push) Failing after 1s
Spelling / Spell Check with Typos (push) Failing after 0s
Rust CI / Test (ubuntu-latest) (push) Failing after 0s
Rust CI / cargo fmt (push) Failing after 0s
Stylua / Check lua files using Stylua (push) Failing after 1s
Lua CI / lua-language-server type check (push) Failing after 12m29s
e2e Tests / e2e (alpine-musl) (push) Successful in 57m31s
e2e Tests / e2e (macos-latest) (push) Has been cancelled
Build & Publish / Build C FFI aarch64-apple-darwin (push) Has been cancelled
Rust CI / Test (windows-latest) (push) Has been cancelled
e2e Tests / e2e (windows-latest) (push) Has been cancelled
Nix CI / check (push) Has been cancelled
Python CI / Python bindings (macos-latest) (push) Has been cancelled
Python CI / Python bindings (windows-latest) (push) Has been cancelled
Build & Publish / Build Neovim aarch64-apple-darwin (push) Has been cancelled
Build & Publish / Build Neovim aarch64-pc-windows-msvc (push) Has been cancelled
Build & Publish / Build Neovim x86_64-apple-darwin (push) Has been cancelled
Build & Publish / Build Neovim x86_64-pc-windows-msvc (push) Has been cancelled
Build & Publish / Build C FFI aarch64-pc-windows-msvc (push) Has been cancelled
Build & Publish / Build C FFI x86_64-apple-darwin (push) Has been cancelled
Build & Publish / Build C FFI x86_64-pc-windows-msvc (push) Has been cancelled
Build & Publish / Build MCP aarch64-apple-darwin (push) Has been cancelled
Build & Publish / Build MCP aarch64-pc-windows-msvc (push) Has been cancelled
Build & Publish / Build MCP x86_64-apple-darwin (push) Has been cancelled
Build & Publish / Build MCP x86_64-pc-windows-msvc (push) Has been cancelled
Build & Publish / Build Python wheels aarch64 (macos-latest) (push) Has been cancelled
Build & Publish / Build Python wheels x86_64 (macos-latest) (push) Has been cancelled
Build & Publish / Build Python wheels x86_64 (windows-latest) (push) Has been cancelled
Build & Publish / Release (push) Has been cancelled
Build & Publish / Publish Python wheels to PyPI (push) Has been cancelled
Build & Publish / Publish Rust crates (push) Has been cancelled
Build & Publish / Publish npm packages (push) Has been cancelled
Rust CI / Fuzz Tests (windows-latest) (push) Has been cancelled
Rust CI / Test (macos-latest) (push) Has been cancelled
Rust CI / Fuzz Tests (macos-latest) (push) Has been cancelled
Python CI / Python bindings (ubuntu-latest) (push) Failing after 0s
Build & Publish / Build Neovim aarch64-linux-android (push) Failing after 0s
Build & Publish / Build Neovim aarch64-unknown-linux-gnu (push) Failing after 0s
Build & Publish / Build MCP x86_64-unknown-linux-musl (push) Failing after 1s
Build & Publish / Build Python wheels aarch64 (ubuntu-latest) (push) Failing after 0s
Build & Publish / Build Python wheels x86_64 (ubuntu-latest) (push) Failing after 1s
Build & Publish / Build Python sdist (push) Failing after 1s
Rust CI / Fuzz Tests (ubuntu-latest) (push) Failing after 1s
Rust CI / Build i686-unknown-linux-gnu (push) Failing after 0s
Rust CI / cargo clippy (push) Failing after 1s
e2e Tests / e2e (ubuntu-latest) (push) Failing after 1s
Lua CI / luacheck lint (push) Failing after 1s
Build & Publish / Build Neovim aarch64-unknown-linux-musl (push) Failing after 1s
Build & Publish / Build Neovim x86_64-unknown-linux-gnu (push) Failing after 0s
Build & Publish / Build Neovim x86_64-unknown-linux-musl (push) Failing after 1s
Build & Publish / Build C FFI aarch64-linux-android (push) Failing after 0s
Build & Publish / Build C FFI aarch64-unknown-linux-gnu (push) Failing after 0s
Build & Publish / Build C FFI aarch64-unknown-linux-musl (push) Failing after 1s
Build & Publish / Build C FFI x86_64-unknown-linux-gnu (push) Failing after 0s
Build & Publish / Build C FFI x86_64-unknown-linux-musl (push) Failing after 1s
Build & Publish / Build MCP aarch64-unknown-linux-gnu (push) Failing after 1s
Build & Publish / Build MCP aarch64-unknown-linux-musl (push) Failing after 0s
Build & Publish / Build MCP x86_64-unknown-linux-gnu (push) Failing after 1s
Spelling / Spell Check with Typos (push) Failing after 0s
Rust CI / Test (ubuntu-latest) (push) Failing after 0s
Rust CI / cargo fmt (push) Failing after 0s
Stylua / Check lua files using Stylua (push) Failing after 1s
Lua CI / lua-language-server type check (push) Failing after 12m29s
e2e Tests / e2e (alpine-musl) (push) Successful in 57m31s
e2e Tests / e2e (macos-latest) (push) Has been cancelled
Build & Publish / Build C FFI aarch64-apple-darwin (push) Has been cancelled
Rust CI / Test (windows-latest) (push) Has been cancelled
e2e Tests / e2e (windows-latest) (push) Has been cancelled
Nix CI / check (push) Has been cancelled
Python CI / Python bindings (macos-latest) (push) Has been cancelled
Python CI / Python bindings (windows-latest) (push) Has been cancelled
Build & Publish / Build Neovim aarch64-apple-darwin (push) Has been cancelled
Build & Publish / Build Neovim aarch64-pc-windows-msvc (push) Has been cancelled
Build & Publish / Build Neovim x86_64-apple-darwin (push) Has been cancelled
Build & Publish / Build Neovim x86_64-pc-windows-msvc (push) Has been cancelled
Build & Publish / Build C FFI aarch64-pc-windows-msvc (push) Has been cancelled
Build & Publish / Build C FFI x86_64-apple-darwin (push) Has been cancelled
Build & Publish / Build C FFI x86_64-pc-windows-msvc (push) Has been cancelled
Build & Publish / Build MCP aarch64-apple-darwin (push) Has been cancelled
Build & Publish / Build MCP aarch64-pc-windows-msvc (push) Has been cancelled
Build & Publish / Build MCP x86_64-apple-darwin (push) Has been cancelled
Build & Publish / Build MCP x86_64-pc-windows-msvc (push) Has been cancelled
Build & Publish / Build Python wheels aarch64 (macos-latest) (push) Has been cancelled
Build & Publish / Build Python wheels x86_64 (macos-latest) (push) Has been cancelled
Build & Publish / Build Python wheels x86_64 (windows-latest) (push) Has been cancelled
Build & Publish / Release (push) Has been cancelled
Build & Publish / Publish Python wheels to PyPI (push) Has been cancelled
Build & Publish / Publish Rust crates (push) Has been cancelled
Build & Publish / Publish npm packages (push) Has been cancelled
Rust CI / Fuzz Tests (windows-latest) (push) Has been cancelled
Rust CI / Test (macos-latest) (push) Has been cancelled
Rust CI / Fuzz Tests (macos-latest) (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
--- End-to-end snapshot tests for fff.nvim's picker UI.
|
||||
local MiniTest = require('mini.test')
|
||||
local fixture_lib = require('tests.snapshot.fixture')
|
||||
|
||||
local PLUGIN_DIR = vim.fn.fnamemodify(debug.getinfo(1, 'S').source:sub(2), ':p:h:h')
|
||||
local FORCE = vim.env.UPDATE_SNAPSHOTS == '1'
|
||||
|
||||
local child, fixture
|
||||
|
||||
local function setup(geometry, opts)
|
||||
opts = opts or {}
|
||||
fixture = fixture_lib.create()
|
||||
child = MiniTest.new_child_neovim()
|
||||
child.start({
|
||||
'--clean',
|
||||
'-n',
|
||||
'-i',
|
||||
'NONE',
|
||||
'--cmd',
|
||||
string.format('let &lines = %d', geometry.rows),
|
||||
'--cmd',
|
||||
string.format('let &columns = %d', geometry.cols),
|
||||
}, {
|
||||
connection_timeout = 15000,
|
||||
})
|
||||
|
||||
child.o.lines = geometry.rows
|
||||
child.o.columns = geometry.cols
|
||||
|
||||
local debug_enabled = opts.debug == true
|
||||
-- Default show_file_info hides timings: Modified/Accessed timestamps drift
|
||||
-- between runs and would otherwise force `ignore_text` on those rows. Tests
|
||||
-- can override (or restore) by passing `opts.show_file_info`.
|
||||
local show_file_info = opts.show_file_info
|
||||
or { file_info = true, score_breakdown = true, timings = false, full_path = true }
|
||||
|
||||
child.lua(
|
||||
string.format(
|
||||
[[
|
||||
local plugin = %q
|
||||
vim.opt.runtimepath:prepend(plugin)
|
||||
package.path = plugin .. '/lua/?.lua;' .. plugin .. '/lua/?/init.lua;' .. package.path
|
||||
vim.cmd('cd ' .. vim.fn.fnameescape(%q))
|
||||
vim.cmd('syntax off')
|
||||
local winborder = %q
|
||||
if winborder ~= '' then vim.o.winborder = winborder end
|
||||
vim.g.fff = {
|
||||
prompt = '> ',
|
||||
frecency = { enabled = true, db_path = %q },
|
||||
history = { enabled = true, db_path = %q },
|
||||
logging = { enabled = false },
|
||||
debug = {
|
||||
enabled = %s,
|
||||
show_scores = %s,
|
||||
show_file_info = %s,
|
||||
},
|
||||
}
|
||||
require('fff.core').ensure_initialized()
|
||||
require('fff.rust').wait_for_initial_scan(8000)
|
||||
]],
|
||||
PLUGIN_DIR,
|
||||
fixture.root,
|
||||
geometry.winborder or '',
|
||||
fixture.frecency_db,
|
||||
fixture.history_db,
|
||||
tostring(debug_enabled),
|
||||
tostring(debug_enabled),
|
||||
vim.inspect(show_file_info)
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
local function teardown()
|
||||
if child and child.is_running() then pcall(child.stop) end
|
||||
if fixture then fixture_lib.cleanup(fixture) end
|
||||
child, fixture = nil, nil
|
||||
end
|
||||
|
||||
--- @param opts table|nil { ignore_text?: number[] }
|
||||
local function assert_snapshot_match(opts)
|
||||
opts = opts or {}
|
||||
MiniTest.expect.reference_screenshot(child.get_screenshot(), nil, {
|
||||
force = FORCE,
|
||||
ignore_text = opts.ignore_text or false,
|
||||
})
|
||||
end
|
||||
|
||||
local function open_picker(prompt_position, query)
|
||||
child.lua(
|
||||
string.format('require("fff.picker_ui.picker_ui").open({ layout = { prompt_position = %q } })', prompt_position)
|
||||
)
|
||||
vim.loop.sleep(400)
|
||||
|
||||
if query and query ~= '' then
|
||||
child.type_keys(query)
|
||||
vim.loop.sleep(400)
|
||||
end
|
||||
end
|
||||
|
||||
local LAYOUTS = {
|
||||
{ name = 'wide', cols = 180, rows = 40, winborder = 'double' },
|
||||
{ name = 'default', cols = 140, rows = 32 }, -- standard on most screens
|
||||
{ name = 'narrow', cols = 70, rows = 24, winborder = 'rounded' },
|
||||
-- Extra-wide: exists primarily so the file_info panel hits the H2 layout.
|
||||
{ name = 'xwide', cols = 240, rows = 48 },
|
||||
}
|
||||
|
||||
local T = MiniTest.new_set()
|
||||
|
||||
local PROMPT_POSITIONS = { 'bottom', 'top' }
|
||||
|
||||
for _, geometry in ipairs(LAYOUTS) do
|
||||
local set = MiniTest.new_set({
|
||||
hooks = {
|
||||
pre_case = function() setup(geometry) end,
|
||||
post_case = teardown,
|
||||
},
|
||||
})
|
||||
|
||||
-- Run every per-geometry case for both prompt positions: layout math and
|
||||
-- list rendering diverge between top/bottom (see AGENTS.md), so a snapshot
|
||||
-- on a single side would silently miss regressions in the other.
|
||||
for _, prompt in ipairs(PROMPT_POSITIONS) do
|
||||
set['empty_' .. prompt] = function()
|
||||
open_picker(prompt)
|
||||
assert_snapshot_match()
|
||||
end
|
||||
|
||||
set['query_main_' .. prompt] = function()
|
||||
open_picker(prompt, 'main')
|
||||
assert_snapshot_match()
|
||||
end
|
||||
|
||||
set['no_results_' .. prompt] = function()
|
||||
open_picker(prompt, 'zzzzzzzzz')
|
||||
assert_snapshot_match()
|
||||
end
|
||||
|
||||
set['cursor_second_item_' .. prompt] = function()
|
||||
open_picker(prompt)
|
||||
-- Bottom prompt visually goes up with <Down>; top prompt goes down with <Down>.
|
||||
-- Either way one keypress moves to the second item — what we want to capture.
|
||||
child.type_keys('<Down>')
|
||||
vim.loop.sleep(200)
|
||||
assert_snapshot_match()
|
||||
end
|
||||
end
|
||||
|
||||
T[geometry.name] = set
|
||||
end
|
||||
|
||||
-- File info panel snapshots. Timings are disabled at the config level (see
|
||||
-- `setup`) so the snapshots stay deterministic — Modified/Accessed timestamps
|
||||
-- drift between runs. We snapshot a narrow and a wide variant for both prompt
|
||||
-- positions to keep the adaptive panel layout (label widths, section headers,
|
||||
-- top vs bottom prompt geometry) covered.
|
||||
local debug_narrow_set = MiniTest.new_set({
|
||||
hooks = {
|
||||
pre_case = function() setup(LAYOUTS[2], { debug = true }) end, -- default 140x32, panel ~57 cols
|
||||
post_case = teardown,
|
||||
},
|
||||
})
|
||||
|
||||
for _, prompt in ipairs(PROMPT_POSITIONS) do
|
||||
debug_narrow_set['file_info_panel_' .. prompt] = function()
|
||||
open_picker(prompt, 'main')
|
||||
assert_snapshot_match()
|
||||
end
|
||||
end
|
||||
T['debug_narrow'] = debug_narrow_set
|
||||
|
||||
local debug_wide_set = MiniTest.new_set({
|
||||
hooks = {
|
||||
pre_case = function() setup(LAYOUTS[4], { debug = true }) end, -- xwide 240x48, panel ~96 cols
|
||||
post_case = teardown,
|
||||
},
|
||||
})
|
||||
|
||||
for _, prompt in ipairs(PROMPT_POSITIONS) do
|
||||
debug_wide_set['file_info_panel_' .. prompt] = function()
|
||||
open_picker(prompt, 'main')
|
||||
assert_snapshot_match()
|
||||
end
|
||||
end
|
||||
T['debug_wide'] = debug_wide_set
|
||||
|
||||
T['combo'] = MiniTest.new_set({
|
||||
hooks = {
|
||||
pre_case = function() setup({ cols = 140, rows = 32 }) end,
|
||||
post_case = teardown,
|
||||
},
|
||||
})
|
||||
|
||||
local function train_combo()
|
||||
-- Train: "main" → src/main.rs four times so open_count crosses the default
|
||||
-- min_combo_count (3). track_query_completion is async; pause between calls
|
||||
-- + final settle for the lmdb writer.
|
||||
for _ = 1, 4 do
|
||||
child.lua(
|
||||
string.format('require("fff.rust").track_query_completion(%q, %q)', 'main', fixture.root .. '/src/main.rs')
|
||||
)
|
||||
vim.loop.sleep(120)
|
||||
end
|
||||
vim.loop.sleep(400)
|
||||
end
|
||||
|
||||
for _, prompt in ipairs(PROMPT_POSITIONS) do
|
||||
T['combo']['boost_' .. prompt] = function()
|
||||
train_combo()
|
||||
open_picker(prompt, 'main')
|
||||
-- Combo overlay float renders asynchronously after render_list.
|
||||
vim.loop.sleep(400)
|
||||
assert_snapshot_match()
|
||||
end
|
||||
end
|
||||
|
||||
T['scrollbar'] = MiniTest.new_set({
|
||||
hooks = {
|
||||
pre_case = function() setup({ cols = 140, rows = 32 }) end,
|
||||
post_case = teardown,
|
||||
},
|
||||
})
|
||||
|
||||
-- Cursor advance key differs by prompt position: bottom prompt iterates the
|
||||
-- list in reverse so `<Up>` walks toward higher indices; top prompt is
|
||||
-- conventional. Either way we walk past the last in-page item to trigger
|
||||
-- load_next_page and surface the scrollbar thumb at the new offset.
|
||||
local SCROLL_KEY = { bottom = '<Up>', top = '<Down>' }
|
||||
|
||||
for _, prompt in ipairs(PROMPT_POSITIONS) do
|
||||
T['scrollbar']['next_page_' .. prompt] = function()
|
||||
open_picker(prompt)
|
||||
for _ = 1, 30 do
|
||||
child.type_keys(SCROLL_KEY[prompt])
|
||||
vim.loop.sleep(20)
|
||||
end
|
||||
vim.loop.sleep(400)
|
||||
assert_snapshot_match()
|
||||
end
|
||||
end
|
||||
|
||||
return T
|
||||
Reference in New Issue
Block a user