-
-
Notifications
You must be signed in to change notification settings - Fork 331
Expand file tree
/
Copy pathtest_harness.lua
More file actions
215 lines (171 loc) · 5.1 KB
/
test_harness.lua
File metadata and controls
215 lines (171 loc) · 5.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
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)
-- TODO: this is broken if we pass mutliple args!
-- figure out if there is a way to call vim commands with lua tables as args.
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 {})
vim.env.PLENARY_TEST_TIMEOUT = opts.timeout
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 busted_opts = {}
if opts.filter then
busted_opts.filter = opts.filter
end
local jobs = vim.tbl_map(function(p)
local args = {
"--headless",
"-c",
string.format(
'lua require("plenary.busted").run("%s", %s)',
p:absolute(),
vim.inspect(busted_opts) -- TODO: find better way to do this!
),
}
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