1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-02-03 05:50:05 +08:00
SpaceVim/bundle/plenary.nvim/lua/plenary/test_harness.lua
2022-05-16 22:20:10 +08:00

203 lines
4.7 KiB
Lua

local Path = require "plenary.path"
local Job = require "plenary.job"
local f = require "plenary.functional"
local log = require "plenary.log"
local win_float = require "plenary.window.float"
local headless = require("plenary.nvim_meta").is_headless
local harness = {}
local print_output = vim.schedule_wrap(function(_, ...)
for _, v in ipairs { ... } do
io.stdout:write(tostring(v))
io.stdout:write "\n"
end
vim.cmd [[mode]]
end)
local get_nvim_output = function(job_id)
return vim.schedule_wrap(function(bufnr, ...)
if not vim.api.nvim_buf_is_valid(bufnr) then
return
end
for _, v in ipairs { ... } do
vim.api.nvim_chan_send(job_id, v .. "\r\n")
end
end)
end
function harness.test_directory_command(command)
local split_string = vim.split(command, " ")
local directory = table.remove(split_string, 1)
local opts = assert(loadstring("return " .. table.concat(split_string, " ")))()
return harness.test_directory(directory, opts)
end
function harness.test_directory(directory, opts)
print "Starting..."
opts = vim.tbl_deep_extend("force", {
winopts = { winblend = 3 },
sequential = false,
keep_going = true,
timeout = 50000,
}, opts or {})
local res = {}
if not headless then
res = win_float.percentage_range_window(0.95, 0.70, opts.winopts)
res.job_id = vim.api.nvim_open_term(res.bufnr, {})
vim.api.nvim_buf_set_keymap(res.bufnr, "n", "q", ":q<CR>", {})
vim.api.nvim_win_set_option(res.win_id, "winhl", "Normal:Normal")
vim.api.nvim_win_set_option(res.win_id, "conceallevel", 3)
vim.api.nvim_win_set_option(res.win_id, "concealcursor", "n")
if res.border_win_id then
vim.api.nvim_win_set_option(res.border_win_id, "winhl", "Normal:Normal")
end
if res.bufnr then
vim.api.nvim_buf_set_option(res.bufnr, "filetype", "PlenaryTestPopup")
end
vim.cmd "mode"
end
local outputter = headless and print_output or get_nvim_output(res.job_id)
local paths = harness._find_files_to_run(directory)
local path_len = #paths
local failure = false
local jobs = vim.tbl_map(function(p)
local args = {
"--headless",
"-c",
string.format('lua require("plenary.busted").run("%s")', p:absolute()),
}
if opts.minimal ~= nil then
table.insert(args, "--noplugin")
elseif opts.minimal_init ~= nil then
table.insert(args, "--noplugin")
table.insert(args, "-u")
table.insert(args, opts.minimal_init)
end
local job = Job:new {
command = vim.v.progpath,
args = args,
-- Can be turned on to debug
on_stdout = function(_, data)
if path_len == 1 then
outputter(res.bufnr, data)
end
end,
on_stderr = function(_, data)
if path_len == 1 then
outputter(res.bufnr, data)
end
end,
on_exit = vim.schedule_wrap(function(j_self, _, _)
if path_len ~= 1 then
outputter(res.bufnr, unpack(j_self:stderr_result()))
outputter(res.bufnr, unpack(j_self:result()))
end
vim.cmd "mode"
end),
}
job.nvim_busted_path = p.filename
return job
end, paths)
log.debug "Running..."
for i, j in ipairs(jobs) do
outputter(res.bufnr, "Scheduling: " .. j.nvim_busted_path)
j:start()
if opts.sequential then
log.debug("... Sequential wait for job number", i)
Job.join(j, opts.timeout)
log.debug("... Completed job number", i)
if j.code ~= 0 then
failure = true
if not opts.keep_going then
break
end
end
end
end
-- TODO: Probably want to let people know when we've completed everything.
if not headless then
return
end
if not opts.sequential then
table.insert(jobs, opts.timeout)
log.debug "... Parallel wait"
Job.join(unpack(jobs))
log.debug "... Completed jobs"
table.remove(jobs, table.getn(jobs))
failure = f.any(function(_, v)
return v.code ~= 0
end, jobs)
end
vim.wait(100)
if headless then
if failure then
return vim.cmd "1cq"
end
return vim.cmd "0cq"
end
end
function harness._find_files_to_run(directory)
local finder = Job:new {
command = "find",
args = { directory, "-type", "f", "-name", "*_spec.lua" },
}
return vim.tbl_map(Path.new, finder:sync())
end
function harness._run_path(test_type, directory)
local paths = harness._find_files_to_run(directory)
local bufnr = 0
local win_id = 0
for _, p in pairs(paths) do
print " "
print("Loading Tests For: ", p:absolute(), "\n")
local ok, _ = pcall(function()
dofile(p:absolute())
end)
if not ok then
print "Failed to load file"
end
end
harness:run(test_type, bufnr, win_id)
vim.cmd "qa!"
return paths
end
return harness