1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-02-03 10:20:04 +08:00
SpaceVim/bundle/nui.nvim/tests/helpers/init.lua
2023-05-30 21:09:18 +08:00

307 lines
7.8 KiB
Lua

local function to_string(text)
if type(text) == "string" then
return text
end
if type(text) == "table" and text.content then
return text:content()
end
error("unsupported text")
end
local popup = {}
local mod = {}
mod.popup = popup
function mod.eq(...)
return assert.are.same(...)
end
function mod.approx(...)
return assert.are.near(...)
end
function mod.neq(...)
return assert["not"].are.same(...)
end
---@param fn fun(): nil
---@param error string
---@param is_plain boolean
function mod.errors(fn, error, is_plain)
assert.matches_error(fn, error, 1, is_plain)
end
---@param keys string
---@param mode string
function mod.feedkeys(keys, mode)
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(keys, true, false, true), mode or "", true)
end
---@param tbl table
---@param keys string[]
function mod.tbl_pick(tbl, keys)
if not keys or #keys == 0 then
return tbl
end
local new_tbl = {}
for _, key in ipairs(keys) do
new_tbl[key] = tbl[key]
end
return new_tbl
end
---@param tbl table
---@param keys string[]
function mod.tbl_omit(tbl, keys)
if not keys or #keys == 0 then
return tbl
end
local new_tbl = vim.deepcopy(tbl)
for _, key in ipairs(keys) do
rawset(new_tbl, key, nil)
end
return new_tbl
end
---@param bufnr number
---@param ns_id integer
---@param linenr integer (1-indexed)
---@param byte_start? integer (0-indexed)
---@param byte_end? integer (0-indexed, inclusive)
function mod.get_line_extmarks(bufnr, ns_id, linenr, byte_start, byte_end)
return vim.api.nvim_buf_get_extmarks(
bufnr,
ns_id,
{ linenr - 1, byte_start or 0 },
{ linenr - 1, byte_end and byte_end + 1 or -1 },
{ details = true }
)
end
---@param bufnr number
---@param ns_id integer
---@param linenr integer (1-indexed)
---@param text string
---@return table[]
---@return { byte_start: integer, byte_end: integer } info (byte range: 0-indexed, inclusive)
function mod.get_text_extmarks(bufnr, ns_id, linenr, text)
local line = vim.api.nvim_buf_get_lines(bufnr, linenr - 1, linenr, false)[1]
local byte_start = string.find(line, text) -- 1-indexed
byte_start = byte_start - 1 -- 0-indexed
local byte_end = byte_start + #text - 1 -- inclusive
local extmarks = vim.api.nvim_buf_get_extmarks(
bufnr,
ns_id,
{ linenr - 1, byte_start },
{ linenr - 1, byte_end },
{ details = true }
)
return extmarks, { byte_start = byte_start, byte_end = byte_end }
end
---@param bufnr number
---@param lines string[]
---@param linenr_start? integer (1-indexed)
---@param linenr_end? integer (1-indexed, inclusive)
function mod.assert_buf_lines(bufnr, lines, linenr_start, linenr_end)
mod.eq(vim.api.nvim_buf_get_lines(bufnr, linenr_start and linenr_start - 1 or 0, linenr_end or -1, false), lines)
end
---@param bufnr number
---@param options table
function mod.assert_buf_options(bufnr, options)
for name, value in pairs(options) do
mod.eq(vim.api.nvim_buf_get_option(bufnr, name), value)
end
end
---@param winid number
---@param options table
function mod.assert_win_options(winid, options)
for name, value in pairs(options) do
mod.eq(vim.api.nvim_win_get_option(winid, name), value)
end
end
---@param extmark table
---@param linenr number (1-indexed)
---@param text string
---@param hl_group string
function mod.assert_extmark(extmark, linenr, text, hl_group)
mod.eq(extmark[2], linenr - 1)
if text then
local start_col = extmark[3]
mod.eq(extmark[4].end_col - start_col, #text)
end
mod.eq(mod.tbl_pick(extmark[4], { "end_row", "hl_group" }), {
end_row = linenr - 1,
hl_group = hl_group,
})
end
---@param bufnr number
---@param ns_id integer
---@param linenr integer (1-indexed)
---@param text string
---@param hl_group string
function mod.assert_highlight(bufnr, ns_id, linenr, text, hl_group)
local extmarks, info = mod.get_text_extmarks(bufnr, ns_id, linenr, text)
mod.eq(#extmarks, 1)
mod.eq(extmarks[1][3], info.byte_start)
mod.assert_extmark(extmarks[1], linenr, text, hl_group)
end
---@param feature_name string
---@param desc string
---@param func fun(is_available: boolean):nil
function mod.describe_flipping_feature(feature_name, desc, func)
local initial_value = require("nui.utils")._.feature[feature_name]
describe(string.format("(w/ %s) %s", feature_name, desc), function()
require("nui.utils")._.feature[feature_name] = true
func(true)
require("nui.utils")._.feature[feature_name] = initial_value
end)
describe(string.format("(w/o %s) %s", feature_name, desc), function()
require("nui.utils")._.feature[feature_name] = false
func(false)
require("nui.utils")._.feature[feature_name] = initial_value
end)
end
function popup.create_border_style_list()
return { "", "", "", "", "", "", "", "" }
end
function popup.create_border_style_map()
return {
top_left = "",
top = "",
top_right = "",
left = "",
right = "",
bottom_left = "",
bottom = "",
bottom_right = "",
}
end
function popup.create_border_style_map_with_tuple(hl_group)
local style = popup.create_border_style_map()
for k, v in pairs(style) do
style[k] = { v, hl_group .. "_" .. k }
end
return style
end
function popup.create_border_style_map_with_nui_text(hl_group)
local Text = require("nui.text")
local style = popup.create_border_style_map()
for k, v in pairs(style) do
style[k] = Text(v, hl_group .. "_" .. k)
end
return style
end
function popup.assert_border_lines(options, border_bufnr)
local size = { width = options.size.width, height = options.size.height }
local style = vim.deepcopy(options.border.style)
if vim.tbl_islist(style) then
style = {
top_left = style[1],
top = style[2],
top_right = style[3],
left = style[8],
right = style[4],
bottom_left = style[7],
bottom = style[6],
bottom_right = style[5],
}
end
local expected_lines = {}
table.insert(
expected_lines,
string.format(
"%s%s%s",
to_string(style.top_left),
string.rep(to_string(style.top), size.width),
to_string(style.top_right)
)
)
for _ = 1, size.height do
table.insert(
expected_lines,
string.format("%s%s%s", to_string(style.left), string.rep(" ", size.width), to_string(style.right))
)
end
table.insert(
expected_lines,
string.format(
"%s%s%s",
to_string(style.bottom_left),
string.rep(to_string(style.bottom), size.width),
to_string(style.bottom_right)
)
)
mod.assert_buf_lines(border_bufnr, expected_lines)
end
function popup.assert_border_highlight(options, border_bufnr, hl_group, no_hl_group_suffix)
local size = { width = options.size.width, height = options.size.height }
for linenr = 1, size.height + 2 do
local is_top_line = linenr == 1
local is_bottom_line = linenr == size.height + 2
local extmarks = mod.get_line_extmarks(border_bufnr, options.ns_id, linenr)
mod.eq(#extmarks, (is_top_line or is_bottom_line) and 4 or 2)
local function with_suffix(hl_group_name, suffix)
if no_hl_group_suffix then
return hl_group_name
end
return hl_group_name .. suffix
end
mod.assert_extmark(
extmarks[1],
linenr,
nil,
with_suffix(hl_group, (is_top_line and "_top_left" or is_bottom_line and "_bottom_left" or "_left"))
)
if is_top_line or is_bottom_line then
mod.assert_extmark(extmarks[2], linenr, nil, with_suffix(hl_group, (is_top_line and "_top" or "_bottom")))
mod.assert_extmark(extmarks[3], linenr, nil, with_suffix(hl_group, (is_top_line and "_top" or "_bottom")))
end
mod.assert_extmark(
extmarks[#extmarks],
linenr,
nil,
with_suffix(hl_group, (is_top_line and "_top_right" or is_bottom_line and "_bottom_right" or "_right"))
)
end
end
return mod