mirror of
https://github.com/neovim/neovim.git
synced 2026-05-24 22:00:10 +00:00
Problem: When using `vim.list.unique` or `vim.list.bisect`, if the `key` function is complex, it can degrade performance, because it is invoked on every comparison Solution: The `key` interface convention is designed specifically to address this issue; performance can be improved by memoizing its results. Also added the shorthand use of the field name string as the key.
74 lines
2.4 KiB
Lua
74 lines
2.4 KiB
Lua
-- Test suite for vim.list
|
|
local t = require('test.testutil')
|
|
local eq = t.eq
|
|
|
|
describe('vim.list', function()
|
|
it('vim.list.unique()', function()
|
|
eq({ 1, 2, 3, 4, 5 }, vim.list.unique({ 1, 2, 2, 3, 4, 4, 5 }))
|
|
eq({ 1, 2, 3, 4, 5 }, vim.list.unique({ 1, 2, 3, 4, 4, 5, 1, 2, 3, 2, 1, 2, 3, 4, 5 }))
|
|
eq({ 1, 2, 3, 4, 5, field = 1 }, vim.list.unique({ 1, 2, 2, 3, 4, 4, 5, field = 1 }))
|
|
|
|
-- Not properly defined, but test anyway
|
|
-- luajit evaluates #t as 7, whereas Lua 5.1 evaluates it as 12
|
|
local r = vim.list.unique({ 1, 2, 2, 3, 4, 4, 5, nil, 6, 6, 7, 7 })
|
|
if jit then
|
|
eq({ 1, 2, 3, 4, 5, nil, nil, nil, 6, 6, 7, 7 }, r)
|
|
else
|
|
eq({ 1, 2, 3, 4, 5, nil, 6, 7 }, r)
|
|
end
|
|
|
|
eq(
|
|
{ { 1 }, { 2 }, { 3 } },
|
|
vim.list.unique({ { 1 }, { 1 }, { 2 }, { 2 }, { 3 }, { 3 } }, function(x)
|
|
return x[1]
|
|
end)
|
|
)
|
|
|
|
eq({ { id = 1 }, { id = 2 } }, vim.list.unique({ { id = 1 }, { id = 2 }, { id = 1 } }, 'id'))
|
|
end)
|
|
|
|
--- Generate a list like { 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, ...}.
|
|
---@param num integer
|
|
local function gen_list(num)
|
|
---@type integer[]
|
|
local list = {}
|
|
for i = 1, num do
|
|
for _ = 1, i do
|
|
list[#list + 1] = i
|
|
end
|
|
end
|
|
return list
|
|
end
|
|
|
|
--- Index of the last {num}.
|
|
--- Mathematically, a triangular number.
|
|
---@param num integer
|
|
local function index(num)
|
|
return math.floor((math.pow(num, 2) + num) / 2)
|
|
end
|
|
|
|
it("vim.list.bisect(..., { bound = 'lower' })", function()
|
|
local num = math.random(100)
|
|
local list = gen_list(num)
|
|
|
|
local target = math.random(num)
|
|
eq(vim.list.bisect(list, target, { bound = 'lower' }), index(target - 1) + 1)
|
|
eq(vim.list.bisect(list, num + 1, { bound = 'lower' }), index(num) + 1)
|
|
|
|
local dict_list = { { value = 1 }, { value = 2 }, { value = 2 }, { value = 3 } }
|
|
eq(2, vim.list.bisect(dict_list, { value = 2 }, { key = 'value', bound = 'lower' }))
|
|
end)
|
|
|
|
it("vim.list.bisect(..., bound = { 'upper' })", function()
|
|
local num = math.random(100)
|
|
local list = gen_list(num)
|
|
|
|
local target = math.random(num)
|
|
eq(vim.list.bisect(list, target, { bound = 'upper' }), index(target) + 1)
|
|
eq(vim.list.bisect(list, num + 1, { bound = 'upper' }), index(num) + 1)
|
|
|
|
local dict_list = { { value = 1 }, { value = 2 }, { value = 2 }, { value = 3 } }
|
|
eq(4, vim.list.bisect(dict_list, { value = 2 }, { key = 'value', bound = 'upper' }))
|
|
end)
|
|
end)
|