-
-
Notifications
You must be signed in to change notification settings - Fork 290
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Busted Output (wip) #86
Changes from all commits
d5170de
8a2486e
b5b4122
03bf6b7
f4d7dcc
629cbe1
0fb0709
598ce0a
416dffe
e13cd17
a7393b9
df605c3
a99ba27
f6befef
96dc3e0
07cccdc
aa01f56
adf0574
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,25 @@ | ||
local Path = require('plenary.path') | ||
|
||
local dirname = function(p) | ||
return vim.fn.fnamemodify(p, ":h") | ||
end | ||
|
||
local function get_trace(element, level, msg) | ||
|
||
local function trimTrace(info) | ||
local index = info.traceback:find('\n%s*%[C]') | ||
info.traceback = info.traceback:sub(1, index) | ||
local start_index = info.traceback:find('/') | ||
local end_index = info.traceback:find(': in') | ||
info.traceback = info.traceback:sub(start_index, end_index) | ||
|
||
return info | ||
end | ||
|
||
level = level or 3 | ||
|
||
local thisdir = dirname(debug.getinfo(1, 'Sl').source, ":h") | ||
local thisdir = dirname(debug.getinfo(1, 'Sl').source) | ||
local info = debug.getinfo(level, 'Sl') | ||
while info.what == 'C' or info.short_src:match('luassert[/\\].*%.lua$') or | ||
(info.source:sub(1,1) == '@' and thisdir == dirname(info.source)) do | ||
(info.source:sub(1,1) == '@' and thisdir == dirname(info.source)) do | ||
level = level + 1 | ||
info = debug.getinfo(level, 'Sl') | ||
end | ||
|
@@ -22,12 +28,44 @@ local function get_trace(element, level, msg) | |
info.message = msg | ||
|
||
-- local file = busted.getFile(element) | ||
local file = false | ||
return file and file.getTrace(file.name, info) or trimTrace(info) | ||
-- local file = false | ||
-- local file = false | ||
-- return file and file.getTrace(file.name, info) or trimTrace(info) | ||
return trimTrace(info) | ||
end | ||
|
||
local function get_file_and_line_number() | ||
|
||
local function trimTrace(trace) | ||
local start_index = trace:find('/') | ||
local end_index = trace:find(': in') | ||
trace = trace:sub(start_index, end_index) | ||
|
||
local split_str = vim.split(trace, ':') | ||
local spec = {} | ||
spec.file = split_str[1] | ||
spec.linenumber = split_str[2] | ||
|
||
return spec | ||
end | ||
|
||
local level = 3 | ||
|
||
local thisdir = dirname(debug.getinfo(1, 'Sl').source) | ||
local info = debug.getinfo(level, 'Sl') | ||
while info.what == 'C' or info.short_src:match('luassert[/\\].*%.lua$') or | ||
(info.source:sub(1,1) == '@' and thisdir == dirname(info.source)) do | ||
level = level + 1 | ||
info = debug.getinfo(level, 'Sl') | ||
end | ||
|
||
local trace = debug.traceback('', level) | ||
|
||
return trimTrace(trace) | ||
end | ||
|
||
--[[ is_headless is always true | ||
-- running in nvim or in terminal --]] | ||
local is_headless = require('plenary.nvim_meta').is_headless | ||
|
||
local print = function(...) | ||
|
@@ -70,61 +108,69 @@ local call_inner = function(desc, func) | |
local desc_stack = add_description(desc) | ||
add_new_each() | ||
local ok, msg = xpcall(func, function(msg) | ||
-- debug.traceback | ||
-- return vim.inspect(get_trace(nil, 3, msg)) | ||
local trace = get_trace(nil, 3, msg) | ||
return trace.message .. "\n" .. trace.traceback | ||
-- return trace.message .. "\n" .. trace.traceback | ||
return trace.message | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should keep the traceback |
||
end) | ||
clear_last_each() | ||
pop_description() | ||
|
||
return ok, msg, desc_stack | ||
end | ||
|
||
local color_table = { | ||
local ansi_color_table = { | ||
cyan = 36, | ||
magenta = 35, | ||
yellow = 33, | ||
green = 32, | ||
red = 31, | ||
} | ||
|
||
local color_string = function(color, str) | ||
if not is_headless then | ||
-- This is never being called | ||
return str | ||
end | ||
|
||
return string.format("%s[%sm%s%s[%sm", | ||
string.char(27), | ||
color_table[color] or 0, | ||
str, | ||
string.char(27), | ||
0 | ||
string.char(27), | ||
ansi_color_table[color] or 0, | ||
str, | ||
string.char(27), | ||
0 | ||
) | ||
end | ||
|
||
local bold_string = function(str) | ||
local ansi_bold = "\027[1m" | ||
local ansi_clear = "\027[0m" | ||
|
||
return ansi_bold .. str .. ansi_clear | ||
end | ||
|
||
-- local SUCCESS = color_string("green", "Success") | ||
local FAIL = color_string("red", "Failure") | ||
local SUCCESS = color_string("green", "Success") | ||
local FAIL = color_string("red", "Fail") | ||
local PENDING = color_string("yellow", "Pending") | ||
|
||
local HEADER = string.rep("=", 40) | ||
local HORIZONTALRULER = string.rep("─", 80) | ||
|
||
mod.format_results = function(result) | ||
|
||
mod.format_results = function(res) | ||
local num_pass = #res.pass | ||
local num_fail = #res.fail | ||
local num_errs = #res.errs | ||
local num_pass = color_string("green", #result.pass) | ||
local num_fail = color_string("red", #result.fail) | ||
local num_errs = color_string("magenta", #result.errs) | ||
|
||
print("") | ||
print(color_string("green", "Success: "), num_pass) | ||
print(color_string("red", "Failed : "), num_fail) | ||
print(color_string("red", "Errors : "), num_errs) | ||
print(HEADER) | ||
print(string.format(" %s successes / %s failures / %s errors", num_pass, num_fail, num_errs)) | ||
end | ||
|
||
mod.describe = function(desc, func) | ||
results.pass = results.pass or {} | ||
results.fail = results.fail or {} | ||
results.errs = results.errs or {} | ||
results.fatal = results.fatal or {} | ||
results.pass = {} | ||
results.fail = {} | ||
results.errs = {} | ||
|
||
print("\n" .. HORIZONTALRULER .."\n ") | ||
-- print("Testing: ", debug.getinfo(2, 'Sl').source) | ||
describe = mod.inner_describe | ||
local ok, msg = call_inner(desc, func) | ||
describe = mod.describe | ||
|
@@ -185,17 +231,27 @@ mod.it = function(desc, func) | |
|
||
-- TODO: We should figure out how to determine whether | ||
-- and assert failed or whether it was an error... | ||
|
||
local to_insert, printed | ||
if not ok then | ||
to_insert = results.fail | ||
test_result.msg = msg | ||
|
||
print(FAIL, "||", table.concat(test_result.descriptions, " ")) | ||
print(indent(msg, 12)) | ||
-- print(FAIL, " → " .. color_string("cyan", "spec/foo/bar_spec.lua @ 7") .. "\n") | ||
|
||
print("{SPEC: FAIL}") | ||
local spec = get_file_and_line_number() | ||
|
||
print(FAIL, " → " .. color_string("cyan", spec.file) .. " @ " .. color_string("cyan", spec.linenumber) .. "\n") | ||
|
||
print(bold_string(table.concat(test_result.descriptions))) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. missing |
||
print(indent("\n" .. msg, 7)) | ||
|
||
print("{ENDOFSPEC}") | ||
|
||
else | ||
to_insert = results.pass | ||
print(SUCCESS, "||", table.concat(test_result.descriptions, " ")) | ||
print("{SPEC: SUCCESS}") | ||
print(SUCCESS, " → ", table.concat(test_result.descriptions, " ")) | ||
print("{ENDOFSPEC}") | ||
end | ||
|
||
table.insert(to_insert, test_result) | ||
|
@@ -219,16 +275,17 @@ clear = mod.clear | |
assert = require("luassert") | ||
|
||
mod.run = function(file) | ||
print("\n" .. HEADER) | ||
print("Testing: ", file) | ||
-- print("Testing: ", file) | ||
|
||
local ok, msg = pcall(dofile, file) | ||
|
||
if not ok then | ||
print(HEADER) | ||
print(HORIZONTALRULER) | ||
print("FAILED TO LOAD FILE") | ||
print(color_string("red", msg)) | ||
print(HEADER) | ||
print(HORIZONTALRULER) | ||
|
||
os.exit(2) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This shouldn't be here I am looking at the whole code now. Give me between 30 ~ 60 mins for an answer. I wanna play around with the code for a bit There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay i am trying to get There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh i see what you doing. I am not sure if i like it i kinda wanna keep the current way of starting a test, with just executing busted itself. We not always wanna go thought There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's exactly the reason for reaching out. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here is what i think we could do. When executing the file with For stacktrace and error, the line always starts with a If you wanna have a more detailed talk, you can write me on gitter in private. |
||
if is_headless then | ||
os.exit(2) | ||
else | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
local ansi_color_table = { | ||
cyan = 36, | ||
magenta = 35, | ||
yellow = 33, | ||
green = 32, | ||
red = 31, | ||
} | ||
|
||
local color_string = function(color, str) | ||
return string.format("%s[%sm%s%s[%sm", | ||
string.char(27), | ||
ansi_color_table[color] or 0, | ||
str, | ||
string.char(27), | ||
0 | ||
) | ||
end | ||
|
||
local successDot = color_string('green', '●') | ||
local failureDot = color_string('red', '◼') | ||
local errorDot = color_string('magenta', '✱') | ||
local pendingDot = color_string('yellow', '◌') | ||
|
||
local function generate_dots(results, status_str, dot) | ||
local dot_count = 0 | ||
for _, spec in pairs(results) do | ||
if spec.status == status_str then | ||
io.stdout:write(dot) | ||
dot_count = dot_count + 1 | ||
end | ||
end | ||
return dot_count | ||
end | ||
|
||
local function generate_score(n_succ, n_fail, n_err, n_pend) | ||
|
||
local success = n_succ == 1 and ' success' or ' successes' | ||
local fail = n_fail == 1 and ' failure' or ' failures' | ||
local error = n_err == 1 and ' error' or ' errors' | ||
|
||
local score = | ||
color_string('green', n_succ) .. success .. ' / ' .. | ||
color_string('red', n_fail) .. fail .. ' / ' .. | ||
color_string('magenta', n_err) .. error .. ' / ' .. | ||
color_string('yellow', n_pend) .. ' pending' | ||
|
||
io.stdout:write(score) | ||
end | ||
|
||
local Score = {} | ||
|
||
function Score.draw(results) | ||
|
||
local n_pend = generate_dots(results, 'pending', pendingDot) | ||
local n_err = generate_dots(results, 'error', errorDot) | ||
local n_fail = generate_dots(results, 'failed', failureDot) | ||
local n_succ = generate_dots(results, 'success', successDot) | ||
|
||
io.stdout:write('\n') | ||
generate_score(n_succ, n_fail, n_err, n_pend) | ||
io.stdout:write('\n\n') | ||
end | ||
|
||
return Score |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
BustedOutputReader = {} | ||
|
||
local spec_results = {} | ||
local current_spec = {} | ||
|
||
local function set_spec_status(line, find_str, status_str) | ||
if line:find(find_str) then | ||
current_spec.status = status_str | ||
return true | ||
end | ||
end | ||
|
||
local is_spec_result | ||
local cat_line | ||
|
||
local function reset() | ||
current_spec, cat_line, is_spec_result = {}, nil, nil | ||
end | ||
|
||
BustedOutputReader.output_to_table = function(...) | ||
|
||
for _, line in pairs({...}) do | ||
|
||
if is_spec_result then | ||
|
||
if line:find('{ENDOFSPEC}') then | ||
current_spec.content = cat_line | ||
table.insert(spec_results, current_spec) | ||
|
||
reset() | ||
else | ||
if not cat_line then cat_line = "" end | ||
cat_line = cat_line .. line .. '\n' | ||
end | ||
end | ||
|
||
if not is_spec_result then | ||
is_spec_result = set_spec_status(line, '{SPEC: FAIL}', 'failed') or | ||
set_spec_status(line, '{SPEC: ERROR}', 'error') or | ||
set_spec_status(line, '{SPEC: SUCCESS}', 'success') or | ||
set_spec_status(line, '{SPEC: PENDING}', 'pending') | ||
end | ||
end | ||
|
||
return spec_results | ||
end | ||
|
||
return BustedOutputReader | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are subbing away here, only busted traceback?