Closed rebelot closed 1 year ago
This is not yet possible, it would require a new consumer. Happy to take contributions :smile:
I'm trying to write a consumer, which kinda works so far. However, the client:get_results() method returns the results for single tests and for the entire test file and I haven't found a "comfortable" way to separate the two kind of results
You probably want to iterate through the tree and get the results for only tests
local results = client:get_results(adapter_id)
local tree = client:get_position(root_id, { adapter = adapter_id })
for _, pos in tree:iter() do
if pos.type == "test" then
...
end
end
Results can come in very often when streamed so I'd recommend having some sort of caching to prevent a tonne of work being done. You could just mark the cache as invalid on a results event and then recalculate when the status is requested
consumers = {
statusline = function(client)
return {
statusline = function()
local adapters = client:get_adapters()
local statuses = {}
local root_id = vim.api.nvim_buf_get_name(0)
for _, adapter_id in ipairs(adapters) do
local results = client:get_results(adapter_id)
local tree = client:get_position(root_id, { adapter = adapter_id })
if not tree then
return
end
for _, pos in tree:iter() do
if pos.type == "test" then
local id = pos.id
if results[id] then
table.insert(statuses, results[id].status)
else
table.insert(statuses, "none")
end
end
end
end
local status_dict = { total = 0, failed = 0, passed = 0 }
for _, s in ipairs(statuses) do
if s == "failed" then
status_dict.failed = status_dict.failed + 1
elseif s == "passed" then
status_dict.passed = status_dict.passed + 1
elseif s == "none" then
status_dict.total = status_dict.total + 1
end
end
status_dict.total = status_dict.total + status_dict.failed + status_dict.passed
return status_dict
end,
}
end,
},
I came up with something like this, but I am not yet so sure it's worth it given the completeness of the summary
consumer...
Your logic around adapters means that if it doesn't match the first adapter, it will always return nil. Also you can simplify the status handling a bit.
---@param client neotest.Client
statusline = function(client)
return {
statusline = function()
local adapters = client:get_adapters()
if not client:has_started() then
return
end
local root_id = vim.api.nvim_buf_get_name(0)
for _, adapter_id in ipairs(adapters) do
local results = client:get_results(adapter_id)
local tree = client:get_position(root_id, { adapter = adapter_id })
if tree then
local status_dict = { total = 0, failed = 0, passed = 0, skipped = 0 }
for _, pos in tree:iter() do
if pos.type == "test" then
status_dict.total = status_dict.total + 1
if results[pos.id] then
status_dict[results[pos.id].status] = status_dict[results[pos.id].status] + 1
end
end
end
return status_dict
end
end
end,
}
end,
Depending on statusline integration this will be called thousands of times within a minute or two, hence why the suggestion of caching. I tested locally and my fans started spinning just from adding this :sweat_smile:
Closing this as the new state
consumer provides a cache for results
Hi, is it possible to retrieve a table of informations to be displayed in custom statuslines? something like:
maybe it is already possible given the large API of neotest but I couldn't find a way to access tests results