repositories / dotfiles
dotfiles
bugabingas dorkfiles
owned by admin
neovim/tests/std/user_command_spec.lua
Rawlocal user_command = require('std.user_command')
describe('std.user_command', function()
before_each(function()
package.loaded['std.user_command'] = nil
user_command = require('std.user_command')
end)
after_each(function()
pcall(vim.api.nvim_del_user_command, 'TestCommand')
pcall(vim.api.nvim_del_user_command, 'AnotherCommand')
pcall(vim.api.nvim_del_user_command, 'NoDescCommand')
pcall(vim.api.nvim_del_user_command, 'NoOptsCommand')
pcall(vim.api.nvim_del_user_command, 'FullChainCommand')
pcall(vim.api.nvim_buf_del_user_command, 0, 'TestBufCmd')
pcall(vim.api.nvim_buf_del_user_command, 0, 'TestBufCmd2')
pcall(vim.api.nvim_buf_del_user_command, 0, 'AnotherBufCmd')
pcall(vim.api.nvim_buf_del_user_command, 0, 'OptsBufCmd')
pcall(vim.api.nvim_buf_del_user_command, 0, 'ExecBufCmd')
end)
local function get_user_command(name)
local commands = vim.api.nvim_get_commands {}
return commands[name]
end
describe('full chain: name -> description -> options -> command', function()
it('should create a user command with all parameters', function()
local deleter = user_command.FullChainCommand 'A test command' {
nargs = '*',
complete = 'file',
} (function()
return 'executed'
end)
assert.is_function(deleter)
local info = get_user_command('FullChainCommand')
assert.is_not_nil(info)
assert.equal('FullChainCommand', info.name)
assert.equal('*', info.nargs)
assert.equal('file', info.complete)
end)
it('should return a deleter function that removes the command', function()
local deleter = user_command.TestCommand 'Description' { nargs = '?' } (function() end)
assert.is_function(deleter)
local info_before = get_user_command('TestCommand')
assert.is_not_nil(info_before)
deleter()
local info_after = get_user_command('TestCommand')
assert.is_nil(info_after)
end)
end)
describe('chain: name -> description -> command (no options)', function()
it('should create a user command with just description and command', function()
local deleter = user_command.TestCommand 'Just a description' (function()
return 'simple'
end)
assert.is_function(deleter)
local info = get_user_command('TestCommand')
assert.is_not_nil(info)
assert.equal('TestCommand', info.name)
end)
end)
describe('command execution', function()
it('should execute the command function when called', function()
local executed = false
local deleter = user_command.TestCommand 'Execute test' (function()
executed = true
return 'done'
end)
vim.cmd('TestCommand')
assert.is_true(executed)
end)
end)
describe('error handling', function()
it('should error on invalid command_name (non-string)', function()
local ok, err = pcall(function() return user_command[123] end)
assert.is_false(ok)
assert.is_not_nil(err:match('command_name: expected string'))
end)
it('should error on invalid description (non-string)', function()
local desc_stage = user_command.TestCommand
local ok, err = pcall(function() return desc_stage(123) end)
assert.is_false(ok)
assert.is_not_nil(err:match('description: expected string'))
end)
it('should error on invalid command (non-function when expected)', function()
local ok, err = pcall(function() return user_command.TestCommand('description')({ nargs = '?' })(123) end)
assert.is_false(ok)
assert.is_not_nil(err:match('command: expected function'))
end)
it('should error on invalid options_or_command (non-table and non-function)', function()
local ok, err = pcall(function() return user_command.TestCommand('description')(123) end)
assert.is_false(ok)
assert.is_not_nil(err:match('options_or_command: expected'))
end)
end)
describe('metatable chaining behavior', function()
it('should return DESCRIPTION_SETTER metatable after setting name', function()
local mt = getmetatable(user_command.TestCommand)
assert.is_function(mt.__call)
end)
it('should return OPTIONS_OR_COMMAND_SETTER metatable after setting description', function()
local desc_stage = user_command.TestCommand 'description'
local mt = getmetatable(desc_stage)
assert.is_function(mt.__call)
end)
it('should return COMMAND_SETTER metatable after setting options', function()
local opts_stage = user_command.TestCommand 'description' { nargs = '?' }
local mt = getmetatable(opts_stage)
assert.is_function(mt.__call)
end)
it('should return deleter function after setting command', function()
local result = user_command.TestCommand 'description' (function() end)
assert.is_function(result)
end)
end)
describe('options merging', function()
it('should create command with correct options', function()
local deleter = user_command.TestCommand 'My description' (function() end)
local info = get_user_command('TestCommand')
assert.is_not_nil(info)
end)
it('should allow custom options to override defaults', function()
local deleter = user_command.TestCommand 'Custom desc' {
nargs = '*',
bang = true,
} (function() end)
local info = get_user_command('TestCommand')
assert.is_not_nil(info)
assert.equal('*', info.nargs)
assert.is_true(info.bang == 1 or info.bang == true)
end)
end)
describe('multiple commands', function()
it('should create multiple independent commands', function()
local deleter1 = user_command.TestCommand 'First' (function() end)
local deleter2 = user_command.AnotherCommand 'Second' (function() end)
local info1 = get_user_command('TestCommand')
local info2 = get_user_command('AnotherCommand')
assert.is_not_nil(info1)
assert.is_not_nil(info2)
assert.equal('TestCommand', info1.name)
assert.equal('AnotherCommand', info2.name)
deleter1()
deleter2()
local after1 = get_user_command('TestCommand')
local after2 = get_user_command('AnotherCommand')
assert.is_nil(after1)
assert.is_nil(after2)
end)
end)
describe('buffer commands', function()
local function get_buf_commands(bufnr)
return vim.api.nvim_buf_get_commands(bufnr, {})
end
it('should create a buffer-local command', function()
local deleter = user_command.buffer(0).TestBufCmd 'A buffer command' (function() end)
local buf_cmds = get_buf_commands(0)
assert.is_not_nil(buf_cmds['TestBufCmd'])
end)
it('should NOT appear in global command namespace', function()
local deleter = user_command.buffer(0).TestBufCmd 'A buffer command' (function() end)
local global_cmds = vim.api.nvim_get_commands {}
assert.is_nil(global_cmds['TestBufCmd'])
end)
it('should appear in buffer-local command namespace', function()
local deleter = user_command.buffer(0).TestBufCmd 'A buffer command' (function() end)
local buf_cmds = get_buf_commands(0)
assert.is_table(buf_cmds['TestBufCmd'])
assert.equal('TestBufCmd', buf_cmds['TestBufCmd'].name)
end)
it('should return a deleter that removes the buffer command', function()
local deleter = user_command.buffer(0).TestBufCmd 'To be deleted' (function() end)
local buf_cmds_before = get_buf_commands(0)
assert.is_not_nil(buf_cmds_before['TestBufCmd'])
deleter()
local buf_cmds_after = get_buf_commands(0)
assert.is_nil(buf_cmds_after['TestBufCmd'])
end)
it('should create multiple independent buffer commands', function()
local deleter1 = user_command.buffer(0).TestBufCmd 'First' (function() end)
local deleter2 = user_command.buffer(0).TestBufCmd2 'Second' (function() end)
local buf_cmds = get_buf_commands(0)
assert.is_not_nil(buf_cmds['TestBufCmd'])
assert.is_not_nil(buf_cmds['TestBufCmd2'])
deleter1()
deleter2()
local buf_cmds_after = get_buf_commands(0)
assert.is_nil(buf_cmds_after['TestBufCmd'])
assert.is_nil(buf_cmds_after['TestBufCmd2'])
end)
it('should error on invalid buffer argument', function()
local ok = pcall(function() return user_command.buffer('not_a_number') end)
assert.is_false(ok)
end)
it('should accept an options table before command', function()
local deleter = user_command.buffer(0).OptsBufCmd 'With options' {
nargs = '*',
bang = true,
} (function() end)
local buf_cmds = get_buf_commands(0)
assert.is_not_nil(buf_cmds['OptsBufCmd'])
assert.equal('*', buf_cmds['OptsBufCmd'].nargs)
deleter()
end)
it('should execute the command function when called', function()
local executed = false
local deleter = user_command.buffer(0).ExecBufCmd 'Execute test' (function()
executed = true
end)
vim.cmd('ExecBufCmd')
assert.is_true(executed)
deleter()
end)
it('should pass opts to command function', function()
---@type vim.api.keyset.create_user_command.command_args?
local received_opts
local deleter = user_command.buffer(0).TestBufCmd 'Opts test' (function(opts)
received_opts = opts
end)
vim.cmd('TestBufCmd')
assert.is_table(received_opts)
assert.equal('TestBufCmd', assert(received_opts).name)
deleter()
end)
it('should be scoped to the specified buffer only', function()
local bufnr1 = vim.api.nvim_create_buf(false, true)
local bufnr2 = vim.api.nvim_create_buf(false, true)
local deleter1 = user_command.buffer(bufnr1).TestBufCmd 'On buffer 1' (function() end)
local deleter2 = user_command.buffer(bufnr2).AnotherBufCmd 'On buffer 2' (function() end)
local cmds1 = get_buf_commands(bufnr1)
local cmds2 = get_buf_commands(bufnr2)
assert.is_not_nil(cmds1['TestBufCmd'])
assert.is_nil(cmds1['AnotherBufCmd'])
assert.is_not_nil(cmds2['AnotherBufCmd'])
assert.is_nil(cmds2['TestBufCmd'])
deleter1()
deleter2()
vim.api.nvim_buf_delete(bufnr1, { force = true })
vim.api.nvim_buf_delete(bufnr2, { force = true })
end)
end)
end)