repositories / dotfiles
dotfiles
bugabingas dorkfiles
owned by admin
neovim/tests/bugabinga/pivi/command_spec.lua
Raw---@diagnostic disable: duplicate-set-field, need-check-nil, param-type-mismatch, assign-type-mismatch
local command = require 'bugabinga.pivi.command'
local session = require 'bugabinga.pivi.session'
local transcript = require 'bugabinga.pivi.transcript'
local publish = require 'bugabinga.pivi.publish'
local fake = dofile 'tests/helpers/pivi_fake.lua'
local notices
describe( 'pivi command', function()
local original_notify, original_select
before_each( function()
notices = {}
original_notify = vim.notify
original_select = vim.ui.select
vim.notify = function( message, level ) table.insert( notices, { message, level, } ) end
end )
after_each( function()
fake.drain()
vim.notify = original_notify
vim.ui.select = original_select
session.stop_all()
transcript.forget_all()
publish.reset()
fake.close_extra_windows()
vim.cmd 'silent! %bwipeout!'
pcall( vim.api.nvim_del_user_command, 'Pi' )
end )
describe( 'slash entry', function()
it( 'opens only at the first character of a pivi input buffer', function()
local bufnr = vim.api.nvim_create_buf( false, true )
vim.bo[bufnr].filetype = command.input_filetype
assert.is_true( command.slash_opens_commands( bufnr, 0 ) )
assert.is_false( command.slash_opens_commands( bufnr, 1 ) )
assert.is_false( command.slash_opens_commands( bufnr, 7 ) )
end )
it( 'gives the prompt window an identity and its submit hint', function()
local channel = fake.new()
local current = session.create { spawn = channel.spawn, name = 'spec', extension = false, skill = false, env = {}, }
local bufnr = command.open_prompt( current )
local win = vim.fn.bufwinid( bufnr )
assert.is_true( win > 0 )
assert.is_true( vim.wo[win].winbar:find( 'spec', 1, true ) ~= nil )
assert.is_true( vim.wo[win].winbar:find( 'send', 1, true ) ~= nil )
assert.is_true( vim.api.nvim_buf_get_name( bufnr ):find( 'pivi://', 1, true ) ~= nil )
assert.equal( 'spec', vim.b[bufnr].pivi_session )
vim.cmd.stopinsert()
end )
it( 'shows the transcript after a prompt submission', function()
local channel = fake.new()
local current = session.create { spawn = channel.spawn, name = 'spec', extension = false, skill = false, env = {}, }
local bufnr = command.open_prompt( current )
vim.cmd.stopinsert()
vim.api.nvim_buf_set_lines( bufnr, 0, -1, false, { 'do the thing', } )
local mapping
for _, entry in ipairs( vim.api.nvim_buf_get_keymap( bufnr, 'n' ) ) do
if entry.lhs == '<Plug>(pivi-submit)' then mapping = entry end
end
assert.is_table( mapping )
mapping.callback()
assert.is_true( vim.fn.bufwinid( current.buffer ) > 0 )
assert.same( { '', }, vim.api.nvim_buf_get_lines( bufnr, 0, -1, false ) )
end )
it( 'reuses the prompt of a session and keeps an unfinished draft', function()
local channel = fake.new()
local current = session.create { spawn = channel.spawn, name = 'spec', extension = false, skill = false, env = {}, }
local first = command.open_prompt( current )
vim.cmd.stopinsert()
vim.api.nvim_buf_set_lines( first, 0, -1, false, { 'my unfinished draft', } )
local again = command.open_prompt( current )
vim.cmd.stopinsert()
assert.equal( first, again )
assert.same( { 'my unfinished draft', }, vim.api.nvim_buf_get_lines( again, 0, -1, false ) )
local alive = 0
for _, bufnr in ipairs( vim.api.nvim_list_bufs() ) do
if vim.bo[bufnr].filetype == command.input_filetype then alive = alive + 1 end
end
assert.equal( 1, alive )
end )
it( 'never opens in an ordinary buffer', function()
vim.cmd 'enew'
local bufnr = vim.api.nvim_get_current_buf()
assert.is_false( command.slash_opens_commands( bufnr, 0 ) )
end )
it( 'never opens in an invalid buffer', function()
local bufnr = vim.api.nvim_create_buf( false, true )
vim.api.nvim_buf_delete( bufnr, { force = true, } )
assert.is_false( command.slash_opens_commands( bufnr, 0 ) )
end )
it( 'keeps ordinary search behavior away from the first character', function()
local channel = fake.new()
local current = session.create { spawn = channel.spawn, name = 'spec', extension = false, skill = false, env = {}, }
local bufnr = command.open_prompt( current )
vim.api.nvim_buf_set_lines( bufnr, 0, -1, false, { 'hello', } )
vim.api.nvim_win_set_cursor( 0, { 1, 3, } )
local mapping
for _, entry in ipairs( vim.api.nvim_buf_get_keymap( bufnr, 'n' ) ) do
if entry.lhs == '/' then mapping = entry end
end
assert.is_table( mapping )
assert.equal( '/', mapping.callback() )
end )
end )
describe( 'dispatch', function()
it( 'registers the user command and its subcommand completion', function()
command.setup()
assert.is_table( vim.api.nvim_get_commands( {} ).Pi )
local names = command.names()
assert.is_true( vim.list_contains( names, 'ask' ) )
assert.is_true( vim.list_contains( names, 'help' ) )
assert.is_true( vim.list_contains( names, 'command' ) )
end )
it( 'opens the prompt when given no subcommand', function()
local channel = fake.new()
session.create { spawn = channel.spawn, name = 'spec', extension = false, skill = false, env = {}, }
command.dispatch { args = '', }
local opened
for _, bufnr in ipairs( vim.api.nvim_list_bufs() ) do
if vim.bo[bufnr].filetype == command.input_filetype then opened = bufnr end
end
assert.is_number( opened )
assert.is_true( vim.fn.bufwinid( opened ) > 0 )
vim.cmd.stopinsert()
end )
it( 'reports an unknown subcommand', function()
command.dispatch { args = 'levitate', }
assert.equal( 1, #notices )
assert.equal( vim.log.levels.ERROR, notices[1][2] )
end )
it( 'refuses an empty question', function()
command.dispatch { args = 'help', }
assert.equal( vim.log.levels.WARN, notices[1][2] )
end )
it( 'reports that nothing is running when no session exists', function()
command.dispatch { args = 'abort', }
assert.equal( vim.log.levels.WARN, notices[1][2] )
end )
end )
describe( 'slash commands', function()
it( 'refuses a name pi does not offer, instead of saying it to the model', function()
local channel = fake.new()
local current = session.create { spawn = channel.spawn, name = 'spec', extension = false, skill = false, env = {}, }
command.subcommands.command 'model'
local request
for _, entry in ipairs( channel.commands ) do
if entry.type == 'get_commands' then request = entry end
end
assert.is_table( request )
channel.frame {
id = request.id,
type = 'response',
command = 'get_commands',
success = true,
data = { commands = { { name = 'compact', source = 'extension', }, }, },
}
assert.is_true( channel.settle( function() return #notices > 0 end ) )
-- Nothing was said to the model.
for _, entry in ipairs( channel.commands ) do
assert.is_not.equal( 'prompt', entry.type )
end
assert.equal( vim.log.levels.WARN, notices[#notices][2] )
assert.is_true( notices[#notices][1]:find( 'model', 1, true ) ~= nil )
end )
it( 'runs a name pi does offer', function()
local channel = fake.new()
local current = session.create { spawn = channel.spawn, name = 'spec', extension = false, skill = false, env = {}, }
command.subcommands.command 'compact focus on edits'
local request
for _, entry in ipairs( channel.commands ) do
if entry.type == 'get_commands' then request = entry end
end
channel.frame {
id = request.id,
type = 'response',
command = 'get_commands',
success = true,
data = { commands = { { name = 'compact', source = 'extension', }, }, },
}
assert.is_true( channel.settle( function()
for _, entry in ipairs( channel.commands ) do
if entry.type == 'prompt' then return true end
end
return false
end ) )
local prompts = {}
for _, entry in ipairs( channel.commands ) do
if entry.type == 'prompt' then table.insert( prompts, entry ) end
end
assert.equal( 1, #prompts )
assert.equal( '/compact focus on edits', prompts[1].message )
end )
it( 'filters the picker on the command name alone', function()
local channel = fake.new()
local current = session.create { spawn = channel.spawn, name = 'spec', extension = false, skill = false, env = {}, }
local offered
vim.ui.select = function( items, options, on_choice )
offered = vim.tbl_map( options.format_item, items )
on_choice( nil )
end
command.subcommands.command ''
local request
for _, entry in ipairs( channel.commands ) do
if entry.type == 'get_commands' then request = entry end
end
channel.frame {
id = request.id,
type = 'response',
command = 'get_commands',
success = true,
data = { commands = {
{ name = 'compact', description = 'Compact the conversation context', source = 'extension', },
}, },
}
assert.is_true( channel.settle( function() return offered ~= nil end ) )
assert.same( { '/compact', }, offered )
end )
it( 'reports when pi offers no commands', function()
local channel = fake.new()
session.create { spawn = channel.spawn, name = 'spec', extension = false, skill = false, env = {}, }
command.subcommands.command ''
local request
for _, entry in ipairs( channel.commands ) do
if entry.type == 'get_commands' then request = entry end
end
channel.frame {
id = request.id,
type = 'response',
command = 'get_commands',
success = true,
data = { commands = {}, },
}
assert.is_true( channel.settle( function() return #notices > 0 end ) )
assert.equal( vim.log.levels.WARN, notices[#notices][2] )
end )
end )
describe( 'completion', function()
it( 'completes subcommands at the first word', function()
command.setup()
local offered = vim.fn.getcompletion( 'Pi ', 'cmdline' )
assert.is_true( vim.list_contains( offered, 'command' ) )
assert.is_true( vim.list_contains( offered, 'model' ) )
end )
it( 'completes the names pi actually offers after `command`', function()
command.setup()
local channel = fake.new()
local current = session.create { spawn = channel.spawn, name = 'spec', extension = false, skill = false, env = {}, }
current.commands = {
{ name = 'compact', source = 'extension', },
{ name = 'skill:wiki', source = 'skill', },
}
local offered = vim.fn.getcompletion( 'Pi command ', 'cmdline' )
assert.is_true( vim.list_contains( offered, 'compact' ) )
assert.is_true( vim.list_contains( offered, 'skill:wiki' ) )
end )
it( 'completes follow modes', function()
command.setup()
local offered = vim.fn.getcompletion( 'Pi follow ', 'cmdline' )
assert.is_true( vim.list_contains( offered, 'window' ) )
assert.is_true( vim.list_contains( offered, 'tab' ) )
end )
end )
describe( 'follow', function()
it( 'toggles follow mode and reports it', function()
command.subcommands.follow ''
assert.is_true( notices[1][1]:find( 'window', 1, true ) ~= nil )
command.subcommands.follow ''
assert.is_true( notices[2][1]:find( 'off', 1, true ) ~= nil )
end )
end )
end )