[BUG] No tests found if calling require("plenary.filetype") before Neotest does it
NeoVim Version
v0.11.1
Describe the bug
When another plugin calls require("plenary.filetype") before Neotest does, it seems that Neotest cannot successfully complete the call to require("neotest.lib").treesitter.parse_positions and does not find any tests.
Note this issue in CopilotChat which describes how I found this issue: https://github.com/CopilotC-Nvim/CopilotChat.nvim/issues/1099
When calling require("neotest.lib").treesitter.parse_positions, you end up in this code path:
logger.error("Couldn't find positions in path", path, debug.traceback(msg, 2))
I started the debugger and found out that msg is Invalid language name "", using the neotest-golang adapter:
msg = ...k/.local/share/fredrik/lazy/nvim-nio/lua/nio/control.lua:145: ...m/share/nvim/runtime/lua/vim/treesitter/languagetree.lua:125: Invalid language name ""
stack traceback:
[C]: in function 'assert'
...m/share/nvim/runtime/lua/vim/treesitter/languagetree.lua:125: in function 'get_string_parser'
...fredrik/lazy/neotest/lua/neotest/lib/treesitter/init.lua:119: in function 'get_parse_root'
...fredrik/lazy/neotest/lua/neotest/lib/treesitter/init.lua:160: in function 'parse_positions_from_string'
...fredrik/lazy/neotest/lua/neotest/lib/treesitter/init.lua:207: in function 'func'
...hare/fredrik/lazy/neotest/lua/neotest/lib/subprocess.lua:156: in function <...hare/fredrik/lazy/neotest/lua/neotest/lib/subprocess.lua:155>
[C]: in function 'xpcall'
...hare/fredrik/lazy/neotest/lua/neotest/lib/subprocess.lua:155: in function <...hare/fredrik/lazy/neotest/lua/neotest/lib/subprocess.lua:154>
logger = table: 0x01068a4730
path = /Users/fredrik/code/public/neotest-golang/tests/go/internal/positions/positions_test.go
Here's a full traceback from the neotest-plenary adapter:
neotest-plenary: ...drik/.local/share/fredrik/lazy/nvim-nio/lua/nio/init.lua:119: The coroutine failed with this message:
...k/.local/share/fredrik/lazy/nvim-nio/lua/nio/control.lua:145: ...m/share/nvim/runtime/lua/vim/treesitter/languagetree.lua:125: Invalid language name ""
stack traceback:
[C]: in function 'assert'
...m/share/nvim/runtime/lua/vim/treesitter/languagetree.lua:125: in function 'get_string_parser'
...fredrik/lazy/neotest/lua/neotest/lib/treesitter/init.lua:119: in function 'get_parse_root'
...fredrik/lazy/neotest/lua/neotest/lib/treesitter/init.lua:160: in function 'parse_positions_from_string'
...fredrik/lazy/neotest/lua/neotest/lib/treesitter/init.lua:207: in function 'func'
...hare/fredrik/lazy/neotest/lua/neotest/lib/subprocess.lua:156: in function <...hare/fredrik/lazy/neotest/lua/neotest/lib/subprocess.lua:155>
[C]: in function 'xpcall'
...hare/fredrik/lazy/neotest/lua/neotest/lib/subprocess.lua:155: in function <...hare/fredrik/lazy/neotest/lua/neotest/lib/subprocess.lua:154>
stack traceback:
[C]: in function 'error'
...k/.local/share/fredrik/lazy/nvim-nio/lua/nio/control.lua:145: in function 'call'
...fredrik/lazy/neotest/lua/neotest/lib/treesitter/init.lua:189: in function 'discover_positions'
...rik/lazy/neotest-plenary/lua/neotest-plenary/adapter.lua:109: in function 'results'
...share/fredrik/lazy/neotest/lua/neotest/client/runner.lua:132: in function '_run_spec'
...share/fredrik/lazy/neotest/lua/neotest/client/runner.lua:89: in function <...share/fredrik/lazy/neotest/lua/neotest/client/runner.lua:88>
stack traceback:
...l/share/fredrik/lazy/neotest/lua/neotest/client/init.lua:89: in function <...l/share/fredrik/lazy/neotest/lua/neotest/client/init.lua:88>
[C]: in function 'error'
...drik/.local/share/fredrik/lazy/nvim-nio/lua/nio/init.lua:119: in function 'gather'
...share/fredrik/lazy/neotest/lua/neotest/client/runner.lua:94: in function '_run_tree'
...share/fredrik/lazy/neotest/lua/neotest/client/runner.lua:65: in function <...share/fredrik/lazy/neotest/lua/neotest/client/runner.lua:22>
[C]: in function 'xpcall'
...l/share/fredrik/lazy/neotest/lua/neotest/client/init.lua:84: in function 'run_tree'
...share/fredrik/lazy/neotest/lua/neotest/consumers/run.lua:85: in function 'func'
...rik/.local/share/fredrik/lazy/nvim-nio/lua/nio/tasks.lua:169: in function <...rik/.local/share/fredrik/lazy/nvim-nio/lua/nio/tasks.lua:168>
To Reproduce
The following will set up the neotest-golang adapter and it won't be able to detect any tests in *.go files, as require("plenary.filetype") was called before Neotest does it (when it detects tests).
vim.opt.runtimepath:remove(vim.fn.expand("~/.config/nvim"))
vim.opt.packpath:remove(vim.fn.expand("~/.local/share/nvim/site"))
local lazypath = "/tmp/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git",
"clone",
"--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable", -- latest stable release
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
require("lazy").setup({
"nvim-neotest/neotest",
dependencies = {
"nvim-lua/plenary.nvim",
"nvim-treesitter/nvim-treesitter",
-- Install adapters here
"fredrikaverpil/neotest-golang",
},
config = function()
-- Trigger bug
require("plenary.filetype")
-- Install any required parsers
require("nvim-treesitter.configs").setup({
ensure_installed = { "go" },
})
require("neotest").setup({
-- Add adapters to the list
adapters = { "neotest-golang" },
})
end,
})
Here's a sample go test:
// foo_test.go
package main
import "testing"
func Add(a, b int) int {
return a + b
}
func TestAdd(t *testing.T) {
result := Add(2, 3)
if result != 5 {
t.Errorf("Expected 5, but got %d", result)
}
}
Steps to reproduce the behavior:
- Launch Neovim with the
minimal.lua:nvim --clean -u minimal.lua - Open the Go test file.
- Open the test summary panel.
- Notice how no tests are shown for the Go file.
Now comment out require("plenary.filetype") from minimal.lua and try again. The test is shown.
Expected behavior
The test should show regardless of whether require("plenary.filetype") was called prior to Neotest doing it or not.
Logs
N/A
Additional context
If you make sure that Neotest calls require("plenary.filetype") before e.g. CopilotChat does, both plugins works as expected.
It's possible that this is a plenary bug?
@fredrikaverpil It's happening to me too. I dig into it myself and I'm erroring out on neotest.Client:get_nearest: no nodes are found, the range is always nil. Is this what you experience? You talk here about plenary. I don't know if it's related. Do you have a fix?
@ruicsh Not sure without more information. Share the full stack trace? You get the same error in the crash as mentioned above?
I solved it on my end by changing up when Neotest (with its require("plenary.filetype")) is loaded, as mentioned above.
hey @fredrikaverpil thanks for your response. Mine doesn't crash, it just prints out "No tests found" and doesn't run any tests. But, it's also because of 'copilot-chat' plugin. If I disable it, 'neotest' works fine. You mentioned you were able to fix it by making sure neotest gets loaded before copilot-chat? How did you do that, with lazy events?
Hopefully this helps (just a workaround): https://github.com/CopilotC-Nvim/CopilotChat.nvim/pull/1162
hey @fredrikaverpil yes it helped, made neotest work. But, I ended up using vim-test. I prefer to have the output panel open a full height vertical split and I couldn't really do it with neotest and it was really easy with vim-test. But thanks for your time. :)
hey @fredrikaverpil thanks for your response. Mine doesn't crash, it just prints out "No tests found" and doesn't run any tests. But, it's also because of 'copilot-chat' plugin. If I disable it, 'neotest' works fine. You mentioned you were able to fix it by making sure neotest gets loaded before copilot-chat? How did you do that, with lazy events?
Mine was also not crashing but I finally found the issue. As nothing was working I searched for alternatives and nvim-test gave me the final clue, at least for me, when I got a message complaining about no treesitter parser for ruby present.
So the solution was installing the parser, in my case with TSInstall ruby, then neotest is already working as always.
In README section for writing adapters it mentions the use of treesitter to parse the tests, but maybe it's worth to add a warning to run checkhealth to check for missing language parsers when "tests not found" error is shown.
This plugin is a must in my neovim config, I hope this helps others too.
I've got something bizarre happening. I share the same config across my macOS laptop and my Arch desktop.
I have the issue where no tests are found (any adapter) on my Arch machine, but works flawlessly on my macOS.
I've found my solution to why my Golang tests aren't being found:
{ "fredrikaverpil/neotest-golang", commit = "cac1039" }, -- Pin to before statement_list change
Essentially, the neotest-golang is using a newer feature that's available in nvim-treesitter 0.11.0 and I was on 0.10.0
● Looking at the debugging we did, here's why we
pinned to commit cac1039:
The Problem
TreeSitter Node Type Mismatch
When we enabled debug logging and read the neotest
log file at ~/.local/state/nvim/neotest.log, we
found this critical error:
Query error at 75:4. Invalid node type
"statement_list"
This meant:
- neotest-golang (newer versions) uses TreeSitter
queries that reference a statement_list node type
- Your nvim-treesitter Go parser (v0.10.0) uses
the older block node type instead
- When neotest-golang tried to parse your Go test
files, the TreeSitter query failed because
statement_list didn't exist in your parser
Why Commit cac1039?
This specific commit represents the last version
of neotest-golang before the statement_list node
type was introduced. By pinning to it:
1. The plugin uses TreeSitter queries with block
(which your parser understands)
2. Test detection works correctly
3. You avoid the query parsing error
Why Not Update TreeSitter Instead?
We tried updating nvim-treesitter, but it was
already at the latest version available in your
setup. The newer Go parser grammar that includes
statement_list wasn't available yet in your
nvim-treesitter version.
The Trade-off
Pinning to cac1039 means you're using a slightly
older version of neotest-golang, but it's the
pragmatic solution that makes everything work with
your current TreeSitter setup. When you
eventually update nvim-treesitter to a version
with the newer Go parser, you can remove the
commit pin and use the latest neotest-golang.
@hahuang65 your issue is unrelated to the plenary.filetype issue I originally reported here.
@hahuang65 your issue is unrelated to the plenary.filetype issue I originally reported here.
Yeah, I'm sorry. I got confused and thought I was posting the message in #495