nvim-neotest / neotest

An extensible framework for interacting with tests within NeoVim.
MIT License
2.12k stars 105 forks source link

fix: no autocommand file name to substitute for <afile> #416

Closed stevearc closed 3 weeks ago

stevearc commented 1 month ago

I encountered a bunch of error in Neotest when I started Neovim in verbose mode (nvim -V1), coming from these autocmds. Turns out, when expand() fails in verbose mode it will throw an error instead of expanding to the empty string (see https://github.com/neovim/neovim/issues/29175). You can reproduce the issue using the minimal init file below:

-- save as repro.lua
-- run with nvim -V1 -u repro.lua
local root = vim.fn.fnamemodify("./.repro", ":p")

-- set stdpaths to use .repro
for _, name in ipairs({ "config", "data", "state", "runtime", "cache" }) do
  vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
end

vim.g.mapleader = " "
-- bootstrap lazy
local lazypath = root .. "/plugins/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({
    "git",
    "clone",
    "--filter=blob:none",
    "--single-branch",
    "https://github.com/folke/lazy.nvim.git",
    lazypath,
  })
end
vim.opt.runtimepath:prepend(lazypath)

-- install plugins
local plugins = {
  {
    "nvim-treesitter/nvim-treesitter",
    config = function()
      require("nvim-treesitter.configs").setup({
        ensure_installed = {
          "python",
        },
        auto_install = true,
      })
    end,
  },
  {
    "nvim-neotest/neotest",
    dependencies = {
      "nvim-lua/plenary.nvim",
      "nvim-neotest/neotest-python",
      "nvim-neotest/nvim-nio",
      "nvim-treesitter/nvim-treesitter",
    },
    keys = {
      {
        "<leader>tf",
        function()
          require("neotest").run.run({ vim.api.nvim_buf_get_name(0) })
        end,
        desc = "[T]est [F]ile",
      },
    },
    config = function()
      require("neotest").setup({
        adapters = {
          require("neotest-python")({}),
        },
      })
    end,
  },
  -- add any other plugins here
}
require("lazy").setup(plugins, {
  root = root .. "/plugins",
})

To see the errors, do

  1. nvim -V1 -u repro.lua test.py (test.py is just some python file with a test)
  2. <leader>tf to run tests
  3. :tabnew
Error detected while processing BufAdd Autocommands for "*":
Error executing lua callback: Vim:E495: No autocommand file name to substitute for "<afile>"
stack traceback:
        [C]: in function 'expand'
        ...e/tmp/.repro/plugins/neotest/lua/neotest/client/init.lua:394: in function <...e/tmp/.repro/plugins/neotest/lua/neotest/client/init.lua:393>
Error executing lua callback: Vim:E495: No autocommand file name to substitute for "<afile>"
stack traceback:
        [C]: in function 'expand'
        ...e/tmp/.repro/plugins/neotest/lua/neotest/client/init.lua:450: in function <...e/tmp/.repro/plugins/neotest/lua/neotest/client/init.lua:449>
Error detected while processing BufEnter Autocommands for "*":
Error executing lua callback: Vim:E495: No autocommand file name to substitute for "<afile>"
stack traceback:
        [C]: in function 'expand'
        ...e/tmp/.repro/plugins/neotest/lua/neotest/client/init.lua:464: in function <...e/tmp/.repro/plugins/neotest/lua/neotest/client/init.lua:463>
Error executing lua callback: Vim:E495: No autocommand file name to substitute for "<afile>"
stack traceback:
        [C]: in function 'expand'
        ...e/tmp/.repro/plugins/neotest/lua/neotest/client/init.lua:476: in function <...e/tmp/.repro/plugins/neotest/lua/neotest/client/init.lua:475>

The workaround I'm applying here is to use the data in the autocmd callback to get the afile instead of calling expand()

stevearc commented 1 month ago

Could not get the test failure to repro locally, is it possible that it's a flake?

rcarriga commented 3 weeks ago

Thanks for the fix! Yeah it looks like a flaky test to me, so LGTM