Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

neovim/tests/drive/run.lua

Raw
---@diagnostic disable: need-check-nil, undefined-field, param-type-mismatch, assign-type-mismatch
-- Drives a live Neovim over RPC and asserts pivi's interactive behavior.
-- Run with: just drive
--
-- The server is a real Neovim with the real configuration runtime path, so
-- keymaps, user commands, autocommands, and buffer state behave as they do
-- for a person. Requests are synchronous, so no scenario sleeps.

local ADDRESS = '127.0.0.1:' .. tostring( 6800 + math.random( 1, 180 ) )

local server = vim.system( {
  vim.v.progpath,
  '--headless',
  '--noplugin',
  '-u', 'tests/minimal_init.lua',
  '--listen', ADDRESS,
}, { stdout = false, stderr = false, } )

local channel
local connected = vim.wait( 20000, function()
  local ok, value = pcall( vim.fn.sockconnect, 'tcp', ADDRESS, { rpc = true, } )
  if ok and value ~= 0 then
    channel = value
    return true
  end
  return false
end, 100 )

if not connected then
  io.stderr:write( 'cannot reach the driven neovim at ' .. ADDRESS .. '\n' )
  server:kill 'sigterm'
  os.exit( 1 )
end

local remote = function( code, arguments )
  return vim.rpcrequest( channel, 'nvim_exec_lua', code, arguments or {} )
end

local failures = {}

local scenario = function( name, body )
  local ok, failure = pcall( body )
  if ok then
    print( 'ok   ' .. name )
  else
    failures[#failures + 1] = name
    print( 'FAIL ' .. name .. ': ' .. tostring( failure ) )
  end
end

local expect = function( condition, message )
  if not condition then error( message or 'expectation failed', 2 ) end
end

remote [[
  local command = require 'bugabinga.pivi.command'
  command.setup()
  _G.DRIVE = { picked = false }
  vim.ui.select = function( items, _, on_choice )
    _G.DRIVE.picked = true
    on_choice( nil )
  end
  return true
]]

scenario( 'the Pi user command exists with subcommand completion', function()
  local names = remote [[
    return vim.fn.getcompletion('Pi ', 'cmdline')
  ]]
  expect( vim.list_contains( names, 'ask' ), 'ask is missing from completion' )
  expect( vim.list_contains( names, 'help' ), 'help is missing from completion' )
end )

scenario( 'an unknown subcommand is reported rather than executed', function()
  local message = remote [[
    local seen
    local original = vim.notify
    vim.notify = function(text) seen = text end
    vim.cmd 'Pi levitate'
    vim.notify = original
    return seen
  ]]
  expect( type( message ) == 'string', 'no message was shown' )
  expect( message:find( 'levitate', 1, true ) ~= nil, 'the message does not name the subcommand' )
end )

scenario( 'slash opens command entry only on the first character', function()
  local result = remote [[
    local session = require 'bugabinga.pivi.session'
    local command = require 'bugabinga.pivi.command'
    local current = setmetatable(
      { name = 'drive', buffer = vim.api.nvim_create_buf(false, true) },
      { __index = function() return function() end end }
    )
    local bufnr = command.open_prompt(current)
    vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, { 'hello' })
    return {
      first = command.slash_opens_commands(bufnr, 0),
      later = command.slash_opens_commands(bufnr, 3),
      filetype = vim.bo[bufnr].filetype,
    }
  ]]
  expect( result.first == true, 'slash does not open at the first character' )
  expect( result.later == false, 'slash wrongly opens later in the line' )
  expect( result.filetype == 'pivi-input', 'the prompt buffer has the wrong filetype' )
end )

scenario( 'typing slash later in the line still searches', function()
  local typed = remote [[
    vim.cmd 'normal! ggdG'
    vim.api.nvim_buf_set_lines(0, 0, -1, false, { 'alpha beta' })
    vim.api.nvim_win_set_cursor(0, { 1, 4 })
    _G.DRIVE.picked = false
    local mapping
    for _, entry in ipairs(vim.api.nvim_buf_get_keymap(0, 'n')) do
      if entry.lhs == '/' then mapping = entry end
    end
    return { produced = mapping.callback(), picked = _G.DRIVE.picked }
  ]]
  expect( typed.produced == '/', 'slash was swallowed away from the first character' )
  expect( typed.picked == false, 'the command picker opened away from the first character' )
end )

scenario( 'status consumers read cached state without any pi process', function()
  local summary = remote [[
    local publish = require 'bugabinga.pivi.publish'
    local status = require 'bugabinga.pivi.status'
    publish.reset()
    local empty = publish.summary()
    publish.session_status('drive', status.reduce(status.initial(), { type = 'agent_start' }))
    return { empty = empty, running = publish.summary('drive') }
  ]]
  expect( summary.empty == '', 'an unpublished statusline is not empty' )
  expect( summary.running == 'pi:run', 'the cached statusline is wrong: ' .. tostring( summary.running ) )
end )

scenario( 'the companion client reaches the running neovim', function()
  local directory = vim.fn.tempname()
  vim.fn.mkdir( directory, 'p' )
  local request = directory .. '/request.json'
  local response = directory .. '/response.json'

  vim.fn.writefile( { vim.json.encode { action = 'help', tag = 'quickfix', }, }, request )

  local client = vim.system( {
    vim.v.progpath,
    '--headless', '--clean',
    '-l', 'lua/bugabinga/pivi/extension/client.lua',
    ADDRESS, request, response,
  }, { stdout = false, stderr = false, } ):wait( 30000 )

  expect( client.code == 0, 'the client exited with ' .. tostring( client.code ) )

  local answer = vim.json.decode( table.concat( vim.fn.readfile( response ), '\n' ) )
  expect( answer.ok == true, 'the bridge refused: ' .. tostring( answer.error ) )
  expect( answer.found == true, 'the help tag did not resolve' )
  expect( answer.file == 'quickfix.txt', 'unexpected help file: ' .. tostring( answer.file ) )
end )

scenario( 'the companion client reports an unreachable neovim', function()
  local directory = vim.fn.tempname()
  vim.fn.mkdir( directory, 'p' )
  local request = directory .. '/request.json'
  local response = directory .. '/response.json'
  vim.fn.writefile( { vim.json.encode { action = 'state', }, }, request )

  vim.system( {
    vim.v.progpath,
    '--headless', '--clean',
    '-l', 'lua/bugabinga/pivi/extension/client.lua',
    '127.0.0.1:6', request, response,
  }, { stdout = false, stderr = false, } ):wait( 30000 )

  local answer = vim.json.decode( table.concat( vim.fn.readfile( response ), '\n' ) )
  expect( answer.ok == false, 'an unreachable neovim was reported as success' )
end )

pcall( vim.fn.chanclose, channel )
server:kill 'sigterm'

if #failures > 0 then
  print( tostring( #failures ) .. ' scenario(s) failed' )
  os.exit( 1 )
end

print 'all drive scenarios passed'